From 5b7406fed5b77fb440d43081bc1d5389bc46b2e6 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 10 May 2022 02:02:35 +0100 Subject: [PATCH 0001/1348] [d3d9] Fix crash when using StretchRect with NULL rts --- src/d3d9/d3d9_device.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 1ca50924a..9dedb8041 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -944,6 +944,9 @@ namespace dxvk { Rc dstImage = dstTextureInfo->GetImage(); Rc srcImage = srcTextureInfo->GetImage(); + if (dstImage == nullptr || srcImage == nullptr) + return D3DERR_INVALIDCALL; + const DxvkFormatInfo* dstFormatInfo = imageFormatInfo(dstImage->info().format); const DxvkFormatInfo* srcFormatInfo = imageFormatInfo(srcImage->info().format); From cde0fbe7b00a1dc0ba4f47858bdc4108cc9575a0 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Wed, 18 May 2022 20:38:18 -0500 Subject: [PATCH 0002/1348] [util] Enable d3d9.deferSurfaceCreation for Small Radios Big Televisions --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index b6b8588ef..427b1ba9e 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -287,6 +287,10 @@ namespace dxvk { /* Stranger of Paradise - FF Origin */ { R"(\\SOPFFO\.exe$)", {{ { "d3d9.deferSurfaceCreation", "True" }, + /* Small Radios Big Televisions */ + }} }, + { R"(\\SRBT\.exe$)", {{ + { "d3d9.deferSurfaceCreation", "True" }, }} }, /**********************************************/ From cc11bb824045505439604d2bc1af9d805749ed09 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Wed, 18 May 2022 12:37:57 -0500 Subject: [PATCH 0003/1348] [d3d9] Don't adjust window position and size in windowed mode. --- src/d3d9/d3d9_swapchain.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index c4ed31b39..fc32bb418 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -631,21 +631,6 @@ namespace dxvk { if (pPresentParams->Windowed) { if (changeFullscreen) this->LeaveFullscreenMode(); - - // Adjust window position and size - RECT newRect = { 0, 0, 0, 0 }; - RECT oldRect = { 0, 0, 0, 0 }; - - ::GetWindowRect(m_window, &oldRect); - ::MapWindowPoints(HWND_DESKTOP, ::GetParent(m_window), reinterpret_cast(&oldRect), 1); - ::SetRect(&newRect, 0, 0, pPresentParams->BackBufferWidth, pPresentParams->BackBufferHeight); - ::AdjustWindowRectEx(&newRect, - ::GetWindowLongW(m_window, GWL_STYLE), FALSE, - ::GetWindowLongW(m_window, GWL_EXSTYLE)); - ::SetRect(&newRect, 0, 0, newRect.right - newRect.left, newRect.bottom - newRect.top); - ::OffsetRect(&newRect, oldRect.left, oldRect.top); - ::MoveWindow(m_window, newRect.left, newRect.top, - newRect.right - newRect.left, newRect.bottom - newRect.top, TRUE); } else { if (changeFullscreen) { From 51e56c04209294cb38c174ec76129bdb857d85c9 Mon Sep 17 00:00:00 2001 From: WinterSnowfall Date: Mon, 18 Apr 2022 18:23:31 +0300 Subject: [PATCH 0004/1348] [util] Enforce a maxAvailableMemory limit for Majesty 2 --- src/util/config/config.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 427b1ba9e..fc980b8e6 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -531,6 +531,14 @@ namespace dxvk { { R"(\\SWTFU2\.exe$)", {{ { "d3d9.forceSamplerTypeSpecConstants", "True" }, }} }, + /* Majesty 2 (Collection) * + * Crashes on UMA without a memory limit, * + * since the game(s) will allocate all * + * available VRAM on startup. */ + { R"(\\Majesty2\.exe$)", {{ + { "d3d9.memoryTrackTest", "True" }, + { "d3d9.maxAvailableMemory", "2048" }, + }} }, }}; From 8147844aef18783ba4b8312fdc965ae475669d86 Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Tue, 17 May 2022 22:51:01 +0800 Subject: [PATCH 0005/1348] [dxgi] Return DXGI_ERROR_INVALID_CALL for invalid IDXGIAdapter3::RegisterVideoMemoryBudgetChangeNotificationEvent() parameters According to wine tests https://source.winehq.org/git/wine.git/commitdiff/14237e321b30bd3f9eaa441586f82c44c15bc5cf Signed-off-by: Zhiyi Zhang --- src/dxgi/dxgi_adapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index cd5f3370f..3e8f6307e 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -404,7 +404,7 @@ namespace dxvk { HANDLE hEvent, DWORD* pdwCookie) { if (!hEvent || !pdwCookie) - return E_INVALIDARG; + return DXGI_ERROR_INVALID_CALL; std::unique_lock lock(m_mutex); DWORD cookie = ++m_eventCookie; From 0678d80e897e0b60f3424a22912c69f439233c53 Mon Sep 17 00:00:00 2001 From: Masanori Kakura Date: Wed, 4 May 2022 23:11:46 +0900 Subject: [PATCH 0006/1348] [meta] Update Meson requirement (>=0.49) in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7da0418e4..8c02992a3 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ export WINEPREFIX=/path/to/.wine-prefix ### Requirements: - [wine 3.10](https://www.winehq.org/) or newer -- [Meson](https://mesonbuild.com/) build system (at least version 0.46) +- [Meson](https://mesonbuild.com/) build system (at least version 0.49) - [Mingw-w64](https://www.mingw-w64.org) compiler and headers (at least version 8.0) - [glslang](https://github.com/KhronosGroup/glslang) compiler From 93eb86aa3eb737ebc48879badb475a739a1f373d Mon Sep 17 00:00:00 2001 From: noneistaken <90960821+noneistaken@users.noreply.github.com> Date: Thu, 12 May 2022 23:50:08 +0700 Subject: [PATCH 0007/1348] Blend HUD text shadow and center correctly This fixes incorrect blending between HUD text, which would cause a narrow transparent gap between the text center and border/shadow that is visible at large text sizes. --- src/dxvk/hud/shaders/hud_text_frag.frag | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dxvk/hud/shaders/hud_text_frag.frag b/src/dxvk/hud/shaders/hud_text_frag.frag index e1278fab1..56a2823ce 100644 --- a/src/dxvk/hud/shaders/hud_text_frag.frag +++ b/src/dxvk/hud/shaders/hud_text_frag.frag @@ -27,10 +27,11 @@ void main() { float r_alpha_center = sampleAlpha(0.0f, 5.0f); float r_alpha_shadow = sampleAlpha(0.3f, 5.0f); - vec4 r_center = vec4(v_color.rgb, v_color.a * r_alpha_center); - vec4 r_shadow = vec4(0.0f, 0.0f, 0.0f, r_alpha_shadow); - - o_color = mix(r_shadow, r_center, r_alpha_center); + vec3 r_center = v_color.rgb; + vec3 r_shadow = vec3(0.0f, 0.0f, 0.0f); + + o_color.rgb = mix(r_shadow, r_center, r_alpha_center); + o_color.a = r_alpha_shadow * v_color.a; o_color.rgb *= o_color.a; if (!srgbSwapchain) From 8c968307525b8b0eea7916153f8f97ea6d324b64 Mon Sep 17 00:00:00 2001 From: Winter Snowfall Date: Tue, 31 May 2022 16:17:31 +0300 Subject: [PATCH 0008/1348] Add d3d9.deferSurfaceCreation workaround for Scrapland (Remastered) (#2574) --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index fc980b8e6..569de20bb 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -531,6 +531,10 @@ namespace dxvk { { R"(\\SWTFU2\.exe$)", {{ { "d3d9.forceSamplerTypeSpecConstants", "True" }, }} }, + /* Scrapland (Remastered) */ + { R"(\\Scrap\.exe$)", {{ + { "d3d9.deferSurfaceCreation", "True" }, + }} }, /* Majesty 2 (Collection) * * Crashes on UMA without a memory limit, * * since the game(s) will allocate all * From 7bcf3e10629b357388996e57280bd6d73422efcc Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Tue, 31 May 2022 15:19:30 +0200 Subject: [PATCH 0009/1348] [util] Force SM1 for the Warhammer ROR Launcher (#2579) Co-authored-by: Philip Rebohle <25567304+doitsujin@users.noreply.github.com> --- src/util/config/config.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 569de20bb..01d9a2260 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -524,6 +524,12 @@ namespace dxvk { { R"(\\limbo\.exe$)", {{ { "d3d9.maxFrameRate", "60" }, }} }, + /* Warhammer: Return of Reckoning Launcher + Forcing SM1 fixes a black window otherwise caused by + the lack of support for partial presentation */ + { R"(\\RoRLauncher\.exe$)", {{ + { "d3d9.shaderModel", "1" }, + }} }, /* Star Wars The Force Unleashed 2 * * Black particles because it tries to bind * * a 2D texture for a shader that * From 4ff7687dea26e58597da15d03a887a09d2555425 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Tue, 31 May 2022 15:35:57 +0200 Subject: [PATCH 0010/1348] [util] Force SM1 for the Halo CE SPV3 launcher --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 01d9a2260..e67688de4 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -530,6 +530,11 @@ namespace dxvk { { R"(\\RoRLauncher\.exe$)", {{ { "d3d9.shaderModel", "1" }, }} }, + /* Halo CE SPV3 launcher + Same issue as Warhammer: RoR above */ + { R"(\\spv3\.exe$)", {{ + { "d3d9.shaderModel", "1" }, + }} }, /* Star Wars The Force Unleashed 2 * * Black particles because it tries to bind * * a 2D texture for a shader that * From 80e125a130d18b222a24501d7f23d539a529efe3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 6 May 2022 15:25:36 +0200 Subject: [PATCH 0011/1348] [dxvk] Perform more extensive validation on pipeline state vectors --- src/dxvk/dxvk_graphics.cpp | 72 +++++++++++++++++++++++++++++++++++--- src/dxvk/dxvk_graphics.h | 15 +++++++- 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index ebde0ab52..66c4131ec 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -67,7 +67,7 @@ namespace dxvk { if (unlikely(!instance)) { // Exit early if the state vector is invalid - if (!this->validatePipelineState(state)) + if (!this->validatePipelineState(state, true)) return VK_NULL_HANDLE; // Prevent other threads from adding new instances and check again @@ -90,7 +90,7 @@ namespace dxvk { const DxvkGraphicsPipelineStateInfo& state, const DxvkRenderPass* renderPass) { // Exit early if the state vector is invalid - if (!this->validatePipelineState(state)) + if (!this->validatePipelineState(state, false)) return; // Keep the object locked while compiling a pipeline since compiling @@ -510,7 +510,8 @@ namespace dxvk { bool DxvkGraphicsPipeline::validatePipelineState( - const DxvkGraphicsPipelineStateInfo& state) const { + const DxvkGraphicsPipelineStateInfo& state, + bool trusted) const { // Tessellation shaders and patches must be used together bool hasPatches = state.ia.primitiveTopology() == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; @@ -528,8 +529,69 @@ namespace dxvk { if (state.il.attributeCount() > DxvkLimits::MaxNumVertexAttributes || state.il.bindingCount() > DxvkLimits::MaxNumVertexBindings) return false; - - // No errors + + // Exit here on the fast path, perform more thorough validation if + // the state vector comes from an untrusted source (i.e. the cache) + if (trusted) + return true; + + // Validate shaders + if (!m_shaders.validate()) { + Logger::err("Invalid pipeline: Shader types do not match stage"); + return false; + } + + // Validate vertex input layout + const DxvkDevice* device = m_pipeMgr->m_device; + uint32_t ilLocationMask = 0; + uint32_t ilBindingMask = 0; + + for (uint32_t i = 0; i < state.il.bindingCount(); i++) + ilBindingMask |= 1u << state.ilBindings[i].binding(); + + for (uint32_t i = 0; i < state.il.attributeCount(); i++) { + const DxvkIlAttribute& attribute = state.ilAttributes[i]; + + if (ilLocationMask & (1u << attribute.location())) { + Logger::err(str::format("Invalid pipeline: Vertex location ", attribute.location(), " defined twice")); + return false; + } + + if (!(ilBindingMask & (1u << attribute.binding()))) { + Logger::err(str::format("Invalid pipeline: Vertex binding ", attribute.binding(), " not defined")); + return false; + } + + VkFormatProperties formatInfo = device->adapter()->formatProperties(attribute.format()); + + if (!(formatInfo.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) { + Logger::err(str::format("Invalid pipeline: Format ", attribute.format(), " not supported for vertex buffers")); + return false; + } + + ilLocationMask |= 1u << attribute.location(); + } + + // Validate rasterization state + if (state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT) { + if (!device->extensions().extConservativeRasterization) { + Logger::err("Conservative rasterization not supported by device"); + return false; + } + + if (state.rs.conservativeMode() == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT + && !device->properties().extConservativeRasterization.primitiveUnderestimation) { + Logger::err("Primitive underestimation not supported by device"); + return false; + } + } + + // Validate depth-stencil state + if (state.ds.enableDepthBoundsTest() && !device->features().core.features.depthBounds) { + Logger::err("Depth bounds not supported by device"); + return false; + } + return true; } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 3a4d93f3c..50d16b1ef 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -55,6 +55,18 @@ namespace dxvk { state.add(DxvkShader::getHash(fs)); return state; } + + bool validate() const { + return validateShaderType(vs, VK_SHADER_STAGE_VERTEX_BIT) + && validateShaderType(tcs, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) + && validateShaderType(tes, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) + && validateShaderType(gs, VK_SHADER_STAGE_GEOMETRY_BIT) + && validateShaderType(fs, VK_SHADER_STAGE_FRAGMENT_BIT); + } + + static bool validateShaderType(const Rc& shader, VkShaderStageFlagBits stage) { + return shader == nullptr || shader->info().stage == stage; + } }; @@ -249,7 +261,8 @@ namespace dxvk { VkShaderStageFlagBits stage) const; bool validatePipelineState( - const DxvkGraphicsPipelineStateInfo& state) const; + const DxvkGraphicsPipelineStateInfo& state, + bool trusted) const; void writePipelineStateToCache( const DxvkGraphicsPipelineStateInfo& state, From 6d3ba1b7d74fe2c3d8565ebbaff4d2c968330ae1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 6 May 2022 16:05:43 +0200 Subject: [PATCH 0012/1348] [dxvk] Perform validation on render pass formats read from state cache --- src/dxvk/dxvk_renderpass.cpp | 41 +++++++++++++++++++++++++++++++++-- src/dxvk/dxvk_renderpass.h | 13 +++++++++-- src/dxvk/dxvk_state_cache.cpp | 6 +++-- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_renderpass.cpp b/src/dxvk/dxvk_renderpass.cpp index ee07945ba..2bac17087 100644 --- a/src/dxvk/dxvk_renderpass.cpp +++ b/src/dxvk/dxvk_renderpass.cpp @@ -269,7 +269,7 @@ namespace dxvk { DxvkRenderPassPool::DxvkRenderPassPool(const DxvkDevice* device) - : m_vkd(device->vkd()) { + : m_device(device) { } @@ -288,8 +288,45 @@ namespace dxvk { auto result = m_renderPasses.emplace(std::piecewise_construct, std::tuple(fmt), - std::tuple(m_vkd, fmt)); + std::tuple(m_device->vkd(), fmt)); return &result.first->second; } + + + bool DxvkRenderPassPool::validateRenderPassFormat( + const DxvkRenderPassFormat& fmt) { + Rc adapter = m_device->adapter(); + + if (fmt.depth.format) { + VkFormatProperties depthInfo = adapter->formatProperties(fmt.depth.format); + VkFormatFeatureFlags depthFlags = depthInfo.linearTilingFeatures | depthInfo.optimalTilingFeatures; + + if (!(depthFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) + return false; + + if (fmt.depth.layout != VK_IMAGE_LAYOUT_GENERAL + && fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL + && fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL + && fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + && fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) + return false; + } + + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + if (fmt.color[i].format) { + VkFormatProperties colorInfo = adapter->formatProperties(fmt.color[i].format); + VkFormatFeatureFlags colorFlags = colorInfo.linearTilingFeatures | colorInfo.optimalTilingFeatures; + + if (!(colorFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) + return false; + + if (fmt.color[i].layout != VK_IMAGE_LAYOUT_GENERAL + && fmt.color[i].layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + return false; + } + } + + return true; + } } \ No newline at end of file diff --git a/src/dxvk/dxvk_renderpass.h b/src/dxvk/dxvk_renderpass.h index ea265b84f..2dff87880 100644 --- a/src/dxvk/dxvk_renderpass.h +++ b/src/dxvk/dxvk_renderpass.h @@ -219,10 +219,19 @@ namespace dxvk { */ DxvkRenderPass* getRenderPass( const DxvkRenderPassFormat& fmt); - + + /** + * \brief Validates render pass format + * + * \param [in] fmt The render pass format + * \returns \c true if the format is supported + */ + bool validateRenderPassFormat( + const DxvkRenderPassFormat& fmt); + private: - const Rc m_vkd; + const DxvkDevice* m_device; dxvk::mutex m_mutex; std::unordered_map< diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index acc574686..15bec1712 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -371,8 +371,10 @@ namespace dxvk { for (auto e = entries.first; e != entries.second; e++) { const auto& entry = m_entries[e->second]; - auto rp = m_passManager->getRenderPass(entry.format); - pipeline->compilePipeline(entry.gpState, rp); + if (m_passManager->validateRenderPassFormat(entry.format)) { + auto rp = m_passManager->getRenderPass(entry.format); + pipeline->compilePipeline(entry.gpState, rp); + } } } else { auto pipeline = m_pipeManager->createComputePipeline(item.cp); From 5d0273f52060ae57842ad2efdd24703a4376bb0f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 6 May 2022 16:10:47 +0200 Subject: [PATCH 0013/1348] [dxvk] Remove interpolation decorations for replaced shader inputs --- src/dxvk/dxvk_shader.cpp | 39 +++++++++++++++++++++++++++-------- src/spirv/spirv_code_buffer.h | 5 +++-- src/spirv/spirv_instruction.h | 8 ++++++- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 688f9e26c..2d9793f45 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -318,16 +318,37 @@ namespace dxvk { } } - // Remove location declarations - for (auto ins : code) { - if (ins.opCode() == spv::OpDecorate - && ins.arg(2) == spv::DecorationLocation - && ins.arg(1) == inputVarId) { - code.beginInsertion(ins.offset()); - code.erase(4); - code.endInsertion(); - break; + // Remove location and other declarations + for (auto iter = code.begin(); iter != code.end(); ) { + auto ins = *(iter++); + + if (ins.opCode() == spv::OpDecorate && ins.arg(1) == inputVarId) { + uint32_t numWords; + + switch (ins.arg(2)) { + case spv::DecorationLocation: + case spv::DecorationFlat: + case spv::DecorationNoPerspective: + case spv::DecorationCentroid: + case spv::DecorationPatch: + case spv::DecorationSample: + numWords = ins.length(); + break; + + default: + numWords = 0; + } + + if (numWords) { + code.beginInsertion(ins.offset()); + code.erase(numWords); + + iter = SpirvInstructionIterator(code.data(), code.endInsertion(), code.dwords()); + } } + + if (ins.opCode() == spv::OpFunction) + break; } // Fix up pointer types used in access chain instructions diff --git a/src/spirv/spirv_code_buffer.h b/src/spirv/spirv_code_buffer.h index a06b594c1..6bee2c9b0 100644 --- a/src/spirv/spirv_code_buffer.h +++ b/src/spirv/spirv_code_buffer.h @@ -208,9 +208,10 @@ namespace dxvk { * After this call, new instructions will be * appended to the stream. In other words, * this will restore default behaviour. + * \returns Previous instruction pointer */ - void endInsertion() { - m_ptr = m_code.size(); + size_t endInsertion() { + return std::exchange(m_ptr, m_code.size()); } private: diff --git a/src/spirv/spirv_instruction.h b/src/spirv/spirv_instruction.h index 061d5ab75..ada816e72 100644 --- a/src/spirv/spirv_instruction.h +++ b/src/spirv/spirv_instruction.h @@ -109,7 +109,7 @@ namespace dxvk { : m_code (length != 0 ? code : nullptr), m_offset(length != 0 ? offset : 0), m_length(length) { - if ((length >= 5) && (m_code[0] == spv::MagicNumber)) + if ((length >= 5) && (offset == 0) && (m_code[0] == spv::MagicNumber)) this->advance(5); } @@ -118,6 +118,12 @@ namespace dxvk { return *this; } + SpirvInstructionIterator operator ++ (int) { + SpirvInstructionIterator result = *this; + this->advance(SpirvInstruction(m_code, m_offset, m_length).length()); + return result; + } + SpirvInstruction operator * () const { return SpirvInstruction(m_code, m_offset, m_length); } From de0f81fcdc67d58dd74e62103c0f38d9c9fee860 Mon Sep 17 00:00:00 2001 From: Mike Lothian Date: Wed, 1 Jun 2022 23:56:55 +0100 Subject: [PATCH 0014/1348] [spirv] Add utility include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a compile issue with GCC 12.1 FAILED: src/spirv/libspirv.a.p/spirv_compression.cpp.obj i686-w64-mingw32-g++ -Isrc/spirv/libspirv.a.p -Isrc/spirv -I../dxvk-9999/src/spirv -I../dxvk-9999/include -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -std=c++17 -O0 -DNOMINMAX -D_WIN32_WINNT=0xa00 -msse -msse2 -msse3 -mfpmath=sse -Wimplicit-fallthrough -O3 -march=native -pipe -flto=16 -mno-avx -MD -MQ src/spirv/libspirv.a.p/spirv_compression.cpp.obj -MF src/spirv/libspirv.a.p/spirv_compression.cpp.obj.d -o src/spirv/libspirv.a.p/spirv_compression.cpp.obj -c ../dxvk-9999/src/spirv/spirv_compression.cpp In file included from ../dxvk-9999/src/spirv/../util/util_flags.h:5, from ../dxvk-9999/src/spirv/spirv_include.h:7, from ../dxvk-9999/src/spirv/spirv_instruction.h:6, from ../dxvk-9999/src/spirv/spirv_code_buffer.h:8, from ../dxvk-9999/src/spirv/spirv_compression.h:5, from ../dxvk-9999/src/spirv/spirv_compression.cpp:1: ../dxvk-9999/src/spirv/../util/util_bit.h:300:33: warning: ‘template struct std::iterator’ is deprecated [-Wdeprecated-declarations] 300 | class iterator: public std::iterator --- src/spirv/spirv_code_buffer.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/spirv/spirv_code_buffer.h b/src/spirv/spirv_code_buffer.h index 6bee2c9b0..a0ed22727 100644 --- a/src/spirv/spirv_code_buffer.h +++ b/src/spirv/spirv_code_buffer.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "spirv_instruction.h" @@ -221,4 +222,4 @@ namespace dxvk { }; -} \ No newline at end of file +} From 1862e4dc8d141e418b2a552543c8c385a0542a12 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Tue, 31 May 2022 20:44:11 +0200 Subject: [PATCH 0015/1348] [util] Report Nvidia VendorId for Myst V Game was made before ATI Technologies was bought by AMD and so doesn't recognize AMD as a GPU vendor, which for some reason makes it bug out. It also works when it sees the word "Radeon" in the device description, which is why this issue doesn't show on amdvlk or wined3d. --- src/util/config/config.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index e67688de4..ede05db44 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -554,6 +554,13 @@ namespace dxvk { { "d3d9.memoryTrackTest", "True" }, { "d3d9.maxAvailableMemory", "2048" }, }} }, + /* Myst V End of Ages + Game has white textures on amd radv. + Expects Nvidia, Intel or ATI VendorId. + "Radeon" in gpu description also works */ + { R"(\\eoa\.exe$)", {{ + { "d3d9.customVendorId", "10de" }, + }} }, }}; From c596738205566162c3a61226e854197e9a0f4779 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Jun 2022 19:44:14 +0200 Subject: [PATCH 0016/1348] [hud] Fix incorrect array length for VS resources --- src/dxvk/hud/dxvk_hud_renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index acafc609f..9ae6d3ce9 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -159,7 +159,7 @@ namespace dxvk::hud { SpirvCodeBuffer vsCode(hud_text_vert); SpirvCodeBuffer fsCode(hud_text_frag); - const std::array vsResources = {{ + const std::array vsResources = {{ { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM }, { 1, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM }, }}; From 279b4b7ec225c2c4bddc4eb6ddfa8bfe89c8bf5c Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Thu, 2 Jun 2022 13:48:18 -0500 Subject: [PATCH 0017/1348] [d3d9] Defer surface creation if no HWND is given to device Planetary Annihilation: TITANS creates a device with a NULL HWND and requires it to succeed. --- src/d3d9/d3d9_swapchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index fc32bb418..a17991174 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -199,7 +199,7 @@ namespace dxvk { m_window = m_presentParams.hDeviceWindow; UpdatePresentRegion(nullptr, nullptr); - if (!pDevice->GetOptions()->deferSurfaceCreation) + if (m_window && !pDevice->GetOptions()->deferSurfaceCreation) CreatePresenter(); CreateBackBuffers(m_presentParams.BackBufferCount); From 9e5c61bf885ae1af0c506326d2b4cb5dabd4327c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 7 Jun 2022 11:45:42 +0200 Subject: [PATCH 0018/1348] [dxvk] Create state cache threads on demand --- src/dxvk/dxvk_pipemanager.cpp | 2 +- src/dxvk/dxvk_pipemanager.h | 4 +- src/dxvk/dxvk_state_cache.cpp | 71 ++++++++++++++++++++++------------- src/dxvk/dxvk_state_cache.h | 7 +++- 4 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 0e112e513..4c5ea32fb 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -5,7 +5,7 @@ namespace dxvk { DxvkPipelineManager::DxvkPipelineManager( - const DxvkDevice* device, + DxvkDevice* device, DxvkRenderPassPool* passManager) : m_device (device), m_cache (new DxvkPipelineCache(device->vkd())) { diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index f32a89133..08c79e0a8 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -38,7 +38,7 @@ namespace dxvk { public: DxvkPipelineManager( - const DxvkDevice* device, + DxvkDevice* device, DxvkRenderPassPool* passManager); ~DxvkPipelineManager(); @@ -97,7 +97,7 @@ namespace dxvk { private: - const DxvkDevice* m_device; + DxvkDevice* m_device; Rc m_cache; Rc m_stateCache; diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 15bec1712..1dfb26d0a 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -150,11 +150,12 @@ namespace dxvk { DxvkStateCache::DxvkStateCache( - const DxvkDevice* device, + DxvkDevice* device, DxvkPipelineManager* pipeManager, DxvkRenderPassPool* passManager) - : m_pipeManager(pipeManager), - m_passManager(passManager) { + : m_device (device), + m_pipeManager (pipeManager), + m_passManager (passManager) { bool newFile = !readCacheFile(); if (newFile) { @@ -184,28 +185,6 @@ namespace dxvk { for (auto& e : m_entries) writeCacheEntry(file, e); } - - // Use half the available CPU cores for pipeline compilation - uint32_t numCpuCores = dxvk::thread::hardware_concurrency(); - uint32_t numWorkers = ((std::max(1u, numCpuCores) - 1) * 5) / 7; - - if (numWorkers < 1) numWorkers = 1; - if (numWorkers > 32) numWorkers = 32; - - if (device->config().numCompilerThreads > 0) - numWorkers = device->config().numCompilerThreads; - - Logger::info(str::format("DXVK: Using ", numWorkers, " compiler threads")); - - // Start the worker threads and the file writer - m_workerBusy.store(numWorkers); - - for (uint32_t i = 0; i < numWorkers; i++) { - m_workerThreads.emplace_back([this] () { workerFunc(); }); - m_workerThreads[i].set_priority(ThreadPriority::Lowest); - } - - m_writerThread = dxvk::thread([this] () { writerFunc(); }); } @@ -238,6 +217,8 @@ namespace dxvk { DxvkComputePipelineStateInfo(), format, g_nullHash }); m_writerCond.notify_one(); + + createWriter(); } @@ -262,6 +243,8 @@ namespace dxvk { DxvkGraphicsPipelineStateInfo(), state, DxvkRenderPassFormat(), g_nullHash }); m_writerCond.notify_one(); + + createWriter(); } @@ -297,8 +280,10 @@ namespace dxvk { m_workerQueue.push(item); } - if (workerLock) + if (workerLock) { m_workerCond.notify_all(); + createWorkers(); + } } @@ -316,7 +301,8 @@ namespace dxvk { for (auto& worker : m_workerThreads) worker.join(); - m_writerThread.join(); + if (m_writerThread.joinable()) + m_writerThread.join(); } @@ -987,6 +973,37 @@ namespace dxvk { } + void DxvkStateCache::createWorkers() { + if (m_workerThreads.empty()) { + // Use half the available CPU cores for pipeline compilation + uint32_t numCpuCores = dxvk::thread::hardware_concurrency(); + uint32_t numWorkers = ((std::max(1u, numCpuCores) - 1) * 5) / 7; + + if (numWorkers < 1) numWorkers = 1; + if (numWorkers > 32) numWorkers = 32; + + if (m_device->config().numCompilerThreads > 0) + numWorkers = m_device->config().numCompilerThreads; + + Logger::info(str::format("DXVK: Using ", numWorkers, " compiler threads")); + + // Start the worker threads and the file writer + m_workerBusy.store(numWorkers); + + for (uint32_t i = 0; i < numWorkers; i++) { + m_workerThreads.emplace_back([this] () { workerFunc(); }); + m_workerThreads[i].set_priority(ThreadPriority::Lowest); + } + } + } + + + void DxvkStateCache::createWriter() { + if (!m_writerThread.joinable()) + m_writerThread = dxvk::thread([this] () { writerFunc(); }); + } + + std::wstring DxvkStateCache::getCacheFileName() const { std::string path = getCacheDir(); diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index a94dbd0e0..f23c85f05 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -28,7 +28,7 @@ namespace dxvk { public: DxvkStateCache( - const DxvkDevice* device, + DxvkDevice* device, DxvkPipelineManager* pipeManager, DxvkRenderPassPool* passManager); @@ -93,6 +93,7 @@ namespace dxvk { DxvkComputePipelineShaders cp; }; + DxvkDevice* m_device; DxvkPipelineManager* m_pipeManager; DxvkRenderPassPool* m_passManager; @@ -181,6 +182,10 @@ namespace dxvk { void writerFunc(); + void createWorkers(); + + void createWriter(); + std::wstring getCacheFileName() const; std::string getCacheDir() const; From 2e4caa4c1468901bdb3576c1582f615f5d1aa030 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Thu, 9 Jun 2022 17:18:38 +0200 Subject: [PATCH 0019/1348] [util] Stop using deprecated std::iterator. --- src/util/util_bit.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index 3c65c70df..7682ace86 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -297,9 +297,13 @@ namespace dxvk::bit { public: - class iterator: public std::iterator { + class iterator { public: + using iterator_category = std::input_iterator_tag; + using value_type = uint32_t; + using difference_type = uint32_t; + using pointer = const uint32_t*; + using reference = uint32_t; explicit iterator(uint32_t flags) : m_mask(flags) { } From 4f56e72d5608bc650e586d10d7414d1713c50b55 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sat, 11 Jun 2022 01:02:25 +0200 Subject: [PATCH 0020/1348] [util] Enable strict float emulation for Sonic Adventure 2 --- src/util/config/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index ede05db44..0f5d881cc 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -321,7 +321,7 @@ namespace dxvk { }} }, /* Sonic Adventure 2 */ { R"(\\Sonic Adventure 2\\(launcher|sonic2app)\.exe$)", {{ - { "d3d9.floatEmulation", "False" }, + { "d3d9.floatEmulation", "Strict" }, }} }, /* The Sims 2, Body Shop, From 968f0cdbc30e2b511076d7b20188aba00abd360d Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sun, 12 Jun 2022 20:21:27 +0200 Subject: [PATCH 0021/1348] [util] Strict float emulation for Supreme Commander --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 0f5d881cc..3a6478367 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -561,6 +561,10 @@ namespace dxvk { { R"(\\eoa\.exe$)", {{ { "d3d9.customVendorId", "10de" }, }} }, + /* Supreme Commander. */ + { R"(\\SupremeCommander\.exe$)", {{ + { "d3d9.floatEmulation", "Strict" }, + }} }, }}; From bd29fbd95d543156ac900b12295d29bcec436290 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 13 Jun 2022 17:04:41 +0200 Subject: [PATCH 0022/1348] [util] Enable sampler type spec constants for SWTOR Co-authored-by: Blisto91 <47954800+Blisto91@users.noreply.github.com> --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 3a6478367..c4bcf1db3 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -565,6 +565,10 @@ namespace dxvk { { R"(\\SupremeCommander\.exe$)", {{ { "d3d9.floatEmulation", "Strict" }, }} }, + /* Star Wars The Old Republic */ + { R"(\\swtor\.exe$)", {{ + { "d3d9.forceSamplerTypeSpecConstants", "True" }, + }} }, }}; From 661f8b5b56d31e3bab82b8a13d6630e9c9c27f5e Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Tue, 14 Jun 2022 00:31:50 +0200 Subject: [PATCH 0023/1348] [util] Add Forged Alliance Forever to Supreme Commander --- src/util/config/config.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index c4bcf1db3..3466f6b2b 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -561,9 +561,9 @@ namespace dxvk { { R"(\\eoa\.exe$)", {{ { "d3d9.customVendorId", "10de" }, }} }, - /* Supreme Commander. */ - { R"(\\SupremeCommander\.exe$)", {{ - { "d3d9.floatEmulation", "Strict" }, + /* Supreme Commander & Forged Alliance Forever */ + { R"(\\(SupremeCommander|ForgedAlliance)\.exe$)", {{ + { "d3d9.floatEmulation", "Strict" }, }} }, /* Star Wars The Old Republic */ { R"(\\swtor\.exe$)", {{ From 27163a6a297e1cae0ea6e517a6ed6ead60b983e3 Mon Sep 17 00:00:00 2001 From: pchome Date: Tue, 21 Jun 2022 22:19:05 +0300 Subject: [PATCH 0024/1348] [util] Fix built-in config options loging --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 3466f6b2b..bf67db134 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -768,6 +768,10 @@ namespace dxvk { if (appConfig != g_appDefaults.end()) { // Inform the user that we loaded a default config Logger::info(str::format("Found built-in config:")); + + for (auto& pair : appConfig->second.m_options) + Logger::info(str::format(" ", pair.first, " = ", pair.second)); + return appConfig->second; } From dee36be20de5562c494052975b57c004e6769e1a Mon Sep 17 00:00:00 2001 From: Federico Dossena Date: Sat, 25 Jun 2022 09:17:42 +0000 Subject: [PATCH 0025/1348] Added config for A Way Out (#2694) --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index bf67db134..c0f2896fa 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -292,6 +292,10 @@ namespace dxvk { { R"(\\SRBT\.exe$)", {{ { "d3d9.deferSurfaceCreation", "True" }, }} }, + /* A Way Out: fix for stuttering and low fps */ + { R"(\\AWayOut(_friend)?\.exe$)", {{ + { "dxgi.maxFrameLatency", "1" }, + }} }, /**********************************************/ /* D3D9 GAMES */ From 972de7c9fb26f391e53fd27986b2bc7744340989 Mon Sep 17 00:00:00 2001 From: Justin Kim Date: Tue, 28 Jun 2022 04:09:14 -0700 Subject: [PATCH 0026/1348] converting flags from VkShaderStageFlags to VkPipelineStageFlags in commitGraphicsBarriers (#2696) --- src/dxvk/dxvk_context.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index ac85428b5..7b5fe3211 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5058,7 +5058,7 @@ namespace dxvk { if ((slot.bufferSlice.defined()) && (slot.bufferSlice.bufferInfo().access & storageBufferAccess)) { srcAccess = this->checkGfxBufferBarrier(slot.bufferSlice, - binding.stages, binding.access); + util::pipelineStages(binding.stages), binding.access); } break; @@ -5067,7 +5067,7 @@ namespace dxvk { if ((slot.bufferView != nullptr) && (slot.bufferView->bufferInfo().access & storageBufferAccess)) { srcAccess = this->checkGfxBufferBarrier(slot.bufferView->slice(), - binding.stages, binding.access); + util::pipelineStages(binding.stages), binding.access); } break; @@ -5077,7 +5077,7 @@ namespace dxvk { if ((slot.imageView != nullptr) && (slot.imageView->imageInfo().access & storageImageAccess)) { srcAccess = this->checkGfxImageBarrier(slot.imageView, - binding.stages, binding.access); + util::pipelineStages(binding.stages), binding.access); } break; From 384a665700f308e46f55142e4ed0113c76acefeb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 28 Jun 2022 14:30:22 +0200 Subject: [PATCH 0027/1348] [dxvk] Optimize util::pipelineStages --- src/dxvk/dxvk_util.cpp | 19 ------------------- src/dxvk/dxvk_util.h | 7 +++++-- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/src/dxvk/dxvk_util.cpp b/src/dxvk/dxvk_util.cpp index 4dcf6aca7..508686967 100644 --- a/src/dxvk/dxvk_util.cpp +++ b/src/dxvk/dxvk_util.cpp @@ -5,25 +5,6 @@ namespace dxvk::util { - VkPipelineStageFlags pipelineStages( - VkShaderStageFlags shaderStages) { - VkPipelineStageFlags result = 0; - if (shaderStages & VK_SHADER_STAGE_COMPUTE_BIT) - result |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - if (shaderStages & VK_SHADER_STAGE_VERTEX_BIT) - result |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT; - if (shaderStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) - result |= VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT; - if (shaderStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) - result |= VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT; - if (shaderStages & VK_SHADER_STAGE_GEOMETRY_BIT) - result |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT; - if (shaderStages & VK_SHADER_STAGE_FRAGMENT_BIT) - result |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - return result; - } - - uint32_t computeMipLevelCount(VkExtent3D imageSize) { uint32_t maxDim = std::max(imageSize.width, imageSize.height); maxDim = std::max(imageSize.depth, maxDim); diff --git a/src/dxvk/dxvk_util.h b/src/dxvk/dxvk_util.h index 4535815e1..94fd06ddf 100644 --- a/src/dxvk/dxvk_util.h +++ b/src/dxvk/dxvk_util.h @@ -10,8 +10,11 @@ namespace dxvk::util { * \param [in] shaderStages Shader stage flags * \returns Corresponding pipeline stage flags */ - VkPipelineStageFlags pipelineStages( - VkShaderStageFlags shaderStages); + inline VkPipelineStageFlags pipelineStages( + VkShaderStageFlags shaderStages) { + return (shaderStages & VK_SHADER_STAGE_ALL_GRAPHICS) << 3 + | (shaderStages & VK_SHADER_STAGE_COMPUTE_BIT) << 6; + } /** * \brief Computes number of mip levels for an image From 67d03aabd0c9b57d00e18d0aca8aca60e27f2ea9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 21 Jun 2022 19:14:32 +0200 Subject: [PATCH 0028/1348] [dxvk] Make recycler a ring buffer Ensures that recycled objects actually get reused soon. Somewhat important for memory efficiency in descriptor pools. --- src/dxvk/dxvk_recycler.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/dxvk/dxvk_recycler.h b/src/dxvk/dxvk_recycler.h index b90befd4f..2dd1d5953 100644 --- a/src/dxvk/dxvk_recycler.h +++ b/src/dxvk/dxvk_recycler.h @@ -31,10 +31,10 @@ namespace dxvk { Rc retrieveObject() { std::lock_guard lock(m_mutex); - if (m_objectId == 0) + if (m_get == m_put) return nullptr; - return m_objects.at(--m_objectId); + return std::exchange(m_objects[(m_get++) % N], Rc()); } /** @@ -48,15 +48,17 @@ namespace dxvk { void returnObject(const Rc& object) { std::lock_guard lock(m_mutex); - if (m_objectId < N) - m_objects.at(m_objectId++) = object; + if (m_put - m_get < N) + m_objects[(m_put++) % N] = object; } private: - dxvk::mutex m_mutex; - std::array, N> m_objects; - size_t m_objectId = 0; + dxvk::mutex m_mutex; + std::array, N> m_objects; + + uint64_t m_get = 0; + uint64_t m_put = 0; }; From 3751edbe0c5a94c419c1c482d3c389b6204f88c1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Jun 2022 15:34:41 +0200 Subject: [PATCH 0029/1348] [dxvk] Introduce DxvkBindingLayout and related classes This is intended to replace the legacy DxvkPipelineLayout, and can support multiple descriptor sets. --- src/dxvk/dxvk_pipelayout.cpp | 333 +++++++++++++++++++++++++ src/dxvk/dxvk_pipelayout.h | 464 +++++++++++++++++++++++++++++++++++ 2 files changed, 797 insertions(+) diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index 72b319a14..7ad5e7cf8 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -1,11 +1,344 @@ #include +#include "dxvk_device.h" #include "dxvk_descriptor.h" #include "dxvk_limits.h" #include "dxvk_pipelayout.h" namespace dxvk { + uint32_t DxvkBindingInfo::computeSetIndex() const { + if (stages & (VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT)) { + // For fragment shaders, create a separate set for UBOs + if (descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER + || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) + return DxvkDescriptorSets::FsBuffers; + + return DxvkDescriptorSets::FsViews; + } else { + // Put all vertex shader resources into the last set. + // Vertex shader UBOs are usually updated every draw, + // and other resource types are rarely used. + return DxvkDescriptorSets::VsAll; + } + } + + + bool DxvkBindingInfo::canMerge(const DxvkBindingInfo& binding) const { + if ((stages & VK_SHADER_STAGE_FRAGMENT_BIT) != (binding.stages & VK_SHADER_STAGE_FRAGMENT_BIT)) + return false; + + return descriptorType == binding.descriptorType + && resourceBinding == binding.resourceBinding + && viewType == binding.viewType; + } + + + void DxvkBindingInfo::merge(const DxvkBindingInfo& binding) { + stages |= binding.stages; + access |= binding.access; + } + + + bool DxvkBindingInfo::eq(const DxvkBindingInfo& other) const { + return descriptorType == other.descriptorType + && resourceBinding == other.resourceBinding + && viewType == other.viewType + && stages == other.stages + && access == other.access; + } + + + size_t DxvkBindingInfo::hash() const { + DxvkHashState hash; + hash.add(descriptorType); + hash.add(resourceBinding); + hash.add(viewType); + hash.add(stages); + hash.add(access); + return hash; + } + + + DxvkBindingList::DxvkBindingList() { + + } + + + DxvkBindingList::~DxvkBindingList() { + + } + + + void DxvkBindingList::addBinding(const DxvkBindingInfo& binding) { + for (auto& b : m_bindings) { + if (b.canMerge(binding)) { + b.merge(binding); + return; + } + } + + m_bindings.push_back(binding); + } + + + void DxvkBindingList::merge(const DxvkBindingList& list) { + for (const auto& binding : list.m_bindings) + addBinding(binding); + } + + + bool DxvkBindingList::eq(const DxvkBindingList& other) const { + if (getBindingCount() != other.getBindingCount()) + return false; + + for (uint32_t i = 0; i < getBindingCount(); i++) { + if (!getBinding(i).eq(other.getBinding(i))) + return false; + } + + return true; + } + + + size_t DxvkBindingList::hash() const { + DxvkHashState hash; + + for (const auto& binding : m_bindings) + hash.add(binding.hash()); + + return hash; + } + + + DxvkBindingSetLayoutKey::DxvkBindingSetLayoutKey(const DxvkBindingList& list) { + m_bindings.resize(list.getBindingCount()); + + for (uint32_t i = 0; i < list.getBindingCount(); i++) { + m_bindings[i].descriptorType = list.getBinding(i).descriptorType; + m_bindings[i].stages = list.getBinding(i).stages; + } + } + + + DxvkBindingSetLayoutKey::~DxvkBindingSetLayoutKey() { + + } + + + bool DxvkBindingSetLayoutKey::eq(const DxvkBindingSetLayoutKey& other) const { + if (m_bindings.size() != other.m_bindings.size()) + return false; + + for (size_t i = 0; i < m_bindings.size(); i++) { + if (m_bindings[i].descriptorType != other.m_bindings[i].descriptorType + || m_bindings[i].stages != other.m_bindings[i].stages) + return false; + } + + return true; + } + + + size_t DxvkBindingSetLayoutKey::hash() const { + DxvkHashState hash; + + for (size_t i = 0; i < m_bindings.size(); i++) { + hash.add(m_bindings[i].descriptorType); + hash.add(m_bindings[i].stages); + } + + return hash; + } + + + DxvkBindingSetLayout::DxvkBindingSetLayout( + DxvkDevice* device, + const DxvkBindingSetLayoutKey& key) + : m_device(device) { + auto vk = m_device->vkd(); + + std::array bindingInfos; + std::array templateInfos; + + VkDescriptorSetLayoutCreateInfo layoutInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; + layoutInfo.bindingCount = key.getBindingCount(); + layoutInfo.pBindings = bindingInfos.data(); + + for (uint32_t i = 0; i < key.getBindingCount(); i++) { + auto entry = key.getBinding(i); + + VkDescriptorSetLayoutBinding& bindingInfo = bindingInfos[i]; + bindingInfo.binding = i; + bindingInfo.descriptorType = entry.descriptorType; + bindingInfo.descriptorCount = 1; + bindingInfo.stageFlags = entry.stages; + bindingInfo.pImmutableSamplers = nullptr; + + VkDescriptorUpdateTemplateEntry& templateInfo = templateInfos[i]; + templateInfo.dstBinding = i; + templateInfo.dstArrayElement = 0; + templateInfo.descriptorCount = 1; + templateInfo.descriptorType = entry.descriptorType; + templateInfo.offset = sizeof(DxvkDescriptorInfo) * i; + templateInfo.stride = sizeof(DxvkDescriptorInfo); + } + + if (vk->vkCreateDescriptorSetLayout(vk->device(), &layoutInfo, nullptr, &m_layout) != VK_SUCCESS) + throw DxvkError("DxvkBindingSetLayoutKey: Failed to create descriptor set layout"); + + if (layoutInfo.bindingCount) { + VkDescriptorUpdateTemplateCreateInfo templateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO }; + templateInfo.descriptorUpdateEntryCount = layoutInfo.bindingCount; + templateInfo.pDescriptorUpdateEntries = templateInfos.data(); + templateInfo.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET; + templateInfo.descriptorSetLayout = m_layout; + + if (vk->vkCreateDescriptorUpdateTemplate(vk->device(), &templateInfo, nullptr, &m_template) != VK_SUCCESS) + throw DxvkError("DxvkBindingLayoutObjects: Failed to create descriptor update template"); + } + } + + + DxvkBindingSetLayout::~DxvkBindingSetLayout() { + auto vk = m_device->vkd(); + + vk->vkDestroyDescriptorSetLayout(vk->device(), m_layout, nullptr); + vk->vkDestroyDescriptorUpdateTemplate(vk->device(), m_template, nullptr); + } + + + DxvkBindingLayout::DxvkBindingLayout() + : m_pushConst { 0, 0, 0 } { + + } + + + DxvkBindingLayout::~DxvkBindingLayout() { + + } + + + void DxvkBindingLayout::addBinding(const DxvkBindingInfo& binding) { + uint32_t set = binding.computeSetIndex(); + m_bindings[set].addBinding(binding); + } + + + void DxvkBindingLayout::addPushConstantRange(VkPushConstantRange range) { + uint32_t oldEnd = m_pushConst.offset + m_pushConst.size; + uint32_t newEnd = range.offset + range.size; + + m_pushConst.stageFlags |= range.stageFlags; + m_pushConst.offset = std::min(m_pushConst.offset, range.offset); + m_pushConst.size = std::max(oldEnd, newEnd) - m_pushConst.offset; + } + + + void DxvkBindingLayout::merge(const DxvkBindingLayout& layout) { + for (uint32_t i = 0; i < layout.m_bindings.size(); i++) + m_bindings[i].merge(layout.m_bindings[i]); + + addPushConstantRange(layout.m_pushConst); + } + + + bool DxvkBindingLayout::eq(const DxvkBindingLayout& other) const { + for (uint32_t i = 0; i < m_bindings.size(); i++) { + if (!m_bindings[i].eq(other.m_bindings[i])) + return false; + } + + if (m_pushConst.stageFlags != other.m_pushConst.stageFlags + || m_pushConst.offset != other.m_pushConst.offset + || m_pushConst.size != other.m_pushConst.size) + return false; + + return true; + } + + + size_t DxvkBindingLayout::hash() const { + DxvkHashState hash; + + for (uint32_t i = 0; i < m_bindings.size(); i++) + hash.add(m_bindings[i].hash()); + + hash.add(m_pushConst.stageFlags); + hash.add(m_pushConst.offset); + hash.add(m_pushConst.size); + return hash; + } + + + DxvkBindingLayoutObjects::DxvkBindingLayoutObjects( + DxvkDevice* device, + const DxvkBindingLayout& layout, + const DxvkBindingSetLayout** setObjects) + : m_device(device), m_layout(layout) { + auto vk = m_device->vkd(); + + uint32_t constId = 0; + + std::array setLayouts; + + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + m_bindingOffsets[i] = constId; + m_bindingObjects[i] = setObjects[i]; + setLayouts[i] = setObjects[i]->getSetLayout(); + + uint32_t bindingCount = m_layout.getBindingCount(i); + + for (uint32_t j = 0; j < bindingCount; j++) { + const DxvkBindingInfo& binding = m_layout.getBinding(i, j); + + DxvkBindingMapping mapping; + mapping.set = i; + mapping.binding = j; + mapping.constId = constId++; + + m_mapping.insert({ binding.resourceBinding, mapping }); + } + + if (bindingCount) + m_setMask |= 1u << i; + } + + VkPushConstantRange pushConst = m_layout.getPushConstantRange(); + + VkPipelineLayoutCreateInfo pipelineLayoutInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; + pipelineLayoutInfo.setLayoutCount = setLayouts.size(); + pipelineLayoutInfo.pSetLayouts = setLayouts.data(); + + if (pushConst.stageFlags && pushConst.size) { + pipelineLayoutInfo.pushConstantRangeCount = 1; + pipelineLayoutInfo.pPushConstantRanges = &pushConst; + } + + if (vk->vkCreatePipelineLayout(vk->device(), &pipelineLayoutInfo, nullptr, &m_pipelineLayout)) + throw DxvkError("DxvkBindingLayoutObjects: Failed to create pipeline layout"); + } + + + DxvkBindingLayoutObjects::~DxvkBindingLayoutObjects() { + auto vk = m_device->vkd(); + + vk->vkDestroyPipelineLayout(vk->device(), m_pipelineLayout, nullptr); + } + + + VkAccessFlags DxvkBindingLayoutObjects::getAccessFlags() const { + VkAccessFlags flags = 0; + + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + for (uint32_t j = 0; j < m_layout.getBindingCount(i); j++) + flags |= m_layout.getBinding(i, j).access; + } + + return flags; + } + + DxvkDescriptorSlotMapping:: DxvkDescriptorSlotMapping() { } DxvkDescriptorSlotMapping::~DxvkDescriptorSlotMapping() { } diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 9e96b34b4..ea43eb4cb 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -1,11 +1,475 @@ #pragma once +#include +#include #include +#include "dxvk_hash.h" #include "dxvk_include.h" namespace dxvk { + class DxvkDevice; + + /** + * \brief Descriptor set indices + */ + struct DxvkDescriptorSets { + static constexpr uint32_t FsViews = 0; + static constexpr uint32_t FsBuffers = 1; + static constexpr uint32_t VsAll = 2; + static constexpr uint32_t SetCount = 3; + }; + + /** + * \brief Binding info + * + * Stores metadata for a single binding in + * a given shader, or for the whole pipeline. + */ + struct DxvkBindingInfo { + VkDescriptorType descriptorType; ///< Vulkan descriptor type + uint32_t resourceBinding; ///< API binding slot for the resource + VkImageViewType viewType; ///< Image view type + VkShaderStageFlags stages; ///< Shader stage mask + VkAccessFlags access; ///< Access mask for the resource + + /** + * \brief Computes descriptor set index for the given binding + * + * This is determines based on the shader stages that use the binding. + * \returns Descriptor set index + */ + uint32_t computeSetIndex() const; + + /** + * \brief Checks whether bindings can be merged + * + * Bindings can be merged if they access the same resource with + * the same view and descriptor type and are part of the same + * descriptor set. + * \param [in] binding The binding to probe + * \returns \c true if the bindings can be merged + */ + bool canMerge(const DxvkBindingInfo& binding) const; + + /** + * \brief Merges bindings + * + * Merges the stage and access flags of two + * otherwise identical binding declarations. + * \param [in] binding The binding to merge + */ + void merge(const DxvkBindingInfo& binding); + + /** + * \brief Checks for equality + * + * \param [in] other Binding to compare to + * \returns \c true if both bindings are equal + */ + bool eq(const DxvkBindingInfo& other) const; + + /** + * \brief Hashes binding info + * \returns Binding hash + */ + size_t hash() const; + + }; + + /** + * \brief Binding list + * + * Linear structure that can be used to look + * up descriptor set objects. + */ + class DxvkBindingList { + + public: + + DxvkBindingList(); + ~DxvkBindingList(); + + /** + * \brief Number of Vulkan bindings + * \returns Binding count + */ + uint32_t getBindingCount() const { + return uint32_t(m_bindings.size()); + } + + /** + * \brief Retrieves binding info + * + * \param [in] idx Binding index + * \returns Binding info + */ + const DxvkBindingInfo& getBinding(uint32_t index) const { + return m_bindings[index]; + } + + /** + * \brief Adds a binding to the list + * \param [in] binding Binding info + */ + void addBinding(const DxvkBindingInfo& binding); + + /** + * \brief Merges binding lists + * + * Adds bindings from another list to the current list. Useful + * when creating descriptor set layouts for pipelines consisting + * of multiple shader stages. + * \param [in] layout Binding list to merge + */ + void merge(const DxvkBindingList& list); + + /** + * \brief Checks for equality + * + * \param [in] other Binding layout to compare to + * \returns \c true if both binding layouts are equal + */ + bool eq(const DxvkBindingList& other) const; + + /** + * \brief Hashes binding layout + * \returns Binding layout hash + */ + size_t hash() const; + + private: + + std::vector m_bindings; + + }; + + + /** + * \brief Binding set layout key entry + * + * Stores unique info for a single binding. + */ + struct DxvkBindingSetLayoutKeyEntry { + VkDescriptorType descriptorType; + VkShaderStageFlags stages; + }; + + + /** + * \brief Binding set layout key + * + * Stores relevant information to look + * up unique descriptor set layouts. + */ + class DxvkBindingSetLayoutKey { + + public: + + DxvkBindingSetLayoutKey(const DxvkBindingList& list); + ~DxvkBindingSetLayoutKey(); + + /** + * \brief Retrieves binding count + * \returns Binding count + */ + uint32_t getBindingCount() const { + return uint32_t(m_bindings.size()); + } + + /** + * \brief Retrieves binding info + * + * \param [in] index Binding index + * \returns Binding info + */ + DxvkBindingSetLayoutKeyEntry getBinding(uint32_t index) const { + return m_bindings[index]; + } + + /** + * \brief Checks for equality + * + * \param [in] other Binding layout to compare to + * \returns \c true if both binding layouts are equal + */ + bool eq(const DxvkBindingSetLayoutKey& other) const; + + /** + * \brief Hashes binding layout + * \returns Binding layout hash + */ + size_t hash() const; + + private: + + std::vector m_bindings; + + }; + + + /** + * \brief Binding list objects + * + * Manages a Vulkan descriptor set layout + * object for a given binding list. + */ + class DxvkBindingSetLayout { + + public: + + DxvkBindingSetLayout( + DxvkDevice* device, + const DxvkBindingSetLayoutKey& key); + + ~DxvkBindingSetLayout(); + + /** + * \brief Queries descriptor set layout + * \returns Descriptor set layout + */ + VkDescriptorSetLayout getSetLayout() const { + return m_layout; + } + + /** + * \brief Queries descriptor template + * \returns Descriptor set template + */ + VkDescriptorUpdateTemplate getSetUpdateTemplate() const { + return m_template; + } + + private: + + DxvkDevice* m_device; + VkDescriptorSetLayout m_layout = VK_NULL_HANDLE; + VkDescriptorUpdateTemplate m_template = VK_NULL_HANDLE; + + }; + + + /** + * \brief Binding layout + * + * Convenience class to map out shader bindings for use in + * descriptor set layouts and pipeline layouts. If possible, + * bindings that only differ in stage will be merged. + */ + class DxvkBindingLayout { + + public: + + DxvkBindingLayout(); + ~DxvkBindingLayout(); + + /** + * \brief Number of Vulkan bindings per set + * + * \param [in] set Descriptor set index + * \returns Binding count for the given set + */ + uint32_t getBindingCount(uint32_t set) const { + return m_bindings[set].getBindingCount(); + } + + /** + * \brief Retrieves binding info + * + * \param [in] set Descriptor set index + * \param [in] idx Binding index + * \returns Binding info + */ + const DxvkBindingInfo& getBinding(uint32_t set, uint32_t idx) const { + return m_bindings[set].getBinding(idx); + } + + /** + * \brief Retrieves binding list for a given set + * + * Use convenience methods above to gather info about + * individual descriptors. This is intended to be used + * for descriptor set lookup primarily. + */ + const DxvkBindingList& getBindingList(uint32_t set) const { + return m_bindings[set]; + } + + /** + * \brief Retrieves push constant range + * \returns Push constant range + */ + VkPushConstantRange getPushConstantRange() const { + return m_pushConst; + } + + /** + * \brief Adds a binding to the layout + * \param [in] binding Binding info + */ + void addBinding(const DxvkBindingInfo& binding); + + /** + * \brief Adds push constant range + * \param [in] range Push constant range + */ + void addPushConstantRange(VkPushConstantRange range); + + /** + * \brief Merges binding layouts + * + * Adds bindings and push constant range from another layout to + * the current layout. Useful when creating pipeline layouts and + * descriptor set layouts for pipelines consisting of multiple + * shader stages. + * \param [in] layout Binding layout to merge + */ + void merge(const DxvkBindingLayout& layout); + + /** + * \brief Checks for equality + * + * \param [in] other Binding layout to compare to + * \returns \c true if both binding layouts are equal + */ + bool eq(const DxvkBindingLayout& other) const; + + /** + * \brief Hashes binding layout + * \returns Binding layout hash + */ + size_t hash() const; + + private: + + std::array m_bindings; + VkPushConstantRange m_pushConst; + + }; + + /** + * \brief Descriptor set and binding number + */ + struct DxvkBindingMapping { + uint32_t set; + uint32_t binding; + uint32_t constId; + }; + + /** + * \brief Pipeline and descriptor set layouts for a given binding layout + * + * Creates the following Vulkan objects for a given binding layout: + * - A descriptor set layout for each required descriptor set + * - A descriptor update template for each set with non-zero binding count + * - A pipeline layout referencing all descriptor sets and the push constant ranges + */ + class DxvkBindingLayoutObjects { + + public: + + DxvkBindingLayoutObjects( + DxvkDevice* device, + const DxvkBindingLayout& layout, + const DxvkBindingSetLayout** setObjects); + + ~DxvkBindingLayoutObjects(); + + /** + * \brief Binding layout + * \returns Binding layout + */ + const DxvkBindingLayout& layout() const { + return m_layout; + } + + /** + * \brief Queries active descriptor set mask + * \returns Bit mask of non-empty descriptor sets + */ + uint32_t getSetMask() const { + return m_setMask; + } + + /** + * \brief Queries first binding number for a given set + * + * This is relevant for generating binding masks. + * \param [in] set Descriptor set index + * \returns First binding in the given set + */ + uint32_t getFirstBinding(uint32_t set) const { + return m_bindingOffsets[set]; + } + + /** + * \brief Retrieves descriptor set layout for a given set + * + * \param [in] set Descriptor set index + * \returns Vulkan descriptor set layout + */ + VkDescriptorSetLayout getSetLayout(uint32_t set) const { + return m_bindingObjects[set]->getSetLayout(); + } + + /** + * \brief Retrieves descriptor update template for a given set + * + * \param [in] set Descriptor set index + * \returns Vulkan descriptor update template + */ + VkDescriptorUpdateTemplate getSetUpdateTemplate(uint32_t set) const { + return m_bindingObjects[set]->getSetUpdateTemplate(); + } + + /** + * \brief Retrieves pipeline layout + * \returns Pipeline layout + */ + VkPipelineLayout getPipelineLayout() const { + return m_pipelineLayout; + } + + /** + * \brief Looks up set and binding number by resource binding + * + * \param [in] index Resource binding index + * \returns Descriptor set and binding number + */ + std::optional lookupBinding(uint32_t index) const { + auto entry = m_mapping.find(index); + + if (entry != m_mapping.end()) + return entry->second; + + return std::nullopt; + } + + /** + * \brief Queries accumulated resource access flags + * + * Can be used to determine whether the pipeline + * reads or writes any resources. + */ + VkAccessFlags getAccessFlags() const; + + private: + + DxvkDevice* m_device; + DxvkBindingLayout m_layout; + VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; + + uint32_t m_setMask = 0; + + std::array m_bindingObjects = { }; + std::array m_bindingOffsets = { }; + + std::unordered_map m_mapping; + + }; + + /** * \brief Resource slot * From 10eabb34dad61cf9e432288ec786e49be01212fe Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Jun 2022 19:36:58 +0200 Subject: [PATCH 0030/1348] [dxvk] Add shader stage parameter to binding methods --- src/dxvk/dxvk_context.cpp | 25 +++++++++++++++++++++++++ src/dxvk/dxvk_context.h | 19 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 7b5fe3211..2fa3011ba 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -147,6 +147,14 @@ namespace dxvk { } + void DxvkContext::bindResourceBuffer( + VkShaderStageFlags stages, + uint32_t slot, + const DxvkBufferSlice& buffer) { + bindResourceBuffer(slot, buffer); + } + + void DxvkContext::bindResourceBuffer( uint32_t slot, const DxvkBufferSlice& buffer) { @@ -171,6 +179,15 @@ namespace dxvk { } + void DxvkContext::bindResourceView( + VkShaderStageFlags stages, + uint32_t slot, + const Rc& imageView, + const Rc& bufferView) { + bindResourceView(slot, imageView, bufferView); + } + + void DxvkContext::bindResourceView( uint32_t slot, const Rc& imageView, @@ -188,6 +205,14 @@ namespace dxvk { } + void DxvkContext::bindResourceSampler( + VkShaderStageFlags stages, + uint32_t slot, + const Rc& sampler) { + bindResourceSampler(slot, sampler); + } + + void DxvkContext::bindResourceSampler( uint32_t slot, const Rc& sampler) { diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 39c5b989d..9e77003e4 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -109,9 +109,15 @@ namespace dxvk { * \brief Binds buffer as a shader resource * * Can be used for uniform and storage buffers. + * \param [in] stages Shader stages that access the binding * \param [in] slot Resource binding slot * \param [in] buffer Buffer to bind */ + void bindResourceBuffer( + VkShaderStageFlags stages, + uint32_t slot, + const DxvkBufferSlice& buffer); + void bindResourceBuffer( uint32_t slot, const DxvkBufferSlice& buffer); @@ -122,10 +128,17 @@ namespace dxvk { * Can be used for sampled images with a dedicated * sampler and for storage images, as well as for * uniform texel buffers and storage texel buffers. + * \param [in] stages Shader stages that access the binding * \param [in] slot Resource binding slot * \param [in] imageView Image view to bind * \param [in] bufferView Buffer view to bind */ + void bindResourceView( + VkShaderStageFlags stages, + uint32_t slot, + const Rc& imageView, + const Rc& bufferView); + void bindResourceView( uint32_t slot, const Rc& imageView, @@ -136,9 +149,15 @@ namespace dxvk { * * Binds a sampler that can be used together with * an image in order to read from a texture. + * \param [in] stages Shader stages that access the binding * \param [in] slot Resource binding slot * \param [in] sampler Sampler view to bind */ + void bindResourceSampler( + VkShaderStageFlags stages, + uint32_t slot, + const Rc& sampler); + void bindResourceSampler( uint32_t slot, const Rc& sampler); From fe03327ecd9ab02b4378ecc89944d5478c23ee7b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Jun 2022 19:42:46 +0200 Subject: [PATCH 0031/1348] [dxvk] Pass shader stage when binding HUD resources --- src/dxvk/dxvk_swapchain_blitter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index 2d0bc8409..37ea0e73e 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -191,11 +191,11 @@ namespace dxvk { else ctx->clearRenderTarget(dstView, VK_IMAGE_ASPECT_COLOR_BIT, VkClearValue()); - ctx->bindResourceSampler(BindingIds::Image, m_samplerPresent); - ctx->bindResourceSampler(BindingIds::Gamma, m_samplerGamma); + ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Image, m_samplerPresent); + ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Gamma, m_samplerGamma); - ctx->bindResourceView(BindingIds::Image, srcView, nullptr); - ctx->bindResourceView(BindingIds::Gamma, m_gammaView, nullptr); + ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Image, srcView, nullptr); + ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Gamma, m_gammaView, nullptr); ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_vs); ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, fs); From ce0a2f08f027e327ae7d70e3cd38e0d560c4b45a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Jun 2022 19:44:40 +0200 Subject: [PATCH 0032/1348] [hud] Pass shader stage when binding HUD shader resources --- src/dxvk/hud/dxvk_hud_renderer.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index 9ae6d3ce9..1bd8ca157 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -107,10 +107,10 @@ namespace dxvk::hud { m_context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_textShaders.vert); m_context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_textShaders.frag); - m_context->bindResourceBuffer (0, DxvkBufferSlice(m_fontBuffer)); - m_context->bindResourceView (1, nullptr, m_dataView); - m_context->bindResourceSampler(2, m_fontSampler); - m_context->bindResourceView (2, m_fontView, nullptr); + m_context->bindResourceBuffer (VK_SHADER_STAGE_VERTEX_BIT, 0, DxvkBufferSlice(m_fontBuffer)); + m_context->bindResourceView (VK_SHADER_STAGE_VERTEX_BIT, 1, nullptr, m_dataView); + m_context->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 2, m_fontSampler); + m_context->bindResourceView (VK_SHADER_STAGE_FRAGMENT_BIT, 2, m_fontView, nullptr); static const DxvkInputAssemblyState iaState = { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, @@ -129,7 +129,7 @@ namespace dxvk::hud { m_context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_graphShaders.vert); m_context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_graphShaders.frag); - m_context->bindResourceBuffer(0, DxvkBufferSlice(m_dataBuffer)); + m_context->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_dataBuffer)); static const DxvkInputAssemblyState iaState = { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, From a1bbc77c047ad700eef4add37c8d2bb91efa87f2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Jun 2022 19:37:16 +0200 Subject: [PATCH 0033/1348] [d3d11] Pass shader stage for binding resources in context methods --- src/d3d11/d3d11_context.cpp | 69 +++++++++++++++++++++++-------------- src/d3d11/d3d11_context.h | 4 +++ 2 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 23fb9e614..78e290d7f 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2282,7 +2282,7 @@ namespace dxvk { m_state.cs.unorderedAccessViews[uavId] = nullptr; m_state.cs.uavMask.clr(uavId); - BindUnorderedAccessView( + BindUnorderedAccessView( uavSlotId + uavId, nullptr, ctrSlotId + uavId, ~0u); } @@ -2303,7 +2303,7 @@ namespace dxvk { m_state.cs.unorderedAccessViews[StartSlot + i] = uav; m_state.cs.uavMask.set(StartSlot + i, uav != nullptr); - BindUnorderedAccessView( + BindUnorderedAccessView( uavSlotId + StartSlot + i, uav, ctrSlotId + StartSlot + i, ctr); @@ -2471,7 +2471,7 @@ namespace dxvk { if (m_state.ps.unorderedAccessViews[i] != uav || ctr != ~0u) { m_state.ps.unorderedAccessViews[i] = uav; - BindUnorderedAccessView( + BindUnorderedAccessView( uavSlotId + i, uav, ctrSlotId + i, ctr); @@ -3135,8 +3135,8 @@ namespace dxvk { uint32_t slotId = computeConstantBufferBinding(ShaderStage, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); - ctx->bindShader (stage, cShader); - ctx->bindResourceBuffer(slotId, cSlice); + ctx->bindShader (stage, cShader); + ctx->bindResourceBuffer(stage, slotId, cSlice); }); } @@ -3253,6 +3253,7 @@ namespace dxvk { } + template void D3D11DeviceContext::BindConstantBuffer( UINT Slot, D3D11Buffer* pBuffer, @@ -3262,11 +3263,13 @@ namespace dxvk { cSlotId = Slot, cBufferSlice = Length ? pBuffer->GetBufferSlice(16 * Offset, 16 * Length) : DxvkBufferSlice() ] (DxvkContext* ctx) { - ctx->bindResourceBuffer(cSlotId, cBufferSlice); + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceBuffer(stage, cSlotId, cBufferSlice); }); } + template void D3D11DeviceContext::BindSampler( UINT Slot, D3D11SamplerState* pSampler) { @@ -3274,11 +3277,13 @@ namespace dxvk { cSlotId = Slot, cSampler = pSampler != nullptr ? pSampler->GetDXVKSampler() : nullptr ] (DxvkContext* ctx) { - ctx->bindResourceSampler(cSlotId, cSampler); + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceSampler(stage, cSlotId, cSampler); }); } + template void D3D11DeviceContext::BindShaderResource( UINT Slot, D3D11ShaderResourceView* pResource) { @@ -3287,11 +3292,13 @@ namespace dxvk { cImageView = pResource != nullptr ? pResource->GetImageView() : nullptr, cBufferView = pResource != nullptr ? pResource->GetBufferView() : nullptr ] (DxvkContext* ctx) { - ctx->bindResourceView(cSlotId, cImageView, cBufferView); + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceView(stage, cSlotId, cImageView, cBufferView); }); } + template void D3D11DeviceContext::BindUnorderedAccessView( UINT UavSlot, D3D11UnorderedAccessView* pUav, @@ -3305,6 +3312,10 @@ namespace dxvk { cCounterSlice = pUav != nullptr ? pUav->GetCounterSlice() : DxvkBufferSlice(), cCounterValue = Counter ] (DxvkContext* ctx) { + VkShaderStageFlags stages = ShaderStage == DxbcProgramType::PixelShader + ? VK_SHADER_STAGE_ALL_GRAPHICS + : VK_SHADER_STAGE_COMPUTE_BIT; + if (cCounterSlice.defined() && cCounterValue != ~0u) { ctx->updateBuffer( cCounterSlice.buffer(), @@ -3313,8 +3324,8 @@ namespace dxvk { &cCounterValue); } - ctx->bindResourceView (cUavSlotId, cImageView, cBufferView); - ctx->bindResourceBuffer (cCtrSlotId, cCounterSlice); + ctx->bindResourceView (stages, cUavSlotId, cImageView, cBufferView); + ctx->bindResourceBuffer (stages, cCtrSlotId, cCounterSlice); }); } @@ -3871,7 +3882,7 @@ namespace dxvk { Bindings[StartSlot + i].constantCount = constantCount; Bindings[StartSlot + i].constantBound = constantCount; - BindConstantBuffer(slotId + i, newBuffer, 0, constantCount); + BindConstantBuffer(slotId + i, newBuffer, 0, constantCount); } } } @@ -3931,7 +3942,7 @@ namespace dxvk { Bindings[StartSlot + i].constantCount = constantCount; Bindings[StartSlot + i].constantBound = constantBound; - BindConstantBuffer(slotId + i, newBuffer, constantOffset, constantBound); + BindConstantBuffer(slotId + i, newBuffer, constantOffset, constantBound); } } } @@ -3950,7 +3961,7 @@ namespace dxvk { if (Bindings[StartSlot + i] != sampler) { Bindings[StartSlot + i] = sampler; - BindSampler(slotId + i, sampler); + BindSampler(slotId + i, sampler); } } } @@ -3979,7 +3990,7 @@ namespace dxvk { } Bindings.views[StartSlot + i] = resView; - BindShaderResource(slotId + i, resView); + BindShaderResource(slotId + i, resView); } } } @@ -4100,35 +4111,41 @@ namespace dxvk { // Unbind per-shader stage resources for (uint32_t i = 0; i < 6; i++) { auto programType = DxbcProgramType(i); - ctx->bindShader(GetShaderStage(programType), nullptr); + auto stage = GetShaderStage(programType); + + ctx->bindShader(stage, nullptr); // Unbind constant buffers, including the shader's ICB auto cbSlotId = computeConstantBufferBinding(programType, 0); for (uint32_t j = 0; j <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; j++) - ctx->bindResourceBuffer(cbSlotId + j, DxvkBufferSlice()); + ctx->bindResourceBuffer(stage, cbSlotId + j, DxvkBufferSlice()); // Unbind shader resource views auto srvSlotId = computeSrvBinding(programType, 0); for (uint32_t j = 0; j < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; j++) - ctx->bindResourceView(srvSlotId + j, nullptr, nullptr); + ctx->bindResourceView(stage, srvSlotId + j, nullptr, nullptr); // Unbind texture samplers auto samplerSlotId = computeSamplerBinding(programType, 0); for (uint32_t j = 0; j < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; j++) - ctx->bindResourceSampler(samplerSlotId + j, nullptr); + ctx->bindResourceSampler(stage, samplerSlotId + j, nullptr); // Unbind UAVs for supported stages if (programType == DxbcProgramType::PixelShader || programType == DxbcProgramType::ComputeShader) { + VkShaderStageFlags stages = programType == DxbcProgramType::PixelShader + ? VK_SHADER_STAGE_ALL_GRAPHICS + : VK_SHADER_STAGE_COMPUTE_BIT; + auto uavSlotId = computeUavBinding(programType, 0); auto ctrSlotId = computeUavCounterBinding(programType, 0); for (uint32_t j = 0; j < D3D11_1_UAV_SLOT_COUNT; j++) { - ctx->bindResourceView (uavSlotId, nullptr, nullptr); - ctx->bindResourceBuffer (ctrSlotId, DxvkBufferSlice()); + ctx->bindResourceView (stages, uavSlotId, nullptr, nullptr); + ctx->bindResourceBuffer (stages, ctrSlotId, DxvkBufferSlice()); } } } @@ -4206,7 +4223,7 @@ namespace dxvk { uint32_t slotId = computeConstantBufferBinding(Stage, 0); for (uint32_t i = 0; i < Bindings.size(); i++) { - BindConstantBuffer(slotId + i, Bindings[i].buffer.ptr(), + BindConstantBuffer(slotId + i, Bindings[i].buffer.ptr(), Bindings[i].constantOffset, Bindings[i].constantBound); } } @@ -4218,7 +4235,7 @@ namespace dxvk { uint32_t slotId = computeSamplerBinding(Stage, 0); for (uint32_t i = 0; i < Bindings.size(); i++) - BindSampler(slotId + i, Bindings[i]); + BindSampler(slotId + i, Bindings[i]); } @@ -4228,7 +4245,7 @@ namespace dxvk { uint32_t slotId = computeSrvBinding(Stage, 0); for (uint32_t i = 0; i < Bindings.views.size(); i++) - BindShaderResource(slotId + i, Bindings.views[i].ptr()); + BindShaderResource(slotId + i, Bindings.views[i].ptr()); } @@ -4239,7 +4256,7 @@ namespace dxvk { uint32_t ctrSlotId = computeUavCounterBinding(Stage, 0); for (uint32_t i = 0; i < Bindings.size(); i++) { - BindUnorderedAccessView( + BindUnorderedAccessView( uavSlotId + i, Bindings[i].ptr(), ctrSlotId + i, ~0u); @@ -4333,7 +4350,7 @@ namespace dxvk { Bindings.views[srvId] = nullptr; Bindings.hazardous.clr(srvId); - BindShaderResource(slotId + srvId, nullptr); + BindShaderResource(slotId + srvId, nullptr); } } else { // Avoid further redundant iterations @@ -4400,7 +4417,7 @@ namespace dxvk { if (CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr())) { m_state.ps.unorderedAccessViews[i] = nullptr; - BindUnorderedAccessView( + BindUnorderedAccessView( uavSlotId + i, nullptr, ctrSlotId + i, ~0u); } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 3bd60a578..18f277f5c 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -751,20 +751,24 @@ namespace dxvk { D3D11Buffer* pBuffer, UINT Offset); + template void BindConstantBuffer( UINT Slot, D3D11Buffer* pBuffer, UINT Offset, UINT Length); + template void BindSampler( UINT Slot, D3D11SamplerState* pSampler); + template void BindShaderResource( UINT Slot, D3D11ShaderResourceView* pResource); + template void BindUnorderedAccessView( UINT UavSlot, D3D11UnorderedAccessView* pUav, From d05864cbcbeaeeec75e05e3745f6ef6845f807b7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Jun 2022 19:40:47 +0200 Subject: [PATCH 0034/1348] [d3d11] Pass shader stage for binding video processor resources --- src/d3d11/d3d11_video.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 9ad9c6a8e..ccf08c1ac 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1199,7 +1199,7 @@ namespace dxvk { ctx->bindRenderTargets(rt); ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_vs); ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_fs); - ctx->bindResourceBuffer(0, DxvkBufferSlice(m_ubo)); + ctx->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo)); DxvkInputAssemblyState iaState; iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; @@ -1292,10 +1292,10 @@ namespace dxvk { ctx->invalidateBuffer(m_ubo, uboSlice); ctx->setViewports(1, &viewport, &scissor); - ctx->bindResourceSampler(1, m_sampler); + ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 1, m_sampler); for (uint32_t i = 0; i < cViews.size(); i++) - ctx->bindResourceView(2 + i, cViews[i], nullptr); + ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, 2 + i, cViews[i], nullptr); ctx->draw(3, 1, 0, 0); }); From 0fb1227792771862cc86dc729e182ec4a6cd6181 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Jun 2022 19:46:55 +0200 Subject: [PATCH 0035/1348] [d3d9] Pass shader stage when binding format conversion resources --- src/d3d9/d3d9_format_helpers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_format_helpers.cpp b/src/d3d9/d3d9_format_helpers.cpp index e528f90cf..09034bb25 100644 --- a/src/d3d9/d3d9_format_helpers.cpp +++ b/src/d3d9/d3d9_format_helpers.cpp @@ -96,8 +96,8 @@ namespace dxvk { if (specConstantValue) m_context->setSpecConstant(VK_PIPELINE_BIND_POINT_COMPUTE, 0, specConstantValue); - m_context->bindResourceView(BindingIds::Image, tmpImageView, nullptr); - m_context->bindResourceView(BindingIds::Buffer, nullptr, tmpBufferView); + m_context->bindResourceView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Image, tmpImageView, nullptr); + m_context->bindResourceView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Buffer, nullptr, tmpBufferView); m_context->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, m_shaders[videoFormat.FormatType]); m_context->pushConstants(0, sizeof(VkExtent2D), &imageExtent); m_context->dispatch( From 4cc559d69082d511641b5218afd3b4502773d025 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Jun 2022 19:56:12 +0200 Subject: [PATCH 0036/1348] [d3d9] Pass shader stage when binding shader resources --- src/d3d9/d3d9_device.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 9dedb8041..4b9a74224 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2653,11 +2653,11 @@ namespace dxvk { ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, nullptr); ctx->bindShader(VK_SHADER_STAGE_GEOMETRY_BIT, shader); - ctx->bindResourceBuffer(getSWVPBufferSlot(), cBufferSlice); + ctx->bindResourceBuffer(VK_SHADER_STAGE_GEOMETRY_BIT, getSWVPBufferSlot(), cBufferSlice); ctx->draw( drawInfo.vertexCount, drawInfo.instanceCount, cStartIndex, 0); - ctx->bindResourceBuffer(getSWVPBufferSlot(), DxvkBufferSlice()); + ctx->bindResourceBuffer(VK_SHADER_STAGE_GEOMETRY_BIT, getSWVPBufferSlot(), DxvkBufferSlice()); ctx->bindShader(VK_SHADER_STAGE_GEOMETRY_BIT, nullptr); }); @@ -4889,10 +4889,11 @@ namespace dxvk { BufferType); EmitCs([ - cSlotId = slotId, - cBuffer = buffer + cShaderStage = GetShaderStage(ShaderStage), + cSlotId = slotId, + cBuffer = buffer ] (DxvkContext* ctx) { - ctx->bindResourceBuffer(cSlotId, + ctx->bindResourceBuffer(cShaderStage, cSlotId, DxvkBufferSlice(cBuffer, 0, cBuffer->info().size)); }); @@ -5072,7 +5073,9 @@ namespace dxvk { cSlotId = slotId, cSize = bufferSize ] (DxvkContext* ctx) { - ctx->bindResourceBuffer(cSlotId, + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + + ctx->bindResourceBuffer(stage, cSlotId, DxvkBufferSlice(cBuffer, 0, cSize)); }); boundConstantBufferSize = bufferSize; @@ -5929,9 +5932,11 @@ namespace dxvk { cSlot = slot, cKey = key ] (DxvkContext* ctx) { + VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; + auto pair = m_samplers.find(cKey); if (pair != m_samplers.end()) { - ctx->bindResourceSampler(cSlot, pair->second); + ctx->bindResourceSampler(stage, cSlot, pair->second); return; } @@ -5971,7 +5976,7 @@ namespace dxvk { auto sampler = m_dxvkDevice->createSampler(info); m_samplers.insert(std::make_pair(cKey, sampler)); - ctx->bindResourceSampler(cSlot, std::move(sampler)); + ctx->bindResourceSampler(stage, cSlot, std::move(sampler)); m_samplerCount++; } @@ -5998,7 +6003,8 @@ namespace dxvk { cSlot = slot, cImageView = commonTex->GetSampleView(srgb) ](DxvkContext* ctx) { - ctx->bindResourceView(cSlot, cImageView, nullptr); + VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; + ctx->bindResourceView(stage, cSlot, cImageView, nullptr); }); } @@ -6013,7 +6019,8 @@ namespace dxvk { uint32_t slot = computeResourceSlotId(shaderSampler.first, DxsoBindingType::Image, uint32_t(shaderSampler.second)); - ctx->bindResourceView(slot, nullptr, nullptr); + VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; + ctx->bindResourceView(stage, slot, nullptr, nullptr); } }); } @@ -7251,10 +7258,12 @@ namespace dxvk { EmitCs([ cSize = m_state.textures.size() ](DxvkContext* ctx) { + VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; + for (uint32_t i = 0; i < cSize; i++) { auto samplerInfo = RemapStateSamplerShader(DWORD(i)); uint32_t slot = computeResourceSlotId(samplerInfo.first, DxsoBindingType::Image, uint32_t(samplerInfo.second)); - ctx->bindResourceView(slot, nullptr, nullptr); + ctx->bindResourceView(stage, slot, nullptr, nullptr); } }); From 53519e2bd5dcfce3418a57a6dd4f7ffdc1319939 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Jun 2022 20:04:12 +0200 Subject: [PATCH 0037/1348] [dxvk] Remove old resource binding methods --- src/dxvk/dxvk_context.cpp | 22 ---------------------- src/dxvk/dxvk_context.h | 13 ------------- 2 files changed, 35 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 2fa3011ba..2d78c9078 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -151,13 +151,6 @@ namespace dxvk { VkShaderStageFlags stages, uint32_t slot, const DxvkBufferSlice& buffer) { - bindResourceBuffer(slot, buffer); - } - - - void DxvkContext::bindResourceBuffer( - uint32_t slot, - const DxvkBufferSlice& buffer) { bool needsUpdate = !m_rc[slot].bufferSlice.matchesBuffer(buffer); if (likely(needsUpdate)) @@ -184,14 +177,6 @@ namespace dxvk { uint32_t slot, const Rc& imageView, const Rc& bufferView) { - bindResourceView(slot, imageView, bufferView); - } - - - void DxvkContext::bindResourceView( - uint32_t slot, - const Rc& imageView, - const Rc& bufferView) { m_rc[slot].imageView = imageView; m_rc[slot].bufferView = bufferView; m_rc[slot].bufferSlice = bufferView != nullptr @@ -209,13 +194,6 @@ namespace dxvk { VkShaderStageFlags stages, uint32_t slot, const Rc& sampler) { - bindResourceSampler(slot, sampler); - } - - - void DxvkContext::bindResourceSampler( - uint32_t slot, - const Rc& sampler) { m_rc[slot].sampler = sampler; m_rcTracked.clr(slot); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 9e77003e4..5cda9248a 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -118,10 +118,6 @@ namespace dxvk { uint32_t slot, const DxvkBufferSlice& buffer); - void bindResourceBuffer( - uint32_t slot, - const DxvkBufferSlice& buffer); - /** * \brief Binds image or buffer view * @@ -139,11 +135,6 @@ namespace dxvk { const Rc& imageView, const Rc& bufferView); - void bindResourceView( - uint32_t slot, - const Rc& imageView, - const Rc& bufferView); - /** * \brief Binds image sampler * @@ -158,10 +149,6 @@ namespace dxvk { uint32_t slot, const Rc& sampler); - void bindResourceSampler( - uint32_t slot, - const Rc& sampler); - /** * \brief Binds a shader to a given state * From 70a95d9085ccc81277ab04e63a7cf53482d3bca4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 3 Jun 2022 17:43:54 +0200 Subject: [PATCH 0038/1348] [dxvk] Add DxvkBindingLayout to DxvkShader class Supposed to replace the old descriptor model eventually. --- src/dxvk/dxvk_shader.cpp | 16 ++++++++++++++++ src/dxvk/dxvk_shader.h | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 2d9793f45..b543d201b 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -66,6 +66,7 @@ namespace dxvk { : m_info(info), m_code(spirv) { m_info.resourceSlots = nullptr; m_info.uniformData = nullptr; + m_info.bindings = nullptr; // Copy resource binding slot infos if (info.resourceSlotCount) { @@ -75,6 +76,21 @@ namespace dxvk { m_info.resourceSlots = m_slots.data(); } + for (uint32_t i = 0; i < info.bindingCount; i++) { + DxvkBindingInfo binding = info.bindings[i]; + binding.stages = info.stage; + m_bindings.addBinding(binding); + } + + if (info.pushConstSize) { + VkPushConstantRange pushConst; + pushConst.stageFlags = info.stage; + pushConst.offset = info.pushConstOffset; + pushConst.size = info.pushConstSize; + + m_bindings.addPushConstantRange(pushConst); + } + // Copy uniform buffer data if (info.uniformSize) { m_uniformData.resize(info.uniformSize); diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 0be8b496b..9f9c7d3e0 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -58,6 +58,8 @@ namespace dxvk { /// Descriptor info uint32_t resourceSlotCount = 0; const DxvkResourceSlot* resourceSlots = nullptr; + uint32_t bindingCount = 0; + const DxvkBindingInfo* bindings = nullptr; /// Input and output register mask uint32_t inputMask = 0; uint32_t outputMask = 0; @@ -116,6 +118,14 @@ namespace dxvk { DxvkShaderFlags flags() const { return m_flags; } + + /** + * \brief Retrieves binding layout + * \returns Binding layout + */ + const DxvkBindingLayout& getBindings() const { + return m_bindings; + } /** * \brief Adds resource slots definitions to a mapping @@ -214,6 +224,8 @@ namespace dxvk { std::vector m_uniformData; std::vector m_idOffsets; + DxvkBindingLayout m_bindings; + static void eliminateInput(SpirvCodeBuffer& code, uint32_t location); }; From 89dadc84534b8c4bd3f220a3383ac8683ac9e25e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 15 Jun 2022 17:03:55 +0200 Subject: [PATCH 0039/1348] [dxvk] Pass new shader binding info struct to swapchain blit shaders --- src/dxvk/dxvk_swapchain_blitter.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index 37ea0e73e..9ff2069d7 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -317,7 +317,12 @@ namespace dxvk { SpirvCodeBuffer fsCodeCopy(dxvk_present_frag); SpirvCodeBuffer fsCodeResolve(dxvk_present_frag_ms); SpirvCodeBuffer fsCodeResolveAmd(dxvk_present_frag_ms_amd); - + + const std::array fsBindings = {{ + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, BindingIds::Image, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, BindingIds::Gamma, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_READ_BIT }, + }}; + const std::array fsResourceSlots = {{ { BindingIds::Image, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_IMAGE_VIEW_TYPE_2D }, { BindingIds::Gamma, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_IMAGE_VIEW_TYPE_1D }, @@ -330,6 +335,8 @@ namespace dxvk { DxvkShaderCreateInfo fsInfo; fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + fsInfo.bindingCount = fsBindings.size(); + fsInfo.bindings = fsBindings.data(); fsInfo.resourceSlotCount = fsResourceSlots.size(); fsInfo.resourceSlots = fsResourceSlots.data(); fsInfo.pushConstSize = sizeof(PresenterArgs); From 7b8b50bca6b8ee8ac1f9bd82aa3cbe9551ff66f2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 15 Jun 2022 17:07:22 +0200 Subject: [PATCH 0040/1348] [hud] Pass new shader binding info struct to HUD shaders --- src/dxvk/hud/dxvk_hud_renderer.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index 1bd8ca157..167cf3c8a 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -159,6 +159,15 @@ namespace dxvk::hud { SpirvCodeBuffer vsCode(hud_text_vert); SpirvCodeBuffer fsCode(hud_text_frag); + const std::array vsBindings = {{ + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_SHADER_READ_BIT }, + }}; + + const std::array fsBindings = {{ + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_SHADER_READ_BIT }, + }}; + const std::array vsResources = {{ { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM }, { 1, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM }, @@ -170,6 +179,8 @@ namespace dxvk::hud { DxvkShaderCreateInfo vsInfo; vsInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; + vsInfo.bindingCount = vsBindings.size(); + vsInfo.bindings = vsBindings.data(); vsInfo.resourceSlotCount = vsResources.size(); vsInfo.resourceSlots = vsResources.data(); vsInfo.outputMask = 0x3; @@ -178,6 +189,8 @@ namespace dxvk::hud { DxvkShaderCreateInfo fsInfo; fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + fsInfo.bindingCount = fsBindings.size(); + fsInfo.bindings = fsBindings.data(); fsInfo.resourceSlotCount = fsResources.size(); fsInfo.resourceSlots = fsResources.data(); fsInfo.inputMask = 0x3; @@ -194,6 +207,10 @@ namespace dxvk::hud { SpirvCodeBuffer vsCode(hud_graph_vert); SpirvCodeBuffer fsCode(hud_graph_frag); + const std::array fsBindings = {{ + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_SHADER_READ_BIT }, + }}; + const std::array fsResources = {{ { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM }, }}; @@ -206,6 +223,8 @@ namespace dxvk::hud { DxvkShaderCreateInfo fsInfo; fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + fsInfo.bindingCount = fsBindings.size(); + fsInfo.bindings = fsBindings.data(); fsInfo.resourceSlotCount = fsResources.size(); fsInfo.resourceSlots = fsResources.data(); fsInfo.inputMask = 0x1; From 5edd8e92a8effe75e92a550de9f816ab23de9815 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 21 Jun 2022 11:05:09 +0200 Subject: [PATCH 0041/1348] [d3d9] Pass new binding info struct to various helper shaders --- src/d3d9/d3d9_format_helpers.cpp | 7 +++++++ src/d3d9/d3d9_swvp_emu.cpp | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/src/d3d9/d3d9_format_helpers.cpp b/src/d3d9/d3d9_format_helpers.cpp index 09034bb25..2615aa49a 100644 --- a/src/d3d9/d3d9_format_helpers.cpp +++ b/src/d3d9/d3d9_format_helpers.cpp @@ -125,6 +125,11 @@ namespace dxvk { Rc D3D9FormatHelper::InitShader(SpirvCodeBuffer code) { + const std::array bindings = { { + { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, BindingIds::Image, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_WRITE_BIT }, + { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, BindingIds::Buffer, VK_IMAGE_VIEW_TYPE_1D, 0, VK_ACCESS_SHADER_READ_BIT }, + } }; + const std::array resourceSlots = { { { BindingIds::Image, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_IMAGE_VIEW_TYPE_2D }, { BindingIds::Buffer, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, VK_IMAGE_VIEW_TYPE_1D }, @@ -132,6 +137,8 @@ namespace dxvk { DxvkShaderCreateInfo info; info.stage = VK_SHADER_STAGE_COMPUTE_BIT; + info.bindingCount = bindings.size(); + info.bindings = bindings.data(); info.resourceSlotCount = resourceSlots.size(); info.resourceSlots = resourceSlots.data(); info.pushConstOffset = 0; diff --git a/src/d3d9/d3d9_swvp_emu.cpp b/src/d3d9/d3d9_swvp_emu.cpp index 40a38fdc4..226191cba 100644 --- a/src/d3d9/d3d9_swvp_emu.cpp +++ b/src/d3d9/d3d9_swvp_emu.cpp @@ -130,6 +130,12 @@ namespace dxvk { m_module.decorateDescriptorSet(buffer, 0); m_module.decorateBinding(buffer, bufferSlot); + m_bufferBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + m_bufferBinding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + m_bufferBinding.resourceBinding = bufferSlot; + m_bufferBinding.access = VK_ACCESS_SHADER_WRITE_BIT; + m_bufferBinding.stages = 0; + m_bufferResource.slot = bufferSlot; m_bufferResource.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; m_bufferResource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; @@ -283,6 +289,8 @@ namespace dxvk { DxvkShaderCreateInfo info; info.stage = VK_SHADER_STAGE_GEOMETRY_BIT; + info.bindingCount = 1; + info.bindings = &m_bufferBinding; info.resourceSlotCount = 1; info.resourceSlots = &m_bufferResource; info.inputMask = m_inputMask; @@ -297,6 +305,7 @@ namespace dxvk { std::vector m_entryPointInterfaces; uint32_t m_entryPointId = 0; uint32_t m_inputMask = 0u; + DxvkBindingInfo m_bufferBinding; DxvkResourceSlot m_bufferResource; }; From ecbada30f5c7955f795a4c8127f7fa88c84bf6cb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 21 Jun 2022 11:12:51 +0200 Subject: [PATCH 0042/1348] [d3d9] Pass new binding info struct to fixed-function shaders --- src/d3d9/d3d9_fixed_function.cpp | 42 +++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 37f6e1ab5..d73e098f3 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -604,6 +604,8 @@ namespace dxvk { SpirvModule m_module; std::vector m_resourceSlots; + std::vector + m_bindings; std::vector m_entryPointInterfaces; uint32_t m_inputMask = 0u; @@ -713,6 +715,8 @@ namespace dxvk { // Create the shader module object DxvkShaderCreateInfo info; info.stage = isVS() ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT; + info.bindingCount = m_bindings.size(); + info.bindings = m_bindings.data(); info.resourceSlotCount = m_resourceSlots.size(); info.resourceSlots = m_resourceSlots.data(); info.inputMask = m_inputMask; @@ -1392,6 +1396,12 @@ namespace dxvk { resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; resource.access = VK_ACCESS_UNIFORM_READ_BIT; m_resourceSlots.push_back(resource); + + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; + binding.resourceBinding = bindingId; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = VK_ACCESS_UNIFORM_READ_BIT; + m_bindings.push_back(binding); } @@ -1432,6 +1442,12 @@ namespace dxvk { resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; resource.access = VK_ACCESS_SHADER_READ_BIT; m_resourceSlots.push_back(resource); + + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER }; + binding.resourceBinding = bindingId; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = VK_ACCESS_SHADER_READ_BIT; + m_bindings.push_back(binding); } @@ -2040,6 +2056,12 @@ namespace dxvk { resource.access = VK_ACCESS_UNIFORM_READ_BIT; m_resourceSlots.push_back(resource); + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; + binding.resourceBinding = bindingId; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = VK_ACCESS_UNIFORM_READ_BIT; + m_bindings.push_back(binding); + // Load constants auto LoadConstant = [&](uint32_t type, uint32_t idx) { uint32_t offset = m_module.constu32(idx); @@ -2111,6 +2133,12 @@ namespace dxvk { resource.view = viewType; resource.access = VK_ACCESS_SHADER_READ_BIT; m_resourceSlots.push_back(resource); + + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER }; + binding.resourceBinding = bindingId; + binding.viewType = viewType; + binding.access = VK_ACCESS_SHADER_READ_BIT; + m_bindings.push_back(binding); } emitPsSharedConstants(); @@ -2133,6 +2161,12 @@ namespace dxvk { resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; resource.access = VK_ACCESS_UNIFORM_READ_BIT; m_resourceSlots.push_back(resource); + + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; + binding.resourceBinding = bindingId; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = VK_ACCESS_UNIFORM_READ_BIT; + m_bindings.push_back(binding); } @@ -2173,7 +2207,13 @@ namespace dxvk { resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; resource.access = VK_ACCESS_UNIFORM_READ_BIT; m_resourceSlots.push_back(resource); - + + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; + binding.resourceBinding = bindingId; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = VK_ACCESS_UNIFORM_READ_BIT; + m_bindings.push_back(binding); + // Declare output array for clip distances uint32_t clipDistArray = m_module.newVar( m_module.defPointerType( From e795f3f33aa0854a05e1d32780172f593d04db88 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 21 Jun 2022 11:19:52 +0200 Subject: [PATCH 0043/1348] [dxso] Pass new binding info struct to shaders --- src/dxso/dxso_compiler.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/dxso/dxso_compiler.h | 1 + 2 files changed, 38 insertions(+) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index b68608a00..372e89b54 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -248,6 +248,8 @@ namespace dxvk { Rc DxsoCompiler::compileShader() { DxvkShaderCreateInfo info; info.stage = m_programInfo.shaderStage(); + info.bindingCount = m_bindings.size(); + info.bindings = m_bindings.data(); info.resourceSlotCount = m_resourceSlots.size(); info.resourceSlots = m_resourceSlots.data(); info.inputMask = m_inputMask; @@ -337,6 +339,12 @@ namespace dxvk { resource.access = VK_ACCESS_UNIFORM_READ_BIT; m_resourceSlots.push_back(resource); + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; + binding.resourceBinding = bindingId; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = VK_ACCESS_UNIFORM_READ_BIT; + m_bindings.push_back(binding); + m_boolSpecConstant = m_module.specConst32(m_module.defIntType(32, 0), 0); m_module.decorateSpecId(m_boolSpecConstant, getSpecId( m_programInfo.type() == DxsoProgramType::VertexShader @@ -433,6 +441,17 @@ namespace dxvk { resource.access = asSsbo ? VK_ACCESS_MEMORY_READ_BIT : VK_ACCESS_UNIFORM_READ_BIT; m_resourceSlots.push_back(resource); + DxvkBindingInfo binding = { }; + binding.descriptorType = asSsbo + ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER + : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + binding.resourceBinding = bindingId; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = asSsbo + ? VK_ACCESS_SHADER_READ_BIT + : VK_ACCESS_UNIFORM_READ_BIT; + m_bindings.push_back(binding); + return constantBufferId; } @@ -516,6 +535,12 @@ namespace dxvk { resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; resource.access = VK_ACCESS_UNIFORM_READ_BIT; m_resourceSlots.push_back(resource); + + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; + binding.resourceBinding = bindingId; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = VK_ACCESS_UNIFORM_READ_BIT; + m_bindings.push_back(binding); } @@ -858,6 +883,12 @@ namespace dxvk { resource.view = implicit ? VK_IMAGE_VIEW_TYPE_MAX_ENUM : viewType; resource.access = VK_ACCESS_SHADER_READ_BIT; m_resourceSlots.push_back(resource); + + DxvkBindingInfo bindingInfo = { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER }; + bindingInfo.resourceBinding = binding; + bindingInfo.viewType = implicit ? VK_IMAGE_VIEW_TYPE_MAX_ENUM : viewType; + bindingInfo.access = VK_ACCESS_SHADER_READ_BIT; + m_bindings.push_back(bindingInfo); } @@ -3659,6 +3690,12 @@ void DxsoCompiler::emitControlFlowGenericLoop( resource.access = VK_ACCESS_UNIFORM_READ_BIT; m_resourceSlots.push_back(resource); + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; + binding.resourceBinding = bindingId; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = VK_ACCESS_UNIFORM_READ_BIT; + m_bindings.push_back(binding); + // Declare output array for clip distances uint32_t clipDistArray = m_module.newVar( m_module.defPointerType( diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h index f26732f45..9b46334aa 100644 --- a/src/dxso/dxso_compiler.h +++ b/src/dxso/dxso_compiler.h @@ -278,6 +278,7 @@ namespace dxvk { // Resource slot description for the shader. This will // be used to map D3D9 bindings to DXVK bindings. std::vector m_resourceSlots; + std::vector m_bindings; //////////////////////////////////////////////// // Temporary r# vector registers with immediate From cb57c2f7fb7be7013ce001fda848cd0f3a122f12 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 15 Jun 2022 17:00:32 +0200 Subject: [PATCH 0044/1348] [d3d11] Pass new binding info struct to video processor shader --- src/d3d11/d3d11_video.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index ccf08c1ac..47a84bd0e 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -329,6 +329,13 @@ namespace dxvk { SpirvCodeBuffer vsCode(d3d11_video_blit_vert); SpirvCodeBuffer fsCode(d3d11_video_blit_frag); + const std::array fsBindings = {{ + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_UNIFORM_READ_BIT }, + { VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, 0 }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_READ_BIT }, + }}; + const std::array fsResourceSlots = {{ { 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC }, { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, @@ -343,6 +350,8 @@ namespace dxvk { DxvkShaderCreateInfo fsInfo; fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + fsInfo.bindingCount = fsBindings.size(); + fsInfo.bindings = fsBindings.data(); fsInfo.resourceSlotCount = fsResourceSlots.size(); fsInfo.resourceSlots = fsResourceSlots.data(); fsInfo.inputMask = 0x1; From 79ecd4e94a3cbf2bb37d439028df190df2d32afe Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 7 Jun 2022 10:44:56 +0200 Subject: [PATCH 0045/1348] [dxbc] Pass new binding info struct to shaders --- src/dxbc/dxbc_compiler.cpp | 73 ++++++++++++++++++++++++++++++++------ src/dxbc/dxbc_compiler.h | 1 + 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 01420c043..e669356a6 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -253,6 +253,8 @@ namespace dxvk { info.stage = m_programInfo.shaderStage(); info.resourceSlotCount = m_resourceSlots.size(); info.resourceSlots = m_resourceSlots.data(); + info.bindingCount = m_bindings.size(); + info.bindings = m_bindings.data(); info.inputMask = m_inputMask; info.outputMask = m_outputMask; info.uniformSize = m_immConstData.size(); @@ -834,14 +836,22 @@ namespace dxvk { m_constantBuffers.at(regIdx) = buf; // Store descriptor info for the shader interface - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = asSsbo + VkDescriptorType descriptorType = asSsbo ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + + DxvkResourceSlot resource; + resource.slot = bindingId; + resource.type = descriptorType; resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; resource.access = VK_ACCESS_UNIFORM_READ_BIT; m_resourceSlots.push_back(resource); + + DxvkBindingInfo binding = { descriptorType }; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = VK_ACCESS_UNIFORM_READ_BIT; + binding.resourceBinding = bindingId; + m_bindings.push_back(binding); } @@ -879,6 +889,11 @@ namespace dxvk { resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; resource.access = 0; m_resourceSlots.push_back(resource); + + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_SAMPLER }; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.resourceBinding = bindingId; + m_bindings.push_back(binding); } @@ -1064,11 +1079,6 @@ namespace dxvk { ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; resource.access = m_analysis->uavInfos[registerId].accessFlags; - - if (!(resource.access & VK_ACCESS_SHADER_WRITE_BIT)) - m_module.decorate(varId, spv::DecorationNonWritable); - if (!(resource.access & VK_ACCESS_SHADER_READ_BIT)) - m_module.decorate(varId, spv::DecorationNonReadable); } else { resource.type = resourceType == DxbcResourceDim::Buffer ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER @@ -1077,6 +1087,29 @@ namespace dxvk { } m_resourceSlots.push_back(resource); + + DxvkBindingInfo binding = { }; + binding.viewType = typeInfo.vtype; + binding.resourceBinding = bindingId; + + if (isUav) { + binding.descriptorType = resourceType == DxbcResourceDim::Buffer + ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER + : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + binding.access = m_analysis->uavInfos[registerId].accessFlags; + + if (!(binding.access & VK_ACCESS_SHADER_WRITE_BIT)) + m_module.decorate(varId, spv::DecorationNonWritable); + if (!(binding.access & VK_ACCESS_SHADER_READ_BIT)) + m_module.decorate(varId, spv::DecorationNonReadable); + } else { + binding.descriptorType = resourceType == DxbcResourceDim::Buffer + ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER + : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + binding.access = VK_ACCESS_SHADER_READ_BIT; + } + + m_bindings.push_back(binding); } @@ -1214,14 +1247,26 @@ namespace dxvk { ? m_analysis->uavInfos[registerId].accessFlags : VK_ACCESS_SHADER_READ_BIT; + m_resourceSlots.push_back(resource); + + DxvkBindingInfo binding = { }; + binding.descriptorType = useRawSsbo + ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER + : (isUav ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER); + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.resourceBinding = bindingId; + binding.access = isUav + ? m_analysis->uavInfos[registerId].accessFlags + : VK_ACCESS_SHADER_READ_BIT; + if (useRawSsbo || isUav) { - if (!(resource.access & VK_ACCESS_SHADER_WRITE_BIT)) + if (!(binding.access & VK_ACCESS_SHADER_WRITE_BIT)) m_module.decorate(varId, spv::DecorationNonWritable); - if (!(resource.access & VK_ACCESS_SHADER_READ_BIT)) + if (!(binding.access & VK_ACCESS_SHADER_READ_BIT)) m_module.decorate(varId, spv::DecorationNonReadable); } - m_resourceSlots.push_back(resource); + m_bindings.push_back(binding); } @@ -1461,6 +1506,12 @@ namespace dxvk { | VK_ACCESS_SHADER_WRITE_BIT; m_resourceSlots.push_back(resource); + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER }; + binding.resourceBinding = bindingId; + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; + m_bindings.push_back(binding); + return varId; } diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 2216642ca..9208ddbbb 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -425,6 +425,7 @@ namespace dxvk { // Resource slot description for the shader. This will // be used to map D3D11 bindings to DXVK bindings. std::vector m_resourceSlots; + std::vector m_bindings; //////////////////////////////////////////////// // Temporary r# vector registers with immediate From ec5ea71174f3c826e9a5a1a906d35e778a29a22b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 13 Jun 2022 16:58:32 +0200 Subject: [PATCH 0046/1348] [dxvk] Store and create pipeline layout objects in pipeline manager This should help avoid a lot of duplication. --- src/dxvk/dxvk_compute.cpp | 5 +-- src/dxvk/dxvk_compute.h | 16 +++++++++- src/dxvk/dxvk_graphics.cpp | 5 +-- src/dxvk/dxvk_graphics.h | 16 +++++++++- src/dxvk/dxvk_pipemanager.cpp | 60 ++++++++++++++++++++++++++++++++--- src/dxvk/dxvk_pipemanager.h | 18 ++++++++++- 6 files changed, 109 insertions(+), 11 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 4e0609081..7dba4f99a 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -12,9 +12,10 @@ namespace dxvk { DxvkComputePipeline::DxvkComputePipeline( DxvkPipelineManager* pipeMgr, - DxvkComputePipelineShaders shaders) + DxvkComputePipelineShaders shaders, + DxvkBindingLayoutObjects* layout) : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), - m_shaders(std::move(shaders)) { + m_shaders(std::move(shaders)), m_bindings(layout) { m_shaders.cs->defineResourceSlots(m_slotMapping); m_slotMapping.makeDescriptorsDynamic( diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index 186d17ef1..74fd778e5 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -91,7 +91,8 @@ namespace dxvk { DxvkComputePipeline( DxvkPipelineManager* pipeMgr, - DxvkComputePipelineShaders shaders); + DxvkComputePipelineShaders shaders, + DxvkBindingLayoutObjects* layout); ~DxvkComputePipeline(); @@ -114,6 +115,18 @@ namespace dxvk { DxvkPipelineLayout* layout() const { return m_layout.ptr(); } + + /** + * \brief Pipeline layout + * + * Stores the pipeline layout and the descriptor set + * layouts, as well as information on the resource + * slots used by the pipeline. + * \returns Pipeline layout + */ + DxvkBindingLayoutObjects* getBindings() const { + return m_bindings; + } /** * \brief Retrieves pipeline handle @@ -142,6 +155,7 @@ namespace dxvk { DxvkComputePipelineShaders m_shaders; DxvkDescriptorSlotMapping m_slotMapping; + DxvkBindingLayoutObjects* m_bindings; Rc m_layout; alignas(CACHE_LINE_SIZE) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 66c4131ec..1b1b9f7df 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -10,9 +10,10 @@ namespace dxvk { DxvkGraphicsPipeline::DxvkGraphicsPipeline( DxvkPipelineManager* pipeMgr, - DxvkGraphicsPipelineShaders shaders) + DxvkGraphicsPipelineShaders shaders, + DxvkBindingLayoutObjects* layout) : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), - m_shaders(std::move(shaders)) { + m_shaders(std::move(shaders)), m_bindings(layout) { if (m_shaders.vs != nullptr) m_shaders.vs ->defineResourceSlots(m_slotMapping); if (m_shaders.tcs != nullptr) m_shaders.tcs->defineResourceSlots(m_slotMapping); if (m_shaders.tes != nullptr) m_shaders.tes->defineResourceSlots(m_slotMapping); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 50d16b1ef..1136a06d8 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -149,7 +149,8 @@ namespace dxvk { DxvkGraphicsPipeline( DxvkPipelineManager* pipeMgr, - DxvkGraphicsPipelineShaders shaders); + DxvkGraphicsPipelineShaders shaders, + DxvkBindingLayoutObjects* layout); ~DxvkGraphicsPipeline(); @@ -181,6 +182,18 @@ namespace dxvk { return m_layout.ptr(); } + /** + * \brief Pipeline layout + * + * Stores the pipeline layout and the descriptor set + * layout, as well as information on the resource + * slots used by the pipeline. + * \returns Pipeline layout + */ + DxvkBindingLayoutObjects* getBindings() const { + return m_bindings; + } + /** * \brief Queries shader for a given stage * @@ -225,6 +238,7 @@ namespace dxvk { DxvkGraphicsPipelineShaders m_shaders; DxvkDescriptorSlotMapping m_slotMapping; + DxvkBindingLayoutObjects* m_bindings; Rc m_layout; uint32_t m_vsIn = 0; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 4c5ea32fb..3f0120ccf 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -31,11 +31,13 @@ namespace dxvk { auto pair = m_computePipelines.find(shaders); if (pair != m_computePipelines.end()) return &pair->second; - + + auto layout = createPipelineLayout(shaders.cs->getBindings()); + auto iter = m_computePipelines.emplace( std::piecewise_construct, std::tuple(shaders), - std::tuple(this, shaders)); + std::tuple(this, shaders, layout)); return &iter.first->second; } @@ -50,11 +52,28 @@ namespace dxvk { auto pair = m_graphicsPipelines.find(shaders); if (pair != m_graphicsPipelines.end()) return &pair->second; - + + DxvkBindingLayout mergedLayout; + mergedLayout.merge(shaders.vs->getBindings()); + + if (shaders.tcs != nullptr) + mergedLayout.merge(shaders.tcs->getBindings()); + + if (shaders.tes != nullptr) + mergedLayout.merge(shaders.tes->getBindings()); + + if (shaders.gs != nullptr) + mergedLayout.merge(shaders.gs->getBindings()); + + if (shaders.fs != nullptr) + mergedLayout.merge(shaders.fs->getBindings()); + + auto layout = createPipelineLayout(mergedLayout); + auto iter = m_graphicsPipelines.emplace( std::piecewise_construct, std::tuple(shaders), - std::tuple(this, shaders)); + std::tuple(this, shaders, layout)); return &iter.first->second; } @@ -84,5 +103,38 @@ namespace dxvk { if (m_stateCache != nullptr) m_stateCache->stopWorkerThreads(); } + + + DxvkBindingSetLayout* DxvkPipelineManager::createDescriptorSetLayout( + const DxvkBindingSetLayoutKey& key) { + auto pair = m_descriptorSetLayouts.find(key); + if (pair != m_descriptorSetLayouts.end()) + return &pair->second; + + auto iter = m_descriptorSetLayouts.emplace( + std::piecewise_construct, + std::tuple(key), + std::tuple(m_device, key)); + return &iter.first->second; + } + + + DxvkBindingLayoutObjects* DxvkPipelineManager::createPipelineLayout( + const DxvkBindingLayout& layout) { + auto pair = m_pipelineLayouts.find(layout); + if (pair != m_pipelineLayouts.end()) + return &pair->second; + + std::array setLayouts = { }; + + for (uint32_t i = 0; i < setLayouts.size(); i++) + setLayouts[i] = createDescriptorSetLayout(layout.getBindingList(i)); + + auto iter = m_pipelineLayouts.emplace( + std::piecewise_construct, + std::tuple(layout), + std::tuple(m_device, layout, setLayouts.data())); + return &iter.first->second; + } } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 08c79e0a8..35e711023 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -106,6 +106,16 @@ namespace dxvk { dxvk::mutex m_mutex; + std::unordered_map< + DxvkBindingSetLayoutKey, + DxvkBindingSetLayout, + DxvkHash, DxvkEq> m_descriptorSetLayouts; + + std::unordered_map< + DxvkBindingLayout, + DxvkBindingLayoutObjects, + DxvkHash, DxvkEq> m_pipelineLayouts; + std::unordered_map< DxvkComputePipelineShaders, DxvkComputePipeline, @@ -115,7 +125,13 @@ namespace dxvk { DxvkGraphicsPipelineShaders, DxvkGraphicsPipeline, DxvkHash, DxvkEq> m_graphicsPipelines; - + + DxvkBindingSetLayout* createDescriptorSetLayout( + const DxvkBindingSetLayoutKey& key); + + DxvkBindingLayoutObjects* createPipelineLayout( + const DxvkBindingLayout& layout); + }; } \ No newline at end of file From 038ee0416d340b949163ec2f140c3f98b32e203a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 15 Jun 2022 15:58:16 +0200 Subject: [PATCH 0047/1348] [dxvk] Add setRange method to DxvkBindingSet --- src/dxvk/dxvk_bind_mask.h | 29 ++++++++++++++++++++++++----- src/dxvk/dxvk_context.cpp | 3 ++- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_bind_mask.h b/src/dxvk/dxvk_bind_mask.h index b45b9b66a..219a70161 100644 --- a/src/dxvk/dxvk_bind_mask.h +++ b/src/dxvk/dxvk_bind_mask.h @@ -88,12 +88,31 @@ namespace dxvk { /** * \brief Enables multiple bindings - * \param [in] n Number of bindings + * + * Leaves bindings outside of this range unaffected. + * \param [in] first First binding to enable + * \param [in] count Number of bindings to enable */ - void setFirst(uint32_t n) { - for (uint32_t i = 0; i < IntCount; i++) { - m_slots[i] = n >= BitCount ? ~0u : ~(~0u << n); - n = n >= BitCount ? n - BitCount : 0; + void setRange(uint32_t first, uint32_t count) { + if (!count) + return; + + uint32_t firstInt = first / BitCount; + uint32_t firstBit = first % BitCount; + + uint32_t lastInt = (first + count - 1) / BitCount; + uint32_t lastBit = (first + count - 1) % BitCount + 1; + + if (firstInt == lastInt) { + m_slots[firstInt] |= (count < BitCount) + ? ((1u << count) - 1) << firstBit + : ~0u; + } else { + m_slots[firstInt] |= ~0u << firstBit; + m_slots[lastInt] |= ~0u >> (BitCount - lastBit); + + for (uint32_t i = firstInt + 1; i < lastInt; i++) + m_slots[i] = ~0u; } } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 2d78c9078..b4091d8c1 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4187,7 +4187,8 @@ namespace dxvk { // Assume that all bindings are active as a fast path DxvkBindingMask bindMask; - bindMask.setFirst(layout->bindingCount()); + bindMask.clear(); + bindMask.setRange(0, layout->bindingCount()); for (uint32_t i = 0; i < layout->bindingCount(); i++) { const auto& binding = layout->binding(i); From 16eba45987b10b99c7d81da8f7eddf6571aa185b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 15 Jun 2022 16:36:47 +0200 Subject: [PATCH 0048/1348] [dxvk] Implement 64-bit tzcnt --- src/util/util_bit.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index 7682ace86..4ee917d83 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -77,6 +77,34 @@ namespace dxvk::bit { #endif } + inline uint32_t tzcnt(uint64_t n) { + #if defined(_M_X64) && defined(_MSC_VER) && !defined(__clang__) + return _tzcnt_u64(n); + #elif defined(__x86_64__) && defined(__BMI__) + return __tzcnt_u64(n); + #elif defined(__x86_64__) && defined(__GNUC__) || defined(__clang__) + uint64_t res; + uint64_t tmp; + asm ( + "mov $64, %1;" + "bsf %2, %0;" + "cmovz %1, %0;" + : "=&r" (res), "=&r" (tmp) + : "r" (n)); + return res; + #else + uint32_t r = 63; + n &= -n; + r -= (n & 0x00000000FFFFFFFFull) ? 32 : 0; + r -= (n & 0x0000FFFF0000FFFFull) ? 16 : 0; + r -= (n & 0x00FF00FF00FF00FFull) ? 8 : 0; + r -= (n & 0x0F0F0F0F0F0F0F0Full) ? 4 : 0; + r -= (n & 0x3333333333333333ull) ? 2 : 0; + r -= (n & 0x5555555555555555ull) ? 1 : 0; + return n != 0 ? r : 64; + #endif + } + inline uint32_t bsf(uint32_t n) { #if defined(_MSC_VER) && !defined(__clang__) unsigned long index; From 955e0cca6275307cbed3265db448884aaf2151fd Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 15 Jun 2022 16:37:29 +0200 Subject: [PATCH 0049/1348] [dxvk] Use native integer size for DxvkBindingSet May make things a tad faster in 64-bit applications. --- src/dxvk/dxvk_bind_mask.h | 65 ++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/src/dxvk/dxvk_bind_mask.h b/src/dxvk/dxvk_bind_mask.h index 219a70161..57931064e 100644 --- a/src/dxvk/dxvk_bind_mask.h +++ b/src/dxvk/dxvk_bind_mask.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "dxvk_buffer.h" #include "dxvk_descriptor.h" #include "dxvk_image.h" @@ -18,7 +20,12 @@ namespace dxvk { */ template class DxvkBindingSet { - constexpr static uint32_t BitCount = 32; + using MaskType = std::conditional_t<(BindingCount > 32), uintptr_t, uint32_t>; + + constexpr static MaskType SetBit = MaskType(1u); + constexpr static MaskType SetMask = ~MaskType(0u); + + constexpr static uint32_t BitCount = 8 * sizeof(MaskType); constexpr static uint32_t IntCount = (BindingCount + BitCount - 1) / BitCount; public: @@ -29,9 +36,9 @@ namespace dxvk { * \returns \c true if the binding is active */ bool test(uint32_t slot) const { - const uint32_t intId = slot / BitCount; - const uint32_t bitId = slot % BitCount; - const uint32_t bitMask = 1u << bitId; + const uint32_t intId = computeIntId(slot); + const uint32_t bitId = computeBitId(slot); + const MaskType bitMask = SetBit << bitId; return (m_slots[intId] & bitMask) != 0; } @@ -43,12 +50,12 @@ namespace dxvk { * \returns \c true if the state has changed */ bool set(uint32_t slot, bool value) { - const uint32_t intId = slot / BitCount; - const uint32_t bitId = slot % BitCount; - const uint32_t bitMask = 1u << bitId; + const uint32_t intId = computeIntId(slot); + const uint32_t bitId = computeBitId(slot); + const MaskType bitMask = SetBit << bitId; - const uint32_t prev = m_slots[intId]; - const uint32_t next = value + const MaskType prev = m_slots[intId]; + const MaskType next = value ? prev | bitMask : prev & ~bitMask; m_slots[intId] = next; @@ -97,22 +104,22 @@ namespace dxvk { if (!count) return; - uint32_t firstInt = first / BitCount; - uint32_t firstBit = first % BitCount; + uint32_t firstInt = computeIntId(first); + uint32_t firstBit = computeBitId(first); - uint32_t lastInt = (first + count - 1) / BitCount; - uint32_t lastBit = (first + count - 1) % BitCount + 1; + uint32_t lastInt = computeIntId(first + count - 1); + uint32_t lastBit = computeBitId(first + count - 1) + 1; if (firstInt == lastInt) { m_slots[firstInt] |= (count < BitCount) - ? ((1u << count) - 1) << firstBit - : ~0u; + ? ((SetBit << count) - 1) << firstBit + : (SetMask); } else { - m_slots[firstInt] |= ~0u << firstBit; - m_slots[lastInt] |= ~0u >> (BitCount - lastBit); + m_slots[firstInt] |= SetMask << firstBit; + m_slots[lastInt] |= SetMask >> (BitCount - lastBit); for (uint32_t i = firstInt + 1; i < lastInt; i++) - m_slots[i] = ~0u; + m_slots[i] = SetMask; } } @@ -126,10 +133,10 @@ namespace dxvk { if (unlikely(first >= BindingCount)) return -1; - uint32_t intId = first / BitCount; - uint32_t bitId = first % BitCount; + uint32_t intId = computeIntId(first); + uint32_t bitId = computeBitId(first); - auto mask = m_slots[intId] & ~((1 << bitId) - 1); + MaskType mask = m_slots[intId] & ~((SetBit << bitId) - 1); while (!mask && ++intId < IntCount) mask = m_slots[intId]; @@ -153,7 +160,21 @@ namespace dxvk { private: - uint32_t m_slots[IntCount]; + MaskType m_slots[IntCount]; + + static uint32_t computeIntId(uint32_t slot) { + if constexpr (IntCount > 1) + return slot / BitCount; + else + return 0; + } + + static uint32_t computeBitId(uint32_t slot) { + if constexpr (IntCount > 1) + return slot % BitCount; + else + return slot; + } }; From d65ceb82cfe664e4be96865a047f1fd88dd77582 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 15 Jun 2022 18:52:45 +0200 Subject: [PATCH 0050/1348] [dxvk] Rework binding ID patching --- src/dxvk/dxvk_shader.cpp | 56 +++++++++++++++++++++++++++++++++++----- src/dxvk/dxvk_shader.h | 16 ++++++++++-- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index b543d201b..bb5dcb8dd 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -100,15 +100,32 @@ namespace dxvk { // Run an analysis pass over the SPIR-V code to gather some // info that we may need during pipeline compilation. + std::vector bindingOffsets; + std::vector constIdOffsets; + std::vector varIds; + SpirvCodeBuffer code = std::move(spirv); uint32_t o1VarId = 0; for (auto ins : code) { if (ins.opCode() == spv::OpDecorate) { - if (ins.arg(2) == spv::DecorationBinding - || ins.arg(2) == spv::DecorationSpecId) - m_idOffsets.push_back(ins.offset() + 3); - + if (ins.arg(2) == spv::DecorationBinding) { + uint32_t varId = ins.arg(1); + bindingOffsets.resize(std::max(bindingOffsets.size(), size_t(varId + 1))); + bindingOffsets[varId].bindingId = ins.arg(3); + bindingOffsets[varId].bindingOffset = ins.offset() + 3; + varIds.push_back(varId); + } + + if (ins.arg(2) == spv::DecorationDescriptorSet) { + uint32_t varId = ins.arg(1); + bindingOffsets.resize(std::max(bindingOffsets.size(), size_t(varId + 1))); + bindingOffsets[varId].setOffset = ins.offset() + 3; + } + + if (ins.arg(2) == spv::DecorationSpecId) + constIdOffsets.push_back({ ins.arg(3), ins.offset() + 3 }); + if (ins.arg(2) == spv::DecorationLocation && ins.arg(3) == 1) { m_o1LocOffset = ins.offset() + 3; o1VarId = ins.arg(1); @@ -133,6 +150,25 @@ namespace dxvk { if (ins.arg(1) == spv::CapabilityShaderViewportIndexLayerEXT) m_flags.set(DxvkShaderFlag::ExportsViewportIndexLayerFromVertexStage); } + + // Ignore the actual shader code, there's nothing interesting for us in there. + if (ins.opCode() == spv::OpFunction) + break; + } + + // Combine spec constant IDs with other binding info + for (auto varId : varIds) { + BindingOffsets info = bindingOffsets[varId]; + + for (const auto& specOfs : constIdOffsets) { + if (info.bindingId == specOfs.bindingId) { + info.constIdOffset = specOfs.constIdOffset; + break; + } + } + + if (info.bindingOffset) + m_bindingOffsets.push_back(info); } } @@ -163,9 +199,15 @@ namespace dxvk { uint32_t* code = spirvCode.data(); // Remap resource binding IDs - for (uint32_t ofs : m_idOffsets) { - if (code[ofs] < MaxNumResourceSlots) - code[ofs] = mapping.getBindingId(code[ofs]); + for (const auto& info : m_bindingOffsets) { + uint32_t mappedBinding = mapping.getBindingId(info.bindingId); + code[info.bindingOffset] = mappedBinding; + + if (info.constIdOffset) + code[info.constIdOffset] = mappedBinding; + + if (code[info.setOffset]) + code[info.setOffset] = 0; } // For dual-source blending we need to re-map diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 9f9c7d3e0..1f1ba19c8 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -209,7 +209,19 @@ namespace dxvk { } private: - + + struct ConstOffsets { + uint32_t bindingId; + uint32_t constIdOffset; + }; + + struct BindingOffsets { + uint32_t bindingId; + uint32_t constIdOffset; + uint32_t bindingOffset; + uint32_t setOffset; + }; + DxvkShaderCreateInfo m_info; SpirvCompressedBuffer m_code; @@ -222,7 +234,7 @@ namespace dxvk { std::vector m_slots; std::vector m_uniformData; - std::vector m_idOffsets; + std::vector m_bindingOffsets; DxvkBindingLayout m_bindings; From ef55a7c2a0a74c2c8b47580687fba9a46933f421 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 15 Jun 2022 19:17:25 +0200 Subject: [PATCH 0051/1348] [dxvk] Add method to create shader module using new binding layout --- src/dxvk/dxvk_shader.cpp | 35 +++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_shader.h | 17 ++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index bb5dcb8dd..af45e2f42 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -223,6 +223,41 @@ namespace dxvk { } + DxvkShaderModule DxvkShader::createShaderModule( + const Rc& vkd, + const DxvkBindingLayoutObjects* layout, + const DxvkShaderModuleCreateInfo& info) { + SpirvCodeBuffer spirvCode = m_code.decompress(); + uint32_t* code = spirvCode.data(); + + // Remap resource binding IDs + for (const auto& info : m_bindingOffsets) { + auto mappedBinding = layout->lookupBinding(info.bindingId); + + if (mappedBinding) { + code[info.bindingOffset] = mappedBinding->binding; + + if (info.constIdOffset) + code[info.constIdOffset] = mappedBinding->constId; + + if (info.setOffset) + code[info.setOffset] = mappedBinding->set; + } + } + + // For dual-source blending we need to re-map + // location 1, index 0 to location 0, index 1 + if (info.fsDualSrcBlend && m_o1IdxOffset && m_o1LocOffset) + std::swap(code[m_o1IdxOffset], code[m_o1LocOffset]); + + // Replace undefined input variables with zero + for (uint32_t u : bit::BitMask(info.undefinedInputs)) + eliminateInput(spirvCode, u); + + return DxvkShaderModule(vkd, this, spirvCode); + } + + void DxvkShader::dump(std::ostream& outputStream) const { m_code.decompress().store(outputStream); } diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 1f1ba19c8..b21928403 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -150,7 +150,22 @@ namespace dxvk { const Rc& vkd, const DxvkDescriptorSlotMapping& mapping, const DxvkShaderModuleCreateInfo& info); - + + /** + * \brief Creates a shader module + * + * Remaps resource binding and descriptor set + * numbers to match the given binding layout. + * \param [in] vkd Vulkan device functions + * \param [in] layout Binding layout + * \param [in] info Module create info + * \returns The shader module + */ + DxvkShaderModule createShaderModule( + const Rc& vkd, + const DxvkBindingLayoutObjects* layout, + const DxvkShaderModuleCreateInfo& info); + /** * \brief Dumps SPIR-V shader * From d5e53d32716a40acb7380663a1506af0a81dc883 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 14 Jun 2022 17:36:59 +0200 Subject: [PATCH 0052/1348] [dxvk] Add resource binding code using new pipeline layouts --- src/dxvk/dxvk_cmdlist.h | 14 +++ src/dxvk/dxvk_context.cpp | 193 ++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_context.h | 3 + 3 files changed, 210 insertions(+) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index b6c4c5ae8..3dedf3f45 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -291,6 +291,20 @@ namespace dxvk { } + void cmdBindDescriptorSets( + VkPipelineBindPoint pipeline, + VkPipelineLayout pipelineLayout, + uint32_t firstSet, + uint32_t descriptorSetCount, + const VkDescriptorSet* descriptorSets, + uint32_t dynamicOffsetCount, + const uint32_t* pDynamicOffsets) { + m_vkd->vkCmdBindDescriptorSets(m_execBuffer, + pipeline, pipelineLayout, firstSet, descriptorSetCount, + descriptorSets, dynamicOffsetCount, pDynamicOffsets); + } + + void cmdBindIndexBuffer( VkBuffer buffer, VkDeviceSize offset, diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b4091d8c1..7f2464082 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4155,6 +4155,199 @@ namespace dxvk { } + template + void DxvkContext::updateResourceBindings(const DxvkBindingLayoutObjects* layout) { + std::array sets = { VK_NULL_HANDLE, VK_NULL_HANDLE }; + std::array descriptors; + + const auto& bindings = layout->layout(); + + // This relies on the bind mask being cleared when the pipeline layout changes. + DxvkBindingMask& refBindMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS + ? m_state.gp.state.bsBindingMask + : m_state.cp.state.bsBindingMask; + + DxvkBindingMask newBindMask = refBindMask; + + uint32_t bindingIndex = 0; + + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + // Initialize binding mask for the current set, only + // clear bits if certain resources are actually unbound. + uint32_t bindingCount = bindings.getBindingCount(i); + + // TODO skip if set is unmodified + if (true) { + newBindMask.setRange(bindingIndex, bindingCount); + + for (uint32_t j = 0; j < bindingCount; j++) { + const auto& binding = bindings.getBinding(i, j); + + switch (binding.descriptorType) { + case VK_DESCRIPTOR_TYPE_SAMPLER: { + const auto& res = m_rc[binding.resourceBinding]; + + if (res.sampler != nullptr) { + descriptors[j].image.sampler = res.sampler->handle(); + descriptors[j].image.imageView = VK_NULL_HANDLE; + descriptors[j].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + if (m_rcTracked.set(binding.resourceBinding)) + m_cmd->trackResource(res.sampler); + } else { + descriptors[j].image = m_common->dummyResources().samplerDescriptor(); + } + } break; + + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: { + const auto& res = m_rc[binding.resourceBinding]; + + if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { + descriptors[j].image.sampler = VK_NULL_HANDLE; + descriptors[j].image.imageView = res.imageView->handle(binding.viewType); + descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; + + if (m_rcTracked.set(binding.resourceBinding)) { + m_cmd->trackResource(res.imageView); + m_cmd->trackResource(res.imageView->image()); + } + } else { + descriptors[j].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, true); + newBindMask.clr(bindingIndex + j); + } + } break; + + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: { + const auto& res = m_rc[binding.resourceBinding]; + + if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { + descriptors[j].image.sampler = VK_NULL_HANDLE; + descriptors[j].image.imageView = res.imageView->handle(binding.viewType); + descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; + + if (m_rcTracked.set(binding.resourceBinding)) { + m_cmd->trackResource(res.imageView); + m_cmd->trackResource(res.imageView->image()); + } + } else { + descriptors[j].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, false); + newBindMask.clr(bindingIndex + j); + } + } break; + + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { + const auto& res = m_rc[binding.resourceBinding]; + + if (res.sampler != nullptr && res.imageView != nullptr + && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { + descriptors[j].image.sampler = res.sampler->handle(); + descriptors[j].image.imageView = res.imageView->handle(binding.viewType); + descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; + + if (m_rcTracked.set(binding.resourceBinding)) { + m_cmd->trackResource(res.sampler); + m_cmd->trackResource(res.imageView); + m_cmd->trackResource(res.imageView->image()); + } + } else { + descriptors[j].image = m_common->dummyResources().imageSamplerDescriptor(binding.viewType); + newBindMask.clr(bindingIndex + j); + } + } break; + + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: { + const auto& res = m_rc[binding.resourceBinding]; + + if (res.bufferView != nullptr) { + res.bufferView->updateView(); + descriptors[j].texelBuffer = res.bufferView->handle(); + + if (m_rcTracked.set(binding.resourceBinding)) { + m_cmd->trackResource(res.bufferView); + m_cmd->trackResource(res.bufferView->buffer()); + } + } else { + descriptors[j].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); + newBindMask.clr(bindingIndex + j); + } + } break; + + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: { + const auto& res = m_rc[binding.resourceBinding]; + + if (res.bufferView != nullptr) { + res.bufferView->updateView(); + descriptors[j].texelBuffer = res.bufferView->handle(); + + if (m_rcTracked.set(binding.resourceBinding)) { + m_cmd->trackResource(res.bufferView); + m_cmd->trackResource(res.bufferView->buffer()); + } + } else { + descriptors[j].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); + newBindMask.clr(bindingIndex + j); + } + } break; + + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: { + const auto& res = m_rc[binding.resourceBinding]; + + if (res.bufferSlice.defined()) { + descriptors[j] = res.bufferSlice.getDescriptor(); + + if (m_rcTracked.set(binding.resourceBinding)) + m_cmd->trackResource(res.bufferSlice.buffer()); + } else { + descriptors[j].buffer = m_common->dummyResources().bufferDescriptor(); + } + } break; + + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: { + const auto& res = m_rc[binding.resourceBinding]; + + if (res.bufferSlice.defined()) { + descriptors[j] = res.bufferSlice.getDescriptor(); + + if (m_rcTracked.set(binding.resourceBinding)) + m_cmd->trackResource(res.bufferSlice.buffer()); + } else { + descriptors[j].buffer = m_common->dummyResources().bufferDescriptor(); + newBindMask.clr(bindingIndex + j); + } + } break; + + default: + Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.descriptorType)); + } + } + } + + // Create and populate descriptor set with the given descriptors + sets[i] = allocateDescriptorSet(layout->getSetLayout(i)); + + m_cmd->updateDescriptorSetWithTemplate(sets[i], + layout->getSetUpdateTemplate(i), descriptors.data()); + + bindingIndex += bindingCount; + } + + // Bind all required descriptor sets + m_cmd->cmdBindDescriptorSets(BindPoint, + layout->getPipelineLayout(), + 0, sets.size(), sets.data(), + 0, nullptr); + + // Update pipeline if there are unbound resources + if (refBindMask != newBindMask) { + refBindMask = newBindMask; + + m_flags.set(BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS + ? DxvkContextFlag::GpDirtyPipelineState + : DxvkContextFlag::CpDirtyPipelineState); + } + } + + void DxvkContext::updateComputeShaderResources() { if ((m_flags.test(DxvkContextFlag::CpDirtyResources)) || (m_state.cp.pipeline->layout()->hasStaticBufferBindings())) diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 5cda9248a..727ba544f 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1218,6 +1218,9 @@ namespace dxvk { bool updateGraphicsPipeline(); bool updateGraphicsPipelineState(); + template + void updateResourceBindings(const DxvkBindingLayoutObjects* layout); + void updateComputeShaderResources(); void updateGraphicsShaderResources(); From 9be454fd3e3bd11e4cbe37100e15a7435cee59be Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 15 Jun 2022 20:01:17 +0200 Subject: [PATCH 0053/1348] [dxvk] Use new pipeline layout for barrier tracking and other things --- src/dxvk/dxvk_compute.cpp | 21 +- src/dxvk/dxvk_compute.h | 5 +- src/dxvk/dxvk_context.cpp | 373 +++++++++++++++++----------------- src/dxvk/dxvk_context_state.h | 2 - src/dxvk/dxvk_graphics.cpp | 31 ++- src/dxvk/dxvk_graphics.h | 5 +- 6 files changed, 207 insertions(+), 230 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 7dba4f99a..9adb7d953 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -16,14 +16,7 @@ namespace dxvk { DxvkBindingLayoutObjects* layout) : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), m_shaders(std::move(shaders)), m_bindings(layout) { - m_shaders.cs->defineResourceSlots(m_slotMapping); - m_slotMapping.makeDescriptorsDynamic( - m_pipeMgr->m_device->options().maxNumDynamicUniformBuffers, - m_pipeMgr->m_device->options().maxNumDynamicStorageBuffers); - - m_layout = new DxvkPipelineLayout(m_vkd, - m_slotMapping, VK_PIPELINE_BIND_POINT_COMPUTE); } @@ -90,8 +83,14 @@ namespace dxvk { } DxvkSpecConstants specData; - for (uint32_t i = 0; i < m_layout->bindingCount(); i++) - specData.set(i, state.bsBindingMask.test(i), true); + uint32_t bindingIndex = 0; + + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + for (uint32_t j = 0; j < m_bindings->layout().getBindingCount(i); j++) { + specData.set(bindingIndex, state.bsBindingMask.test(bindingIndex), true); + bindingIndex += 1; + } + } for (uint32_t i = 0; i < MaxNumSpecConstants; i++) specData.set(getSpecId(i), state.sc.specConstants[i], 0u); @@ -101,14 +100,14 @@ namespace dxvk { DxvkShaderModuleCreateInfo moduleInfo; moduleInfo.fsDualSrcBlend = false; - auto csm = m_shaders.cs->createShaderModule(m_vkd, m_slotMapping, moduleInfo); + auto csm = m_shaders.cs->createShaderModule(m_vkd, m_bindings, moduleInfo); VkComputePipelineCreateInfo info; info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; info.pNext = nullptr; info.flags = 0; info.stage = csm.stageInfo(&specInfo); - info.layout = m_layout->pipelineLayout(); + info.layout = m_bindings->getPipelineLayout(); info.basePipelineHandle = VK_NULL_HANDLE; info.basePipelineIndex = -1; diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index 74fd778e5..135b9616c 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -113,7 +113,7 @@ namespace dxvk { * \returns Pipeline layout */ DxvkPipelineLayout* layout() const { - return m_layout.ptr(); + return nullptr; } /** @@ -153,10 +153,7 @@ namespace dxvk { DxvkPipelineManager* m_pipeMgr; DxvkComputePipelineShaders m_shaders; - DxvkDescriptorSlotMapping m_slotMapping; - DxvkBindingLayoutObjects* m_bindings; - Rc m_layout; alignas(CACHE_LINE_SIZE) dxvk::mutex m_mutex; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 7f2464082..d01add70e 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -158,15 +158,9 @@ namespace dxvk { else needsUpdate = m_rc[slot].bufferSlice.length() != buffer.length(); - if (likely(needsUpdate)) { - m_flags.set( - DxvkContextFlag::CpDirtyResources, - DxvkContextFlag::GpDirtyResources); - } else { - m_flags.set( - DxvkContextFlag::CpDirtyDescriptorBinding, - DxvkContextFlag::GpDirtyDescriptorBinding); - } + m_flags.set( + DxvkContextFlag::CpDirtyResources, + DxvkContextFlag::GpDirtyResources); m_rc[slot].bufferSlice = buffer; } @@ -1759,25 +1753,21 @@ namespace dxvk { ~(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT); - if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) { - m_flags.set(prevSlice.handle == slice.handle - ? DxvkContextFlags(DxvkContextFlag::GpDirtyDescriptorBinding, - DxvkContextFlag::CpDirtyDescriptorBinding) - : DxvkContextFlags(DxvkContextFlag::GpDirtyResources, - DxvkContextFlag::CpDirtyResources)); - } + VkBufferUsageFlags resourceMask = + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | + VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; - // Fast early-out for uniform buffers, very common - if (likely(usage == VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) - return; - - if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT - | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT - | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) { + if (usage & resourceMask) { m_flags.set(DxvkContextFlag::GpDirtyResources, DxvkContextFlag::CpDirtyResources); } + // Fast early-out for resource buffers, very common + if (likely(!(usage & ~resourceMask))) + return; + if (usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer); @@ -4037,7 +4027,7 @@ namespace dxvk { if (unlikely(m_state.cp.pipeline == nullptr)) return false; - if (m_state.cp.pipeline->layout()->pushConstRange().size) + if (m_state.cp.pipeline->getBindings()->layout().getPushConstantRange().size) m_flags.set(DxvkContextFlag::DirtyPushConstants); m_flags.clr(DxvkContextFlag::CpDirtyPipeline); @@ -4101,7 +4091,7 @@ namespace dxvk { this->spillRenderPass(true); } - if (m_state.gp.pipeline->layout()->pushConstRange().size) + if (m_state.gp.pipeline->getBindings()->layout().getPushConstantRange().size) m_flags.set(DxvkContextFlag::DirtyPushConstants); m_flags.clr(DxvkContextFlag::GpDirtyPipeline); @@ -4325,8 +4315,10 @@ namespace dxvk { // Create and populate descriptor set with the given descriptors sets[i] = allocateDescriptorSet(layout->getSetLayout(i)); - m_cmd->updateDescriptorSetWithTemplate(sets[i], - layout->getSetUpdateTemplate(i), descriptors.data()); + if (bindingCount) { + m_cmd->updateDescriptorSetWithTemplate(sets[i], + layout->getSetUpdateTemplate(i), descriptors.data()); + } bindingIndex += bindingCount; } @@ -4349,28 +4341,16 @@ namespace dxvk { void DxvkContext::updateComputeShaderResources() { - if ((m_flags.test(DxvkContextFlag::CpDirtyResources)) - || (m_state.cp.pipeline->layout()->hasStaticBufferBindings())) - this->updateShaderResources(m_state.cp.pipeline->layout()); + this->updateResourceBindings(m_state.cp.pipeline->getBindings()); - this->updateShaderDescriptorSetBinding( - m_cpSet, m_state.cp.pipeline->layout()); - - m_flags.clr(DxvkContextFlag::CpDirtyResources, - DxvkContextFlag::CpDirtyDescriptorBinding); + m_flags.clr(DxvkContextFlag::CpDirtyResources); } void DxvkContext::updateGraphicsShaderResources() { - if ((m_flags.test(DxvkContextFlag::GpDirtyResources)) - || (m_state.gp.pipeline->layout()->hasStaticBufferBindings())) - this->updateShaderResources(m_state.gp.pipeline->layout()); + this->updateResourceBindings(m_state.gp.pipeline->getBindings()); - this->updateShaderDescriptorSetBinding( - m_gpSet, m_state.gp.pipeline->layout()); - - m_flags.clr(DxvkContextFlag::GpDirtyResources, - DxvkContextFlag::GpDirtyDescriptorBinding); + m_flags.clr(DxvkContextFlag::GpDirtyResources); } @@ -4942,19 +4922,17 @@ namespace dxvk { void DxvkContext::updatePushConstants() { m_flags.clr(DxvkContextFlag::DirtyPushConstants); - auto layout = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS - ? m_state.gp.pipeline->layout() - : m_state.cp.pipeline->layout(); + auto bindings = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS + ? m_state.gp.pipeline->getBindings() + : m_state.cp.pipeline->getBindings(); - if (!layout) - return; - - VkPushConstantRange pushConstRange = layout->pushConstRange(); + VkPushConstantRange pushConstRange = bindings->layout().getPushConstantRange(); + if (!pushConstRange.size) return; m_cmd->cmdPushConstants( - layout->pipelineLayout(), + bindings->getPipelineLayout(), pushConstRange.stageFlags, pushConstRange.offset, pushConstRange.size, @@ -4970,9 +4948,7 @@ namespace dxvk { return false; } - if (m_flags.any( - DxvkContextFlag::CpDirtyResources, - DxvkContextFlag::CpDirtyDescriptorBinding)) + if (m_flags.test(DxvkContextFlag::CpDirtyResources)) this->updateComputeShaderResources(); if (m_flags.test(DxvkContextFlag::CpDirtyPipelineState)) { @@ -5014,9 +4990,7 @@ namespace dxvk { if (m_flags.test(DxvkContextFlag::GpDirtyVertexBuffers)) this->updateVertexBufferBindings(); - if (m_flags.any( - DxvkContextFlag::GpDirtyResources, - DxvkContextFlag::GpDirtyDescriptorBinding)) + if (m_flags.test(DxvkContextFlag::GpDirtyResources)) this->updateGraphicsShaderResources(); if (m_flags.test(DxvkContextFlag::GpDirtyPipelineState)) { @@ -5046,58 +5020,66 @@ namespace dxvk { void DxvkContext::commitComputeInitBarriers() { - auto layout = m_state.cp.pipeline->layout(); + const auto& layout = m_state.cp.pipeline->getBindings()->layout(); bool requiresBarrier = false; - for (uint32_t i = 0; i < layout->bindingCount() && !requiresBarrier; i++) { - if (m_state.cp.state.bsBindingMask.test(i)) { - const DxvkDescriptorSlot binding = layout->binding(i); - const DxvkShaderResourceSlot& slot = m_rc[binding.slot]; + uint32_t index = 0; - DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); - DxvkAccessFlags srcAccess = 0; - - switch (binding.type) { - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - srcAccess = m_execBarriers.getBufferAccess( - slot.bufferSlice.getSliceHandle()); - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - srcAccess = m_execBarriers.getBufferAccess( - slot.bufferView->getSliceHandle()); - break; + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount && !requiresBarrier; i++) { + uint32_t bindingCount = layout.getBindingCount(i); + + for (uint32_t j = 0; j < bindingCount && !requiresBarrier; j++) { + if (m_state.cp.state.bsBindingMask.test(index + j)) { + const DxvkBindingInfo& binding = layout.getBinding(i, j); + const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; + + DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); + DxvkAccessFlags srcAccess = 0; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - srcAccess = m_execBarriers.getImageAccess( - slot.imageView->image(), - slot.imageView->imageSubresources()); - break; + switch (binding.descriptorType) { + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + srcAccess = m_execBarriers.getBufferAccess( + slot.bufferSlice.getSliceHandle()); + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + srcAccess = m_execBarriers.getBufferAccess( + slot.bufferView->getSliceHandle()); + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + srcAccess = m_execBarriers.getImageAccess( + slot.imageView->image(), + slot.imageView->imageSubresources()); + break; - default: - /* nothing to do */; + default: + /* nothing to do */; + } + + if (srcAccess == 0) + continue; + + // Skip write-after-write barriers if explicitly requested + VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT + | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; + + if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) + && (!(m_execBarriers.getSrcStages() & ~stageMask)) + && ((srcAccess | dstAccess) == DxvkAccess::Write)) + continue; + + requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); } - - if (srcAccess == 0) - continue; - - // Skip write-after-write barriers if explicitly requested - VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT - | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; - - if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) - && (!(m_execBarriers.getSrcStages() & ~stageMask)) - && ((srcAccess | dstAccess) == DxvkAccess::Write)) - continue; - - requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); } + + index += bindingCount; } if (requiresBarrier) @@ -5106,53 +5088,60 @@ namespace dxvk { void DxvkContext::commitComputePostBarriers() { - auto layout = m_state.cp.pipeline->layout(); - - for (uint32_t i = 0; i < layout->bindingCount(); i++) { - if (m_state.cp.state.bsBindingMask.test(i)) { - const DxvkDescriptorSlot binding = layout->binding(i); - const DxvkShaderResourceSlot& slot = m_rc[binding.slot]; + const auto& layout = m_state.cp.pipeline->getBindings()->layout(); + uint32_t index = 0; - VkPipelineStageFlags stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - VkAccessFlags access = binding.access; - - switch (binding.type) { - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - m_execBarriers.accessBuffer( - slot.bufferSlice.getSliceHandle(), - stages, access, - slot.bufferSlice.bufferInfo().stages, - slot.bufferSlice.bufferInfo().access); - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - m_execBarriers.accessBuffer( - slot.bufferView->getSliceHandle(), - stages, access, - slot.bufferView->bufferInfo().stages, - slot.bufferView->bufferInfo().access); - break; + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + uint32_t bindingCount = layout.getBindingCount(i); + + for (uint32_t j = 0; j < bindingCount; j++) { + if (m_state.cp.state.bsBindingMask.test(index + j)) { + const DxvkBindingInfo& binding = layout.getBinding(i, j); + const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; + + VkPipelineStageFlags stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + VkAccessFlags access = binding.access; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - m_execBarriers.accessImage( - slot.imageView->image(), - slot.imageView->imageSubresources(), - slot.imageView->imageInfo().layout, - stages, access, - slot.imageView->imageInfo().layout, - slot.imageView->imageInfo().stages, - slot.imageView->imageInfo().access); - break; + switch (binding.descriptorType) { + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + m_execBarriers.accessBuffer( + slot.bufferSlice.getSliceHandle(), + stages, access, + slot.bufferSlice.bufferInfo().stages, + slot.bufferSlice.bufferInfo().access); + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + m_execBarriers.accessBuffer( + slot.bufferView->getSliceHandle(), + stages, access, + slot.bufferView->bufferInfo().stages, + slot.bufferView->bufferInfo().access); + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + m_execBarriers.accessImage( + slot.imageView->image(), + slot.imageView->imageSubresources(), + slot.imageView->imageInfo().layout, + stages, access, + slot.imageView->imageInfo().layout, + slot.imageView->imageInfo().stages, + slot.imageView->imageInfo().access); + break; - default: - /* nothing to do */; + default: + /* nothing to do */; + } } } + + index += bindingCount; } } @@ -5162,8 +5151,6 @@ namespace dxvk { if (m_barrierControl.test(DxvkBarrierControl::IgnoreGraphicsBarriers)) return; - auto layout = m_state.gp.pipeline->layout(); - constexpr auto storageBufferAccess = VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT; constexpr auto storageImageAccess = VK_ACCESS_SHADER_WRITE_BIT; @@ -5241,56 +5228,62 @@ namespace dxvk { } // Check shader resources on every draw to handle WAW hazards - for (uint32_t i = 0; i < layout->bindingCount() && !requiresBarrier; i++) { - const DxvkDescriptorSlot binding = layout->binding(i); - const DxvkShaderResourceSlot& slot = m_rc[binding.slot]; + auto layout = m_state.gp.pipeline->getBindings()->layout(); - DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); - DxvkAccessFlags srcAccess = 0; - - switch (binding.type) { - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - if ((slot.bufferSlice.defined()) - && (slot.bufferSlice.bufferInfo().access & storageBufferAccess)) { - srcAccess = this->checkGfxBufferBarrier(slot.bufferSlice, - util::pipelineStages(binding.stages), binding.access); - } - break; + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + uint32_t bindingCount = layout.getBindingCount(i); - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - if ((slot.bufferView != nullptr) - && (slot.bufferView->bufferInfo().access & storageBufferAccess)) { - srcAccess = this->checkGfxBufferBarrier(slot.bufferView->slice(), - util::pipelineStages(binding.stages), binding.access); - } - break; + for (uint32_t j = 0; j < bindingCount && !requiresBarrier; j++) { + const DxvkBindingInfo& binding = layout.getBinding(i, j); + const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - if ((slot.imageView != nullptr) - && (slot.imageView->imageInfo().access & storageImageAccess)) { - srcAccess = this->checkGfxImageBarrier(slot.imageView, - util::pipelineStages(binding.stages), binding.access); - } - break; + DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); + DxvkAccessFlags srcAccess = 0; + + switch (binding.descriptorType) { + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + if ((slot.bufferSlice.defined()) + && (slot.bufferSlice.bufferInfo().access & storageBufferAccess)) { + srcAccess = this->checkGfxBufferBarrier(slot.bufferSlice, + util::pipelineStages(binding.stages), binding.access); + } + break; - default: - /* nothing to do */; + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + if ((slot.bufferView != nullptr) + && (slot.bufferView->bufferInfo().access & storageBufferAccess)) { + srcAccess = this->checkGfxBufferBarrier(slot.bufferView->slice(), + util::pipelineStages(binding.stages), binding.access); + } + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + if ((slot.imageView != nullptr) + && (slot.imageView->imageInfo().access & storageImageAccess)) { + srcAccess = this->checkGfxImageBarrier(slot.imageView, + util::pipelineStages(binding.stages), binding.access); + } + break; + + default: + /* nothing to do */; + } + + if (srcAccess == 0) + continue; + + // Skip write-after-write barriers if explicitly requested + if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) + && ((srcAccess | dstAccess) == DxvkAccess::Write)) + continue; + + requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); } - - if (srcAccess == 0) - continue; - - // Skip write-after-write barriers if explicitly requested - if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) - && ((srcAccess | dstAccess) == DxvkAccess::Write)) - continue; - - requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); } // External subpass dependencies serve as full memory diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 27a6de587..b8bb46b8b 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -28,7 +28,6 @@ namespace dxvk { GpDirtyPipeline, ///< Graphics pipeline binding is out of date GpDirtyPipelineState, ///< Graphics pipeline needs to be recompiled GpDirtyResources, ///< Graphics pipeline resource bindings are out of date - GpDirtyDescriptorBinding, ///< Graphics descriptor set needs to be rebound GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date GpDirtyIndexBuffer, ///< Index buffer binding are out of date GpDirtyXfbBuffers, ///< Transform feedback buffer bindings are out of date @@ -45,7 +44,6 @@ namespace dxvk { CpDirtyPipeline, ///< Compute pipeline binding are out of date CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled CpDirtyResources, ///< Compute pipeline resource bindings are out of date - CpDirtyDescriptorBinding, ///< Compute descriptor set needs to be rebound DirtyDrawBuffer, ///< Indirect argument buffer is dirty DirtyPushConstants, ///< Push constant data has changed diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 1b1b9f7df..b369a9e16 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -14,26 +14,13 @@ namespace dxvk { DxvkBindingLayoutObjects* layout) : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), m_shaders(std::move(shaders)), m_bindings(layout) { - if (m_shaders.vs != nullptr) m_shaders.vs ->defineResourceSlots(m_slotMapping); - if (m_shaders.tcs != nullptr) m_shaders.tcs->defineResourceSlots(m_slotMapping); - if (m_shaders.tes != nullptr) m_shaders.tes->defineResourceSlots(m_slotMapping); - if (m_shaders.gs != nullptr) m_shaders.gs ->defineResourceSlots(m_slotMapping); - if (m_shaders.fs != nullptr) m_shaders.fs ->defineResourceSlots(m_slotMapping); - - m_slotMapping.makeDescriptorsDynamic( - pipeMgr->m_device->options().maxNumDynamicUniformBuffers, - pipeMgr->m_device->options().maxNumDynamicStorageBuffers); - - m_layout = new DxvkPipelineLayout(m_vkd, - m_slotMapping, VK_PIPELINE_BIND_POINT_GRAPHICS); - m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->info().inputMask : 0; m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->info().outputMask : 0; if (m_shaders.gs != nullptr && m_shaders.gs->flags().test(DxvkShaderFlag::HasTransformFeedback)) m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback); - if (m_layout->getStorageDescriptorStages()) + if (layout->getAccessFlags() & VK_ACCESS_SHADER_WRITE_BIT) m_flags.set(DxvkGraphicsPipelineFlag::HasStorageDescriptors); m_common.msSampleShadingEnable = m_shaders.fs != nullptr && m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading); @@ -166,9 +153,15 @@ namespace dxvk { // Set up some specialization constants DxvkSpecConstants specData; specData.set(uint32_t(DxvkSpecConstantId::RasterizerSampleCount), sampleCount, VK_SAMPLE_COUNT_1_BIT); - - for (uint32_t i = 0; i < m_layout->bindingCount(); i++) - specData.set(i, state.bsBindingMask.test(i), true); + + uint32_t bindingIndex = 0; + + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + for (uint32_t j = 0; j < m_bindings->layout().getBindingCount(i); j++) { + specData.set(bindingIndex, state.bsBindingMask.test(bindingIndex), true); + bindingIndex += 1; + } + } for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if ((m_fsOut & (1 << i)) != 0) { @@ -408,7 +401,7 @@ namespace dxvk { info.pDepthStencilState = &dsInfo; info.pColorBlendState = &cbInfo; info.pDynamicState = &dyInfo; - info.layout = m_layout->pipelineLayout(); + info.layout = m_bindings->getPipelineLayout(); info.renderPass = renderPass->getDefaultHandle(); info.subpass = 0; info.basePipelineHandle = VK_NULL_HANDLE; @@ -481,7 +474,7 @@ namespace dxvk { } info.undefinedInputs = (providedInputs & consumedInputs) ^ consumedInputs; - return shader->createShaderModule(m_vkd, m_slotMapping, info); + return shader->createShaderModule(m_vkd, m_bindings, info); } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 1136a06d8..ed76b915d 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -179,7 +179,7 @@ namespace dxvk { * \returns Pipeline layout */ DxvkPipelineLayout* layout() const { - return m_layout.ptr(); + return nullptr; } /** @@ -236,10 +236,7 @@ namespace dxvk { DxvkPipelineManager* m_pipeMgr; DxvkGraphicsPipelineShaders m_shaders; - DxvkDescriptorSlotMapping m_slotMapping; - DxvkBindingLayoutObjects* m_bindings; - Rc m_layout; uint32_t m_vsIn = 0; uint32_t m_fsOut = 0; From 893183a7cc1a523807c668c2b9738360b5ae12a5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 16 Jun 2022 03:11:08 +0200 Subject: [PATCH 0054/1348] [dxvk] Remove old pipeline layout from pipeline objects --- src/dxvk/dxvk_compute.h | 12 ------------ src/dxvk/dxvk_graphics.h | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index 135b9616c..51566389d 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -104,18 +104,6 @@ namespace dxvk { return m_shaders; } - /** - * \brief Pipeline layout - * - * Stores the pipeline layout and the descriptor set - * layout, as well as information on the resource - * slots used by the pipeline. - * \returns Pipeline layout - */ - DxvkPipelineLayout* layout() const { - return nullptr; - } - /** * \brief Pipeline layout * diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index ed76b915d..574d5d2cd 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -170,18 +170,6 @@ namespace dxvk { return m_flags; } - /** - * \brief Pipeline layout - * - * Stores the pipeline layout and the descriptor set - * layout, as well as information on the resource - * slots used by the pipeline. - * \returns Pipeline layout - */ - DxvkPipelineLayout* layout() const { - return nullptr; - } - /** * \brief Pipeline layout * From db85de8c91ba22cc86da02454a312527adb770bc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 21 Jun 2022 15:22:05 +0200 Subject: [PATCH 0055/1348] [dxvk] Add method to query shader stages that can access a buffer --- src/dxvk/dxvk_buffer.cpp | 3 ++- src/dxvk/dxvk_buffer.h | 11 +++++++++++ src/dxvk/dxvk_util.h | 12 ++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 931a6269d..3de5b4d7b 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -14,7 +14,8 @@ namespace dxvk { : m_device (device), m_info (createInfo), m_memAlloc (&memAlloc), - m_memFlags (memFlags) { + m_memFlags (memFlags), + m_shaderStages (util::shaderStages(createInfo.stages)) { // Align slices so that we don't violate any alignment // requirements imposed by the Vulkan device/driver VkDeviceSize sliceAlignment = computeSliceAlignment(); diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 4d94cec73..139098104 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -142,6 +142,16 @@ namespace dxvk { void* mapPtr(VkDeviceSize offset) const { return reinterpret_cast(m_physSlice.mapPtr) + offset; } + + /** + * \brief Queries shader stages that can access this buffer + * + * Derived from the pipeline stage mask passed in during creation. + * \returns Shader stages that may access this buffer + */ + VkShaderStageFlags getShaderStages() const { + return m_shaderStages; + } /** * \brief Retrieves slice handle @@ -286,6 +296,7 @@ namespace dxvk { DxvkBufferCreateInfo m_info; DxvkMemoryAllocator* m_memAlloc; VkMemoryPropertyFlags m_memFlags; + VkShaderStageFlags m_shaderStages; DxvkBufferHandle m_buffer; DxvkBufferSliceHandle m_physSlice; diff --git a/src/dxvk/dxvk_util.h b/src/dxvk/dxvk_util.h index 94fd06ddf..181e448db 100644 --- a/src/dxvk/dxvk_util.h +++ b/src/dxvk/dxvk_util.h @@ -16,6 +16,18 @@ namespace dxvk::util { | (shaderStages & VK_SHADER_STAGE_COMPUTE_BIT) << 6; } + /** + * \brief Gets shader stage flags included in pipeline stages + * + * \param [in] pipelineStages Pipeline stage flags + * \returns Corresponding shader stage flags, if any + */ + inline VkShaderStageFlags shaderStages( + VkPipelineStageFlags pipelineStages) { + return ((pipelineStages >> 3) & VK_SHADER_STAGE_ALL_GRAPHICS) + | ((pipelineStages >> 6) & VK_SHADER_STAGE_COMPUTE_BIT); + } + /** * \brief Computes number of mip levels for an image * From 219853aa9f62da7f9df5630c350e65ba624cde63 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 16 Jun 2022 13:16:35 +0200 Subject: [PATCH 0056/1348] [dxvk] Rework dirty descriptor state tracking --- src/dxvk/dxvk_context.cpp | 123 ++++++++++++++++++---------------- src/dxvk/dxvk_context.h | 3 +- src/dxvk/dxvk_context_state.h | 2 - src/dxvk/dxvk_pipelayout.h | 78 +++++++++++++++++++++ 4 files changed, 147 insertions(+), 59 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index d01add70e..b80637854 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -53,7 +53,6 @@ namespace dxvk { DxvkContextFlag::GpDirtyFramebuffer, DxvkContextFlag::GpDirtyPipeline, DxvkContextFlag::GpDirtyPipelineState, - DxvkContextFlag::GpDirtyResources, DxvkContextFlag::GpDirtyVertexBuffers, DxvkContextFlag::GpDirtyIndexBuffer, DxvkContextFlag::GpDirtyXfbBuffers, @@ -64,8 +63,13 @@ namespace dxvk { DxvkContextFlag::GpDirtyDepthBounds, DxvkContextFlag::CpDirtyPipeline, DxvkContextFlag::CpDirtyPipelineState, - DxvkContextFlag::CpDirtyResources, DxvkContextFlag::DirtyDrawBuffer); + + m_descriptorState.dirtyStages( + VK_SHADER_STAGE_ALL_GRAPHICS | + VK_SHADER_STAGE_COMPUTE_BIT); + + m_descriptorState.clearSets(); } @@ -155,14 +159,10 @@ namespace dxvk { if (likely(needsUpdate)) m_rcTracked.clr(slot); - else - needsUpdate = m_rc[slot].bufferSlice.length() != buffer.length(); - - m_flags.set( - DxvkContextFlag::CpDirtyResources, - DxvkContextFlag::GpDirtyResources); m_rc[slot].bufferSlice = buffer; + + m_descriptorState.dirtyBuffers(stages); } @@ -178,9 +178,7 @@ namespace dxvk { : DxvkBufferSlice(); m_rcTracked.clr(slot); - m_flags.set( - DxvkContextFlag::CpDirtyResources, - DxvkContextFlag::GpDirtyResources); + m_descriptorState.dirtyViews(stages); } @@ -191,9 +189,7 @@ namespace dxvk { m_rc[slot].sampler = sampler; m_rcTracked.clr(slot); - m_flags.set( - DxvkContextFlag::CpDirtyResources, - DxvkContextFlag::GpDirtyResources); + m_descriptorState.dirtyViews(stages); } @@ -217,13 +213,11 @@ namespace dxvk { if (stage == VK_SHADER_STAGE_COMPUTE_BIT) { m_flags.set( DxvkContextFlag::CpDirtyPipeline, - DxvkContextFlag::CpDirtyPipelineState, - DxvkContextFlag::CpDirtyResources); + DxvkContextFlag::CpDirtyPipelineState); } else { m_flags.set( DxvkContextFlag::GpDirtyPipeline, - DxvkContextFlag::GpDirtyPipelineState, - DxvkContextFlag::GpDirtyResources); + DxvkContextFlag::GpDirtyPipelineState); } } @@ -1753,21 +1747,16 @@ namespace dxvk { ~(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT); - VkBufferUsageFlags resourceMask = - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | - VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | - VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | - VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; + if (usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) + m_descriptorState.dirtyBuffers(buffer->getShaderStages()); - if (usage & resourceMask) { - m_flags.set(DxvkContextFlag::GpDirtyResources, - DxvkContextFlag::CpDirtyResources); - } - - // Fast early-out for resource buffers, very common - if (likely(!(usage & ~resourceMask))) + // Fast early-out for plain buffers, very common + if (likely(!(usage & ~(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)))) return; + if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) + m_descriptorState.dirtyViews(buffer->getShaderStages()); + if (usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer); @@ -4014,19 +4003,26 @@ namespace dxvk { void DxvkContext::unbindComputePipeline() { m_flags.set( DxvkContextFlag::CpDirtyPipeline, - DxvkContextFlag::CpDirtyPipelineState, - DxvkContextFlag::CpDirtyResources); + DxvkContextFlag::CpDirtyPipelineState); + m_descriptorState.dirtyStages(VK_SHADER_STAGE_COMPUTE_BIT); + + m_state.cp.state.bsBindingMask.clear(); m_cpActivePipeline = VK_NULL_HANDLE; } bool DxvkContext::updateComputePipeline() { - m_state.cp.pipeline = lookupComputePipeline(m_state.cp.shaders); + auto newPipeline = lookupComputePipeline(m_state.cp.shaders); - if (unlikely(m_state.cp.pipeline == nullptr)) + m_state.cp.pipeline = newPipeline; + + if (unlikely(!newPipeline)) return false; - + + m_descriptorState.dirtyStages(VK_SHADER_STAGE_COMPUTE_BIT); + m_state.cp.state.bsBindingMask.clear(); + if (m_state.cp.pipeline->getBindings()->layout().getPushConstantRange().size) m_flags.set(DxvkContextFlag::DirtyPushConstants); @@ -4054,7 +4050,6 @@ namespace dxvk { m_flags.set( DxvkContextFlag::GpDirtyPipeline, DxvkContextFlag::GpDirtyPipelineState, - DxvkContextFlag::GpDirtyResources, DxvkContextFlag::GpDirtyVertexBuffers, DxvkContextFlag::GpDirtyIndexBuffer, DxvkContextFlag::GpDirtyXfbBuffers, @@ -4064,20 +4059,25 @@ namespace dxvk { DxvkContextFlag::GpDirtyDepthBias, DxvkContextFlag::GpDirtyDepthBounds); + m_descriptorState.dirtyStages(VK_SHADER_STAGE_ALL_GRAPHICS); + + m_state.gp.state.bsBindingMask.clear(); m_gpActivePipeline = VK_NULL_HANDLE; } bool DxvkContext::updateGraphicsPipeline() { - m_state.gp.pipeline = lookupGraphicsPipeline(m_state.gp.shaders); + auto newPipeline = lookupGraphicsPipeline(m_state.gp.shaders); - if (unlikely(m_state.gp.pipeline == nullptr)) { + m_state.gp.pipeline = newPipeline; + + if (unlikely(!newPipeline)) { m_state.gp.flags = DxvkGraphicsPipelineFlags(); return false; } - if (m_state.gp.flags != m_state.gp.pipeline->flags()) { - m_state.gp.flags = m_state.gp.pipeline->flags(); + if (m_state.gp.flags != newPipeline->flags()) { + m_state.gp.flags = newPipeline->flags(); // Force-update vertex/index buffers for hazard checks m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer, @@ -4091,7 +4091,10 @@ namespace dxvk { this->spillRenderPass(true); } - if (m_state.gp.pipeline->getBindings()->layout().getPushConstantRange().size) + m_descriptorState.dirtyStages(VK_SHADER_STAGE_ALL_GRAPHICS); + m_state.gp.state.bsBindingMask.clear(); + + if (newPipeline->getBindings()->layout().getPushConstantRange().size) m_flags.set(DxvkContextFlag::DirtyPushConstants); m_flags.clr(DxvkContextFlag::GpDirtyPipeline); @@ -4147,7 +4150,6 @@ namespace dxvk { template void DxvkContext::updateResourceBindings(const DxvkBindingLayoutObjects* layout) { - std::array sets = { VK_NULL_HANDLE, VK_NULL_HANDLE }; std::array descriptors; const auto& bindings = layout->layout(); @@ -4159,15 +4161,20 @@ namespace dxvk { DxvkBindingMask newBindMask = refBindMask; + uint32_t dirtySetMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS + ? m_descriptorState.getDirtyGraphicsSets() + : m_descriptorState.getDirtyComputeSets(); + uint32_t bindingIndex = 0; + uint32_t firstUpdated = DxvkDescriptorSets::SetCount; for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { // Initialize binding mask for the current set, only // clear bits if certain resources are actually unbound. uint32_t bindingCount = bindings.getBindingCount(i); - // TODO skip if set is unmodified - if (true) { + if ((dirtySetMask & (1u << i)) || !m_descriptorState.getSet(i)) { + firstUpdated = std::min(firstUpdated, i); newBindMask.setRange(bindingIndex, bindingCount); for (uint32_t j = 0; j < bindingCount; j++) { @@ -4310,23 +4317,27 @@ namespace dxvk { Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.descriptorType)); } } - } - // Create and populate descriptor set with the given descriptors - sets[i] = allocateDescriptorSet(layout->getSetLayout(i)); + // Create and populate descriptor set with the given descriptors + VkDescriptorSet& set = m_descriptorState.getSet(i); + set = allocateDescriptorSet(layout->getSetLayout(i)); - if (bindingCount) { - m_cmd->updateDescriptorSetWithTemplate(sets[i], - layout->getSetUpdateTemplate(i), descriptors.data()); + if (bindingCount) { + m_cmd->updateDescriptorSetWithTemplate(set, + layout->getSetUpdateTemplate(i), descriptors.data()); + } } bindingIndex += bindingCount; } - // Bind all required descriptor sets + // Bind all updated descriptor sets + uint32_t setCount = DxvkDescriptorSets::SetCount - firstUpdated; + const VkDescriptorSet* setData = &m_descriptorState.getSet(firstUpdated); + m_cmd->cmdBindDescriptorSets(BindPoint, layout->getPipelineLayout(), - 0, sets.size(), sets.data(), + firstUpdated, setCount, setData, 0, nullptr); // Update pipeline if there are unbound resources @@ -4343,14 +4354,14 @@ namespace dxvk { void DxvkContext::updateComputeShaderResources() { this->updateResourceBindings(m_state.cp.pipeline->getBindings()); - m_flags.clr(DxvkContextFlag::CpDirtyResources); + m_descriptorState.clearStages(VK_SHADER_STAGE_COMPUTE_BIT); } void DxvkContext::updateGraphicsShaderResources() { this->updateResourceBindings(m_state.gp.pipeline->getBindings()); - m_flags.clr(DxvkContextFlag::GpDirtyResources); + m_descriptorState.clearStages(VK_SHADER_STAGE_ALL_GRAPHICS); } @@ -4948,7 +4959,7 @@ namespace dxvk { return false; } - if (m_flags.test(DxvkContextFlag::CpDirtyResources)) + if (m_descriptorState.hasDirtyComputeSets()) this->updateComputeShaderResources(); if (m_flags.test(DxvkContextFlag::CpDirtyPipelineState)) { @@ -4990,7 +5001,7 @@ namespace dxvk { if (m_flags.test(DxvkContextFlag::GpDirtyVertexBuffers)) this->updateVertexBufferBindings(); - if (m_flags.test(DxvkContextFlag::GpDirtyResources)) + if (m_descriptorState.hasDirtyGraphicsSets()) this->updateGraphicsShaderResources(); if (m_flags.test(DxvkContextFlag::GpDirtyPipelineState)) { diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 727ba544f..d5e41db6d 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1047,6 +1047,7 @@ namespace dxvk { DxvkContextFlags m_flags; DxvkContextState m_state; DxvkContextFeatures m_features; + DxvkDescriptorState m_descriptorState; DxvkBarrierSet m_sdmaAcquires; DxvkBarrierSet m_sdmaBarriers; @@ -1055,7 +1056,7 @@ namespace dxvk { DxvkBarrierSet m_execBarriers; DxvkBarrierSet m_gfxBarriers; DxvkBarrierControlFlags m_barrierControl; - + DxvkGpuQueryManager m_queryManager; DxvkStagingBuffer m_staging; diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index b8bb46b8b..992e5dd13 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -27,7 +27,6 @@ namespace dxvk { GpDirtyFramebuffer, ///< Framebuffer binding is out of date GpDirtyPipeline, ///< Graphics pipeline binding is out of date GpDirtyPipelineState, ///< Graphics pipeline needs to be recompiled - GpDirtyResources, ///< Graphics pipeline resource bindings are out of date GpDirtyVertexBuffers, ///< Vertex buffer bindings are out of date GpDirtyIndexBuffer, ///< Index buffer binding are out of date GpDirtyXfbBuffers, ///< Transform feedback buffer bindings are out of date @@ -43,7 +42,6 @@ namespace dxvk { CpDirtyPipeline, ///< Compute pipeline binding are out of date CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled - CpDirtyResources, ///< Compute pipeline resource bindings are out of date DirtyDrawBuffer, ///< Indirect argument buffer is dirty DirtyPushConstants, ///< Push constant data has changed diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index ea43eb4cb..c2acbb5f4 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -470,6 +470,84 @@ namespace dxvk { }; + /** + * \brief Dirty descriptor set state + */ + class DxvkDescriptorState { + + public: + + void dirtyBuffers(VkShaderStageFlags stages) { + m_dirtyBuffers |= stages; + } + + void dirtyViews(VkShaderStageFlags stages) { + m_dirtyViews |= stages; + } + + void dirtyStages(VkShaderStageFlags stages) { + m_dirtyBuffers |= stages; + m_dirtyViews |= stages; + } + + void clearStages(VkShaderStageFlags stages) { + m_dirtyBuffers &= ~stages; + m_dirtyViews &= ~stages; + } + + bool hasDirtyGraphicsSets() const { + return (m_dirtyBuffers | m_dirtyViews) & (VK_SHADER_STAGE_ALL_GRAPHICS); + } + + bool hasDirtyComputeSets() const { + return (m_dirtyBuffers | m_dirtyViews) & (VK_SHADER_STAGE_COMPUTE_BIT); + } + + uint32_t getDirtyGraphicsSets() const { + uint32_t result = 0; + if (m_dirtyBuffers & VK_SHADER_STAGE_FRAGMENT_BIT) + result |= (1u << DxvkDescriptorSets::FsBuffers); + if (m_dirtyViews & VK_SHADER_STAGE_FRAGMENT_BIT) + result |= (1u << DxvkDescriptorSets::FsViews) | (1u << DxvkDescriptorSets::FsBuffers); + if ((m_dirtyBuffers | m_dirtyViews) & (VK_SHADER_STAGE_ALL_GRAPHICS & ~VK_SHADER_STAGE_FRAGMENT_BIT)) + result |= (1u << DxvkDescriptorSets::VsAll); + return result; + } + + uint32_t getDirtyComputeSets() const { + uint32_t result = 0; + if (m_dirtyBuffers & VK_SHADER_STAGE_COMPUTE_BIT) + result |= (1u << DxvkDescriptorSets::FsBuffers); + if (m_dirtyViews & VK_SHADER_STAGE_COMPUTE_BIT) + result |= (1u << DxvkDescriptorSets::FsViews) | (1u << DxvkDescriptorSets::FsBuffers); + return result; + } + + void clearSets() { + for (size_t i = 0; i < m_sets.size(); i++) + m_sets[i] = VK_NULL_HANDLE; + } + + template + VkDescriptorSet& getSet(uint32_t index) { + return m_sets[BindPoint * DxvkDescriptorSets::SetCount + index]; + } + + template + const VkDescriptorSet& getSet(uint32_t index) const { + return m_sets[BindPoint * DxvkDescriptorSets::SetCount + index]; + } + + private: + + VkShaderStageFlags m_dirtyBuffers = 0; + VkShaderStageFlags m_dirtyViews = 0; + + std::array m_sets; + + }; + + /** * \brief Resource slot * From f9e6d8e23a871425255bbb2980257218da791a93 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 16 Jun 2022 13:17:49 +0200 Subject: [PATCH 0057/1348] [dxvk] Remove old resource update code --- src/dxvk/dxvk_context.cpp | 193 -------------------------------------- src/dxvk/dxvk_context.h | 12 --- 2 files changed, 205 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b80637854..da05864fc 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4365,199 +4365,6 @@ namespace dxvk { } - template - void DxvkContext::updateShaderResources(const DxvkPipelineLayout* layout) { - std::array descriptors; - - // Assume that all bindings are active as a fast path - DxvkBindingMask bindMask; - bindMask.clear(); - bindMask.setRange(0, layout->bindingCount()); - - for (uint32_t i = 0; i < layout->bindingCount(); i++) { - const auto& binding = layout->binding(i); - const auto& res = m_rc[binding.slot]; - - switch (binding.type) { - case VK_DESCRIPTOR_TYPE_SAMPLER: - if (res.sampler != nullptr) { - descriptors[i].image.sampler = res.sampler->handle(); - descriptors[i].image.imageView = VK_NULL_HANDLE; - descriptors[i].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; - - if (m_rcTracked.set(binding.slot)) - m_cmd->trackResource(res.sampler); - } else { - descriptors[i].image = m_common->dummyResources().samplerDescriptor(); - } break; - - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - if (res.imageView != nullptr && res.imageView->handle(binding.view) != VK_NULL_HANDLE) { - descriptors[i].image.sampler = VK_NULL_HANDLE; - descriptors[i].image.imageView = res.imageView->handle(binding.view); - descriptors[i].image.imageLayout = res.imageView->imageInfo().layout; - - if (m_rcTracked.set(binding.slot)) { - m_cmd->trackResource(res.imageView); - m_cmd->trackResource(res.imageView->image()); - } - } else { - bindMask.clr(i); - descriptors[i].image = m_common->dummyResources().imageViewDescriptor(binding.view, true); - } break; - - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - if (res.imageView != nullptr && res.imageView->handle(binding.view) != VK_NULL_HANDLE) { - descriptors[i].image.sampler = VK_NULL_HANDLE; - descriptors[i].image.imageView = res.imageView->handle(binding.view); - descriptors[i].image.imageLayout = res.imageView->imageInfo().layout; - - if (m_rcTracked.set(binding.slot)) { - m_cmd->trackResource(res.imageView); - m_cmd->trackResource(res.imageView->image()); - } - } else { - bindMask.clr(i); - descriptors[i].image = m_common->dummyResources().imageViewDescriptor(binding.view, false); - } break; - - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - if (res.sampler != nullptr && res.imageView != nullptr - && res.imageView->handle(binding.view) != VK_NULL_HANDLE) { - descriptors[i].image.sampler = res.sampler->handle(); - descriptors[i].image.imageView = res.imageView->handle(binding.view); - descriptors[i].image.imageLayout = res.imageView->imageInfo().layout; - - if (m_rcTracked.set(binding.slot)) { - m_cmd->trackResource(res.sampler); - m_cmd->trackResource(res.imageView); - m_cmd->trackResource(res.imageView->image()); - } - } else { - bindMask.clr(i); - descriptors[i].image = m_common->dummyResources().imageSamplerDescriptor(binding.view); - } break; - - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - if (res.bufferView != nullptr) { - res.bufferView->updateView(); - descriptors[i].texelBuffer = res.bufferView->handle(); - - if (m_rcTracked.set(binding.slot)) { - m_cmd->trackResource(res.bufferView); - m_cmd->trackResource(res.bufferView->buffer()); - } - } else { - bindMask.clr(i); - descriptors[i].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); - } break; - - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - if (res.bufferView != nullptr) { - res.bufferView->updateView(); - descriptors[i].texelBuffer = res.bufferView->handle(); - - if (m_rcTracked.set(binding.slot)) { - m_cmd->trackResource(res.bufferView); - m_cmd->trackResource(res.bufferView->buffer()); - } - } else { - bindMask.clr(i); - descriptors[i].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); - } break; - - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - if (res.bufferSlice.defined()) { - descriptors[i] = res.bufferSlice.getDescriptor(); - - if (m_rcTracked.set(binding.slot)) - m_cmd->trackResource(res.bufferSlice.buffer()); - } else { - bindMask.clr(i); - descriptors[i].buffer = m_common->dummyResources().bufferDescriptor(); - } break; - - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - if (res.bufferSlice.defined()) { - descriptors[i] = res.bufferSlice.getDescriptor(); - - if (m_rcTracked.set(binding.slot)) - m_cmd->trackResource(res.bufferSlice.buffer()); - } else { - bindMask.clr(i); - descriptors[i].buffer = m_common->dummyResources().bufferDescriptor(); - } break; - - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - if (res.bufferSlice.defined()) { - descriptors[i] = res.bufferSlice.getDescriptor(); - descriptors[i].buffer.offset = 0; - - if (m_rcTracked.set(binding.slot)) - m_cmd->trackResource(res.bufferSlice.buffer()); - } else { - bindMask.clr(i); - descriptors[i].buffer = m_common->dummyResources().bufferDescriptor(); - } break; - - default: - Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.type)); - } - } - - // Allocate and update descriptor set - auto& set = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ? m_gpSet : m_cpSet; - - if (layout->bindingCount()) { - set = allocateDescriptorSet(layout->descriptorSetLayout()); - - m_cmd->updateDescriptorSetWithTemplate(set, - layout->descriptorTemplate(), descriptors.data()); - } else { - set = VK_NULL_HANDLE; - } - - // Select the active binding mask to update - auto& refMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS - ? m_state.gp.state.bsBindingMask - : m_state.cp.state.bsBindingMask; - - // If some resources are not bound, we may need to - // update spec constants and rebind the pipeline - if (refMask != bindMask) { - refMask = bindMask; - - m_flags.set(BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS - ? DxvkContextFlag::GpDirtyPipelineState - : DxvkContextFlag::CpDirtyPipelineState); - } - } - - - template - void DxvkContext::updateShaderDescriptorSetBinding( - VkDescriptorSet set, - const DxvkPipelineLayout* layout) { - if (set) { - std::array offsets; - - for (uint32_t i = 0; i < layout->dynamicBindingCount(); i++) { - const auto& binding = layout->dynamicBinding(i); - const auto& res = m_rc[binding.slot]; - - offsets[i] = res.bufferSlice.defined() - ? res.bufferSlice.getDynamicOffset() - : 0; - } - - m_cmd->cmdBindDescriptorSet(BindPoint, - layout->pipelineLayout(), set, - layout->dynamicBindingCount(), - offsets.data()); - } - } - - DxvkFramebufferInfo DxvkContext::makeFramebufferInfo( const DxvkRenderTargets& renderTargets) { auto renderPassFormat = DxvkFramebufferInfo::getRenderPassFormat(renderTargets); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index d5e41db6d..62c331a7c 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1065,9 +1065,6 @@ namespace dxvk { VkPipeline m_gpActivePipeline = VK_NULL_HANDLE; VkPipeline m_cpActivePipeline = VK_NULL_HANDLE; - VkDescriptorSet m_gpSet = VK_NULL_HANDLE; - VkDescriptorSet m_cpSet = VK_NULL_HANDLE; - DxvkBindingSet m_vbTracked; DxvkBindingSet m_rcTracked; @@ -1225,15 +1222,6 @@ namespace dxvk { void updateComputeShaderResources(); void updateGraphicsShaderResources(); - template - void updateShaderResources( - const DxvkPipelineLayout* layout); - - template - void updateShaderDescriptorSetBinding( - VkDescriptorSet set, - const DxvkPipelineLayout* layout); - DxvkFramebufferInfo makeFramebufferInfo( const DxvkRenderTargets& renderTargets); From 15cf1303698be81e46e2fe1b740361b117a9727f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 16 Jun 2022 15:13:14 +0200 Subject: [PATCH 0058/1348] [dxvk] Optimize descriptor set binding further --- src/dxvk/dxvk_context.cpp | 278 +++++++++++++++++++------------------- 1 file changed, 142 insertions(+), 136 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index da05864fc..774c0a179 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4161,184 +4161,190 @@ namespace dxvk { DxvkBindingMask newBindMask = refBindMask; + uint32_t layoutSetMask = layout->getSetMask(); + uint32_t dirtySetMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ? m_descriptorState.getDirtyGraphicsSets() : m_descriptorState.getDirtyComputeSets(); + dirtySetMask &= layoutSetMask; - uint32_t bindingIndex = 0; - uint32_t firstUpdated = DxvkDescriptorSets::SetCount; + uint32_t firstUpdated = bit::tzcnt(dirtySetMask); + + while (dirtySetMask) { + uint32_t setIndex = bit::tzcnt(dirtySetMask); - for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { // Initialize binding mask for the current set, only // clear bits if certain resources are actually unbound. - uint32_t bindingCount = bindings.getBindingCount(i); + uint32_t bindingIndex = layout->getFirstBinding(setIndex); + uint32_t bindingCount = bindings.getBindingCount(setIndex); - if ((dirtySetMask & (1u << i)) || !m_descriptorState.getSet(i)) { - firstUpdated = std::min(firstUpdated, i); - newBindMask.setRange(bindingIndex, bindingCount); + newBindMask.setRange(bindingIndex, bindingCount); - for (uint32_t j = 0; j < bindingCount; j++) { - const auto& binding = bindings.getBinding(i, j); + for (uint32_t j = 0; j < bindingCount; j++) { + const auto& binding = bindings.getBinding(setIndex, j); - switch (binding.descriptorType) { - case VK_DESCRIPTOR_TYPE_SAMPLER: { - const auto& res = m_rc[binding.resourceBinding]; + switch (binding.descriptorType) { + case VK_DESCRIPTOR_TYPE_SAMPLER: { + const auto& res = m_rc[binding.resourceBinding]; - if (res.sampler != nullptr) { - descriptors[j].image.sampler = res.sampler->handle(); - descriptors[j].image.imageView = VK_NULL_HANDLE; - descriptors[j].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + if (res.sampler != nullptr) { + descriptors[j].image.sampler = res.sampler->handle(); + descriptors[j].image.imageView = VK_NULL_HANDLE; + descriptors[j].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; - if (m_rcTracked.set(binding.resourceBinding)) - m_cmd->trackResource(res.sampler); - } else { - descriptors[j].image = m_common->dummyResources().samplerDescriptor(); + if (m_rcTracked.set(binding.resourceBinding)) + m_cmd->trackResource(res.sampler); + } else { + descriptors[j].image = m_common->dummyResources().samplerDescriptor(); + } + } break; + + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: { + const auto& res = m_rc[binding.resourceBinding]; + + if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { + descriptors[j].image.sampler = VK_NULL_HANDLE; + descriptors[j].image.imageView = res.imageView->handle(binding.viewType); + descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; + + if (m_rcTracked.set(binding.resourceBinding)) { + m_cmd->trackResource(res.imageView); + m_cmd->trackResource(res.imageView->image()); } - } break; + } else { + descriptors[j].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, true); + newBindMask.clr(bindingIndex + j); + } + } break; - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: { - const auto& res = m_rc[binding.resourceBinding]; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: { + const auto& res = m_rc[binding.resourceBinding]; - if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - descriptors[j].image.sampler = VK_NULL_HANDLE; - descriptors[j].image.imageView = res.imageView->handle(binding.viewType); - descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; + if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { + descriptors[j].image.sampler = VK_NULL_HANDLE; + descriptors[j].image.imageView = res.imageView->handle(binding.viewType); + descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; - if (m_rcTracked.set(binding.resourceBinding)) { - m_cmd->trackResource(res.imageView); - m_cmd->trackResource(res.imageView->image()); - } - } else { - descriptors[j].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, true); - newBindMask.clr(bindingIndex + j); + if (m_rcTracked.set(binding.resourceBinding)) { + m_cmd->trackResource(res.imageView); + m_cmd->trackResource(res.imageView->image()); } - } break; + } else { + descriptors[j].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, false); + newBindMask.clr(bindingIndex + j); + } + } break; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: { - const auto& res = m_rc[binding.resourceBinding]; + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { + const auto& res = m_rc[binding.resourceBinding]; - if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - descriptors[j].image.sampler = VK_NULL_HANDLE; - descriptors[j].image.imageView = res.imageView->handle(binding.viewType); - descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; + if (res.sampler != nullptr && res.imageView != nullptr + && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { + descriptors[j].image.sampler = res.sampler->handle(); + descriptors[j].image.imageView = res.imageView->handle(binding.viewType); + descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; - if (m_rcTracked.set(binding.resourceBinding)) { - m_cmd->trackResource(res.imageView); - m_cmd->trackResource(res.imageView->image()); - } - } else { - descriptors[j].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, false); - newBindMask.clr(bindingIndex + j); + if (m_rcTracked.set(binding.resourceBinding)) { + m_cmd->trackResource(res.sampler); + m_cmd->trackResource(res.imageView); + m_cmd->trackResource(res.imageView->image()); } - } break; + } else { + descriptors[j].image = m_common->dummyResources().imageSamplerDescriptor(binding.viewType); + newBindMask.clr(bindingIndex + j); + } + } break; - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { - const auto& res = m_rc[binding.resourceBinding]; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: { + const auto& res = m_rc[binding.resourceBinding]; - if (res.sampler != nullptr && res.imageView != nullptr - && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - descriptors[j].image.sampler = res.sampler->handle(); - descriptors[j].image.imageView = res.imageView->handle(binding.viewType); - descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; + if (res.bufferView != nullptr) { + res.bufferView->updateView(); + descriptors[j].texelBuffer = res.bufferView->handle(); - if (m_rcTracked.set(binding.resourceBinding)) { - m_cmd->trackResource(res.sampler); - m_cmd->trackResource(res.imageView); - m_cmd->trackResource(res.imageView->image()); - } - } else { - descriptors[j].image = m_common->dummyResources().imageSamplerDescriptor(binding.viewType); - newBindMask.clr(bindingIndex + j); + if (m_rcTracked.set(binding.resourceBinding)) { + m_cmd->trackResource(res.bufferView); + m_cmd->trackResource(res.bufferView->buffer()); } - } break; + } else { + descriptors[j].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); + newBindMask.clr(bindingIndex + j); + } + } break; - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: { - const auto& res = m_rc[binding.resourceBinding]; + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: { + const auto& res = m_rc[binding.resourceBinding]; - if (res.bufferView != nullptr) { - res.bufferView->updateView(); - descriptors[j].texelBuffer = res.bufferView->handle(); + if (res.bufferView != nullptr) { + res.bufferView->updateView(); + descriptors[j].texelBuffer = res.bufferView->handle(); - if (m_rcTracked.set(binding.resourceBinding)) { - m_cmd->trackResource(res.bufferView); - m_cmd->trackResource(res.bufferView->buffer()); - } - } else { - descriptors[j].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); - newBindMask.clr(bindingIndex + j); + if (m_rcTracked.set(binding.resourceBinding)) { + m_cmd->trackResource(res.bufferView); + m_cmd->trackResource(res.bufferView->buffer()); } - } break; + } else { + descriptors[j].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); + newBindMask.clr(bindingIndex + j); + } + } break; - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: { - const auto& res = m_rc[binding.resourceBinding]; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: { + const auto& res = m_rc[binding.resourceBinding]; - if (res.bufferView != nullptr) { - res.bufferView->updateView(); - descriptors[j].texelBuffer = res.bufferView->handle(); + if (res.bufferSlice.defined()) { + descriptors[j] = res.bufferSlice.getDescriptor(); - if (m_rcTracked.set(binding.resourceBinding)) { - m_cmd->trackResource(res.bufferView); - m_cmd->trackResource(res.bufferView->buffer()); - } - } else { - descriptors[j].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); - newBindMask.clr(bindingIndex + j); - } - } break; + if (m_rcTracked.set(binding.resourceBinding)) + m_cmd->trackResource(res.bufferSlice.buffer()); + } else { + descriptors[j].buffer = m_common->dummyResources().bufferDescriptor(); + } + } break; - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: { - const auto& res = m_rc[binding.resourceBinding]; + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: { + const auto& res = m_rc[binding.resourceBinding]; - if (res.bufferSlice.defined()) { - descriptors[j] = res.bufferSlice.getDescriptor(); + if (res.bufferSlice.defined()) { + descriptors[j] = res.bufferSlice.getDescriptor(); - if (m_rcTracked.set(binding.resourceBinding)) - m_cmd->trackResource(res.bufferSlice.buffer()); - } else { - descriptors[j].buffer = m_common->dummyResources().bufferDescriptor(); - } - } break; + if (m_rcTracked.set(binding.resourceBinding)) + m_cmd->trackResource(res.bufferSlice.buffer()); + } else { + descriptors[j].buffer = m_common->dummyResources().bufferDescriptor(); + newBindMask.clr(bindingIndex + j); + } + } break; - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: { - const auto& res = m_rc[binding.resourceBinding]; - - if (res.bufferSlice.defined()) { - descriptors[j] = res.bufferSlice.getDescriptor(); - - if (m_rcTracked.set(binding.resourceBinding)) - m_cmd->trackResource(res.bufferSlice.buffer()); - } else { - descriptors[j].buffer = m_common->dummyResources().bufferDescriptor(); - newBindMask.clr(bindingIndex + j); - } - } break; - - default: - Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.descriptorType)); - } - } - - // Create and populate descriptor set with the given descriptors - VkDescriptorSet& set = m_descriptorState.getSet(i); - set = allocateDescriptorSet(layout->getSetLayout(i)); - - if (bindingCount) { - m_cmd->updateDescriptorSetWithTemplate(set, - layout->getSetUpdateTemplate(i), descriptors.data()); + default: + Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.descriptorType)); } } - bindingIndex += bindingCount; + // Create and populate descriptor set with the given descriptors + VkDescriptorSet& set = m_descriptorState.getSet(setIndex); + set = allocateDescriptorSet(layout->getSetLayout(setIndex)); + + m_cmd->updateDescriptorSetWithTemplate(set, + layout->getSetUpdateTemplate(setIndex), descriptors.data()); + + dirtySetMask &= dirtySetMask - 1; } - // Bind all updated descriptor sets - uint32_t setCount = DxvkDescriptorSets::SetCount - firstUpdated; - const VkDescriptorSet* setData = &m_descriptorState.getSet(firstUpdated); + // Bind all descriptor sets that need updating + uint32_t bindSetMask = layoutSetMask & ~((1u << firstUpdated) - 1); - m_cmd->cmdBindDescriptorSets(BindPoint, - layout->getPipelineLayout(), - firstUpdated, setCount, setData, - 0, nullptr); + while (bindSetMask) { + uint32_t setIndex = bit::tzcnt(bindSetMask); + + VkDescriptorSet& set = m_descriptorState.getSet(setIndex); + + m_cmd->cmdBindDescriptorSets(BindPoint, + layout->getPipelineLayout(), + setIndex, 1, &set, 0, nullptr); + + bindSetMask &= bindSetMask - 1; + } // Update pipeline if there are unbound resources if (refBindMask != newBindMask) { From f34d1c886a2be5ab35a23cb8eea6f861627680d0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 16 Jun 2022 17:08:56 +0200 Subject: [PATCH 0059/1348] [dxvk] Only use descriptor update templates in 32-bit builds --- src/dxvk/dxvk_context.cpp | 94 +++++++++++++++++++++++++------------- src/dxvk/dxvk_context.h | 3 ++ src/dxvk/dxvk_pipelayout.h | 2 +- 3 files changed, 66 insertions(+), 33 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 774c0a179..8752ff6f7 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -26,6 +26,19 @@ namespace dxvk { // Init framebuffer info with default render pass in case // the app does not explicitly bind any render targets m_state.om.framebufferInfo = makeFramebufferInfo(m_state.om.renderTargets); + + for (uint32_t i = 0; i < MaxNumActiveBindings; i++) { + m_descriptorWrites[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + m_descriptorWrites[i].pNext = nullptr; + m_descriptorWrites[i].dstSet = VK_NULL_HANDLE; + m_descriptorWrites[i].dstBinding = 0; + m_descriptorWrites[i].dstArrayElement = 0; + m_descriptorWrites[i].descriptorCount = 1; + m_descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_MAX_ENUM; + m_descriptorWrites[i].pImageInfo = &m_descriptors[i].image; + m_descriptorWrites[i].pBufferInfo = &m_descriptors[i].buffer; + m_descriptorWrites[i].pTexelBufferView = &m_descriptors[i].texelBuffer; + } } @@ -4150,10 +4163,13 @@ namespace dxvk { template void DxvkContext::updateResourceBindings(const DxvkBindingLayoutObjects* layout) { - std::array descriptors; - const auto& bindings = layout->layout(); + // On 32-bit wine, vkUpdateDescriptorSets has significant overhead due + // to struct conversion, so we should use descriptor update templates. + // For 64-bit applications, using templates is slower on some drivers. + constexpr bool useDescriptorTemplates = env::is32BitHostPlatform(); + // This relies on the bind mask being cleared when the pipeline layout changes. DxvkBindingMask& refBindMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ? m_state.gp.state.bsBindingMask @@ -4169,6 +4185,7 @@ namespace dxvk { dirtySetMask &= layoutSetMask; uint32_t firstUpdated = bit::tzcnt(dirtySetMask); + uint32_t k = 0; while (dirtySetMask) { uint32_t setIndex = bit::tzcnt(dirtySetMask); @@ -4180,22 +4197,31 @@ namespace dxvk { newBindMask.setRange(bindingIndex, bindingCount); + VkDescriptorSet& set = m_descriptorState.getSet(setIndex); + set = allocateDescriptorSet(layout->getSetLayout(setIndex)); + for (uint32_t j = 0; j < bindingCount; j++) { const auto& binding = bindings.getBinding(setIndex, j); + if (!useDescriptorTemplates) { + m_descriptorWrites[k].dstSet = set; + m_descriptorWrites[k].dstBinding = j; + m_descriptorWrites[k].descriptorType = binding.descriptorType; + } + switch (binding.descriptorType) { case VK_DESCRIPTOR_TYPE_SAMPLER: { const auto& res = m_rc[binding.resourceBinding]; if (res.sampler != nullptr) { - descriptors[j].image.sampler = res.sampler->handle(); - descriptors[j].image.imageView = VK_NULL_HANDLE; - descriptors[j].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + m_descriptors[k].image.sampler = res.sampler->handle(); + m_descriptors[k].image.imageView = VK_NULL_HANDLE; + m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.sampler); } else { - descriptors[j].image = m_common->dummyResources().samplerDescriptor(); + m_descriptors[k].image = m_common->dummyResources().samplerDescriptor(); } } break; @@ -4203,16 +4229,16 @@ namespace dxvk { const auto& res = m_rc[binding.resourceBinding]; if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - descriptors[j].image.sampler = VK_NULL_HANDLE; - descriptors[j].image.imageView = res.imageView->handle(binding.viewType); - descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; + m_descriptors[k].image.sampler = VK_NULL_HANDLE; + m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); + m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout; if (m_rcTracked.set(binding.resourceBinding)) { m_cmd->trackResource(res.imageView); m_cmd->trackResource(res.imageView->image()); } } else { - descriptors[j].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, true); + m_descriptors[k].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, true); newBindMask.clr(bindingIndex + j); } } break; @@ -4221,16 +4247,16 @@ namespace dxvk { const auto& res = m_rc[binding.resourceBinding]; if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - descriptors[j].image.sampler = VK_NULL_HANDLE; - descriptors[j].image.imageView = res.imageView->handle(binding.viewType); - descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; + m_descriptors[k].image.sampler = VK_NULL_HANDLE; + m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); + m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout; if (m_rcTracked.set(binding.resourceBinding)) { m_cmd->trackResource(res.imageView); m_cmd->trackResource(res.imageView->image()); } } else { - descriptors[j].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, false); + m_descriptors[k].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, false); newBindMask.clr(bindingIndex + j); } } break; @@ -4240,9 +4266,9 @@ namespace dxvk { if (res.sampler != nullptr && res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - descriptors[j].image.sampler = res.sampler->handle(); - descriptors[j].image.imageView = res.imageView->handle(binding.viewType); - descriptors[j].image.imageLayout = res.imageView->imageInfo().layout; + m_descriptors[k].image.sampler = res.sampler->handle(); + m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); + m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout; if (m_rcTracked.set(binding.resourceBinding)) { m_cmd->trackResource(res.sampler); @@ -4250,7 +4276,7 @@ namespace dxvk { m_cmd->trackResource(res.imageView->image()); } } else { - descriptors[j].image = m_common->dummyResources().imageSamplerDescriptor(binding.viewType); + m_descriptors[k].image = m_common->dummyResources().imageSamplerDescriptor(binding.viewType); newBindMask.clr(bindingIndex + j); } } break; @@ -4260,14 +4286,14 @@ namespace dxvk { if (res.bufferView != nullptr) { res.bufferView->updateView(); - descriptors[j].texelBuffer = res.bufferView->handle(); + m_descriptors[k].texelBuffer = res.bufferView->handle(); if (m_rcTracked.set(binding.resourceBinding)) { m_cmd->trackResource(res.bufferView); m_cmd->trackResource(res.bufferView->buffer()); } } else { - descriptors[j].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); + m_descriptors[k].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); newBindMask.clr(bindingIndex + j); } } break; @@ -4277,14 +4303,14 @@ namespace dxvk { if (res.bufferView != nullptr) { res.bufferView->updateView(); - descriptors[j].texelBuffer = res.bufferView->handle(); + m_descriptors[k].texelBuffer = res.bufferView->handle(); if (m_rcTracked.set(binding.resourceBinding)) { m_cmd->trackResource(res.bufferView); m_cmd->trackResource(res.bufferView->buffer()); } } else { - descriptors[j].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); + m_descriptors[k].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); newBindMask.clr(bindingIndex + j); } } break; @@ -4293,12 +4319,12 @@ namespace dxvk { const auto& res = m_rc[binding.resourceBinding]; if (res.bufferSlice.defined()) { - descriptors[j] = res.bufferSlice.getDescriptor(); + m_descriptors[k] = res.bufferSlice.getDescriptor(); if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.bufferSlice.buffer()); } else { - descriptors[j].buffer = m_common->dummyResources().bufferDescriptor(); + m_descriptors[k].buffer = m_common->dummyResources().bufferDescriptor(); } } break; @@ -4306,12 +4332,12 @@ namespace dxvk { const auto& res = m_rc[binding.resourceBinding]; if (res.bufferSlice.defined()) { - descriptors[j] = res.bufferSlice.getDescriptor(); + m_descriptors[k] = res.bufferSlice.getDescriptor(); if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.bufferSlice.buffer()); } else { - descriptors[j].buffer = m_common->dummyResources().bufferDescriptor(); + m_descriptors[k].buffer = m_common->dummyResources().bufferDescriptor(); newBindMask.clr(bindingIndex + j); } } break; @@ -4319,18 +4345,22 @@ namespace dxvk { default: Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.descriptorType)); } + + k += 1; } - // Create and populate descriptor set with the given descriptors - VkDescriptorSet& set = m_descriptorState.getSet(setIndex); - set = allocateDescriptorSet(layout->getSetLayout(setIndex)); - - m_cmd->updateDescriptorSetWithTemplate(set, - layout->getSetUpdateTemplate(setIndex), descriptors.data()); + if (useDescriptorTemplates) { + m_cmd->updateDescriptorSetWithTemplate(set, + layout->getSetUpdateTemplate(setIndex), + &m_descriptors[k - bindingCount]); + } dirtySetMask &= dirtySetMask - 1; } + if (!useDescriptorTemplates && k) + m_cmd->updateDescriptorSets(k, m_descriptorWrites.data()); + // Bind all descriptor sets that need updating uint32_t bindSetMask = layoutSetMask & ~((1u << firstUpdated) - 1); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 62c331a7c..874da38a7 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1070,6 +1070,9 @@ namespace dxvk { std::vector m_deferredClears; + std::array m_descriptorWrites; + std::array m_descriptors; + std::array m_rc; std::array m_gpLookupCache = { }; std::array m_cpLookupCache = { }; diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index c2acbb5f4..81a9ae510 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -235,7 +235,7 @@ namespace dxvk { /** * \brief Queries descriptor template - * \returns Descriptor set template + * \returns Descriptor update template */ VkDescriptorUpdateTemplate getSetUpdateTemplate() const { return m_template; From 8dde72da06f9781438e953ce93e031c299b623ff Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 19 Jun 2022 13:31:25 +0200 Subject: [PATCH 0060/1348] [dxvk] Do not allocate descriptor set space for dynamic UBOs --- src/dxvk/dxvk_descriptor.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index cdd2ae67b..8529c0ba3 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -7,7 +7,7 @@ namespace dxvk { : m_vkd(vkd) { constexpr uint32_t MaxSets = 2048; - std::array pools = {{ + std::array pools = {{ { VK_DESCRIPTOR_TYPE_SAMPLER, MaxSets * 2 }, { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, MaxSets * 3 }, { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, MaxSets / 8 }, @@ -15,7 +15,6 @@ namespace dxvk { { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, MaxSets / 8 }, { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, MaxSets * 3 }, { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, MaxSets / 8 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, MaxSets * 3 }, { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MaxSets * 2 } }}; VkDescriptorPoolCreateInfo info; From ab0c15ea54f743ebb96c890616ff7b9c6502d70c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 21 Jun 2022 23:17:26 +0200 Subject: [PATCH 0061/1348] [dxvk] Introduce DxvkContextType --- src/d3d11/d3d11_context_imm.cpp | 2 +- src/d3d11/d3d11_initializer.cpp | 2 +- src/d3d11/d3d11_swapchain.cpp | 2 +- src/d3d9/d3d9_device.cpp | 2 +- src/d3d9/d3d9_format_helpers.cpp | 2 +- src/d3d9/d3d9_initializer.cpp | 2 +- src/d3d9/d3d9_swapchain.cpp | 2 +- src/dxvk/dxvk_context.cpp | 3 ++- src/dxvk/dxvk_context.h | 3 ++- src/dxvk/dxvk_descriptor.h | 10 ++++++++++ src/dxvk/dxvk_device.cpp | 4 ++-- src/dxvk/dxvk_device.h | 3 ++- src/dxvk/dxvk_unbound.cpp | 2 +- 13 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 0ff64e25e..536aef856 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -13,7 +13,7 @@ namespace dxvk { D3D11Device* pParent, const Rc& Device) : D3D11DeviceContext(pParent, Device, DxvkCsChunkFlag::SingleUse), - m_csThread(Device, Device->createContext()), + m_csThread(Device, Device->createContext(DxvkContextType::Primary)), m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize), m_videoContext(this, Device) { EmitCs([ diff --git a/src/d3d11/d3d11_initializer.cpp b/src/d3d11/d3d11_initializer.cpp index 863c453e7..cfe0e9bcc 100644 --- a/src/d3d11/d3d11_initializer.cpp +++ b/src/d3d11/d3d11_initializer.cpp @@ -9,7 +9,7 @@ namespace dxvk { D3D11Device* pParent) : m_parent(pParent), m_device(pParent->GetDXVKDevice()), - m_context(m_device->createContext()) { + m_context(m_device->createContext(DxvkContextType::Supplementary)) { m_context->beginRecording( m_device->createCommandList()); } diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 56c51a7b8..b6ba21e17 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -21,7 +21,7 @@ namespace dxvk { m_window (hWnd), m_desc (*pDesc), m_device (pDevice->GetDXVKDevice()), - m_context (m_device->createContext()), + m_context (m_device->createContext(DxvkContextType::Supplementary)), m_frameLatencyCap(pDevice->GetOptions()->maxFrameLatency) { CreateFrameLatencyEvent(); diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 4b9a74224..f2411de8d 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -49,7 +49,7 @@ namespace dxvk { , m_d3d9Options ( dxvkDevice, pParent->GetInstance()->config() ) , m_multithread ( BehaviorFlags & D3DCREATE_MULTITHREADED ) , m_isSWVP ( (BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) ? true : false ) - , m_csThread ( dxvkDevice, dxvkDevice->createContext() ) + , m_csThread ( dxvkDevice, dxvkDevice->createContext(DxvkContextType::Primary) ) , m_csChunk ( AllocCsChunk() ) { // If we can SWVP, then we use an extended constant set // as SWVP has many more slots available than HWVP. diff --git a/src/d3d9/d3d9_format_helpers.cpp b/src/d3d9/d3d9_format_helpers.cpp index 2615aa49a..0ccfba350 100644 --- a/src/d3d9/d3d9_format_helpers.cpp +++ b/src/d3d9/d3d9_format_helpers.cpp @@ -10,7 +10,7 @@ namespace dxvk { D3D9FormatHelper::D3D9FormatHelper(const Rc& device) - : m_device(device), m_context(m_device->createContext()) { + : m_device(device), m_context(m_device->createContext(DxvkContextType::Supplementary)) { m_context->beginRecording( m_device->createCommandList()); diff --git a/src/d3d9/d3d9_initializer.cpp b/src/d3d9/d3d9_initializer.cpp index 22088c9b2..daf60cb0a 100644 --- a/src/d3d9/d3d9_initializer.cpp +++ b/src/d3d9/d3d9_initializer.cpp @@ -6,7 +6,7 @@ namespace dxvk { D3D9Initializer::D3D9Initializer( const Rc& Device) - : m_device(Device), m_context(m_device->createContext()) { + : m_device(Device), m_context(m_device->createContext(DxvkContextType::Supplementary)) { m_context->beginRecording( m_device->createCommandList()); } diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index a17991174..4422913cb 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -190,7 +190,7 @@ namespace dxvk { const D3DDISPLAYMODEEX* pFullscreenDisplayMode) : D3D9SwapChainExBase(pDevice) , m_device (pDevice->GetDXVKDevice()) - , m_context (m_device->createContext()) + , m_context (m_device->createContext(DxvkContextType::Supplementary)) , m_frameLatencyCap (pDevice->GetOptions()->maxFrameLatency) , m_frameLatencySignal(new sync::Fence(m_frameId)) , m_dialog (pDevice->GetOptions()->enableDialogMode) { diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 8752ff6f7..abd2318fc 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -7,8 +7,9 @@ namespace dxvk { - DxvkContext::DxvkContext(const Rc& device) + DxvkContext::DxvkContext(const Rc& device, DxvkContextType type) : m_device (device), + m_type (type), m_common (&device->m_objects), m_sdmaAcquires(DxvkCmdBuffer::SdmaBuffer), m_sdmaBarriers(DxvkCmdBuffer::SdmaBuffer), diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 874da38a7..56ced3d4e 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -22,7 +22,7 @@ namespace dxvk { constexpr static VkDeviceSize StagingBufferSize = 4ull << 20; public: - DxvkContext(const Rc& device); + DxvkContext(const Rc& device, DxvkContextType type); ~DxvkContext(); /** @@ -1038,6 +1038,7 @@ namespace dxvk { private: Rc m_device; + DxvkContextType m_type; DxvkObjects* m_common; Rc m_cmd; diff --git a/src/dxvk/dxvk_descriptor.h b/src/dxvk/dxvk_descriptor.h index 243e6b0a2..6c8c8d4c5 100644 --- a/src/dxvk/dxvk_descriptor.h +++ b/src/dxvk/dxvk_descriptor.h @@ -8,6 +8,16 @@ namespace dxvk { class DxvkDevice; + /** + * \brief DXVK context type + * + * Used as a hint to optimize certain usage patterns. + */ + enum class DxvkContextType : uint32_t { + Primary = 0, + Supplementary = 1, + }; + /** * \brief Descriptor info * diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index a31be08da..5795455d6 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -94,8 +94,8 @@ namespace dxvk { } - Rc DxvkDevice::createContext() { - return new DxvkContext(this); + Rc DxvkDevice::createContext(DxvkContextType type) { + return new DxvkContext(this, type); } diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 227e66c69..0d1ac5cc7 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -244,9 +244,10 @@ namespace dxvk { * * Creates a context object that can * be used to record command buffers. + * \param [in] type Context type * \returns The context object */ - Rc createContext(); + Rc createContext(DxvkContextType type); /** * \brief Creates a GPU event diff --git a/src/dxvk/dxvk_unbound.cpp b/src/dxvk/dxvk_unbound.cpp index 852672418..7ea2f1db5 100644 --- a/src/dxvk/dxvk_unbound.cpp +++ b/src/dxvk/dxvk_unbound.cpp @@ -21,7 +21,7 @@ namespace dxvk { void DxvkUnboundResources::clearResources(DxvkDevice* dev) { - const Rc ctx = dev->createContext(); + const Rc ctx = dev->createContext(DxvkContextType::Supplementary); ctx->beginRecording(dev->createCommandList()); this->clearBuffer(ctx, m_buffer); From 5610b3a742df139a3c27fd5c60e4bd7ad3659db0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 22 Jun 2022 00:38:44 +0200 Subject: [PATCH 0062/1348] [dxvk] Introduce endFrame method --- src/dxvk/dxvk_context.cpp | 5 +++++ src/dxvk/dxvk_context.h | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index abd2318fc..b8fe29007 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -100,6 +100,11 @@ namespace dxvk { } + void DxvkContext::endFrame() { + + } + + void DxvkContext::flushCommandList() { m_device->submitCommandList( this->endRecording(), diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 56ced3d4e..8e6bae3d9 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -49,6 +49,14 @@ namespace dxvk { */ Rc endRecording(); + /** + * \brief Ends frame + * + * Must be called once per frame before the + * final call to \ref endRecording. + */ + void endFrame(); + /** * \brief Flushes command buffer * From acf70501d2a0e8bb6ef23e9cf0d87d6e0af40bba Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 22 Jun 2022 00:39:19 +0200 Subject: [PATCH 0063/1348] [d3d9] Call endFrame at the end of each frame --- src/d3d9/d3d9_device.cpp | 7 +++++++ src/d3d9/d3d9_device.h | 2 ++ src/d3d9/d3d9_swapchain.cpp | 1 + 3 files changed, 10 insertions(+) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index f2411de8d..79a3b5542 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5241,6 +5241,13 @@ namespace dxvk { } + void D3D9DeviceEx::EndFrame() { + EmitCs([] (DxvkContext* ctx) { + ctx->endFrame(); + }); + } + + inline void D3D9DeviceEx::UpdateBoundRTs(uint32_t index) { const uint32_t bit = 1 << index; diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index cec48291c..6817d8b24 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -747,6 +747,8 @@ namespace dxvk { void Flush(); + void EndFrame(); + void UpdateBoundRTs(uint32_t index); void UpdateActiveRTs(uint32_t index); diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 4422913cb..7fbf75a5e 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -809,6 +809,7 @@ namespace dxvk { void D3D9SwapChainEx::PresentImage(UINT SyncInterval) { + m_parent->EndFrame(); m_parent->Flush(); // Retrieve the image and image view to present From 7e42939a4a7efa32834ff159089e5007b09849d9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 22 Jun 2022 00:39:36 +0200 Subject: [PATCH 0064/1348] [d3d11] Call endFrame at the end of each frame --- src/d3d11/d3d11_context_imm.cpp | 7 +++++++ src/d3d11/d3d11_context_imm.h | 2 ++ src/d3d11/d3d11_swapchain.cpp | 1 + 3 files changed, 10 insertions(+) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 536aef856..15e4accfe 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -682,6 +682,13 @@ namespace dxvk { } + void D3D11ImmediateContext::EndFrame() { + EmitCs([] (DxvkContext* ctx) { + ctx->endFrame(); + }); + } + + bool D3D11ImmediateContext::WaitForResource( const Rc& Resource, uint64_t SequenceNumber, diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 9a5ba21f5..6bc1e6da0 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -158,6 +158,8 @@ namespace dxvk { UINT CopyFlags); void SynchronizeDevice(); + + void EndFrame(); bool WaitForResource( const Rc& Resource, diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index b6ba21e17..771ade123 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -259,6 +259,7 @@ namespace dxvk { // Flush pending rendering commands before auto immediateContext = static_cast(deviceContext.ptr()); + immediateContext->EndFrame(); immediateContext->Flush(); // Bump our frame id. From 9b0b1edf7414e685030539481022125ddb495773 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 19 Jun 2022 22:54:37 +0200 Subject: [PATCH 0065/1348] [dxvk] Introduce persistent descriptor pool --- src/dxvk/dxvk_descriptor.cpp | 263 +++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_descriptor.h | 154 ++++++++++++++++++++ 2 files changed, 417 insertions(+) diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index 8529c0ba3..3824cacd8 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -57,6 +57,239 @@ namespace dxvk { } + DxvkPersistentDescriptorSetList::DxvkPersistentDescriptorSetList() { + + } + + + DxvkPersistentDescriptorSetList::~DxvkPersistentDescriptorSetList() { + + } + + + VkDescriptorSet DxvkPersistentDescriptorSetList::alloc() { + if (unlikely(m_next == m_sets.size())) + return VK_NULL_HANDLE; + + return m_sets[m_next++]; + } + + + void DxvkPersistentDescriptorSetList::addSet(VkDescriptorSet set) { + m_sets.push_back(set); + m_next = m_sets.size(); + } + + + void DxvkPersistentDescriptorSetList::reset() { + m_next = 0; + } + + + + DxvkPersistentDescriptorPool::DxvkPersistentDescriptorPool( + DxvkDevice* device, + DxvkContextType contextType) + : m_device(device), m_contextType(contextType), + m_cachedEntry(nullptr, nullptr) { + + } + + + DxvkPersistentDescriptorPool::~DxvkPersistentDescriptorPool() { + auto vk = m_device->vkd(); + + for (auto pool : m_descriptorPools) + vk->vkDestroyDescriptorPool(vk->device(), pool, nullptr); + } + + + void DxvkPersistentDescriptorPool::alloc( + const DxvkBindingLayoutObjects* layout, + uint32_t setMask, + VkDescriptorSet* sets) { + auto setMap = getSetMapCached(layout); + + while (setMask) { + uint32_t setIndex = bit::tzcnt(setMask); + + sets[setIndex] = allocSet( + setMap->sets[setIndex], + layout->getSetLayout(setIndex)); + + m_setsUsed += 1; + setMask &= setMask - 1; + } + } + + + VkDescriptorSet DxvkPersistentDescriptorPool::alloc( + VkDescriptorSetLayout layout) { + auto setList = getSetList(layout); + return allocSet(setList, layout); + } + + + void DxvkPersistentDescriptorPool::reset() { + // As a heuristic to save memory, check how many descriptors + // have actively been used in the past couple of submissions. + bool isLowUsageFrame = false; + + size_t poolCount = m_descriptorPools.size(); + + if (poolCount > 1) { + double factor = std::max(11.0 / 3.0 - double(poolCount) / 3.0, 1.0); + isLowUsageFrame = double(m_setsUsed) * factor < double(m_setsAllocated); + } + + m_lowUsageFrames = isLowUsageFrame + ? m_lowUsageFrames + 1 + : 0; + m_setsUsed = 0; + + if (m_lowUsageFrames < 16) { + for (auto& entry : m_setLists) + entry.second.reset(); + } else { + // If most sets are no longer being used, reset and destroy + // descriptor pools and reset all lookup tables in order to + // accomodate more descriptors of different layouts. + auto vk = m_device->vkd(); + vk->vkResetDescriptorPool(vk->device(), m_descriptorPools[0], 0); + + for (uint32_t i = 1; i < m_descriptorPools.size(); i++) + vk->vkDestroyDescriptorPool(vk->device(), m_descriptorPools[i], nullptr); + + m_descriptorPools.resize(1); + m_setLists.clear(); + m_setMaps.clear(); + + m_setsAllocated = 0; + m_lowUsageFrames = 0; + } + + m_cachedEntry = { nullptr, nullptr }; + } + + + DxvkPersistentDescriptorSetMap* DxvkPersistentDescriptorPool::getSetMapCached( + const DxvkBindingLayoutObjects* layout) { + if (likely(m_cachedEntry.first == layout)) + return m_cachedEntry.second; + + auto map = getSetMap(layout); + m_cachedEntry = std::make_pair(layout, map); + return map; + } + + + DxvkPersistentDescriptorSetMap* DxvkPersistentDescriptorPool::getSetMap( + const DxvkBindingLayoutObjects* layout) { + auto pair = m_setMaps.find(layout->getPipelineLayout()); + if (likely(pair != m_setMaps.end())) { + return &pair->second; + } + + auto iter = m_setMaps.emplace( + std::piecewise_construct, + std::tuple(layout->getPipelineLayout()), + std::tuple()); + + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + iter.first->second.sets[i] = (layout->getSetMask() & (1u << i)) + ? getSetList(layout->getSetLayout(i)) + : nullptr; + } + + return &iter.first->second; + } + + + DxvkPersistentDescriptorSetList* DxvkPersistentDescriptorPool::getSetList( + VkDescriptorSetLayout layout) { + auto pair = m_setLists.find(layout); + if (pair != m_setLists.end()) + return &pair->second; + + auto iter = m_setLists.emplace( + std::piecewise_construct, + std::tuple(layout), + std::tuple()); + return &iter.first->second; + } + + + VkDescriptorSet DxvkPersistentDescriptorPool::allocSet( + DxvkPersistentDescriptorSetList* list, + VkDescriptorSetLayout layout) { + VkDescriptorSet set = list->alloc(); + + if (unlikely(!set)) { + if (!m_descriptorPools.empty()) + set = allocSetFromPool(m_descriptorPools.back(), layout); + + if (!set) + set = allocSetFromPool(addPool(), layout); + + list->addSet(set); + m_setsAllocated += 1; + } + + return set; + } + + + VkDescriptorSet DxvkPersistentDescriptorPool::allocSetFromPool( + VkDescriptorPool pool, + VkDescriptorSetLayout layout) { + auto vk = m_device->vkd(); + + VkDescriptorSetAllocateInfo info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; + info.descriptorPool = pool; + info.descriptorSetCount = 1; + info.pSetLayouts = &layout; + + VkDescriptorSet set = VK_NULL_HANDLE; + + if (vk->vkAllocateDescriptorSets(vk->device(), &info, &set) != VK_SUCCESS) + return VK_NULL_HANDLE; + + return set; + } + + + VkDescriptorPool DxvkPersistentDescriptorPool::addPool() { + auto vk = m_device->vkd(); + + uint32_t maxSets = m_contextType == DxvkContextType::Primary + ? 8192 : 256; + + std::array pools = {{ + { VK_DESCRIPTOR_TYPE_SAMPLER, maxSets * 2 }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, maxSets * 2 }, + { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, maxSets / 64 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, maxSets * 4 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, maxSets * 1 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, maxSets * 1 }, + { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, maxSets / 64 }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, maxSets * 1 } }}; + + VkDescriptorPoolCreateInfo info; + info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + info.pNext = nullptr; + info.flags = 0; + info.maxSets = maxSets; + info.poolSizeCount = pools.size(); + info.pPoolSizes = pools.data(); + + VkDescriptorPool pool = VK_NULL_HANDLE; + + if (vk->vkCreateDescriptorPool(vk->device(), &info, nullptr, &pool) != VK_SUCCESS) + throw DxvkError("DxvkDescriptorPool: Failed to create descriptor pool"); + + m_descriptorPools.push_back(pool); + return pool; + } DxvkDescriptorPoolTracker::DxvkDescriptorPoolTracker(DxvkDevice* device) @@ -84,4 +317,34 @@ namespace dxvk { m_pools.clear(); } + DxvkDescriptorManager::DxvkDescriptorManager( + DxvkDevice* device, + DxvkContextType contextType) + : m_device(device), m_contextType(contextType) { + + } + + + DxvkDescriptorManager::~DxvkDescriptorManager() { + + } + + + Rc DxvkDescriptorManager::getDescriptorPool() { + Rc pool = m_pools.retrieveObject(); + + if (pool == nullptr) + pool = new DxvkPersistentDescriptorPool(m_device, m_contextType); + + return pool; + } + + + void DxvkDescriptorManager::recycleDescriptorPool( + const Rc& pool) { + pool->reset(); + + m_pools.returnObject(pool); + } + } \ No newline at end of file diff --git a/src/dxvk/dxvk_descriptor.h b/src/dxvk/dxvk_descriptor.h index 6c8c8d4c5..cd5ee301b 100644 --- a/src/dxvk/dxvk_descriptor.h +++ b/src/dxvk/dxvk_descriptor.h @@ -3,6 +3,8 @@ #include #include "dxvk_include.h" +#include "dxvk_pipelayout.h" +#include "dxvk_recycler.h" namespace dxvk { @@ -70,6 +72,122 @@ namespace dxvk { }; + /** + * \brief Descriptor set list + */ + class DxvkPersistentDescriptorSetList { + + public: + + DxvkPersistentDescriptorSetList(); + ~DxvkPersistentDescriptorSetList(); + + VkDescriptorSet alloc(); + + void addSet(VkDescriptorSet set); + + void reset(); + + private: + + size_t m_next = 0; + std::vector m_sets; + + }; + + + /** + * \brief Persistent descriptor set map + * + * Points to a list of set maps for each + * defined set in a pipeline layout. + */ + struct DxvkPersistentDescriptorSetMap { + std::array sets; + }; + + + /** + * \brief Descriptor pool + * + * Manages descriptors that have the same lifetime. Sets are + * intended to be reused as much as possible in order to reduce + * overhead in the driver from descriptor set initialization, + * but allocated sets will have unspecified contents and need + * to be updated. + */ + class DxvkPersistentDescriptorPool : public RcObject { + + public: + + DxvkPersistentDescriptorPool( + DxvkDevice* device, + DxvkContextType contextType); + + ~DxvkPersistentDescriptorPool(); + + /** + * \brief Allocates one or multiple descriptor sets + * + * \param [in] layout Binding layout + * \param [in] setMask Descriptor set mask + * \param [out] sets Descriptor sets + */ + void alloc( + const DxvkBindingLayoutObjects* layout, + uint32_t setMask, + VkDescriptorSet* sets); + + /** + * \brief Allocates a single descriptor set + * + * \param [in] layout Descriptor set layout + * \returns The descriptor set + */ + VkDescriptorSet alloc( + VkDescriptorSetLayout layout); + + /** + * \brief Resets pool + */ + void reset(); + + private: + + DxvkDevice* m_device; + DxvkContextType m_contextType; + + std::vector m_descriptorPools; + std::unordered_map m_setLists; + std::unordered_map m_setMaps; + std::pair m_cachedEntry; + + uint32_t m_setsAllocated = 0; + uint32_t m_setsUsed = 0; + uint32_t m_lowUsageFrames = 0; + + DxvkPersistentDescriptorSetMap* getSetMapCached( + const DxvkBindingLayoutObjects* layout); + + DxvkPersistentDescriptorSetMap* getSetMap( + const DxvkBindingLayoutObjects* layout); + + DxvkPersistentDescriptorSetList* getSetList( + VkDescriptorSetLayout layout); + + VkDescriptorSet allocSet( + DxvkPersistentDescriptorSetList* list, + VkDescriptorSetLayout layout); + + VkDescriptorSet allocSetFromPool( + VkDescriptorPool pool, + VkDescriptorSetLayout layout); + + VkDescriptorPool addPool(); + + }; + + /** * \brief Descriptor pool tracker * @@ -107,4 +225,40 @@ namespace dxvk { }; + /* + * \brief Descriptor pool manager + */ + class DxvkDescriptorManager : public RcObject { + + public: + + DxvkDescriptorManager( + DxvkDevice* device, + DxvkContextType contextType); + + ~DxvkDescriptorManager(); + + /** + * \brief Retrieves or creates a descriptor type + * \returns The descriptor pool + */ + Rc getDescriptorPool(); + + /** + * \brief Recycles descriptor pool + * + * Resets and recycles the given + * descriptor pool for future use. + */ + void recycleDescriptorPool( + const Rc& pool); + + private: + + DxvkDevice* m_device; + DxvkContextType m_contextType; + DxvkRecycler m_pools; + + }; + } \ No newline at end of file From f4e9b76515e143851a51f7ade6133b4e17b4f1a5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 19 Jun 2022 22:58:15 +0200 Subject: [PATCH 0066/1348] [dxvk] Add descriptor pool tracking to command list --- src/dxvk/dxvk_cmdlist.cpp | 5 +++++ src/dxvk/dxvk_cmdlist.h | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 09a851bef..169f8b442 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -186,6 +186,11 @@ namespace dxvk { // Less important stuff m_signalTracker.reset(); m_statCounters.reset(); + + for (const auto& descriptorPools : m_descriptorPools) + descriptorPools.second->recycleDescriptorPool(descriptorPools.first); + + m_descriptorPools.clear(); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 3dedf3f45..231635651 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -200,7 +200,7 @@ namespace dxvk { m_resources.notify(); m_signalTracker.notify(); } - + /** * \brief Resets the command list * @@ -763,6 +763,12 @@ namespace dxvk { m_vkd->device(), queryPool, queryId, 1); } + void trackDescriptorPool( + const Rc& pool, + const Rc& manager) { + m_descriptorPools.push_back({ pool, manager }); + } + private: DxvkDevice* m_device; @@ -789,6 +795,10 @@ namespace dxvk { DxvkBufferTracker m_bufferTracker; DxvkStatCounters m_statCounters; + std::vector, + Rc>> m_descriptorPools; + VkCommandBuffer getCmdBuffer(DxvkCmdBuffer cmdBuffer) const { if (cmdBuffer == DxvkCmdBuffer::ExecBuffer) return m_execBuffer; if (cmdBuffer == DxvkCmdBuffer::InitBuffer) return m_initBuffer; From e2b7522034342fcef604183728af4fee6dead526 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 20 Jun 2022 12:17:23 +0200 Subject: [PATCH 0067/1348] [dxvk] Use persistent descriptor pool for regular descriptor sets --- src/dxvk/dxvk_context.cpp | 40 +++++++++++++++++++++++++++------------ src/dxvk/dxvk_context.h | 3 +++ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b8fe29007..a0426707b 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -40,6 +40,8 @@ namespace dxvk { m_descriptorWrites[i].pBufferInfo = &m_descriptors[i].buffer; m_descriptorWrites[i].pTexelBufferView = &m_descriptors[i].texelBuffer; } + + m_descriptorManager = new DxvkDescriptorManager(device.ptr(), type); } @@ -84,6 +86,9 @@ namespace dxvk { VK_SHADER_STAGE_COMPUTE_BIT); m_descriptorState.clearSets(); + + if (m_descriptorPool == nullptr) + m_descriptorPool = m_descriptorManager->getDescriptorPool(); } @@ -95,13 +100,21 @@ namespace dxvk { m_initBarriers.recordCommands(m_cmd); m_execBarriers.recordCommands(m_cmd); + if (m_type != DxvkContextType::Primary) { + m_cmd->trackDescriptorPool(m_descriptorPool, m_descriptorManager); + m_descriptorPool = nullptr; + } + m_cmd->endRecording(); return std::exchange(m_cmd, nullptr); } void DxvkContext::endFrame() { - + if (m_descriptorPool != nullptr) { + m_cmd->trackDescriptorPool(m_descriptorPool, m_descriptorManager); + m_descriptorPool = m_descriptorManager->getDescriptorPool(); + } } @@ -405,7 +418,7 @@ namespace dxvk { // Create a descriptor set pointing to the view VkBufferView viewObject = bufferView->handle(); - VkDescriptorSet descriptorSet = allocateDescriptorSet(pipeInfo.dsetLayout); + VkDescriptorSet descriptorSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); VkWriteDescriptorSet descriptorWrite; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; @@ -894,7 +907,7 @@ namespace dxvk { descriptors.srcDepth = dView->getDescriptor(VK_IMAGE_VIEW_TYPE_2D_ARRAY, layout).image; descriptors.srcStencil = sView->getDescriptor(VK_IMAGE_VIEW_TYPE_2D_ARRAY, layout).image; - VkDescriptorSet dset = allocateDescriptorSet(pipeInfo.dsetLayout); + VkDescriptorSet dset = m_descriptorPool->alloc(pipeInfo.dsetLayout); m_cmd->updateDescriptorSetWithTemplate(dset, pipeInfo.dsetTemplate, &descriptors); // Since this is a meta operation, the image may be @@ -1054,7 +1067,7 @@ namespace dxvk { } auto pipeInfo = m_common->metaCopy().getCopyBufferImagePipeline(); - VkDescriptorSet descriptorSet = allocateDescriptorSet(pipeInfo.dsetLayout); + VkDescriptorSet descriptorSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); std::array descriptorWrites; @@ -1212,7 +1225,7 @@ namespace dxvk { descriptors.dstStencil = tmpBufferViewS->handle(); descriptors.srcBuffer = srcBuffer->getDescriptor(srcBufferOffset, VK_WHOLE_SIZE).buffer; - VkDescriptorSet dset = allocateDescriptorSet(pipeInfo.dsetLayout); + VkDescriptorSet dset = m_descriptorPool->alloc(pipeInfo.dsetLayout); m_cmd->updateDescriptorSetWithTemplate(dset, pipeInfo.dsetTemplate, &descriptors); // Unpack the source buffer to temporary buffers @@ -1704,7 +1717,7 @@ namespace dxvk { // Create descriptor set with the current source view descriptorImage.imageView = pass.srcView; - descriptorWrite.dstSet = allocateDescriptorSet(pipeInfo.dsetLayout); + descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); m_cmd->updateDescriptorSets(1, &descriptorWrite); // Set up viewport and scissor rect @@ -2706,7 +2719,7 @@ namespace dxvk { VkWriteDescriptorSet descriptorWrite; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptorWrite.pNext = nullptr; - descriptorWrite.dstSet = allocateDescriptorSet(pipeInfo.dsetLayout); + descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); descriptorWrite.dstBinding = 0; descriptorWrite.dstArrayElement = 0; descriptorWrite.descriptorCount = 1; @@ -3086,7 +3099,7 @@ namespace dxvk { imageView->type(), imageFormatInfo(imageView->info().format)->flags); // Create a descriptor set pointing to the view - VkDescriptorSet descriptorSet = allocateDescriptorSet(pipeInfo.dsetLayout); + VkDescriptorSet descriptorSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); VkDescriptorImageInfo viewInfo; viewInfo.sampler = VK_NULL_HANDLE; @@ -3395,7 +3408,7 @@ namespace dxvk { descriptorWrite.pBufferInfo = nullptr; descriptorWrite.pTexelBufferView = nullptr; - descriptorWrite.dstSet = allocateDescriptorSet(pipeInfo.dsetLayout); + descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); m_cmd->updateDescriptorSets(1, &descriptorWrite); if (srcSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { @@ -3759,7 +3772,7 @@ namespace dxvk { descriptorWrite.pBufferInfo = nullptr; descriptorWrite.pTexelBufferView = nullptr; - descriptorWrite.dstSet = allocateDescriptorSet(pipeInfo.dsetLayout); + descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); m_cmd->updateDescriptorSets(1, &descriptorWrite); if (srcStencilView != nullptr) { @@ -4193,6 +4206,9 @@ namespace dxvk { uint32_t firstUpdated = bit::tzcnt(dirtySetMask); uint32_t k = 0; + std::array sets = { }; + m_descriptorPool->alloc(layout, dirtySetMask, sets.data()); + while (dirtySetMask) { uint32_t setIndex = bit::tzcnt(dirtySetMask); @@ -4203,8 +4219,8 @@ namespace dxvk { newBindMask.setRange(bindingIndex, bindingCount); - VkDescriptorSet& set = m_descriptorState.getSet(setIndex); - set = allocateDescriptorSet(layout->getSetLayout(setIndex)); + VkDescriptorSet set = sets[setIndex]; + m_descriptorState.getSet(setIndex) = set; for (uint32_t j = 0; j < bindingCount; j++) { const auto& binding = bindings.getBinding(setIndex, j); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 8e6bae3d9..b78d59f9a 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1058,6 +1058,9 @@ namespace dxvk { DxvkContextFeatures m_features; DxvkDescriptorState m_descriptorState; + Rc m_descriptorPool; + Rc m_descriptorManager; + DxvkBarrierSet m_sdmaAcquires; DxvkBarrierSet m_sdmaBarriers; DxvkBarrierSet m_initBarriers; From a27448bc76e66d54d65d19d36be5f0592500711e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 20 Jun 2022 01:32:33 +0200 Subject: [PATCH 0068/1348] [dxvk] Bind consecutive descriptor sets in one go Most of the time we'll be able to bind all sets in one iteration. Binding sets is expected to be cheap in the driver, but we should avoid unnecessary function call overhead for this frequently called function. --- src/dxvk/dxvk_context.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index a0426707b..af572e001 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4384,18 +4384,19 @@ namespace dxvk { m_cmd->updateDescriptorSets(k, m_descriptorWrites.data()); // Bind all descriptor sets that need updating - uint32_t bindSetMask = layoutSetMask & ~((1u << firstUpdated) - 1); + uint32_t bindSetMask = layoutSetMask & ((~0u) << firstUpdated); while (bindSetMask) { uint32_t setIndex = bit::tzcnt(bindSetMask); + uint32_t setCount = bit::tzcnt(~(bindSetMask >> setIndex)); - VkDescriptorSet& set = m_descriptorState.getSet(setIndex); + VkDescriptorSet* sets = &m_descriptorState.getSet(setIndex); m_cmd->cmdBindDescriptorSets(BindPoint, layout->getPipelineLayout(), - setIndex, 1, &set, 0, nullptr); + setIndex, setCount, sets, 0, nullptr); - bindSetMask &= bindSetMask - 1; + bindSetMask &= (~0u) << (setIndex + setCount); } // Update pipeline if there are unbound resources From af418dcffde184890af95077c051c0ca4cc8d026 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 21 Jun 2022 14:06:13 +0200 Subject: [PATCH 0069/1348] [dxvk] Fix pipeline invalidation We need to update descriptors and other graphics state when changing between compute and graphics. This happened to work by chance since any real-world app binds a new set of shaders around mode switches anyway, but it could theoretically happen that we wouldn't update descriptor sets on the first draw after a dispatch. --- src/dxvk/dxvk_context.cpp | 82 +++++++++++++++++++++++++-------------- src/dxvk/dxvk_context.h | 5 +-- 2 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index af572e001..9e65f111f 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -87,6 +87,9 @@ namespace dxvk { m_descriptorState.clearSets(); + m_state.gp.pipeline = nullptr; + m_state.cp.pipeline = nullptr; + if (m_descriptorPool == nullptr) m_descriptorPool = m_descriptorManager->getDescriptorPool(); } @@ -400,7 +403,7 @@ namespace dxvk { VkDeviceSize length, VkClearColorValue value) { this->spillRenderPass(true); - this->unbindComputePipeline(); + this->invalidateState(); // The view range might have been invalidated, so // we need to make sure the handle is up to date @@ -874,7 +877,7 @@ namespace dxvk { this->spillRenderPass(true); this->prepareImage(m_execBarriers, srcImage, vk::makeSubresourceRange(srcSubresource)); - this->unbindComputePipeline(); + this->invalidateState(); // Retrieve compute pipeline for the given format auto pipeInfo = m_common->metaPack().getPackPipeline(format); @@ -990,7 +993,7 @@ namespace dxvk { VkExtent3D extent, VkDeviceSize elementSize) { this->spillRenderPass(true); - this->unbindComputePipeline(); + this->invalidateState(); auto dstBufferSlice = dstBuffer->getSliceHandle(dstBufferOffset, elementSize * util::flattenImageExtent(dstSize)); auto srcBufferSlice = srcBuffer->getSliceHandle(srcBufferOffset, elementSize * util::flattenImageExtent(srcSize)); @@ -1154,9 +1157,9 @@ namespace dxvk { VkExtent2D srcExtent, VkFormat format) { this->spillRenderPass(true); - this->prepareImage(m_execBarriers, dstImage, vk::makeSubresourceRange(dstSubresource)); + this->invalidateState(); - this->unbindComputePipeline(); + this->prepareImage(m_execBarriers, dstImage, vk::makeSubresourceRange(dstSubresource)); if (m_execBarriers.isBufferDirty(srcBuffer->getSliceHandle(), DxvkAccess::Read) || m_execBarriers.isImageDirty(dstImage, vk::makeSubresourceRange(dstSubresource), DxvkAccess::Write)) @@ -1669,6 +1672,7 @@ namespace dxvk { return; this->spillRenderPass(false); + this->invalidateState(); m_execBarriers.recordCommands(m_cmd); @@ -2616,6 +2620,8 @@ namespace dxvk { const VkImageBlit& region, const VkComponentMapping& mapping, VkFilter filter) { + this->invalidateState(); + auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource); auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource); @@ -3086,7 +3092,7 @@ namespace dxvk { VkExtent3D extent, VkClearValue value) { this->spillRenderPass(false); - this->unbindComputePipeline(); + this->invalidateState(); if (m_execBarriers.isImageDirty( imageView->image(), @@ -3270,6 +3276,8 @@ namespace dxvk { VkImageSubresourceLayers srcSubresource, VkOffset3D srcOffset, VkExtent3D extent) { + this->invalidateState(); + auto dstSubresourceRange = vk::makeSubresourceRange(dstSubresource); auto srcSubresourceRange = vk::makeSubresourceRange(srcSubresource); @@ -3691,6 +3699,8 @@ namespace dxvk { VkFormat format, VkResolveModeFlagBitsKHR depthMode, VkResolveModeFlagBitsKHR stencilMode) { + this->invalidateState(); + auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource); auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource); @@ -3840,7 +3850,22 @@ namespace dxvk { this->applyRenderTargetLoadLayouts(); this->flushClears(true); - m_flags.set(DxvkContextFlag::GpRenderPassBound); + // Make sure all graphics state gets reapplied on the next draw + m_descriptorState.dirtyStages(VK_SHADER_STAGE_ALL_GRAPHICS); + + m_flags.set( + DxvkContextFlag::GpRenderPassBound, + DxvkContextFlag::GpDirtyPipelineState, + DxvkContextFlag::GpDirtyVertexBuffers, + DxvkContextFlag::GpDirtyIndexBuffer, + DxvkContextFlag::GpDirtyXfbBuffers, + DxvkContextFlag::GpDirtyBlendConstants, + DxvkContextFlag::GpDirtyStencilRef, + DxvkContextFlag::GpDirtyViewport, + DxvkContextFlag::GpDirtyDepthBias, + DxvkContextFlag::GpDirtyDepthBounds, + DxvkContextFlag::DirtyPushConstants); + m_flags.clr(DxvkContextFlag::GpRenderPassSuspended); m_execBarriers.recordCommands(m_cmd); @@ -3884,8 +3909,6 @@ namespace dxvk { this->transitionRenderTargetLayouts(m_gfxBarriers, false); m_gfxBarriers.recordCommands(m_cmd); - - this->unbindGraphicsPipeline(); } else if (!suspend) { // We may end a previously suspended render pass if (m_flags.test(DxvkContextFlag::GpRenderPassSuspended)) { @@ -4036,17 +4059,16 @@ namespace dxvk { m_flags.set( DxvkContextFlag::CpDirtyPipeline, DxvkContextFlag::CpDirtyPipelineState); - - m_descriptorState.dirtyStages(VK_SHADER_STAGE_COMPUTE_BIT); - m_state.cp.state.bsBindingMask.clear(); - m_cpActivePipeline = VK_NULL_HANDLE; + m_state.cp.pipeline = nullptr; } bool DxvkContext::updateComputePipeline() { - auto newPipeline = lookupComputePipeline(m_state.cp.shaders); + if (unlikely(m_state.gp.pipeline != nullptr)) + this->unbindGraphicsPipeline(); + auto newPipeline = lookupComputePipeline(m_state.cp.shaders); m_state.cp.pipeline = newPipeline; if (unlikely(!newPipeline)) @@ -4064,14 +4086,14 @@ namespace dxvk { bool DxvkContext::updateComputePipelineState() { - m_cpActivePipeline = m_state.cp.pipeline->getPipelineHandle(m_state.cp.state); + VkPipeline pipeline = m_state.cp.pipeline->getPipelineHandle(m_state.cp.state); - if (unlikely(!m_cpActivePipeline)) + if (unlikely(!pipeline)) return false; m_cmd->cmdBindPipeline( VK_PIPELINE_BIND_POINT_COMPUTE, - m_cpActivePipeline); + pipeline); m_flags.clr(DxvkContextFlag::CpDirtyPipelineState); return true; @@ -4090,17 +4112,16 @@ namespace dxvk { DxvkContextFlag::GpDirtyViewport, DxvkContextFlag::GpDirtyDepthBias, DxvkContextFlag::GpDirtyDepthBounds); - - m_descriptorState.dirtyStages(VK_SHADER_STAGE_ALL_GRAPHICS); - m_state.gp.state.bsBindingMask.clear(); - m_gpActivePipeline = VK_NULL_HANDLE; + m_state.gp.pipeline = nullptr; } bool DxvkContext::updateGraphicsPipeline() { - auto newPipeline = lookupGraphicsPipeline(m_state.gp.shaders); + if (unlikely(m_state.cp.pipeline != nullptr)) + this->unbindComputePipeline(); + auto newPipeline = lookupGraphicsPipeline(m_state.gp.shaders); m_state.gp.pipeline = newPipeline; if (unlikely(!newPipeline)) { @@ -4165,20 +4186,26 @@ namespace dxvk { : DxvkContextFlag::GpDirtyStencilRef); // Retrieve and bind actual Vulkan pipeline handle - m_gpActivePipeline = m_state.gp.pipeline->getPipelineHandle( + VkPipeline pipeline = m_state.gp.pipeline->getPipelineHandle( m_state.gp.state, m_state.om.framebufferInfo.renderPass()); - if (unlikely(!m_gpActivePipeline)) + if (unlikely(!pipeline)) return false; m_cmd->cmdBindPipeline( VK_PIPELINE_BIND_POINT_GRAPHICS, - m_gpActivePipeline); + pipeline); m_flags.clr(DxvkContextFlag::GpDirtyPipelineState); return true; } - + + + void DxvkContext::invalidateState() { + this->unbindComputePipeline(); + this->unbindGraphicsPipeline(); + } + template void DxvkContext::updateResourceBindings(const DxvkBindingLayoutObjects* layout) { @@ -4748,9 +4775,6 @@ namespace dxvk { void DxvkContext::updateDynamicState() { - if (!m_gpActivePipeline) - return; - if (m_flags.test(DxvkContextFlag::GpDirtyViewport)) { m_flags.clr(DxvkContextFlag::GpDirtyViewport); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index b78d59f9a..27aa2897a 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1074,9 +1074,6 @@ namespace dxvk { DxvkRenderTargetLayouts m_rtLayouts = { }; - VkPipeline m_gpActivePipeline = VK_NULL_HANDLE; - VkPipeline m_cpActivePipeline = VK_NULL_HANDLE; - DxvkBindingSet m_vbTracked; DxvkBindingSet m_rcTracked; @@ -1231,6 +1228,8 @@ namespace dxvk { bool updateGraphicsPipeline(); bool updateGraphicsPipelineState(); + void invalidateState(); + template void updateResourceBindings(const DxvkBindingLayoutObjects* layout); From 6aeed40af20040d557aaba7f75b06ec85da50479 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 20 Jun 2022 14:44:21 +0200 Subject: [PATCH 0070/1348] [dxvk] Remove old descriptor pool implementation --- src/dxvk/dxvk_cmdlist.cpp | 6 +-- src/dxvk/dxvk_cmdlist.h | 9 ---- src/dxvk/dxvk_context.cpp | 18 -------- src/dxvk/dxvk_context.h | 4 -- src/dxvk/dxvk_descriptor.cpp | 79 ------------------------------------ src/dxvk/dxvk_descriptor.h | 77 ----------------------------------- src/dxvk/dxvk_device.cpp | 15 ------- src/dxvk/dxvk_device.h | 16 +------- 8 files changed, 2 insertions(+), 222 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 169f8b442..90d3408e9 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -7,8 +7,7 @@ namespace dxvk { : m_device (device), m_vkd (device->vkd()), m_vki (device->instance()->vki()), - m_cmdBuffersUsed(0), - m_descriptorPoolTracker(device) { + m_cmdBuffersUsed(0) { const auto& graphicsQueue = m_device->queues().graphics; const auto& transferQueue = m_device->queues().transfer; @@ -173,9 +172,6 @@ namespace dxvk { // that are no longer in use m_resources.reset(); - // Recycle heavy Vulkan objects - m_descriptorPoolTracker.reset(); - // Return buffer memory slices m_bufferTracker.reset(); diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 231635651..30cc720fd 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -151,14 +151,6 @@ namespace dxvk { m_resources.trackResource(std::move(rc)); } - /** - * \brief Tracks a descriptor pool - * \param [in] pool The descriptor pool - */ - void trackDescriptorPool(Rc pool) { - m_descriptorPoolTracker.trackDescriptorPool(pool); - } - /** * \brief Tracks a GPU event * @@ -788,7 +780,6 @@ namespace dxvk { DxvkCmdBufferFlags m_cmdBuffersUsed; DxvkLifetimeTracker m_resources; - DxvkDescriptorPoolTracker m_descriptorPoolTracker; DxvkSignalTracker m_signalTracker; DxvkGpuEventTracker m_gpuEventTracker; DxvkGpuQueryTracker m_gpuQueryTracker; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 9e65f111f..06950c814 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5256,24 +5256,6 @@ namespace dxvk { } - VkDescriptorSet DxvkContext::allocateDescriptorSet( - VkDescriptorSetLayout layout) { - if (m_descPool == nullptr) - m_descPool = m_device->createDescriptorPool(); - - VkDescriptorSet set = m_descPool->alloc(layout); - - if (set == VK_NULL_HANDLE) { - m_cmd->trackDescriptorPool(std::move(m_descPool)); - - m_descPool = m_device->createDescriptorPool(); - set = m_descPool->alloc(layout); - } - - return set; - } - - void DxvkContext::trackDrawBuffer() { if (m_flags.test(DxvkContextFlag::DirtyDrawBuffer)) { m_flags.clr(DxvkContextFlag::DirtyDrawBuffer); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 27aa2897a..d93a2db85 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1050,7 +1050,6 @@ namespace dxvk { DxvkObjects* m_common; Rc m_cmd; - Rc m_descPool; Rc m_zeroBuffer; DxvkContextFlags m_flags; @@ -1310,9 +1309,6 @@ namespace dxvk { VkPipelineStageFlags dstStages, VkAccessFlags dstAccess); - VkDescriptorSet allocateDescriptorSet( - VkDescriptorSetLayout layout); - void trackDrawBuffer(); bool tryInvalidateDeviceLocalBuffer( diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index 3824cacd8..d8658db1f 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -2,60 +2,6 @@ #include "dxvk_device.h" namespace dxvk { - - DxvkDescriptorPool::DxvkDescriptorPool(const Rc& vkd) - : m_vkd(vkd) { - constexpr uint32_t MaxSets = 2048; - - std::array pools = {{ - { VK_DESCRIPTOR_TYPE_SAMPLER, MaxSets * 2 }, - { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, MaxSets * 3 }, - { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, MaxSets / 8 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, MaxSets * 3 }, - { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, MaxSets / 8 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, MaxSets * 3 }, - { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, MaxSets / 8 }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MaxSets * 2 } }}; - - VkDescriptorPoolCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.maxSets = MaxSets; - info.poolSizeCount = pools.size(); - info.pPoolSizes = pools.data(); - - if (m_vkd->vkCreateDescriptorPool(m_vkd->device(), &info, nullptr, &m_pool) != VK_SUCCESS) - throw DxvkError("DxvkDescriptorPool: Failed to create descriptor pool"); - } - - - DxvkDescriptorPool::~DxvkDescriptorPool() { - m_vkd->vkDestroyDescriptorPool( - m_vkd->device(), m_pool, nullptr); - } - - - VkDescriptorSet DxvkDescriptorPool::alloc(VkDescriptorSetLayout layout) { - VkDescriptorSetAllocateInfo info; - info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - info.pNext = nullptr; - info.descriptorPool = m_pool; - info.descriptorSetCount = 1; - info.pSetLayouts = &layout; - - VkDescriptorSet set = VK_NULL_HANDLE; - if (m_vkd->vkAllocateDescriptorSets(m_vkd->device(), &info, &set) != VK_SUCCESS) - return VK_NULL_HANDLE; - return set; - } - - - void DxvkDescriptorPool::reset() { - m_vkd->vkResetDescriptorPool( - m_vkd->device(), m_pool, 0); - } - DxvkPersistentDescriptorSetList::DxvkPersistentDescriptorSetList() { @@ -291,31 +237,6 @@ namespace dxvk { return pool; } - - DxvkDescriptorPoolTracker::DxvkDescriptorPoolTracker(DxvkDevice* device) - : m_device(device) { - - } - - - DxvkDescriptorPoolTracker::~DxvkDescriptorPoolTracker() { - - } - - - void DxvkDescriptorPoolTracker::trackDescriptorPool(Rc pool) { - m_pools.push_back(std::move(pool)); - } - - - void DxvkDescriptorPoolTracker::reset() { - for (const auto& pool : m_pools) { - pool->reset(); - m_device->recycleDescriptorPool(pool); - } - - m_pools.clear(); - } DxvkDescriptorManager::DxvkDescriptorManager( DxvkDevice* device, diff --git a/src/dxvk/dxvk_descriptor.h b/src/dxvk/dxvk_descriptor.h index cd5ee301b..9609ccc22 100644 --- a/src/dxvk/dxvk_descriptor.h +++ b/src/dxvk/dxvk_descriptor.h @@ -33,45 +33,6 @@ namespace dxvk { }; - /** - * \brief Descriptor pool - * - * Wrapper around a Vulkan descriptor pool that - * descriptor sets can be allocated from. - */ - class DxvkDescriptorPool : public RcObject { - - public: - - DxvkDescriptorPool( - const Rc& vkd); - ~DxvkDescriptorPool(); - - /** - * \brief Allocates a descriptor set - * - * \param [in] layout Descriptor set layout - * \returns The descriptor set - */ - VkDescriptorSet alloc( - VkDescriptorSetLayout layout); - - /** - * \brief Resets descriptor set allocator - * - * Destroys all descriptor sets and - * resets the Vulkan descriptor pools. - */ - void reset(); - - private: - - Rc m_vkd; - VkDescriptorPool m_pool; - - }; - - /** * \brief Descriptor set list */ @@ -186,44 +147,6 @@ namespace dxvk { VkDescriptorPool addPool(); }; - - - /** - * \brief Descriptor pool tracker - * - * Tracks descriptor pools that are either full - * or no longer needed by the DXVK context. The - * command list will reset and recycle all pools - * once it has completed execution on the GPU. - */ - class DxvkDescriptorPoolTracker { - - public: - - DxvkDescriptorPoolTracker(DxvkDevice* device); - ~DxvkDescriptorPoolTracker(); - - /** - * \brief Adds a descriptor pool to track - * \param [in] pool The descriptor pool - */ - void trackDescriptorPool(Rc pool); - - /** - * \brief Resets event tracker - * - * Resets all tracked descriptor pools - * and returns them to the device. - */ - void reset(); - - private: - - DxvkDevice* m_device; - - std::vector> m_pools; - - }; /* * \brief Descriptor pool manager diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 5795455d6..87a29c568 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -84,16 +84,6 @@ namespace dxvk { } - Rc DxvkDevice::createDescriptorPool() { - Rc pool = m_recycledDescriptorPools.retrieveObject(); - - if (pool == nullptr) - pool = new DxvkDescriptorPool(m_vkd); - - return pool; - } - - Rc DxvkDevice::createContext(DxvkContextType type) { return new DxvkContext(this, type); } @@ -279,11 +269,6 @@ namespace dxvk { } - void DxvkDevice::recycleDescriptorPool(const Rc& pool) { - m_recycledDescriptorPools.returnObject(pool); - } - - DxvkDeviceQueue DxvkDevice::getQueue( uint32_t family, uint32_t index) const { diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 0d1ac5cc7..6877b3107 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -229,16 +229,6 @@ namespace dxvk { */ Rc createCommandList(); - /** - * \brief Creates a descriptor pool - * - * Returns a previously recycled pool, or creates - * a new one if necessary. The context should take - * ownership of the returned pool. - * \returns Descriptor pool - */ - Rc createDescriptorPool(); - /** * \brief Creates a context * @@ -497,8 +487,7 @@ namespace dxvk { DxvkDeviceQueueSet m_queues; - DxvkRecycler m_recycledCommandLists; - DxvkRecycler m_recycledDescriptorPools; + DxvkRecycler m_recycledCommandLists; DxvkSubmissionQueue m_submissionQueue; @@ -507,9 +496,6 @@ namespace dxvk { void recycleCommandList( const Rc& cmdList); - void recycleDescriptorPool( - const Rc& pool); - DxvkDeviceQueue getQueue( uint32_t family, uint32_t index) const; From eea5c9f0dafa412f4017ec88d92f8f2d49685fc3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 21 Jun 2022 14:16:24 +0200 Subject: [PATCH 0071/1348] [dxvk] Rename new descriptor pool implementation to DxvkDescriptorPool --- src/dxvk/dxvk_cmdlist.h | 4 ++-- src/dxvk/dxvk_context.h | 2 +- src/dxvk/dxvk_descriptor.cpp | 42 ++++++++++++++++++------------------ src/dxvk/dxvk_descriptor.h | 38 ++++++++++++++++---------------- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 30cc720fd..4a3b5b625 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -756,7 +756,7 @@ namespace dxvk { } void trackDescriptorPool( - const Rc& pool, + const Rc& pool, const Rc& manager) { m_descriptorPools.push_back({ pool, manager }); } @@ -787,7 +787,7 @@ namespace dxvk { DxvkStatCounters m_statCounters; std::vector, + Rc, Rc>> m_descriptorPools; VkCommandBuffer getCmdBuffer(DxvkCmdBuffer cmdBuffer) const { diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index d93a2db85..2ce14e72b 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1057,7 +1057,7 @@ namespace dxvk { DxvkContextFeatures m_features; DxvkDescriptorState m_descriptorState; - Rc m_descriptorPool; + Rc m_descriptorPool; Rc m_descriptorManager; DxvkBarrierSet m_sdmaAcquires; diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index d8658db1f..bfaf0b8e9 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -3,17 +3,17 @@ namespace dxvk { - DxvkPersistentDescriptorSetList::DxvkPersistentDescriptorSetList() { + DxvkDescriptorSetList::DxvkDescriptorSetList() { } - DxvkPersistentDescriptorSetList::~DxvkPersistentDescriptorSetList() { + DxvkDescriptorSetList::~DxvkDescriptorSetList() { } - VkDescriptorSet DxvkPersistentDescriptorSetList::alloc() { + VkDescriptorSet DxvkDescriptorSetList::alloc() { if (unlikely(m_next == m_sets.size())) return VK_NULL_HANDLE; @@ -21,19 +21,19 @@ namespace dxvk { } - void DxvkPersistentDescriptorSetList::addSet(VkDescriptorSet set) { + void DxvkDescriptorSetList::addSet(VkDescriptorSet set) { m_sets.push_back(set); m_next = m_sets.size(); } - void DxvkPersistentDescriptorSetList::reset() { + void DxvkDescriptorSetList::reset() { m_next = 0; } - DxvkPersistentDescriptorPool::DxvkPersistentDescriptorPool( + DxvkDescriptorPool::DxvkDescriptorPool( DxvkDevice* device, DxvkContextType contextType) : m_device(device), m_contextType(contextType), @@ -42,7 +42,7 @@ namespace dxvk { } - DxvkPersistentDescriptorPool::~DxvkPersistentDescriptorPool() { + DxvkDescriptorPool::~DxvkDescriptorPool() { auto vk = m_device->vkd(); for (auto pool : m_descriptorPools) @@ -50,7 +50,7 @@ namespace dxvk { } - void DxvkPersistentDescriptorPool::alloc( + void DxvkDescriptorPool::alloc( const DxvkBindingLayoutObjects* layout, uint32_t setMask, VkDescriptorSet* sets) { @@ -69,14 +69,14 @@ namespace dxvk { } - VkDescriptorSet DxvkPersistentDescriptorPool::alloc( + VkDescriptorSet DxvkDescriptorPool::alloc( VkDescriptorSetLayout layout) { auto setList = getSetList(layout); return allocSet(setList, layout); } - void DxvkPersistentDescriptorPool::reset() { + void DxvkDescriptorPool::reset() { // As a heuristic to save memory, check how many descriptors // have actively been used in the past couple of submissions. bool isLowUsageFrame = false; @@ -118,7 +118,7 @@ namespace dxvk { } - DxvkPersistentDescriptorSetMap* DxvkPersistentDescriptorPool::getSetMapCached( + DxvkDescriptorSetMap* DxvkDescriptorPool::getSetMapCached( const DxvkBindingLayoutObjects* layout) { if (likely(m_cachedEntry.first == layout)) return m_cachedEntry.second; @@ -129,7 +129,7 @@ namespace dxvk { } - DxvkPersistentDescriptorSetMap* DxvkPersistentDescriptorPool::getSetMap( + DxvkDescriptorSetMap* DxvkDescriptorPool::getSetMap( const DxvkBindingLayoutObjects* layout) { auto pair = m_setMaps.find(layout->getPipelineLayout()); if (likely(pair != m_setMaps.end())) { @@ -151,7 +151,7 @@ namespace dxvk { } - DxvkPersistentDescriptorSetList* DxvkPersistentDescriptorPool::getSetList( + DxvkDescriptorSetList* DxvkDescriptorPool::getSetList( VkDescriptorSetLayout layout) { auto pair = m_setLists.find(layout); if (pair != m_setLists.end()) @@ -165,8 +165,8 @@ namespace dxvk { } - VkDescriptorSet DxvkPersistentDescriptorPool::allocSet( - DxvkPersistentDescriptorSetList* list, + VkDescriptorSet DxvkDescriptorPool::allocSet( + DxvkDescriptorSetList* list, VkDescriptorSetLayout layout) { VkDescriptorSet set = list->alloc(); @@ -185,7 +185,7 @@ namespace dxvk { } - VkDescriptorSet DxvkPersistentDescriptorPool::allocSetFromPool( + VkDescriptorSet DxvkDescriptorPool::allocSetFromPool( VkDescriptorPool pool, VkDescriptorSetLayout layout) { auto vk = m_device->vkd(); @@ -204,7 +204,7 @@ namespace dxvk { } - VkDescriptorPool DxvkPersistentDescriptorPool::addPool() { + VkDescriptorPool DxvkDescriptorPool::addPool() { auto vk = m_device->vkd(); uint32_t maxSets = m_contextType == DxvkContextType::Primary @@ -251,18 +251,18 @@ namespace dxvk { } - Rc DxvkDescriptorManager::getDescriptorPool() { - Rc pool = m_pools.retrieveObject(); + Rc DxvkDescriptorManager::getDescriptorPool() { + Rc pool = m_pools.retrieveObject(); if (pool == nullptr) - pool = new DxvkPersistentDescriptorPool(m_device, m_contextType); + pool = new DxvkDescriptorPool(m_device, m_contextType); return pool; } void DxvkDescriptorManager::recycleDescriptorPool( - const Rc& pool) { + const Rc& pool) { pool->reset(); m_pools.returnObject(pool); diff --git a/src/dxvk/dxvk_descriptor.h b/src/dxvk/dxvk_descriptor.h index 9609ccc22..346eb3795 100644 --- a/src/dxvk/dxvk_descriptor.h +++ b/src/dxvk/dxvk_descriptor.h @@ -36,12 +36,12 @@ namespace dxvk { /** * \brief Descriptor set list */ - class DxvkPersistentDescriptorSetList { + class DxvkDescriptorSetList { public: - DxvkPersistentDescriptorSetList(); - ~DxvkPersistentDescriptorSetList(); + DxvkDescriptorSetList(); + ~DxvkDescriptorSetList(); VkDescriptorSet alloc(); @@ -63,8 +63,8 @@ namespace dxvk { * Points to a list of set maps for each * defined set in a pipeline layout. */ - struct DxvkPersistentDescriptorSetMap { - std::array sets; + struct DxvkDescriptorSetMap { + std::array sets; }; @@ -77,15 +77,15 @@ namespace dxvk { * but allocated sets will have unspecified contents and need * to be updated. */ - class DxvkPersistentDescriptorPool : public RcObject { + class DxvkDescriptorPool : public RcObject { public: - DxvkPersistentDescriptorPool( + DxvkDescriptorPool( DxvkDevice* device, DxvkContextType contextType); - ~DxvkPersistentDescriptorPool(); + ~DxvkDescriptorPool(); /** * \brief Allocates one or multiple descriptor sets @@ -118,26 +118,26 @@ namespace dxvk { DxvkDevice* m_device; DxvkContextType m_contextType; - std::vector m_descriptorPools; - std::unordered_map m_setLists; - std::unordered_map m_setMaps; - std::pair m_cachedEntry; + std::vector m_descriptorPools; + std::unordered_map m_setLists; + std::unordered_map m_setMaps; + std::pair m_cachedEntry; uint32_t m_setsAllocated = 0; uint32_t m_setsUsed = 0; uint32_t m_lowUsageFrames = 0; - DxvkPersistentDescriptorSetMap* getSetMapCached( + DxvkDescriptorSetMap* getSetMapCached( const DxvkBindingLayoutObjects* layout); - DxvkPersistentDescriptorSetMap* getSetMap( + DxvkDescriptorSetMap* getSetMap( const DxvkBindingLayoutObjects* layout); - DxvkPersistentDescriptorSetList* getSetList( + DxvkDescriptorSetList* getSetList( VkDescriptorSetLayout layout); VkDescriptorSet allocSet( - DxvkPersistentDescriptorSetList* list, + DxvkDescriptorSetList* list, VkDescriptorSetLayout layout); VkDescriptorSet allocSetFromPool( @@ -165,7 +165,7 @@ namespace dxvk { * \brief Retrieves or creates a descriptor type * \returns The descriptor pool */ - Rc getDescriptorPool(); + Rc getDescriptorPool(); /** * \brief Recycles descriptor pool @@ -174,13 +174,13 @@ namespace dxvk { * descriptor pool for future use. */ void recycleDescriptorPool( - const Rc& pool); + const Rc& pool); private: DxvkDevice* m_device; DxvkContextType m_contextType; - DxvkRecycler m_pools; + DxvkRecycler m_pools; }; From cfc06405d2e574b1b76afe50879c0289e4c1d9a6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 22 Jun 2022 16:12:05 +0200 Subject: [PATCH 0072/1348] [dxvk] Recycle Vulkan descriptor pools as well Reduces the number of expensive reallocations when large descriptor pools get reset and repopulated. --- src/dxvk/dxvk_descriptor.cpp | 96 +++++++++++++++++++++++------------- src/dxvk/dxvk_descriptor.h | 28 ++++++++++- 2 files changed, 88 insertions(+), 36 deletions(-) diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index bfaf0b8e9..3e2ab8e14 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -35,8 +35,8 @@ namespace dxvk { DxvkDescriptorPool::DxvkDescriptorPool( DxvkDevice* device, - DxvkContextType contextType) - : m_device(device), m_contextType(contextType), + DxvkDescriptorManager* manager) + : m_device(device), m_manager(manager), m_cachedEntry(nullptr, nullptr) { } @@ -100,13 +100,10 @@ namespace dxvk { // If most sets are no longer being used, reset and destroy // descriptor pools and reset all lookup tables in order to // accomodate more descriptors of different layouts. - auto vk = m_device->vkd(); - vk->vkResetDescriptorPool(vk->device(), m_descriptorPools[0], 0); + for (auto pool : m_descriptorPools) + m_manager->recycleVulkanDescriptorPool(pool); - for (uint32_t i = 1; i < m_descriptorPools.size(); i++) - vk->vkDestroyDescriptorPool(vk->device(), m_descriptorPools[i], nullptr); - - m_descriptorPools.resize(1); + m_descriptorPools.clear(); m_setLists.clear(); m_setMaps.clear(); @@ -205,8 +202,55 @@ namespace dxvk { VkDescriptorPool DxvkDescriptorPool::addPool() { + VkDescriptorPool pool = m_manager->createVulkanDescriptorPool(); + m_descriptorPools.push_back(pool); + return pool; + } + + + DxvkDescriptorManager::DxvkDescriptorManager( + DxvkDevice* device, + DxvkContextType contextType) + : m_device(device), m_contextType(contextType) { + + } + + + DxvkDescriptorManager::~DxvkDescriptorManager() { auto vk = m_device->vkd(); + for (size_t i = 0; i < m_vkPoolCount; i++) + vk->vkDestroyDescriptorPool(vk->device(), m_vkPools[i], nullptr); + } + + + Rc DxvkDescriptorManager::getDescriptorPool() { + Rc pool = m_pools.retrieveObject(); + + if (pool == nullptr) + pool = new DxvkDescriptorPool(m_device, this); + + return pool; + } + + + void DxvkDescriptorManager::recycleDescriptorPool( + const Rc& pool) { + pool->reset(); + + m_pools.returnObject(pool); + } + + + VkDescriptorPool DxvkDescriptorManager::createVulkanDescriptorPool() { + auto vk = m_device->vkd(); + + { std::lock_guard lock(m_mutex); + + if (m_vkPoolCount) + return m_vkPools[--m_vkPoolCount]; + } + uint32_t maxSets = m_contextType == DxvkContextType::Primary ? 8192 : 256; @@ -233,39 +277,23 @@ namespace dxvk { if (vk->vkCreateDescriptorPool(vk->device(), &info, nullptr, &pool) != VK_SUCCESS) throw DxvkError("DxvkDescriptorPool: Failed to create descriptor pool"); - m_descriptorPools.push_back(pool); return pool; } - DxvkDescriptorManager::DxvkDescriptorManager( - DxvkDevice* device, - DxvkContextType contextType) - : m_device(device), m_contextType(contextType) { + void DxvkDescriptorManager::recycleVulkanDescriptorPool(VkDescriptorPool pool) { + auto vk = m_device->vkd(); + vk->vkResetDescriptorPool(vk->device(), pool, 0); - } + { std::lock_guard lock(m_mutex); + if (m_vkPoolCount < m_vkPools.size()) { + m_vkPools[m_vkPoolCount++] = pool; + return; + } + } - DxvkDescriptorManager::~DxvkDescriptorManager() { - - } - - - Rc DxvkDescriptorManager::getDescriptorPool() { - Rc pool = m_pools.retrieveObject(); - - if (pool == nullptr) - pool = new DxvkDescriptorPool(m_device, m_contextType); - - return pool; - } - - - void DxvkDescriptorManager::recycleDescriptorPool( - const Rc& pool) { - pool->reset(); - - m_pools.returnObject(pool); + vk->vkDestroyDescriptorPool(vk->device(), pool, nullptr); } } \ No newline at end of file diff --git a/src/dxvk/dxvk_descriptor.h b/src/dxvk/dxvk_descriptor.h index 346eb3795..d1fc4a6af 100644 --- a/src/dxvk/dxvk_descriptor.h +++ b/src/dxvk/dxvk_descriptor.h @@ -9,6 +9,7 @@ namespace dxvk { class DxvkDevice; + class DxvkDescriptorManager; /** * \brief DXVK context type @@ -83,7 +84,7 @@ namespace dxvk { DxvkDescriptorPool( DxvkDevice* device, - DxvkContextType contextType); + DxvkDescriptorManager* manager); ~DxvkDescriptorPool(); @@ -116,7 +117,7 @@ namespace dxvk { private: DxvkDevice* m_device; - DxvkContextType m_contextType; + DxvkDescriptorManager* m_manager; std::vector m_descriptorPools; std::unordered_map m_setLists; @@ -176,12 +177,35 @@ namespace dxvk { void recycleDescriptorPool( const Rc& pool); + /** + * \brief Creates a Vulkan descriptor pool + * + * Returns an existing unused pool or + * creates a new one if necessary. + * \returns The descriptor pool + */ + VkDescriptorPool createVulkanDescriptorPool(); + + /** + * \brief Returns unused descriptor pool + * + * Caches the pool for future use, or destroys + * it if there are too many objects in the cache + * already. + * \param [in] pool Vulkan descriptor pool + */ + void recycleVulkanDescriptorPool(VkDescriptorPool pool); + private: DxvkDevice* m_device; DxvkContextType m_contextType; DxvkRecycler m_pools; + dxvk::mutex m_mutex; + std::array m_vkPools; + size_t m_vkPoolCount = 0; + }; } \ No newline at end of file From d4d87123b44623dcf93ca1b5d77f41572006e9dd Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 23 Jun 2022 16:00:23 +0200 Subject: [PATCH 0073/1348] [dxvk] Add safety mechanism to submit large descriptor pools --- src/dxvk/dxvk_context.cpp | 6 +++--- src/dxvk/dxvk_descriptor.cpp | 18 ++++++++++++++++++ src/dxvk/dxvk_descriptor.h | 8 ++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 06950c814..1ce295768 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -103,9 +103,9 @@ namespace dxvk { m_initBarriers.recordCommands(m_cmd); m_execBarriers.recordCommands(m_cmd); - if (m_type != DxvkContextType::Primary) { + if (m_descriptorPool->shouldSubmit(false)) { m_cmd->trackDescriptorPool(m_descriptorPool, m_descriptorManager); - m_descriptorPool = nullptr; + m_descriptorPool = m_descriptorManager->getDescriptorPool(); } m_cmd->endRecording(); @@ -114,7 +114,7 @@ namespace dxvk { void DxvkContext::endFrame() { - if (m_descriptorPool != nullptr) { + if (m_descriptorPool->shouldSubmit(true)) { m_cmd->trackDescriptorPool(m_descriptorPool, m_descriptorManager); m_descriptorPool = m_descriptorManager->getDescriptorPool(); } diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index 3e2ab8e14..0516baeeb 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -50,6 +50,24 @@ namespace dxvk { } + bool DxvkDescriptorPool::shouldSubmit(bool endFrame) { + // Never submit empty descriptor pools + if (!m_setsAllocated) + return false; + + // No frame tracking for supplementary contexts, so + // always submit those at the end of a command list + if (endFrame || m_contextType != DxvkContextType::Primary) + return true; + + // Submit very large descriptor pools to prevent extreme + // memory bloat. This may be necessary for off-screen + // rendering applications, or in situations where games + // pre-render a lot of images without presenting in between. + return m_descriptorPools.size() >= 8; + } + + void DxvkDescriptorPool::alloc( const DxvkBindingLayoutObjects* layout, uint32_t setMask, diff --git a/src/dxvk/dxvk_descriptor.h b/src/dxvk/dxvk_descriptor.h index d1fc4a6af..05534f0f2 100644 --- a/src/dxvk/dxvk_descriptor.h +++ b/src/dxvk/dxvk_descriptor.h @@ -88,6 +88,14 @@ namespace dxvk { ~DxvkDescriptorPool(); + /** + * \brief Tests whether the descriptor pool should be replaced + * + * \param [in] endFrame Whether this is the end of the frame + * \returns \c true if the pool should be submitted + */ + bool shouldSubmit(bool endFrame); + /** * \brief Allocates one or multiple descriptor sets * From 758ba5a80dcaf42dbc23c2e0aac21d115c95cd40 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 22 Jun 2022 01:58:57 +0200 Subject: [PATCH 0074/1348] [dxvk] Inline all frequently-used binding methods --- src/dxvk/dxvk_context.cpp | 117 -------------------------------------- src/dxvk/dxvk_context.h | 88 +++++++++++++++++++++++++--- 2 files changed, 80 insertions(+), 125 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 1ce295768..ff69d2e6f 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -142,92 +142,6 @@ namespace dxvk { } - void DxvkContext::bindRenderTargets( - const DxvkRenderTargets& targets) { - // Set up default render pass ops - m_state.om.renderTargets = targets; - - this->resetRenderPassOps( - m_state.om.renderTargets, - m_state.om.renderPassOps); - - if (!m_state.om.framebufferInfo.hasTargets(targets)) { - // Create a new framebuffer object next - // time we start rendering something - m_flags.set(DxvkContextFlag::GpDirtyFramebuffer); - } else { - // Don't redundantly spill the render pass if - // the same render targets are bound again - m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer); - } - } - - - void DxvkContext::bindDrawBuffers( - const DxvkBufferSlice& argBuffer, - const DxvkBufferSlice& cntBuffer) { - m_state.id.argBuffer = argBuffer; - m_state.id.cntBuffer = cntBuffer; - - m_flags.set(DxvkContextFlag::DirtyDrawBuffer); - } - - - void DxvkContext::bindIndexBuffer( - const DxvkBufferSlice& buffer, - VkIndexType indexType) { - if (!m_state.vi.indexBuffer.matchesBuffer(buffer)) - m_vbTracked.clr(MaxNumVertexBindings); - - m_state.vi.indexBuffer = buffer; - m_state.vi.indexType = indexType; - - m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer); - } - - - void DxvkContext::bindResourceBuffer( - VkShaderStageFlags stages, - uint32_t slot, - const DxvkBufferSlice& buffer) { - bool needsUpdate = !m_rc[slot].bufferSlice.matchesBuffer(buffer); - - if (likely(needsUpdate)) - m_rcTracked.clr(slot); - - m_rc[slot].bufferSlice = buffer; - - m_descriptorState.dirtyBuffers(stages); - } - - - void DxvkContext::bindResourceView( - VkShaderStageFlags stages, - uint32_t slot, - const Rc& imageView, - const Rc& bufferView) { - m_rc[slot].imageView = imageView; - m_rc[slot].bufferView = bufferView; - m_rc[slot].bufferSlice = bufferView != nullptr - ? bufferView->slice() - : DxvkBufferSlice(); - m_rcTracked.clr(slot); - - m_descriptorState.dirtyViews(stages); - } - - - void DxvkContext::bindResourceSampler( - VkShaderStageFlags stages, - uint32_t slot, - const Rc& sampler) { - m_rc[slot].sampler = sampler; - m_rcTracked.clr(slot); - - m_descriptorState.dirtyViews(stages); - } - - void DxvkContext::bindShader( VkShaderStageFlagBits stage, const Rc& shader) { @@ -257,37 +171,6 @@ namespace dxvk { } - void DxvkContext::bindVertexBuffer( - uint32_t binding, - const DxvkBufferSlice& buffer, - uint32_t stride) { - if (!m_state.vi.vertexBuffers[binding].matchesBuffer(buffer)) - m_vbTracked.clr(binding); - - m_state.vi.vertexBuffers[binding] = buffer; - m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers); - - if (unlikely(m_state.vi.vertexStrides[binding] != stride)) { - m_state.vi.vertexStrides[binding] = stride; - m_flags.set(DxvkContextFlag::GpDirtyPipelineState); - } - } - - - void DxvkContext::bindXfbBuffer( - uint32_t binding, - const DxvkBufferSlice& buffer, - const DxvkBufferSlice& counter) { - if (!m_state.xfb.buffers [binding].matches(buffer) - || !m_state.xfb.counters[binding].matches(counter)) { - m_state.xfb.buffers [binding] = buffer; - m_state.xfb.counters[binding] = counter; - - m_flags.set(DxvkContextFlag::GpDirtyXfbBuffers); - } - } - - void DxvkContext::blitImage( const Rc& dstImage, const VkComponentMapping& dstMapping, diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 2ce14e72b..443ba8640 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -87,7 +87,24 @@ namespace dxvk { * \param [in] targets Render targets to bind */ void bindRenderTargets( - const DxvkRenderTargets& targets); + const DxvkRenderTargets& targets) { + // Set up default render pass ops + m_state.om.renderTargets = targets; + + this->resetRenderPassOps( + m_state.om.renderTargets, + m_state.om.renderPassOps); + + if (!m_state.om.framebufferInfo.hasTargets(targets)) { + // Create a new framebuffer object next + // time we start rendering something + m_flags.set(DxvkContextFlag::GpDirtyFramebuffer); + } else { + // Don't redundantly spill the render pass if + // the same render targets are bound again + m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer); + } + } /** * \brief Binds indirect argument buffer @@ -99,7 +116,12 @@ namespace dxvk { */ void bindDrawBuffers( const DxvkBufferSlice& argBuffer, - const DxvkBufferSlice& cntBuffer); + const DxvkBufferSlice& cntBuffer) { + m_state.id.argBuffer = argBuffer; + m_state.id.cntBuffer = cntBuffer; + + m_flags.set(DxvkContextFlag::DirtyDrawBuffer); + } /** * \brief Binds index buffer @@ -111,7 +133,15 @@ namespace dxvk { */ void bindIndexBuffer( const DxvkBufferSlice& buffer, - VkIndexType indexType); + VkIndexType indexType) { + if (!m_state.vi.indexBuffer.matchesBuffer(buffer)) + m_vbTracked.clr(MaxNumVertexBindings); + + m_state.vi.indexBuffer = buffer; + m_state.vi.indexType = indexType; + + m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer); + } /** * \brief Binds buffer as a shader resource @@ -124,7 +154,16 @@ namespace dxvk { void bindResourceBuffer( VkShaderStageFlags stages, uint32_t slot, - const DxvkBufferSlice& buffer); + const DxvkBufferSlice& buffer) { + bool needsUpdate = !m_rc[slot].bufferSlice.matchesBuffer(buffer); + + if (likely(needsUpdate)) + m_rcTracked.clr(slot); + + m_rc[slot].bufferSlice = buffer; + + m_descriptorState.dirtyBuffers(stages); + } /** * \brief Binds image or buffer view @@ -141,7 +180,16 @@ namespace dxvk { VkShaderStageFlags stages, uint32_t slot, const Rc& imageView, - const Rc& bufferView); + const Rc& bufferView) { + m_rc[slot].imageView = imageView; + m_rc[slot].bufferView = bufferView; + m_rc[slot].bufferSlice = bufferView != nullptr + ? bufferView->slice() + : DxvkBufferSlice(); + m_rcTracked.clr(slot); + + m_descriptorState.dirtyViews(stages); + } /** * \brief Binds image sampler @@ -155,7 +203,12 @@ namespace dxvk { void bindResourceSampler( VkShaderStageFlags stages, uint32_t slot, - const Rc& sampler); + const Rc& sampler) { + m_rc[slot].sampler = sampler; + m_rcTracked.clr(slot); + + m_descriptorState.dirtyViews(stages); + } /** * \brief Binds a shader to a given state @@ -178,7 +231,18 @@ namespace dxvk { void bindVertexBuffer( uint32_t binding, const DxvkBufferSlice& buffer, - uint32_t stride); + uint32_t stride) { + if (!m_state.vi.vertexBuffers[binding].matchesBuffer(buffer)) + m_vbTracked.clr(binding); + + m_state.vi.vertexBuffers[binding] = buffer; + m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers); + + if (unlikely(m_state.vi.vertexStrides[binding] != stride)) { + m_state.vi.vertexStrides[binding] = stride; + m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + } + } /** * \brief Binds transform feedback buffer @@ -190,7 +254,15 @@ namespace dxvk { void bindXfbBuffer( uint32_t binding, const DxvkBufferSlice& buffer, - const DxvkBufferSlice& counter); + const DxvkBufferSlice& counter) { + if (!m_state.xfb.buffers [binding].matches(buffer) + || !m_state.xfb.counters[binding].matches(counter)) { + m_state.xfb.buffers [binding] = buffer; + m_state.xfb.counters[binding] = counter; + + m_flags.set(DxvkContextFlag::GpDirtyXfbBuffers); + } + } /** * \brief Blits an image From d4a3b823a24807cd44490fe581f77b42c82ac76a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 23 Jun 2022 00:41:42 +0200 Subject: [PATCH 0075/1348] [dxvk] Add stat counters for descriptor sets and pools --- src/dxvk/dxvk_cmdlist.h | 1 + src/dxvk/dxvk_descriptor.cpp | 36 ++++++++++++++++++++++++++++++++---- src/dxvk/dxvk_descriptor.h | 14 +++++++++++++- src/dxvk/dxvk_stats.h | 2 ++ 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 4a3b5b625..cfb4840de 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -758,6 +758,7 @@ namespace dxvk { void trackDescriptorPool( const Rc& pool, const Rc& manager) { + pool->updateStats(m_statCounters); m_descriptorPools.push_back({ pool, manager }); } diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index 0516baeeb..fa1e1e77d 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -35,8 +35,9 @@ namespace dxvk { DxvkDescriptorPool::DxvkDescriptorPool( DxvkDevice* device, - DxvkDescriptorManager* manager) - : m_device(device), m_manager(manager), + DxvkDescriptorManager* manager, + DxvkContextType contextType) + : m_device(device), m_manager(manager), m_contextType(contextType), m_cachedEntry(nullptr, nullptr) { } @@ -47,6 +48,13 @@ namespace dxvk { for (auto pool : m_descriptorPools) vk->vkDestroyDescriptorPool(vk->device(), pool, nullptr); + + if (m_contextType == DxvkContextType::Primary) { + m_device->addStatCtr(DxvkStatCounter::DescriptorPoolCount, + uint64_t(-int64_t(m_descriptorPools.size()))); + m_device->addStatCtr(DxvkStatCounter::DescriptorSetCount, + uint64_t(-int64_t(m_setsAllocated))); + } } @@ -133,6 +141,16 @@ namespace dxvk { } + void DxvkDescriptorPool::updateStats(DxvkStatCounters& counters) { + if (m_contextType == DxvkContextType::Primary) { + counters.addCtr(DxvkStatCounter::DescriptorSetCount, + uint64_t(int64_t(m_setsAllocated) - int64_t(m_prevSetsAllocated))); + } + + m_prevSetsAllocated = m_setsAllocated; + } + + DxvkDescriptorSetMap* DxvkDescriptorPool::getSetMapCached( const DxvkBindingLayoutObjects* layout) { if (likely(m_cachedEntry.first == layout)) @@ -181,7 +199,7 @@ namespace dxvk { VkDescriptorSet DxvkDescriptorPool::allocSet( - DxvkDescriptorSetList* list, + DxvkDescriptorSetList* list, VkDescriptorSetLayout layout) { VkDescriptorSet set = list->alloc(); @@ -239,6 +257,11 @@ namespace dxvk { for (size_t i = 0; i < m_vkPoolCount; i++) vk->vkDestroyDescriptorPool(vk->device(), m_vkPools[i], nullptr); + + if (m_contextType == DxvkContextType::Primary) { + m_device->addStatCtr(DxvkStatCounter::DescriptorPoolCount, + uint64_t(-int64_t(m_vkPoolCount))); + } } @@ -246,7 +269,7 @@ namespace dxvk { Rc pool = m_pools.retrieveObject(); if (pool == nullptr) - pool = new DxvkDescriptorPool(m_device, this); + pool = new DxvkDescriptorPool(m_device, this, m_contextType); return pool; } @@ -295,6 +318,8 @@ namespace dxvk { if (vk->vkCreateDescriptorPool(vk->device(), &info, nullptr, &pool) != VK_SUCCESS) throw DxvkError("DxvkDescriptorPool: Failed to create descriptor pool"); + if (m_contextType == DxvkContextType::Primary) + m_device->addStatCtr(DxvkStatCounter::DescriptorPoolCount, 1); return pool; } @@ -311,6 +336,9 @@ namespace dxvk { } } + if (m_contextType == DxvkContextType::Primary) + m_device->addStatCtr(DxvkStatCounter::DescriptorPoolCount, uint64_t(-1ll)); + vk->vkDestroyDescriptorPool(vk->device(), pool, nullptr); } diff --git a/src/dxvk/dxvk_descriptor.h b/src/dxvk/dxvk_descriptor.h index 05534f0f2..7c874f65d 100644 --- a/src/dxvk/dxvk_descriptor.h +++ b/src/dxvk/dxvk_descriptor.h @@ -5,6 +5,7 @@ #include "dxvk_include.h" #include "dxvk_pipelayout.h" #include "dxvk_recycler.h" +#include "dxvk_stats.h" namespace dxvk { @@ -84,7 +85,8 @@ namespace dxvk { DxvkDescriptorPool( DxvkDevice* device, - DxvkDescriptorManager* manager); + DxvkDescriptorManager* manager, + DxvkContextType contextType); ~DxvkDescriptorPool(); @@ -122,10 +124,17 @@ namespace dxvk { */ void reset(); + /** + * \brief Updates stat counters with set count + * \param [out] counters Stat counters + */ + void updateStats(DxvkStatCounters& counters); + private: DxvkDevice* m_device; DxvkDescriptorManager* m_manager; + DxvkContextType m_contextType; std::vector m_descriptorPools; std::unordered_map m_setLists; @@ -134,6 +143,9 @@ namespace dxvk { uint32_t m_setsAllocated = 0; uint32_t m_setsUsed = 0; + + uint32_t m_prevSetsAllocated = 0; + uint32_t m_lowUsageFrames = 0; DxvkDescriptorSetMap* getSetMapCached( diff --git a/src/dxvk/dxvk_stats.h b/src/dxvk/dxvk_stats.h index 9138c7c6f..4d274bba4 100644 --- a/src/dxvk/dxvk_stats.h +++ b/src/dxvk/dxvk_stats.h @@ -26,6 +26,8 @@ namespace dxvk { CsSyncCount, ///< CS thread synchronizations CsSyncTicks, ///< Time spent waiting on CS CsChunkCount, ///< Submitted CS chunks + DescriptorPoolCount, ///< Descriptor pool count + DescriptorSetCount, ///< Descriptor sets allocated NumCounters, ///< Number of counters available }; From c67481b904379c8e6ceca810c17411fff06ee152 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 23 Jun 2022 00:41:53 +0200 Subject: [PATCH 0076/1348] [hud] Add HUD item for descriptor stats --- README.md | 1 + src/dxvk/hud/dxvk_hud.cpp | 1 + src/dxvk/hud/dxvk_hud_item.cpp | 49 ++++++++++++++++++++++++++++++++++ src/dxvk/hud/dxvk_hud_item.h | 27 +++++++++++++++++++ 4 files changed, 78 insertions(+) diff --git a/README.md b/README.md index 8c02992a3..4db6c29a5 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ The `DXVK_HUD` environment variable controls a HUD which can display the framera - `submissions`: Shows the number of command buffers submitted per frame. - `drawcalls`: Shows the number of draw calls and render passes per frame. - `pipelines`: Shows the total number of graphics and compute pipelines. +- `descriptors`: Shows the number of descriptor pools and descriptor sets. - `memory`: Shows the amount of device memory allocated and used. - `gpuload`: Shows estimated GPU load. May be inaccurate. - `version`: Shows DXVK version. diff --git a/src/dxvk/hud/dxvk_hud.cpp b/src/dxvk/hud/dxvk_hud.cpp index 003c19156..f5e725044 100644 --- a/src/dxvk/hud/dxvk_hud.cpp +++ b/src/dxvk/hud/dxvk_hud.cpp @@ -42,6 +42,7 @@ namespace dxvk::hud { addItem("submissions", -1, device); addItem("drawcalls", -1, device); addItem("pipelines", -1, device); + addItem("descriptors", -1, device); addItem("memory", -1, device); addItem("cs", -1, device); addItem("gpuload", -1, device); diff --git a/src/dxvk/hud/dxvk_hud_item.cpp b/src/dxvk/hud/dxvk_hud_item.cpp index d236287a8..59ca3ffe0 100644 --- a/src/dxvk/hud/dxvk_hud_item.cpp +++ b/src/dxvk/hud/dxvk_hud_item.cpp @@ -500,6 +500,55 @@ namespace dxvk::hud { } + HudDescriptorStatsItem::HudDescriptorStatsItem(const Rc& device) + : m_device(device) { + + } + + + HudDescriptorStatsItem::~HudDescriptorStatsItem() { + + } + + + void HudDescriptorStatsItem::update(dxvk::high_resolution_clock::time_point time) { + DxvkStatCounters counters = m_device->getStatCounters(); + + m_descriptorPoolCount = counters.getCtr(DxvkStatCounter::DescriptorPoolCount); + m_descriptorSetCount = counters.getCtr(DxvkStatCounter::DescriptorSetCount); + } + + + HudPos HudDescriptorStatsItem::render( + HudRenderer& renderer, + HudPos position) { + position.y += 16.0f; + renderer.drawText(16.0f, + { position.x, position.y }, + { 1.0f, 0.25f, 0.5f, 1.0f }, + "Descriptor pools:"); + + renderer.drawText(16.0f, + { position.x + 216.0f, position.y }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + str::format(m_descriptorPoolCount)); + + position.y += 20.0f; + renderer.drawText(16.0f, + { position.x, position.y }, + { 1.0f, 0.25f, 0.5f, 1.0f }, + "Descriptor sets:"); + + renderer.drawText(16.0f, + { position.x + 216.0f, position.y }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + str::format(m_descriptorSetCount)); + + position.y += 8.0f; + return position; + } + + HudMemoryStatsItem::HudMemoryStatsItem(const Rc& device) : m_device(device), m_memory(device->adapter()->memoryProperties()) { diff --git a/src/dxvk/hud/dxvk_hud_item.h b/src/dxvk/hud/dxvk_hud_item.h index 275461c6d..a868c9293 100644 --- a/src/dxvk/hud/dxvk_hud_item.h +++ b/src/dxvk/hud/dxvk_hud_item.h @@ -336,6 +336,33 @@ namespace dxvk::hud { }; + /** + * \brief HUD item to display descriptor stats + */ + class HudDescriptorStatsItem : public HudItem { + + public: + + HudDescriptorStatsItem(const Rc& device); + + ~HudDescriptorStatsItem(); + + void update(dxvk::high_resolution_clock::time_point time); + + HudPos render( + HudRenderer& renderer, + HudPos position); + + private: + + Rc m_device; + + uint64_t m_descriptorPoolCount = 0; + uint64_t m_descriptorSetCount = 0; + + }; + + /** * \brief HUD item to display memory usage */ From db078615181e9a719e41e2b193c7c734af24d55a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 23 Jun 2022 17:41:19 +0200 Subject: [PATCH 0077/1348] [dxvk] Remove old pipeline layout implementation --- src/d3d11/d3d11_video.cpp | 9 - src/d3d9/d3d9_fixed_function.cpp | 46 ----- src/d3d9/d3d9_format_helpers.cpp | 7 - src/d3d9/d3d9_swvp_emu.cpp | 8 - src/dxbc/dxbc_compiler.cpp | 56 ------ src/dxbc/dxbc_compiler.h | 1 - src/dxso/dxso_compiler.cpp | 39 ---- src/dxso/dxso_compiler.h | 1 - src/dxvk/dxvk_pipelayout.cpp | 189 ------------------- src/dxvk/dxvk_pipelayout.h | 273 ---------------------------- src/dxvk/dxvk_shader.cpp | 53 ------ src/dxvk/dxvk_shader.h | 27 --- src/dxvk/dxvk_swapchain_blitter.cpp | 7 - src/dxvk/hud/dxvk_hud_renderer.cpp | 19 -- 14 files changed, 735 deletions(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 47a84bd0e..f414d5473 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -336,13 +336,6 @@ namespace dxvk { { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_READ_BIT }, }}; - const std::array fsResourceSlots = {{ - { 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC }, - { 1, VK_DESCRIPTOR_TYPE_SAMPLER }, - { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_IMAGE_VIEW_TYPE_2D }, - { 3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_IMAGE_VIEW_TYPE_2D }, - }}; - DxvkShaderCreateInfo vsInfo; vsInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; vsInfo.outputMask = 0x1; @@ -352,8 +345,6 @@ namespace dxvk { fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; fsInfo.bindingCount = fsBindings.size(); fsInfo.bindings = fsBindings.data(); - fsInfo.resourceSlotCount = fsResourceSlots.size(); - fsInfo.resourceSlots = fsResourceSlots.data(); fsInfo.inputMask = 0x1; fsInfo.outputMask = 0x1; m_fs = new DxvkShader(fsInfo, std::move(fsCode)); diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index d73e098f3..03b073434 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -602,8 +602,6 @@ namespace dxvk { std::string m_filename; SpirvModule m_module; - std::vector - m_resourceSlots; std::vector m_bindings; std::vector m_entryPointInterfaces; @@ -717,8 +715,6 @@ namespace dxvk { info.stage = isVS() ? VK_SHADER_STAGE_VERTEX_BIT : VK_SHADER_STAGE_FRAGMENT_BIT; info.bindingCount = m_bindings.size(); info.bindings = m_bindings.data(); - info.resourceSlotCount = m_resourceSlots.size(); - info.resourceSlots = m_resourceSlots.data(); info.inputMask = m_inputMask; info.outputMask = m_outputMask; info.pushConstOffset = m_pushConstOffset; @@ -1390,13 +1386,6 @@ namespace dxvk { m_module.decorateDescriptorSet(m_vs.constantBuffer, 0); m_module.decorateBinding(m_vs.constantBuffer, bindingId); - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = VK_ACCESS_UNIFORM_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; @@ -1436,13 +1425,6 @@ namespace dxvk { m_module.decorate(m_vs.vertexBlendData, spv::DecorationNonWritable); - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = VK_ACCESS_SHADER_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER }; binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; @@ -2049,13 +2031,6 @@ namespace dxvk { m_module.decorateDescriptorSet(m_ps.constantBuffer, 0); m_module.decorateBinding(m_ps.constantBuffer, bindingId); - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = VK_ACCESS_UNIFORM_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; @@ -2127,13 +2102,6 @@ namespace dxvk { m_module.decorateBinding(sampler.varId, bindingId); // Store descriptor info for the shader interface - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - resource.view = viewType; - resource.access = VK_ACCESS_SHADER_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER }; binding.resourceBinding = bindingId; binding.viewType = viewType; @@ -2155,13 +2123,6 @@ namespace dxvk { m_module.decorateDescriptorSet(m_ps.sharedState, 0); m_module.decorateBinding(m_ps.sharedState, bindingId); - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = VK_ACCESS_UNIFORM_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; @@ -2201,13 +2162,6 @@ namespace dxvk { m_module.decorateDescriptorSet(clipPlaneBlock, 0); m_module.decorateBinding (clipPlaneBlock, bindingId); - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = VK_ACCESS_UNIFORM_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; diff --git a/src/d3d9/d3d9_format_helpers.cpp b/src/d3d9/d3d9_format_helpers.cpp index 0ccfba350..d8d73d70a 100644 --- a/src/d3d9/d3d9_format_helpers.cpp +++ b/src/d3d9/d3d9_format_helpers.cpp @@ -130,17 +130,10 @@ namespace dxvk { { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, BindingIds::Buffer, VK_IMAGE_VIEW_TYPE_1D, 0, VK_ACCESS_SHADER_READ_BIT }, } }; - const std::array resourceSlots = { { - { BindingIds::Image, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_IMAGE_VIEW_TYPE_2D }, - { BindingIds::Buffer, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, VK_IMAGE_VIEW_TYPE_1D }, - } }; - DxvkShaderCreateInfo info; info.stage = VK_SHADER_STAGE_COMPUTE_BIT; info.bindingCount = bindings.size(); info.bindings = bindings.data(); - info.resourceSlotCount = resourceSlots.size(); - info.resourceSlots = resourceSlots.data(); info.pushConstOffset = 0; info.pushConstSize = sizeof(VkExtent2D); diff --git a/src/d3d9/d3d9_swvp_emu.cpp b/src/d3d9/d3d9_swvp_emu.cpp index 226191cba..f02d4a20e 100644 --- a/src/d3d9/d3d9_swvp_emu.cpp +++ b/src/d3d9/d3d9_swvp_emu.cpp @@ -136,11 +136,6 @@ namespace dxvk { m_bufferBinding.access = VK_ACCESS_SHADER_WRITE_BIT; m_bufferBinding.stages = 0; - m_bufferResource.slot = bufferSlot; - m_bufferResource.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - m_bufferResource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - m_bufferResource.access = VK_ACCESS_SHADER_WRITE_BIT; - // Load our builtins uint32_t primitiveIdPtr = m_module.newVar(m_module.defPointerType(uint_t, spv::StorageClassInput), spv::StorageClassInput); m_module.decorateBuiltIn(primitiveIdPtr, spv::BuiltInPrimitiveId); @@ -291,8 +286,6 @@ namespace dxvk { info.stage = VK_SHADER_STAGE_GEOMETRY_BIT; info.bindingCount = 1; info.bindings = &m_bufferBinding; - info.resourceSlotCount = 1; - info.resourceSlots = &m_bufferResource; info.inputMask = m_inputMask; return new DxvkShader(info, m_module.compile()); @@ -306,7 +299,6 @@ namespace dxvk { uint32_t m_entryPointId = 0; uint32_t m_inputMask = 0u; DxvkBindingInfo m_bufferBinding; - DxvkResourceSlot m_bufferResource; }; diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index e669356a6..27c956280 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -251,8 +251,6 @@ namespace dxvk { // Create the shader object DxvkShaderCreateInfo info; info.stage = m_programInfo.shaderStage(); - info.resourceSlotCount = m_resourceSlots.size(); - info.resourceSlots = m_resourceSlots.data(); info.bindingCount = m_bindings.size(); info.bindings = m_bindings.data(); info.inputMask = m_inputMask; @@ -840,13 +838,6 @@ namespace dxvk { ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = descriptorType; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = VK_ACCESS_UNIFORM_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { descriptorType }; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; @@ -883,13 +874,6 @@ namespace dxvk { m_module.decorateBinding(varId, bindingId); // Store descriptor info for the shader interface - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_SAMPLER; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = 0; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_SAMPLER }; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.resourceBinding = bindingId; @@ -1070,24 +1054,6 @@ namespace dxvk { } // Store descriptor info for the shader interface - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.view = typeInfo.vtype; - - if (isUav) { - resource.type = resourceType == DxbcResourceDim::Buffer - ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER - : VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - resource.access = m_analysis->uavInfos[registerId].accessFlags; - } else { - resource.type = resourceType == DxbcResourceDim::Buffer - ? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER - : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - resource.access = VK_ACCESS_SHADER_READ_BIT; - } - - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { }; binding.viewType = typeInfo.vtype; binding.resourceBinding = bindingId; @@ -1235,20 +1201,6 @@ namespace dxvk { } // Store descriptor info for the shader interface - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = useRawSsbo - ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER - : (isUav - ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER - : VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER); - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = isUav - ? m_analysis->uavInfos[registerId].accessFlags - : VK_ACCESS_SHADER_READ_BIT; - - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { }; binding.descriptorType = useRawSsbo ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER @@ -1498,14 +1450,6 @@ namespace dxvk { m_module.decorateBinding(varId, bindingId); // Declare the storage buffer binding - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = VK_ACCESS_SHADER_READ_BIT - | VK_ACCESS_SHADER_WRITE_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER }; binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 9208ddbbb..3adaca86a 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -424,7 +424,6 @@ namespace dxvk { /////////////////////////////////////////////////////// // Resource slot description for the shader. This will // be used to map D3D11 bindings to DXVK bindings. - std::vector m_resourceSlots; std::vector m_bindings; //////////////////////////////////////////////// diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 372e89b54..6b73977a8 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -250,8 +250,6 @@ namespace dxvk { info.stage = m_programInfo.shaderStage(); info.bindingCount = m_bindings.size(); info.bindings = m_bindings.data(); - info.resourceSlotCount = m_resourceSlots.size(); - info.resourceSlots = m_resourceSlots.data(); info.inputMask = m_inputMask; info.outputMask = m_outputMask; info.pushConstOffset = m_pushConstOffset; @@ -332,13 +330,6 @@ namespace dxvk { m_module.decorateDescriptorSet(m_cBuffer, 0); m_module.decorateBinding(m_cBuffer, bindingId); - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = VK_ACCESS_UNIFORM_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; @@ -432,15 +423,6 @@ namespace dxvk { if (asSsbo) m_module.decorate(constantBufferId, spv::DecorationNonWritable); - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = asSsbo - ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER - : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = asSsbo ? VK_ACCESS_MEMORY_READ_BIT : VK_ACCESS_UNIFORM_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { }; binding.descriptorType = asSsbo ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER @@ -529,13 +511,6 @@ namespace dxvk { m_module.decorateDescriptorSet(m_ps.sharedState, 0); m_module.decorateBinding(m_ps.sharedState, bindingId); - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = VK_ACCESS_UNIFORM_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; @@ -877,13 +852,6 @@ namespace dxvk { str::format("s", idx, "_bound").c_str()); // Store descriptor info for the shader interface - DxvkResourceSlot resource; - resource.slot = binding; - resource.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - resource.view = implicit ? VK_IMAGE_VIEW_TYPE_MAX_ENUM : viewType; - resource.access = VK_ACCESS_SHADER_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo bindingInfo = { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER }; bindingInfo.resourceBinding = binding; bindingInfo.viewType = implicit ? VK_IMAGE_VIEW_TYPE_MAX_ENUM : viewType; @@ -3683,13 +3651,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( m_module.decorateDescriptorSet(clipPlaneBlock, 0); m_module.decorateBinding (clipPlaneBlock, bindingId); - DxvkResourceSlot resource; - resource.slot = bindingId; - resource.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - resource.access = VK_ACCESS_UNIFORM_READ_BIT; - m_resourceSlots.push_back(resource); - DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h index 9b46334aa..d28d613fa 100644 --- a/src/dxso/dxso_compiler.h +++ b/src/dxso/dxso_compiler.h @@ -277,7 +277,6 @@ namespace dxvk { /////////////////////////////////////////////////////// // Resource slot description for the shader. This will // be used to map D3D9 bindings to DXVK bindings. - std::vector m_resourceSlots; std::vector m_bindings; //////////////////////////////////////////////// diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index 7ad5e7cf8..65ef26c0b 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -338,193 +338,4 @@ namespace dxvk { return flags; } - - DxvkDescriptorSlotMapping:: DxvkDescriptorSlotMapping() { } - DxvkDescriptorSlotMapping::~DxvkDescriptorSlotMapping() { } - - - void DxvkDescriptorSlotMapping::defineSlot( - VkShaderStageFlagBits stage, - const DxvkResourceSlot& desc) { - uint32_t bindingId = this->getBindingId(desc.slot); - - if (bindingId != InvalidBinding) { - m_descriptorSlots[bindingId].stages |= stage; - m_descriptorSlots[bindingId].access |= desc.access; - } else { - DxvkDescriptorSlot slotInfo; - slotInfo.slot = desc.slot; - slotInfo.type = desc.type; - slotInfo.view = desc.view; - slotInfo.stages = stage; - slotInfo.access = desc.access; - m_descriptorSlots.push_back(slotInfo); - } - } - - - void DxvkDescriptorSlotMapping::definePushConstRange( - VkShaderStageFlagBits stage, - uint32_t offset, - uint32_t size) { - m_pushConstRange.stageFlags |= stage; - m_pushConstRange.size = std::max( - m_pushConstRange.size, offset + size); - } - - - uint32_t DxvkDescriptorSlotMapping::getBindingId(uint32_t slot) const { - // This won't win a performance competition, but the number - // of bindings used by a shader is usually much smaller than - // the number of resource slots available to the system. - for (uint32_t i = 0; i < m_descriptorSlots.size(); i++) { - if (m_descriptorSlots[i].slot == slot) - return i; - } - - return InvalidBinding; - } - - - void DxvkDescriptorSlotMapping::makeDescriptorsDynamic( - uint32_t uniformBuffers, - uint32_t storageBuffers) { - if (this->countDescriptors(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) <= uniformBuffers) - this->replaceDescriptors(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC); - } - - - uint32_t DxvkDescriptorSlotMapping::countDescriptors( - VkDescriptorType type) const { - uint32_t count = 0; - - for (const auto& slot : m_descriptorSlots) - count += slot.type == type ? 1 : 0; - - return count; - } - - - void DxvkDescriptorSlotMapping::replaceDescriptors( - VkDescriptorType oldType, - VkDescriptorType newType) { - for (auto& slot : m_descriptorSlots) { - if (slot.type == oldType) - slot.type = newType; - } - } - - - DxvkPipelineLayout::DxvkPipelineLayout( - const Rc& vkd, - const DxvkDescriptorSlotMapping& slotMapping, - VkPipelineBindPoint pipelineBindPoint) - : m_vkd (vkd), - m_pushConstRange(slotMapping.pushConstRange()), - m_bindingSlots (slotMapping.bindingCount()) { - - auto bindingCount = slotMapping.bindingCount(); - auto bindingInfos = slotMapping.bindingInfos(); - - if (bindingCount > MaxNumActiveBindings) - throw DxvkError(str::format("Too many active bindings in pipeline layout (", bindingCount, ")")); - - for (uint32_t i = 0; i < bindingCount; i++) - m_bindingSlots[i] = bindingInfos[i]; - - std::vector bindings(bindingCount); - std::vector tEntries(bindingCount); - - for (uint32_t i = 0; i < bindingCount; i++) { - bindings[i].binding = i; - bindings[i].descriptorType = bindingInfos[i].type; - bindings[i].descriptorCount = 1; - bindings[i].stageFlags = bindingInfos[i].stages; - bindings[i].pImmutableSamplers = nullptr; - - tEntries[i].dstBinding = i; - tEntries[i].dstArrayElement = 0; - tEntries[i].descriptorCount = 1; - tEntries[i].descriptorType = bindingInfos[i].type; - tEntries[i].offset = sizeof(DxvkDescriptorInfo) * i; - tEntries[i].stride = 0; - - if (bindingInfos[i].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) - m_dynamicSlots.push_back(i); - - m_descriptorTypes.set(bindingInfos[i].type); - } - - // Create descriptor set layout. We do not need to - // create one if there are no active resource bindings. - if (bindingCount > 0) { - VkDescriptorSetLayoutCreateInfo dsetInfo; - dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - dsetInfo.pNext = nullptr; - dsetInfo.flags = 0; - dsetInfo.bindingCount = bindings.size(); - dsetInfo.pBindings = bindings.data(); - - if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(), - &dsetInfo, nullptr, &m_descriptorSetLayout) != VK_SUCCESS) - throw DxvkError("DxvkPipelineLayout: Failed to create descriptor set layout"); - } - - // Create pipeline layout with the given descriptor set layout - VkPipelineLayoutCreateInfo pipeInfo; - pipeInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeInfo.pNext = nullptr; - pipeInfo.flags = 0; - pipeInfo.setLayoutCount = bindingCount > 0 ? 1 : 0; - pipeInfo.pSetLayouts = &m_descriptorSetLayout; - pipeInfo.pushConstantRangeCount = 0; - pipeInfo.pPushConstantRanges = nullptr; - - if (m_pushConstRange.size) { - pipeInfo.pushConstantRangeCount = 1; - pipeInfo.pPushConstantRanges = &m_pushConstRange; - } - - if (m_vkd->vkCreatePipelineLayout(m_vkd->device(), - &pipeInfo, nullptr, &m_pipelineLayout) != VK_SUCCESS) { - m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_descriptorSetLayout, nullptr); - throw DxvkError("DxvkPipelineLayout: Failed to create pipeline layout"); - } - - // Create descriptor update template. If there are no active - // resource bindings, there won't be any descriptors to update. - if (bindingCount > 0) { - VkDescriptorUpdateTemplateCreateInfo templateInfo; - templateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO; - templateInfo.pNext = nullptr; - templateInfo.flags = 0; - templateInfo.descriptorUpdateEntryCount = tEntries.size(); - templateInfo.pDescriptorUpdateEntries = tEntries.data(); - templateInfo.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET; - templateInfo.descriptorSetLayout = m_descriptorSetLayout; - templateInfo.pipelineBindPoint = pipelineBindPoint; - templateInfo.pipelineLayout = m_pipelineLayout; - templateInfo.set = 0; - - if (m_vkd->vkCreateDescriptorUpdateTemplate( - m_vkd->device(), &templateInfo, nullptr, &m_descriptorTemplate) != VK_SUCCESS) { - m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_descriptorSetLayout, nullptr); - m_vkd->vkDestroyPipelineLayout(m_vkd->device(), m_pipelineLayout, nullptr); - throw DxvkError("DxvkPipelineLayout: Failed to create descriptor update template"); - } - } - } - - - DxvkPipelineLayout::~DxvkPipelineLayout() { - m_vkd->vkDestroyDescriptorUpdateTemplate( - m_vkd->device(), m_descriptorTemplate, nullptr); - - m_vkd->vkDestroyPipelineLayout( - m_vkd->device(), m_pipelineLayout, nullptr); - - m_vkd->vkDestroyDescriptorSetLayout( - m_vkd->device(), m_descriptorSetLayout, nullptr); - } - } \ No newline at end of file diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 81a9ae510..152af61a7 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -546,278 +546,5 @@ namespace dxvk { std::array m_sets; }; - - - /** - * \brief Resource slot - * - * Describes the type of a single resource - * binding that a shader can access. - */ - struct DxvkResourceSlot { - uint32_t slot; - VkDescriptorType type; - VkImageViewType view; - VkAccessFlags access; - }; - - /** - * \brief Shader interface binding - * - * Corresponds to a single descriptor binding in - * Vulkan. DXVK does not use descriptor arrays. - * Instead, each binding stores one descriptor. - */ - struct DxvkDescriptorSlot { - uint32_t slot; ///< Resource slot index for the context - VkDescriptorType type; ///< Descriptor type (aka resource type) - VkImageViewType view; ///< Compatible image view type - VkShaderStageFlags stages; ///< Stages that can use the resource - VkAccessFlags access; ///< Access flags - }; - - - /** - * \brief Descriptor slot mapping - * - * Convenience class that generates descriptor slot - * index to binding index mappings. This is required - * when generating Vulkan pipeline and descriptor set - * layouts. - */ - class DxvkDescriptorSlotMapping { - constexpr static uint32_t InvalidBinding = 0xFFFFFFFFu; - public: - - DxvkDescriptorSlotMapping(); - ~DxvkDescriptorSlotMapping(); - - /** - * \brief Number of descriptor bindings - * \returns Descriptor binding count - */ - uint32_t bindingCount() const { - return m_descriptorSlots.size(); - } - - /** - * \brief Descriptor binding infos - * \returns Descriptor binding infos - */ - const DxvkDescriptorSlot* bindingInfos() const { - return m_descriptorSlots.data(); - } - - /** - * \brief Push constant range - * \returns Push constant range - */ - VkPushConstantRange pushConstRange() const { - return m_pushConstRange; - } - - /** - * \brief Defines a new slot - * - * Adds a slot to the mapping. If the slot is already - * defined by another shader stage, this will extend - * the stage mask by the given stage. Otherwise, an - * entirely new binding is added. - * \param [in] stage Shader stage - * \param [in] desc Slot description - */ - void defineSlot( - VkShaderStageFlagBits stage, - const DxvkResourceSlot& desc); - - /** - * \brief Defines new push constant range - * - * \param [in] stage Shader stage - * \param [in] offset Range offset - * \param [in] size Range size - */ - void definePushConstRange( - VkShaderStageFlagBits stage, - uint32_t offset, - uint32_t size); - - /** - * \brief Gets binding ID for a slot - * - * \param [in] slot Resource slot - * \returns Binding index, or \c InvalidBinding - */ - uint32_t getBindingId( - uint32_t slot) const; - - /** - * \brief Makes static descriptors dynamic - * - * Replaces static uniform and storage buffer bindings by - * their dynamic equivalent if the number of bindings of - * the respective type lies within supported device limits. - * Using dynamic descriptor types may improve performance. - * \param [in] uniformBuffers Max number of uniform buffers - * \param [in] storageBuffers Max number of storage buffers - */ - void makeDescriptorsDynamic( - uint32_t uniformBuffers, - uint32_t storageBuffers); - - private: - - std::vector m_descriptorSlots; - VkPushConstantRange m_pushConstRange = { }; - - uint32_t countDescriptors( - VkDescriptorType type) const; - - void replaceDescriptors( - VkDescriptorType oldType, - VkDescriptorType newType); - - }; - - - /** - * \brief Shader interface - * - * Describes shader resource bindings - * for a graphics or compute pipeline. - */ - class DxvkPipelineLayout : public RcObject { - - public: - - DxvkPipelineLayout( - const Rc& vkd, - const DxvkDescriptorSlotMapping& slotMapping, - VkPipelineBindPoint pipelineBindPoint); - - ~DxvkPipelineLayout(); - - /** - * \brief Number of resource bindings - * \returns Resource binding count - */ - uint32_t bindingCount() const { - return m_bindingSlots.size(); - } - - /** - * \brief Resource binding info - * - * \param [in] id Binding index - * \returns Resource binding info - */ - const DxvkDescriptorSlot& binding(uint32_t id) const { - return m_bindingSlots[id]; - } - - /** - * \brief Resource binding info - * \returns Resource binding info - */ - const DxvkDescriptorSlot* bindings() const { - return m_bindingSlots.data(); - } - - /** - * \brief Push constant range - * \returns Push constant range - */ - const VkPushConstantRange& pushConstRange() const { - return m_pushConstRange; - } - - /** - * \brief Descriptor set layout handle - * \returns Descriptor set layout handle - */ - VkDescriptorSetLayout descriptorSetLayout() const { - return m_descriptorSetLayout; - } - - /** - * \brief Pipeline layout handle - * \returns Pipeline layout handle - */ - VkPipelineLayout pipelineLayout() const { - return m_pipelineLayout; - } - - /** - * \brief Descriptor update template - * \returns Descriptor update template - */ - VkDescriptorUpdateTemplateKHR descriptorTemplate() const { - return m_descriptorTemplate; - } - - /** - * \brief Number of dynamic bindings - * \returns Dynamic binding count - */ - uint32_t dynamicBindingCount() const { - return m_dynamicSlots.size(); - } - - /** - * \brief Returns a dynamic binding - * - * \param [in] id Dynamic binding ID - * \returns Reference to that binding - */ - const DxvkDescriptorSlot& dynamicBinding(uint32_t id) const { - return this->binding(m_dynamicSlots[id]); - } - - /** - * \brief Checks for static buffer bindings - * - * Returns \c true if there is at least one - * descriptor of the static uniform buffer - * type. - */ - bool hasStaticBufferBindings() const { - return m_descriptorTypes.test( - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - } - - /** - * \brief Checks whether buffers or images are written to - * - * It is assumed that storage images and buffers - * will be written to if they are present. Used - * for synchronization purposes. - * \param [in] stages Shader stages to check - */ - VkShaderStageFlags getStorageDescriptorStages() const { - VkShaderStageFlags stages = 0; - - for (const auto& slot : m_bindingSlots) { - if (slot.access & VK_ACCESS_SHADER_WRITE_BIT) - stages |= slot.stages; - } - - return stages; - } - - private: - - Rc m_vkd; - - VkPushConstantRange m_pushConstRange = { }; - VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE; - VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; - VkDescriptorUpdateTemplateKHR m_descriptorTemplate = VK_NULL_HANDLE; - - std::vector m_bindingSlots; - std::vector m_dynamicSlots; - - Flags m_descriptorTypes; - - }; } \ No newline at end of file diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index af45e2f42..4056b00ab 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -64,18 +64,10 @@ namespace dxvk { const DxvkShaderCreateInfo& info, SpirvCodeBuffer&& spirv) : m_info(info), m_code(spirv) { - m_info.resourceSlots = nullptr; m_info.uniformData = nullptr; m_info.bindings = nullptr; // Copy resource binding slot infos - if (info.resourceSlotCount) { - m_slots.resize(info.resourceSlotCount); - for (uint32_t i = 0; i < info.resourceSlotCount; i++) - m_slots[i] = info.resourceSlots[i]; - m_info.resourceSlots = m_slots.data(); - } - for (uint32_t i = 0; i < info.bindingCount; i++) { DxvkBindingInfo binding = info.bindings[i]; binding.stages = info.stage; @@ -178,51 +170,6 @@ namespace dxvk { } - void DxvkShader::defineResourceSlots( - DxvkDescriptorSlotMapping& mapping) const { - for (const auto& slot : m_slots) - mapping.defineSlot(m_info.stage, slot); - - if (m_info.pushConstSize) { - mapping.definePushConstRange(m_info.stage, - m_info.pushConstOffset, - m_info.pushConstSize); - } - } - - - DxvkShaderModule DxvkShader::createShaderModule( - const Rc& vkd, - const DxvkDescriptorSlotMapping& mapping, - const DxvkShaderModuleCreateInfo& info) { - SpirvCodeBuffer spirvCode = m_code.decompress(); - uint32_t* code = spirvCode.data(); - - // Remap resource binding IDs - for (const auto& info : m_bindingOffsets) { - uint32_t mappedBinding = mapping.getBindingId(info.bindingId); - code[info.bindingOffset] = mappedBinding; - - if (info.constIdOffset) - code[info.constIdOffset] = mappedBinding; - - if (code[info.setOffset]) - code[info.setOffset] = 0; - } - - // For dual-source blending we need to re-map - // location 1, index 0 to location 0, index 1 - if (info.fsDualSrcBlend && m_o1IdxOffset && m_o1LocOffset) - std::swap(code[m_o1IdxOffset], code[m_o1LocOffset]); - - // Replace undefined input variables with zero - for (uint32_t u : bit::BitMask(info.undefinedInputs)) - eliminateInput(spirvCode, u); - - return DxvkShaderModule(vkd, this, spirvCode); - } - - DxvkShaderModule DxvkShader::createShaderModule( const Rc& vkd, const DxvkBindingLayoutObjects* layout, diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index b21928403..e0869d463 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -56,8 +56,6 @@ namespace dxvk { /// Shader stage VkShaderStageFlagBits stage; /// Descriptor info - uint32_t resourceSlotCount = 0; - const DxvkResourceSlot* resourceSlots = nullptr; uint32_t bindingCount = 0; const DxvkBindingInfo* bindings = nullptr; /// Input and output register mask @@ -127,30 +125,6 @@ namespace dxvk { return m_bindings; } - /** - * \brief Adds resource slots definitions to a mapping - * - * Used to generate the exact descriptor set layout when - * compiling a graphics or compute pipeline. Slot indices - * have to be mapped to actual binding numbers. - */ - void defineResourceSlots( - DxvkDescriptorSlotMapping& mapping) const; - - /** - * \brief Creates a shader module - * - * Maps the binding slot numbers - * \param [in] vkd Vulkan device functions - * \param [in] mapping Resource slot mapping - * \param [in] info Module create info - * \returns The shader module - */ - DxvkShaderModule createShaderModule( - const Rc& vkd, - const DxvkDescriptorSlotMapping& mapping, - const DxvkShaderModuleCreateInfo& info); - /** * \brief Creates a shader module * @@ -247,7 +221,6 @@ namespace dxvk { size_t m_o1IdxOffset = 0; size_t m_o1LocOffset = 0; - std::vector m_slots; std::vector m_uniformData; std::vector m_bindingOffsets; diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index 9ff2069d7..c2130ba60 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -323,11 +323,6 @@ namespace dxvk { { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, BindingIds::Gamma, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_READ_BIT }, }}; - const std::array fsResourceSlots = {{ - { BindingIds::Image, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_IMAGE_VIEW_TYPE_2D }, - { BindingIds::Gamma, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_IMAGE_VIEW_TYPE_1D }, - }}; - DxvkShaderCreateInfo vsInfo; vsInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; vsInfo.outputMask = 0x1; @@ -337,8 +332,6 @@ namespace dxvk { fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; fsInfo.bindingCount = fsBindings.size(); fsInfo.bindings = fsBindings.data(); - fsInfo.resourceSlotCount = fsResourceSlots.size(); - fsInfo.resourceSlots = fsResourceSlots.data(); fsInfo.pushConstSize = sizeof(PresenterArgs); fsInfo.inputMask = 0x1; fsInfo.outputMask = 0x1; diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index 167cf3c8a..e6bcc9f7c 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -168,21 +168,10 @@ namespace dxvk::hud { { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_SHADER_READ_BIT }, }}; - const std::array vsResources = {{ - { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM }, - { 1, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM }, - }}; - - const std::array fsResources = {{ - { 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_IMAGE_VIEW_TYPE_2D }, - }}; - DxvkShaderCreateInfo vsInfo; vsInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; vsInfo.bindingCount = vsBindings.size(); vsInfo.bindings = vsBindings.data(); - vsInfo.resourceSlotCount = vsResources.size(); - vsInfo.resourceSlots = vsResources.data(); vsInfo.outputMask = 0x3; vsInfo.pushConstSize = sizeof(HudTextPushConstants); result.vert = new DxvkShader(vsInfo, std::move(vsCode)); @@ -191,8 +180,6 @@ namespace dxvk::hud { fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; fsInfo.bindingCount = fsBindings.size(); fsInfo.bindings = fsBindings.data(); - fsInfo.resourceSlotCount = fsResources.size(); - fsInfo.resourceSlots = fsResources.data(); fsInfo.inputMask = 0x3; fsInfo.outputMask = 0x1; result.frag = new DxvkShader(fsInfo, std::move(fsCode)); @@ -211,10 +198,6 @@ namespace dxvk::hud { { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_SHADER_READ_BIT }, }}; - const std::array fsResources = {{ - { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_IMAGE_VIEW_TYPE_MAX_ENUM }, - }}; - DxvkShaderCreateInfo vsInfo; vsInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; vsInfo.outputMask = 0x1; @@ -225,8 +208,6 @@ namespace dxvk::hud { fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; fsInfo.bindingCount = fsBindings.size(); fsInfo.bindings = fsBindings.data(); - fsInfo.resourceSlotCount = fsResources.size(); - fsInfo.resourceSlots = fsResources.data(); fsInfo.inputMask = 0x1; fsInfo.outputMask = 0x1; fsInfo.pushConstSize = sizeof(HudGraphPushConstants); From 8d1d3d66e0ab810a3dabf69936cf69454011c923 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 25 Jun 2022 16:02:22 +0200 Subject: [PATCH 0078/1348] [dxvk] Optimize descriptor set binding further --- src/dxvk/dxvk_context.cpp | 46 ++++++++++++++++++-------------------- src/dxvk/dxvk_pipelayout.h | 17 -------------- 2 files changed, 22 insertions(+), 41 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index ff69d2e6f..428503a07 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -85,8 +85,6 @@ namespace dxvk { VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT); - m_descriptorState.clearSets(); - m_state.gp.pipeline = nullptr; m_state.cp.pipeline = nullptr; @@ -4113,10 +4111,10 @@ namespace dxvk { : m_descriptorState.getDirtyComputeSets(); dirtySetMask &= layoutSetMask; - uint32_t firstUpdated = bit::tzcnt(dirtySetMask); + uint32_t bindCount = 0; uint32_t k = 0; - std::array sets = { }; + std::array sets; m_descriptorPool->alloc(layout, dirtySetMask, sets.data()); while (dirtySetMask) { @@ -4130,7 +4128,6 @@ namespace dxvk { newBindMask.setRange(bindingIndex, bindingCount); VkDescriptorSet set = sets[setIndex]; - m_descriptorState.getSet(setIndex) = set; for (uint32_t j = 0; j < bindingCount; j++) { const auto& binding = bindings.getBinding(setIndex, j); @@ -4287,28 +4284,29 @@ namespace dxvk { &m_descriptors[k - bindingCount]); } + bindCount += 1; + + // If the next set is not dirty, update and bind all previously + // updated sets in one go in order to reduce api call overhead. + if (!(dirtySetMask & (1u << (setIndex + 1)))) { + if (!useDescriptorTemplates) { + m_cmd->updateDescriptorSets(k, m_descriptorWrites.data()); + k = 0; + } + + uint32_t firstSet = setIndex + 1 - bindCount; + + m_cmd->cmdBindDescriptorSets(BindPoint, + layout->getPipelineLayout(), + firstSet, bindCount, &sets[firstSet], + 0, nullptr); + + bindCount = 0; + } + dirtySetMask &= dirtySetMask - 1; } - if (!useDescriptorTemplates && k) - m_cmd->updateDescriptorSets(k, m_descriptorWrites.data()); - - // Bind all descriptor sets that need updating - uint32_t bindSetMask = layoutSetMask & ((~0u) << firstUpdated); - - while (bindSetMask) { - uint32_t setIndex = bit::tzcnt(bindSetMask); - uint32_t setCount = bit::tzcnt(~(bindSetMask >> setIndex)); - - VkDescriptorSet* sets = &m_descriptorState.getSet(setIndex); - - m_cmd->cmdBindDescriptorSets(BindPoint, - layout->getPipelineLayout(), - setIndex, setCount, sets, 0, nullptr); - - bindSetMask &= (~0u) << (setIndex + setCount); - } - // Update pipeline if there are unbound resources if (refBindMask != newBindMask) { refBindMask = newBindMask; diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 152af61a7..223652e90 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -523,28 +523,11 @@ namespace dxvk { return result; } - void clearSets() { - for (size_t i = 0; i < m_sets.size(); i++) - m_sets[i] = VK_NULL_HANDLE; - } - - template - VkDescriptorSet& getSet(uint32_t index) { - return m_sets[BindPoint * DxvkDescriptorSets::SetCount + index]; - } - - template - const VkDescriptorSet& getSet(uint32_t index) const { - return m_sets[BindPoint * DxvkDescriptorSets::SetCount + index]; - } - private: VkShaderStageFlags m_dirtyBuffers = 0; VkShaderStageFlags m_dirtyViews = 0; - std::array m_sets; - }; } \ No newline at end of file From 0e38b115695b93dfcdccccb50844aac964fca05e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 27 Jun 2022 15:10:23 +0200 Subject: [PATCH 0079/1348] [dxvk] Rework DxvkResource lifetime tracking Reduces the number of atomic operations required for lifetime tracking by using a single 64-bit integer for usage tracking and reference counting. --- src/dxvk/dxvk_cmdlist.h | 6 +-- src/dxvk/dxvk_lifetime.cpp | 10 +--- src/dxvk/dxvk_lifetime.h | 84 +++++++++++++++++++++++++++--- src/dxvk/dxvk_resource.h | 103 ++++++++++++++++++++++++------------- 4 files changed, 148 insertions(+), 55 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index cfb4840de..fe3c5f3aa 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -146,9 +146,9 @@ namespace dxvk { * the device can guarantee that the submission has * completed. */ - template - void trackResource(Rc rc) { - m_resources.trackResource(std::move(rc)); + template + void trackResource(const Rc& rc) { + m_resources.trackResource(rc.ptr()); } /** diff --git a/src/dxvk/dxvk_lifetime.cpp b/src/dxvk/dxvk_lifetime.cpp index e9439c55d..c38e78651 100644 --- a/src/dxvk/dxvk_lifetime.cpp +++ b/src/dxvk/dxvk_lifetime.cpp @@ -7,19 +7,11 @@ namespace dxvk { void DxvkLifetimeTracker::notify() { - for (const auto& resource : m_resources) - resource.first->release(resource.second); - - m_notified = true; + m_resources.clear(); } void DxvkLifetimeTracker::reset() { - // If this gets called without ever being submitted then - // we should at least report the resources as unused - if (!m_notified) - this->notify(); - m_resources.clear(); } diff --git a/src/dxvk/dxvk_lifetime.h b/src/dxvk/dxvk_lifetime.h index fb80d05f6..4b0211860 100644 --- a/src/dxvk/dxvk_lifetime.h +++ b/src/dxvk/dxvk_lifetime.h @@ -7,7 +7,81 @@ namespace dxvk { /** - * \brief DXVK lifetime tracker + * \brief Resource pointer + * + * Keeps a resource alive and stores access information. + */ + class DxvkLifetime { + + public: + + DxvkLifetime() + : m_resource(nullptr), m_access(DxvkAccess::None) { } + + DxvkLifetime( + DxvkResource* resource, + DxvkAccess access) + : m_resource(resource), m_access(access) { + acquire(); + } + + DxvkLifetime(DxvkLifetime&& other) + : m_resource(other.m_resource), m_access(other.m_access) { + other.m_resource = nullptr; + other.m_access = DxvkAccess::None; + } + + DxvkLifetime(const DxvkLifetime& other) + : m_resource(other.m_resource), m_access(other.m_access) { + acquire(); + } + + DxvkLifetime& operator = (DxvkLifetime&& other) { + release(); + + m_resource = other.m_resource; + m_access = other.m_access; + + other.m_resource = nullptr; + other.m_access = DxvkAccess::None; + return *this; + } + + DxvkLifetime& operator = (const DxvkLifetime& other) { + other.acquire(); + release(); + + m_resource = other.m_resource; + m_access = other.m_access; + return *this; + } + + ~DxvkLifetime() { + release(); + } + + private: + + DxvkResource* m_resource; + DxvkAccess m_access; + + void acquire() const { + if (m_resource) + m_resource->acquire(m_access); + } + + void release() const { + if (m_resource) { + if (!m_resource->release(m_access)) + delete m_resource; + } + } + + }; + + + /** + * \brief Lifetime tracker * * Maintains references to a set of resources. This is * used to guarantee that resources are not destroyed @@ -26,9 +100,8 @@ namespace dxvk { * \param [in] rc The resource to track */ template - void trackResource(Rc&& rc) { - rc->acquire(Access); - m_resources.emplace_back(std::move(rc), Access); + void trackResource(DxvkResource* rc) { + m_resources.emplace_back(rc, Access); } /** @@ -48,8 +121,7 @@ namespace dxvk { private: - std::vector, DxvkAccess>> m_resources; - bool m_notified = false; + std::vector m_resources; }; diff --git a/src/dxvk/dxvk_resource.h b/src/dxvk/dxvk_resource.h index 9a73ed818..80a935270 100644 --- a/src/dxvk/dxvk_resource.h +++ b/src/dxvk/dxvk_resource.h @@ -4,7 +4,7 @@ namespace dxvk { - enum class DxvkAccess { + enum class DxvkAccess : uint32_t { Read = 0, Write = 1, None = 2, @@ -19,12 +19,59 @@ namespace dxvk { * by the GPU. As soon as a command that uses the resource * is recorded, it will be marked as 'in use'. */ - class DxvkResource : public RcObject { + class DxvkResource { + static constexpr uint64_t RdAccessShift = 24; + static constexpr uint64_t WrAccessShift = 44; + static constexpr uint64_t RefcountMask = (1ull << RdAccessShift) - 1; + static constexpr uint64_t RdAccessMask = ((1ull << (WrAccessShift - RdAccessShift)) - 1) << RdAccessShift; + static constexpr uint64_t WrAccessMask = ((1ull << (64 - WrAccessShift)) - 1) << WrAccessShift; + + static constexpr uint64_t RefcountInc = 1ull; + static constexpr uint64_t RdAccessInc = 1ull << RdAccessShift; + static constexpr uint64_t WrAccessInc = 1ull << WrAccessShift; public: virtual ~DxvkResource(); - + + /** + * \brief Increments reference count + * \returns New reference count + */ + uint32_t incRef() { + return acquire(DxvkAccess::None); + } + + /** + * \brief Decrements reference count + * \returns New reference count + */ + uint32_t decRef() { + return release(DxvkAccess::None); + } + + /** + * \brief Acquires resource with given access + * + * Atomically increments both the reference count + * as well as the use count for the given access. + * \returns New reference count + */ + uint32_t acquire(DxvkAccess access) { + return uint32_t((m_useCount += getIncrement(access)) & RefcountMask); + } + + /** + * \brief Releases resource with given access + * + * Atomically decrements both the reference count + * as well as the use count for the given access. + * \returns New reference count + */ + uint32_t release(DxvkAccess access) { + return uint32_t((m_useCount -= getIncrement(access)) & RefcountMask); + } + /** * \brief Checks whether resource is in use * @@ -36,40 +83,12 @@ namespace dxvk { * \returns \c true if the resource is in use */ bool isInUse(DxvkAccess access = DxvkAccess::Read) const { - bool result = m_useCountW.load() != 0; + uint64_t mask = WrAccessMask; if (access == DxvkAccess::Read) - result |= m_useCountR.load() != 0; - return result; + mask |= RdAccessMask; + return bool(m_useCount.load() & mask); } - /** - * \brief Acquires resource - * - * Increments use count for the given access type. - * \param Access Resource access type - */ - void acquire(DxvkAccess access) { - if (access != DxvkAccess::None) { - (access == DxvkAccess::Read - ? m_useCountR - : m_useCountW) += 1; - } - } - - /** - * \brief Releases resource - * - * Decrements use count for the given access type. - * \param Access Resource access type - */ - void release(DxvkAccess access) { - if (access != DxvkAccess::None) { - (access == DxvkAccess::Read - ? m_useCountR - : m_useCountW) -= 1; - } - } - /** * \brief Waits for resource to become unused * @@ -85,9 +104,19 @@ namespace dxvk { private: - std::atomic m_useCountR = { 0u }; - std::atomic m_useCountW = { 0u }; + std::atomic m_useCount = { 0ull }; + + static constexpr uint64_t getIncrement(DxvkAccess access) { + uint64_t increment = RefcountInc; + + if (access != DxvkAccess::None) { + increment |= (access == DxvkAccess::Read) + ? RdAccessInc : WrAccessInc; + } + + return increment; + } }; - + } \ No newline at end of file From 129689008343ebeca8eab61e0c1bd1992e33e661 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 27 Jun 2022 21:00:22 +0200 Subject: [PATCH 0080/1348] [dxvk] Remove error logging from updateResourceBindings It's not super useful to emit log messages in the hottest code path, and for some reason GCC compiles some stringstream initialization code into those parts of the function that are unconditionally executed. --- src/dxvk/dxvk_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 428503a07..897b5176e 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4272,7 +4272,7 @@ namespace dxvk { } break; default: - Logger::err(str::format("DxvkContext: Unhandled descriptor type: ", binding.descriptorType)); + break; } k += 1; From e81094533b02b542c609a56466a68ab92a006ff9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 20:47:38 +0200 Subject: [PATCH 0081/1348] [dxvk] Fix gamma texture bind point --- src/dxvk/dxvk_swapchain_blitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index c2130ba60..d4fe47edf 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -320,7 +320,7 @@ namespace dxvk { const std::array fsBindings = {{ { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, BindingIds::Image, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_READ_BIT }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, BindingIds::Gamma, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, BindingIds::Gamma, VK_IMAGE_VIEW_TYPE_1D, 0, VK_ACCESS_SHADER_READ_BIT }, }}; DxvkShaderCreateInfo vsInfo; From 76ba03398d378351c35d58260c8eddb256424bec Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 1 Jul 2022 17:57:42 +0200 Subject: [PATCH 0082/1348] [d3d9,dxso] Fix push constant validation errors Derp. --- src/d3d9/d3d9_fixed_function.cpp | 2 +- src/dxso/dxso_compiler.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 03b073434..51ab3b3c4 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -718,7 +718,7 @@ namespace dxvk { info.inputMask = m_inputMask; info.outputMask = m_outputMask; info.pushConstOffset = m_pushConstOffset; - info.pushConstSize = m_pushConstOffset; + info.pushConstSize = m_pushConstSize; return new DxvkShader(info, m_module.compile()); } diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 6b73977a8..eee28f7b3 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -253,7 +253,7 @@ namespace dxvk { info.inputMask = m_inputMask; info.outputMask = m_outputMask; info.pushConstOffset = m_pushConstOffset; - info.pushConstSize = m_pushConstOffset; + info.pushConstSize = m_pushConstSize; return new DxvkShader(info, m_module.compile()); } From e406484b84f7ebf9b3a6ebeea187c4d127aa0856 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 2 Jul 2022 15:26:02 +0200 Subject: [PATCH 0083/1348] [d3d9] Don't use VK_RESOLVE_MODE_AVERAGE_BIT_KHR for stencil resolves Doesn't work, always write sample zero instead. --- src/d3d9/d3d9_device.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 79a3b5542..cdfdfea08 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -1066,7 +1066,7 @@ namespace dxvk { ctx->resolveDepthStencilImage( cDstImage, cSrcImage, cRegion, VK_RESOLVE_MODE_AVERAGE_BIT_KHR, - VK_RESOLVE_MODE_AVERAGE_BIT_KHR); + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR); } }); }; From 98dcd722ea219a2fc9789c190f7711cef8c0f6ec Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sat, 2 Jul 2022 16:50:12 +0200 Subject: [PATCH 0084/1348] [util] Add workaround for Garden Warfare 2 (#2700) --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index c0f2896fa..a587d3822 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -296,6 +296,11 @@ namespace dxvk { { R"(\\AWayOut(_friend)?\.exe$)", {{ { "dxgi.maxFrameLatency", "1" }, }} }, + /* Garden Warfare 2 + Won't start on amd Id without atiadlxx */ + { R"(\\GW2.Main_Win64_Retail\.exe$)", {{ + { "dxgi.customVendorId", "10de" }, + }} }, /**********************************************/ /* D3D9 GAMES */ From f95f5418529822e60e108dd8e33100c17dc6b839 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sat, 2 Jul 2022 16:51:04 +0200 Subject: [PATCH 0085/1348] [util] Limit Bionic Commando to 60fps (#2685) --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index a587d3822..09eb1996e 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -578,6 +578,11 @@ namespace dxvk { { R"(\\swtor\.exe$)", {{ { "d3d9.forceSamplerTypeSpecConstants", "True" }, }} }, + /* Bionic Commando + Physics break at high fps */ + { R"(\\bionic_commando\.exe$)", {{ + { "d3d9.maxFrameRate", "60" }, + }} }, }}; From 2e7e9eac7ad6c5b86da4b312cf1929291c5d1e8d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 14:42:07 +0200 Subject: [PATCH 0086/1348] [dxvk] Require EXT_robustness2 and the null descriptor feature --- src/d3d11/d3d11_device.cpp | 1 - src/d3d9/d3d9_device.cpp | 3 --- src/dxvk/dxvk_adapter.cpp | 2 ++ src/dxvk/dxvk_context.cpp | 8 +------- src/dxvk/dxvk_context_state.h | 1 - src/dxvk/dxvk_extensions.h | 2 +- 6 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 09f3559ab..7b982cecd 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1931,7 +1931,6 @@ namespace dxvk { enabled.extRobustness2.robustBufferAccess2 = supported.extRobustness2.robustBufferAccess2; enabled.extRobustness2.robustImageAccess2 = supported.extRobustness2.robustImageAccess2; - enabled.extRobustness2.nullDescriptor = supported.extRobustness2.nullDescriptor; enabled.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation = supported.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index cdfdfea08..29b56c9e6 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3903,9 +3903,6 @@ namespace dxvk { enabled.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor = supported.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor; enabled.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor = supported.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor; - // Null Descriptors - enabled.extRobustness2.nullDescriptor = supported.extRobustness2.nullDescriptor; - // ProcessVertices enabled.core.features.vertexPipelineStoresAndAtomics = supported.core.features.vertexPipelineStoresAndAtomics; diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 33307e9b2..4af554fca 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -329,6 +329,8 @@ namespace dxvk { enabledFeatures.ext4444Formats.formatA4B4G4R4 = m_deviceFeatures.ext4444Formats.formatA4B4G4R4; enabledFeatures.ext4444Formats.formatA4R4G4B4 = m_deviceFeatures.ext4444Formats.formatA4R4G4B4; + enabledFeatures.extRobustness2.nullDescriptor = VK_TRUE; + Logger::info(str::format("Device properties:" "\n Device name: : ", m_deviceInfo.core.properties.deviceName, "\n Driver version : ", diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 897b5176e..8211ba46f 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -19,8 +19,6 @@ namespace dxvk { m_gfxBarriers (DxvkCmdBuffer::ExecBuffer), m_queryManager(m_common->queryPool()), m_staging (device, StagingBufferSize) { - if (m_device->features().extRobustness2.nullDescriptor) - m_features.set(DxvkContextFeature::NullDescriptors); if (m_device->features().extExtendedDynamicState.extendedDynamicState) m_features.set(DxvkContextFeature::ExtendedDynamicState); @@ -4589,12 +4587,8 @@ namespace dxvk { if (m_vbTracked.set(binding)) m_cmd->trackResource(m_state.vi.vertexBuffers[binding].buffer()); - } else if (m_features.test(DxvkContextFeature::NullDescriptors)) { - buffers[i] = VK_NULL_HANDLE; - offsets[i] = 0; - lengths[i] = 0; } else { - buffers[i] = m_common->dummyResources().bufferHandle(); + buffers[i] = VK_NULL_HANDLE; offsets[i] = 0; lengths[i] = 0; } diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 992e5dd13..9eb68c11c 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -54,7 +54,6 @@ namespace dxvk { * \brief Context feature bits */ enum class DxvkContextFeature { - NullDescriptors, ExtendedDynamicState, }; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index b2f60d556..8a3912bfe 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -287,7 +287,7 @@ namespace dxvk { DxvkExt extHostQueryReset = { VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extMemoryBudget = { VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, DxvkExtMode::Passive }; DxvkExt extMemoryPriority = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt extRobustness2 = { VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extRobustness2 = { VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt extShaderDemoteToHelperInvocation = { VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderViewportIndexLayer = { VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, DxvkExtMode::Optional }; From 8f03c3a4196554769499cd835b5d67eb0724758f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 17:45:23 +0200 Subject: [PATCH 0087/1348] [dxvk] Don't check binding mask when processing barriers --- src/dxvk/dxvk_context.cpp | 128 ++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 60 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 8211ba46f..c6aae0bf2 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4806,53 +4806,57 @@ namespace dxvk { uint32_t bindingCount = layout.getBindingCount(i); for (uint32_t j = 0; j < bindingCount && !requiresBarrier; j++) { - if (m_state.cp.state.bsBindingMask.test(index + j)) { - const DxvkBindingInfo& binding = layout.getBinding(i, j); - const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; + const DxvkBindingInfo& binding = layout.getBinding(i, j); + const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; - DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); - DxvkAccessFlags srcAccess = 0; - - switch (binding.descriptorType) { - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); + DxvkAccessFlags srcAccess = 0; + + switch (binding.descriptorType) { + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + if (likely(slot.bufferSlice.defined())) { srcAccess = m_execBarriers.getBufferAccess( slot.bufferSlice.getSliceHandle()); - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + } + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + if (likely(slot.bufferView != nullptr)) { srcAccess = m_execBarriers.getBufferAccess( slot.bufferView->getSliceHandle()); - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + } + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + if (likely(slot.imageView != nullptr)) { srcAccess = m_execBarriers.getImageAccess( slot.imageView->image(), slot.imageView->imageSubresources()); - break; + } + break; - default: - /* nothing to do */; - } - - if (srcAccess == 0) - continue; - - // Skip write-after-write barriers if explicitly requested - VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT - | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; - - if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) - && (!(m_execBarriers.getSrcStages() & ~stageMask)) - && ((srcAccess | dstAccess) == DxvkAccess::Write)) - continue; - - requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); + default: + /* nothing to do */; } + + if (srcAccess == 0) + continue; + + // Skip write-after-write barriers if explicitly requested + VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT + | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; + + if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) + && (!(m_execBarriers.getSrcStages() & ~stageMask)) + && ((srcAccess | dstAccess) == DxvkAccess::Write)) + continue; + + requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); } index += bindingCount; @@ -4871,36 +4875,40 @@ namespace dxvk { uint32_t bindingCount = layout.getBindingCount(i); for (uint32_t j = 0; j < bindingCount; j++) { - if (m_state.cp.state.bsBindingMask.test(index + j)) { - const DxvkBindingInfo& binding = layout.getBinding(i, j); - const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; + const DxvkBindingInfo& binding = layout.getBinding(i, j); + const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; - VkPipelineStageFlags stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - VkAccessFlags access = binding.access; - - switch (binding.descriptorType) { - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + VkPipelineStageFlags stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + VkAccessFlags access = binding.access; + + switch (binding.descriptorType) { + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + if (likely(slot.bufferSlice.defined())) { m_execBarriers.accessBuffer( slot.bufferSlice.getSliceHandle(), stages, access, slot.bufferSlice.bufferInfo().stages, slot.bufferSlice.bufferInfo().access); - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + } + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + if (likely(slot.bufferView != nullptr)) { m_execBarriers.accessBuffer( slot.bufferView->getSliceHandle(), stages, access, slot.bufferView->bufferInfo().stages, slot.bufferView->bufferInfo().access); - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + } + break; + + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + if (likely(slot.imageView != nullptr)) { m_execBarriers.accessImage( slot.imageView->image(), slot.imageView->imageSubresources(), @@ -4909,11 +4917,11 @@ namespace dxvk { slot.imageView->imageInfo().layout, slot.imageView->imageInfo().stages, slot.imageView->imageInfo().access); - break; + } + break; - default: - /* nothing to do */; - } + default: + /* nothing to do */; } } From 186dc293841568e9e3fd192122978a5f4c1b22e5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 18:04:58 +0200 Subject: [PATCH 0088/1348] [d3d9] Remove bound spec constants from fixed-function shaders Texture stages are disabled anyway when textures are unbound, so we will never hit the unbound case. --- src/d3d9/d3d9_fixed_function.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 51ab3b3c4..62073c6a8 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -540,7 +540,6 @@ namespace dxvk { uint32_t texcoordCnt; uint32_t typeId; uint32_t varId; - uint32_t bound; } samplers[8]; struct { @@ -1657,12 +1656,6 @@ namespace dxvk { texture = m_module.opVectorTimesScalar(m_vec4Type, texture, scale); } - - uint32_t bool_t = m_module.defBoolType(); - uint32_t bvec4_t = m_module.defVectorType(bool_t, 4); - std::array boundIndices = { m_ps.samplers[i].bound, m_ps.samplers[i].bound, m_ps.samplers[i].bound, m_ps.samplers[i].bound }; - uint32_t bound4 = m_module.opCompositeConstruct(bvec4_t, boundIndices.size(), boundIndices.data()); - texture = m_module.opSelect(m_vec4Type, bound4, texture, m_module.constvec4f32(0.0f, 0.0f, 0.0f, 1.0f)); } processedTexture = true; @@ -2093,11 +2086,6 @@ namespace dxvk { const uint32_t bindingId = computeResourceSlotId(DxsoProgramType::PixelShader, DxsoBindingType::Image, i); - sampler.bound = m_module.specConstBool(true); - m_module.decorateSpecId(sampler.bound, bindingId); - m_module.setDebugName(sampler.bound, - str::format("s", i, "_bound").c_str()); - m_module.decorateDescriptorSet(sampler.varId, 0); m_module.decorateBinding(sampler.varId, bindingId); From 735e7416819ddd11d210c2b911175ab167bc6779 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 22:33:06 +0200 Subject: [PATCH 0089/1348] [d3d9] Add spec constant for null samplers And rework the way spec constants are updated. --- src/d3d9/d3d9_device.cpp | 78 ++++++++++++++-------------------- src/d3d9/d3d9_device.h | 9 ++-- src/d3d9/d3d9_spec_constants.h | 1 + 3 files changed, 37 insertions(+), 51 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 29b56c9e6..65eaa82e3 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -6182,17 +6182,6 @@ namespace dxvk { if (m_flags.test(D3D9DeviceFlag::DirtyInputLayout)) BindInputLayout(); - auto UpdateSamplerTypes = [&](uint32_t types, uint32_t projections, uint32_t fetch4) { - if (m_lastSamplerTypes != types) - UpdateSamplerSpecConsant(types); - - if (m_lastProjectionBitfield != projections) - UpdateProjectionSpecConstant(projections); - - if (m_lastFetch4 != fetch4) - UpdateFetch4SpecConstant(fetch4); - }; - if (likely(UseProgrammablePS())) { UploadConstants(); @@ -6203,9 +6192,9 @@ namespace dxvk { const auto& programInfo = GetCommonShader(m_state.pixelShader)->GetInfo(); if (programInfo.majorVersion() >= 2) - UpdateSamplerTypes(m_d3d9Options.forceSamplerTypeSpecConstants ? m_textureTypes : 0u, 0u, fetch4); + UpdatePsSamplerSpecConstants(m_d3d9Options.forceSamplerTypeSpecConstants ? m_textureTypes : 0u, 0u, fetch4); else - UpdateSamplerTypes(m_textureTypes, programInfo.minorVersion() >= 4 ? 0u : projected, fetch4); // For implicit samplers... + UpdatePsSamplerSpecConstants(m_textureTypes, programInfo.minorVersion() >= 4 ? 0u : projected, fetch4); // For implicit samplers... UpdateBoolSpecConstantPixel( m_state.psConsts.bConsts[0] & @@ -6213,14 +6202,14 @@ namespace dxvk { } else { UpdateBoolSpecConstantPixel(0); - UpdateSamplerTypes(0u, 0u, 0u); + UpdatePsSamplerSpecConstants(0u, 0u, 0u); UpdateFixedFunctionPS(); } + const uint32_t nullTextureMask = usedSamplerMask & ~usedTextureMask; const uint32_t depthTextureMask = m_depthTextures & usedTextureMask; - if (depthTextureMask != m_lastSamplerDepthMode) - UpdateSamplerDepthModeSpecConstant(depthTextureMask); + UpdateCommonSamplerSpecConstants(nullTextureMask, depthTextureMask); if (m_flags.test(D3D9DeviceFlag::DirtySharedPixelShaderData)) { m_flags.clr(D3D9DeviceFlag::DirtySharedPixelShaderData); @@ -6904,39 +6893,38 @@ namespace dxvk { } - void D3D9DeviceEx::UpdateSamplerSpecConsant(uint32_t value) { - EmitCs([cBitfield = value](DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::SamplerType, cBitfield); - }); + void D3D9DeviceEx::UpdatePsSamplerSpecConstants(uint32_t types, uint32_t projections, uint32_t fetch4) { + if (m_lastSamplerTypes != types || m_lastProjectionBitfield != projections || m_lastFetch4 != fetch4) { + m_lastSamplerTypes = types; + m_lastProjectionBitfield = projections; + m_lastFetch4 = fetch4; - m_lastSamplerTypes = value; - } - - - void D3D9DeviceEx::UpdateProjectionSpecConstant(uint32_t value) { - EmitCs([cBitfield = value](DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::ProjectionType, cBitfield); - }); - - m_lastProjectionBitfield = value; - } - - - void D3D9DeviceEx::UpdateFetch4SpecConstant(uint32_t value) { - EmitCs([cBitfield = value](DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::Fetch4, cBitfield); + EmitCs([ + cSamplerType = types, + cProjectionType = projections, + cFetch4 = fetch4 + ] (DxvkContext* ctx) { + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::SamplerType, cSamplerType); + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::ProjectionType, cProjectionType); + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::Fetch4, cFetch4); }); - - m_lastFetch4 = value; + } } - void D3D9DeviceEx::UpdateSamplerDepthModeSpecConstant(uint32_t value) { - EmitCs([cBitfield = value](DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::SamplerDepthMode, cBitfield); - }); + void D3D9DeviceEx::UpdateCommonSamplerSpecConstants(uint32_t nullMask, uint32_t depthMask) { + if (m_lastSamplerNull != nullMask || m_lastSamplerDepthMode != depthMask) { + m_lastSamplerNull = nullMask; + m_lastSamplerDepthMode = depthMask; - m_lastSamplerDepthMode = value; + EmitCs([ + cNullMask = nullMask, + cDepthMask = depthMask + ] (DxvkContext* ctx) { + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::SamplerNull, cNullMask); + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::SamplerDepthMode, cDepthMask); + }); + } } @@ -7304,10 +7292,10 @@ namespace dxvk { // We should do this... m_flags.set(D3D9DeviceFlag::DirtyInputLayout); - UpdateSamplerSpecConsant(0u); + UpdatePsSamplerSpecConstants(0u, 0u, 0u); UpdateBoolSpecConstantVertex(0u); UpdateBoolSpecConstantPixel(0u); - UpdateSamplerDepthModeSpecConstant(0u); + UpdateCommonSamplerSpecConstants(0u, 0u); return D3D_OK; } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 6817d8b24..ae48ba0a1 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1126,13 +1126,9 @@ namespace dxvk { void UpdateBoolSpecConstantPixel(uint32_t value); - void UpdateSamplerSpecConsant(uint32_t value); + void UpdatePsSamplerSpecConstants(uint32_t types, uint32_t projections, uint32_t fetch4); - void UpdateProjectionSpecConstant(uint32_t value); - - void UpdateFetch4SpecConstant(uint32_t value); - - void UpdateSamplerDepthModeSpecConstant(uint32_t value); + void UpdateCommonSamplerSpecConstants(uint32_t boundMask, uint32_t depthMask); void TrackBufferMappingBufferSequenceNumber( D3D9CommonBuffer* pResource); @@ -1228,6 +1224,7 @@ namespace dxvk { uint32_t m_lastBoolSpecConstantPixel = 0; uint32_t m_lastSamplerDepthMode = 0; uint32_t m_lastProjectionBitfield = 0; + uint32_t m_lastSamplerNull = 0; uint32_t m_lastSamplerTypes = 0; uint32_t m_lastPointMode = 0; uint32_t m_lastFetch4 = 0; diff --git a/src/d3d9/d3d9_spec_constants.h b/src/d3d9/d3d9_spec_constants.h index 7a8a33d5e..2f7cdaf39 100644 --- a/src/d3d9/d3d9_spec_constants.h +++ b/src/d3d9/d3d9_spec_constants.h @@ -19,6 +19,7 @@ namespace dxvk { Fetch4 = 9, SamplerDepthMode = 10, + SamplerNull = 11, }; } \ No newline at end of file From c7afe0dd2386f0c4acdf610fb7d2c9eaa95c3516 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 22:41:44 +0200 Subject: [PATCH 0090/1348] [dxso] Use new bit mask spec constant to determine whether textures are bound --- src/dxso/dxso_compiler.cpp | 35 +++++++++++++++++++---------------- src/dxso/dxso_compiler.h | 3 +-- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index eee28f7b3..1b2413fc5 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -271,6 +271,10 @@ namespace dxvk { this->emitDclConstantBuffer(); } + m_nullSpecConstant = m_module.specConst32(m_module.defIntType(32, 0), 0); + m_module.decorateSpecId(m_nullSpecConstant, getSpecId(D3D9SpecConstantId::SamplerNull)); + m_module.setDebugName(m_nullSpecConstant, "nullSamplers"); + m_depthSpecConstant = m_module.specConst32(m_module.defIntType(32, 0), 0); m_module.decorateSpecId(m_depthSpecConstant, getSpecId(D3D9SpecConstantId::SamplerDepthMode)); m_module.setDebugName(m_depthSpecConstant, "depthSamplers"); @@ -844,12 +848,7 @@ namespace dxvk { } } - DxsoSampler& sampler = m_samplers[idx]; - sampler.boundConst = m_module.specConstBool(true); - sampler.type = type; - m_module.decorateSpecId(sampler.boundConst, binding); - m_module.setDebugName(sampler.boundConst, - str::format("s", idx, "_bound").c_str()); + m_samplers[idx].type = type; // Store descriptor info for the shader interface DxvkBindingInfo bindingInfo = { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER }; @@ -2892,7 +2891,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( DxsoSampler sampler = m_samplers.at(samplerIdx); - auto SampleImage = [this, opcode, dst, ctx, samplerIdx, GetProjectionValue](DxsoRegisterValue texcoordVar, DxsoSamplerInfo& sampler, bool depth, DxsoSamplerType samplerType, uint32_t specConst) { + auto SampleImage = [this, opcode, dst, ctx, samplerIdx, GetProjectionValue](DxsoRegisterValue texcoordVar, DxsoSamplerInfo& sampler, bool depth, DxsoSamplerType samplerType, uint32_t isNull) { DxsoRegisterValue result; result.type.ctype = dst.type.ctype; result.type.ccount = depth ? 1 : 4; @@ -3015,12 +3014,12 @@ void DxsoCompiler::emitControlFlowGenericLoop( // If we are sampling depth we've already specc'ed this! // This path is always size 4 because it only hits on color. - if (specConst != 0) { + if (isNull != 0) { uint32_t bool_t = m_module.defBoolType(); uint32_t bvec4_t = m_module.defVectorType(bool_t, 4); - std::array indices = { specConst, specConst, specConst, specConst }; - specConst = m_module.opCompositeConstruct(bvec4_t, indices.size(), indices.data()); - result.id = m_module.opSelect(typeId, specConst, result.id, m_module.constvec4f32(0.0f, 0.0f, 0.0f, 1.0f)); + std::array indices = { isNull, isNull, isNull, isNull }; + isNull = m_module.opCompositeConstruct(bvec4_t, indices.size(), indices.data()); + result.id = m_module.opSelect(typeId, isNull, m_module.constvec4f32(0.0f, 0.0f, 0.0f, 1.0f), result.id); } // Apply operand swizzle to the operand value @@ -3055,6 +3054,13 @@ void DxsoCompiler::emitControlFlowGenericLoop( }; auto SampleType = [&](DxsoSamplerType samplerType) { + uint32_t typeId = m_module.defIntType(32, 0); + uint32_t offset = m_module.consti32(m_programInfo.type() == DxsoProgramTypes::VertexShader ? samplerIdx + 17 : samplerIdx); + uint32_t bitCnt = m_module.consti32(1); + + uint32_t isNull = m_module.opBitFieldUExtract(typeId, m_nullSpecConstant, offset, bitCnt); + isNull = m_module.opIEqual(m_module.defBoolType(), isNull, m_module.constu32(1)); + // Only do the check for depth comp. samplers // if we aren't a 3D texture if (samplerType != SamplerTypeTexture3D) { @@ -3062,9 +3068,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t depthLabel = m_module.allocateId(); uint32_t endLabel = m_module.allocateId(); - uint32_t typeId = m_module.defIntType(32, 0); - uint32_t offset = m_module.consti32(m_programInfo.type() == DxsoProgramTypes::VertexShader ? samplerIdx + 17 : samplerIdx); - uint32_t bitCnt = m_module.consti32(1); uint32_t isDepth = m_module.opBitFieldUExtract(typeId, m_depthSpecConstant, offset, bitCnt); isDepth = m_module.opIEqual(m_module.defBoolType(), isDepth, m_module.constu32(1)); @@ -3072,7 +3075,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( m_module.opBranchConditional(isDepth, depthLabel, colorLabel); m_module.opLabel(colorLabel); - SampleImage(texcoordVar, sampler.color[samplerType], false, samplerType, sampler.boundConst); + SampleImage(texcoordVar, sampler.color[samplerType], false, samplerType, isNull); m_module.opBranch(endLabel); m_module.opLabel(depthLabel); @@ -3083,7 +3086,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( m_module.opLabel(endLabel); } else - SampleImage(texcoordVar, sampler.color[samplerType], false, samplerType, sampler.boundConst); + SampleImage(texcoordVar, sampler.color[samplerType], false, samplerType, isNull); }; if (m_programInfo.majorVersion() >= 2 && !m_moduleInfo.options.forceSamplerTypeSpecConstants) { diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h index d28d613fa..1d1699d60 100644 --- a/src/dxso/dxso_compiler.h +++ b/src/dxso/dxso_compiler.h @@ -129,8 +129,6 @@ namespace dxvk { DxsoSamplerInfo color[SamplerTypeCount]; DxsoSamplerInfo depth[SamplerTypeCount]; - uint32_t boundConst; - DxsoTextureType type; }; @@ -272,6 +270,7 @@ namespace dxvk { SpirvModule m_module; uint32_t m_boolSpecConstant; + uint32_t m_nullSpecConstant; uint32_t m_depthSpecConstant; /////////////////////////////////////////////////////// From 185331df9cfc0cf987035bc617095c9b6329675f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 18:44:16 +0200 Subject: [PATCH 0091/1348] [d3d11] Don't use spec constants for video blitter Store required info in the UBO instead. --- src/d3d11/d3d11_video.cpp | 1 + src/d3d11/d3d11_video.h | 1 + src/d3d11/shaders/d3d11_video_blit_frag.frag | 5 ++--- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index f414d5473..5c1edc299 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1278,6 +1278,7 @@ namespace dxvk { uboData.coordMatrix[1][1] = 1.0f; uboData.yMin = 0.0f; uboData.yMax = 1.0f; + uboData.isPlanar = cViews[1] != nullptr; if (cIsYCbCr) ApplyYCbCrMatrix(uboData.colorMatrix, cStreamState.colorSpace.YCbCr_Matrix); diff --git a/src/d3d11/d3d11_video.h b/src/d3d11/d3d11_video.h index 85979eb8f..435b7c57e 100644 --- a/src/d3d11/d3d11_video.h +++ b/src/d3d11/d3d11_video.h @@ -585,6 +585,7 @@ namespace dxvk { float colorMatrix[3][4]; float coordMatrix[3][2]; float yMin, yMax; + VkBool32 isPlanar; }; D3D11ImmediateContext* m_ctx; diff --git a/src/d3d11/shaders/d3d11_video_blit_frag.frag b/src/d3d11/shaders/d3d11_video_blit_frag.frag index d659176cc..ff54aedaf 100644 --- a/src/d3d11/shaders/d3d11_video_blit_frag.frag +++ b/src/d3d11/shaders/d3d11_video_blit_frag.frag @@ -1,7 +1,5 @@ #version 450 -layout(constant_id = 3) const bool c_planar = true; - // Can't use matrix types here since even a two-row // matrix will be padded to 16 bytes per column for // absolutely no reason @@ -15,6 +13,7 @@ uniform ubo_t { vec2 coord_matrix_c3; float y_min; float y_max; + bool is_planar; }; layout(location = 0) in vec2 i_texcoord; @@ -37,7 +36,7 @@ void main() { // Fetch source image color vec4 color = vec4(0.0f, 0.0f, 0.0f, 1.0f); - if (c_planar) { + if (is_planar) { color.g = texture(sampler2D(s_inputY, s_sampler), coord).r; color.rb = texture(sampler2D(s_inputCbCr, s_sampler), coord).gr; color.g = clamp((color.g - y_min) / (y_max - y_min), 0.0f, 1.0f); From 3349f2d80e8011ab3f50e07dcd05ca202a061b06 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 18:37:51 +0200 Subject: [PATCH 0092/1348] [dxvk] Use custom spec constant for swap chain blitter --- src/dxvk/dxvk_swapchain_blitter.cpp | 2 ++ src/dxvk/shaders/dxvk_present_frag.frag | 2 +- src/dxvk/shaders/dxvk_present_frag_blit.frag | 2 +- src/dxvk/shaders/dxvk_present_frag_ms.frag | 2 +- src/dxvk/shaders/dxvk_present_frag_ms_amd.frag | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index d4fe47edf..f0edefcd1 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -211,8 +211,10 @@ namespace dxvk { ctx->pushConstants(0, sizeof(args), &args); ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, srcView->imageInfo().sampleCount); + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 1, m_gammaView != nullptr); ctx->draw(3, 1, 0, 0); ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0); + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 1, 0); } void DxvkSwapchainBlitter::resolve( diff --git a/src/dxvk/shaders/dxvk_present_frag.frag b/src/dxvk/shaders/dxvk_present_frag.frag index 7498a4076..fb7e0c414 100644 --- a/src/dxvk/shaders/dxvk_present_frag.frag +++ b/src/dxvk/shaders/dxvk_present_frag.frag @@ -1,6 +1,6 @@ #version 450 -layout(constant_id = 1) const bool s_gamma_bound = true; +layout(constant_id = 1226) const bool s_gamma_bound = false; layout(binding = 0) uniform sampler2D s_image; layout(binding = 1) uniform sampler1D s_gamma; diff --git a/src/dxvk/shaders/dxvk_present_frag_blit.frag b/src/dxvk/shaders/dxvk_present_frag_blit.frag index c5b660691..f85d86060 100644 --- a/src/dxvk/shaders/dxvk_present_frag_blit.frag +++ b/src/dxvk/shaders/dxvk_present_frag_blit.frag @@ -1,6 +1,6 @@ #version 450 -layout(constant_id = 1) const bool s_gamma_bound = true; +layout(constant_id = 1226) const bool s_gamma_bound = false; layout(binding = 0) uniform sampler2D s_image; layout(binding = 1) uniform sampler1D s_gamma; diff --git a/src/dxvk/shaders/dxvk_present_frag_ms.frag b/src/dxvk/shaders/dxvk_present_frag_ms.frag index 9dd751ecf..119516673 100644 --- a/src/dxvk/shaders/dxvk_present_frag_ms.frag +++ b/src/dxvk/shaders/dxvk_present_frag_ms.frag @@ -1,7 +1,7 @@ #version 450 -layout(constant_id = 1) const bool s_gamma_bound = true; layout(constant_id = 1225) const uint c_samples = 0; +layout(constant_id = 1226) const bool s_gamma_bound = false; layout(binding = 0) uniform sampler2DMS s_image; layout(binding = 1) uniform sampler1D s_gamma; diff --git a/src/dxvk/shaders/dxvk_present_frag_ms_amd.frag b/src/dxvk/shaders/dxvk_present_frag_ms_amd.frag index c234591f1..23773310f 100644 --- a/src/dxvk/shaders/dxvk_present_frag_ms_amd.frag +++ b/src/dxvk/shaders/dxvk_present_frag_ms_amd.frag @@ -2,8 +2,8 @@ #extension GL_AMD_shader_fragment_mask: enable -layout(constant_id = 1) const bool s_gamma_bound = true; layout(constant_id = 1225) const uint c_samples = 0; +layout(constant_id = 1226) const bool s_gamma_bound = false; layout(binding = 0) uniform sampler2DMS s_image; layout(binding = 1) uniform sampler1D s_gamma; From 54eaa444a2e43286e1954352b879d6ad02377e3f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 18:31:23 +0200 Subject: [PATCH 0093/1348] [dxvk] Use null descriptors for unbound resources --- src/dxvk/dxvk_context.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index c6aae0bf2..540c0f5c2 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4165,7 +4165,7 @@ namespace dxvk { m_cmd->trackResource(res.imageView->image()); } } else { - m_descriptors[k].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, true); + m_descriptors[k].image = VkDescriptorImageInfo(); newBindMask.clr(bindingIndex + j); } } break; @@ -4183,7 +4183,7 @@ namespace dxvk { m_cmd->trackResource(res.imageView->image()); } } else { - m_descriptors[k].image = m_common->dummyResources().imageViewDescriptor(binding.viewType, false); + m_descriptors[k].image = VkDescriptorImageInfo(); newBindMask.clr(bindingIndex + j); } } break; @@ -4203,7 +4203,7 @@ namespace dxvk { m_cmd->trackResource(res.imageView->image()); } } else { - m_descriptors[k].image = m_common->dummyResources().imageSamplerDescriptor(binding.viewType); + m_descriptors[k].image = m_common->dummyResources().samplerDescriptor(); newBindMask.clr(bindingIndex + j); } } break; @@ -4220,7 +4220,7 @@ namespace dxvk { m_cmd->trackResource(res.bufferView->buffer()); } } else { - m_descriptors[k].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); + m_descriptors[k].texelBuffer = VK_NULL_HANDLE; newBindMask.clr(bindingIndex + j); } } break; @@ -4237,7 +4237,7 @@ namespace dxvk { m_cmd->trackResource(res.bufferView->buffer()); } } else { - m_descriptors[k].texelBuffer = m_common->dummyResources().bufferViewDescriptor(); + m_descriptors[k].texelBuffer = VK_NULL_HANDLE; newBindMask.clr(bindingIndex + j); } } break; @@ -4251,7 +4251,7 @@ namespace dxvk { if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.bufferSlice.buffer()); } else { - m_descriptors[k].buffer = m_common->dummyResources().bufferDescriptor(); + m_descriptors[k].buffer = VkDescriptorBufferInfo(); } } break; @@ -4264,7 +4264,7 @@ namespace dxvk { if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.bufferSlice.buffer()); } else { - m_descriptors[k].buffer = m_common->dummyResources().bufferDescriptor(); + m_descriptors[k].buffer = VkDescriptorBufferInfo(); newBindMask.clr(bindingIndex + j); } } break; From 8abb5ffc77166b7de2ebff65fc21e9aed1f4074d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 18:32:47 +0200 Subject: [PATCH 0094/1348] [dxvk] Remove binding mask from pipeline state --- src/dxvk/dxvk_compute.cpp | 8 -------- src/dxvk/dxvk_context.cpp | 29 ----------------------------- src/dxvk/dxvk_graphics.cpp | 9 --------- src/dxvk/dxvk_graphics_state.h | 2 -- src/dxvk/dxvk_state_cache.cpp | 22 +++++++++------------- src/dxvk/dxvk_state_cache_types.h | 2 +- 6 files changed, 10 insertions(+), 62 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 9adb7d953..64d7ace74 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -83,14 +83,6 @@ namespace dxvk { } DxvkSpecConstants specData; - uint32_t bindingIndex = 0; - - for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { - for (uint32_t j = 0; j < m_bindings->layout().getBindingCount(i); j++) { - specData.set(bindingIndex, state.bsBindingMask.test(bindingIndex), true); - bindingIndex += 1; - } - } for (uint32_t i = 0; i < MaxNumSpecConstants; i++) specData.set(getSpecId(i), state.sc.specConstants[i], 0u); diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 540c0f5c2..ba889069d 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -3954,7 +3954,6 @@ namespace dxvk { return false; m_descriptorState.dirtyStages(VK_SHADER_STAGE_COMPUTE_BIT); - m_state.cp.state.bsBindingMask.clear(); if (m_state.cp.pipeline->getBindings()->layout().getPushConstantRange().size) m_flags.set(DxvkContextFlag::DirtyPushConstants); @@ -4024,7 +4023,6 @@ namespace dxvk { } m_descriptorState.dirtyStages(VK_SHADER_STAGE_ALL_GRAPHICS); - m_state.gp.state.bsBindingMask.clear(); if (newPipeline->getBindings()->layout().getPushConstantRange().size) m_flags.set(DxvkContextFlag::DirtyPushConstants); @@ -4095,15 +4093,7 @@ namespace dxvk { // For 64-bit applications, using templates is slower on some drivers. constexpr bool useDescriptorTemplates = env::is32BitHostPlatform(); - // This relies on the bind mask being cleared when the pipeline layout changes. - DxvkBindingMask& refBindMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS - ? m_state.gp.state.bsBindingMask - : m_state.cp.state.bsBindingMask; - - DxvkBindingMask newBindMask = refBindMask; - uint32_t layoutSetMask = layout->getSetMask(); - uint32_t dirtySetMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ? m_descriptorState.getDirtyGraphicsSets() : m_descriptorState.getDirtyComputeSets(); @@ -4120,11 +4110,7 @@ namespace dxvk { // Initialize binding mask for the current set, only // clear bits if certain resources are actually unbound. - uint32_t bindingIndex = layout->getFirstBinding(setIndex); uint32_t bindingCount = bindings.getBindingCount(setIndex); - - newBindMask.setRange(bindingIndex, bindingCount); - VkDescriptorSet set = sets[setIndex]; for (uint32_t j = 0; j < bindingCount; j++) { @@ -4166,7 +4152,6 @@ namespace dxvk { } } else { m_descriptors[k].image = VkDescriptorImageInfo(); - newBindMask.clr(bindingIndex + j); } } break; @@ -4184,7 +4169,6 @@ namespace dxvk { } } else { m_descriptors[k].image = VkDescriptorImageInfo(); - newBindMask.clr(bindingIndex + j); } } break; @@ -4204,7 +4188,6 @@ namespace dxvk { } } else { m_descriptors[k].image = m_common->dummyResources().samplerDescriptor(); - newBindMask.clr(bindingIndex + j); } } break; @@ -4221,7 +4204,6 @@ namespace dxvk { } } else { m_descriptors[k].texelBuffer = VK_NULL_HANDLE; - newBindMask.clr(bindingIndex + j); } } break; @@ -4238,7 +4220,6 @@ namespace dxvk { } } else { m_descriptors[k].texelBuffer = VK_NULL_HANDLE; - newBindMask.clr(bindingIndex + j); } } break; @@ -4265,7 +4246,6 @@ namespace dxvk { m_cmd->trackResource(res.bufferSlice.buffer()); } else { m_descriptors[k].buffer = VkDescriptorBufferInfo(); - newBindMask.clr(bindingIndex + j); } } break; @@ -4304,15 +4284,6 @@ namespace dxvk { dirtySetMask &= dirtySetMask - 1; } - - // Update pipeline if there are unbound resources - if (refBindMask != newBindMask) { - refBindMask = newBindMask; - - m_flags.set(BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS - ? DxvkContextFlag::GpDirtyPipelineState - : DxvkContextFlag::CpDirtyPipelineState); - } } diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index b369a9e16..3d7feca05 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -154,15 +154,6 @@ namespace dxvk { DxvkSpecConstants specData; specData.set(uint32_t(DxvkSpecConstantId::RasterizerSampleCount), sampleCount, VK_SAMPLE_COUNT_1_BIT); - uint32_t bindingIndex = 0; - - for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { - for (uint32_t j = 0; j < m_bindings->layout().getBindingCount(i); j++) { - specData.set(bindingIndex, state.bsBindingMask.test(bindingIndex), true); - bindingIndex += 1; - } - } - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if ((m_fsOut & (1 << i)) != 0) { specData.set(uint32_t(DxvkSpecConstantId::ColorComponentMappings) + i, diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index b10f78355..0044b4053 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -679,7 +679,6 @@ namespace dxvk { return result; } - DxvkBindingMask bsBindingMask; DxvkIaInfo ia; DxvkIlInfo il; DxvkRsInfo rs; @@ -721,7 +720,6 @@ namespace dxvk { return !bit::bcmpeq(this, &other); } - DxvkBindingMask bsBindingMask; DxvkScInfo sc; }; diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 1dfb26d0a..491315b4d 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -45,6 +45,10 @@ namespace dxvk { } bool read(DxvkBindingMask& data, uint32_t version) { + // v11 removes this field + if (version >= 11) + return true; + if (version < 9) { DxvkBindingMaskV8 v8; @@ -551,8 +555,10 @@ namespace dxvk { keys[i] = g_nullShaderKey; } + DxvkBindingMask dummyBindingMask = { }; + if (stageMask & VK_SHADER_STAGE_COMPUTE_BIT) { - if (!data.read(entry.cpState.bsBindingMask, version)) + if (!data.read(dummyBindingMask, version)) return false; } else { // Read packed render pass format @@ -582,7 +588,7 @@ namespace dxvk { return false; // Read common pipeline state - if (!data.read(entry.gpState.bsBindingMask, version) + if (!data.read(dummyBindingMask, version) || !data.read(entry.gpState.ia, version) || !data.read(entry.gpState.il, version) || !data.read(entry.gpState.rs, version) @@ -659,10 +665,7 @@ namespace dxvk { } } - if (stageMask & VK_SHADER_STAGE_COMPUTE_BIT) { - // Nothing else here to write out - data.write(entry.cpState.bsBindingMask); - } else { + if (!(stageMask & VK_SHADER_STAGE_COMPUTE_BIT)) { // Pack render pass format data.write(uint8_t(entry.format.sampleCount)); data.write(uint8_t(entry.format.depth.format)); @@ -674,7 +677,6 @@ namespace dxvk { } // Write out common pipeline state - data.write(entry.gpState.bsBindingMask); data.write(entry.gpState.ia); data.write(entry.gpState.il); data.write(entry.gpState.rs); @@ -821,9 +823,6 @@ namespace dxvk { out.hash = in.hash; if (in.shaders.cs.eq(g_nullShaderKey)) { - // Binding mask - out.gpState.bsBindingMask = in.gpState.bsBindingMask.convert(); - // Graphics state out.gpState.ia = DxvkIaInfo( in.gpState.iaPrimitiveTopology, @@ -898,9 +897,6 @@ namespace dxvk { for (uint32_t i = 0; i < 8 && i < MaxNumSpecConstants; i++) out.cpState.sc.specConstants[i] = in.cpState.scSpecConstants[i]; } else { - // Binding mask - out.cpState.bsBindingMask = in.cpState.bsBindingMask.convert(); - for (uint32_t i = 0; i < 8 && i < MaxNumSpecConstants; i++) out.gpState.sc.specConstants[i] = in.gpState.scSpecConstants[i]; } diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index 41ff4d470..c60861ca6 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -52,7 +52,7 @@ namespace dxvk { */ struct DxvkStateCacheHeader { char magic[4] = { 'D', 'X', 'V', 'K' }; - uint32_t version = 10; + uint32_t version = 11; uint32_t entrySize = 0; /* no longer meaningful */ }; From 87e2d70448d054ea769ac0b3a79f5f3d9e5032d4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 18:51:01 +0200 Subject: [PATCH 0095/1348] [dxbc] Remove bound spec constants from shader code --- src/dxbc/dxbc_compiler.cpp | 91 ++------------------------------------ src/dxbc/dxbc_compiler.h | 1 - 2 files changed, 4 insertions(+), 88 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 27c956280..84fc55b21 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -821,13 +821,6 @@ namespace dxvk { if (asSsbo) m_module.decorate(varId, spv::DecorationNonWritable); - // Declare a specialization constant which will - // store whether or not the resource is bound. - const uint32_t specConstId = m_module.specConstBool(true); - m_module.decorateSpecId(specConstId, bindingId); - m_module.setDebugName(specConstId, - str::format(name, "_bound").c_str()); - DxbcConstantBuffer buf; buf.varId = varId; buf.size = numConstants; @@ -1008,18 +1001,12 @@ namespace dxvk { // Declare a specialization constant which will // store whether or not the resource is bound. - const uint32_t specConstId = m_module.specConstBool(true); - m_module.decorateSpecId(specConstId, bindingId); - m_module.setDebugName(specConstId, - str::format(isUav ? "u" : "t", registerId, "_bound").c_str()); - if (isUav) { DxbcUav uav; uav.type = DxbcResourceType::Typed; uav.imageInfo = typeInfo; uav.varId = varId; uav.ctrId = 0; - uav.specId = specConstId; uav.sampledType = sampledType; uav.sampledTypeId = sampledTypeId; uav.imageTypeId = imageTypeId; @@ -1031,7 +1018,6 @@ namespace dxvk { res.type = DxbcResourceType::Typed; res.imageInfo = typeInfo; res.varId = varId; - res.specId = specConstId; res.sampledType = sampledType; res.sampledTypeId = sampledTypeId; res.imageTypeId = imageTypeId; @@ -1164,20 +1150,12 @@ namespace dxvk { if (ins.controls.uavFlags().test(DxbcUavFlag::GloballyCoherent)) m_module.decorate(varId, spv::DecorationCoherent); - // Declare a specialization constant which will - // store whether or not the resource is bound. - const uint32_t specConstId = m_module.specConstBool(true); - m_module.decorateSpecId(specConstId, bindingId); - m_module.setDebugName(specConstId, - str::format(isUav ? "u" : "t", registerId, "_bound").c_str()); - if (isUav) { DxbcUav uav; uav.type = resType; uav.imageInfo = typeInfo; uav.varId = varId; uav.ctrId = 0; - uav.specId = specConstId; uav.sampledType = sampledType; uav.sampledTypeId = sampledTypeId; uav.imageTypeId = resTypeId; @@ -1189,7 +1167,6 @@ namespace dxvk { res.type = resType; res.imageInfo = typeInfo; res.varId = varId; - res.specId = specConstId; res.sampledType = sampledType; res.sampledTypeId = sampledTypeId; res.imageTypeId = resTypeId; @@ -3421,18 +3398,7 @@ namespace dxvk { result = emitRegisterSwizzle(result, ins.src[1].swizzle, ins.dst[0].mask); - // If the texture is not bound, return zeroes - DxbcRegisterValue bound; - bound.type = { DxbcScalarType::Bool, 1 }; - bound.id = texture.specId; - - DxbcRegisterValue mergedResult; - mergedResult.type = result.type; - mergedResult.id = m_module.opSelect(getVectorTypeId(mergedResult.type), - emitBuildVector(bound, result.type.ccount).id, result.id, - emitBuildZeroVector(result.type).id); - - emitRegisterStore(ins.dst[0], mergedResult); + emitRegisterStore(ins.dst[0], result); } @@ -3537,14 +3503,6 @@ namespace dxvk { result = emitRegisterSwizzle(result, textureReg.swizzle, ins.dst[0].mask); - DxbcRegisterValue bound; - bound.type = { DxbcScalarType::Bool, 1 }; - bound.id = texture.specId; - - result.id = m_module.opSelect(getVectorTypeId(result.type), - emitBuildVector(bound, result.type.ccount).id, result.id, - emitBuildZeroVector(result.type).id); - emitRegisterStore(ins.dst[0], result); } @@ -3692,14 +3650,6 @@ namespace dxvk { textureReg.swizzle, ins.dst[0].mask); } - DxbcRegisterValue bound; - bound.type = { DxbcScalarType::Bool, 1 }; - bound.id = texture.specId; - - result.id = m_module.opSelect(getVectorTypeId(result.type), - emitBuildVector(bound, result.type.ccount).id, result.id, - emitBuildZeroVector(result.type).id); - emitRegisterStore(ins.dst[0], result); } @@ -5311,9 +5261,6 @@ namespace dxvk { getVectorTypeId(result.type), bufferInfo.varId, 0); - // Report a size of 0 if resource is not bound - result.id = m_module.opSelect(getVectorTypeId(result.type), - bufferInfo.specId, result.id, m_module.constu32(0)); return result; } @@ -5334,9 +5281,6 @@ namespace dxvk { result.id = m_module.opImageQuerySize( getVectorTypeId(result.type), bufferId); - // Report a size of 0 if resource is not bound - result.id = m_module.opSelect(getVectorTypeId(result.type), - bufferInfo.specId, result.id, m_module.constu32(0)); return result; } @@ -5358,9 +5302,6 @@ namespace dxvk { result.id = m_module.constu32(1); } - // Report zero LODs for unbound images - result.id = m_module.opSelect(getVectorTypeId(result.type), - info.specId, result.id, m_module.constu32(0)); return result; } @@ -5398,9 +5339,6 @@ namespace dxvk { result.id = m_module.constu32(1); } - // Report a sample count of 0 for unbound images - result.id = m_module.opSelect(getVectorTypeId(result.type), - info.specId, result.id, m_module.constu32(0)); return result; } } @@ -5426,26 +5364,6 @@ namespace dxvk { m_module.opLoad(info.typeId, info.varId)); } - // Report a size of zero for unbound textures - uint32_t zero = m_module.constu32(0); - uint32_t cond = info.specId; - - if (result.type.ccount > 1) { - std::array zeroes = {{ zero, zero, zero, zero }}; - std::array conds = {{ cond, cond, cond, cond }}; - - zero = m_module.opCompositeConstruct( - getVectorTypeId(result.type), - result.type.ccount, zeroes.data()); - - cond = m_module.opCompositeConstruct( - m_module.defVectorType(m_module.defBoolType(), result.type.ccount), - result.type.ccount, conds.data()); - } - - result.id = m_module.opSelect( - getVectorTypeId(result.type), - cond, result.id, zero); return result; } @@ -6644,13 +6562,15 @@ namespace dxvk { uint32_t DxbcCompiler::emitUavWriteTest(const DxbcBufferInfo& uav) { uint32_t typeId = m_module.defBoolType(); - uint32_t testId = uav.specId; + uint32_t testId = 0; if (m_ps.killState != 0) { uint32_t killState = m_module.opLoad(typeId, m_ps.killState); testId = m_module.opLogicalAnd(typeId, testId, m_module.opLogicalNot(typeId, killState)); + } else { + testId = m_module.constBool(true); } return testId; @@ -7649,7 +7569,6 @@ namespace dxvk { result.type = texture.type; result.typeId = texture.imageTypeId; result.varId = texture.varId; - result.specId = texture.specId; result.stride = texture.structStride; result.align = texture.structAlign; return result; @@ -7664,7 +7583,6 @@ namespace dxvk { result.type = uav.type; result.typeId = uav.imageTypeId; result.varId = uav.varId; - result.specId = uav.specId; result.stride = uav.structStride; result.align = uav.structAlign; return result; @@ -7679,7 +7597,6 @@ namespace dxvk { getScalarTypeId(DxbcScalarType::Uint32), spv::StorageClassWorkgroup); result.varId = m_gRegs.at(registerId).varId; - result.specId = 0; result.stride = m_gRegs.at(registerId).elementStride; result.align = 0; return result; diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 3adaca86a..e59e67c53 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -348,7 +348,6 @@ namespace dxvk { DxbcResourceType type; uint32_t typeId; uint32_t varId; - uint32_t specId; uint32_t stride; uint32_t align; }; From a637134c56aea39ef031d9141224548df384269b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 19:26:26 +0200 Subject: [PATCH 0096/1348] [d3d11,dxbc] Use push constant instead of spec constant for rasterizer sample count --- src/d3d11/d3d11_context.cpp | 70 +++++++++++++++++++++++++-------- src/d3d11/d3d11_context.h | 2 + src/d3d11/d3d11_context_state.h | 2 + src/d3d11/d3d11_view_dsv.h | 4 ++ src/d3d11/d3d11_view_rtv.h | 4 ++ src/dxbc/dxbc_compiler.cpp | 38 +++++++++++++----- src/dxbc/dxbc_compiler.h | 4 +- src/dxbc/dxbc_util.h | 8 ++++ 8 files changed, 105 insertions(+), 27 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 78e290d7f..1f9cafe46 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -9,7 +9,7 @@ #include "../dxbc/dxbc_util.h" namespace dxvk { - + D3D11DeviceContext::D3D11DeviceContext( D3D11Device* pParent, const Rc& Device, @@ -230,6 +230,7 @@ namespace dxvk { for (uint32_t i = 0; i < 4; i++) m_state.om.blendFactor[i] = 1.0f; + m_state.om.sampleCount = 0; m_state.om.sampleMask = D3D11_DEFAULT_SAMPLE_MASK; m_state.om.stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE; @@ -2606,24 +2607,25 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::RSSetState(ID3D11RasterizerState* pRasterizerState) { D3D10DeviceLock lock = LockContext(); - auto rasterizerState = static_cast(pRasterizerState); + auto currRasterizerState = m_state.rs.state; + auto nextRasterizerState = static_cast(pRasterizerState); - bool currScissorEnable = m_state.rs.state != nullptr - ? m_state.rs.state->Desc()->ScissorEnable - : false; - - bool nextScissorEnable = rasterizerState != nullptr - ? rasterizerState->Desc()->ScissorEnable - : false; - - if (m_state.rs.state != rasterizerState) { - m_state.rs.state = rasterizerState; - - // In D3D11, the rasterizer state defines whether the - // scissor test is enabled, so we have to update the - // scissor rectangles as well. + if (m_state.rs.state != nextRasterizerState) { + m_state.rs.state = nextRasterizerState; ApplyRasterizerState(); + // If necessary, update the rasterizer sample count push constant + uint32_t currSampleCount = currRasterizerState != nullptr ? currRasterizerState->Desc()->ForcedSampleCount : 0; + uint32_t nextSampleCount = nextRasterizerState != nullptr ? nextRasterizerState->Desc()->ForcedSampleCount : 0; + + if (currSampleCount != nextSampleCount) + ApplyRasterizerSampleCount(); + + // In D3D11, the rasterizer state defines whether the scissor test is + // enabled, so if that changes, we need to update scissor rects as well. + bool currScissorEnable = currRasterizerState != nullptr ? currRasterizerState->Desc()->ScissorEnable : false; + bool nextScissorEnable = nextRasterizerState != nullptr ? nextRasterizerState->Desc()->ScissorEnable : false; + if (currScissorEnable != nextScissorEnable) ApplyViewportState(); } @@ -3025,6 +3027,25 @@ namespace dxvk { } + void D3D11DeviceContext::ApplyRasterizerSampleCount() { + DxbcPushConstants pc; + pc.rasterizerSampleCount = m_state.om.sampleCount; + + if (unlikely(!m_state.om.sampleCount)) { + pc.rasterizerSampleCount = m_state.rs.state->Desc()->ForcedSampleCount; + + if (!m_state.om.sampleCount) + pc.rasterizerSampleCount = 1; + } + + EmitCs([ + cPushConstants = pc + ] (DxvkContext* ctx) { + ctx->pushConstants(0, sizeof(cPushConstants), &cPushConstants); + }); + } + + void D3D11DeviceContext::ApplyViewportState() { std::array viewports; std::array scissors; @@ -3143,7 +3164,8 @@ namespace dxvk { void D3D11DeviceContext::BindFramebuffer() { DxvkRenderTargets attachments; - + uint32_t sampleCount = 0; + // D3D11 doesn't have the concept of a framebuffer object, // so we'll just create a new one every time the render // target bindings are updated. Set up the attachments. @@ -3152,6 +3174,7 @@ namespace dxvk { attachments.color[i] = { m_state.om.renderTargetViews[i]->GetImageView(), m_state.om.renderTargetViews[i]->GetRenderLayout() }; + sampleCount = m_state.om.renderTargetViews[i]->GetSampleCount(); } } @@ -3159,6 +3182,7 @@ namespace dxvk { attachments.depth = { m_state.om.depthStencilView->GetImageView(), m_state.om.depthStencilView->GetRenderLayout() }; + sampleCount = m_state.om.depthStencilView->GetSampleCount(); } // Create and bind the framebuffer object to the context @@ -3167,6 +3191,12 @@ namespace dxvk { ] (DxvkContext* ctx) { ctx->bindRenderTargets(cAttachments); }); + + // If necessary, update push constant for the sample count + if (m_state.om.sampleCount != sampleCount) { + m_state.om.sampleCount = sampleCount; + ApplyRasterizerSampleCount(); + } } @@ -4149,6 +4179,11 @@ namespace dxvk { } } } + + // Initialize push constants + DxbcPushConstants pc; + pc.rasterizerSampleCount = 1; + ctx->pushConstants(0, sizeof(pc), &pc); }); } @@ -4170,6 +4205,7 @@ namespace dxvk { ApplyDepthStencilState(); ApplyStencilRef(); ApplyRasterizerState(); + ApplyRasterizerSampleCount(); ApplyViewportState(); BindDrawBuffers( diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 18f277f5c..1f1d19302 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -723,6 +723,8 @@ namespace dxvk { void ApplyRasterizerState(); + void ApplyRasterizerSampleCount(); + void ApplyViewportState(); template diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index eca2a3c9d..d146a738d 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -129,6 +129,8 @@ namespace dxvk { D3D11DepthStencilState* dsState = nullptr; FLOAT blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + + UINT sampleCount = 0u; UINT sampleMask = 0xFFFFFFFFu; UINT stencilRef = 0u; diff --git a/src/d3d11/d3d11_view_dsv.h b/src/d3d11/d3d11_view_dsv.h index 41b6fcb1a..a07d29b24 100644 --- a/src/d3d11/d3d11_view_dsv.h +++ b/src/d3d11/d3d11_view_dsv.h @@ -66,6 +66,10 @@ namespace dxvk { } } + UINT GetSampleCount() const { + return UINT(m_view->imageInfo().sampleCount); + } + VkImageAspectFlags GetWritableAspectMask() const { VkImageAspectFlags mask = m_view->formatInfo()->aspectMask; if (m_desc.Flags & D3D11_DSV_READ_ONLY_DEPTH) mask &= ~VK_IMAGE_ASPECT_DEPTH_BIT; diff --git a/src/d3d11/d3d11_view_rtv.h b/src/d3d11/d3d11_view_rtv.h index 080146eca..0be9ff7ae 100644 --- a/src/d3d11/d3d11_view_rtv.h +++ b/src/d3d11/d3d11_view_rtv.h @@ -57,6 +57,10 @@ namespace dxvk { : VK_IMAGE_LAYOUT_GENERAL; } + UINT GetSampleCount() const { + return UINT(m_view->imageInfo().sampleCount); + } + D3D10RenderTargetView* GetD3D10Iface() { return &m_d3d10; } diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 84fc55b21..b86919a95 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -258,6 +258,9 @@ namespace dxvk { info.uniformSize = m_immConstData.size(); info.uniformData = m_immConstData.data(); + if (m_programInfo.type() == DxbcProgramType::PixelShader && m_ps.pushConstantId) + info.pushConstSize = sizeof(DxbcPushConstants); + if (m_moduleInfo.xfb) { info.xfbRasterizedStream = m_moduleInfo.xfb->rasterizedStream; @@ -5309,19 +5312,20 @@ namespace dxvk { DxbcRegisterValue DxbcCompiler::emitQueryTextureSamples( const DxbcRegister& resource) { if (resource.type == DxbcOperandType::Rasterizer) { - // SPIR-V has no gl_NumSamples equivalent, so we have - // to work around it using a specialization constant - if (!m_ps.specRsSampleCount) { - m_ps.specRsSampleCount = emitNewSpecConstant( - DxvkSpecConstantId::RasterizerSampleCount, - DxbcScalarType::Uint32, 1, - "RasterizerSampleCount"); - } + // SPIR-V has no gl_NumSamples equivalent, so we + // have to work around it using a push constant + if (!m_ps.pushConstantId) + m_ps.pushConstantId = emitPushConstants(); + + uint32_t uintTypeId = m_module.defIntType(32, 0); + uint32_t ptrTypeId = m_module.defPointerType(uintTypeId, spv::StorageClassPushConstant); + uint32_t index = m_module.constu32(0); DxbcRegisterValue result; result.type.ctype = DxbcScalarType::Uint32; result.type.ccount = 1; - result.id = m_ps.specRsSampleCount; + result.id = m_module.opLoad(uintTypeId, + m_module.opAccessChain(ptrTypeId, m_ps.pushConstantId, 1, &index)); return result; } else { DxbcBufferInfo info = getBufferInfo(resource); @@ -7532,6 +7536,22 @@ namespace dxvk { } + uint32_t DxbcCompiler::emitPushConstants() { + uint32_t uintTypeId = m_module.defIntType(32, 0); + uint32_t structTypeId = m_module.defStructTypeUnique(1, &uintTypeId); + + m_module.setDebugName(structTypeId, "pc_t"); + m_module.setDebugMemberName(structTypeId, 0, "RasterizerSampleCount"); + m_module.memberDecorateOffset(structTypeId, 0, 0); + + uint32_t ptrTypeId = m_module.defPointerType(structTypeId, spv::StorageClassPushConstant); + uint32_t varId = m_module.newVar(ptrTypeId, spv::StorageClassPushConstant); + + m_module.setDebugName(varId, "pc"); + return varId; + } + + void DxbcCompiler::enableShaderViewportIndexLayer() { if (!m_extensions.shaderViewportIndexLayer) { m_extensions.shaderViewportIndexLayer = true; diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index e59e67c53..b38412cf0 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -184,7 +184,7 @@ namespace dxvk { uint32_t builtinLaneId = 0; uint32_t killState = 0; - uint32_t specRsSampleCount = 0; + uint32_t pushConstantId = 0; }; @@ -1198,6 +1198,8 @@ namespace dxvk { uint32_t emitBuiltinTessLevelInner( spv::StorageClass storageClass); + uint32_t emitPushConstants(); + //////////////////////////////// // Extension enablement methods void enableShaderViewportIndexLayer(); diff --git a/src/dxbc/dxbc_util.h b/src/dxbc/dxbc_util.h index 4bc49620d..04bec752a 100644 --- a/src/dxbc/dxbc_util.h +++ b/src/dxbc/dxbc_util.h @@ -5,6 +5,14 @@ namespace dxvk { + /** + * \brief Push constant struct + */ + struct DxbcPushConstants { + uint32_t rasterizerSampleCount; + }; + + /** * \brief Binding numbers and properties */ From 2e73e4679930bcbef54484f750a19cd193c9b191 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 22:54:12 +0200 Subject: [PATCH 0097/1348] [dxvk] Do not remap spec constant IDs when compiling shaders No longer needed since we don't emit per-binding constants anymore. --- src/dxvk/dxvk_shader.cpp | 14 -------------- src/dxvk/dxvk_shader.h | 6 ------ 2 files changed, 20 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 4056b00ab..f8c5fdce9 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -93,7 +93,6 @@ namespace dxvk { // Run an analysis pass over the SPIR-V code to gather some // info that we may need during pipeline compilation. std::vector bindingOffsets; - std::vector constIdOffsets; std::vector varIds; SpirvCodeBuffer code = std::move(spirv); @@ -115,9 +114,6 @@ namespace dxvk { bindingOffsets[varId].setOffset = ins.offset() + 3; } - if (ins.arg(2) == spv::DecorationSpecId) - constIdOffsets.push_back({ ins.arg(3), ins.offset() + 3 }); - if (ins.arg(2) == spv::DecorationLocation && ins.arg(3) == 1) { m_o1LocOffset = ins.offset() + 3; o1VarId = ins.arg(1); @@ -152,13 +148,6 @@ namespace dxvk { for (auto varId : varIds) { BindingOffsets info = bindingOffsets[varId]; - for (const auto& specOfs : constIdOffsets) { - if (info.bindingId == specOfs.bindingId) { - info.constIdOffset = specOfs.constIdOffset; - break; - } - } - if (info.bindingOffset) m_bindingOffsets.push_back(info); } @@ -184,9 +173,6 @@ namespace dxvk { if (mappedBinding) { code[info.bindingOffset] = mappedBinding->binding; - if (info.constIdOffset) - code[info.constIdOffset] = mappedBinding->constId; - if (info.setOffset) code[info.setOffset] = mappedBinding->set; } diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index e0869d463..0267e6467 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -199,14 +199,8 @@ namespace dxvk { private: - struct ConstOffsets { - uint32_t bindingId; - uint32_t constIdOffset; - }; - struct BindingOffsets { uint32_t bindingId; - uint32_t constIdOffset; uint32_t bindingOffset; uint32_t setOffset; }; From 7c4d60286396e997a49e20cea9dc77ed464159ad Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 30 Jun 2022 20:47:50 +0200 Subject: [PATCH 0098/1348] [dxvk] Change spec constant IDs We no longer support per-resource spec constants, so there is no good reason not to use a 1:1 mapping for user-defined constants. --- src/d3d9/shaders/d3d9_convert_yuy2_uyvy.comp | 2 +- src/dxvk/dxvk_graphics.cpp | 1 - src/dxvk/dxvk_shader.h | 8 ++------ src/dxvk/hud/shaders/hud_graph_frag.frag | 2 +- src/dxvk/hud/shaders/hud_text_frag.frag | 2 +- src/dxvk/shaders/dxvk_present_frag.frag | 2 +- src/dxvk/shaders/dxvk_present_frag_blit.frag | 2 +- src/dxvk/shaders/dxvk_present_frag_ms.frag | 4 ++-- src/dxvk/shaders/dxvk_present_frag_ms_amd.frag | 4 ++-- 9 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/d3d9/shaders/d3d9_convert_yuy2_uyvy.comp b/src/d3d9/shaders/d3d9_convert_yuy2_uyvy.comp index 8f38c9bac..bbcf8e283 100644 --- a/src/d3d9/shaders/d3d9_convert_yuy2_uyvy.comp +++ b/src/d3d9/shaders/d3d9_convert_yuy2_uyvy.comp @@ -3,7 +3,7 @@ #include "d3d9_convert_common.h" -layout(constant_id = 1225) const bool s_is_uyvy = false; +layout(constant_id = 0) const bool s_is_uyvy = false; layout( local_size_x = 8, diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 3d7feca05..b611059a4 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -152,7 +152,6 @@ namespace dxvk { // Set up some specialization constants DxvkSpecConstants specData; - specData.set(uint32_t(DxvkSpecConstantId::RasterizerSampleCount), sampleCount, VK_SAMPLE_COUNT_1_BIT); for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if ((m_fsOut & (1 << i)) != 0) { diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 0267e6467..ba798aea5 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -24,14 +24,10 @@ namespace dxvk { * implementation at pipeline compilation time. */ enum class DxvkSpecConstantId : uint32_t { + FirstPipelineConstant = 0, /// Special constant ranges that do not count /// towards the spec constant min/max values - ColorComponentMappings = MaxNumResourceSlots, - - // Specialization constants for pipeline state - SpecConstantRangeStart = ColorComponentMappings + MaxNumRenderTargets, - RasterizerSampleCount = SpecConstantRangeStart + 0, - FirstPipelineConstant + ColorComponentMappings = DxvkLimits::MaxNumSpecConstants, }; /** diff --git a/src/dxvk/hud/shaders/hud_graph_frag.frag b/src/dxvk/hud/shaders/hud_graph_frag.frag index b45aa43ef..224eb061c 100644 --- a/src/dxvk/hud/shaders/hud_graph_frag.frag +++ b/src/dxvk/hud/shaders/hud_graph_frag.frag @@ -1,6 +1,6 @@ #version 450 -layout(constant_id = 1225) const bool srgbSwapchain = false; +layout(constant_id = 0) const bool srgbSwapchain = false; layout(location = 0) in vec2 v_coord; layout(location = 0) out vec4 o_color; diff --git a/src/dxvk/hud/shaders/hud_text_frag.frag b/src/dxvk/hud/shaders/hud_text_frag.frag index 56a2823ce..86d3a9093 100644 --- a/src/dxvk/hud/shaders/hud_text_frag.frag +++ b/src/dxvk/hud/shaders/hud_text_frag.frag @@ -1,6 +1,6 @@ #version 450 -layout(constant_id = 1225) const bool srgbSwapchain = false; +layout(constant_id = 0) const bool srgbSwapchain = false; layout(binding = 2) uniform sampler2D s_font; diff --git a/src/dxvk/shaders/dxvk_present_frag.frag b/src/dxvk/shaders/dxvk_present_frag.frag index fb7e0c414..3501a4f27 100644 --- a/src/dxvk/shaders/dxvk_present_frag.frag +++ b/src/dxvk/shaders/dxvk_present_frag.frag @@ -1,6 +1,6 @@ #version 450 -layout(constant_id = 1226) const bool s_gamma_bound = false; +layout(constant_id = 1) const bool s_gamma_bound = false; layout(binding = 0) uniform sampler2D s_image; layout(binding = 1) uniform sampler1D s_gamma; diff --git a/src/dxvk/shaders/dxvk_present_frag_blit.frag b/src/dxvk/shaders/dxvk_present_frag_blit.frag index f85d86060..e14ae311a 100644 --- a/src/dxvk/shaders/dxvk_present_frag_blit.frag +++ b/src/dxvk/shaders/dxvk_present_frag_blit.frag @@ -1,6 +1,6 @@ #version 450 -layout(constant_id = 1226) const bool s_gamma_bound = false; +layout(constant_id = 1) const bool s_gamma_bound = false; layout(binding = 0) uniform sampler2D s_image; layout(binding = 1) uniform sampler1D s_gamma; diff --git a/src/dxvk/shaders/dxvk_present_frag_ms.frag b/src/dxvk/shaders/dxvk_present_frag_ms.frag index 119516673..18771d38b 100644 --- a/src/dxvk/shaders/dxvk_present_frag_ms.frag +++ b/src/dxvk/shaders/dxvk_present_frag_ms.frag @@ -1,7 +1,7 @@ #version 450 -layout(constant_id = 1225) const uint c_samples = 0; -layout(constant_id = 1226) const bool s_gamma_bound = false; +layout(constant_id = 0) const uint c_samples = 0; +layout(constant_id = 1) const bool s_gamma_bound = false; layout(binding = 0) uniform sampler2DMS s_image; layout(binding = 1) uniform sampler1D s_gamma; diff --git a/src/dxvk/shaders/dxvk_present_frag_ms_amd.frag b/src/dxvk/shaders/dxvk_present_frag_ms_amd.frag index 23773310f..df391fb11 100644 --- a/src/dxvk/shaders/dxvk_present_frag_ms_amd.frag +++ b/src/dxvk/shaders/dxvk_present_frag_ms_amd.frag @@ -2,8 +2,8 @@ #extension GL_AMD_shader_fragment_mask: enable -layout(constant_id = 1225) const uint c_samples = 0; -layout(constant_id = 1226) const bool s_gamma_bound = false; +layout(constant_id = 0) const uint c_samples = 0; +layout(constant_id = 1) const bool s_gamma_bound = false; layout(binding = 0) uniform sampler2DMS s_image; layout(binding = 1) uniform sampler1D s_gamma; From 8d413e2d09a96afddb79d769f4e22c362893787b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 3 Jul 2022 15:37:52 +0200 Subject: [PATCH 0099/1348] [dxvk] Fix opening state cache files for writing operator bool() only checks if errors have occured in previous writes, so we'd be missing out on the first cache entry written. --- src/dxvk/dxvk_state_cache.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 491315b4d..ab08a1427 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -958,8 +958,8 @@ namespace dxvk { m_writerQueue.pop(); } - if (!file) { - file = std::ofstream(getCacheFileName().c_str(), + if (!file.is_open()) { + file.open(getCacheFileName().c_str(), std::ios_base::binary | std::ios_base::app); } From 593c6e3fe832a84610d0254c6a14947ceca6f1c0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 13:02:54 +0200 Subject: [PATCH 0100/1348] [dxvk] Remove spec constant ID mapping from pipeline layouts No longer needed. --- src/dxvk/dxvk_pipelayout.cpp | 4 ---- src/dxvk/dxvk_pipelayout.h | 13 ------------- 2 files changed, 17 deletions(-) diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index 65ef26c0b..aee75d3bb 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -278,12 +278,9 @@ namespace dxvk { : m_device(device), m_layout(layout) { auto vk = m_device->vkd(); - uint32_t constId = 0; - std::array setLayouts; for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { - m_bindingOffsets[i] = constId; m_bindingObjects[i] = setObjects[i]; setLayouts[i] = setObjects[i]->getSetLayout(); @@ -295,7 +292,6 @@ namespace dxvk { DxvkBindingMapping mapping; mapping.set = i; mapping.binding = j; - mapping.constId = constId++; m_mapping.insert({ binding.resourceBinding, mapping }); } diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 223652e90..c16dce029 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -354,7 +354,6 @@ namespace dxvk { struct DxvkBindingMapping { uint32_t set; uint32_t binding; - uint32_t constId; }; /** @@ -392,17 +391,6 @@ namespace dxvk { return m_setMask; } - /** - * \brief Queries first binding number for a given set - * - * This is relevant for generating binding masks. - * \param [in] set Descriptor set index - * \returns First binding in the given set - */ - uint32_t getFirstBinding(uint32_t set) const { - return m_bindingOffsets[set]; - } - /** * \brief Retrieves descriptor set layout for a given set * @@ -463,7 +451,6 @@ namespace dxvk { uint32_t m_setMask = 0; std::array m_bindingObjects = { }; - std::array m_bindingOffsets = { }; std::unordered_map m_mapping; From 03ac5775779cfc8e39d392f0cd3de9bd64305eb9 Mon Sep 17 00:00:00 2001 From: WinterSnowfall Date: Sat, 2 Jul 2022 18:20:19 +0300 Subject: [PATCH 0101/1348] [util] Add workaround to fix missing sun & light shafts in Beyond Good And Evil --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 09eb1996e..7f4e7ae4a 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -570,6 +570,11 @@ namespace dxvk { { R"(\\eoa\.exe$)", {{ { "d3d9.customVendorId", "10de" }, }} }, + /* Beyond Good And Evil * + * Fixes missing sun and light shafts */ + { R"(\\BGE\.exe$)", {{ + { "d3d9.allowDoNotWait", "False" }, + }} }, /* Supreme Commander & Forged Alliance Forever */ { R"(\\(SupremeCommander|ForgedAlliance)\.exe$)", {{ { "d3d9.floatEmulation", "Strict" }, From e9ac543627467a1c65a8d0360c0f364580ed1b00 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Thu, 9 Jun 2022 15:04:42 +0200 Subject: [PATCH 0102/1348] [include] Update Vulkan headers to 1.3.217. --- include/vulkan/vulkan_core.h | 2836 ++++++++++++++++++++++++---------- 1 file changed, 2008 insertions(+), 828 deletions(-) diff --git a/include/vulkan/vulkan_core.h b/include/vulkan/vulkan_core.h index a2f4e7717..07b4acfe2 100644 --- a/include/vulkan/vulkan_core.h +++ b/include/vulkan/vulkan_core.h @@ -2,7 +2,7 @@ #define VULKAN_CORE_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -72,10 +72,10 @@ extern "C" { #define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 // Version of this file -#define VK_HEADER_VERSION 197 +#define VK_HEADER_VERSION 217 // Complete version of this file -#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 2, VK_HEADER_VERSION) +#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) // DEPRECATED: This define is deprecated. VK_API_VERSION_MAJOR should be used instead. #define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) @@ -120,7 +120,6 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) -#define VK_UUID_SIZE 16U #define VK_ATTACHMENT_UNUSED (~0U) #define VK_FALSE 0U #define VK_LOD_CLAMP_NONE 1000.0F @@ -131,10 +130,11 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) #define VK_TRUE 1U #define VK_WHOLE_SIZE (~0ULL) #define VK_MAX_MEMORY_TYPES 32U -#define VK_MAX_MEMORY_HEAPS 16U #define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256U +#define VK_UUID_SIZE 16U #define VK_MAX_EXTENSION_NAME_SIZE 256U #define VK_MAX_DESCRIPTION_SIZE 256U +#define VK_MAX_MEMORY_HEAPS 16U typedef enum VkResult { VK_SUCCESS = 0, @@ -160,6 +160,7 @@ typedef enum VkResult { VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, VK_ERROR_FRAGMENTATION = -1000161000, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, + VK_PIPELINE_COMPILE_REQUIRED = 1000297000, VK_ERROR_SURFACE_LOST_KHR = -1000000000, VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, VK_SUBOPTIMAL_KHR = 1000001003, @@ -168,19 +169,21 @@ typedef enum VkResult { VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, VK_ERROR_INVALID_SHADER_NV = -1000012000, VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, - VK_ERROR_NOT_PERMITTED_EXT = -1000174001, + VK_ERROR_NOT_PERMITTED_KHR = -1000174001, VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, VK_THREAD_IDLE_KHR = 1000268000, VK_THREAD_DONE_KHR = 1000268001, VK_OPERATION_DEFERRED_KHR = 1000268002, VK_OPERATION_NOT_DEFERRED_KHR = 1000268003, - VK_PIPELINE_COMPILE_REQUIRED_EXT = 1000297000, + VK_ERROR_COMPRESSION_EXHAUSTED_EXT = -1000338000, VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY, VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE, VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION, + VK_ERROR_NOT_PERMITTED_EXT = VK_ERROR_NOT_PERMITTED_KHR, VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED_EXT, + VK_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, + VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, VK_RESULT_MAX_ENUM = 0x7FFFFFFF } VkResult; @@ -349,6 +352,58 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES = 53, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES = 54, + VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES = 1000245000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES = 1000295000, + VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO = 1000295001, + VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO = 1000295002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000, + VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 = 1000314000, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 = 1000314001, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 = 1000314002, + VK_STRUCTURE_TYPE_DEPENDENCY_INFO = 1000314003, + VK_STRUCTURE_TYPE_SUBMIT_INFO_2 = 1000314004, + VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO = 1000314005, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO = 1000314006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES = 1000314007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000, + VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 = 1000337000, + VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2 = 1000337001, + VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 = 1000337002, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2 = 1000337003, + VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 = 1000337004, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2 = 1000337005, + VK_STRUCTURE_TYPE_BUFFER_COPY_2 = 1000337006, + VK_STRUCTURE_TYPE_IMAGE_COPY_2 = 1000337007, + VK_STRUCTURE_TYPE_IMAGE_BLIT_2 = 1000337008, + VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 = 1000337009, + VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2 = 1000337010, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES = 1000225000, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO = 1000225001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES = 1000225002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES = 1000138000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES = 1000138001, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK = 1000138002, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO = 1000138003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000, + VK_STRUCTURE_TYPE_RENDERING_INFO = 1000044000, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO = 1000044001, + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO = 1000044002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES = 1000044003, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO = 1000044004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 = 1000360000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001, + VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, @@ -418,8 +473,14 @@ typedef enum VkStructureType { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR = 1000023015, #endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_2_KHR = 1000023016, +#endif #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR = 1000024000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR = 1000024001, #endif VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, @@ -436,89 +497,90 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_CAPABILITIES_EXT = 1000038000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_CREATE_INFO_EXT = 1000038001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038001, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038002, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038002, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038003, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038003, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038004, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038004, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038005, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038005, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038006, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038006, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038007, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_EXT = 1000038007, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_EXT = 1000038008, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_INFO_EXT = 1000038008, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_LAYER_INFO_EXT = 1000038009, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_REFERENCE_LISTS_EXT = 1000038010, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_CAPABILITIES_EXT = 1000039000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_CREATE_INFO_EXT = 1000039001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000039001, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000039002, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000039002, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000039003, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_VCL_FRAME_INFO_EXT = 1000039003, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_VCL_FRAME_INFO_EXT = 1000039004, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_EXT = 1000039004, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_EXT = 1000039005, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_NALU_SLICE_SEGMENT_EXT = 1000039005, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_NALU_SLICE_EXT = 1000039006, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_EMIT_PICTURE_PARAMETERS_EXT = 1000039006, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_EMIT_PICTURE_PARAMETERS_EXT = 1000039007, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_EXT = 1000039007, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_EXT = 1000039008, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_REFERENCE_LISTS_EXT = 1000039008, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_REFERENCE_LISTS_EXT = 1000039009, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_EXT = 1000039009, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_EXT = 1000039010, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_EXT = 1000040000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_CREATE_INFO_EXT = 1000040001, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040001, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040002, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_MVC_EXT = 1000040002, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_MVC_EXT = 1000040003, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_EXT = 1000040003, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_EXT = 1000040004, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040004, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040005, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040005, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040006, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040007, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040006, #endif VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, - VK_STRUCTURE_TYPE_RENDERING_INFO_KHR = 1000044000, - VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR = 1000044001, - VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR = 1000044002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR = 1000044003, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR = 1000044004, VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000044006, VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT = 1000044007, VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD = 1000044008, @@ -532,7 +594,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000, VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = 1000066000, VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, @@ -605,10 +666,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005, VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID = 1000129006, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002, - VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = 1000138003, VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000, VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, @@ -675,7 +732,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, - VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000, VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, @@ -687,33 +743,31 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_EXT = 1000187000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_CREATE_INFO_EXT = 1000187001, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187001, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187002, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187002, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187003, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_EXT = 1000187003, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_EXT = 1000187004, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187004, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187005, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187006, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187005, #endif + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR = 1000174000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR = 1000388000, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR = 1000388001, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000, - VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000192000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000, VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002, @@ -730,14 +784,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000, VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001, VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = 1000215000, VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = 1000225000, - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = 1000225001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = 1000225002, VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000, VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002, @@ -753,7 +803,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000, VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = 1000245000, VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, @@ -784,7 +833,6 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, @@ -795,10 +843,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = 1000280000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = 1000280001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000, @@ -812,30 +857,41 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, VK_STRUCTURE_TYPE_PRESENT_ID_KHR = 1000294000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = 1000295000, - VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = 1000295001, - VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = 1000295002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = 1000297000, #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR = 1000299000, #endif #ifdef VK_ENABLE_BETA_EXTENSIONS VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_INFO_KHR = 1000299001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR = 1000299002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR = 1000299003, #endif VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, - VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR = 1000314000, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR = 1000314001, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR = 1000314002, - VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR = 1000314003, - VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR = 1000314004, - VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR = 1000314005, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR = 1000314006, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = 1000314007, + VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECT_CREATE_INFO_EXT = 1000311000, + VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECTS_INFO_EXT = 1000311001, + VK_STRUCTURE_TYPE_EXPORT_METAL_DEVICE_INFO_EXT = 1000311002, + VK_STRUCTURE_TYPE_EXPORT_METAL_COMMAND_QUEUE_INFO_EXT = 1000311003, + VK_STRUCTURE_TYPE_EXPORT_METAL_BUFFER_INFO_EXT = 1000311004, + VK_STRUCTURE_TYPE_IMPORT_METAL_BUFFER_INFO_EXT = 1000311005, + VK_STRUCTURE_TYPE_EXPORT_METAL_TEXTURE_INFO_EXT = 1000311006, + VK_STRUCTURE_TYPE_IMPORT_METAL_TEXTURE_INFO_EXT = 1000311007, + VK_STRUCTURE_TYPE_EXPORT_METAL_IO_SURFACE_INFO_EXT = 1000311008, + VK_STRUCTURE_TYPE_IMPORT_METAL_IO_SURFACE_INFO_EXT = 1000311009, + VK_STRUCTURE_TYPE_EXPORT_METAL_SHARED_EVENT_INFO_EXT = 1000311010, + VK_STRUCTURE_TYPE_IMPORT_METAL_SHARED_EVENT_INFO_EXT = 1000311011, VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, VK_STRUCTURE_TYPE_CHECKPOINT_DATA_2_NV = 1000314009, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT = 1000320000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT = 1000320001, + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT = 1000320002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD = 1000321000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR = 1000203000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_PROPERTIES_KHR = 1000322000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR = 1000323000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = 1000325000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001, VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002, @@ -846,20 +902,14 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001, VK_STRUCTURE_TYPE_COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = 1000335000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR = 1000336000, - VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR = 1000337000, - VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR = 1000337001, - VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR = 1000337002, - VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR = 1000337003, - VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR = 1000337004, - VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR = 1000337005, - VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR = 1000337006, - VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR = 1000337007, - VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = 1000337008, - VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = 1000337009, - VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = 1000337010, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT = 1000338000, + VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT = 1000338001, + VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_EXT = 1000338002, + VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_EXT = 1000338003, + VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT = 1000338004, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM = 1000342000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT = 1000344000, VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = 1000351000, @@ -868,8 +918,9 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001, VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT = 1000355000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT = 1000355001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000, - VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR = 1000360000, VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000, VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001, VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002, @@ -891,24 +942,43 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI = 1000370000, VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV = 1000371000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001, + VK_STRUCTURE_TYPE_PIPELINE_PROPERTIES_IDENTIFIER_EXT = 1000372000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT = 1000372001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000, VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = 1000388000, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = 1000388001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT = 1000382000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MAINTENANCE_1_FEATURES_KHR = 1000386000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT = 1000391000, + VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT = 1000391001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT = 1000393000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT = 1000411000, VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT = 1000411001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR = 1000413000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR = 1000413001, - VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR = 1000413002, - VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR = 1000413003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE = 1000420000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_BINDING_REFERENCE_VALVE = 1000420001, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_HOST_MAPPING_INFO_VALVE = 1000420002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT = 1000422000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM = 1000425000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM = 1000425001, + VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM = 1000425002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV = 1000430000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT = 1000437000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_MERGE_FEEDBACK_FEATURES_EXT = 1000458000, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_CONTROL_EXT = 1000458001, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000458002, + VK_STRUCTURE_TYPE_RENDER_PASS_SUBPASS_FEEDBACK_CREATE_INFO_EXT = 1000458003, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, + VK_STRUCTURE_TYPE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_INFO, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO, VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_NV = VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD, VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, @@ -929,6 +999,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO, VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES, VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, @@ -971,6 +1042,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO, VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, @@ -992,13 +1067,16 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, + VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, @@ -1007,12 +1085,17 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT, VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES, VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, @@ -1021,9 +1104,51 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, + VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO, + VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, + VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, + VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR = VK_STRUCTURE_TYPE_SUBMIT_INFO_2, + VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, + VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2, + VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2, + VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_IMAGE_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = VK_STRUCTURE_TYPE_IMAGE_BLIT_2, + VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3, + VK_STRUCTURE_TYPE_PIPELINE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES, + VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS, VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkStructureType; +typedef enum VkPipelineCacheHeaderVersion { + VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, + VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCacheHeaderVersion; + typedef enum VkImageLayout { VK_IMAGE_LAYOUT_UNDEFINED = 0, VK_IMAGE_LAYOUT_GENERAL = 1, @@ -1040,6 +1165,8 @@ typedef enum VkImageLayout { VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL = 1000314000, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL = 1000314001, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, #ifdef VK_ENABLE_BETA_EXTENSIONS VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR = 1000024000, @@ -1062,8 +1189,6 @@ typedef enum VkImageLayout { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR = 1000299002, #endif - VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = 1000314000, - VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = 1000314001, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, @@ -1071,6 +1196,8 @@ typedef enum VkImageLayout { VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF } VkImageLayout; @@ -1103,6 +1230,7 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_COMMAND_POOL = 25, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, + VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000, VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000, @@ -1123,18 +1251,13 @@ typedef enum VkObjectType { VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000, VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000, VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV = 1000277000, - VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = 1000295000, VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = 1000366000, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, + VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = VK_OBJECT_TYPE_PRIVATE_DATA_SLOT, VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } VkObjectType; -typedef enum VkPipelineCacheHeaderVersion { - VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, - VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCacheHeaderVersion; - typedef enum VkVendorId { VK_VENDOR_ID_VIV = 0x10001, VK_VENDOR_ID_VSI = 0x10002, @@ -1379,6 +1502,26 @@ typedef enum VkFormat { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031, VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032, VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033, + VK_FORMAT_G8_B8R8_2PLANE_444_UNORM = 1000330000, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002, + VK_FORMAT_G16_B16R16_2PLANE_444_UNORM = 1000330003, + VK_FORMAT_A4R4G4B4_UNORM_PACK16 = 1000340000, + VK_FORMAT_A4B4G4R4_UNORM_PACK16 = 1000340001, + VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK = 1000066000, + VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK = 1000066001, + VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK = 1000066002, + VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK = 1000066003, + VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK = 1000066004, + VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK = 1000066005, + VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK = 1000066006, + VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK = 1000066007, + VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK = 1000066008, + VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK = 1000066009, + VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK = 1000066010, + VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011, + VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012, + VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013, VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000, VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001, VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002, @@ -1387,26 +1530,20 @@ typedef enum VkFormat { VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, - VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = 1000066000, - VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = 1000066001, - VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = 1000066002, - VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = 1000066003, - VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = 1000066004, - VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = 1000066005, - VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = 1000066006, - VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = 1000066007, - VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = 1000066008, - VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = 1000066009, - VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = 1000066010, - VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = 1000066011, - VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = 1000066012, - VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = 1000066013, - VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = 1000330000, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = 1000330001, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = 1000330002, - VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = 1000330003, - VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = 1000340000, - VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = 1000340001, + VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK, + VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK, + VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK, + VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK, + VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK, VK_FORMAT_G8B8G8R8_422_UNORM_KHR = VK_FORMAT_G8B8G8R8_422_UNORM, VK_FORMAT_B8G8R8G8_422_UNORM_KHR = VK_FORMAT_B8G8R8G8_422_UNORM, VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, @@ -1441,6 +1578,12 @@ typedef enum VkFormat { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, + VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, + VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM, + VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = VK_FORMAT_A4R4G4B4_UNORM_PACK16, + VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = VK_FORMAT_A4B4G4R4_UNORM_PACK16, VK_FORMAT_MAX_ENUM = 0x7FFFFFFF } VkFormat; @@ -1483,6 +1626,9 @@ typedef enum VkQueryType { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_QUERY_TYPE_VIDEO_ENCODE_BITSTREAM_BUFFER_RANGE_KHR = 1000299000, #endif + VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT = 1000382000, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR = 1000386000, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR = 1000386001, VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF } VkQueryType; @@ -1614,6 +1760,21 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, + VK_DYNAMIC_STATE_CULL_MODE = 1000267000, + VK_DYNAMIC_STATE_FRONT_FACE = 1000267001, + VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = 1000267002, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT = 1000267003, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT = 1000267004, + VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE = 1000267005, + VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE = 1000267006, + VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE = 1000267007, + VK_DYNAMIC_STATE_DEPTH_COMPARE_OP = 1000267008, + VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE = 1000267009, + VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE = 1000267010, + VK_DYNAMIC_STATE_STENCIL_OP = 1000267011, + VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE = 1000377001, + VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE = 1000377002, + VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004, VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000, VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000, VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000, @@ -1623,25 +1784,25 @@ typedef enum VkDynamicState { VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001, VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR = 1000226000, VK_DYNAMIC_STATE_LINE_STIPPLE_EXT = 1000259000, - VK_DYNAMIC_STATE_CULL_MODE_EXT = 1000267000, - VK_DYNAMIC_STATE_FRONT_FACE_EXT = 1000267001, - VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT = 1000267002, - VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT = 1000267003, - VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT = 1000267004, - VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT = 1000267005, - VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT = 1000267006, - VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT = 1000267007, - VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT = 1000267008, - VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT = 1000267009, - VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT = 1000267010, - VK_DYNAMIC_STATE_STENCIL_OP_EXT = 1000267011, VK_DYNAMIC_STATE_VERTEX_INPUT_EXT = 1000352000, VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT = 1000377000, - VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT = 1000377001, - VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT = 1000377002, VK_DYNAMIC_STATE_LOGIC_OP_EXT = 1000377003, - VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT = 1000377004, VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT = 1000381000, + VK_DYNAMIC_STATE_CULL_MODE_EXT = VK_DYNAMIC_STATE_CULL_MODE, + VK_DYNAMIC_STATE_FRONT_FACE_EXT = VK_DYNAMIC_STATE_FRONT_FACE, + VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, + VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE, + VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE, + VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE, + VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP, + VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE, + VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE, + VK_DYNAMIC_STATE_STENCIL_OP_EXT = VK_DYNAMIC_STATE_STENCIL_OP, + VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE, + VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE, + VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE, VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF } VkDynamicState; @@ -1760,10 +1921,11 @@ typedef enum VkDescriptorType { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, - VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = 1000138000, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK = 1000138000, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, VK_DESCRIPTOR_TYPE_MUTABLE_VALVE = 1000351000, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF } VkDescriptorType; @@ -1778,9 +1940,10 @@ typedef enum VkAttachmentLoadOp { typedef enum VkAttachmentStoreOp { VK_ATTACHMENT_STORE_OP_STORE = 0, VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, - VK_ATTACHMENT_STORE_OP_NONE_KHR = 1000301000, - VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE_KHR, - VK_ATTACHMENT_STORE_OP_NONE_EXT = VK_ATTACHMENT_STORE_OP_NONE_KHR, + VK_ATTACHMENT_STORE_OP_NONE = 1000301000, + VK_ATTACHMENT_STORE_OP_NONE_KHR = VK_ATTACHMENT_STORE_OP_NONE, + VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE, + VK_ATTACHMENT_STORE_OP_NONE_EXT = VK_ATTACHMENT_STORE_OP_NONE, VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF } VkAttachmentStoreOp; @@ -1832,6 +1995,7 @@ typedef enum VkAccessFlagBits { VK_ACCESS_HOST_WRITE_BIT = 0x00004000, VK_ACCESS_MEMORY_READ_BIT = 0x00008000, VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, + VK_ACCESS_NONE = 0, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, @@ -1843,10 +2007,10 @@ typedef enum VkAccessFlagBits { VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000, VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000, VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000, - VK_ACCESS_NONE_KHR = 0, VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, + VK_ACCESS_NONE_KHR = VK_ACCESS_NONE, VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkAccessFlagBits; typedef VkFlags VkAccessFlags; @@ -1859,6 +2023,7 @@ typedef enum VkImageAspectFlagBits { VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, + VK_IMAGE_ASPECT_NONE = 0, VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080, VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100, VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200, @@ -1866,6 +2031,7 @@ typedef enum VkImageAspectFlagBits { VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT, VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT, + VK_IMAGE_ASPECT_NONE_KHR = VK_IMAGE_ASPECT_NONE, VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageAspectFlagBits; typedef VkFlags VkImageAspectFlags; @@ -1941,6 +2107,8 @@ typedef enum VkImageCreateFlagBits { VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000, VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000, + VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT = 0x00020000, + VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM = 0x00008000, VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, @@ -1997,6 +2165,11 @@ typedef enum VkImageUsageFlagBits { VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageUsageFlagBits; typedef VkFlags VkImageUsageFlags; + +typedef enum VkInstanceCreateFlagBits { + VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR = 0x00000001, + VK_INSTANCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkInstanceCreateFlagBits; typedef VkFlags VkInstanceCreateFlags; typedef enum VkMemoryHeapFlagBits { @@ -2062,6 +2235,7 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, + VK_PIPELINE_STAGE_NONE = 0, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000, VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000, @@ -2071,10 +2245,10 @@ typedef enum VkPipelineStageFlagBits { VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000, VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = 0x00020000, - VK_PIPELINE_STAGE_NONE_KHR = 0, VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, + VK_PIPELINE_STAGE_NONE_KHR = VK_PIPELINE_STAGE_NONE, VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineStageFlagBits; typedef VkFlags VkPipelineStageFlags; @@ -2102,7 +2276,8 @@ typedef VkFlags VkFenceCreateFlags; typedef VkFlags VkSemaphoreCreateFlags; typedef enum VkEventCreateFlagBits { - VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = 0x00000001, + VK_EVENT_CREATE_DEVICE_ONLY_BIT = 0x00000001, + VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = VK_EVENT_CREATE_DEVICE_ONLY_BIT, VK_EVENT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkEventCreateFlagBits; typedef VkFlags VkEventCreateFlags; @@ -2194,7 +2369,8 @@ typedef VkFlags VkImageViewCreateFlags; typedef VkFlags VkShaderModuleCreateFlags; typedef enum VkPipelineCacheCreateFlagBits { - VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = 0x00000001, + VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001, + VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT, VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineCacheCreateFlagBits; typedef VkFlags VkPipelineCacheCreateFlags; @@ -2214,8 +2390,10 @@ typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 0x00000010, - VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000, - VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT = 0x00000100, + VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT = 0x00000200, + VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000, + VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000, VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000, @@ -2228,19 +2406,25 @@ typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080, VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV = 0x00040000, VK_PIPELINE_CREATE_LIBRARY_BIT_KHR = 0x00000800, - VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = 0x00000100, - VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = 0x00000200, + VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT = 0x00800000, + VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT = 0x00000400, VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000, VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, + VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, + VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT, VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT, VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT, + VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT, VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineCreateFlagBits; typedef VkFlags VkPipelineCreateFlags; typedef enum VkPipelineShaderStageCreateFlagBits { - VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = 0x00000001, - VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = 0x00000002, + VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT = 0x00000001, + VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT = 0x00000002, + VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT, + VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT, VK_PIPELINE_SHADER_STAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkPipelineShaderStageCreateFlagBits; typedef VkFlags VkPipelineShaderStageCreateFlags; @@ -2286,15 +2470,32 @@ typedef VkFlags VkPipelineTessellationStateCreateFlags; typedef VkFlags VkPipelineViewportStateCreateFlags; typedef VkFlags VkPipelineRasterizationStateCreateFlags; typedef VkFlags VkPipelineMultisampleStateCreateFlags; + +typedef enum VkPipelineDepthStencilStateCreateFlagBits { + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = 0x00000001, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = 0x00000002, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineDepthStencilStateCreateFlagBits; typedef VkFlags VkPipelineDepthStencilStateCreateFlags; + +typedef enum VkPipelineColorBlendStateCreateFlagBits { + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM = 0x00000001, + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineColorBlendStateCreateFlagBits; typedef VkFlags VkPipelineColorBlendStateCreateFlags; typedef VkFlags VkPipelineDynamicStateCreateFlags; + +typedef enum VkPipelineLayoutCreateFlagBits { + VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT = 0x00000002, + VK_PIPELINE_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineLayoutCreateFlagBits; typedef VkFlags VkPipelineLayoutCreateFlags; typedef VkFlags VkShaderStageFlags; typedef enum VkSamplerCreateFlagBits { VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT = 0x00000001, VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT = 0x00000002, + VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT = 0x00000004, VK_SAMPLER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSamplerCreateFlagBits; typedef VkFlags VkSamplerCreateFlags; @@ -2352,6 +2553,9 @@ typedef enum VkSubpassDescriptionFlagBits { VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002, VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM = 0x00000004, VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM = 0x00000008, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM = 0x00000010, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = 0x00000020, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = 0x00000040, VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSubpassDescriptionFlagBits; typedef VkFlags VkSubpassDescriptionFlags; @@ -5352,6 +5556,8 @@ typedef enum VkDriverId { VK_DRIVER_ID_MESA_TURNIP = 18, VK_DRIVER_ID_MESA_V3DV = 19, VK_DRIVER_ID_MESA_PANVK = 20, + VK_DRIVER_ID_SAMSUNG_PROPRIETARY = 21, + VK_DRIVER_ID_MESA_VENUS = 22, VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY, VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE, VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV, @@ -6073,6 +6279,1039 @@ VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress( #endif +#define VK_VERSION_1_3 1 +// Vulkan 1.3 version number +#define VK_API_VERSION_1_3 VK_MAKE_API_VERSION(0, 1, 3, 0)// Patch version should always be set to 0 + +typedef uint64_t VkFlags64; +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlot) + +typedef enum VkPipelineCreationFeedbackFlagBits { + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT = 0x00000001, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT = 0x00000002, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT = 0x00000004, + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT, + VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCreationFeedbackFlagBits; +typedef VkFlags VkPipelineCreationFeedbackFlags; + +typedef enum VkToolPurposeFlagBits { + VK_TOOL_PURPOSE_VALIDATION_BIT = 0x00000001, + VK_TOOL_PURPOSE_PROFILING_BIT = 0x00000002, + VK_TOOL_PURPOSE_TRACING_BIT = 0x00000004, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT = 0x00000008, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT = 0x00000010, + VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020, + VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040, + VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = VK_TOOL_PURPOSE_VALIDATION_BIT, + VK_TOOL_PURPOSE_PROFILING_BIT_EXT = VK_TOOL_PURPOSE_PROFILING_BIT, + VK_TOOL_PURPOSE_TRACING_BIT_EXT = VK_TOOL_PURPOSE_TRACING_BIT, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT, + VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkToolPurposeFlagBits; +typedef VkFlags VkToolPurposeFlags; +typedef VkFlags VkPrivateDataSlotCreateFlags; +typedef VkFlags64 VkPipelineStageFlags2; + +// Flag bits for VkPipelineStageFlagBits2 +typedef VkFlags64 VkPipelineStageFlagBits2; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE = 0ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT = 0x00000001ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT = 0x00000002ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT = 0x00000004ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT = 0x00000008ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT = 0x00000040ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT = 0x00000080ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT = 0x00000100ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT = 0x00000200ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT = 0x00000800ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT = 0x00002000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT = 0x00004000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT = 0x00008000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT = 0x00010000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT = 0x100000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT = 0x200000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT = 0x400000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT = 0x800000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT = 0x1000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT = 0x2000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT = 0x4000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR = 0x04000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR = 0x08000000ULL; +#endif +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR = 0x10000000ULL; + +typedef VkFlags64 VkAccessFlags2; + +// Flag bits for VkAccessFlagBits2 +typedef VkFlags64 VkAccessFlagBits2; +static const VkAccessFlagBits2 VK_ACCESS_2_NONE = 0ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_NONE_KHR = 0ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT = 0x00000001ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT = 0x00000002ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT = 0x00000008ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT = 0x00000010ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT = 0x00000020ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT = 0x00000040ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT = 0x00000080ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT = 0x00000800ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT = 0x00001000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT = 0x00002000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT = 0x00004000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT = 0x00008000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT = 0x00010000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT = 0x100000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT = 0x200000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT = 0x400000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR = 0x800000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR = 0x1000000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR = 0x2000000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR = 0x4000000000ULL; +#endif +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_BINDING_TABLE_READ_BIT_KHR = 0x10000000000ULL; + + +typedef enum VkSubmitFlagBits { + VK_SUBMIT_PROTECTED_BIT = 0x00000001, + VK_SUBMIT_PROTECTED_BIT_KHR = VK_SUBMIT_PROTECTED_BIT, + VK_SUBMIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSubmitFlagBits; +typedef VkFlags VkSubmitFlags; + +typedef enum VkRenderingFlagBits { + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 0x00000001, + VK_RENDERING_SUSPENDING_BIT = 0x00000002, + VK_RENDERING_RESUMING_BIT = 0x00000004, + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, + VK_RENDERING_SUSPENDING_BIT_KHR = VK_RENDERING_SUSPENDING_BIT, + VK_RENDERING_RESUMING_BIT_KHR = VK_RENDERING_RESUMING_BIT, + VK_RENDERING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkRenderingFlagBits; +typedef VkFlags VkRenderingFlags; +typedef VkFlags64 VkFormatFeatureFlags2; + +// Flag bits for VkFormatFeatureFlagBits2 +typedef VkFlags64 VkFormatFeatureFlagBits2; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT = 0x00000001ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR = 0x00000001ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT = 0x00000002ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR = 0x00000002ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR = 0x00000004ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT = 0x00000010ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000010ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR = 0x00000020ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT = 0x00000040ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR = 0x00000040ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT = 0x00000080ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR = 0x00000080ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR = 0x00000100ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 0x00000200ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT = 0x00000400ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR = 0x00000400ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT = 0x00000800ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR = 0x00000800ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR = 0x00001000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT = 0x00002000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT = 0x00004000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR = 0x00004000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT = 0x00008000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR = 0x00008000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR = 0x00010000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 0x00020000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 0x00040000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 0x00080000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 0x00100000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 0x00200000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT = 0x00400000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR = 0x00400000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT = 0x00800000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR = 0x00800000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT = 0x80000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR = 0x80000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT = 0x100000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR = 0x100000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT = 0x200000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR = 0x200000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000ULL; +#endif +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000ULL; +#endif +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV = 0x4000000000ULL; + +typedef struct VkPhysicalDeviceVulkan13Features { + VkStructureType sType; + void* pNext; + VkBool32 robustImageAccess; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; + VkBool32 pipelineCreationCacheControl; + VkBool32 privateData; + VkBool32 shaderDemoteToHelperInvocation; + VkBool32 shaderTerminateInvocation; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; + VkBool32 synchronization2; + VkBool32 textureCompressionASTC_HDR; + VkBool32 shaderZeroInitializeWorkgroupMemory; + VkBool32 dynamicRendering; + VkBool32 shaderIntegerDotProduct; + VkBool32 maintenance4; +} VkPhysicalDeviceVulkan13Features; + +typedef struct VkPhysicalDeviceVulkan13Properties { + VkStructureType sType; + void* pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; + uint32_t maxInlineUniformTotalSize; + VkBool32 integerDotProduct8BitUnsignedAccelerated; + VkBool32 integerDotProduct8BitSignedAccelerated; + VkBool32 integerDotProduct8BitMixedSignednessAccelerated; + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProduct16BitUnsignedAccelerated; + VkBool32 integerDotProduct16BitSignedAccelerated; + VkBool32 integerDotProduct16BitMixedSignednessAccelerated; + VkBool32 integerDotProduct32BitUnsignedAccelerated; + VkBool32 integerDotProduct32BitSignedAccelerated; + VkBool32 integerDotProduct32BitMixedSignednessAccelerated; + VkBool32 integerDotProduct64BitUnsignedAccelerated; + VkBool32 integerDotProduct64BitSignedAccelerated; + VkBool32 integerDotProduct64BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; + VkDeviceSize storageTexelBufferOffsetAlignmentBytes; + VkBool32 storageTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize maxBufferSize; +} VkPhysicalDeviceVulkan13Properties; + +typedef struct VkPipelineCreationFeedback { + VkPipelineCreationFeedbackFlags flags; + uint64_t duration; +} VkPipelineCreationFeedback; + +typedef struct VkPipelineCreationFeedbackCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreationFeedback* pPipelineCreationFeedback; + uint32_t pipelineStageCreationFeedbackCount; + VkPipelineCreationFeedback* pPipelineStageCreationFeedbacks; +} VkPipelineCreationFeedbackCreateInfo; + +typedef struct VkPhysicalDeviceShaderTerminateInvocationFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderTerminateInvocation; +} VkPhysicalDeviceShaderTerminateInvocationFeatures; + +typedef struct VkPhysicalDeviceToolProperties { + VkStructureType sType; + void* pNext; + char name[VK_MAX_EXTENSION_NAME_SIZE]; + char version[VK_MAX_EXTENSION_NAME_SIZE]; + VkToolPurposeFlags purposes; + char description[VK_MAX_DESCRIPTION_SIZE]; + char layer[VK_MAX_EXTENSION_NAME_SIZE]; +} VkPhysicalDeviceToolProperties; + +typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderDemoteToHelperInvocation; +} VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures; + +typedef struct VkPhysicalDevicePrivateDataFeatures { + VkStructureType sType; + void* pNext; + VkBool32 privateData; +} VkPhysicalDevicePrivateDataFeatures; + +typedef struct VkDevicePrivateDataCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t privateDataSlotRequestCount; +} VkDevicePrivateDataCreateInfo; + +typedef struct VkPrivateDataSlotCreateInfo { + VkStructureType sType; + const void* pNext; + VkPrivateDataSlotCreateFlags flags; +} VkPrivateDataSlotCreateInfo; + +typedef struct VkPhysicalDevicePipelineCreationCacheControlFeatures { + VkStructureType sType; + void* pNext; + VkBool32 pipelineCreationCacheControl; +} VkPhysicalDevicePipelineCreationCacheControlFeatures; + +typedef struct VkMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; +} VkMemoryBarrier2; + +typedef struct VkBufferMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; +} VkBufferMemoryBarrier2; + +typedef struct VkImageMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier2; + +typedef struct VkDependencyInfo { + VkStructureType sType; + const void* pNext; + VkDependencyFlags dependencyFlags; + uint32_t memoryBarrierCount; + const VkMemoryBarrier2* pMemoryBarriers; + uint32_t bufferMemoryBarrierCount; + const VkBufferMemoryBarrier2* pBufferMemoryBarriers; + uint32_t imageMemoryBarrierCount; + const VkImageMemoryBarrier2* pImageMemoryBarriers; +} VkDependencyInfo; + +typedef struct VkSemaphoreSubmitInfo { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + uint64_t value; + VkPipelineStageFlags2 stageMask; + uint32_t deviceIndex; +} VkSemaphoreSubmitInfo; + +typedef struct VkCommandBufferSubmitInfo { + VkStructureType sType; + const void* pNext; + VkCommandBuffer commandBuffer; + uint32_t deviceMask; +} VkCommandBufferSubmitInfo; + +typedef struct VkSubmitInfo2 { + VkStructureType sType; + const void* pNext; + VkSubmitFlags flags; + uint32_t waitSemaphoreInfoCount; + const VkSemaphoreSubmitInfo* pWaitSemaphoreInfos; + uint32_t commandBufferInfoCount; + const VkCommandBufferSubmitInfo* pCommandBufferInfos; + uint32_t signalSemaphoreInfoCount; + const VkSemaphoreSubmitInfo* pSignalSemaphoreInfos; +} VkSubmitInfo2; + +typedef struct VkPhysicalDeviceSynchronization2Features { + VkStructureType sType; + void* pNext; + VkBool32 synchronization2; +} VkPhysicalDeviceSynchronization2Features; + +typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderZeroInitializeWorkgroupMemory; +} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures; + +typedef struct VkPhysicalDeviceImageRobustnessFeatures { + VkStructureType sType; + void* pNext; + VkBool32 robustImageAccess; +} VkPhysicalDeviceImageRobustnessFeatures; + +typedef struct VkBufferCopy2 { + VkStructureType sType; + const void* pNext; + VkDeviceSize srcOffset; + VkDeviceSize dstOffset; + VkDeviceSize size; +} VkBufferCopy2; + +typedef struct VkCopyBufferInfo2 { + VkStructureType sType; + const void* pNext; + VkBuffer srcBuffer; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferCopy2* pRegions; +} VkCopyBufferInfo2; + +typedef struct VkImageCopy2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy2; + +typedef struct VkCopyImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageCopy2* pRegions; +} VkCopyImageInfo2; + +typedef struct VkBufferImageCopy2 { + VkStructureType sType; + const void* pNext; + VkDeviceSize bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy2; + +typedef struct VkCopyBufferToImageInfo2 { + VkStructureType sType; + const void* pNext; + VkBuffer srcBuffer; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkBufferImageCopy2* pRegions; +} VkCopyBufferToImageInfo2; + +typedef struct VkCopyImageToBufferInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferImageCopy2* pRegions; +} VkCopyImageToBufferInfo2; + +typedef struct VkImageBlit2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets[2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets[2]; +} VkImageBlit2; + +typedef struct VkBlitImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageBlit2* pRegions; + VkFilter filter; +} VkBlitImageInfo2; + +typedef struct VkImageResolve2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageResolve2; + +typedef struct VkResolveImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageResolve2* pRegions; +} VkResolveImageInfo2; + +typedef struct VkPhysicalDeviceSubgroupSizeControlFeatures { + VkStructureType sType; + void* pNext; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; +} VkPhysicalDeviceSubgroupSizeControlFeatures; + +typedef struct VkPhysicalDeviceSubgroupSizeControlProperties { + VkStructureType sType; + void* pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; +} VkPhysicalDeviceSubgroupSizeControlProperties; + +typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfo { + VkStructureType sType; + void* pNext; + uint32_t requiredSubgroupSize; +} VkPipelineShaderStageRequiredSubgroupSizeCreateInfo; + +typedef struct VkPhysicalDeviceInlineUniformBlockFeatures { + VkStructureType sType; + void* pNext; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; +} VkPhysicalDeviceInlineUniformBlockFeatures; + +typedef struct VkPhysicalDeviceInlineUniformBlockProperties { + VkStructureType sType; + void* pNext; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; +} VkPhysicalDeviceInlineUniformBlockProperties; + +typedef struct VkWriteDescriptorSetInlineUniformBlock { + VkStructureType sType; + const void* pNext; + uint32_t dataSize; + const void* pData; +} VkWriteDescriptorSetInlineUniformBlock; + +typedef struct VkDescriptorPoolInlineUniformBlockCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t maxInlineUniformBlockBindings; +} VkDescriptorPoolInlineUniformBlockCreateInfo; + +typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeatures { + VkStructureType sType; + void* pNext; + VkBool32 textureCompressionASTC_HDR; +} VkPhysicalDeviceTextureCompressionASTCHDRFeatures; + +typedef struct VkRenderingAttachmentInfo { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; + VkResolveModeFlagBits resolveMode; + VkImageView resolveImageView; + VkImageLayout resolveImageLayout; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkClearValue clearValue; +} VkRenderingAttachmentInfo; + +typedef struct VkRenderingInfo { + VkStructureType sType; + const void* pNext; + VkRenderingFlags flags; + VkRect2D renderArea; + uint32_t layerCount; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkRenderingAttachmentInfo* pColorAttachments; + const VkRenderingAttachmentInfo* pDepthAttachment; + const VkRenderingAttachmentInfo* pStencilAttachment; +} VkRenderingInfo; + +typedef struct VkPipelineRenderingCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; +} VkPipelineRenderingCreateInfo; + +typedef struct VkPhysicalDeviceDynamicRenderingFeatures { + VkStructureType sType; + void* pNext; + VkBool32 dynamicRendering; +} VkPhysicalDeviceDynamicRenderingFeatures; + +typedef struct VkCommandBufferInheritanceRenderingInfo { + VkStructureType sType; + const void* pNext; + VkRenderingFlags flags; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; + VkSampleCountFlagBits rasterizationSamples; +} VkCommandBufferInheritanceRenderingInfo; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderIntegerDotProduct; +} VkPhysicalDeviceShaderIntegerDotProductFeatures; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductProperties { + VkStructureType sType; + void* pNext; + VkBool32 integerDotProduct8BitUnsignedAccelerated; + VkBool32 integerDotProduct8BitSignedAccelerated; + VkBool32 integerDotProduct8BitMixedSignednessAccelerated; + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProduct16BitUnsignedAccelerated; + VkBool32 integerDotProduct16BitSignedAccelerated; + VkBool32 integerDotProduct16BitMixedSignednessAccelerated; + VkBool32 integerDotProduct32BitUnsignedAccelerated; + VkBool32 integerDotProduct32BitSignedAccelerated; + VkBool32 integerDotProduct32BitMixedSignednessAccelerated; + VkBool32 integerDotProduct64BitUnsignedAccelerated; + VkBool32 integerDotProduct64BitSignedAccelerated; + VkBool32 integerDotProduct64BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; +} VkPhysicalDeviceShaderIntegerDotProductProperties; + +typedef struct VkPhysicalDeviceTexelBufferAlignmentProperties { + VkStructureType sType; + void* pNext; + VkDeviceSize storageTexelBufferOffsetAlignmentBytes; + VkBool32 storageTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; +} VkPhysicalDeviceTexelBufferAlignmentProperties; + +typedef struct VkFormatProperties3 { + VkStructureType sType; + void* pNext; + VkFormatFeatureFlags2 linearTilingFeatures; + VkFormatFeatureFlags2 optimalTilingFeatures; + VkFormatFeatureFlags2 bufferFeatures; +} VkFormatProperties3; + +typedef struct VkPhysicalDeviceMaintenance4Features { + VkStructureType sType; + void* pNext; + VkBool32 maintenance4; +} VkPhysicalDeviceMaintenance4Features; + +typedef struct VkPhysicalDeviceMaintenance4Properties { + VkStructureType sType; + void* pNext; + VkDeviceSize maxBufferSize; +} VkPhysicalDeviceMaintenance4Properties; + +typedef struct VkDeviceBufferMemoryRequirements { + VkStructureType sType; + const void* pNext; + const VkBufferCreateInfo* pCreateInfo; +} VkDeviceBufferMemoryRequirements; + +typedef struct VkDeviceImageMemoryRequirements { + VkStructureType sType; + const void* pNext; + const VkImageCreateInfo* pCreateInfo; + VkImageAspectFlagBits planeAspect; +} VkDeviceImageMemoryRequirements; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolProperties)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlot)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); +typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlot)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); +typedef void (VKAPI_PTR *PFN_vkGetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRendering)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRendering)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdSetCullMode)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode); +typedef void (VKAPI_PTR *PFN_vkCmdSetFrontFace)(VkCommandBuffer commandBuffer, VkFrontFace frontFace); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveTopology)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWithCount)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport* pViewports); +typedef void (VKAPI_PTR *PFN_vkCmdSetScissorWithCount)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers2)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthWriteEnable)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthCompareOp)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBoundsTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilTestEnable)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOp)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizerDiscardEnable)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBiasEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnable)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); +typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirements)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pToolCount, + VkPhysicalDeviceToolProperties* pToolProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlot( + VkDevice device, + const VkPrivateDataSlotCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPrivateDataSlot* pPrivateDataSlot); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlot( + VkDevice device, + VkPrivateDataSlot privateDataSlot, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateData( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, + uint64_t data); + +VKAPI_ATTR void VKAPI_CALL vkGetPrivateData( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, + uint64_t* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2( + VkCommandBuffer commandBuffer, + VkEvent event, + const VkDependencyInfo* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags2 stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + const VkDependencyInfo* pDependencyInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2( + VkCommandBuffer commandBuffer, + const VkDependencyInfo* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags2 stage, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2( + VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo2* pSubmits, + VkFence fence); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyBufferInfo2* pCopyBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2( + VkCommandBuffer commandBuffer, + const VkCopyImageInfo2* pCopyImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2( + VkCommandBuffer commandBuffer, + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2( + VkCommandBuffer commandBuffer, + const VkBlitImageInfo2* pBlitImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2( + VkCommandBuffer commandBuffer, + const VkResolveImageInfo2* pResolveImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRendering( + VkCommandBuffer commandBuffer, + const VkRenderingInfo* pRenderingInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRendering( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCullMode( + VkCommandBuffer commandBuffer, + VkCullModeFlags cullMode); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFace( + VkCommandBuffer commandBuffer, + VkFrontFace frontFace); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopology( + VkCommandBuffer commandBuffer, + VkPrimitiveTopology primitiveTopology); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCount( + VkCommandBuffer commandBuffer, + uint32_t viewportCount, + const VkViewport* pViewports); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCount( + VkCommandBuffer commandBuffer, + uint32_t scissorCount, + const VkRect2D* pScissors); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets, + const VkDeviceSize* pSizes, + const VkDeviceSize* pStrides); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthWriteEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOp( + VkCommandBuffer commandBuffer, + VkCompareOp depthCompareOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthBoundsTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 stencilTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOp( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + VkStencilOp failOp, + VkStencilOp passOp, + VkStencilOp depthFailOp, + VkCompareOp compareOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnable( + VkCommandBuffer commandBuffer, + VkBool32 rasterizerDiscardEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthBiasEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnable( + VkCommandBuffer commandBuffer, + VkBool32 primitiveRestartEnable); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirements( + VkDevice device, + const VkDeviceBufferMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); +#endif + + #define VK_KHR_surface 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) #define VK_KHR_SURFACE_SPEC_VERSION 25 @@ -6502,67 +7741,19 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( #define VK_KHR_dynamic_rendering 1 #define VK_KHR_DYNAMIC_RENDERING_SPEC_VERSION 1 #define VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME "VK_KHR_dynamic_rendering" +typedef VkRenderingFlags VkRenderingFlagsKHR; -typedef enum VkRenderingFlagBitsKHR { - VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = 0x00000001, - VK_RENDERING_SUSPENDING_BIT_KHR = 0x00000002, - VK_RENDERING_RESUMING_BIT_KHR = 0x00000004, - VK_RENDERING_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkRenderingFlagBitsKHR; -typedef VkFlags VkRenderingFlagsKHR; -typedef struct VkRenderingAttachmentInfoKHR { - VkStructureType sType; - const void* pNext; - VkImageView imageView; - VkImageLayout imageLayout; - VkResolveModeFlagBits resolveMode; - VkImageView resolveImageView; - VkImageLayout resolveImageLayout; - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkClearValue clearValue; -} VkRenderingAttachmentInfoKHR; +typedef VkRenderingFlagBits VkRenderingFlagBitsKHR; -typedef struct VkRenderingInfoKHR { - VkStructureType sType; - const void* pNext; - VkRenderingFlagsKHR flags; - VkRect2D renderArea; - uint32_t layerCount; - uint32_t viewMask; - uint32_t colorAttachmentCount; - const VkRenderingAttachmentInfoKHR* pColorAttachments; - const VkRenderingAttachmentInfoKHR* pDepthAttachment; - const VkRenderingAttachmentInfoKHR* pStencilAttachment; -} VkRenderingInfoKHR; +typedef VkRenderingInfo VkRenderingInfoKHR; -typedef struct VkPipelineRenderingCreateInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t viewMask; - uint32_t colorAttachmentCount; - const VkFormat* pColorAttachmentFormats; - VkFormat depthAttachmentFormat; - VkFormat stencilAttachmentFormat; -} VkPipelineRenderingCreateInfoKHR; +typedef VkRenderingAttachmentInfo VkRenderingAttachmentInfoKHR; -typedef struct VkPhysicalDeviceDynamicRenderingFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 dynamicRendering; -} VkPhysicalDeviceDynamicRenderingFeaturesKHR; +typedef VkPipelineRenderingCreateInfo VkPipelineRenderingCreateInfoKHR; -typedef struct VkCommandBufferInheritanceRenderingInfoKHR { - VkStructureType sType; - const void* pNext; - VkRenderingFlagsKHR flags; - uint32_t viewMask; - uint32_t colorAttachmentCount; - const VkFormat* pColorAttachmentFormats; - VkFormat depthAttachmentFormat; - VkFormat stencilAttachmentFormat; - VkSampleCountFlagBits rasterizationSamples; -} VkCommandBufferInheritanceRenderingInfoKHR; +typedef VkPhysicalDeviceDynamicRenderingFeatures VkPhysicalDeviceDynamicRenderingFeaturesKHR; + +typedef VkCommandBufferInheritanceRenderingInfo VkCommandBufferInheritanceRenderingInfoKHR; typedef struct VkRenderingFragmentShadingRateAttachmentInfoKHR { VkStructureType sType; @@ -6596,13 +7787,13 @@ typedef struct VkMultiviewPerViewAttributesInfoNVX { VkBool32 perViewAttributesPositionXOnly; } VkMultiviewPerViewAttributesInfoNVX; -typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderingKHR)(VkCommandBuffer commandBuffer, const VkRenderingInfoKHR* pRenderingInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderingKHR)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); typedef void (VKAPI_PTR *PFN_vkCmdEndRenderingKHR)(VkCommandBuffer commandBuffer); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderingKHR( VkCommandBuffer commandBuffer, - const VkRenderingInfoKHR* pRenderingInfo); + const VkRenderingInfo* pRenderingInfo); VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderingKHR( VkCommandBuffer commandBuffer); @@ -7660,6 +8851,43 @@ typedef struct VkPhysicalDeviceShaderClockFeaturesKHR { +#define VK_KHR_global_priority 1 +#define VK_MAX_GLOBAL_PRIORITY_SIZE_KHR 16U +#define VK_KHR_GLOBAL_PRIORITY_SPEC_VERSION 1 +#define VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME "VK_KHR_global_priority" + +typedef enum VkQueueGlobalPriorityKHR { + VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR = 128, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR = 256, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR = 512, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR = 1024, + VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR, + VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_KHR = 0x7FFFFFFF +} VkQueueGlobalPriorityKHR; +typedef struct VkDeviceQueueGlobalPriorityCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkQueueGlobalPriorityKHR globalPriority; +} VkDeviceQueueGlobalPriorityCreateInfoKHR; + +typedef struct VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 globalPriorityQuery; +} VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR; + +typedef struct VkQueueFamilyGlobalPriorityPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t priorityCount; + VkQueueGlobalPriorityKHR priorities[VK_MAX_GLOBAL_PRIORITY_SIZE_KHR]; +} VkQueueFamilyGlobalPriorityPropertiesKHR; + + + #define VK_KHR_driver_properties 1 #define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1 #define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties" @@ -7752,11 +8980,7 @@ typedef VkPhysicalDeviceVulkanMemoryModelFeatures VkPhysicalDeviceVulkanMemoryMo #define VK_KHR_shader_terminate_invocation 1 #define VK_KHR_SHADER_TERMINATE_INVOCATION_SPEC_VERSION 1 #define VK_KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME "VK_KHR_shader_terminate_invocation" -typedef struct VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderTerminateInvocation; -} VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR; +typedef VkPhysicalDeviceShaderTerminateInvocationFeatures VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR; @@ -8053,46 +9277,9 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR #define VK_KHR_shader_integer_dot_product 1 #define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION 1 #define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME "VK_KHR_shader_integer_dot_product" -typedef struct VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderIntegerDotProduct; -} VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR; +typedef VkPhysicalDeviceShaderIntegerDotProductFeatures VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR; -typedef struct VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR { - VkStructureType sType; - void* pNext; - VkBool32 integerDotProduct8BitUnsignedAccelerated; - VkBool32 integerDotProduct8BitSignedAccelerated; - VkBool32 integerDotProduct8BitMixedSignednessAccelerated; - VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProduct16BitUnsignedAccelerated; - VkBool32 integerDotProduct16BitSignedAccelerated; - VkBool32 integerDotProduct16BitMixedSignednessAccelerated; - VkBool32 integerDotProduct32BitUnsignedAccelerated; - VkBool32 integerDotProduct32BitSignedAccelerated; - VkBool32 integerDotProduct32BitMixedSignednessAccelerated; - VkBool32 integerDotProduct64BitUnsignedAccelerated; - VkBool32 integerDotProduct64BitSignedAccelerated; - VkBool32 integerDotProduct64BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; -} VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR; +typedef VkPhysicalDeviceShaderIntegerDotProductProperties VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR; @@ -8132,261 +9319,94 @@ typedef struct VkPhysicalDevicePresentIdFeaturesKHR { #define VK_KHR_synchronization2 1 -typedef uint64_t VkFlags64; #define VK_KHR_SYNCHRONIZATION_2_SPEC_VERSION 1 #define VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME "VK_KHR_synchronization2" -typedef VkFlags64 VkPipelineStageFlags2KHR; +typedef VkPipelineStageFlags2 VkPipelineStageFlags2KHR; -// Flag bits for VkPipelineStageFlagBits2KHR -typedef VkFlags64 VkPipelineStageFlagBits2KHR; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR = 0x04000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR = 0x08000000ULL; -#endif -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL; -static const VkPipelineStageFlagBits2KHR VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL; +typedef VkPipelineStageFlagBits2 VkPipelineStageFlagBits2KHR; -typedef VkFlags64 VkAccessFlags2KHR; +typedef VkAccessFlags2 VkAccessFlags2KHR; -// Flag bits for VkAccessFlagBits2KHR -typedef VkFlags64 VkAccessFlagBits2KHR; -static const VkAccessFlagBits2KHR VK_ACCESS_2_NONE_KHR = 0ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR = 0x800000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR = 0x1000000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR = 0x2000000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2KHR VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR = 0x4000000000ULL; -#endif -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL; -static const VkAccessFlagBits2KHR VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL; +typedef VkAccessFlagBits2 VkAccessFlagBits2KHR; +typedef VkSubmitFlagBits VkSubmitFlagBitsKHR; -typedef enum VkSubmitFlagBitsKHR { - VK_SUBMIT_PROTECTED_BIT_KHR = 0x00000001, - VK_SUBMIT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSubmitFlagBitsKHR; -typedef VkFlags VkSubmitFlagsKHR; -typedef struct VkMemoryBarrier2KHR { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2KHR srcStageMask; - VkAccessFlags2KHR srcAccessMask; - VkPipelineStageFlags2KHR dstStageMask; - VkAccessFlags2KHR dstAccessMask; -} VkMemoryBarrier2KHR; +typedef VkSubmitFlags VkSubmitFlagsKHR; -typedef struct VkBufferMemoryBarrier2KHR { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2KHR srcStageMask; - VkAccessFlags2KHR srcAccessMask; - VkPipelineStageFlags2KHR dstStageMask; - VkAccessFlags2KHR dstAccessMask; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize size; -} VkBufferMemoryBarrier2KHR; +typedef VkMemoryBarrier2 VkMemoryBarrier2KHR; -typedef struct VkImageMemoryBarrier2KHR { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2KHR srcStageMask; - VkAccessFlags2KHR srcAccessMask; - VkPipelineStageFlags2KHR dstStageMask; - VkAccessFlags2KHR dstAccessMask; - VkImageLayout oldLayout; - VkImageLayout newLayout; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkImage image; - VkImageSubresourceRange subresourceRange; -} VkImageMemoryBarrier2KHR; +typedef VkBufferMemoryBarrier2 VkBufferMemoryBarrier2KHR; -typedef struct VkDependencyInfoKHR { - VkStructureType sType; - const void* pNext; - VkDependencyFlags dependencyFlags; - uint32_t memoryBarrierCount; - const VkMemoryBarrier2KHR* pMemoryBarriers; - uint32_t bufferMemoryBarrierCount; - const VkBufferMemoryBarrier2KHR* pBufferMemoryBarriers; - uint32_t imageMemoryBarrierCount; - const VkImageMemoryBarrier2KHR* pImageMemoryBarriers; -} VkDependencyInfoKHR; +typedef VkImageMemoryBarrier2 VkImageMemoryBarrier2KHR; -typedef struct VkSemaphoreSubmitInfoKHR { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - uint64_t value; - VkPipelineStageFlags2KHR stageMask; - uint32_t deviceIndex; -} VkSemaphoreSubmitInfoKHR; +typedef VkDependencyInfo VkDependencyInfoKHR; -typedef struct VkCommandBufferSubmitInfoKHR { - VkStructureType sType; - const void* pNext; - VkCommandBuffer commandBuffer; - uint32_t deviceMask; -} VkCommandBufferSubmitInfoKHR; +typedef VkSubmitInfo2 VkSubmitInfo2KHR; -typedef struct VkSubmitInfo2KHR { - VkStructureType sType; - const void* pNext; - VkSubmitFlagsKHR flags; - uint32_t waitSemaphoreInfoCount; - const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos; - uint32_t commandBufferInfoCount; - const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos; - uint32_t signalSemaphoreInfoCount; - const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos; -} VkSubmitInfo2KHR; +typedef VkSemaphoreSubmitInfo VkSemaphoreSubmitInfoKHR; -typedef struct VkPhysicalDeviceSynchronization2FeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 synchronization2; -} VkPhysicalDeviceSynchronization2FeaturesKHR; +typedef VkCommandBufferSubmitInfo VkCommandBufferSubmitInfoKHR; + +typedef VkPhysicalDeviceSynchronization2Features VkPhysicalDeviceSynchronization2FeaturesKHR; typedef struct VkQueueFamilyCheckpointProperties2NV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlags2KHR checkpointExecutionStageMask; + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2 checkpointExecutionStageMask; } VkQueueFamilyCheckpointProperties2NV; typedef struct VkCheckpointData2NV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlags2KHR stage; - void* pCheckpointMarker; + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2 stage; + void* pCheckpointMarker; } VkCheckpointData2NV; -typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfoKHR* pDependencyInfo); -typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR stageMask); -typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2KHR)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfoKHR* pDependencyInfos); -typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2KHR)(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR* pDependencyInfo); -typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2KHR)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2KHR stage, VkQueryPool queryPool, uint32_t query); -typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR* pSubmits, VkFence fence); -typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2KHR stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2KHR)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2KHR)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2KHR)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); +typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointData2NV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointData2NV* pCheckpointData); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2KHR( VkCommandBuffer commandBuffer, VkEvent event, - const VkDependencyInfoKHR* pDependencyInfo); + const VkDependencyInfo* pDependencyInfo); VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2KHR( VkCommandBuffer commandBuffer, VkEvent event, - VkPipelineStageFlags2KHR stageMask); + VkPipelineStageFlags2 stageMask); VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2KHR( VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, - const VkDependencyInfoKHR* pDependencyInfos); + const VkDependencyInfo* pDependencyInfos); VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2KHR( VkCommandBuffer commandBuffer, - const VkDependencyInfoKHR* pDependencyInfo); + const VkDependencyInfo* pDependencyInfo); VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2KHR( VkCommandBuffer commandBuffer, - VkPipelineStageFlags2KHR stage, + VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2KHR( VkQueue queue, uint32_t submitCount, - const VkSubmitInfo2KHR* pSubmits, + const VkSubmitInfo2* pSubmits, VkFence fence); VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarker2AMD( VkCommandBuffer commandBuffer, - VkPipelineStageFlags2KHR stage, + VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); @@ -8398,6 +9418,23 @@ VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointData2NV( #endif +#define VK_KHR_fragment_shader_barycentric 1 +#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1 +#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_KHR_fragment_shader_barycentric" +typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 fragmentShaderBarycentric; +} VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR; + +typedef struct VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 triStripVertexOrderIndependentOfProvokingVertex; +} VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR; + + + #define VK_KHR_shader_subgroup_uniform_control_flow 1 #define VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_SPEC_VERSION 1 #define VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_EXTENSION_NAME "VK_KHR_shader_subgroup_uniform_control_flow" @@ -8412,11 +9449,7 @@ typedef struct VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR { #define VK_KHR_zero_initialize_workgroup_memory 1 #define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_SPEC_VERSION 1 #define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_EXTENSION_NAME "VK_KHR_zero_initialize_workgroup_memory" -typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderZeroInitializeWorkgroupMemory; -} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR; +typedef VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR; @@ -8437,257 +9470,143 @@ typedef struct VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR { #define VK_KHR_copy_commands2 1 #define VK_KHR_COPY_COMMANDS_2_SPEC_VERSION 1 #define VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME "VK_KHR_copy_commands2" -typedef struct VkBufferCopy2KHR { - VkStructureType sType; - const void* pNext; - VkDeviceSize srcOffset; - VkDeviceSize dstOffset; - VkDeviceSize size; -} VkBufferCopy2KHR; +typedef VkCopyBufferInfo2 VkCopyBufferInfo2KHR; -typedef struct VkCopyBufferInfo2KHR { - VkStructureType sType; - const void* pNext; - VkBuffer srcBuffer; - VkBuffer dstBuffer; - uint32_t regionCount; - const VkBufferCopy2KHR* pRegions; -} VkCopyBufferInfo2KHR; +typedef VkCopyImageInfo2 VkCopyImageInfo2KHR; -typedef struct VkImageCopy2KHR { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageCopy2KHR; +typedef VkCopyBufferToImageInfo2 VkCopyBufferToImageInfo2KHR; -typedef struct VkCopyImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageCopy2KHR* pRegions; -} VkCopyImageInfo2KHR; +typedef VkCopyImageToBufferInfo2 VkCopyImageToBufferInfo2KHR; -typedef struct VkBufferImageCopy2KHR { - VkStructureType sType; - const void* pNext; - VkDeviceSize bufferOffset; - uint32_t bufferRowLength; - uint32_t bufferImageHeight; - VkImageSubresourceLayers imageSubresource; - VkOffset3D imageOffset; - VkExtent3D imageExtent; -} VkBufferImageCopy2KHR; +typedef VkBlitImageInfo2 VkBlitImageInfo2KHR; -typedef struct VkCopyBufferToImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkBuffer srcBuffer; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkBufferImageCopy2KHR* pRegions; -} VkCopyBufferToImageInfo2KHR; +typedef VkResolveImageInfo2 VkResolveImageInfo2KHR; -typedef struct VkCopyImageToBufferInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkBuffer dstBuffer; - uint32_t regionCount; - const VkBufferImageCopy2KHR* pRegions; -} VkCopyImageToBufferInfo2KHR; +typedef VkBufferCopy2 VkBufferCopy2KHR; -typedef struct VkImageBlit2KHR { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffsets[2]; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffsets[2]; -} VkImageBlit2KHR; +typedef VkImageCopy2 VkImageCopy2KHR; -typedef struct VkBlitImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageBlit2KHR* pRegions; - VkFilter filter; -} VkBlitImageInfo2KHR; +typedef VkImageBlit2 VkImageBlit2KHR; -typedef struct VkImageResolve2KHR { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageResolve2KHR; +typedef VkBufferImageCopy2 VkBufferImageCopy2KHR; -typedef struct VkResolveImageInfo2KHR { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageResolve2KHR* pRegions; -} VkResolveImageInfo2KHR; +typedef VkImageResolve2 VkImageResolve2KHR; -typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2KHR* pCopyBufferInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2KHR* pCopyImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo); -typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2KHR)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2KHR* pBlitImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2KHR)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2KHR* pResolveImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2KHR)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2KHR)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2KHR( VkCommandBuffer commandBuffer, - const VkCopyBufferInfo2KHR* pCopyBufferInfo); + const VkCopyBufferInfo2* pCopyBufferInfo); VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2KHR( VkCommandBuffer commandBuffer, - const VkCopyImageInfo2KHR* pCopyImageInfo); + const VkCopyImageInfo2* pCopyImageInfo); VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2KHR( VkCommandBuffer commandBuffer, - const VkCopyBufferToImageInfo2KHR* pCopyBufferToImageInfo); + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2KHR( VkCommandBuffer commandBuffer, - const VkCopyImageToBufferInfo2KHR* pCopyImageToBufferInfo); + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2KHR( VkCommandBuffer commandBuffer, - const VkBlitImageInfo2KHR* pBlitImageInfo); + const VkBlitImageInfo2* pBlitImageInfo); VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2KHR( VkCommandBuffer commandBuffer, - const VkResolveImageInfo2KHR* pResolveImageInfo); + const VkResolveImageInfo2* pResolveImageInfo); #endif #define VK_KHR_format_feature_flags2 1 #define VK_KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION 1 #define VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME "VK_KHR_format_feature_flags2" -typedef VkFlags64 VkFormatFeatureFlags2KHR; +typedef VkFormatFeatureFlags2 VkFormatFeatureFlags2KHR; -// Flag bits for VkFormatFeatureFlagBits2KHR -typedef VkFlags64 VkFormatFeatureFlagBits2KHR; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR = 0x00000001ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR = 0x00000002ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR = 0x00000004ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000010ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR = 0x00000020ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR = 0x00000040ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR = 0x00000080ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR = 0x00000100ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 0x00000200ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR = 0x00000400ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR = 0x00000800ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR = 0x00001000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR = 0x00004000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR = 0x00008000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR = 0x00010000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 0x00020000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 0x00040000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 0x00080000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 0x00100000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 0x00200000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR = 0x00400000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR = 0x00800000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR = 0x80000000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR = 0x100000000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR = 0x200000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000ULL; -#endif -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000ULL; -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkFormatFeatureFlagBits2KHR VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000ULL; +typedef VkFormatFeatureFlagBits2 VkFormatFeatureFlagBits2KHR; + +typedef VkFormatProperties3 VkFormatProperties3KHR; + + + +#define VK_KHR_ray_tracing_maintenance1 1 +#define VK_KHR_RAY_TRACING_MAINTENANCE_1_SPEC_VERSION 1 +#define VK_KHR_RAY_TRACING_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_ray_tracing_maintenance1" +typedef struct VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 rayTracingMaintenance1; + VkBool32 rayTracingPipelineTraceRaysIndirect2; +} VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR; + +typedef struct VkTraceRaysIndirectCommand2KHR { + VkDeviceAddress raygenShaderRecordAddress; + VkDeviceSize raygenShaderRecordSize; + VkDeviceAddress missShaderBindingTableAddress; + VkDeviceSize missShaderBindingTableSize; + VkDeviceSize missShaderBindingTableStride; + VkDeviceAddress hitShaderBindingTableAddress; + VkDeviceSize hitShaderBindingTableSize; + VkDeviceSize hitShaderBindingTableStride; + VkDeviceAddress callableShaderBindingTableAddress; + VkDeviceSize callableShaderBindingTableSize; + VkDeviceSize callableShaderBindingTableStride; + uint32_t width; + uint32_t height; + uint32_t depth; +} VkTraceRaysIndirectCommand2KHR; + +typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysIndirect2KHR)(VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirect2KHR( + VkCommandBuffer commandBuffer, + VkDeviceAddress indirectDeviceAddress); #endif -typedef struct VkFormatProperties3KHR { - VkStructureType sType; - void* pNext; - VkFormatFeatureFlags2KHR linearTilingFeatures; - VkFormatFeatureFlags2KHR optimalTilingFeatures; - VkFormatFeatureFlags2KHR bufferFeatures; -} VkFormatProperties3KHR; +#define VK_KHR_portability_enumeration 1 +#define VK_KHR_PORTABILITY_ENUMERATION_SPEC_VERSION 1 +#define VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME "VK_KHR_portability_enumeration" #define VK_KHR_maintenance4 1 -#define VK_KHR_MAINTENANCE_4_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_4_SPEC_VERSION 2 #define VK_KHR_MAINTENANCE_4_EXTENSION_NAME "VK_KHR_maintenance4" -typedef struct VkPhysicalDeviceMaintenance4FeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 maintenance4; -} VkPhysicalDeviceMaintenance4FeaturesKHR; +typedef VkPhysicalDeviceMaintenance4Features VkPhysicalDeviceMaintenance4FeaturesKHR; -typedef struct VkPhysicalDeviceMaintenance4PropertiesKHR { - VkStructureType sType; - void* pNext; - VkDeviceSize maxBufferSize; -} VkPhysicalDeviceMaintenance4PropertiesKHR; +typedef VkPhysicalDeviceMaintenance4Properties VkPhysicalDeviceMaintenance4PropertiesKHR; -typedef struct VkDeviceBufferMemoryRequirementsKHR { - VkStructureType sType; - const void* pNext; - const VkBufferCreateInfo* pCreateInfo; -} VkDeviceBufferMemoryRequirementsKHR; +typedef VkDeviceBufferMemoryRequirements VkDeviceBufferMemoryRequirementsKHR; -typedef struct VkDeviceImageMemoryRequirementsKHR { - VkStructureType sType; - const void* pNext; - const VkImageCreateInfo* pCreateInfo; - VkImageAspectFlagBits planeAspect; -} VkDeviceImageMemoryRequirementsKHR; +typedef VkDeviceImageMemoryRequirements VkDeviceImageMemoryRequirementsKHR; -typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirementsKHR)(VkDevice device, const VkDeviceBufferMemoryRequirementsKHR* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirementsKHR* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirementsKHR* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirementsKHR)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirementsKHR( VkDevice device, - const VkDeviceBufferMemoryRequirementsKHR* pInfo, + const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirementsKHR( VkDevice device, - const VkDeviceImageMemoryRequirementsKHR* pInfo, + const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirementsKHR( VkDevice device, - const VkDeviceImageMemoryRequirementsKHR* pInfo, + const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); #endif @@ -9323,11 +10242,7 @@ typedef struct VkValidationFlagsEXT { #define VK_EXT_texture_compression_astc_hdr 1 #define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_SPEC_VERSION 1 #define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME "VK_EXT_texture_compression_astc_hdr" -typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 textureCompressionASTC_HDR; -} VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT; +typedef VkPhysicalDeviceTextureCompressionASTCHDRFeatures VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT; @@ -9955,35 +10870,13 @@ typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFil #define VK_EXT_inline_uniform_block 1 #define VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION 1 #define VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME "VK_EXT_inline_uniform_block" -typedef struct VkPhysicalDeviceInlineUniformBlockFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 inlineUniformBlock; - VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; -} VkPhysicalDeviceInlineUniformBlockFeaturesEXT; +typedef VkPhysicalDeviceInlineUniformBlockFeatures VkPhysicalDeviceInlineUniformBlockFeaturesEXT; -typedef struct VkPhysicalDeviceInlineUniformBlockPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t maxInlineUniformBlockSize; - uint32_t maxPerStageDescriptorInlineUniformBlocks; - uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; - uint32_t maxDescriptorSetInlineUniformBlocks; - uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; -} VkPhysicalDeviceInlineUniformBlockPropertiesEXT; +typedef VkPhysicalDeviceInlineUniformBlockProperties VkPhysicalDeviceInlineUniformBlockPropertiesEXT; -typedef struct VkWriteDescriptorSetInlineUniformBlockEXT { - VkStructureType sType; - const void* pNext; - uint32_t dataSize; - const void* pData; -} VkWriteDescriptorSetInlineUniformBlockEXT; +typedef VkWriteDescriptorSetInlineUniformBlock VkWriteDescriptorSetInlineUniformBlockEXT; -typedef struct VkDescriptorPoolInlineUniformBlockCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t maxInlineUniformBlockBindings; -} VkDescriptorPoolInlineUniformBlockCreateInfoEXT; +typedef VkDescriptorPoolInlineUniformBlockCreateInfo VkDescriptorPoolInlineUniformBlockCreateInfoEXT; @@ -10216,9 +11109,9 @@ typedef struct VkImageDrmFormatModifierPropertiesEXT { } VkImageDrmFormatModifierPropertiesEXT; typedef struct VkDrmFormatModifierProperties2EXT { - uint64_t drmFormatModifier; - uint32_t drmFormatModifierPlaneCount; - VkFormatFeatureFlags2KHR drmFormatModifierTilingFeatures; + uint64_t drmFormatModifier; + uint32_t drmFormatModifierPlaneCount; + VkFormatFeatureFlags2 drmFormatModifierTilingFeatures; } VkDrmFormatModifierProperties2EXT; typedef struct VkDrmFormatModifierPropertiesList2EXT { @@ -10829,19 +11722,9 @@ typedef struct VkFilterCubicImageViewImageFormatPropertiesEXT { #define VK_EXT_global_priority 1 #define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2 #define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority" +typedef VkQueueGlobalPriorityKHR VkQueueGlobalPriorityEXT; -typedef enum VkQueueGlobalPriorityEXT { - VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = 128, - VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = 256, - VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = 512, - VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = 1024, - VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_EXT = 0x7FFFFFFF -} VkQueueGlobalPriorityEXT; -typedef struct VkDeviceQueueGlobalPriorityCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkQueueGlobalPriorityEXT globalPriority; -} VkDeviceQueueGlobalPriorityCreateInfoEXT; +typedef VkDeviceQueueGlobalPriorityCreateInfoKHR VkDeviceQueueGlobalPriorityCreateInfoEXT; @@ -11019,26 +11902,13 @@ typedef struct VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT { #define VK_EXT_pipeline_creation_feedback 1 #define VK_EXT_PIPELINE_CREATION_FEEDBACK_SPEC_VERSION 1 #define VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME "VK_EXT_pipeline_creation_feedback" +typedef VkPipelineCreationFeedbackFlagBits VkPipelineCreationFeedbackFlagBitsEXT; -typedef enum VkPipelineCreationFeedbackFlagBitsEXT { - VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = 0x00000001, - VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = 0x00000002, - VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = 0x00000004, - VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPipelineCreationFeedbackFlagBitsEXT; -typedef VkFlags VkPipelineCreationFeedbackFlagsEXT; -typedef struct VkPipelineCreationFeedbackEXT { - VkPipelineCreationFeedbackFlagsEXT flags; - uint64_t duration; -} VkPipelineCreationFeedbackEXT; +typedef VkPipelineCreationFeedbackFlags VkPipelineCreationFeedbackFlagsEXT; -typedef struct VkPipelineCreationFeedbackCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPipelineCreationFeedbackEXT* pPipelineCreationFeedback; - uint32_t pipelineStageCreationFeedbackCount; - VkPipelineCreationFeedbackEXT* pPipelineStageCreationFeedbacks; -} VkPipelineCreationFeedbackCreateInfoEXT; +typedef VkPipelineCreationFeedbackCreateInfo VkPipelineCreationFeedbackCreateInfoEXT; + +typedef VkPipelineCreationFeedback VkPipelineCreationFeedbackEXT; @@ -11123,11 +11993,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountNV( #define VK_NV_fragment_shader_barycentric 1 #define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1 #define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_NV_fragment_shader_barycentric" -typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 fragmentShaderBarycentric; -} VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV; +typedef VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV; @@ -11437,27 +12303,11 @@ typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLay #define VK_EXT_subgroup_size_control 1 #define VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION 2 #define VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME "VK_EXT_subgroup_size_control" -typedef struct VkPhysicalDeviceSubgroupSizeControlFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 subgroupSizeControl; - VkBool32 computeFullSubgroups; -} VkPhysicalDeviceSubgroupSizeControlFeaturesEXT; +typedef VkPhysicalDeviceSubgroupSizeControlFeatures VkPhysicalDeviceSubgroupSizeControlFeaturesEXT; -typedef struct VkPhysicalDeviceSubgroupSizeControlPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t minSubgroupSize; - uint32_t maxSubgroupSize; - uint32_t maxComputeWorkgroupSubgroups; - VkShaderStageFlags requiredSubgroupSizeStages; -} VkPhysicalDeviceSubgroupSizeControlPropertiesEXT; +typedef VkPhysicalDeviceSubgroupSizeControlProperties VkPhysicalDeviceSubgroupSizeControlPropertiesEXT; -typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT { - VkStructureType sType; - void* pNext; - uint32_t requiredSubgroupSize; -} VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT; +typedef VkPipelineShaderStageRequiredSubgroupSizeCreateInfo VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT; @@ -11574,35 +12424,19 @@ VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT( #define VK_EXT_tooling_info 1 #define VK_EXT_TOOLING_INFO_SPEC_VERSION 1 #define VK_EXT_TOOLING_INFO_EXTENSION_NAME "VK_EXT_tooling_info" +typedef VkToolPurposeFlagBits VkToolPurposeFlagBitsEXT; -typedef enum VkToolPurposeFlagBitsEXT { - VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = 0x00000001, - VK_TOOL_PURPOSE_PROFILING_BIT_EXT = 0x00000002, - VK_TOOL_PURPOSE_TRACING_BIT_EXT = 0x00000004, - VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = 0x00000008, - VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = 0x00000010, - VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020, - VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040, - VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkToolPurposeFlagBitsEXT; -typedef VkFlags VkToolPurposeFlagsEXT; -typedef struct VkPhysicalDeviceToolPropertiesEXT { - VkStructureType sType; - void* pNext; - char name[VK_MAX_EXTENSION_NAME_SIZE]; - char version[VK_MAX_EXTENSION_NAME_SIZE]; - VkToolPurposeFlagsEXT purposes; - char description[VK_MAX_DESCRIPTION_SIZE]; - char layer[VK_MAX_EXTENSION_NAME_SIZE]; -} VkPhysicalDeviceToolPropertiesEXT; +typedef VkToolPurposeFlags VkToolPurposeFlagsEXT; -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties); +typedef VkPhysicalDeviceToolProperties VkPhysicalDeviceToolPropertiesEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolPropertiesEXT( VkPhysicalDevice physicalDevice, uint32_t* pToolCount, - VkPhysicalDeviceToolPropertiesEXT* pToolProperties); + VkPhysicalDeviceToolProperties* pToolProperties); #endif @@ -12033,11 +12867,7 @@ typedef struct VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT { #define VK_EXT_shader_demote_to_helper_invocation 1 #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION 1 #define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME "VK_EXT_shader_demote_to_helper_invocation" -typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 shaderDemoteToHelperInvocation; -} VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT; +typedef VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT; @@ -12259,14 +13089,7 @@ typedef struct VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT { VkBool32 texelBufferAlignment; } VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT; -typedef struct VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT { - VkStructureType sType; - void* pNext; - VkDeviceSize storageTexelBufferOffsetAlignmentBytes; - VkBool32 storageTexelBufferOffsetSingleTexelAlignment; - VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; - VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; -} VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT; +typedef VkPhysicalDeviceTexelBufferAlignmentProperties VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT; @@ -12404,61 +13227,47 @@ typedef struct VkPhysicalDeviceCustomBorderColorFeaturesEXT { #define VK_EXT_private_data 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlotEXT) +typedef VkPrivateDataSlot VkPrivateDataSlotEXT; + #define VK_EXT_PRIVATE_DATA_SPEC_VERSION 1 #define VK_EXT_PRIVATE_DATA_EXTENSION_NAME "VK_EXT_private_data" +typedef VkPrivateDataSlotCreateFlags VkPrivateDataSlotCreateFlagsEXT; -typedef enum VkPrivateDataSlotCreateFlagBitsEXT { - VK_PRIVATE_DATA_SLOT_CREATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPrivateDataSlotCreateFlagBitsEXT; -typedef VkFlags VkPrivateDataSlotCreateFlagsEXT; -typedef struct VkPhysicalDevicePrivateDataFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 privateData; -} VkPhysicalDevicePrivateDataFeaturesEXT; +typedef VkPhysicalDevicePrivateDataFeatures VkPhysicalDevicePrivateDataFeaturesEXT; -typedef struct VkDevicePrivateDataCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t privateDataSlotRequestCount; -} VkDevicePrivateDataCreateInfoEXT; +typedef VkDevicePrivateDataCreateInfo VkDevicePrivateDataCreateInfoEXT; -typedef struct VkPrivateDataSlotCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPrivateDataSlotCreateFlagsEXT flags; -} VkPrivateDataSlotCreateInfoEXT; +typedef VkPrivateDataSlotCreateInfo VkPrivateDataSlotCreateInfoEXT; -typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlotEXT)(VkDevice device, const VkPrivateDataSlotCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlotEXT* pPrivateDataSlot); -typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlotEXT)(VkDevice device, VkPrivateDataSlotEXT privateDataSlot, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t data); -typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t* pData); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlotEXT)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); +typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlotEXT)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); +typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlotEXT( VkDevice device, - const VkPrivateDataSlotCreateInfoEXT* pCreateInfo, + const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, - VkPrivateDataSlotEXT* pPrivateDataSlot); + VkPrivateDataSlot* pPrivateDataSlot); VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlotEXT( VkDevice device, - VkPrivateDataSlotEXT privateDataSlot, + VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateDataEXT( VkDevice device, VkObjectType objectType, uint64_t objectHandle, - VkPrivateDataSlotEXT privateDataSlot, + VkPrivateDataSlot privateDataSlot, uint64_t data); VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( VkDevice device, VkObjectType objectType, uint64_t objectHandle, - VkPrivateDataSlotEXT privateDataSlot, + VkPrivateDataSlot privateDataSlot, uint64_t* pData); #endif @@ -12466,22 +13275,19 @@ VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( #define VK_EXT_pipeline_creation_cache_control 1 #define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_SPEC_VERSION 3 #define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME "VK_EXT_pipeline_creation_cache_control" -typedef struct VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 pipelineCreationCacheControl; -} VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT; +typedef VkPhysicalDevicePipelineCreationCacheControlFeatures VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT; #define VK_NV_device_diagnostics_config 1 -#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_SPEC_VERSION 1 +#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_SPEC_VERSION 2 #define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME "VK_NV_device_diagnostics_config" typedef enum VkDeviceDiagnosticsConfigFlagBitsNV { VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV = 0x00000001, VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV = 0x00000002, VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV = 0x00000004, + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_ERROR_REPORTING_BIT_NV = 0x00000008, VK_DEVICE_DIAGNOSTICS_CONFIG_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF } VkDeviceDiagnosticsConfigFlagBitsNV; typedef VkFlags VkDeviceDiagnosticsConfigFlagsNV; @@ -12504,6 +13310,50 @@ typedef struct VkDeviceDiagnosticsConfigCreateInfoNV { #define VK_QCOM_RENDER_PASS_STORE_OPS_EXTENSION_NAME "VK_QCOM_render_pass_store_ops" +#define VK_EXT_graphics_pipeline_library 1 +#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_SPEC_VERSION 1 +#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME "VK_EXT_graphics_pipeline_library" + +typedef enum VkGraphicsPipelineLibraryFlagBitsEXT { + VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT = 0x00000001, + VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT = 0x00000002, + VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT = 0x00000004, + VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT = 0x00000008, + VK_GRAPHICS_PIPELINE_LIBRARY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkGraphicsPipelineLibraryFlagBitsEXT; +typedef VkFlags VkGraphicsPipelineLibraryFlagsEXT; +typedef struct VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 graphicsPipelineLibrary; +} VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT; + +typedef struct VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 graphicsPipelineLibraryFastLinking; + VkBool32 graphicsPipelineLibraryIndependentInterpolationDecoration; +} VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT; + +typedef struct VkGraphicsPipelineLibraryCreateInfoEXT { + VkStructureType sType; + void* pNext; + VkGraphicsPipelineLibraryFlagsEXT flags; +} VkGraphicsPipelineLibraryCreateInfoEXT; + + + +#define VK_AMD_shader_early_and_late_fragment_tests 1 +#define VK_AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_SPEC_VERSION 1 +#define VK_AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_EXTENSION_NAME "VK_AMD_shader_early_and_late_fragment_tests" +typedef struct VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD { + VkStructureType sType; + void* pNext; + VkBool32 shaderEarlyAndLateFragmentTests; +} VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD; + + + #define VK_NV_fragment_shading_rate_enums 1 #define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_SPEC_VERSION 1 #define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME "VK_NV_fragment_shading_rate_enums" @@ -12696,12 +13546,94 @@ typedef struct VkCopyCommandTransformInfoQCOM { #define VK_EXT_image_robustness 1 #define VK_EXT_IMAGE_ROBUSTNESS_SPEC_VERSION 1 #define VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_image_robustness" -typedef struct VkPhysicalDeviceImageRobustnessFeaturesEXT { +typedef VkPhysicalDeviceImageRobustnessFeatures VkPhysicalDeviceImageRobustnessFeaturesEXT; + + + +#define VK_EXT_image_compression_control 1 +#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SPEC_VERSION 1 +#define VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME "VK_EXT_image_compression_control" + +typedef enum VkImageCompressionFlagBitsEXT { + VK_IMAGE_COMPRESSION_DEFAULT_EXT = 0, + VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT = 0x00000001, + VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT = 0x00000002, + VK_IMAGE_COMPRESSION_DISABLED_EXT = 0x00000004, + VK_IMAGE_COMPRESSION_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkImageCompressionFlagBitsEXT; +typedef VkFlags VkImageCompressionFlagsEXT; + +typedef enum VkImageCompressionFixedRateFlagBitsEXT { + VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT = 0, + VK_IMAGE_COMPRESSION_FIXED_RATE_1BPC_BIT_EXT = 0x00000001, + VK_IMAGE_COMPRESSION_FIXED_RATE_2BPC_BIT_EXT = 0x00000002, + VK_IMAGE_COMPRESSION_FIXED_RATE_3BPC_BIT_EXT = 0x00000004, + VK_IMAGE_COMPRESSION_FIXED_RATE_4BPC_BIT_EXT = 0x00000008, + VK_IMAGE_COMPRESSION_FIXED_RATE_5BPC_BIT_EXT = 0x00000010, + VK_IMAGE_COMPRESSION_FIXED_RATE_6BPC_BIT_EXT = 0x00000020, + VK_IMAGE_COMPRESSION_FIXED_RATE_7BPC_BIT_EXT = 0x00000040, + VK_IMAGE_COMPRESSION_FIXED_RATE_8BPC_BIT_EXT = 0x00000080, + VK_IMAGE_COMPRESSION_FIXED_RATE_9BPC_BIT_EXT = 0x00000100, + VK_IMAGE_COMPRESSION_FIXED_RATE_10BPC_BIT_EXT = 0x00000200, + VK_IMAGE_COMPRESSION_FIXED_RATE_11BPC_BIT_EXT = 0x00000400, + VK_IMAGE_COMPRESSION_FIXED_RATE_12BPC_BIT_EXT = 0x00000800, + VK_IMAGE_COMPRESSION_FIXED_RATE_13BPC_BIT_EXT = 0x00001000, + VK_IMAGE_COMPRESSION_FIXED_RATE_14BPC_BIT_EXT = 0x00002000, + VK_IMAGE_COMPRESSION_FIXED_RATE_15BPC_BIT_EXT = 0x00004000, + VK_IMAGE_COMPRESSION_FIXED_RATE_16BPC_BIT_EXT = 0x00008000, + VK_IMAGE_COMPRESSION_FIXED_RATE_17BPC_BIT_EXT = 0x00010000, + VK_IMAGE_COMPRESSION_FIXED_RATE_18BPC_BIT_EXT = 0x00020000, + VK_IMAGE_COMPRESSION_FIXED_RATE_19BPC_BIT_EXT = 0x00040000, + VK_IMAGE_COMPRESSION_FIXED_RATE_20BPC_BIT_EXT = 0x00080000, + VK_IMAGE_COMPRESSION_FIXED_RATE_21BPC_BIT_EXT = 0x00100000, + VK_IMAGE_COMPRESSION_FIXED_RATE_22BPC_BIT_EXT = 0x00200000, + VK_IMAGE_COMPRESSION_FIXED_RATE_23BPC_BIT_EXT = 0x00400000, + VK_IMAGE_COMPRESSION_FIXED_RATE_24BPC_BIT_EXT = 0x00800000, + VK_IMAGE_COMPRESSION_FIXED_RATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkImageCompressionFixedRateFlagBitsEXT; +typedef VkFlags VkImageCompressionFixedRateFlagsEXT; +typedef struct VkPhysicalDeviceImageCompressionControlFeaturesEXT { VkStructureType sType; void* pNext; - VkBool32 robustImageAccess; -} VkPhysicalDeviceImageRobustnessFeaturesEXT; + VkBool32 imageCompressionControl; +} VkPhysicalDeviceImageCompressionControlFeaturesEXT; +typedef struct VkImageCompressionControlEXT { + VkStructureType sType; + const void* pNext; + VkImageCompressionFlagsEXT flags; + uint32_t compressionControlPlaneCount; + VkImageCompressionFixedRateFlagsEXT* pFixedRateFlags; +} VkImageCompressionControlEXT; + +typedef struct VkSubresourceLayout2EXT { + VkStructureType sType; + void* pNext; + VkSubresourceLayout subresourceLayout; +} VkSubresourceLayout2EXT; + +typedef struct VkImageSubresource2EXT { + VkStructureType sType; + void* pNext; + VkImageSubresource imageSubresource; +} VkImageSubresource2EXT; + +typedef struct VkImageCompressionPropertiesEXT { + VkStructureType sType; + void* pNext; + VkImageCompressionFlagsEXT imageCompressionFlags; + VkImageCompressionFixedRateFlagsEXT imageCompressionFixedRateFlags; +} VkImageCompressionPropertiesEXT; + +typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout2EXT)(VkDevice device, VkImage image, const VkImageSubresource2EXT* pSubresource, VkSubresourceLayout2EXT* pLayout); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout2EXT( + VkDevice device, + VkImage image, + const VkImageSubresource2EXT* pSubresource, + VkSubresourceLayout2EXT* pLayout); +#endif #define VK_EXT_4444_formats 1 @@ -12716,6 +13648,19 @@ typedef struct VkPhysicalDevice4444FormatsFeaturesEXT { +#define VK_ARM_rasterization_order_attachment_access 1 +#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_SPEC_VERSION 1 +#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME "VK_ARM_rasterization_order_attachment_access" +typedef struct VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 rasterizationOrderColorAttachmentAccess; + VkBool32 rasterizationOrderDepthAttachmentAccess; + VkBool32 rasterizationOrderStencilAttachmentAccess; +} VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM; + + + #define VK_EXT_rgba10x6_formats 1 #define VK_EXT_RGBA10X6_FORMATS_SPEC_VERSION 1 #define VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME "VK_EXT_rgba10x6_formats" @@ -12823,6 +13768,23 @@ typedef struct VkPhysicalDeviceDrmPropertiesEXT { +#define VK_EXT_depth_clip_control 1 +#define VK_EXT_DEPTH_CLIP_CONTROL_SPEC_VERSION 1 +#define VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME "VK_EXT_depth_clip_control" +typedef struct VkPhysicalDeviceDepthClipControlFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 depthClipControl; +} VkPhysicalDeviceDepthClipControlFeaturesEXT; + +typedef struct VkPipelineViewportDepthClipControlCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 negativeOneToOne; +} VkPipelineViewportDepthClipControlCreateInfoEXT; + + + #define VK_EXT_primitive_topology_list_restart 1 #define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION 1 #define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME "VK_EXT_primitive_topology_list_restart" @@ -12917,6 +13879,33 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryRemoteAddressNV( #endif +#define VK_EXT_pipeline_properties 1 +#define VK_EXT_PIPELINE_PROPERTIES_SPEC_VERSION 1 +#define VK_EXT_PIPELINE_PROPERTIES_EXTENSION_NAME "VK_EXT_pipeline_properties" +typedef VkPipelineInfoKHR VkPipelineInfoEXT; + +typedef struct VkPipelinePropertiesIdentifierEXT { + VkStructureType sType; + void* pNext; + uint8_t pipelineIdentifier[VK_UUID_SIZE]; +} VkPipelinePropertiesIdentifierEXT; + +typedef struct VkPhysicalDevicePipelinePropertiesFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 pipelinePropertiesIdentifier; +} VkPhysicalDevicePipelinePropertiesFeaturesEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelinePropertiesEXT)(VkDevice device, const VkPipelineInfoEXT* pPipelineInfo, VkBaseOutStructure* pPipelineProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelinePropertiesEXT( + VkDevice device, + const VkPipelineInfoEXT* pPipelineInfo, + VkBaseOutStructure* pPipelineProperties); +#endif + + #define VK_EXT_extended_dynamic_state2 1 #define VK_EXT_EXTENDED_DYNAMIC_STATE_2_SPEC_VERSION 1 #define VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME "VK_EXT_extended_dynamic_state2" @@ -12983,22 +13972,43 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWrite #endif -#define VK_EXT_global_priority_query 1 -#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT 16U -#define VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION 1 -#define VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME "VK_EXT_global_priority_query" -typedef struct VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT { +#define VK_EXT_primitives_generated_query 1 +#define VK_EXT_PRIMITIVES_GENERATED_QUERY_SPEC_VERSION 1 +#define VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME "VK_EXT_primitives_generated_query" +typedef struct VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT { VkStructureType sType; void* pNext; - VkBool32 globalPriorityQuery; -} VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; + VkBool32 primitivesGeneratedQuery; + VkBool32 primitivesGeneratedQueryWithRasterizerDiscard; + VkBool32 primitivesGeneratedQueryWithNonZeroStreams; +} VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT; -typedef struct VkQueueFamilyGlobalPriorityPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t priorityCount; - VkQueueGlobalPriorityEXT priorities[VK_MAX_GLOBAL_PRIORITY_SIZE_EXT]; -} VkQueueFamilyGlobalPriorityPropertiesEXT; + + +#define VK_EXT_global_priority_query 1 +#define VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION 1 +#define VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME "VK_EXT_global_priority_query" +#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT VK_MAX_GLOBAL_PRIORITY_SIZE_KHR +typedef VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; + +typedef VkQueueFamilyGlobalPriorityPropertiesKHR VkQueueFamilyGlobalPriorityPropertiesEXT; + + + +#define VK_EXT_image_view_min_lod 1 +#define VK_EXT_IMAGE_VIEW_MIN_LOD_SPEC_VERSION 1 +#define VK_EXT_IMAGE_VIEW_MIN_LOD_EXTENSION_NAME "VK_EXT_image_view_min_lod" +typedef struct VkPhysicalDeviceImageViewMinLodFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 minLod; +} VkPhysicalDeviceImageViewMinLodFeaturesEXT; + +typedef struct VkImageViewMinLodCreateInfoEXT { + VkStructureType sType; + const void* pNext; + float minLod; +} VkImageViewMinLodCreateInfoEXT; @@ -13051,6 +14061,18 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT( #endif +#define VK_EXT_image_2d_view_of_3d 1 +#define VK_EXT_IMAGE_2D_VIEW_OF_3D_SPEC_VERSION 1 +#define VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME "VK_EXT_image_2d_view_of_3d" +typedef struct VkPhysicalDeviceImage2DViewOf3DFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 image2DViewOf3D; + VkBool32 sampler2DViewOf3D; +} VkPhysicalDeviceImage2DViewOf3DFeaturesEXT; + + + #define VK_EXT_load_store_op_none 1 #define VK_EXT_LOAD_STORE_OP_NONE_SPEC_VERSION 1 #define VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_EXT_load_store_op_none" @@ -13094,6 +14116,164 @@ VKAPI_ATTR void VKAPI_CALL vkSetDeviceMemoryPriorityEXT( #endif +#define VK_VALVE_descriptor_set_host_mapping 1 +#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_SPEC_VERSION 1 +#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_EXTENSION_NAME "VK_VALVE_descriptor_set_host_mapping" +typedef struct VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE { + VkStructureType sType; + void* pNext; + VkBool32 descriptorSetHostMapping; +} VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE; + +typedef struct VkDescriptorSetBindingReferenceVALVE { + VkStructureType sType; + const void* pNext; + VkDescriptorSetLayout descriptorSetLayout; + uint32_t binding; +} VkDescriptorSetBindingReferenceVALVE; + +typedef struct VkDescriptorSetLayoutHostMappingInfoVALVE { + VkStructureType sType; + void* pNext; + size_t descriptorOffset; + uint32_t descriptorSize; +} VkDescriptorSetLayoutHostMappingInfoVALVE; + +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE)(VkDevice device, const VkDescriptorSetBindingReferenceVALVE* pBindingReference, VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping); +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetHostMappingVALVE)(VkDevice device, VkDescriptorSet descriptorSet, void** ppData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutHostMappingInfoVALVE( + VkDevice device, + const VkDescriptorSetBindingReferenceVALVE* pBindingReference, + VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping); + +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetHostMappingVALVE( + VkDevice device, + VkDescriptorSet descriptorSet, + void** ppData); +#endif + + +#define VK_EXT_non_seamless_cube_map 1 +#define VK_EXT_NON_SEAMLESS_CUBE_MAP_SPEC_VERSION 1 +#define VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME "VK_EXT_non_seamless_cube_map" +typedef struct VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 nonSeamlessCubeMap; +} VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT; + + + +#define VK_QCOM_fragment_density_map_offset 1 +#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION 1 +#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME "VK_QCOM_fragment_density_map_offset" +typedef struct VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 fragmentDensityMapOffset; +} VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM; + +typedef struct VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM { + VkStructureType sType; + void* pNext; + VkExtent2D fragmentDensityOffsetGranularity; +} VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM; + +typedef struct VkSubpassFragmentDensityMapOffsetEndInfoQCOM { + VkStructureType sType; + const void* pNext; + uint32_t fragmentDensityOffsetCount; + const VkOffset2D* pFragmentDensityOffsets; +} VkSubpassFragmentDensityMapOffsetEndInfoQCOM; + + + +#define VK_NV_linear_color_attachment 1 +#define VK_NV_LINEAR_COLOR_ATTACHMENT_SPEC_VERSION 1 +#define VK_NV_LINEAR_COLOR_ATTACHMENT_EXTENSION_NAME "VK_NV_linear_color_attachment" +typedef struct VkPhysicalDeviceLinearColorAttachmentFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 linearColorAttachment; +} VkPhysicalDeviceLinearColorAttachmentFeaturesNV; + + + +#define VK_GOOGLE_surfaceless_query 1 +#define VK_GOOGLE_SURFACELESS_QUERY_SPEC_VERSION 1 +#define VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME "VK_GOOGLE_surfaceless_query" + + +#define VK_EXT_image_compression_control_swapchain 1 +#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_SPEC_VERSION 1 +#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME "VK_EXT_image_compression_control_swapchain" +typedef struct VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 imageCompressionControlSwapchain; +} VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT; + + + +#define VK_EXT_subpass_merge_feedback 1 +#define VK_EXT_SUBPASS_MERGE_FEEDBACK_SPEC_VERSION 2 +#define VK_EXT_SUBPASS_MERGE_FEEDBACK_EXTENSION_NAME "VK_EXT_subpass_merge_feedback" + +typedef enum VkSubpassMergeStatusEXT { + VK_SUBPASS_MERGE_STATUS_MERGED_EXT = 0, + VK_SUBPASS_MERGE_STATUS_DISALLOWED_EXT = 1, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SIDE_EFFECTS_EXT = 2, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SAMPLES_MISMATCH_EXT = 3, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_VIEWS_MISMATCH_EXT = 4, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_ALIASING_EXT = 5, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPENDENCIES_EXT = 6, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INCOMPATIBLE_INPUT_ATTACHMENT_EXT = 7, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_TOO_MANY_ATTACHMENTS_EXT = 8, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INSUFFICIENT_STORAGE_EXT = 9, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPTH_STENCIL_COUNT_EXT = 10, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_RESOLVE_ATTACHMENT_REUSE_EXT = 11, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SINGLE_SUBPASS_EXT = 12, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_UNSPECIFIED_EXT = 13, + VK_SUBPASS_MERGE_STATUS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkSubpassMergeStatusEXT; +typedef struct VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 subpassMergeFeedback; +} VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT; + +typedef struct VkRenderPassCreationControlEXT { + VkStructureType sType; + const void* pNext; + VkBool32 disallowMerging; +} VkRenderPassCreationControlEXT; + +typedef struct VkRenderPassCreationFeedbackInfoEXT { + uint32_t postMergeSubpassCount; +} VkRenderPassCreationFeedbackInfoEXT; + +typedef struct VkRenderPassCreationFeedbackCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkRenderPassCreationFeedbackInfoEXT* pRenderPassFeedback; +} VkRenderPassCreationFeedbackCreateInfoEXT; + +typedef struct VkRenderPassSubpassFeedbackInfoEXT { + VkSubpassMergeStatusEXT subpassMergeStatus; + char description[VK_MAX_DESCRIPTION_SIZE]; + uint32_t postMergeIndex; +} VkRenderPassSubpassFeedbackInfoEXT; + +typedef struct VkRenderPassSubpassFeedbackCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkRenderPassSubpassFeedbackInfoEXT* pSubpassFeedback; +} VkRenderPassSubpassFeedbackCreateInfoEXT; + + + #define VK_KHR_acceleration_structure 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) #define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 From f2b1805d7e4777af52327a0e51e6892604e34446 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Thu, 9 Jun 2022 16:55:00 +0200 Subject: [PATCH 0103/1348] [dxvk] Allow non seamless samplers. --- src/d3d11/d3d11_sampler.cpp | 1 + src/d3d11/d3d11_video.cpp | 1 + src/d3d9/d3d9_device.cpp | 1 + src/dxvk/dxvk_sampler.cpp | 2 +- src/dxvk/dxvk_sampler.h | 3 +++ src/dxvk/dxvk_swapchain_blitter.cpp | 1 + src/dxvk/dxvk_unbound.cpp | 1 + src/dxvk/hud/dxvk_hud_renderer.cpp | 1 + 8 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_sampler.cpp b/src/d3d11/d3d11_sampler.cpp index c8a54af56..e3e54cf39 100644 --- a/src/d3d11/d3d11_sampler.cpp +++ b/src/d3d11/d3d11_sampler.cpp @@ -38,6 +38,7 @@ namespace dxvk { info.borderColor.float32[i] = desc.BorderColor[i]; info.usePixelCoord = VK_FALSE; // Not supported in D3D11 + info.nonSeamless = VK_FALSE; // Make sure to use a valid anisotropy value if (desc.MaxAnisotropy < 1) info.maxAnisotropy = 1.0f; diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 5c1edc299..883f9188e 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -365,6 +365,7 @@ namespace dxvk { samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; samplerInfo.borderColor = VkClearColorValue(); samplerInfo.usePixelCoord = VK_FALSE; + samplerInfo.nonSeamless = VK_FALSE; m_sampler = Device->createSampler(samplerInfo); DxvkBufferCreateInfo bufferInfo; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 65eaa82e3..50c4d1274 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5961,6 +5961,7 @@ namespace dxvk { info.mipmapLodMin = mipFilter.MipsEnabled ? float(cKey.MaxMipLevel) : 0; info.mipmapLodMax = mipFilter.MipsEnabled ? FLT_MAX : 0; info.usePixelCoord = VK_FALSE; + info.nonSeamless = VK_FALSE; DecodeD3DCOLOR(cKey.BorderColor, info.borderColor.float32); diff --git a/src/dxvk/dxvk_sampler.cpp b/src/dxvk/dxvk_sampler.cpp index ca82a2972..c10e82d02 100644 --- a/src/dxvk/dxvk_sampler.cpp +++ b/src/dxvk/dxvk_sampler.cpp @@ -16,7 +16,7 @@ namespace dxvk { VkSamplerCreateInfo samplerInfo; samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; samplerInfo.pNext = nullptr; - samplerInfo.flags = 0; + samplerInfo.flags = info.nonSeamless ? VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT : 0; samplerInfo.magFilter = info.magFilter; samplerInfo.minFilter = info.minFilter; samplerInfo.mipmapMode = info.mipmapMode; diff --git a/src/dxvk/dxvk_sampler.h b/src/dxvk/dxvk_sampler.h index 5ed268f3b..e2e421b35 100644 --- a/src/dxvk/dxvk_sampler.h +++ b/src/dxvk/dxvk_sampler.h @@ -38,6 +38,9 @@ namespace dxvk { /// Enables unnormalized coordinates VkBool32 usePixelCoord; + + /// Enables non seamless cube map filtering + VkBool32 nonSeamless; }; diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index f0edefcd1..ade44e218 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -304,6 +304,7 @@ namespace dxvk { samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; samplerInfo.borderColor = VkClearColorValue(); samplerInfo.usePixelCoord = VK_TRUE; + samplerInfo.nonSeamless = VK_FALSE; m_samplerPresent = m_device->createSampler(samplerInfo); samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; diff --git a/src/dxvk/dxvk_unbound.cpp b/src/dxvk/dxvk_unbound.cpp index 7ea2f1db5..cb8f665de 100644 --- a/src/dxvk/dxvk_unbound.cpp +++ b/src/dxvk/dxvk_unbound.cpp @@ -53,6 +53,7 @@ namespace dxvk { info.compareOp = VK_COMPARE_OP_NEVER; info.borderColor = VkClearColorValue(); info.usePixelCoord = VK_FALSE; + info.nonSeamless = VK_FALSE; return dev->createSampler(info); } diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index e6bcc9f7c..10720eb50 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -311,6 +311,7 @@ namespace dxvk::hud { info.compareOp = VK_COMPARE_OP_NEVER; info.borderColor = VkClearColorValue(); info.usePixelCoord = VK_TRUE; + info.nonSeamless = VK_FALSE; return m_device->createSampler(info); } From 0015a34498d7068c3b4aea0a56bf9d22afae55f8 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Thu, 9 Jun 2022 17:07:59 +0200 Subject: [PATCH 0104/1348] [dxvk] Enable VK_EXT_non_seamless_cube_map if requested. --- src/dxvk/dxvk_adapter.cpp | 17 ++++++++++++++++- src/dxvk/dxvk_device_info.h | 1 + src/dxvk/dxvk_extensions.h | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 4af554fca..ee9a13f83 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -238,6 +238,8 @@ namespace dxvk { || !required.extHostQueryReset.hostQueryReset) && (m_deviceFeatures.extMemoryPriority.memoryPriority || !required.extMemoryPriority.memoryPriority) + && (m_deviceFeatures.extNonSeamlessCubeMap.nonSeamlessCubeMap + || !required.extNonSeamlessCubeMap.nonSeamlessCubeMap) && (m_deviceFeatures.extRobustness2.robustBufferAccess2 || !required.extRobustness2.robustBufferAccess2) && (m_deviceFeatures.extRobustness2.robustImageAccess2 @@ -263,7 +265,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -275,6 +277,7 @@ namespace dxvk { &devExtensions.extHostQueryReset, &devExtensions.extMemoryBudget, &devExtensions.extMemoryPriority, + &devExtensions.extNonSeamlessCubeMap, &devExtensions.extRobustness2, &devExtensions.extShaderDemoteToHelperInvocation, &devExtensions.extShaderStencilExport, @@ -379,6 +382,11 @@ namespace dxvk { enabledFeatures.extMemoryPriority.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extMemoryPriority); } + if (devExtensions.extNonSeamlessCubeMap) { + enabledFeatures.extNonSeamlessCubeMap.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT; + enabledFeatures.extNonSeamlessCubeMap.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extNonSeamlessCubeMap); + } + if (devExtensions.extShaderDemoteToHelperInvocation) { enabledFeatures.extShaderDemoteToHelperInvocation.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT; enabledFeatures.extShaderDemoteToHelperInvocation.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extShaderDemoteToHelperInvocation); @@ -684,6 +692,11 @@ namespace dxvk { m_deviceFeatures.extMemoryPriority.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extMemoryPriority); } + if (m_deviceExtensions.supports(VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME)) { + m_deviceFeatures.extNonSeamlessCubeMap.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT; + m_deviceFeatures.extNonSeamlessCubeMap.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extNonSeamlessCubeMap); + } + if (m_deviceExtensions.supports(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME)) { m_deviceFeatures.extRobustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; m_deviceFeatures.extRobustness2.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extRobustness2); @@ -789,6 +802,8 @@ namespace dxvk { "\n hostQueryReset : ", features.extHostQueryReset.hostQueryReset ? "1" : "0", "\n", VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, "\n memoryPriority : ", features.extMemoryPriority.memoryPriority ? "1" : "0", + "\n", VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, + "\n nonSeamlessCubeMap : ", features.extNonSeamlessCubeMap.nonSeamlessCubeMap ? "1" : "0", "\n", VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, "\n robustBufferAccess2 : ", features.extRobustness2.robustBufferAccess2 ? "1" : "0", "\n robustImageAccess2 : ", features.extRobustness2.robustImageAccess2 ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index d832bec14..d3f9eb164 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -43,6 +43,7 @@ namespace dxvk { VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extExtendedDynamicState; VkPhysicalDeviceHostQueryResetFeaturesEXT extHostQueryReset; VkPhysicalDeviceMemoryPriorityFeaturesEXT extMemoryPriority; + VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT extNonSeamlessCubeMap; VkPhysicalDeviceRobustness2FeaturesEXT extRobustness2; VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT extShaderDemoteToHelperInvocation; VkPhysicalDeviceTransformFeedbackFeaturesEXT extTransformFeedback; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 8a3912bfe..7f2d8e349 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -287,6 +287,7 @@ namespace dxvk { DxvkExt extHostQueryReset = { VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extMemoryBudget = { VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, DxvkExtMode::Passive }; DxvkExt extMemoryPriority = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extNonSeamlessCubeMap = { VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extRobustness2 = { VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt extShaderDemoteToHelperInvocation = { VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; From cd8e2360f45f652513d480d440875ba1f1284dbd Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Thu, 9 Jun 2022 17:12:38 +0200 Subject: [PATCH 0105/1348] [d3d9] Use non seamless samplers if supported. --- src/d3d9/d3d9_device.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 50c4d1274..fe2dddda7 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3944,6 +3944,8 @@ namespace dxvk { enabled.extCustomBorderColor.customBorderColorWithoutFormat = VK_TRUE; } + enabled.extNonSeamlessCubeMap.nonSeamlessCubeMap = supported.extNonSeamlessCubeMap.nonSeamlessCubeMap; + return enabled; } @@ -5961,7 +5963,7 @@ namespace dxvk { info.mipmapLodMin = mipFilter.MipsEnabled ? float(cKey.MaxMipLevel) : 0; info.mipmapLodMax = mipFilter.MipsEnabled ? FLT_MAX : 0; info.usePixelCoord = VK_FALSE; - info.nonSeamless = VK_FALSE; + info.nonSeamless = m_dxvkDevice->features().extNonSeamlessCubeMap.nonSeamlessCubeMap; DecodeD3DCOLOR(cKey.BorderColor, info.borderColor.float32); From 913129d3b666709c5c500e5575f0b835a8ae15df Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Tue, 5 Jul 2022 17:24:46 +0200 Subject: [PATCH 0106/1348] [d3d9] Add an config option to disable non seamless cube maps. --- dxvk.conf | 10 ++++++++++ src/d3d9/d3d9_device.cpp | 2 +- src/d3d9/d3d9_options.cpp | 1 + src/d3d9/d3d9_options.h | 3 +++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/dxvk.conf b/dxvk.conf index e7a0614a6..ebab35571 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -548,6 +548,16 @@ # d3d9.apitraceMode = False +# Seamless Cubes +# +# Don't use non seamless cube maps even if they are supported. +# Non seamless cubes are correct d3d9 behavior, but can produce worse looking edges. +# +# Supported values: +# - True/False + +# d3d9.seamlessCubes = False + # Debug Utils # # Enables debug utils as this is off by default, this enables user annotations like BeginEvent()/EndEvent(). diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index fe2dddda7..97acadbcb 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5963,7 +5963,7 @@ namespace dxvk { info.mipmapLodMin = mipFilter.MipsEnabled ? float(cKey.MaxMipLevel) : 0; info.mipmapLodMax = mipFilter.MipsEnabled ? FLT_MAX : 0; info.usePixelCoord = VK_FALSE; - info.nonSeamless = m_dxvkDevice->features().extNonSeamlessCubeMap.nonSeamlessCubeMap; + info.nonSeamless = m_dxvkDevice->features().extNonSeamlessCubeMap.nonSeamlessCubeMap && !m_d3d9Options.seamlessCubes; DecodeD3DCOLOR(cKey.BorderColor, info.borderColor.float32); diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index 6a4ff4d3d..29d2c60a6 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -73,6 +73,7 @@ namespace dxvk { this->apitraceMode = config.getOption ("d3d9.apitraceMode", false); this->deviceLocalConstantBuffers = config.getOption ("d3d9.deviceLocalConstantBuffers", false); this->allowDirectBufferMapping = config.getOption ("d3d9.allowDirectBufferMapping", true); + this->seamlessCubes = config.getOption ("d3d9.seamlessCubes", false); // If we are not Nvidia, enable general hazards. this->generalHazards = adapter != nullptr diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index 029fe54e1..17ffb41d7 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -157,6 +157,9 @@ namespace dxvk { /// Disable direct buffer mapping bool allowDirectBufferMapping; + + /// Don't use non seamless cube maps + bool seamlessCubes; }; } From 4a0a9d62861abd4654a39152d1803bdbc3122212 Mon Sep 17 00:00:00 2001 From: Trevonn Date: Sat, 2 Jul 2022 21:59:55 +0100 Subject: [PATCH 0107/1348] [util] Limit Dead Space to 60fps and fix vsync https://www.pcgamingwiki.com/wiki/Dead_Space#Issues_fixed The game has mouse acceleration and physics issues above 60 FPS. Also the game locks to 30 FPS using the built-in vsync. Setting presentInterval to 1 blocks this and the game continues to run at 60 FPS --- src/util/config/config.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 7f4e7ae4a..bb55eb738 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -347,9 +347,13 @@ namespace dxvk { { "d3d9.memoryTrackTest", "True" }, }} }, /* Dead Space uses the a NULL render target instead - of a 1x1 one if DF24 is NOT supported */ + of a 1x1 one if DF24 is NOT supported + Mouse and physics issues above 60 FPS + Built-in Vsync Locks the game to 30 FPS */ { R"(\\Dead Space\.exe$)", {{ { "d3d9.supportDFFormats", "False" }, + { "d3d9.maxFrameRate", "60" }, + { "d3d9.presentInterval", "1" }, }} }, /* Halo CE/HaloPC */ { R"(\\halo(ce)?\.exe$)", {{ From 38cf16a5be9a048bb77e8c9a1e2b8ddde2dd6e0d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 1 Jul 2022 12:49:39 +0200 Subject: [PATCH 0108/1348] [dxvk] Enable and require VK_KHR_dynamic_rendering --- src/dxvk/dxvk_adapter.cpp | 19 +++++++++++++++++-- src/dxvk/dxvk_device_info.h | 1 + src/dxvk/dxvk_extensions.h | 3 ++- src/vulkan/vulkan_loader.h | 5 +++++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index ee9a13f83..1ceda5249 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -265,7 +265,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -289,6 +289,7 @@ namespace dxvk { &devExtensions.khrDepthStencilResolve, &devExtensions.khrDrawIndirectCount, &devExtensions.khrDriverProperties, + &devExtensions.khrDynamicRendering, &devExtensions.khrExternalMemoryWin32, &devExtensions.khrImageFormatList, &devExtensions.khrSamplerMirrorClampToEdge, @@ -334,6 +335,8 @@ namespace dxvk { enabledFeatures.extRobustness2.nullDescriptor = VK_TRUE; + enabledFeatures.khrDynamicRendering.dynamicRendering = VK_TRUE; + Logger::info(str::format("Device properties:" "\n Device name: : ", m_deviceInfo.core.properties.deviceName, "\n Driver version : ", @@ -412,6 +415,11 @@ namespace dxvk { enabledFeatures.khrBufferDeviceAddress.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.khrBufferDeviceAddress); } + if (devExtensions.khrDynamicRendering) { + enabledFeatures.khrDynamicRendering.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR; + enabledFeatures.khrDynamicRendering.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.khrDynamicRendering); + } + // Report the desired overallocation behaviour to the driver VkDeviceMemoryOverallocationCreateInfoAMD overallocInfo; overallocInfo.sType = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD; @@ -722,6 +730,11 @@ namespace dxvk { m_deviceFeatures.khrBufferDeviceAddress.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.khrBufferDeviceAddress); } + if (m_deviceExtensions.supports(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME)) { + m_deviceFeatures.khrDynamicRendering.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR; + m_deviceFeatures.khrDynamicRendering.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.khrDynamicRendering); + } + m_vki->vkGetPhysicalDeviceFeatures2(m_handle, &m_deviceFeatures.core); } @@ -817,7 +830,9 @@ namespace dxvk { "\n vertexAttributeInstanceRateDivisor : ", features.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor ? "1" : "0", "\n vertexAttributeInstanceRateZeroDivisor : ", features.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor ? "1" : "0", "\n", VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, - "\n bufferDeviceAddress : ", features.khrBufferDeviceAddress.bufferDeviceAddress)); + "\n bufferDeviceAddress : ", features.khrBufferDeviceAddress.bufferDeviceAddress ? "1" : "0", + "\n", VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, + "\n dynamicRendering : ", features.khrDynamicRendering.dynamicRendering ? "1" : "0")); } diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index d3f9eb164..5f4ee91f2 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -49,6 +49,7 @@ namespace dxvk { VkPhysicalDeviceTransformFeedbackFeaturesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT extVertexAttributeDivisor; VkPhysicalDeviceBufferDeviceAddressFeaturesKHR khrBufferDeviceAddress; + VkPhysicalDeviceDynamicRenderingFeaturesKHR khrDynamicRendering; }; } \ No newline at end of file diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 7f2d8e349..b3596607b 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -296,9 +296,10 @@ namespace dxvk { DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrBufferDeviceAddress = { VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, DxvkExtMode::Disabled }; DxvkExt khrCreateRenderPass2 = { VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt khrDepthStencilResolve = { VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt khrDepthStencilResolve = { VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrDrawIndirectCount = { VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrDriverProperties = { VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt khrDynamicRendering = { VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrImageFormatList = { VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrSamplerMirrorClampToEdge = { VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 9ff7f1452..ba5def691 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -365,6 +365,11 @@ namespace dxvk::vk { VULKAN_FN(vkGetBufferDeviceAddressKHR); #endif + #ifdef VK_KHR_dynamic_rendering + VULKAN_FN(vkCmdBeginRenderingKHR); + VULKAN_FN(vkCmdEndRenderingKHR); + #endif + #ifdef VK_KHR_external_memory_win32 VULKAN_FN(vkGetMemoryWin32HandleKHR); VULKAN_FN(vkGetMemoryWin32HandlePropertiesKHR); From d5cc50f73f6e582be0912e66d1a6252b3a152e39 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 1 Jul 2022 13:27:25 +0200 Subject: [PATCH 0109/1348] [dxvk] Add dynamic rendering commands to DxvkCommandList --- src/dxvk/dxvk_cmdlist.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index fe3c5f3aa..f6d98855d 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -251,7 +251,13 @@ namespace dxvk { m_vkd->vkCmdBeginQueryIndexedEXT( m_execBuffer, queryPool, query, flags, index); } - + + + void cmdBeginRendering( + const VkRenderingInfoKHR* pRenderingInfo) { + m_vkd->vkCmdBeginRenderingKHR(m_execBuffer, pRenderingInfo); + } + void cmdBeginRenderPass( const VkRenderPassBeginInfo* pRenderPassBegin, @@ -589,6 +595,11 @@ namespace dxvk { } + void cmdEndRendering() { + m_vkd->vkCmdEndRenderingKHR(m_execBuffer); + } + + void cmdEndRenderPass() { m_vkd->vkCmdEndRenderPass(m_execBuffer); } From a450c88c7282faddd98849086446d0053132353f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 1 Jul 2022 16:05:01 +0200 Subject: [PATCH 0110/1348] [dxvk] Use dynamic rendering for blits and mip generation --- src/dxvk/dxvk_context.cpp | 197 ++++++++++++++------ src/dxvk/dxvk_meta_blit.cpp | 332 ++++++---------------------------- src/dxvk/dxvk_meta_blit.h | 39 +--- src/dxvk/dxvk_meta_mipgen.cpp | 134 +++----------- src/dxvk/dxvk_meta_mipgen.h | 106 ++++++++--- 5 files changed, 299 insertions(+), 509 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index ba889069d..66399112d 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1553,53 +1553,72 @@ namespace dxvk { this->spillRenderPass(false); this->invalidateState(); - m_execBarriers.recordCommands(m_cmd); + // Create image views, etc. + Rc mipGenerator = new DxvkMetaMipGenRenderPass(m_device->vkd(), imageView); - // Create the a set of framebuffers and image views - const Rc mipGenerator - = new DxvkMetaMipGenRenderPass(m_device->vkd(), imageView); + if (m_execBarriers.isImageDirty(imageView->image(), imageView->imageSubresources(), DxvkAccess::Write)) + m_execBarriers.recordCommands(m_cmd); + + VkImageLayout dstLayout = imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + VkImageLayout srcLayout = imageView->pickLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + // If necessary, transition first mip level to the read-only layout + if (imageView->imageInfo().layout != srcLayout) { + m_execAcquires.accessImage(imageView->image(), + mipGenerator->getTopSubresource(), + imageView->imageInfo().layout, + imageView->imageInfo().stages, 0, + srcLayout, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_SHADER_READ_BIT); + } + + // If necessary, initialize all levels that are written to + if (imageView->imageInfo().layout != dstLayout) { + m_execAcquires.accessImage(imageView->image(), + mipGenerator->getAllTargetSubresources(), + VK_IMAGE_LAYOUT_UNDEFINED, + imageView->imageInfo().stages, 0, + dstLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + } + + m_execAcquires.recordCommands(m_cmd); // Common descriptor set properties that we use to // bind the source image view to the fragment shader - VkDescriptorImageInfo descriptorImage; + VkDescriptorImageInfo descriptorImage = { }; descriptorImage.sampler = m_common->metaBlit().getSampler(filter); - descriptorImage.imageView = VK_NULL_HANDLE; - descriptorImage.imageLayout = imageView->imageInfo().layout; + descriptorImage.imageLayout = srcLayout; - VkWriteDescriptorSet descriptorWrite; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.pNext = nullptr; - descriptorWrite.dstSet = VK_NULL_HANDLE; + VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; descriptorWrite.dstBinding = 0; descriptorWrite.dstArrayElement = 0; descriptorWrite.descriptorCount = 1; descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; descriptorWrite.pImageInfo = &descriptorImage; - descriptorWrite.pBufferInfo = nullptr; - descriptorWrite.pTexelBufferView = nullptr; // Common render pass info - VkRenderPassBeginInfo passInfo; - passInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - passInfo.pNext = nullptr; - passInfo.renderPass = mipGenerator->renderPass(); - passInfo.framebuffer = VK_NULL_HANDLE; - passInfo.renderArea = VkRect2D { }; - passInfo.clearValueCount = 0; - passInfo.pClearValues = nullptr; + VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + attachmentInfo.imageLayout = dstLayout; + attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + renderingInfo.colorAttachmentCount = 1; + renderingInfo.pColorAttachments = &attachmentInfo; // Retrieve a compatible pipeline to use for rendering DxvkMetaBlitPipeline pipeInfo = m_common->metaBlit().getPipeline( - mipGenerator->viewType(), imageView->info().format, VK_SAMPLE_COUNT_1_BIT); + mipGenerator->getSrcViewType(), imageView->info().format, VK_SAMPLE_COUNT_1_BIT); - for (uint32_t i = 0; i < mipGenerator->passCount(); i++) { - DxvkMetaBlitPass pass = mipGenerator->pass(i); - + for (uint32_t i = 0; i < mipGenerator->getPassCount(); i++) { // Width, height and layer count for the current pass - VkExtent3D passExtent = mipGenerator->passExtent(i); + VkExtent3D passExtent = mipGenerator->computePassExtent(i); // Create descriptor set with the current source view - descriptorImage.imageView = pass.srcView; + descriptorImage.imageView = mipGenerator->getSrcView(i); descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); m_cmd->updateDescriptorSets(1, &descriptorWrite); @@ -1616,17 +1635,30 @@ namespace dxvk { scissor.offset = { 0, 0 }; scissor.extent = { passExtent.width, passExtent.height }; - // Set up render pass info - passInfo.framebuffer = pass.framebuffer; - passInfo.renderArea = scissor; + // Set up rendering info + attachmentInfo.imageView = mipGenerator->getDstView(i); + renderingInfo.renderArea = scissor; + renderingInfo.layerCount = passExtent.depth; // Set up push constants DxvkMetaBlitPushConstants pushConstants = { }; pushConstants.srcCoord0 = { 0.0f, 0.0f, 0.0f }; pushConstants.srcCoord1 = { 1.0f, 1.0f, 1.0f }; pushConstants.layerCount = passExtent.depth; - - m_cmd->cmdBeginRenderPass(&passInfo, VK_SUBPASS_CONTENTS_INLINE); + + if (i) { + m_execAcquires.accessImage(imageView->image(), + mipGenerator->getSourceSubresource(i), + dstLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + srcLayout, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_SHADER_READ_BIT); + m_execAcquires.recordCommands(m_cmd); + } + + m_cmd->cmdBeginRendering(&renderingInfo); m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle); m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeLayout, descriptorWrite.dstSet, 0, nullptr); @@ -1641,9 +1673,44 @@ namespace dxvk { &pushConstants); m_cmd->cmdDraw(3, passExtent.depth, 0, 0); - m_cmd->cmdEndRenderPass(); + m_cmd->cmdEndRendering(); } - + + // Issue barriers to ensure we can safely access all mip + // levels of the image in all ways the image can be used + if (srcLayout == dstLayout) { + m_execBarriers.accessImage(imageView->image(), + imageView->imageSubresources(), + srcLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_SHADER_READ_BIT, + imageView->imageInfo().layout, + imageView->imageInfo().stages, + imageView->imageInfo().access); + } else { + m_execBarriers.accessImage(imageView->image(), + mipGenerator->getAllSourceSubresources(), + srcLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_SHADER_READ_BIT, + imageView->imageInfo().layout, + imageView->imageInfo().stages, + imageView->imageInfo().access); + + m_execBarriers.accessImage(imageView->image(), + mipGenerator->getBottomSubresource(), + dstLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + imageView->imageInfo().layout, + imageView->imageInfo().stages, + imageView->imageInfo().access); + } + m_cmd->trackResource(mipGenerator); m_cmd->trackResource(imageView->image()); } @@ -2508,12 +2575,26 @@ namespace dxvk { || m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); - bool isDepthStencil = region.srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); + bool srcIsDepthStencil = region.srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); - VkImageLayout srcLayout = srcImage->pickLayout(isDepthStencil + VkImageLayout srcLayout = srcImage->pickLayout(srcIsDepthStencil ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - + + VkImageLayout dstLayout = dstImage->pickLayout( + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + + if (dstImage->info().layout != dstLayout) { + m_execAcquires.accessImage( + dstImage, dstSubresourceRange, + dstImage->info().layout, + dstImage->info().stages, 0, + dstLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT); + } + if (srcImage->info().layout != srcLayout) { m_execAcquires.accessImage( srcImage, srcSubresourceRange, @@ -2522,10 +2603,10 @@ namespace dxvk { srcLayout, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); - - m_execAcquires.recordCommands(m_cmd); } + m_execAcquires.recordCommands(m_cmd); + // Sort out image offsets so that dstOffset[0] points // to the top-left corner of the target area VkOffset3D srcOffsets[2] = { region.srcOffsets[0], region.srcOffsets[1] }; @@ -2554,24 +2635,24 @@ namespace dxvk { // Begin render pass Rc pass = new DxvkMetaBlitRenderPass( m_device, dstImage, srcImage, region, mapping); - DxvkMetaBlitPass passObjects = pass->pass(); VkExtent3D imageExtent = dstImage->mipLevelExtent(region.dstSubresource.mipLevel); - VkRect2D renderArea; - renderArea.offset = VkOffset2D { 0, 0 }; - renderArea.extent = VkExtent2D { imageExtent.width, imageExtent.height }; + VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + attachmentInfo.imageView = pass->getDstView(); + attachmentInfo.imageLayout = dstLayout; + attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - VkRenderPassBeginInfo passInfo; - passInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - passInfo.pNext = nullptr; - passInfo.renderPass = passObjects.renderPass; - passInfo.framebuffer = passObjects.framebuffer; - passInfo.renderArea = renderArea; - passInfo.clearValueCount = 0; - passInfo.pClearValues = nullptr; + VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + renderingInfo.renderArea = VkRect2D { + VkOffset2D { 0, 0 }, + VkExtent2D { imageExtent.width, imageExtent.height } }; + renderingInfo.layerCount = pass->framebufferLayerCount(); + renderingInfo.colorAttachmentCount = 1; + renderingInfo.pColorAttachments = &attachmentInfo; - m_cmd->cmdBeginRenderPass(&passInfo, VK_SUBPASS_CONTENTS_INLINE); + m_cmd->cmdBeginRendering(&renderingInfo); // Bind pipeline DxvkMetaBlitPipeline pipeInfo = m_common->metaBlit().getPipeline( @@ -2598,20 +2679,16 @@ namespace dxvk { // Bind source image view VkDescriptorImageInfo descriptorImage; descriptorImage.sampler = m_common->metaBlit().getSampler(filter); - descriptorImage.imageView = passObjects.srcView; + descriptorImage.imageView = pass->getSrcView(); descriptorImage.imageLayout = srcLayout; - VkWriteDescriptorSet descriptorWrite; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.pNext = nullptr; + VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); descriptorWrite.dstBinding = 0; descriptorWrite.dstArrayElement = 0; descriptorWrite.descriptorCount = 1; descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; descriptorWrite.pImageInfo = &descriptorImage; - descriptorWrite.pBufferInfo = nullptr; - descriptorWrite.pTexelBufferView = nullptr; m_cmd->updateDescriptorSets(1, &descriptorWrite); m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, @@ -2638,12 +2715,12 @@ namespace dxvk { &pushConstants); m_cmd->cmdDraw(3, pushConstants.layerCount, 0, 0); - m_cmd->cmdEndRenderPass(); + m_cmd->cmdEndRendering(); // Add barriers and track image objects m_execBarriers.accessImage(dstImage, vk::makeSubresourceRange(region.dstSubresource), - dstImage->info().layout, + dstLayout, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, dstImage->info().layout, diff --git a/src/dxvk/dxvk_meta_blit.cpp b/src/dxvk/dxvk_meta_blit.cpp index 7956b2ed4..2cf0773f0 100644 --- a/src/dxvk/dxvk_meta_blit.cpp +++ b/src/dxvk/dxvk_meta_blit.cpp @@ -22,9 +22,7 @@ namespace dxvk { m_srcImage (srcImage), m_region (region), m_dstView (createDstView()), - m_srcView (createSrcView(mapping)), - m_renderPass (createRenderPass()), - m_framebuffer (createFramebuffer()) { + m_srcView (createSrcView(mapping)) { } @@ -32,13 +30,11 @@ namespace dxvk { DxvkMetaBlitRenderPass::~DxvkMetaBlitRenderPass() { m_vkd->vkDestroyImageView(m_vkd->device(), m_dstView, nullptr); m_vkd->vkDestroyImageView(m_vkd->device(), m_srcView, nullptr); - m_vkd->vkDestroyRenderPass(m_vkd->device(), m_renderPass, nullptr); - m_vkd->vkDestroyFramebuffer(m_vkd->device(), m_framebuffer, nullptr); } VkImageViewType DxvkMetaBlitRenderPass::viewType() const { - std::array viewTypes = {{ + static const std::array viewTypes = {{ VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_IMAGE_VIEW_TYPE_3D, @@ -71,16 +67,6 @@ namespace dxvk { } - DxvkMetaBlitPass DxvkMetaBlitRenderPass::pass() const { - DxvkMetaBlitPass result; - result.srcView = m_srcView; - result.dstView = m_dstView; - result.renderPass = m_renderPass; - result.framebuffer = m_framebuffer; - return result; - } - - VkImageView DxvkMetaBlitRenderPass::createDstView() { std::array viewTypes = {{ VK_IMAGE_VIEW_TYPE_1D_ARRAY, @@ -138,75 +124,8 @@ namespace dxvk { } - VkRenderPass DxvkMetaBlitRenderPass::createRenderPass() { - VkAttachmentDescription attachment; - attachment.flags = 0; - attachment.format = m_dstImage->info().format; - attachment.samples = m_dstImage->info().sampleCount; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment.initialLayout = m_dstImage->info().layout; - attachment.finalLayout = m_dstImage->info().layout; - - VkAttachmentReference attachmentRef; - attachmentRef.attachment = 0; - attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attachmentRef; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = 1; - info.pAttachments = &attachment; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = 0; - info.pDependencies = nullptr; - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaBlitRenderPass: Failed to create render pass"); - return result; - } - VkFramebuffer DxvkMetaBlitRenderPass::createFramebuffer() { - VkExtent3D extent = m_dstImage->mipLevelExtent(m_region.dstSubresource.mipLevel); - - VkFramebufferCreateInfo fboInfo; - fboInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - fboInfo.pNext = nullptr; - fboInfo.flags = 0; - fboInfo.renderPass = m_renderPass; - fboInfo.attachmentCount = 1; - fboInfo.pAttachments = &m_dstView; - fboInfo.width = extent.width; - fboInfo.height = extent.height; - fboInfo.layers = framebufferLayerCount(); - - VkFramebuffer result; - if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fboInfo, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaBlitRenderPass: Failed to create target framebuffer"); - return result; - } - - - - DxvkMetaBlitObjects::DxvkMetaBlitObjects(const DxvkDevice* device) : m_vkd (device->vkd()), m_samplerCopy (createSampler(VK_FILTER_NEAREST)), @@ -224,9 +143,6 @@ namespace dxvk { DxvkMetaBlitObjects::~DxvkMetaBlitObjects() { - for (const auto& pair : m_renderPasses) - m_vkd->vkDestroyRenderPass(m_vkd->device(), pair.second, nullptr); - for (const auto& pair : m_pipelines) { m_vkd->vkDestroyPipeline(m_vkd->device(), pair.second.pipeHandle, nullptr); m_vkd->vkDestroyPipelineLayout(m_vkd->device(), pair.second.pipeLayout, nullptr); @@ -272,23 +188,6 @@ namespace dxvk { } - VkRenderPass DxvkMetaBlitObjects::getRenderPass( - VkFormat viewFormat, - VkSampleCountFlagBits samples) { - DxvkMetaBlitRenderPassKey key; - key.viewFormat = viewFormat; - key.samples = samples; - - auto entry = m_renderPasses.find(key); - if (entry != m_renderPasses.end()) - return entry->second; - - VkRenderPass renderPass = this->createRenderPass(viewFormat, samples); - m_renderPasses.insert({ key, renderPass }); - return renderPass; - } - - VkSampler DxvkMetaBlitObjects::createSampler(VkFilter filter) const { VkSamplerCreateInfo info; info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; @@ -337,73 +236,18 @@ namespace dxvk { DxvkMetaBlitPipeline pipe; pipe.dsetLayout = this->createDescriptorSetLayout(key.viewType); pipe.pipeLayout = this->createPipelineLayout(pipe.dsetLayout); - pipe.pipeHandle = this->createPipeline(key.viewType, pipe.pipeLayout, - this->getRenderPass(key.viewFormat, key.samples), key.samples); + pipe.pipeHandle = this->createPipeline(pipe.pipeLayout, + key.viewType, key.viewFormat, key.samples); return pipe; } - VkRenderPass DxvkMetaBlitObjects::createRenderPass( - VkFormat format, - VkSampleCountFlagBits samples) const { - VkAttachmentDescription attachment; - attachment.flags = 0; - attachment.format = format; - attachment.samples = samples; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkAttachmentReference attachmentRef; - attachmentRef.attachment = 0; - attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attachmentRef; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = 1; - info.pAttachments = &attachment; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = 0; - info.pDependencies = nullptr; - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaBlitObjects: Failed to create render pass"); - return result; - } - - VkDescriptorSetLayout DxvkMetaBlitObjects::createDescriptorSetLayout( VkImageViewType viewType) const { - VkDescriptorSetLayoutBinding binding; - binding.binding = 0; - binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - binding.descriptorCount = 1; - binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - binding.pImmutableSamplers = nullptr; + VkDescriptorSetLayoutBinding binding = { 0, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT }; - VkDescriptorSetLayoutCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkDescriptorSetLayoutCreateInfo info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; info.bindingCount = 1; info.pBindings = &binding; @@ -416,15 +260,9 @@ namespace dxvk { VkPipelineLayout DxvkMetaBlitObjects::createPipelineLayout( VkDescriptorSetLayout descriptorSetLayout) const { - VkPushConstantRange pushRange; - pushRange.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - pushRange.offset = 0; - pushRange.size = sizeof(DxvkMetaBlitPushConstants); + VkPushConstantRange pushRange = { VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(DxvkMetaBlitPushConstants) }; - VkPipelineLayoutCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkPipelineLayoutCreateInfo info = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; info.setLayoutCount = 1; info.pSetLayouts = &descriptorSetLayout; info.pushConstantRangeCount = 1; @@ -438,156 +276,90 @@ namespace dxvk { VkPipeline DxvkMetaBlitObjects::createPipeline( - VkImageViewType imageViewType, VkPipelineLayout pipelineLayout, - VkRenderPass renderPass, + VkImageViewType imageViewType, + VkFormat format, VkSampleCountFlagBits samples) const { std::array stages; uint32_t stageCount = 0; - VkPipelineShaderStageCreateInfo& vsStage = stages[stageCount++]; - vsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vsStage.pNext = nullptr; - vsStage.flags = 0; - vsStage.stage = VK_SHADER_STAGE_VERTEX_BIT; - vsStage.module = m_shaderVert; - vsStage.pName = "main"; - vsStage.pSpecializationInfo = nullptr; + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_VERTEX_BIT, m_shaderVert, "main" }; if (m_shaderGeom) { - VkPipelineShaderStageCreateInfo& gsStage = stages[stageCount++]; - gsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - gsStage.pNext = nullptr; - gsStage.flags = 0; - gsStage.stage = VK_SHADER_STAGE_GEOMETRY_BIT; - gsStage.module = m_shaderGeom; - gsStage.pName = "main"; - gsStage.pSpecializationInfo = nullptr; + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_GEOMETRY_BIT, m_shaderGeom, "main" }; } - - VkPipelineShaderStageCreateInfo& psStage = stages[stageCount++]; - psStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - psStage.pNext = nullptr; - psStage.flags = 0; - psStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - psStage.module = VK_NULL_HANDLE; - psStage.pName = "main"; - psStage.pSpecializationInfo = nullptr; - + + VkShaderModule psModule = VK_NULL_HANDLE; + switch (imageViewType) { - case VK_IMAGE_VIEW_TYPE_1D_ARRAY: psStage.module = m_shaderFrag1D; break; - case VK_IMAGE_VIEW_TYPE_2D_ARRAY: psStage.module = m_shaderFrag2D; break; - case VK_IMAGE_VIEW_TYPE_3D: psStage.module = m_shaderFrag3D; break; + case VK_IMAGE_VIEW_TYPE_1D_ARRAY: psModule = m_shaderFrag1D; break; + case VK_IMAGE_VIEW_TYPE_2D_ARRAY: psModule = m_shaderFrag2D; break; + case VK_IMAGE_VIEW_TYPE_3D: psModule = m_shaderFrag3D; break; default: throw DxvkError("DxvkMetaBlitObjects: Invalid view type"); } + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_FRAGMENT_BIT, psModule, "main" }; + std::array dynStates = {{ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, }}; - VkPipelineDynamicStateCreateInfo dynState; - dynState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynState.pNext = nullptr; - dynState.flags = 0; - dynState.dynamicStateCount = dynStates.size(); - dynState.pDynamicStates = dynStates.data(); + VkPipelineDynamicStateCreateInfo dynState = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + dynState.dynamicStateCount = dynStates.size(); + dynState.pDynamicStates = dynStates.data(); - VkPipelineVertexInputStateCreateInfo viState; - viState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - viState.pNext = nullptr; - viState.flags = 0; - viState.vertexBindingDescriptionCount = 0; - viState.pVertexBindingDescriptions = nullptr; - viState.vertexAttributeDescriptionCount = 0; - viState.pVertexAttributeDescriptions = nullptr; + VkPipelineVertexInputStateCreateInfo viState = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; - VkPipelineInputAssemblyStateCreateInfo iaState; - iaState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - iaState.pNext = nullptr; - iaState.flags = 0; - iaState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + VkPipelineInputAssemblyStateCreateInfo iaState = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; + iaState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; iaState.primitiveRestartEnable = VK_FALSE; - VkPipelineViewportStateCreateInfo vpState; - vpState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - vpState.pNext = nullptr; - vpState.flags = 0; - vpState.viewportCount = 1; - vpState.pViewports = nullptr; - vpState.scissorCount = 1; - vpState.pScissors = nullptr; + VkPipelineViewportStateCreateInfo vpState = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; + vpState.viewportCount = 1; + vpState.scissorCount = 1; - VkPipelineRasterizationStateCreateInfo rsState; - rsState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rsState.pNext = nullptr; - rsState.flags = 0; - rsState.depthClampEnable = VK_TRUE; - rsState.rasterizerDiscardEnable = VK_FALSE; - rsState.polygonMode = VK_POLYGON_MODE_FILL; - rsState.cullMode = VK_CULL_MODE_NONE; - rsState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rsState.depthBiasEnable = VK_FALSE; - rsState.depthBiasConstantFactor = 0.0f; - rsState.depthBiasClamp = 0.0f; - rsState.depthBiasSlopeFactor = 0.0f; - rsState.lineWidth = 1.0f; + VkPipelineRasterizationStateCreateInfo rsState = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; + rsState.polygonMode = VK_POLYGON_MODE_FILL; + rsState.cullMode = VK_CULL_MODE_NONE; + rsState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + rsState.lineWidth = 1.0f; uint32_t msMask = 0xFFFFFFFF; - VkPipelineMultisampleStateCreateInfo msState; - msState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - msState.pNext = nullptr; - msState.flags = 0; + VkPipelineMultisampleStateCreateInfo msState = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; msState.rasterizationSamples = samples; - msState.sampleShadingEnable = VK_FALSE; - msState.minSampleShading = 1.0f; - msState.pSampleMask = &msMask; - msState.alphaToCoverageEnable = VK_FALSE; - msState.alphaToOneEnable = VK_FALSE; + msState.pSampleMask = &msMask; - VkPipelineColorBlendAttachmentState cbAttachment; - cbAttachment.blendEnable = VK_FALSE; - cbAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - cbAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; - cbAttachment.colorBlendOp = VK_BLEND_OP_ADD; - cbAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - cbAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - cbAttachment.alphaBlendOp = VK_BLEND_OP_ADD; - cbAttachment.colorWriteMask = + VkPipelineColorBlendAttachmentState cbAttachment = { }; + cbAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - VkPipelineColorBlendStateCreateInfo cbState; - cbState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - cbState.pNext = nullptr; - cbState.flags = 0; - cbState.logicOpEnable = VK_FALSE; - cbState.logicOp = VK_LOGIC_OP_NO_OP; + VkPipelineColorBlendStateCreateInfo cbState = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; cbState.attachmentCount = 1; cbState.pAttachments = &cbAttachment; - - for (uint32_t i = 0; i < 4; i++) - cbState.blendConstants[i] = 0.0f; - - VkGraphicsPipelineCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + + VkPipelineRenderingCreateInfoKHR rtState = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + rtState.colorAttachmentCount = 1; + rtState.pColorAttachmentFormats = &format; + + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &rtState }; info.stageCount = stageCount; info.pStages = stages.data(); info.pVertexInputState = &viState; info.pInputAssemblyState = &iaState; - info.pTessellationState = nullptr; info.pViewportState = &vpState; info.pRasterizationState = &rsState; info.pMultisampleState = &msState; info.pColorBlendState = &cbState; - info.pDepthStencilState = nullptr; info.pDynamicState = &dynState; info.layout = pipelineLayout; - info.renderPass = renderPass; - info.subpass = 0; - info.basePipelineHandle = VK_NULL_HANDLE; info.basePipelineIndex = -1; VkPipeline result = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_meta_blit.h b/src/dxvk/dxvk_meta_blit.h index 28f8616c5..32a1eab0d 100644 --- a/src/dxvk/dxvk_meta_blit.h +++ b/src/dxvk/dxvk_meta_blit.h @@ -87,20 +87,6 @@ namespace dxvk { }; - /** - * \brief Blit framebuffer - * - * Stores the image views and framebuffer - * handle used to generate one mip level. - */ - struct DxvkMetaBlitPass { - VkImageView srcView; - VkImageView dstView; - VkRenderPass renderPass; - VkFramebuffer framebuffer; - }; - - /** * \brief Blit render pass * @@ -126,7 +112,8 @@ namespace dxvk { uint32_t framebufferLayerIndex() const; uint32_t framebufferLayerCount() const; - DxvkMetaBlitPass pass() const; + VkImageView getDstView() const { return m_dstView; } + VkImageView getSrcView() const { return m_srcView; } private: @@ -137,15 +124,10 @@ namespace dxvk { VkImageBlit m_region; VkImageView m_dstView; VkImageView m_srcView; - VkRenderPass m_renderPass; - VkFramebuffer m_framebuffer; VkImageView createDstView(); VkImageView createSrcView(const VkComponentMapping& mapping); - VkRenderPass createRenderPass(); - VkFramebuffer createFramebuffer(); - }; @@ -201,20 +183,11 @@ namespace dxvk { dxvk::mutex m_mutex; - std::unordered_map< - DxvkMetaBlitRenderPassKey, - VkRenderPass, - DxvkHash, DxvkEq> m_renderPasses; - std::unordered_map< DxvkMetaBlitPipelineKey, DxvkMetaBlitPipeline, DxvkHash, DxvkEq> m_pipelines; - VkRenderPass getRenderPass( - VkFormat viewFormat, - VkSampleCountFlagBits samples); - VkSampler createSampler( VkFilter filter) const; @@ -224,10 +197,6 @@ namespace dxvk { DxvkMetaBlitPipeline createPipeline( const DxvkMetaBlitPipelineKey& key); - VkRenderPass createRenderPass( - VkFormat format, - VkSampleCountFlagBits samples) const; - VkDescriptorSetLayout createDescriptorSetLayout( VkImageViewType viewType) const; @@ -235,9 +204,9 @@ namespace dxvk { VkDescriptorSetLayout descriptorSetLayout) const; VkPipeline createPipeline( - VkImageViewType imageViewType, VkPipelineLayout pipelineLayout, - VkRenderPass renderPass, + VkImageViewType imageViewType, + VkFormat format, VkSampleCountFlagBits samples) const; }; diff --git a/src/dxvk/dxvk_meta_mipgen.cpp b/src/dxvk/dxvk_meta_mipgen.cpp index 297da07e7..46c2dd73c 100644 --- a/src/dxvk/dxvk_meta_mipgen.cpp +++ b/src/dxvk/dxvk_meta_mipgen.cpp @@ -5,7 +5,7 @@ namespace dxvk { DxvkMetaMipGenRenderPass::DxvkMetaMipGenRenderPass( const Rc& vkd, const Rc& view) - : m_vkd(vkd), m_view(view), m_renderPass(createRenderPass()) { + : m_vkd(vkd), m_view(view) { // Determine view type based on image type const std::array, 3> viewTypes = {{ { VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_1D_ARRAY }, @@ -20,22 +20,19 @@ namespace dxvk { m_passes.resize(view->info().numLevels - 1); for (uint32_t i = 0; i < m_passes.size(); i++) - m_passes.at(i) = this->createFramebuffer(i); + m_passes[i] = createViews(i); } DxvkMetaMipGenRenderPass::~DxvkMetaMipGenRenderPass() { - for (const auto& pass : m_passes) { - m_vkd->vkDestroyFramebuffer(m_vkd->device(), pass.framebuffer, nullptr); - m_vkd->vkDestroyImageView(m_vkd->device(), pass.dstView, nullptr); - m_vkd->vkDestroyImageView(m_vkd->device(), pass.srcView, nullptr); + for (const auto& views : m_passes) { + m_vkd->vkDestroyImageView(m_vkd->device(), views.src, nullptr); + m_vkd->vkDestroyImageView(m_vkd->device(), views.dst, nullptr); } - - m_vkd->vkDestroyRenderPass(m_vkd->device(), m_renderPass, nullptr); } - VkExtent3D DxvkMetaMipGenRenderPass::passExtent(uint32_t passId) const { + VkExtent3D DxvkMetaMipGenRenderPass::computePassExtent(uint32_t passId) const { VkExtent3D extent = m_view->mipLevelExtent(passId + 1); if (m_view->imageInfo().type != VK_IMAGE_TYPE_3D) @@ -45,81 +42,14 @@ namespace dxvk { } - VkRenderPass DxvkMetaMipGenRenderPass::createRenderPass() const { - std::array subpassDeps = {{ - { VK_SUBPASS_EXTERNAL, 0, - m_view->imageInfo().stages, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 0 }, - { 0, VK_SUBPASS_EXTERNAL, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - m_view->imageInfo().stages, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - m_view->imageInfo().access, 0 }, - }}; - - VkAttachmentDescription attachment; - attachment.flags = 0; - attachment.format = m_view->info().format; - attachment.samples = VK_SAMPLE_COUNT_1_BIT; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - attachment.finalLayout = m_view->imageInfo().layout; - - VkAttachmentReference attachmentRef; - attachmentRef.attachment = 0; - attachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attachmentRef; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = 1; - info.pAttachments = &attachment; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = subpassDeps.size(); - info.pDependencies = subpassDeps.data(); - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create render pass"); - return result; - } - - - DxvkMetaBlitPass DxvkMetaMipGenRenderPass::createFramebuffer(uint32_t pass) const { - DxvkMetaBlitPass result; - result.srcView = VK_NULL_HANDLE; - result.dstView = VK_NULL_HANDLE; - result.renderPass = m_renderPass; - result.framebuffer = VK_NULL_HANDLE; - - // Common image view info - VkImageViewCreateInfo viewInfo; - viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewInfo.pNext = nullptr; - viewInfo.flags = 0; - viewInfo.image = m_view->imageHandle(); - viewInfo.format = m_view->info().format; - viewInfo.components = { - VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }; + DxvkMetaMipGenRenderPass::PassViews DxvkMetaMipGenRenderPass::createViews(uint32_t pass) const { + PassViews result = { }; + + VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; + + VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo }; + viewInfo.image = m_view->imageHandle(); + viewInfo.format = m_view->info().format; // Create source image view, which points to // the one mip level we're going to sample. @@ -130,10 +60,11 @@ namespace dxvk { srcSubresources.baseArrayLayer = m_view->info().minLayer; srcSubresources.layerCount = m_view->info().numLayers; - viewInfo.viewType = m_srcViewType; + usageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + viewInfo.viewType = m_srcViewType; viewInfo.subresourceRange = srcSubresources; - - if (m_vkd->vkCreateImageView(m_vkd->device(), &viewInfo, nullptr, &result.srcView) != VK_SUCCESS) + + if (m_vkd->vkCreateImageView(m_vkd->device(), &viewInfo, nullptr, &result.src) != VK_SUCCESS) throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create source image view"); // Create destination image view, which points @@ -147,34 +78,19 @@ namespace dxvk { if (m_view->imageInfo().type != VK_IMAGE_TYPE_3D) { dstSubresources.baseArrayLayer = m_view->info().minLayer; - dstSubresources.layerCount = m_view->info().numLayers; + dstSubresources.layerCount = m_view->info().numLayers; } else { dstSubresources.baseArrayLayer = 0; - dstSubresources.layerCount = dstExtent.depth; + dstSubresources.layerCount = dstExtent.depth; } - viewInfo.viewType = m_dstViewType; + usageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + viewInfo.viewType = m_dstViewType; viewInfo.subresourceRange = dstSubresources; - if (m_vkd->vkCreateImageView(m_vkd->device(), &viewInfo, nullptr, &result.dstView) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create target image view"); - - // Create framebuffer using the destination - // image view as its color attachment. - VkFramebufferCreateInfo fboInfo; - fboInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - fboInfo.pNext = nullptr; - fboInfo.flags = 0; - fboInfo.renderPass = m_renderPass; - fboInfo.attachmentCount = 1; - fboInfo.pAttachments = &result.dstView; - fboInfo.width = dstExtent.width; - fboInfo.height = dstExtent.height; - fboInfo.layers = dstSubresources.layerCount; - - if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fboInfo, nullptr, &result.framebuffer) != VK_SUCCESS) - throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create target framebuffer"); - + if (m_vkd->vkCreateImageView(m_vkd->device(), &viewInfo, nullptr, &result.dst) != VK_SUCCESS) + throw DxvkError("DxvkMetaMipGenRenderPass: Failed to create destination image view"); + return result; } diff --git a/src/dxvk/dxvk_meta_mipgen.h b/src/dxvk/dxvk_meta_mipgen.h index a5d2d60f9..e473816d1 100644 --- a/src/dxvk/dxvk_meta_mipgen.h +++ b/src/dxvk/dxvk_meta_mipgen.h @@ -23,14 +23,6 @@ namespace dxvk { ~DxvkMetaMipGenRenderPass(); - /** - * \brief Render pass handle - * \returns Render pass handle - */ - VkRenderPass renderPass() const { - return m_renderPass; - } - /** * \brief Source image view type * @@ -38,7 +30,7 @@ namespace dxvk { * resource descriptor needs to have. * \returns Source image view type */ - VkImageViewType viewType() const { + VkImageViewType getSrcViewType() const { return m_srcViewType; } @@ -48,45 +40,109 @@ namespace dxvk { * Number of mip levels to generate. * \returns Render pass count */ - uint32_t passCount() const { + uint32_t getPassCount() const { return m_passes.size(); } /** - * \brief Framebuffer handles + * \brief Source image view * - * Returns image view and framebuffer handles - * required to generate a single mip level. * \param [in] pass Render pass index - * \returns Object handles for the given pass + * \returns Source image view handle for the given pass */ - DxvkMetaBlitPass pass(uint32_t passId) const { - return m_passes.at(passId); + VkImageView getSrcView(uint32_t passId) const { + return m_passes.at(passId).src; } - + + /** + * \brief Destination image view + * + * \param [in] pass Render pass index + * \returns Destination image view handle for the given pass + */ + VkImageView getDstView(uint32_t passId) const { + return m_passes.at(passId).dst; + } + + /** + * \brief Returns subresource that will only be read + * \returns Top level of the image view + */ + VkImageSubresourceRange getTopSubresource() const { + VkImageSubresourceRange sr = m_view->imageSubresources(); + sr.levelCount = 1; + return sr; + } + + /** + * \brief Returns subresource that will only be written + * \returns Top level of the image view + */ + VkImageSubresourceRange getBottomSubresource() const { + VkImageSubresourceRange sr = m_view->imageSubresources(); + sr.baseMipLevel += sr.levelCount - 1; + sr.levelCount = 1; + return sr; + } + + /** + * \brief Returns all subresources that will be written + * \returns All mip levels except the top level + */ + VkImageSubresourceRange getAllTargetSubresources() const { + VkImageSubresourceRange sr = m_view->imageSubresources(); + sr.baseMipLevel += 1; + sr.levelCount -= 1; + return sr; + } + + /** + * \brief Returns all subresources that will be read + * \returns All mip levels except the bottom level + */ + VkImageSubresourceRange getAllSourceSubresources() const { + VkImageSubresourceRange sr = m_view->imageSubresources(); + sr.levelCount -= 1; + return sr; + } + + /** + * \brief Returns subresource read in a given pass + * + * \param [in] pass Pass index + * \returns The source subresource + */ + VkImageSubresourceRange getSourceSubresource(uint32_t pass) const { + VkImageSubresourceRange sr = m_view->imageSubresources(); + sr.baseMipLevel += pass; + sr.levelCount = 1; + return sr; + } + /** * \brief Framebuffer size for a given pass * * Stores the width, height, and layer count * of the framebuffer for the given pass ID. */ - VkExtent3D passExtent(uint32_t passId) const; + VkExtent3D computePassExtent(uint32_t passId) const; private: - + + struct PassViews { + VkImageView src; + VkImageView dst; + }; + Rc m_vkd; Rc m_view; - VkRenderPass m_renderPass; - VkImageViewType m_srcViewType; VkImageViewType m_dstViewType; - std::vector m_passes; + std::vector m_passes; - VkRenderPass createRenderPass() const; - - DxvkMetaBlitPass createFramebuffer(uint32_t pass) const; + PassViews createViews(uint32_t pass) const; }; From 96e102beff04317b2d0463a774f5b083e6bcf748 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 2 Jul 2022 03:32:31 +0200 Subject: [PATCH 0111/1348] [dxvk] Use dynamic rendering for copies Significantly reworks framebuffer copies as well. We'll no longer create dummy samplers to work around glslang versions not supporting texture descriptors without samplers, and copyImageFb was cleaned up to factor out the part where a temporary image is created. --- src/dxvk/dxvk_context.cpp | 349 ++++++------ src/dxvk/dxvk_context.h | 10 + src/dxvk/dxvk_meta_copy.cpp | 531 +++++------------- src/dxvk/dxvk_meta_copy.h | 58 +- src/dxvk/shaders/dxvk_copy_color_1d.frag | 4 +- src/dxvk/shaders/dxvk_copy_color_2d.frag | 4 +- src/dxvk/shaders/dxvk_copy_color_ms.frag | 4 +- src/dxvk/shaders/dxvk_copy_depth_1d.frag | 4 +- src/dxvk/shaders/dxvk_copy_depth_2d.frag | 4 +- src/dxvk/shaders/dxvk_copy_depth_ms.frag | 4 +- .../shaders/dxvk_copy_depth_stencil_1d.frag | 7 +- .../shaders/dxvk_copy_depth_stencil_2d.frag | 5 +- .../shaders/dxvk_copy_depth_stencil_ms.frag | 5 +- 13 files changed, 387 insertions(+), 602 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 66399112d..3192b6453 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -3232,6 +3232,82 @@ namespace dxvk { VkImageSubresourceLayers srcSubresource, VkOffset3D srcOffset, VkExtent3D extent) { + VkFormat viewFormat = m_common->metaCopy().getCopyDestinationFormat( + dstSubresource.aspectMask, + srcSubresource.aspectMask, + srcImage->info().format); + + if (!viewFormat) { + Logger::err("DxvkContext: copyImageFb: Unsupported format"); + return; + } + + // Usually we should be able to draw directly to the destination image, + // but in some cases this might not be possible, e.g. if when copying + // from something like D32_SFLOAT to RGBA8_UNORM. In those situations, + // create a temporary image to draw to, and then copy to the actual + // destination image using a regular Vulkan transfer function. + bool useDirectCopy = (dstImage->info().usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) + && (dstImage->isViewCompatible(viewFormat)); + + if (useDirectCopy) { + this->copyImageFbDirect( + dstImage, dstSubresource, dstOffset, viewFormat, + srcImage, srcSubresource, srcOffset, extent); + } else { + DxvkImageCreateInfo imageInfo = dstImage->info(); + imageInfo.format = viewFormat; + imageInfo.flags = 0; + imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + imageInfo.extent = extent; + imageInfo.numLayers = dstSubresource.layerCount; + imageInfo.mipLevels = 1; + imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageInfo.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + imageInfo.stages = VK_PIPELINE_STAGE_TRANSFER_BIT; + imageInfo.access = VK_ACCESS_TRANSFER_READ_BIT; + imageInfo.viewFormatCount = 0; + + if (dstImage->formatInfo()->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { + imageInfo.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + imageInfo.stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + imageInfo.access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + } else { + imageInfo.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + imageInfo.stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT + | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + imageInfo.access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + } + + Rc tmpImage = m_device->createImage(imageInfo, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + VkImageSubresourceLayers tmpSubresource = dstSubresource; + tmpSubresource.mipLevel = 0; + tmpSubresource.baseArrayLayer = 0; + + VkOffset3D tmpOffset = { 0, 0, 0 }; + + this->copyImageFbDirect( + tmpImage, tmpSubresource, tmpOffset, viewFormat, + srcImage, srcSubresource, srcOffset, extent); + + this->copyImageHw( + dstImage, dstSubresource, dstOffset, + tmpImage, tmpSubresource, tmpOffset, extent); + } + } + + + void DxvkContext::copyImageFbDirect( + const Rc& dstImage, + VkImageSubresourceLayers dstSubresource, + VkOffset3D dstOffset, + VkFormat dstFormat, + const Rc& srcImage, + VkImageSubresourceLayers srcSubresource, + VkOffset3D srcOffset, + VkExtent3D extent) { this->invalidateState(); auto dstSubresourceRange = vk::makeSubresourceRange(dstSubresource); @@ -3241,24 +3317,33 @@ namespace dxvk { || m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); - // Source image needs to be readable - if (!(srcImage->info().usage & VK_IMAGE_USAGE_SAMPLED_BIT)) { - Logger::err("DxvkContext: copyImageFb: Source image not readable"); - return; + // Flag used to determine whether we can do an UNDEFINED transition + bool doDiscard = dstImage->isFullSubresource(dstSubresource, extent); + + // This function can process both color and depth-stencil images, so + // some things change a lot depending on the destination image type + VkPipelineStageFlags dstStages; + VkAccessFlags dstAccess; + VkImageLayout dstLayout; + + if (dstSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { + dstLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + dstStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dstAccess = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + if (!doDiscard) + dstAccess |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + } else { + dstLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + dstStages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT + | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + dstAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + + if (!doDiscard) + dstAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; } - // Render target format to use for this copy - VkFormat viewFormat = m_common->metaCopy().getCopyDestinationFormat( - dstSubresource.aspectMask, - srcSubresource.aspectMask, - srcImage->info().format); - - if (viewFormat == VK_FORMAT_UNDEFINED) { - Logger::err("DxvkContext: copyImageFb: Unsupported format"); - return; - } - - // We might have to transition the source image layout + // Might have to transition source image as well VkImageLayout srcLayout = (srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) ? srcImage->pickLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) : srcImage->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL); @@ -3271,183 +3356,131 @@ namespace dxvk { srcLayout, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); - - m_execAcquires.recordCommands(m_cmd); } - // In some cases, we may be able to render to the destination - // image directly, which is faster than using a temporary image - VkImageUsageFlagBits tgtUsage = (dstSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) - ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT - : VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - - bool useDirectRender = (dstImage->isViewCompatible(viewFormat)) - && (dstImage->info().usage & tgtUsage); - - // If needed, create a temporary render target for the copy - Rc tgtImage; - VkImageSubresourceLayers tgtSubresource = dstSubresource; - VkOffset3D tgtOffset = dstOffset; - - if (!useDirectRender) { - DxvkImageCreateInfo info; - info.type = dstImage->info().type; - info.format = viewFormat; - info.flags = 0; - info.sampleCount = dstImage->info().sampleCount; - info.extent = extent; - info.numLayers = dstSubresource.layerCount; - info.mipLevels = 1; - info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | tgtUsage; - info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT; - info.access = VK_ACCESS_TRANSFER_READ_BIT; - info.tiling = VK_IMAGE_TILING_OPTIMAL; - info.layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - - tgtImage = m_device->createImage(info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - - tgtSubresource.mipLevel = 0; - tgtSubresource.baseArrayLayer = 0; - - tgtOffset = { 0, 0, 0 }; - } else { - tgtImage = dstImage; + if (dstImage->info().layout != dstLayout) { + m_execAcquires.accessImage( + dstImage, dstSubresourceRange, + doDiscard ? VK_IMAGE_LAYOUT_UNDEFINED + : dstImage->info().layout, + dstImage->info().stages, 0, + dstLayout, dstStages, dstAccess); } - + + m_execAcquires.recordCommands(m_cmd); + // Create source and destination image views - VkImageViewType viewType = dstImage->info().type == VK_IMAGE_TYPE_1D - ? VK_IMAGE_VIEW_TYPE_1D_ARRAY - : VK_IMAGE_VIEW_TYPE_2D_ARRAY; + Rc views = new DxvkMetaCopyViews(m_device->vkd(), + dstImage, dstSubresource, dstFormat, + srcImage, srcSubresource); - DxvkImageViewCreateInfo tgtViewInfo; - tgtViewInfo.type = viewType; - tgtViewInfo.format = viewFormat; - tgtViewInfo.usage = tgtUsage; - tgtViewInfo.aspect = tgtSubresource.aspectMask; - tgtViewInfo.minLevel = tgtSubresource.mipLevel; - tgtViewInfo.numLevels = 1; - tgtViewInfo.minLayer = tgtSubresource.baseArrayLayer; - tgtViewInfo.numLayers = tgtSubresource.layerCount; + // Create pipeline for the copy operation + DxvkMetaCopyPipeline pipeInfo = m_common->metaCopy().getPipeline( + views->getSrcViewType(), dstFormat, dstImage->info().sampleCount); - DxvkImageViewCreateInfo srcViewInfo; - srcViewInfo.type = viewType; - srcViewInfo.format = srcImage->info().format; - srcViewInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; - srcViewInfo.aspect = srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_COLOR_BIT); - srcViewInfo.minLevel = srcSubresource.mipLevel; - srcViewInfo.numLevels = 1; - srcViewInfo.minLayer = srcSubresource.baseArrayLayer; - srcViewInfo.numLayers = srcSubresource.layerCount; + // Create and initialize descriptor set + VkDescriptorSet descriptorSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); - Rc tgtImageView = m_device->createImageView(tgtImage, tgtViewInfo); - Rc srcImageView = m_device->createImageView(srcImage, srcViewInfo); - Rc srcStencilView; + std::array descriptorImages = {{ + { VK_NULL_HANDLE, views->getSrcView(), srcLayout }, + { VK_NULL_HANDLE, views->getSrcStencilView(), srcLayout }, + }}; - if (srcSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { - srcViewInfo.aspect = VK_IMAGE_ASPECT_STENCIL_BIT; - srcStencilView = m_device->createImageView(srcImage, srcViewInfo); + std::array descriptorWrites; + + for (uint32_t i = 0; i < descriptorWrites.size(); i++) { + descriptorWrites[i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + descriptorWrites[i].dstSet = descriptorSet; + descriptorWrites[i].dstBinding = i; + descriptorWrites[i].descriptorCount = 1; + descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + descriptorWrites[i].pImageInfo = &descriptorImages[i]; } - // Create framebuffer and pipeline for the copy - Rc fb = new DxvkMetaCopyRenderPass( - m_device->vkd(), tgtImageView, srcImageView, srcStencilView, - tgtImage->isFullSubresource(tgtSubresource, extent)); - - auto pipeInfo = m_common->metaCopy().getPipeline( - viewType, viewFormat, tgtImage->info().sampleCount); - - VkDescriptorImageInfo descriptorImage; - descriptorImage.sampler = VK_NULL_HANDLE; - descriptorImage.imageView = srcImageView->handle(); - descriptorImage.imageLayout = srcLayout; + m_cmd->updateDescriptorSets( + descriptorWrites.size(), + descriptorWrites.data()); - VkWriteDescriptorSet descriptorWrite; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.pNext = nullptr; - descriptorWrite.dstBinding = 0; - descriptorWrite.dstArrayElement = 0; - descriptorWrite.descriptorCount = 1; - descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptorWrite.pImageInfo = &descriptorImage; - descriptorWrite.pBufferInfo = nullptr; - descriptorWrite.pTexelBufferView = nullptr; - - descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); - m_cmd->updateDescriptorSets(1, &descriptorWrite); - - if (srcSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) { - descriptorImage.imageView = srcStencilView->handle(); - descriptorWrite.dstBinding = 1; - m_cmd->updateDescriptorSets(1, &descriptorWrite); - } - + // Set up render state VkViewport viewport; - viewport.x = float(tgtOffset.x); - viewport.y = float(tgtOffset.y); - viewport.width = float(extent.width); - viewport.height = float(extent.height); + viewport.x = float(dstOffset.x); + viewport.y = float(dstOffset.y); + viewport.width = float(extent.width); + viewport.height = float(extent.height); viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; VkRect2D scissor; - scissor.offset = { tgtOffset.x, tgtOffset.y }; - scissor.extent = { extent.width, extent.height }; + scissor.offset = { dstOffset.x, dstOffset.y }; + scissor.extent = { extent.width, extent.height }; - VkRenderPassBeginInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - info.pNext = nullptr; - info.renderPass = fb->renderPass(); - info.framebuffer = fb->framebuffer(); - info.renderArea.offset = { 0, 0 }; - info.renderArea.extent = { - tgtImage->mipLevelExtent(tgtSubresource.mipLevel).width, - tgtImage->mipLevelExtent(tgtSubresource.mipLevel).height }; - info.clearValueCount = 0; - info.pClearValues = nullptr; + VkExtent3D mipExtent = dstImage->mipLevelExtent(dstSubresource.mipLevel); + + VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + attachmentInfo.imageView = views->getDstView(); + attachmentInfo.imageLayout = dstLayout; + attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + if (doDiscard) + attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + + VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + renderingInfo.renderArea.offset = VkOffset2D { 0, 0 }; + renderingInfo.renderArea.extent = VkExtent2D { mipExtent.width, mipExtent.height }; + renderingInfo.layerCount = dstSubresource.layerCount; + + VkImageAspectFlags dstAspects = dstImage->formatInfo()->aspectMask; + + if (dstAspects & VK_IMAGE_ASPECT_COLOR_BIT) { + renderingInfo.colorAttachmentCount = 1; + renderingInfo.pColorAttachments = &attachmentInfo; + } else { + if (dstAspects & VK_IMAGE_ASPECT_DEPTH_BIT) + renderingInfo.pDepthAttachment = &attachmentInfo; + if (dstAspects & VK_IMAGE_ASPECT_STENCIL_BIT) + renderingInfo.pStencilAttachment = &attachmentInfo; + } // Perform the actual copy operation - m_cmd->cmdBeginRenderPass(&info, VK_SUBPASS_CONTENTS_INLINE); + m_cmd->cmdBeginRendering(&renderingInfo); m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle); m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeInfo.pipeLayout, descriptorWrite.dstSet, 0, nullptr); + pipeInfo.pipeLayout, descriptorSet, 0, nullptr); m_cmd->cmdSetViewport(0, 1, &viewport); m_cmd->cmdSetScissor (0, 1, &scissor); VkOffset2D srcCoordOffset = { - srcOffset.x - tgtOffset.x, - srcOffset.y - tgtOffset.y }; + srcOffset.x - dstOffset.x, + srcOffset.y - dstOffset.y }; m_cmd->cmdPushConstants(pipeInfo.pipeLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(srcCoordOffset), &srcCoordOffset); - m_cmd->cmdDraw(3, tgtSubresource.layerCount, 0, 0); - m_cmd->cmdEndRenderPass(); + m_cmd->cmdDraw(3, dstSubresource.layerCount, 0, 0); + m_cmd->cmdEndRendering(); - if (srcLayout != srcImage->info().layout) { - m_execBarriers.accessImage( - srcImage, srcSubresourceRange, srcLayout, - srcImage->info().stages, - srcImage->info().access, - srcImage->info().layout, - srcImage->info().stages, - srcImage->info().access); - } + m_execBarriers.accessImage( + srcImage, srcSubresourceRange, srcLayout, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_SHADER_READ_BIT, + srcImage->info().layout, + srcImage->info().stages, + srcImage->info().access); - m_cmd->trackResource(tgtImage); + m_execBarriers.accessImage( + dstImage, dstSubresourceRange, + dstLayout, dstStages, dstAccess, + dstImage->info().layout, + dstImage->info().stages, + dstImage->info().access); + + m_cmd->trackResource(dstImage); m_cmd->trackResource(srcImage); - m_cmd->trackResource(fb); - - // If necessary, copy the temporary image - // to the original destination image - if (!useDirectRender) { - this->copyImageHw( - dstImage, dstSubresource, dstOffset, - tgtImage, tgtSubresource, tgtOffset, - extent); - } + m_cmd->trackResource(views); } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 443ba8640..de29f3c22 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1224,6 +1224,16 @@ namespace dxvk { VkOffset3D srcOffset, VkExtent3D extent); + void copyImageFbDirect( + const Rc& dstImage, + VkImageSubresourceLayers dstSubresource, + VkOffset3D dstOffset, + VkFormat dstFormat, + const Rc& srcImage, + VkImageSubresourceLayers srcSubresource, + VkOffset3D srcOffset, + VkExtent3D extent); + bool copyImageClear( const Rc& dstImage, VkImageSubresourceLayers dstSubresource, diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index ed79bb4ae..6f1bdf234 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -18,143 +18,68 @@ namespace dxvk { - DxvkMetaCopyRenderPass::DxvkMetaCopyRenderPass( - const Rc& vkd, - const Rc& dstImageView, - const Rc& srcImageView, - const Rc& srcStencilView, - bool discardDst) - : m_vkd (vkd), - m_dstImageView (dstImageView), - m_srcImageView (srcImageView), - m_srcStencilView(srcStencilView), - m_renderPass (createRenderPass(discardDst)), - m_framebuffer (createFramebuffer()) { + DxvkMetaCopyViews::DxvkMetaCopyViews( + const Rc& vkd, + const Rc& dstImage, + const VkImageSubresourceLayers& dstSubresources, + VkFormat dstFormat, + const Rc& srcImage, + const VkImageSubresourceLayers& srcSubresources) + : m_vkd(vkd) { + VkImageAspectFlags dstAspects = dstImage->formatInfo()->aspectMask; + VkImageAspectFlags srcAspects = srcImage->formatInfo()->aspectMask; + // We don't support 3D here, so we can safely ignore that case + m_dstViewType = dstImage->info().type == VK_IMAGE_TYPE_1D + ? VK_IMAGE_VIEW_TYPE_1D_ARRAY : VK_IMAGE_VIEW_TYPE_2D_ARRAY; + m_srcViewType = srcImage->info().type == VK_IMAGE_TYPE_1D + ? VK_IMAGE_VIEW_TYPE_1D_ARRAY : VK_IMAGE_VIEW_TYPE_2D_ARRAY; + + VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; + usageInfo.usage = (dstAspects & VK_IMAGE_ASPECT_COLOR_BIT) + ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT + : VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + // Create destination view + VkImageViewCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo }; + info.image = dstImage->handle(); + info.viewType = m_dstViewType; + info.format = dstFormat; + info.subresourceRange = vk::makeSubresourceRange(dstSubresources); + + if ((m_vkd->vkCreateImageView(m_vkd->device(), &info, nullptr, &m_dstImageView))) + throw DxvkError("DxvkMetaCopyViews: Failed to create destination image view"); + + // Create source image views + usageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + + info.image = srcImage->handle(); + info.viewType = m_srcViewType; + info.format = srcImage->info().format; + info.subresourceRange = vk::makeSubresourceRange(srcSubresources); + info.subresourceRange.aspectMask = srcAspects & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT); + + if ((m_vkd->vkCreateImageView(m_vkd->device(), &info, nullptr, &m_srcImageView))) + throw DxvkError("DxvkMetaCopyViews: Failed to create source image view"); + + if (srcAspects & VK_IMAGE_ASPECT_STENCIL_BIT) { + info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; + + if ((m_vkd->vkCreateImageView(m_vkd->device(), &info, nullptr, &m_srcStencilView))) + throw DxvkError("DxvkMetaCopyViews: Failed to create source stencil view"); + } } - DxvkMetaCopyRenderPass::~DxvkMetaCopyRenderPass() { - m_vkd->vkDestroyFramebuffer(m_vkd->device(), m_framebuffer, nullptr); - m_vkd->vkDestroyRenderPass (m_vkd->device(), m_renderPass, nullptr); + DxvkMetaCopyViews::~DxvkMetaCopyViews() { + m_vkd->vkDestroyImageView(m_vkd->device(), m_dstImageView, nullptr); + m_vkd->vkDestroyImageView(m_vkd->device(), m_srcImageView, nullptr); + m_vkd->vkDestroyImageView(m_vkd->device(), m_srcStencilView, nullptr); } - VkRenderPass DxvkMetaCopyRenderPass::createRenderPass(bool discard) const { - auto aspect = m_dstImageView->info().aspect; - - VkPipelineStageFlags cpyStages = 0; - VkAccessFlags cpyAccess = 0; - - VkAttachmentDescription attachment; - attachment.flags = 0; - attachment.format = m_dstImageView->info().format; - attachment.samples = m_dstImageView->imageInfo().sampleCount; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.initialLayout = m_dstImageView->imageInfo().layout; - attachment.finalLayout = m_dstImageView->imageInfo().layout; - - if (discard) { - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - } - - VkAttachmentReference attachmentRef; - attachmentRef.attachment = 0; - attachmentRef.layout = (aspect & VK_IMAGE_ASPECT_COLOR_BIT) - ? m_dstImageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) - : m_dstImageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 0; - subpass.pColorAttachments = nullptr; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - if (aspect & VK_IMAGE_ASPECT_COLOR_BIT) { - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attachmentRef; - - cpyStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - cpyAccess |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - if (!discard) - cpyAccess |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - } else { - subpass.pDepthStencilAttachment = &attachmentRef; - - cpyStages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT - | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; - cpyAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - - if (!discard) - cpyAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - } - - // We have to be somewhat conservative here since we cannot assume - // that the backend blocks stages that are only used for meta ops - VkPipelineStageFlags extStages = m_dstImageView->imageInfo().stages | m_srcImageView->imageInfo().stages; - VkAccessFlags extAccess = m_dstImageView->imageInfo().access; - - std::array dependencies = {{ - { VK_SUBPASS_EXTERNAL, 0, extStages, cpyStages, 0, cpyAccess, 0 }, - { 0, VK_SUBPASS_EXTERNAL, cpyStages, extStages, cpyAccess, extAccess, 0 }, - }}; - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = 1; - info.pAttachments = &attachment; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = dependencies.size(); - info.pDependencies = dependencies.data(); - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaCopyRenderPass: Failed to create render pass"); - return result; - } - - - VkFramebuffer DxvkMetaCopyRenderPass::createFramebuffer() const { - VkImageView dstViewHandle = m_dstImageView->handle(); - VkImageSubresourceRange dstSubresources = m_dstImageView->subresources(); - VkExtent3D dstExtent = m_dstImageView->mipLevelExtent(0); - - VkFramebufferCreateInfo fboInfo; - fboInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - fboInfo.pNext = nullptr; - fboInfo.flags = 0; - fboInfo.renderPass = m_renderPass; - fboInfo.attachmentCount = 1; - fboInfo.pAttachments = &dstViewHandle; - fboInfo.width = dstExtent.width; - fboInfo.height = dstExtent.height; - fboInfo.layers = dstSubresources.layerCount; - - VkFramebuffer result = VK_NULL_HANDLE; - if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fboInfo, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaCopyRenderPass: Failed to create target framebuffer"); - return result; - } - - DxvkMetaCopyObjects::DxvkMetaCopyObjects(const DxvkDevice* device) : m_vkd (device->vkd()), - m_sampler (createSampler()), m_color { createShaderModule(dxvk_copy_color_1d), createShaderModule(dxvk_copy_color_2d), @@ -188,7 +113,6 @@ namespace dxvk { m_vkd->vkDestroyPipeline(m_vkd->device(), pair.second.pipeHandle, nullptr); m_vkd->vkDestroyPipelineLayout(m_vkd->device(), pair.second.pipeLayout, nullptr); m_vkd->vkDestroyDescriptorSetLayout (m_vkd->device(), pair.second.dsetLayout, nullptr); - m_vkd->vkDestroyRenderPass(m_vkd->device(), pair.second.renderPass, nullptr); } m_vkd->vkDestroyShaderModule(m_vkd->device(), m_depthStencil.fragMs, nullptr); @@ -202,8 +126,6 @@ namespace dxvk { m_vkd->vkDestroyShaderModule(m_vkd->device(), m_color.frag1D, nullptr); m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderGeom, nullptr); m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderVert, nullptr); - - m_vkd->vkDestroySampler(m_vkd->device(), m_sampler, nullptr); } @@ -267,34 +189,6 @@ namespace dxvk { } - VkSampler DxvkMetaCopyObjects::createSampler() const { - VkSamplerCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.magFilter = VK_FILTER_NEAREST; - info.minFilter = VK_FILTER_NEAREST; - info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.mipLodBias = 0.0f; - info.anisotropyEnable = VK_FALSE; - info.maxAnisotropy = 1.0f; - info.compareEnable = VK_FALSE; - info.compareOp = VK_COMPARE_OP_ALWAYS; - info.minLod = 0.0f; - info.maxLod = 0.0f; - info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; - info.unnormalizedCoordinates = VK_FALSE; - - VkSampler result = VK_NULL_HANDLE; - if (m_vkd->vkCreateSampler(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaCopyObjects: Failed to create sampler"); - return result; - } - - VkShaderModule DxvkMetaCopyObjects::createShaderModule( const SpirvCodeBuffer& code) const { VkShaderModuleCreateInfo info; @@ -313,17 +207,13 @@ namespace dxvk { DxvkMetaCopyPipeline DxvkMetaCopyObjects::createCopyBufferImagePipeline() { DxvkMetaCopyPipeline pipeline; - pipeline.renderPass = VK_NULL_HANDLE; std::array bindings = {{ { 0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, { 1, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, }}; - VkDescriptorSetLayoutCreateInfo setLayoutInfo; - setLayoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - setLayoutInfo.pNext = nullptr; - setLayoutInfo.flags = 0; + VkDescriptorSetLayoutCreateInfo setLayoutInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; setLayoutInfo.bindingCount = bindings.size(); setLayoutInfo.pBindings = bindings.data(); @@ -332,10 +222,7 @@ namespace dxvk { VkPushConstantRange pushRange = { VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(DxvkCopyBufferImageArgs) }; - VkPipelineLayoutCreateInfo pipelineLayoutInfo; - pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipelineLayoutInfo.pNext = nullptr; - pipelineLayoutInfo.flags = 0; + VkPipelineLayoutCreateInfo pipelineLayoutInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; pipelineLayoutInfo.setLayoutCount = 1; pipelineLayoutInfo.pSetLayouts = &pipeline.dsetLayout; pipelineLayoutInfo.pushConstantRangeCount = 1; @@ -346,19 +233,12 @@ namespace dxvk { VkShaderModule shaderModule = createShaderModule(dxvk_copy_buffer_image); - VkComputePipelineCreateInfo pipelineInfo; - pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - pipelineInfo.pNext = nullptr; - pipelineInfo.flags = 0; + VkComputePipelineCreateInfo pipelineInfo = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; pipelineInfo.layout = pipeline.pipeLayout; pipelineInfo.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - pipelineInfo.stage.pNext = nullptr; - pipelineInfo.stage.flags = 0; pipelineInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; pipelineInfo.stage.module = shaderModule; pipelineInfo.stage.pName = "main"; - pipelineInfo.stage.pSpecializationInfo = nullptr; - pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; pipelineInfo.basePipelineIndex = -1; if (m_vkd->vkCreateComputePipelines(m_vkd->device(), VK_NULL_HANDLE, @@ -373,96 +253,24 @@ namespace dxvk { DxvkMetaCopyPipeline DxvkMetaCopyObjects::createPipeline( const DxvkMetaCopyPipelineKey& key) { DxvkMetaCopyPipeline pipeline; - pipeline.renderPass = this->createRenderPass(key); pipeline.dsetLayout = this->createDescriptorSetLayout(key); pipeline.pipeLayout = this->createPipelineLayout(pipeline.dsetLayout); - pipeline.pipeHandle = this->createPipelineObject(key, pipeline.pipeLayout, pipeline.renderPass); + pipeline.pipeHandle = this->createPipelineObject(key, pipeline.pipeLayout); return pipeline; } - VkRenderPass DxvkMetaCopyObjects::createRenderPass( - const DxvkMetaCopyPipelineKey& key) const { - auto aspect = imageFormatInfo(key.format)->aspectMask; - - VkAttachmentDescription attachment; - attachment.flags = 0; - attachment.format = key.format; - attachment.samples = key.samples; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.initialLayout = VK_IMAGE_LAYOUT_GENERAL; - attachment.finalLayout = VK_IMAGE_LAYOUT_GENERAL; - - VkAttachmentReference attachmentRef; - attachmentRef.attachment = 0; - attachmentRef.layout = (aspect & VK_IMAGE_ASPECT_COLOR_BIT) - ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 0; - subpass.pColorAttachments = nullptr; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = nullptr; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - if (aspect & VK_IMAGE_ASPECT_COLOR_BIT) { - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &attachmentRef; - } else { - subpass.pDepthStencilAttachment = &attachmentRef; - } - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = 1; - info.pAttachments = &attachment; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = 0; - info.pDependencies = nullptr; - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaCopyObjects: Failed to create render pass"); - return result; - } - - VkDescriptorSetLayout DxvkMetaCopyObjects::createDescriptorSetLayout( const DxvkMetaCopyPipelineKey& key) const { - std::array bindings; - - for (uint32_t i = 0; i < 2; i++) { - bindings[i].binding = i; - bindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - bindings[i].descriptorCount = 1; - bindings[i].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - bindings[i].pImmutableSamplers = &m_sampler; - } + std::array bindings = {{ + { 0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT }, + { 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT }, + }}; - VkDescriptorSetLayoutCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.bindingCount = 1; - info.pBindings = bindings.data(); + VkDescriptorSetLayoutCreateInfo info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; + info.bindingCount = bindings.size(); + info.pBindings = bindings.data(); - auto format = imageFormatInfo(key.format); - - if (format->aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) - info.bindingCount = 2; - VkDescriptorSetLayout result = VK_NULL_HANDLE; if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) throw DxvkError("DxvkMetaCopyObjects: Failed to create descriptor set layout"); @@ -472,15 +280,9 @@ namespace dxvk { VkPipelineLayout DxvkMetaCopyObjects::createPipelineLayout( VkDescriptorSetLayout descriptorSetLayout) const { - VkPushConstantRange push; - push.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - push.offset = 0; - push.size = sizeof(VkOffset2D); + VkPushConstantRange push = { VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(VkOffset2D) }; - VkPipelineLayoutCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkPipelineLayoutCreateInfo info = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; info.setLayoutCount = 1; info.pSetLayouts = &descriptorSetLayout; info.pushConstantRangeCount = 1; @@ -495,42 +297,22 @@ namespace dxvk { VkPipeline DxvkMetaCopyObjects::createPipelineObject( const DxvkMetaCopyPipelineKey& key, - VkPipelineLayout pipelineLayout, - VkRenderPass renderPass) { + VkPipelineLayout pipelineLayout) { auto aspect = imageFormatInfo(key.format)->aspectMask; std::array stages; uint32_t stageCount = 0; - VkPipelineShaderStageCreateInfo& vsStage = stages[stageCount++]; - vsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vsStage.pNext = nullptr; - vsStage.flags = 0; - vsStage.stage = VK_SHADER_STAGE_VERTEX_BIT; - vsStage.module = m_shaderVert; - vsStage.pName = "main"; - vsStage.pSpecializationInfo = nullptr; + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_VERTEX_BIT, m_shaderVert, "main" }; if (m_shaderGeom) { - VkPipelineShaderStageCreateInfo& gsStage = stages[stageCount++]; - gsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - gsStage.pNext = nullptr; - gsStage.flags = 0; - gsStage.stage = VK_SHADER_STAGE_GEOMETRY_BIT; - gsStage.module = m_shaderGeom; - gsStage.pName = "main"; - gsStage.pSpecializationInfo = nullptr; + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_GEOMETRY_BIT, m_shaderGeom, "main" }; } - VkPipelineShaderStageCreateInfo& psStage = stages[stageCount++]; - psStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - psStage.pNext = nullptr; - psStage.flags = 0; - psStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - psStage.module = VK_NULL_HANDLE; - psStage.pName = "main"; - psStage.pSpecializationInfo = nullptr; - std::array, 3> shaderSets = {{ { &m_color, VK_IMAGE_ASPECT_COLOR_BIT }, { &m_depth, VK_IMAGE_ASPECT_DEPTH_BIT }, @@ -545,135 +327,95 @@ namespace dxvk { } if (!shaderSet) - throw DxvkError("DxvkMetaCopyObjects: Unsupported aspect mask"); + throw DxvkError(str::format("DxvkMetaCopyObjects: Unsupported aspect mask: ", aspect)); + + VkShaderModule psModule = VK_NULL_HANDLE; if (key.viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY) - psStage.module = shaderSet->frag1D; + psModule = shaderSet->frag1D; else if (key.samples == VK_SAMPLE_COUNT_1_BIT) - psStage.module = shaderSet->frag2D; + psModule = shaderSet->frag2D; else - psStage.module = shaderSet->fragMs; + psModule = shaderSet->fragMs; + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_FRAGMENT_BIT, psModule, "main" }; + std::array dynStates = {{ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, }}; - VkPipelineDynamicStateCreateInfo dynState; - dynState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynState.pNext = nullptr; - dynState.flags = 0; - dynState.dynamicStateCount = dynStates.size(); - dynState.pDynamicStates = dynStates.data(); + VkPipelineDynamicStateCreateInfo dynState = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + dynState.dynamicStateCount = dynStates.size(); + dynState.pDynamicStates = dynStates.data(); - VkPipelineVertexInputStateCreateInfo viState; - viState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - viState.pNext = nullptr; - viState.flags = 0; - viState.vertexBindingDescriptionCount = 0; - viState.pVertexBindingDescriptions = nullptr; - viState.vertexAttributeDescriptionCount = 0; - viState.pVertexAttributeDescriptions = nullptr; + VkPipelineVertexInputStateCreateInfo viState = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; - VkPipelineInputAssemblyStateCreateInfo iaState; - iaState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - iaState.pNext = nullptr; - iaState.flags = 0; - iaState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - iaState.primitiveRestartEnable = VK_FALSE; + VkPipelineInputAssemblyStateCreateInfo iaState = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; + iaState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - VkPipelineViewportStateCreateInfo vpState; - vpState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - vpState.pNext = nullptr; - vpState.flags = 0; - vpState.viewportCount = 1; - vpState.pViewports = nullptr; - vpState.scissorCount = 1; - vpState.pScissors = nullptr; + VkPipelineViewportStateCreateInfo vpState = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; + vpState.viewportCount = 1; + vpState.scissorCount = 1; - VkPipelineRasterizationStateCreateInfo rsState; - rsState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rsState.pNext = nullptr; - rsState.flags = 0; - rsState.depthClampEnable = VK_TRUE; - rsState.rasterizerDiscardEnable = VK_FALSE; - rsState.polygonMode = VK_POLYGON_MODE_FILL; - rsState.cullMode = VK_CULL_MODE_NONE; - rsState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rsState.depthBiasEnable = VK_FALSE; - rsState.depthBiasConstantFactor = 0.0f; - rsState.depthBiasClamp = 0.0f; - rsState.depthBiasSlopeFactor = 0.0f; - rsState.lineWidth = 1.0f; + VkPipelineRasterizationStateCreateInfo rsState = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; + rsState.depthClampEnable = VK_TRUE; + rsState.polygonMode = VK_POLYGON_MODE_FILL; + rsState.cullMode = VK_CULL_MODE_NONE; + rsState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + rsState.lineWidth = 1.0f; uint32_t msMask = 0xFFFFFFFF; - VkPipelineMultisampleStateCreateInfo msState; - msState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - msState.pNext = nullptr; - msState.flags = 0; - msState.rasterizationSamples = key.samples; - msState.sampleShadingEnable = key.samples != VK_SAMPLE_COUNT_1_BIT; - msState.minSampleShading = 1.0f; - msState.pSampleMask = &msMask; - msState.alphaToCoverageEnable = VK_FALSE; - msState.alphaToOneEnable = VK_FALSE; + VkPipelineMultisampleStateCreateInfo msState = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; + msState.rasterizationSamples = key.samples; + msState.sampleShadingEnable = key.samples != VK_SAMPLE_COUNT_1_BIT; + msState.minSampleShading = 1.0f; + msState.pSampleMask = &msMask; - VkPipelineColorBlendAttachmentState cbAttachment; - cbAttachment.blendEnable = VK_FALSE; - cbAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - cbAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; - cbAttachment.colorBlendOp = VK_BLEND_OP_ADD; - cbAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - cbAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - cbAttachment.alphaBlendOp = VK_BLEND_OP_ADD; - cbAttachment.colorWriteMask = + VkPipelineColorBlendAttachmentState cbAttachment = { }; + cbAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - VkPipelineColorBlendStateCreateInfo cbState; - cbState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - cbState.pNext = nullptr; - cbState.flags = 0; - cbState.logicOpEnable = VK_FALSE; - cbState.logicOp = VK_LOGIC_OP_NO_OP; - cbState.attachmentCount = 1; - cbState.pAttachments = &cbAttachment; + VkPipelineColorBlendStateCreateInfo cbState = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; + cbState.attachmentCount = 1; + cbState.pAttachments = &cbAttachment; - for (uint32_t i = 0; i < 4; i++) - cbState.blendConstants[i] = 0.0f; + VkStencilOpState stencilOp = { }; + stencilOp.failOp = VK_STENCIL_OP_REPLACE; + stencilOp.passOp = VK_STENCIL_OP_REPLACE; + stencilOp.depthFailOp = VK_STENCIL_OP_REPLACE; + stencilOp.compareOp = VK_COMPARE_OP_ALWAYS; + stencilOp.compareMask = 0xFFFFFFFF; + stencilOp.writeMask = 0xFFFFFFFF; - VkStencilOpState stencilOp; - stencilOp.failOp = VK_STENCIL_OP_REPLACE; - stencilOp.passOp = VK_STENCIL_OP_REPLACE; - stencilOp.depthFailOp = VK_STENCIL_OP_REPLACE; - stencilOp.compareOp = VK_COMPARE_OP_ALWAYS; - stencilOp.compareMask = 0xFFFFFFFF; - stencilOp.writeMask = 0xFFFFFFFF; - stencilOp.reference = 0; + VkPipelineDepthStencilStateCreateInfo dsState = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; + dsState.depthTestEnable = VK_TRUE; + dsState.depthWriteEnable = VK_TRUE; + dsState.depthCompareOp = VK_COMPARE_OP_ALWAYS; + dsState.stencilTestEnable = VK_TRUE; + dsState.front = stencilOp; + dsState.back = stencilOp; - VkPipelineDepthStencilStateCreateInfo dsState; - dsState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - dsState.pNext = nullptr; - dsState.flags = 0; - dsState.depthTestEnable = VK_TRUE; - dsState.depthWriteEnable = VK_TRUE; - dsState.depthCompareOp = VK_COMPARE_OP_ALWAYS; - dsState.depthBoundsTestEnable = VK_FALSE; - dsState.stencilTestEnable = VK_TRUE; - dsState.front = stencilOp; - dsState.back = stencilOp; - dsState.minDepthBounds = 0.0f; - dsState.maxDepthBounds = 1.0f; - - VkGraphicsPipelineCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkPipelineRenderingCreateInfoKHR rtState = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + + if (aspect & VK_IMAGE_ASPECT_COLOR_BIT) { + rtState.colorAttachmentCount = 1; + rtState.pColorAttachmentFormats = &key.format; + } else { + if (aspect & VK_IMAGE_ASPECT_DEPTH_BIT) + rtState.depthAttachmentFormat = key.format; + if (aspect & VK_IMAGE_ASPECT_STENCIL_BIT) + rtState.stencilAttachmentFormat = key.format; + } + + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &rtState }; info.stageCount = stageCount; info.pStages = stages.data(); info.pVertexInputState = &viState; info.pInputAssemblyState = &iaState; - info.pTessellationState = nullptr; info.pViewportState = &vpState; info.pRasterizationState = &rsState; info.pMultisampleState = &msState; @@ -681,9 +423,6 @@ namespace dxvk { info.pDepthStencilState = (aspect & VK_IMAGE_ASPECT_COLOR_BIT) ? nullptr : &dsState; info.pDynamicState = &dynState; info.layout = pipelineLayout; - info.renderPass = renderPass; - info.subpass = 0; - info.basePipelineHandle = VK_NULL_HANDLE; info.basePipelineIndex = -1; VkPipeline result = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_meta_copy.h b/src/dxvk/dxvk_meta_copy.h index c80b7f797..bb7481fc9 100644 --- a/src/dxvk/dxvk_meta_copy.h +++ b/src/dxvk/dxvk_meta_copy.h @@ -32,7 +32,6 @@ namespace dxvk { * that is used for fragment shader copies. */ struct DxvkMetaCopyPipeline { - VkRenderPass renderPass; VkDescriptorSetLayout dsetLayout; VkPipelineLayout pipeLayout; VkPipeline pipeHandle; @@ -63,46 +62,43 @@ namespace dxvk { }; /** - * \brief Copy framebuffer and render pass + * \brief Copy view objects * - * Creates a framebuffer and render - * pass object for an image view. + * Creates and manages views used in a + * framebuffer-based copy operations. */ - class DxvkMetaCopyRenderPass : public DxvkResource { + class DxvkMetaCopyViews : public DxvkResource { public: - DxvkMetaCopyRenderPass( - const Rc& vkd, - const Rc& dstImageView, - const Rc& srcImageView, - const Rc& srcStencilView, - bool discardDst); + DxvkMetaCopyViews( + const Rc& vkd, + const Rc& dstImage, + const VkImageSubresourceLayers& dstSubresources, + VkFormat dstFormat, + const Rc& srcImage, + const VkImageSubresourceLayers& srcSubresources); - ~DxvkMetaCopyRenderPass(); + ~DxvkMetaCopyViews(); - VkRenderPass renderPass() const { - return m_renderPass; - } + VkImageView getDstView() const { return m_dstImageView; } + VkImageView getSrcView() const { return m_srcImageView; } + VkImageView getSrcStencilView() const { return m_srcStencilView; } - VkFramebuffer framebuffer() const { - return m_framebuffer; + VkImageViewType getSrcViewType() const { + return m_srcViewType; } private: Rc m_vkd; - Rc m_dstImageView; - Rc m_srcImageView; - Rc m_srcStencilView; - - VkRenderPass m_renderPass = VK_NULL_HANDLE; - VkFramebuffer m_framebuffer = VK_NULL_HANDLE; + VkImageViewType m_srcViewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + VkImageViewType m_dstViewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; - VkRenderPass createRenderPass(bool discard) const; - - VkFramebuffer createFramebuffer() const; + VkImageView m_dstImageView = VK_NULL_HANDLE; + VkImageView m_srcImageView = VK_NULL_HANDLE; + VkImageView m_srcStencilView = VK_NULL_HANDLE; }; @@ -162,8 +158,6 @@ namespace dxvk { Rc m_vkd; - VkSampler m_sampler; - VkShaderModule m_shaderVert = VK_NULL_HANDLE; VkShaderModule m_shaderGeom = VK_NULL_HANDLE; @@ -180,8 +174,6 @@ namespace dxvk { DxvkMetaCopyPipeline m_copyBufferImagePipeline = { }; - VkSampler createSampler() const; - VkShaderModule createShaderModule( const SpirvCodeBuffer& code) const; @@ -190,9 +182,6 @@ namespace dxvk { DxvkMetaCopyPipeline createPipeline( const DxvkMetaCopyPipelineKey& key); - VkRenderPass createRenderPass( - const DxvkMetaCopyPipelineKey& key) const; - VkDescriptorSetLayout createDescriptorSetLayout( const DxvkMetaCopyPipelineKey& key) const; @@ -201,8 +190,7 @@ namespace dxvk { VkPipeline createPipelineObject( const DxvkMetaCopyPipelineKey& key, - VkPipelineLayout pipelineLayout, - VkRenderPass renderPass); + VkPipelineLayout pipelineLayout); }; diff --git a/src/dxvk/shaders/dxvk_copy_color_1d.frag b/src/dxvk/shaders/dxvk_copy_color_1d.frag index 76e83dac3..b91067d91 100644 --- a/src/dxvk/shaders/dxvk_copy_color_1d.frag +++ b/src/dxvk/shaders/dxvk_copy_color_1d.frag @@ -1,7 +1,9 @@ #version 450 +#extension GL_EXT_samplerless_texture_functions : require + layout(set = 0, binding = 0) -uniform sampler1DArray s_image; +uniform texture1DArray s_image; layout(location = 0) out vec4 o_color; diff --git a/src/dxvk/shaders/dxvk_copy_color_2d.frag b/src/dxvk/shaders/dxvk_copy_color_2d.frag index db76c2483..99a0cc270 100644 --- a/src/dxvk/shaders/dxvk_copy_color_2d.frag +++ b/src/dxvk/shaders/dxvk_copy_color_2d.frag @@ -1,7 +1,9 @@ #version 450 +#extension GL_EXT_samplerless_texture_functions : require + layout(set = 0, binding = 0) -uniform sampler2DArray s_image; +uniform texture2DArray s_image; layout(location = 0) out vec4 o_color; diff --git a/src/dxvk/shaders/dxvk_copy_color_ms.frag b/src/dxvk/shaders/dxvk_copy_color_ms.frag index 61b81241d..b7a79057f 100644 --- a/src/dxvk/shaders/dxvk_copy_color_ms.frag +++ b/src/dxvk/shaders/dxvk_copy_color_ms.frag @@ -1,7 +1,9 @@ #version 450 +#extension GL_EXT_samplerless_texture_functions : require + layout(set = 0, binding = 0) -uniform sampler2DMSArray s_image; +uniform texture2DMSArray s_image; layout(location = 0) out vec4 o_color; diff --git a/src/dxvk/shaders/dxvk_copy_depth_1d.frag b/src/dxvk/shaders/dxvk_copy_depth_1d.frag index 7150db10d..acf627293 100644 --- a/src/dxvk/shaders/dxvk_copy_depth_1d.frag +++ b/src/dxvk/shaders/dxvk_copy_depth_1d.frag @@ -1,7 +1,9 @@ #version 450 +#extension GL_EXT_samplerless_texture_functions : require + layout(set = 0, binding = 0) -uniform sampler1DArray s_image; +uniform texture1DArray s_image; layout(push_constant) uniform u_info_t { diff --git a/src/dxvk/shaders/dxvk_copy_depth_2d.frag b/src/dxvk/shaders/dxvk_copy_depth_2d.frag index a5eaf4e93..dabcd4a56 100644 --- a/src/dxvk/shaders/dxvk_copy_depth_2d.frag +++ b/src/dxvk/shaders/dxvk_copy_depth_2d.frag @@ -1,7 +1,9 @@ #version 450 +#extension GL_EXT_samplerless_texture_functions : require + layout(set = 0, binding = 0) -uniform sampler2DArray s_image; +uniform texture2DArray s_image; layout(push_constant) uniform u_info_t { diff --git a/src/dxvk/shaders/dxvk_copy_depth_ms.frag b/src/dxvk/shaders/dxvk_copy_depth_ms.frag index 4264c0387..44c07c305 100644 --- a/src/dxvk/shaders/dxvk_copy_depth_ms.frag +++ b/src/dxvk/shaders/dxvk_copy_depth_ms.frag @@ -1,7 +1,9 @@ #version 450 +#extension GL_EXT_samplerless_texture_functions : require + layout(set = 0, binding = 0) -uniform sampler2DMSArray s_image; +uniform texture2DMSArray s_image; layout(push_constant) uniform u_info_t { diff --git a/src/dxvk/shaders/dxvk_copy_depth_stencil_1d.frag b/src/dxvk/shaders/dxvk_copy_depth_stencil_1d.frag index e017145df..fb5bea678 100644 --- a/src/dxvk/shaders/dxvk_copy_depth_stencil_1d.frag +++ b/src/dxvk/shaders/dxvk_copy_depth_stencil_1d.frag @@ -1,12 +1,13 @@ #version 450 -#extension GL_ARB_shader_stencil_export : enable +#extension GL_ARB_shader_stencil_export : require +#extension GL_EXT_samplerless_texture_functions : require layout(set = 0, binding = 0) -uniform sampler1DArray s_depth; +uniform texture1DArray s_depth; layout(set = 0, binding = 1) -uniform usampler1DArray s_stencil; +uniform utexture1DArray s_stencil; layout(push_constant) uniform u_info_t { diff --git a/src/dxvk/shaders/dxvk_copy_depth_stencil_2d.frag b/src/dxvk/shaders/dxvk_copy_depth_stencil_2d.frag index 29e7d6b0b..2b5fad670 100644 --- a/src/dxvk/shaders/dxvk_copy_depth_stencil_2d.frag +++ b/src/dxvk/shaders/dxvk_copy_depth_stencil_2d.frag @@ -1,12 +1,13 @@ #version 450 #extension GL_ARB_shader_stencil_export : enable +#extension GL_EXT_samplerless_texture_functions : require layout(set = 0, binding = 0) -uniform sampler2DArray s_depth; +uniform texture2DArray s_depth; layout(set = 0, binding = 1) -uniform usampler2DArray s_stencil; +uniform utexture2DArray s_stencil; layout(push_constant) uniform u_info_t { diff --git a/src/dxvk/shaders/dxvk_copy_depth_stencil_ms.frag b/src/dxvk/shaders/dxvk_copy_depth_stencil_ms.frag index dfb5f0058..0c6a27d39 100644 --- a/src/dxvk/shaders/dxvk_copy_depth_stencil_ms.frag +++ b/src/dxvk/shaders/dxvk_copy_depth_stencil_ms.frag @@ -1,12 +1,13 @@ #version 450 #extension GL_ARB_shader_stencil_export : enable +#extension GL_EXT_samplerless_texture_functions : require layout(set = 0, binding = 0) -uniform sampler2DMSArray s_depth; +uniform texture2DMSArray s_depth; layout(set = 0, binding = 1) -uniform usampler2DMSArray s_stencil; +uniform utexture2DMSArray s_stencil; layout(push_constant) uniform u_info_t { From 5b6a598ed6a07c0e9a25dcba25c49afea2894de3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 2 Jul 2022 15:46:11 +0200 Subject: [PATCH 0112/1348] [dxvk] Use dynamic rendering for resolve operations --- src/dxvk/dxvk_context.cpp | 314 ++++++++++++-------- src/dxvk/dxvk_meta_copy.cpp | 5 +- src/dxvk/dxvk_meta_copy.h | 3 +- src/dxvk/dxvk_meta_resolve.cpp | 524 +++++---------------------------- src/dxvk/dxvk_meta_resolve.h | 75 ++--- 5 files changed, 296 insertions(+), 625 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 3192b6453..595140fb9 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1816,11 +1816,9 @@ namespace dxvk { & VK_IMAGE_ASPECT_STENCIL_BIT)) stencilMode = VK_RESOLVE_MODE_NONE_KHR; - // We can only use the depth-stencil resolve path if the - // extension is supported, if we are resolving a full - // subresource, and both images have the same format. - bool useFb = !m_device->extensions().khrDepthStencilResolve - || !dstImage->isFullSubresource(region.dstSubresource, region.extent) + // We can only use the depth-stencil resolve path if we are resolving + // a full subresource and both images have the same format. + bool useFb = !dstImage->isFullSubresource(region.dstSubresource, region.extent) || !srcImage->isFullSubresource(region.srcSubresource, region.extent) || dstImage->info().format != srcImage->info().format; @@ -3370,9 +3368,11 @@ namespace dxvk { m_execAcquires.recordCommands(m_cmd); // Create source and destination image views + VkFormat srcFormat = srcImage->info().format; + Rc views = new DxvkMetaCopyViews(m_device->vkd(), dstImage, dstSubresource, dstFormat, - srcImage, srcSubresource); + srcImage, srcSubresource, srcFormat); // Create pipeline for the copy operation DxvkMetaCopyPipeline pipeInfo = m_common->metaCopy().getPipeline( @@ -3631,53 +3631,92 @@ namespace dxvk { if (m_execBarriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write) || m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); - - // Create image views covering the requested subresourcs - DxvkImageViewCreateInfo dstViewInfo; - dstViewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - dstViewInfo.format = dstImage->info().format; - dstViewInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - dstViewInfo.aspect = region.dstSubresource.aspectMask; - dstViewInfo.minLevel = region.dstSubresource.mipLevel; - dstViewInfo.numLevels = 1; - dstViewInfo.minLayer = region.dstSubresource.baseArrayLayer; - dstViewInfo.numLayers = region.dstSubresource.layerCount; - DxvkImageViewCreateInfo srcViewInfo; - srcViewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - srcViewInfo.format = srcImage->info().format; - srcViewInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - srcViewInfo.aspect = region.srcSubresource.aspectMask; - srcViewInfo.minLevel = region.srcSubresource.mipLevel; - srcViewInfo.numLevels = 1; - srcViewInfo.minLayer = region.srcSubresource.baseArrayLayer; - srcViewInfo.numLayers = region.srcSubresource.layerCount; + // Transition both images to usable layouts if necessary. For the source image we + // can be fairly leniet since writable layouts are allowed for resolve attachments. + VkImageLayout dstLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + VkImageLayout srcLayout = srcImage->info().layout; - Rc dstImageView = m_device->createImageView(dstImage, dstViewInfo); - Rc srcImageView = m_device->createImageView(srcImage, srcViewInfo); + if (srcLayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL + && srcLayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) + srcLayout = srcImage->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - // Create a framebuffer for the resolve op - VkExtent3D passExtent = dstImageView->mipLevelExtent(0); + if (srcImage->info().layout != srcLayout) { + m_execAcquires.accessImage(srcImage, srcSubresourceRange, + srcImage->info().layout, + srcImage->info().stages, 0, + srcLayout, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT); + } - Rc fb = new DxvkMetaResolveRenderPass( - m_device->vkd(), dstImageView, srcImageView, depthMode, stencilMode); + if (dstImage->info().layout != dstLayout) { + m_execAcquires.accessImage(dstImage, dstSubresourceRange, + VK_IMAGE_LAYOUT_UNDEFINED, dstImage->info().stages, 0, + dstLayout, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT); + } - VkRenderPassBeginInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - info.pNext = nullptr; - info.renderPass = fb->renderPass(); - info.framebuffer = fb->framebuffer(); - info.renderArea.offset = { 0, 0 }; - info.renderArea.extent = { passExtent.width, passExtent.height }; - info.clearValueCount = 0; - info.pClearValues = nullptr; + m_execAcquires.recordCommands(m_cmd); - m_cmd->cmdBeginRenderPass(&info, VK_SUBPASS_CONTENTS_INLINE); - m_cmd->cmdEndRenderPass(); + // Create a pair of views for the attachment resolve + Rc views = new DxvkMetaResolveViews(m_device->vkd(), + dstImage, region.dstSubresource, srcImage, region.srcSubresource, + dstImage->info().format); + + VkRenderingAttachmentInfoKHR depthAttachment = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + depthAttachment.imageView = views->getSrcView(); + depthAttachment.imageLayout = srcLayout; + depthAttachment.resolveMode = depthMode; + depthAttachment.resolveImageView = views->getDstView(); + depthAttachment.resolveImageLayout = dstLayout; + depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + VkRenderingAttachmentInfoKHR stencilAttachment = depthAttachment; + stencilAttachment.resolveMode = stencilMode; + + VkExtent3D extent = dstImage->mipLevelExtent(region.dstSubresource.mipLevel); + + VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + renderingInfo.renderArea.offset = VkOffset2D { 0, 0 }; + renderingInfo.renderArea.extent = VkExtent2D { extent.width, extent.height }; + renderingInfo.layerCount = region.dstSubresource.layerCount; + + if (dstImage->formatInfo()->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) + renderingInfo.pDepthAttachment = &depthAttachment; + + if (dstImage->formatInfo()->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) + renderingInfo.pStencilAttachment = &stencilAttachment; + + m_cmd->cmdBeginRendering(&renderingInfo); + m_cmd->cmdEndRendering(); + + // Add barriers for the resolve operation + m_execBarriers.accessImage(srcImage, srcSubresourceRange, + srcLayout, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, + srcImage->info().layout, + srcImage->info().stages, + srcImage->info().access); + + m_execBarriers.accessImage(dstImage, dstSubresourceRange, + dstLayout, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + dstImage->info().layout, + dstImage->info().stages, + dstImage->info().access); m_cmd->trackResource(dstImage); m_cmd->trackResource(srcImage); - m_cmd->trackResource(fb); + m_cmd->trackResource(views); } @@ -3692,13 +3731,59 @@ namespace dxvk { auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource); auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource); - + if (m_execBarriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write) || m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); - // We might have to transition the source image layout - VkImageLayout srcLayout = srcImage->pickLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + // Discard the destination image if we're fully writing it, + // and transition the image layout if necessary + bool doDiscard = dstImage->isFullSubresource(region.dstSubresource, region.extent); + + if (region.dstSubresource.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) + doDiscard &= depthMode != VK_RESOLVE_MODE_NONE_KHR; + if (region.dstSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) + doDiscard &= stencilMode != VK_RESOLVE_MODE_NONE_KHR; + + VkPipelineStageFlags dstStages; + VkImageLayout dstLayout; + VkAccessFlags dstAccess; + + if (region.dstSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { + dstLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + dstStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dstAccess = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + if (!doDiscard) + dstAccess |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + } else { + dstLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + dstStages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT + | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + dstAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + + if (!doDiscard) + dstAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + } + + if (dstImage->info().layout != dstLayout) { + m_execAcquires.accessImage( + dstImage, dstSubresourceRange, + doDiscard ? VK_IMAGE_LAYOUT_UNDEFINED + : dstImage->info().layout, + dstImage->info().stages, 0, + dstLayout, dstStages, dstAccess); + } + + // Check source image layout, and try to avoid transitions if we can + VkImageLayout srcLayout = srcImage->info().layout; + + if (srcLayout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + && srcLayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) { + srcLayout = (region.srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT & VK_IMAGE_ASPECT_COLOR_BIT) + ? srcImage->pickLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + : srcImage->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL); + } if (srcImage->info().layout != srcLayout) { m_execAcquires.accessImage( @@ -3708,78 +3793,47 @@ namespace dxvk { srcLayout, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT); - - m_execAcquires.recordCommands(m_cmd); } - // Create image views covering the requested subresourcs - DxvkImageViewCreateInfo dstViewInfo; - dstViewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - dstViewInfo.format = format ? format : dstImage->info().format; - dstViewInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - dstViewInfo.aspect = region.dstSubresource.aspectMask; - dstViewInfo.minLevel = region.dstSubresource.mipLevel; - dstViewInfo.numLevels = 1; - dstViewInfo.minLayer = region.dstSubresource.baseArrayLayer; - dstViewInfo.numLayers = region.dstSubresource.layerCount; - - if (region.dstSubresource.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) - dstViewInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - - DxvkImageViewCreateInfo srcViewInfo; - srcViewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - srcViewInfo.format = format ? format : srcImage->info().format; - srcViewInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; - srcViewInfo.aspect = region.srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_COLOR_BIT); - srcViewInfo.minLevel = region.srcSubresource.mipLevel; - srcViewInfo.numLevels = 1; - srcViewInfo.minLayer = region.srcSubresource.baseArrayLayer; - srcViewInfo.numLayers = region.srcSubresource.layerCount; - - Rc dstImageView = m_device->createImageView(dstImage, dstViewInfo); - Rc srcImageView = m_device->createImageView(srcImage, srcViewInfo); - Rc srcStencilView = nullptr; - - if ((region.dstSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && stencilMode != VK_RESOLVE_MODE_NONE_KHR) { - srcViewInfo.aspect = VK_IMAGE_ASPECT_STENCIL_BIT; - srcStencilView = m_device->createImageView(srcImage, srcViewInfo); - } + m_execAcquires.recordCommands(m_cmd); // Create a framebuffer and pipeline for the resolve op - VkExtent3D passExtent = dstImageView->mipLevelExtent(0); + VkFormat dstFormat = format ? format : dstImage->info().format; + VkFormat srcFormat = format ? format : srcImage->info().format; - Rc fb = new DxvkMetaResolveRenderPass( - m_device->vkd(), dstImageView, srcImageView, srcStencilView, - dstImage->isFullSubresource(region.dstSubresource, region.extent)); + VkExtent3D passExtent = dstImage->mipLevelExtent(region.dstSubresource.mipLevel); - auto pipeInfo = m_common->metaResolve().getPipeline( - dstViewInfo.format, srcImage->info().sampleCount, depthMode, stencilMode); - - VkDescriptorImageInfo descriptorImage; - descriptorImage.sampler = VK_NULL_HANDLE; - descriptorImage.imageView = srcImageView->handle(); - descriptorImage.imageLayout = srcLayout; + Rc views = new DxvkMetaCopyViews(m_device->vkd(), + dstImage, region.dstSubresource, dstFormat, + srcImage, region.srcSubresource, srcFormat); - VkWriteDescriptorSet descriptorWrite; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.pNext = nullptr; - descriptorWrite.dstBinding = 0; - descriptorWrite.dstArrayElement = 0; - descriptorWrite.descriptorCount = 1; - descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptorWrite.pImageInfo = &descriptorImage; - descriptorWrite.pBufferInfo = nullptr; - descriptorWrite.pTexelBufferView = nullptr; - - descriptorWrite.dstSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); - m_cmd->updateDescriptorSets(1, &descriptorWrite); + DxvkMetaResolvePipeline pipeInfo = m_common->metaResolve().getPipeline( + dstFormat, srcImage->info().sampleCount, depthMode, stencilMode); - if (srcStencilView != nullptr) { - descriptorWrite.dstBinding = 1; - descriptorImage.imageView = srcStencilView->handle(); - m_cmd->updateDescriptorSets(1, &descriptorWrite); + // Create and initialize descriptor set + VkDescriptorSet descriptorSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); + + std::array descriptorImages = {{ + { VK_NULL_HANDLE, views->getSrcView(), srcLayout }, + { VK_NULL_HANDLE, views->getSrcStencilView(), srcLayout }, + }}; + + std::array descriptorWrites; + + for (uint32_t i = 0; i < descriptorWrites.size(); i++) { + descriptorWrites[i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + descriptorWrites[i].dstSet = descriptorSet; + descriptorWrites[i].dstBinding = i; + descriptorWrites[i].descriptorCount = 1; + descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptorWrites[i].pImageInfo = &descriptorImages[i]; } + + m_cmd->updateDescriptorSets( + descriptorWrites.size(), + descriptorWrites.data()); + // Set up render state VkViewport viewport; viewport.x = float(region.dstOffset.x); viewport.y = float(region.dstOffset.y); @@ -3792,32 +3846,48 @@ namespace dxvk { scissor.offset = { region.dstOffset.x, region.dstOffset.y }; scissor.extent = { region.extent.width, region.extent.height }; - VkRenderPassBeginInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - info.pNext = nullptr; - info.renderPass = fb->renderPass(); - info.framebuffer = fb->framebuffer(); - info.renderArea.offset = { 0, 0 }; - info.renderArea.extent = { passExtent.width, passExtent.height }; - info.clearValueCount = 0; - info.pClearValues = nullptr; + VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + attachmentInfo.imageView = views->getDstView(); + attachmentInfo.imageLayout = dstLayout; + attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + if (doDiscard) + attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + + VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + renderingInfo.renderArea.offset = VkOffset2D { 0, 0 }; + renderingInfo.renderArea.extent = VkExtent2D { passExtent.width, passExtent.height }; + renderingInfo.layerCount = region.dstSubresource.layerCount; + VkImageAspectFlags dstAspects = dstImage->formatInfo()->aspectMask; + + if (dstAspects & VK_IMAGE_ASPECT_COLOR_BIT) { + renderingInfo.colorAttachmentCount = 1; + renderingInfo.pColorAttachments = &attachmentInfo; + } else { + if (dstAspects & VK_IMAGE_ASPECT_DEPTH_BIT) + renderingInfo.pDepthAttachment = &attachmentInfo; + if (dstAspects & VK_IMAGE_ASPECT_STENCIL_BIT) + renderingInfo.pStencilAttachment = &attachmentInfo; + } + // Perform the actual resolve operation VkOffset2D srcOffset = { region.srcOffset.x - region.dstOffset.x, region.srcOffset.y - region.dstOffset.y }; - m_cmd->cmdBeginRenderPass(&info, VK_SUBPASS_CONTENTS_INLINE); + m_cmd->cmdBeginRendering(&renderingInfo); m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle); m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeInfo.pipeLayout, descriptorWrite.dstSet, 0, nullptr); + pipeInfo.pipeLayout, descriptorSet, 0, nullptr); m_cmd->cmdSetViewport(0, 1, &viewport); m_cmd->cmdSetScissor (0, 1, &scissor); m_cmd->cmdPushConstants(pipeInfo.pipeLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(srcOffset), &srcOffset); m_cmd->cmdDraw(3, region.dstSubresource.layerCount, 0, 0); - m_cmd->cmdEndRenderPass(); + m_cmd->cmdEndRendering(); if (srcImage->info().layout != srcLayout) { m_execBarriers.accessImage( @@ -3830,7 +3900,7 @@ namespace dxvk { m_cmd->trackResource(dstImage); m_cmd->trackResource(srcImage); - m_cmd->trackResource(fb); + m_cmd->trackResource(views); } diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index 6f1bdf234..4816172bb 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -24,7 +24,8 @@ namespace dxvk { const VkImageSubresourceLayers& dstSubresources, VkFormat dstFormat, const Rc& srcImage, - const VkImageSubresourceLayers& srcSubresources) + const VkImageSubresourceLayers& srcSubresources, + VkFormat srcFormat) : m_vkd(vkd) { VkImageAspectFlags dstAspects = dstImage->formatInfo()->aspectMask; VkImageAspectFlags srcAspects = srcImage->formatInfo()->aspectMask; @@ -55,7 +56,7 @@ namespace dxvk { info.image = srcImage->handle(); info.viewType = m_srcViewType; - info.format = srcImage->info().format; + info.format = srcFormat; info.subresourceRange = vk::makeSubresourceRange(srcSubresources); info.subresourceRange.aspectMask = srcAspects & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT); diff --git a/src/dxvk/dxvk_meta_copy.h b/src/dxvk/dxvk_meta_copy.h index bb7481fc9..c32dbc0d6 100644 --- a/src/dxvk/dxvk_meta_copy.h +++ b/src/dxvk/dxvk_meta_copy.h @@ -77,7 +77,8 @@ namespace dxvk { const VkImageSubresourceLayers& dstSubresources, VkFormat dstFormat, const Rc& srcImage, - const VkImageSubresourceLayers& srcSubresources); + const VkImageSubresourceLayers& srcSubresources, + VkFormat srcFormat); ~DxvkMetaCopyViews(); diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index 55dde83c2..e95900695 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -14,274 +14,42 @@ namespace dxvk { - DxvkMetaResolveRenderPass::DxvkMetaResolveRenderPass( - const Rc& vkd, - const Rc& dstImageView, - const Rc& srcImageView, - const Rc& srcStencilView, - bool discardDst) - : m_vkd(vkd), - m_dstImageView(dstImageView), - m_srcImageView(srcImageView), - m_srcStencilView(srcStencilView), - m_renderPass (createShaderRenderPass(discardDst)), - m_framebuffer (createShaderFramebuffer()) { } + DxvkMetaResolveViews::DxvkMetaResolveViews( + const Rc& vkd, + const Rc& dstImage, + const VkImageSubresourceLayers& dstSubresources, + const Rc& srcImage, + const VkImageSubresourceLayers& srcSubresources, + VkFormat format) + : m_vkd(vkd) { + VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; + usageInfo.usage = (imageFormatInfo(format)->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) + ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT + : VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + VkImageViewCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo }; + info.image = dstImage->handle(); + info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY; + info.format = format; + info.subresourceRange = vk::makeSubresourceRange(dstSubresources); - DxvkMetaResolveRenderPass::DxvkMetaResolveRenderPass( - const Rc& vkd, - const Rc& dstImageView, - const Rc& srcImageView, - VkResolveModeFlagBitsKHR modeD, - VkResolveModeFlagBitsKHR modeS) - : m_vkd(vkd), - m_dstImageView(dstImageView), - m_srcImageView(srcImageView), - m_renderPass (createAttachmentRenderPass(modeD, modeS)), - m_framebuffer (createAttachmentFramebuffer()) { } - + if (m_vkd->vkCreateImageView(m_vkd->device(), &info, nullptr, &m_dstImageView)) + throw DxvkError("DxvkMetaResolveViews: Failed to create destination view"); - DxvkMetaResolveRenderPass::~DxvkMetaResolveRenderPass() { - m_vkd->vkDestroyFramebuffer(m_vkd->device(), m_framebuffer, nullptr); - m_vkd->vkDestroyRenderPass (m_vkd->device(), m_renderPass, nullptr); + info.image = srcImage->handle(); + info.subresourceRange = vk::makeSubresourceRange(srcSubresources); + + if (m_vkd->vkCreateImageView(m_vkd->device(), &info, nullptr, &m_srcImageView)) + throw DxvkError("DxvkMetaResolveViews: Failed to create source view"); } - VkRenderPass DxvkMetaResolveRenderPass::createShaderRenderPass(bool discard) const { - auto formatInfo = m_dstImageView->formatInfo(); - bool isColorImage = (formatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT); - - VkAttachmentDescription attachment; - attachment.flags = 0; - attachment.format = m_dstImageView->info().format; - attachment.samples = VK_SAMPLE_COUNT_1_BIT; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.initialLayout = m_dstImageView->imageInfo().layout; - attachment.finalLayout = m_dstImageView->imageInfo().layout; - - if (discard) { - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - } - - VkImageLayout layout = isColorImage - ? m_dstImageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) - : m_dstImageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - - VkAttachmentReference dstRef; - dstRef.attachment = 0; - dstRef.layout = layout; - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = isColorImage ? 1 : 0; - subpass.pColorAttachments = isColorImage ? &dstRef : nullptr; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = isColorImage ? nullptr : &dstRef; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkPipelineStageFlags cpyStages = 0; - VkAccessFlags cpyAccess = 0; - - if (isColorImage) { - cpyStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - cpyAccess |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - if (!discard) - cpyAccess |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - } else { - cpyStages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT - | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; - cpyAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - - if (!discard) - cpyAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - } - - // Resolve targets are required to be render targets - VkPipelineStageFlags extStages = m_dstImageView->imageInfo().stages | m_srcImageView->imageInfo().stages; - VkAccessFlags extAccess = m_dstImageView->imageInfo().access; - - std::array dependencies = {{ - { VK_SUBPASS_EXTERNAL, 0, cpyStages, cpyStages, 0, cpyAccess, 0 }, - { 0, VK_SUBPASS_EXTERNAL, cpyStages, extStages, cpyAccess, extAccess, 0 }, - }}; - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = 1; - info.pAttachments = &attachment; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = dependencies.size(); - info.pDependencies = dependencies.data(); - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaResolveRenderPass: Failed to create render pass"); - return result; + DxvkMetaResolveViews::~DxvkMetaResolveViews() { + m_vkd->vkDestroyImageView(m_vkd->device(), m_srcImageView, nullptr); + m_vkd->vkDestroyImageView(m_vkd->device(), m_dstImageView, nullptr); } - VkRenderPass DxvkMetaResolveRenderPass::createAttachmentRenderPass( - VkResolveModeFlagBitsKHR modeD, - VkResolveModeFlagBitsKHR modeS) const { - std::array attachments; - attachments[0].sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR; - attachments[0].pNext = nullptr; - attachments[0].flags = 0; - attachments[0].format = m_srcImageView->info().format; - attachments[0].samples = m_srcImageView->imageInfo().sampleCount; - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[0].initialLayout = m_srcImageView->imageInfo().layout; - attachments[0].finalLayout = m_srcImageView->imageInfo().layout; - - attachments[1].sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR; - attachments[1].pNext = nullptr; - attachments[1].flags = 0; - attachments[1].format = m_dstImageView->info().format; - attachments[1].samples = VK_SAMPLE_COUNT_1_BIT; - attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - attachments[1].initialLayout = m_dstImageView->imageInfo().layout; - attachments[1].finalLayout = m_dstImageView->imageInfo().layout; - - if (modeD != VK_RESOLVE_MODE_NONE_KHR && modeS != VK_RESOLVE_MODE_NONE_KHR) { - attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachments[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - } - - VkAttachmentReference2KHR srcRef; - srcRef.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR; - srcRef.pNext = nullptr; - srcRef.attachment = 0; - srcRef.layout = m_srcImageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - srcRef.aspectMask = m_srcImageView->formatInfo()->aspectMask; - - VkAttachmentReference2KHR dstRef; - dstRef.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR; - dstRef.pNext = nullptr; - dstRef.attachment = 1; - dstRef.layout = m_dstImageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - dstRef.aspectMask = m_dstImageView->formatInfo()->aspectMask; - - VkSubpassDescriptionDepthStencilResolveKHR subpassResolve; - subpassResolve.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR; - subpassResolve.pNext = nullptr; - subpassResolve.depthResolveMode = modeD; - subpassResolve.stencilResolveMode = modeS; - subpassResolve.pDepthStencilResolveAttachment = &dstRef; - - VkSubpassDescription2KHR subpass; - subpass.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR; - subpass.pNext = &subpassResolve; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.viewMask = 0; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = 0; - subpass.pColorAttachments = nullptr; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = &srcRef; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkPipelineStageFlags cpyStages = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; - VkPipelineStageFlags extStages = m_dstImageView->imageInfo().stages | m_srcImageView->imageInfo().stages; - VkAccessFlags cpyAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - VkAccessFlags extAccess = m_dstImageView->imageInfo().access; - - std::array dependencies = {{ - { VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR, nullptr, VK_SUBPASS_EXTERNAL, 0, cpyStages, cpyStages, 0, cpyAccess, 0 }, - { VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR, nullptr, 0, VK_SUBPASS_EXTERNAL, cpyStages, extStages, cpyAccess, extAccess, 0 }, - }}; - - VkRenderPassCreateInfo2KHR info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = attachments.size(); - info.pAttachments = attachments.data(); - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = dependencies.size(); - info.pDependencies = dependencies.data(); - info.correlatedViewMaskCount = 0; - info.pCorrelatedViewMasks = nullptr; - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass2KHR(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaResolveRenderPass: Failed to create render pass"); - return result; - } - - - VkFramebuffer DxvkMetaResolveRenderPass::createShaderFramebuffer() const { - VkImageSubresourceRange dstSubresources = m_dstImageView->subresources(); - VkExtent3D dstExtent = m_dstImageView->mipLevelExtent(0); - VkImageView dstHandle = m_dstImageView->handle(); - - VkFramebufferCreateInfo fboInfo; - fboInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - fboInfo.pNext = nullptr; - fboInfo.flags = 0; - fboInfo.renderPass = m_renderPass; - fboInfo.attachmentCount = 1; - fboInfo.pAttachments = &dstHandle; - fboInfo.width = dstExtent.width; - fboInfo.height = dstExtent.height; - fboInfo.layers = dstSubresources.layerCount; - - VkFramebuffer result = VK_NULL_HANDLE; - if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fboInfo, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaResolveRenderPass: Failed to create target framebuffer"); - return result; - } - - - VkFramebuffer DxvkMetaResolveRenderPass::createAttachmentFramebuffer() const { - VkImageSubresourceRange dstSubresources = m_dstImageView->subresources(); - VkExtent3D dstExtent = m_dstImageView->mipLevelExtent(0); - - std::array handles = {{ - m_srcImageView->handle(), - m_dstImageView->handle(), - }}; - - VkFramebufferCreateInfo fboInfo; - fboInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - fboInfo.pNext = nullptr; - fboInfo.flags = 0; - fboInfo.renderPass = m_renderPass; - fboInfo.attachmentCount = handles.size(); - fboInfo.pAttachments = handles.data(); - fboInfo.width = dstExtent.width; - fboInfo.height = dstExtent.height; - fboInfo.layers = dstSubresources.layerCount; - - VkFramebuffer result = VK_NULL_HANDLE; - if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fboInfo, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaResolveRenderPass: Failed to create target framebuffer"); - return result; - } - DxvkMetaResolveObjects::DxvkMetaResolveObjects(const DxvkDevice* device) @@ -310,7 +78,6 @@ namespace dxvk { m_vkd->vkDestroyPipeline(m_vkd->device(), pair.second.pipeHandle, nullptr); m_vkd->vkDestroyPipelineLayout(m_vkd->device(), pair.second.pipeLayout, nullptr); m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), pair.second.dsetLayout, nullptr); - m_vkd->vkDestroyRenderPass(m_vkd->device(), pair.second.renderPass, nullptr); } m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFragDS, nullptr); @@ -395,87 +162,24 @@ namespace dxvk { DxvkMetaResolvePipeline DxvkMetaResolveObjects::createPipeline( const DxvkMetaResolvePipelineKey& key) { DxvkMetaResolvePipeline pipeline; - pipeline.renderPass = this->createRenderPass(key); pipeline.dsetLayout = this->createDescriptorSetLayout(key); pipeline.pipeLayout = this->createPipelineLayout(pipeline.dsetLayout); - pipeline.pipeHandle = this->createPipelineObject(key, pipeline.pipeLayout, pipeline.renderPass); + pipeline.pipeHandle = this->createPipelineObject(key, pipeline.pipeLayout); return pipeline; } - VkRenderPass DxvkMetaResolveObjects::createRenderPass( - const DxvkMetaResolvePipelineKey& key) { - auto formatInfo = imageFormatInfo(key.format); - bool isColorImage = (formatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT); - - VkAttachmentDescription attachment; - attachment.flags = 0; - attachment.format = key.format; - attachment.samples = VK_SAMPLE_COUNT_1_BIT; - attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment.initialLayout = VK_IMAGE_LAYOUT_GENERAL; - attachment.finalLayout = VK_IMAGE_LAYOUT_GENERAL; - - VkImageLayout layout = isColorImage - ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkAttachmentReference attachmentRef; - attachmentRef.attachment = 0; - attachmentRef.layout = layout; - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = isColorImage ? 1 : 0; - subpass.pColorAttachments = isColorImage ? &attachmentRef : nullptr; - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = isColorImage ? nullptr : &attachmentRef; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = 1; - info.pAttachments = &attachment; - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = 0; - info.pDependencies = nullptr; - - VkRenderPass result = VK_NULL_HANDLE; - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaResolveObjects: Failed to create render pass"); - return result; - } - - VkDescriptorSetLayout DxvkMetaResolveObjects::createDescriptorSetLayout( const DxvkMetaResolvePipelineKey& key) { - auto formatInfo = imageFormatInfo(key.format); - std::array bindings = {{ { 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, &m_sampler }, { 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, &m_sampler }, }}; - VkDescriptorSetLayoutCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.bindingCount = 1; - info.pBindings = bindings.data(); + VkDescriptorSetLayoutCreateInfo info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; + info.bindingCount = bindings.size(); + info.pBindings = bindings.data(); - if ((formatInfo->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && key.modeS != VK_RESOLVE_MODE_NONE_KHR) - info.bindingCount = 2; - VkDescriptorSetLayout result = VK_NULL_HANDLE; if (m_vkd->vkCreateDescriptorSetLayout(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) throw DxvkError("DxvkMetaResolveObjects: Failed to create descriptor set layout"); @@ -485,15 +189,9 @@ namespace dxvk { VkPipelineLayout DxvkMetaResolveObjects::createPipelineLayout( VkDescriptorSetLayout descriptorSetLayout) { - VkPushConstantRange push; - push.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; - push.offset = 0; - push.size = sizeof(VkOffset2D); + VkPushConstantRange push = { VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(VkOffset2D) }; - VkPipelineLayoutCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkPipelineLayoutCreateInfo info = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; info.setLayoutCount = 1; info.pSetLayouts = &descriptorSetLayout; info.pushConstantRangeCount = 1; @@ -508,10 +206,8 @@ namespace dxvk { VkPipeline DxvkMetaResolveObjects::createPipelineObject( const DxvkMetaResolvePipelineKey& key, - VkPipelineLayout pipelineLayout, - VkRenderPass renderPass) { + VkPipelineLayout pipelineLayout) { auto formatInfo = imageFormatInfo(key.format); - bool isColorImage = formatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT; std::array stages; uint32_t stageCount = 0; @@ -528,181 +224,117 @@ namespace dxvk { specInfo.dataSize = sizeof(key); specInfo.pData = &key; - VkPipelineShaderStageCreateInfo& vsStage = stages[stageCount++]; - vsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - vsStage.pNext = nullptr; - vsStage.flags = 0; - vsStage.stage = VK_SHADER_STAGE_VERTEX_BIT; - vsStage.module = m_shaderVert; - vsStage.pName = "main"; - vsStage.pSpecializationInfo = nullptr; + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_VERTEX_BIT, m_shaderVert, "main" }; if (m_shaderGeom) { - VkPipelineShaderStageCreateInfo& gsStage = stages[stageCount++]; - gsStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - gsStage.pNext = nullptr; - gsStage.flags = 0; - gsStage.stage = VK_SHADER_STAGE_GEOMETRY_BIT; - gsStage.module = m_shaderGeom; - gsStage.pName = "main"; - gsStage.pSpecializationInfo = nullptr; + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_GEOMETRY_BIT, m_shaderGeom, "main" }; } - VkPipelineShaderStageCreateInfo& psStage = stages[stageCount++]; - psStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - psStage.pNext = nullptr; - psStage.flags = 0; - psStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - psStage.module = VK_NULL_HANDLE; - psStage.pName = "main"; - psStage.pSpecializationInfo = &specInfo; + VkShaderModule psModule = VK_NULL_HANDLE; if ((formatInfo->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && key.modeS != VK_RESOLVE_MODE_NONE_KHR) { if (m_shaderFragDS) { - psStage.module = m_shaderFragDS; + psModule = m_shaderFragDS; } else { - psStage.module = m_shaderFragD; + psModule = m_shaderFragD; Logger::err("DXVK: Stencil export not supported by device, skipping stencil resolve"); } } else if (formatInfo->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) - psStage.module = m_shaderFragD; + psModule = m_shaderFragD; else if (formatInfo->flags.test(DxvkFormatFlag::SampledUInt)) - psStage.module = m_shaderFragU; + psModule = m_shaderFragU; else if (formatInfo->flags.test(DxvkFormatFlag::SampledSInt)) - psStage.module = m_shaderFragI; + psModule = m_shaderFragI; else - psStage.module = m_shaderFragF; - + psModule = m_shaderFragF; + + stages[stageCount++] = VkPipelineShaderStageCreateInfo { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0, + VK_SHADER_STAGE_FRAGMENT_BIT, psModule, "main", &specInfo }; + std::array dynStates = {{ VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, }}; - VkPipelineDynamicStateCreateInfo dynState; - dynState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynState.pNext = nullptr; - dynState.flags = 0; + VkPipelineDynamicStateCreateInfo dynState = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; dynState.dynamicStateCount = dynStates.size(); dynState.pDynamicStates = dynStates.data(); - VkPipelineVertexInputStateCreateInfo viState; - viState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - viState.pNext = nullptr; - viState.flags = 0; - viState.vertexBindingDescriptionCount = 0; - viState.pVertexBindingDescriptions = nullptr; - viState.vertexAttributeDescriptionCount = 0; - viState.pVertexAttributeDescriptions = nullptr; + VkPipelineVertexInputStateCreateInfo viState = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; - VkPipelineInputAssemblyStateCreateInfo iaState; - iaState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - iaState.pNext = nullptr; - iaState.flags = 0; + VkPipelineInputAssemblyStateCreateInfo iaState = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; iaState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - iaState.primitiveRestartEnable = VK_FALSE; - VkPipelineViewportStateCreateInfo vpState; - vpState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - vpState.pNext = nullptr; - vpState.flags = 0; + VkPipelineViewportStateCreateInfo vpState = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; vpState.viewportCount = 1; - vpState.pViewports = nullptr; vpState.scissorCount = 1; - vpState.pScissors = nullptr; - VkPipelineRasterizationStateCreateInfo rsState; - rsState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rsState.pNext = nullptr; - rsState.flags = 0; + VkPipelineRasterizationStateCreateInfo rsState = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rsState.depthClampEnable = VK_TRUE; - rsState.rasterizerDiscardEnable = VK_FALSE; rsState.polygonMode = VK_POLYGON_MODE_FILL; rsState.cullMode = VK_CULL_MODE_NONE; rsState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - rsState.depthBiasEnable = VK_FALSE; - rsState.depthBiasConstantFactor = 0.0f; - rsState.depthBiasClamp = 0.0f; - rsState.depthBiasSlopeFactor = 0.0f; rsState.lineWidth = 1.0f; uint32_t msMask = 0xFFFFFFFF; - VkPipelineMultisampleStateCreateInfo msState; - msState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - msState.pNext = nullptr; - msState.flags = 0; + VkPipelineMultisampleStateCreateInfo msState = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; msState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - msState.sampleShadingEnable = VK_FALSE; - msState.minSampleShading = 1.0f; msState.pSampleMask = &msMask; - msState.alphaToCoverageEnable = VK_FALSE; - msState.alphaToOneEnable = VK_FALSE; - VkPipelineColorBlendAttachmentState cbAttachment; - cbAttachment.blendEnable = VK_FALSE; - cbAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - cbAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; - cbAttachment.colorBlendOp = VK_BLEND_OP_ADD; - cbAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - cbAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; - cbAttachment.alphaBlendOp = VK_BLEND_OP_ADD; - cbAttachment.colorWriteMask = + VkPipelineColorBlendAttachmentState cbAttachment = { }; + cbAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - VkPipelineColorBlendStateCreateInfo cbState; - cbState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - cbState.pNext = nullptr; - cbState.flags = 0; - cbState.logicOpEnable = VK_FALSE; - cbState.logicOp = VK_LOGIC_OP_NO_OP; + VkPipelineColorBlendStateCreateInfo cbState = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; cbState.attachmentCount = 1; cbState.pAttachments = &cbAttachment; - for (uint32_t i = 0; i < 4; i++) - cbState.blendConstants[i] = 0.0f; - - VkStencilOpState stencilOp; + VkStencilOpState stencilOp = { }; stencilOp.failOp = VK_STENCIL_OP_REPLACE; stencilOp.passOp = VK_STENCIL_OP_REPLACE; stencilOp.depthFailOp = VK_STENCIL_OP_REPLACE; stencilOp.compareOp = VK_COMPARE_OP_ALWAYS; stencilOp.compareMask = 0xFFFFFFFF; stencilOp.writeMask = 0xFFFFFFFF; - stencilOp.reference = 0; - VkPipelineDepthStencilStateCreateInfo dsState; - dsState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - dsState.pNext = nullptr; - dsState.flags = 0; + VkPipelineDepthStencilStateCreateInfo dsState = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; dsState.depthTestEnable = key.modeD != VK_RESOLVE_MODE_NONE_KHR; dsState.depthWriteEnable = key.modeD != VK_RESOLVE_MODE_NONE_KHR; dsState.depthCompareOp = VK_COMPARE_OP_ALWAYS; - dsState.depthBoundsTestEnable = VK_FALSE; dsState.stencilTestEnable = key.modeS != VK_RESOLVE_MODE_NONE_KHR; dsState.front = stencilOp; dsState.back = stencilOp; - dsState.minDepthBounds = 0.0f; - dsState.maxDepthBounds = 1.0f; - VkGraphicsPipelineCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkPipelineRenderingCreateInfoKHR rtState = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + + if (formatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { + rtState.colorAttachmentCount = 1; + rtState.pColorAttachmentFormats = &key.format; + } else { + if (formatInfo->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) + rtState.depthAttachmentFormat = key.format; + if (formatInfo->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) + rtState.stencilAttachmentFormat = key.format; + } + + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &rtState }; info.stageCount = stageCount; info.pStages = stages.data(); info.pVertexInputState = &viState; info.pInputAssemblyState = &iaState; - info.pTessellationState = nullptr; info.pViewportState = &vpState; info.pRasterizationState = &rsState; info.pMultisampleState = &msState; - info.pColorBlendState = isColorImage ? &cbState : nullptr; - info.pDepthStencilState = isColorImage ? nullptr : &dsState; + info.pColorBlendState = (formatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) ? &cbState : nullptr; + info.pDepthStencilState = (formatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) ? nullptr : &dsState; info.pDynamicState = &dynState; info.layout = pipelineLayout; - info.renderPass = renderPass; - info.subpass = 0; - info.basePipelineHandle = VK_NULL_HANDLE; info.basePipelineIndex = -1; VkPipeline result = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_meta_resolve.h b/src/dxvk/dxvk_meta_resolve.h index 72161325b..0f738e01a 100644 --- a/src/dxvk/dxvk_meta_resolve.h +++ b/src/dxvk/dxvk_meta_resolve.h @@ -18,7 +18,6 @@ namespace dxvk { * that is used for fragment shader resolve. */ struct DxvkMetaResolvePipeline { - VkRenderPass renderPass; VkDescriptorSetLayout dsetLayout; VkPipelineLayout pipeLayout; VkPipeline pipeHandle; @@ -52,62 +51,34 @@ namespace dxvk { }; /** - * \brief Meta resolve render pass - * - * Stores a framebuffer and image view objects - * for a meta resolve operation. Can be tracked. + * \brief Meta resolve views for attachment-based resolves */ - class DxvkMetaResolveRenderPass : public DxvkResource { - - public: - - DxvkMetaResolveRenderPass( - const Rc& vkd, - const Rc& dstImageView, - const Rc& srcImageView, - const Rc& srcStencilView, - bool discardDst); - - DxvkMetaResolveRenderPass( - const Rc& vkd, - const Rc& dstImageView, - const Rc& srcImageView, - VkResolveModeFlagBitsKHR modeD, - VkResolveModeFlagBitsKHR modeS); - - ~DxvkMetaResolveRenderPass(); - - VkRenderPass renderPass() const { - return m_renderPass; - } + class DxvkMetaResolveViews : public DxvkResource { - VkFramebuffer framebuffer() const { - return m_framebuffer; - } + public: + + DxvkMetaResolveViews( + const Rc& vkd, + const Rc& dstImage, + const VkImageSubresourceLayers& dstSubresources, + const Rc& srcImage, + const VkImageSubresourceLayers& srcSubresources, + VkFormat format); + + ~DxvkMetaResolveViews(); + + VkImageView getDstView() const { return m_dstImageView; } + VkImageView getSrcView() const { return m_srcImageView; } private: - - const Rc m_vkd; - const Rc m_dstImageView; - const Rc m_srcImageView; - const Rc m_srcStencilView; - - VkRenderPass m_renderPass = VK_NULL_HANDLE; - VkFramebuffer m_framebuffer = VK_NULL_HANDLE; + Rc m_vkd; - VkRenderPass createShaderRenderPass(bool discard) const; - - VkRenderPass createAttachmentRenderPass( - VkResolveModeFlagBitsKHR modeD, - VkResolveModeFlagBitsKHR modeS) const; - - VkFramebuffer createShaderFramebuffer() const; - - VkFramebuffer createAttachmentFramebuffer() const; + VkImageView m_dstImageView = VK_NULL_HANDLE; + VkImageView m_srcImageView = VK_NULL_HANDLE; }; - + /** * \brief Meta resolve objects @@ -166,9 +137,6 @@ namespace dxvk { DxvkMetaResolvePipeline createPipeline( const DxvkMetaResolvePipelineKey& key); - VkRenderPass createRenderPass( - const DxvkMetaResolvePipelineKey& key); - VkDescriptorSetLayout createDescriptorSetLayout( const DxvkMetaResolvePipelineKey& key); @@ -177,8 +145,7 @@ namespace dxvk { VkPipeline createPipelineObject( const DxvkMetaResolvePipelineKey& key, - VkPipelineLayout pipelineLayout, - VkRenderPass renderPass); + VkPipelineLayout pipelineLayout); }; From 343eba693d9866f1dcc1dda07a9eaeb20162dbd1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 2 Jul 2022 20:39:20 +0200 Subject: [PATCH 0113/1348] [dxvk] Use dynamic rendering for regular graphics pipelines For now, just do whatever we were previously doing for render passes, but explicitly. --- src/dxvk/dxvk_context.cpp | 225 +++++++++++++++++++++++++++++---- src/dxvk/dxvk_context.h | 8 ++ src/dxvk/dxvk_framebuffer.cpp | 21 +++ src/dxvk/dxvk_framebuffer.h | 7 + src/dxvk/dxvk_graphics.cpp | 148 +++++++++------------- src/dxvk/dxvk_graphics_state.h | 92 ++++++++++++++ 6 files changed, 389 insertions(+), 112 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 595140fb9..115f7acaa 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1932,10 +1932,7 @@ namespace dxvk { } if (attachmentIndex < 0) { - if (m_execBarriers.isImageDirty( - imageView->image(), - imageView->imageSubresources(), - DxvkAccess::Write)) + if (m_execBarriers.isImageDirty(imageView->image(), imageView->imageSubresources(), DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); // Set up and bind a temporary framebuffer @@ -3982,6 +3979,133 @@ namespace dxvk { } + void DxvkContext::renderPassEmitInitBarriers( + const DxvkFramebufferInfo& framebufferInfo, + const DxvkRenderPassOps& ops) { + // If any of the involved images are dirty, emit all pending barriers now. + // Otherwise, skip this step so that we can more efficiently batch barriers. + for (uint32_t i = 0; i < framebufferInfo.numAttachments(); i++) { + const auto& attachment = framebufferInfo.getAttachment(i); + + if (m_execBarriers.isImageDirty( + attachment.view->image(), + attachment.view->imageSubresources(), + DxvkAccess::Write)) { + m_execBarriers.recordCommands(m_cmd); + break; + } + } + + // Transition all images to the render layout as necessary + const auto& depthAttachment = framebufferInfo.getDepthTarget(); + + if (depthAttachment.layout != ops.depthOps.loadLayout + && depthAttachment.view != nullptr) { + VkImageAspectFlags depthAspects = depthAttachment.view->info().aspect; + + VkPipelineStageFlags depthStages = + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + VkAccessFlags depthAccess = 0; + + if (((depthAspects & VK_IMAGE_ASPECT_DEPTH_BIT) && ops.depthOps.loadOpD == VK_ATTACHMENT_LOAD_OP_LOAD) + || ((depthAspects & VK_IMAGE_ASPECT_STENCIL_BIT) && ops.depthOps.loadOpS == VK_ATTACHMENT_LOAD_OP_LOAD)) + depthAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + + if (((depthAspects & VK_IMAGE_ASPECT_DEPTH_BIT) && ops.depthOps.loadOpD != VK_ATTACHMENT_LOAD_OP_LOAD) + || ((depthAspects & VK_IMAGE_ASPECT_STENCIL_BIT) && ops.depthOps.loadOpS != VK_ATTACHMENT_LOAD_OP_LOAD) + || (depthAttachment.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL)) + depthAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + + if (depthAttachment.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { + depthStages |= m_device->getShaderPipelineStages(); + depthAccess |= VK_ACCESS_SHADER_READ_BIT; + } + + m_execBarriers.accessImage( + depthAttachment.view->image(), + depthAttachment.view->imageSubresources(), + ops.depthOps.loadLayout, + depthStages, 0, + depthAttachment.layout, + depthStages, depthAccess); + } + + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + const auto& colorAttachment = framebufferInfo.getColorTarget(i); + + if (colorAttachment.layout != ops.colorOps[i].loadLayout + && colorAttachment.view != nullptr) { + VkAccessFlags colorAccess = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + + if (ops.colorOps[i].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) + colorAccess |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + + m_execBarriers.accessImage( + colorAttachment.view->image(), + colorAttachment.view->imageSubresources(), + ops.colorOps[i].loadLayout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, + colorAttachment.layout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + colorAccess); + } + } + + // Unconditionally emit barriers here. We need to do this + // even if there are no layout transitions, since we don't + // track resource usage during render passes. + m_execBarriers.recordCommands(m_cmd); + } + + + void DxvkContext::renderPassEmitPostBarriers( + const DxvkFramebufferInfo& framebufferInfo, + const DxvkRenderPassOps& ops) { + const auto& depthAttachment = framebufferInfo.getDepthTarget(); + + if (depthAttachment.view != nullptr) { + m_execBarriers.accessImage( + depthAttachment.view->image(), + depthAttachment.view->imageSubresources(), + depthAttachment.layout, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + ops.depthOps.storeLayout, + depthAttachment.view->imageInfo().stages, + depthAttachment.view->imageInfo().access); + } + + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + const auto& colorAttachment = framebufferInfo.getColorTarget(i); + + if (colorAttachment.view != nullptr) { + m_execBarriers.accessImage( + colorAttachment.view->image(), + colorAttachment.view->imageSubresources(), + colorAttachment.layout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + ops.colorOps[i].storeLayout, + colorAttachment.view->imageInfo().stages, + colorAttachment.view->imageInfo().access); + } + } + + m_execBarriers.accessMemory( + ops.barrier.srcStages, + ops.barrier.srcAccess, + ops.barrier.dstStages, + ops.barrier.dstAccess); + + // Do not flush barriers here. This is intended since + // we pre-record them when binding the framebuffer. + } + + void DxvkContext::renderPassBindFramebuffer( const DxvkFramebufferInfo& framebufferInfo, const DxvkRenderPassOps& ops, @@ -3989,26 +4113,75 @@ namespace dxvk { const VkClearValue* clearValues) { const DxvkFramebufferSize fbSize = framebufferInfo.size(); - Rc framebuffer = this->lookupFramebuffer(framebufferInfo); + this->renderPassEmitInitBarriers(framebufferInfo, ops); + this->renderPassEmitPostBarriers(framebufferInfo, ops); - VkRect2D renderArea; - renderArea.offset = VkOffset2D { 0, 0 }; - renderArea.extent = VkExtent2D { fbSize.width, fbSize.height }; - - VkRenderPassBeginInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - info.pNext = nullptr; - info.renderPass = framebufferInfo.renderPass()->getHandle(ops); - info.framebuffer = framebuffer->handle(); - info.renderArea = renderArea; - info.clearValueCount = clearValueCount; - info.pClearValues = clearValues; - - m_cmd->cmdBeginRenderPass(&info, - VK_SUBPASS_CONTENTS_INLINE); - - m_cmd->trackResource(framebuffer); + uint32_t clearValueIndex = 0; + uint32_t colorInfoCount = 0; + std::array colorInfos; + + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + const auto& colorTarget = framebufferInfo.getColorTarget(i); + colorInfos[i] = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + + if (colorTarget.view != nullptr) { + colorInfos[i].imageView = colorTarget.view->handle(); + colorInfos[i].imageLayout = colorTarget.layout; + colorInfos[i].loadOp = ops.colorOps[i].loadOp; + colorInfos[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + if (ops.colorOps[i].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) + colorInfos[i].clearValue = clearValues[clearValueIndex]; + + clearValueIndex += 1; + colorInfoCount = i + 1; + } + } + + VkRenderingAttachmentInfoKHR depthInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + VkImageAspectFlags depthStencilAspects = 0; + + if (framebufferInfo.getDepthTarget().view != nullptr) { + const auto& depthTarget = framebufferInfo.getDepthTarget(); + depthStencilAspects = depthTarget.view->info().aspect; + depthInfo.imageView = depthTarget.view->handle(); + depthInfo.imageLayout = depthTarget.layout; + depthInfo.loadOp = ops.depthOps.loadOpD; + depthInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + if (ops.depthOps.loadOpD == VK_ATTACHMENT_LOAD_OP_CLEAR) + depthInfo.clearValue = clearValues[clearValueIndex]; + } + + VkRenderingAttachmentInfoKHR stencilInfo = depthInfo; + + if (framebufferInfo.getDepthTarget().view != nullptr) { + stencilInfo.loadOp = ops.depthOps.loadOpS; + stencilInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + if (ops.depthOps.loadOpS == VK_ATTACHMENT_LOAD_OP_CLEAR) + stencilInfo.clearValue = clearValues[clearValueIndex]; + } + + VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + renderingInfo.renderArea.offset = VkOffset2D { 0, 0 }; + renderingInfo.renderArea.extent = VkExtent2D { fbSize.width, fbSize.height }; + renderingInfo.layerCount = fbSize.layers; + + if (colorInfoCount) { + renderingInfo.colorAttachmentCount = colorInfoCount; + renderingInfo.pColorAttachments = colorInfos.data(); + } + + if (depthStencilAspects & VK_IMAGE_ASPECT_DEPTH_BIT) + renderingInfo.pDepthAttachment = &depthInfo; + + if (depthStencilAspects & VK_IMAGE_ASPECT_STENCIL_BIT) + renderingInfo.pStencilAttachment = &stencilInfo; + + m_cmd->cmdBeginRendering(&renderingInfo); + for (uint32_t i = 0; i < framebufferInfo.numAttachments(); i++) { m_cmd->trackResource (framebufferInfo.getAttachment(i).view); m_cmd->trackResource(framebufferInfo.getAttachment(i).view->image()); @@ -4019,7 +4192,11 @@ namespace dxvk { void DxvkContext::renderPassUnbindFramebuffer() { - m_cmd->cmdEndRenderPass(); + m_cmd->cmdEndRendering(); + + // TODO Try to get rid of this for performance reasons. + // This only exists to emulate render pass barriers. + m_execBarriers.recordCommands(m_cmd); } @@ -4499,7 +4676,9 @@ namespace dxvk { DxvkFramebufferInfo fbInfo = makeFramebufferInfo(m_state.om.renderTargets); this->updateRenderTargetLayouts(fbInfo, m_state.om.framebufferInfo); + // Update relevant graphics pipeline state m_state.gp.state.ms.setSampleCount(fbInfo.getSampleCount()); + m_state.gp.state.rt = fbInfo.getRtInfo(); m_state.om.framebufferInfo = fbInfo; for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index de29f3c22..fb6fdddf7 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1286,6 +1286,14 @@ namespace dxvk { void startRenderPass(); void spillRenderPass(bool suspend); + void renderPassEmitInitBarriers( + const DxvkFramebufferInfo& framebufferInfo, + const DxvkRenderPassOps& ops); + + void renderPassEmitPostBarriers( + const DxvkFramebufferInfo& framebufferInfo, + const DxvkRenderPassOps& ops); + void renderPassBindFramebuffer( const DxvkFramebufferInfo& framebufferInfo, const DxvkRenderPassOps& ops, diff --git a/src/dxvk/dxvk_framebuffer.cpp b/src/dxvk/dxvk_framebuffer.cpp index 58d07e3b0..226e3f11e 100644 --- a/src/dxvk/dxvk_framebuffer.cpp +++ b/src/dxvk/dxvk_framebuffer.cpp @@ -88,6 +88,27 @@ namespace dxvk { } + DxvkRtInfo DxvkFramebufferInfo::getRtInfo() const { + VkFormat depthStencilFormat = VK_FORMAT_UNDEFINED; + VkImageAspectFlags depthStencilReadOnlyAspects = 0; + + if (m_renderTargets.depth.view != nullptr) { + depthStencilFormat = m_renderTargets.depth.view->info().format; + depthStencilReadOnlyAspects = m_renderTargets.depth.view->formatInfo()->aspectMask + & ~vk::getWritableAspectsForLayout(m_renderTargets.depth.layout); + } + + std::array colorFormats = { }; + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + if (m_renderTargets.color[i].view != nullptr) + colorFormats[i] = m_renderTargets.color[i].view->info().format; + } + + return DxvkRtInfo(MaxNumRenderTargets, colorFormats.data(), + depthStencilFormat, depthStencilReadOnlyAspects); + } + + DxvkRenderPassFormat DxvkFramebufferInfo::getRenderPassFormat(const DxvkRenderTargets& renderTargets) { DxvkRenderPassFormat format; diff --git a/src/dxvk/dxvk_framebuffer.h b/src/dxvk/dxvk_framebuffer.h index b55e6e5fa..c0eb8919d 100644 --- a/src/dxvk/dxvk_framebuffer.h +++ b/src/dxvk/dxvk_framebuffer.h @@ -1,6 +1,7 @@ #pragma once #include "dxvk_image.h" +#include "dxvk_graphics_state.h" #include "dxvk_renderpass.h" namespace dxvk { @@ -225,6 +226,12 @@ namespace dxvk { */ DxvkFramebufferKey key() const; + /** + * \brief Generates render target state + * \returns Render target state info + */ + DxvkRtInfo getRtInfo() const; + /** * \brief Generatess render pass format * diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index b611059a4..e1644d103 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -120,9 +120,6 @@ namespace dxvk { this->logPipelineState(LogLevel::Debug, state); } - // Render pass format and image layouts - DxvkRenderPassFormat passFormat = renderPass->format(); - // Set up dynamic states as needed std::array dynamicStates; uint32_t dynamicStateCount = 0; @@ -180,29 +177,41 @@ namespace dxvk { if (fsm) stages.push_back(fsm.stageInfo(&specInfo)); // Fix up color write masks using the component mappings - std::array omBlendAttachments; + VkImageAspectFlags rtReadOnlyAspects = state.rt.getDepthStencilReadOnlyAspects(); + VkFormat rtDepthFormat = state.rt.getDepthStencilFormat(); + auto rtDepthFormatInfo = imageFormatInfo(rtDepthFormat); + + std::array omBlendAttachments = { }; + std::array rtColorFormats; + uint32_t rtColorFormatCount = 0; const VkColorComponentFlags fullMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - auto formatInfo = imageFormatInfo(passFormat.color[i].format); - omBlendAttachments[i] = state.omBlend[i].state(); + rtColorFormats[i] = state.rt.getColorFormat(i); - if (!(m_fsOut & (1 << i)) || !formatInfo) { - omBlendAttachments[i].colorWriteMask = 0; - } else { - if (omBlendAttachments[i].colorWriteMask != fullMask) { - omBlendAttachments[i].colorWriteMask = util::remapComponentMask( - state.omBlend[i].colorWriteMask(), state.omSwizzle[i].mapping()); - } + if (rtColorFormats[i]) { + rtColorFormatCount = i + 1; - omBlendAttachments[i].colorWriteMask &= formatInfo->componentMask; + auto formatInfo = imageFormatInfo(rtColorFormats[i]); + omBlendAttachments[i] = state.omBlend[i].state(); - if (omBlendAttachments[i].colorWriteMask == formatInfo->componentMask) { - omBlendAttachments[i].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT - | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + if (!(m_fsOut & (1 << i)) || !formatInfo) { + omBlendAttachments[i].colorWriteMask = 0; + } else { + if (omBlendAttachments[i].colorWriteMask != fullMask) { + omBlendAttachments[i].colorWriteMask = util::remapComponentMask( + state.omBlend[i].colorWriteMask(), state.omSwizzle[i].mapping()); + } + + omBlendAttachments[i].colorWriteMask &= formatInfo->componentMask; + + if (omBlendAttachments[i].colorWriteMask == formatInfo->componentMask) { + omBlendAttachments[i].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT + | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + } } } } @@ -241,16 +250,11 @@ namespace dxvk { viAttribs[i].binding = viBindingMap[state.ilAttributes[i].binding()]; } - VkPipelineVertexInputDivisorStateCreateInfoEXT viDivisorInfo; - viDivisorInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT; - viDivisorInfo.pNext = nullptr; + VkPipelineVertexInputDivisorStateCreateInfoEXT viDivisorInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT }; viDivisorInfo.vertexBindingDivisorCount = viDivisorCount; viDivisorInfo.pVertexBindingDivisors = viDivisorDesc.data(); - VkPipelineVertexInputStateCreateInfo viInfo; - viInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - viInfo.pNext = &viDivisorInfo; - viInfo.flags = 0; + VkPipelineVertexInputStateCreateInfo viInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, &viDivisorInfo }; viInfo.vertexBindingDescriptionCount = state.il.bindingCount(); viInfo.pVertexBindingDescriptions = viBindings.data(); viInfo.vertexAttributeDescriptionCount = state.il.attributeCount(); @@ -263,60 +267,34 @@ namespace dxvk { if (!m_pipeMgr->m_device->features().extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor) viInfo.pNext = viDivisorInfo.pNext; - VkPipelineInputAssemblyStateCreateInfo iaInfo; - iaInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - iaInfo.pNext = nullptr; - iaInfo.flags = 0; + VkPipelineInputAssemblyStateCreateInfo iaInfo = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; iaInfo.topology = state.ia.primitiveTopology(); iaInfo.primitiveRestartEnable = state.ia.primitiveRestart(); - VkPipelineTessellationStateCreateInfo tsInfo; - tsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; - tsInfo.pNext = nullptr; - tsInfo.flags = 0; + VkPipelineTessellationStateCreateInfo tsInfo = { VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO }; tsInfo.patchControlPoints = state.ia.patchVertexCount(); - VkPipelineViewportStateCreateInfo vpInfo; - vpInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - vpInfo.pNext = nullptr; - vpInfo.flags = 0; + VkPipelineViewportStateCreateInfo vpInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; vpInfo.viewportCount = state.rs.viewportCount(); - vpInfo.pViewports = nullptr; vpInfo.scissorCount = state.rs.viewportCount(); - vpInfo.pScissors = nullptr; - VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeInfo; - conservativeInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT; - conservativeInfo.pNext = nullptr; - conservativeInfo.flags = 0; + VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT }; conservativeInfo.conservativeRasterizationMode = state.rs.conservativeMode(); conservativeInfo.extraPrimitiveOverestimationSize = 0.0f; - VkPipelineRasterizationStateStreamCreateInfoEXT xfbStreamInfo; - xfbStreamInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT; - xfbStreamInfo.pNext = nullptr; - xfbStreamInfo.flags = 0; + VkPipelineRasterizationStateStreamCreateInfoEXT xfbStreamInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT }; xfbStreamInfo.rasterizationStream = uint32_t(rasterizedStream); - VkPipelineRasterizationDepthClipStateCreateInfoEXT rsDepthClipInfo; - rsDepthClipInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT; - rsDepthClipInfo.pNext = nullptr; - rsDepthClipInfo.flags = 0; + VkPipelineRasterizationDepthClipStateCreateInfoEXT rsDepthClipInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT }; rsDepthClipInfo.depthClipEnable = state.rs.depthClipEnable(); - VkPipelineRasterizationStateCreateInfo rsInfo; - rsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rsInfo.pNext = nullptr; - rsInfo.flags = 0; + VkPipelineRasterizationStateCreateInfo rsInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rsInfo.depthClampEnable = VK_TRUE; rsInfo.rasterizerDiscardEnable = rasterizedStream < 0; rsInfo.polygonMode = state.rs.polygonMode(); rsInfo.cullMode = state.rs.cullMode(); rsInfo.frontFace = state.rs.frontFace(); rsInfo.depthBiasEnable = state.rs.depthBiasEnable(); - rsInfo.depthBiasConstantFactor= 0.0f; - rsInfo.depthBiasClamp = 0.0f; - rsInfo.depthBiasSlopeFactor = 0.0f; rsInfo.lineWidth = 1.0f; if (rasterizedStream > 0) @@ -332,10 +310,7 @@ namespace dxvk { uint32_t sampleMask = state.ms.sampleMask(); - VkPipelineMultisampleStateCreateInfo msInfo; - msInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - msInfo.pNext = nullptr; - msInfo.flags = 0; + VkPipelineMultisampleStateCreateInfo msInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; msInfo.rasterizationSamples = sampleCount; msInfo.sampleShadingEnable = m_common.msSampleShadingEnable; msInfo.minSampleShading = m_common.msSampleShadingFactor; @@ -343,43 +318,41 @@ namespace dxvk { msInfo.alphaToCoverageEnable = state.ms.enableAlphaToCoverage(); msInfo.alphaToOneEnable = VK_FALSE; - VkPipelineDepthStencilStateCreateInfo dsInfo; - dsInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - dsInfo.pNext = nullptr; - dsInfo.flags = 0; + VkPipelineDepthStencilStateCreateInfo dsInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; dsInfo.depthTestEnable = state.ds.enableDepthTest(); - dsInfo.depthWriteEnable = state.ds.enableDepthWrite() && !util::isDepthReadOnlyLayout(passFormat.depth.layout); + dsInfo.depthWriteEnable = state.ds.enableDepthWrite() && !(rtReadOnlyAspects & VK_IMAGE_ASPECT_DEPTH_BIT); dsInfo.depthCompareOp = state.ds.depthCompareOp(); dsInfo.depthBoundsTestEnable = state.ds.enableDepthBoundsTest(); dsInfo.stencilTestEnable = state.ds.enableStencilTest(); dsInfo.front = state.dsFront.state(); dsInfo.back = state.dsBack.state(); - dsInfo.minDepthBounds = 0.0f; - dsInfo.maxDepthBounds = 1.0f; - VkPipelineColorBlendStateCreateInfo cbInfo; - cbInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - cbInfo.pNext = nullptr; - cbInfo.flags = 0; + VkPipelineColorBlendStateCreateInfo cbInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; cbInfo.logicOpEnable = state.om.enableLogicOp(); cbInfo.logicOp = state.om.logicOp(); - cbInfo.attachmentCount = DxvkLimits::MaxNumRenderTargets; + cbInfo.attachmentCount = rtColorFormatCount; cbInfo.pAttachments = omBlendAttachments.data(); - for (uint32_t i = 0; i < 4; i++) - cbInfo.blendConstants[i] = 0.0f; - - VkPipelineDynamicStateCreateInfo dyInfo; - dyInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dyInfo.pNext = nullptr; - dyInfo.flags = 0; + VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; dyInfo.dynamicStateCount = dynamicStateCount; dyInfo.pDynamicStates = dynamicStates.data(); - - VkGraphicsPipelineCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + + VkPipelineRenderingCreateInfoKHR rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + + if (rtColorFormatCount) { + rtInfo.colorAttachmentCount = rtColorFormatCount; + rtInfo.pColorAttachmentFormats = rtColorFormats.data(); + } + + if (rtDepthFormat) { + if (rtDepthFormatInfo->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) + rtInfo.depthAttachmentFormat = rtDepthFormat; + + if (rtDepthFormatInfo->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) + rtInfo.stencilAttachmentFormat = rtDepthFormat; + } + + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &rtInfo }; info.stageCount = stages.size(); info.pStages = stages.data(); info.pVertexInputState = &viInfo; @@ -392,12 +365,9 @@ namespace dxvk { info.pColorBlendState = &cbInfo; info.pDynamicState = &dyInfo; info.layout = m_bindings->getPipelineLayout(); - info.renderPass = renderPass->getDefaultHandle(); - info.subpass = 0; - info.basePipelineHandle = VK_NULL_HANDLE; info.basePipelineIndex = -1; - if (tsInfo.patchControlPoints == 0) + if (!tsInfo.patchControlPoints) info.pTessellationState = nullptr; // Time pipeline compilation for debugging purposes diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 0044b4053..2c8ae023e 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -477,6 +477,97 @@ namespace dxvk { }; + /** + * \brief Packed render target formats + * + * Compact representation of depth-stencil and color attachments, + * as well as the read-only mask for the depth-stencil attachment, + * which needs to be known at pipeline compile time. + */ + class DxvkRtInfo { + + public: + + DxvkRtInfo() = default; + + DxvkRtInfo( + uint32_t colorFormatCount, + const VkFormat* colorFormats, + VkFormat depthStencilFormat, + VkImageAspectFlags depthStencilReadOnlyAspects) + : m_packedData(0ull) { + m_packedData |= encodeDepthStencilFormat(depthStencilFormat); + m_packedData |= encodeDepthStencilAspects(depthStencilReadOnlyAspects); + + for (uint32_t i = 0; i < colorFormatCount; i++) + m_packedData |= encodeColorFormat(colorFormats[i], i); + } + + VkFormat getColorFormat(uint32_t index) const { + return decodeColorFormat(m_packedData, index); + } + + VkFormat getDepthStencilFormat() const { + return decodeDepthStencilFormat(m_packedData); + } + + VkImageAspectFlags getDepthStencilReadOnlyAspects() const { + return decodeDepthStencilAspects(m_packedData); + } + + private: + + uint64_t m_packedData; + + static uint64_t encodeDepthStencilAspects(VkImageAspectFlags aspects) { + return uint64_t(aspects) << 61; + } + + static uint64_t encodeDepthStencilFormat(VkFormat format) { + return format + ? (uint64_t(format) - uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)) << 56 + : (uint64_t(0)); + } + + static uint64_t encodeColorFormat(VkFormat format, uint32_t index) { + uint64_t value = uint64_t(format); + + if (value >= uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT)) { + value -= uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT); + value += uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) + 1; + } else if (value > uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)) { + value = 0; + } + + return value << (7 * index); + } + + static VkImageAspectFlags decodeDepthStencilAspects(uint64_t value) { + return VkImageAspectFlags((value >> 61) & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)); + } + + static VkFormat decodeDepthStencilFormat(uint64_t value) { + value = (value >> 56) & 0x1F; + + return value + ? VkFormat(value + uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)) + : VkFormat(VK_FORMAT_UNDEFINED); + } + + static VkFormat decodeColorFormat(uint64_t value, uint32_t index) { + value = (value >> (7 * index)) & 0x7F; + + if (value > uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)) { + value -= uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) + 1ull; + value += uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT); + } + + return VkFormat(value); + } + + }; + + /** * \brief Packed attachment blend mode * @@ -685,6 +776,7 @@ namespace dxvk { DxvkMsInfo ms; DxvkDsInfo ds; DxvkOmInfo om; + DxvkRtInfo rt; DxvkScInfo sc; DxvkDsStencilOp dsFront; DxvkDsStencilOp dsBack; From 39a2b1cb7a2e64ab9e8d012ef9463e55580308e4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 2 Jul 2022 20:59:12 +0200 Subject: [PATCH 0114/1348] [dxvk] Remove support for state cache versions older than v8 We could technically keep supporting this with Dynamic Rendering, but it's a huge amount of work and there's no good reason to do so. --- src/dxvk/dxvk_state_cache.cpp | 233 +----------------------------- src/dxvk/dxvk_state_cache.h | 20 --- src/dxvk/dxvk_state_cache_types.h | 141 ------------------ 3 files changed, 1 insertion(+), 393 deletions(-) diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index ab08a1427..16f965ba6 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -397,25 +397,8 @@ namespace dxvk { return false; } - // Struct size hasn't changed between v2 and v4 - size_t expectedSize = newHeader.entrySize; - - if (curHeader.version <= 4) - expectedSize = sizeof(DxvkStateCacheEntryV4); - else if (curHeader.version <= 5) - expectedSize = sizeof(DxvkStateCacheEntryV5); - else if (curHeader.version <= 6) - expectedSize = sizeof(DxvkStateCacheEntryV6); - else if (curHeader.version <= 7) - expectedSize = sizeof(DxvkStateCacheEntry); - - if (curHeader.entrySize != expectedSize) { - Logger::warn("DXVK: State cache entry size changed"); - return false; - } - // Discard caches of unsupported versions - if (curHeader.version < 2 || curHeader.version > newHeader.version) { + if (curHeader.version < 8 || curHeader.version > newHeader.version) { Logger::warn("DXVK: State cache version not supported"); return false; } @@ -485,51 +468,10 @@ namespace dxvk { } - bool DxvkStateCache::readCacheEntryV7( - uint32_t version, - std::istream& stream, - DxvkStateCacheEntry& entry) const { - if (version <= 6) { - DxvkStateCacheEntryV6 v6; - - if (version <= 4) { - DxvkStateCacheEntryV4 v4; - - if (!readCacheEntryTyped(stream, v4)) - return false; - - if (version == 2) - convertEntryV2(v4); - - if (!convertEntryV4(v4, v6)) - return false; - } else if (version <= 5) { - DxvkStateCacheEntryV5 v5; - - if (!readCacheEntryTyped(stream, v5)) - return false; - - if (!convertEntryV5(v5, v6)) - return false; - } else { - if (!readCacheEntryTyped(stream, v6)) - return false; - } - - return convertEntryV6(v6, entry); - } else { - return readCacheEntryTyped(stream, entry); - } - } - - bool DxvkStateCache::readCacheEntry( uint32_t version, std::istream& stream, DxvkStateCacheEntry& entry) const { - if (version < 8) - return readCacheEntryV7(version, stream, entry); - // Read entry metadata and actual data DxvkStateCacheEntryHeader header; DxvkStateCacheEntryData data; @@ -732,179 +674,6 @@ namespace dxvk { } - bool DxvkStateCache::convertEntryV2( - DxvkStateCacheEntryV4& entry) const { - // Semantics changed: - // v2: rsDepthClampEnable - // v3: rsDepthClipEnable - entry.gpState.rsDepthClipEnable = !entry.gpState.rsDepthClipEnable; - - // Frontend changed: Depth bias - // will typically be disabled - entry.gpState.rsDepthBiasEnable = VK_FALSE; - return true; - } - - - bool DxvkStateCache::convertEntryV4( - const DxvkStateCacheEntryV4& in, - DxvkStateCacheEntryV6& out) const { - out.shaders = in.shaders; - out.format = in.format; - out.hash = in.hash; - - out.cpState.bsBindingMask = in.cpState.bsBindingMask; - out.gpState.bsBindingMask = in.gpState.bsBindingMask; - - out.gpState.iaPrimitiveTopology = in.gpState.iaPrimitiveTopology; - out.gpState.iaPrimitiveRestart = in.gpState.iaPrimitiveRestart; - out.gpState.iaPatchVertexCount = in.gpState.iaPatchVertexCount; - - out.gpState.ilAttributeCount = in.gpState.ilAttributeCount; - out.gpState.ilBindingCount = in.gpState.ilBindingCount; - - for (uint32_t i = 0; i < in.gpState.ilAttributeCount; i++) - out.gpState.ilAttributes[i] = in.gpState.ilAttributes[i]; - - for (uint32_t i = 0; i < in.gpState.ilBindingCount; i++) { - out.gpState.ilBindings[i] = in.gpState.ilBindings[i]; - out.gpState.ilDivisors[i] = in.gpState.ilDivisors[i]; - } - - out.gpState.rsDepthClipEnable = in.gpState.rsDepthClipEnable; - out.gpState.rsDepthBiasEnable = in.gpState.rsDepthBiasEnable; - out.gpState.rsPolygonMode = in.gpState.rsPolygonMode; - out.gpState.rsCullMode = in.gpState.rsCullMode; - out.gpState.rsFrontFace = in.gpState.rsFrontFace; - out.gpState.rsViewportCount = in.gpState.rsViewportCount; - out.gpState.rsSampleCount = in.gpState.rsSampleCount; - - out.gpState.msSampleCount = in.gpState.msSampleCount; - out.gpState.msSampleMask = in.gpState.msSampleMask; - out.gpState.msEnableAlphaToCoverage = in.gpState.msEnableAlphaToCoverage; - - out.gpState.dsEnableDepthTest = in.gpState.dsEnableDepthTest; - out.gpState.dsEnableDepthWrite = in.gpState.dsEnableDepthWrite; - out.gpState.dsEnableStencilTest = in.gpState.dsEnableStencilTest; - out.gpState.dsDepthCompareOp = in.gpState.dsDepthCompareOp; - out.gpState.dsStencilOpFront = in.gpState.dsStencilOpFront; - out.gpState.dsStencilOpBack = in.gpState.dsStencilOpBack; - - out.gpState.omEnableLogicOp = in.gpState.omEnableLogicOp; - out.gpState.omLogicOp = in.gpState.omLogicOp; - - for (uint32_t i = 0; i < 8; i++) { - out.gpState.omBlendAttachments[i] = in.gpState.omBlendAttachments[i]; - out.gpState.omComponentMapping[i] = in.gpState.omComponentMapping[i]; - } - - return true; - } - - - bool DxvkStateCache::convertEntryV5( - const DxvkStateCacheEntryV5& in, - DxvkStateCacheEntryV6& out) const { - out.shaders = in.shaders; - out.gpState = in.gpState; - out.format = in.format; - out.hash = in.hash; - - out.cpState.bsBindingMask = in.cpState.bsBindingMask; - return true; - } - - - bool DxvkStateCache::convertEntryV6( - const DxvkStateCacheEntryV6& in, - DxvkStateCacheEntry& out) const { - out.shaders = in.shaders; - out.format = in.format; - out.hash = in.hash; - - if (in.shaders.cs.eq(g_nullShaderKey)) { - // Graphics state - out.gpState.ia = DxvkIaInfo( - in.gpState.iaPrimitiveTopology, - in.gpState.iaPrimitiveRestart, - in.gpState.iaPatchVertexCount); - - out.gpState.il = DxvkIlInfo( - in.gpState.ilAttributeCount, - in.gpState.ilBindingCount); - - for (uint32_t i = 0; i < in.gpState.ilAttributeCount; i++) { - out.gpState.ilAttributes[i] = DxvkIlAttribute( - in.gpState.ilAttributes[i].location, - in.gpState.ilAttributes[i].binding, - in.gpState.ilAttributes[i].format, - in.gpState.ilAttributes[i].offset); - } - - for (uint32_t i = 0; i < in.gpState.ilBindingCount; i++) { - out.gpState.ilBindings[i] = DxvkIlBinding( - in.gpState.ilBindings[i].binding, - in.gpState.ilBindings[i].stride, - in.gpState.ilBindings[i].inputRate, - in.gpState.ilDivisors[i]); - } - - out.gpState.rs = DxvkRsInfo( - in.gpState.rsDepthClipEnable, - in.gpState.rsDepthBiasEnable, - in.gpState.rsPolygonMode, - in.gpState.rsCullMode, - in.gpState.rsFrontFace, - in.gpState.rsViewportCount, - in.gpState.rsSampleCount, - VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT); - - out.gpState.ms = DxvkMsInfo( - in.gpState.msSampleCount, - in.gpState.msSampleMask, - in.gpState.msEnableAlphaToCoverage); - - out.gpState.ds = DxvkDsInfo( - in.gpState.dsEnableDepthTest, - in.gpState.dsEnableDepthWrite, - in.gpState.dsEnableDepthBoundsTest, - in.gpState.dsEnableStencilTest, - in.gpState.dsDepthCompareOp); - - out.gpState.dsFront = DxvkDsStencilOp(in.gpState.dsStencilOpFront); - out.gpState.dsBack = DxvkDsStencilOp(in.gpState.dsStencilOpBack); - - out.gpState.om = DxvkOmInfo( - in.gpState.omEnableLogicOp, - in.gpState.omLogicOp); - - for (uint32_t i = 0; i < 8 && i < MaxNumRenderTargets; i++) { - out.gpState.omBlend[i] = DxvkOmAttachmentBlend( - in.gpState.omBlendAttachments[i].blendEnable, - in.gpState.omBlendAttachments[i].srcColorBlendFactor, - in.gpState.omBlendAttachments[i].dstColorBlendFactor, - in.gpState.omBlendAttachments[i].colorBlendOp, - in.gpState.omBlendAttachments[i].srcAlphaBlendFactor, - in.gpState.omBlendAttachments[i].dstAlphaBlendFactor, - in.gpState.omBlendAttachments[i].alphaBlendOp, - in.gpState.omBlendAttachments[i].colorWriteMask); - - out.gpState.omSwizzle[i] = DxvkOmAttachmentSwizzle( - in.gpState.omComponentMapping[i]); - } - - // Specialization constants - for (uint32_t i = 0; i < 8 && i < MaxNumSpecConstants; i++) - out.cpState.sc.specConstants[i] = in.cpState.scSpecConstants[i]; - } else { - for (uint32_t i = 0; i < 8 && i < MaxNumSpecConstants; i++) - out.gpState.sc.specConstants[i] = in.gpState.scSpecConstants[i]; - } - - return true; - } - - void DxvkStateCache::workerFunc() { env::setThreadName("dxvk-shader"); diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index f23c85f05..6419a797f 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -149,11 +149,6 @@ namespace dxvk { std::istream& stream, DxvkStateCacheHeader& header) const; - bool readCacheEntryV7( - uint32_t version, - std::istream& stream, - DxvkStateCacheEntry& entry) const; - bool readCacheEntry( uint32_t version, std::istream& stream, @@ -163,21 +158,6 @@ namespace dxvk { std::ostream& stream, DxvkStateCacheEntry& entry) const; - bool convertEntryV2( - DxvkStateCacheEntryV4& entry) const; - - bool convertEntryV4( - const DxvkStateCacheEntryV4& in, - DxvkStateCacheEntryV6& out) const; - - bool convertEntryV5( - const DxvkStateCacheEntryV5& in, - DxvkStateCacheEntryV6& out) const; - - bool convertEntryV6( - const DxvkStateCacheEntryV6& in, - DxvkStateCacheEntry& out) const; - void workerFunc(); void writerFunc(); diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index c60861ca6..a9c33b2d3 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -89,145 +89,4 @@ namespace dxvk { }; - /** - * \brief Version 4 graphics pipeline state - */ - struct DxvkGraphicsPipelineStateInfoV4 { - DxvkBindingMaskV8 bsBindingMask; - - VkPrimitiveTopology iaPrimitiveTopology; - VkBool32 iaPrimitiveRestart; - uint32_t iaPatchVertexCount; - - uint32_t ilAttributeCount; - uint32_t ilBindingCount; - VkVertexInputAttributeDescription ilAttributes[32]; - VkVertexInputBindingDescription ilBindings[32]; - uint32_t ilDivisors[32]; - - VkBool32 rsDepthClipEnable; - VkBool32 rsDepthBiasEnable; - VkPolygonMode rsPolygonMode; - VkCullModeFlags rsCullMode; - VkFrontFace rsFrontFace; - uint32_t rsViewportCount; - VkSampleCountFlags rsSampleCount; - - VkSampleCountFlags msSampleCount; - uint32_t msSampleMask; - VkBool32 msEnableAlphaToCoverage; - - VkCompareOp xsAlphaCompareOp; - - VkBool32 dsEnableDepthTest; - VkBool32 dsEnableDepthWrite; - VkBool32 dsEnableStencilTest; - VkCompareOp dsDepthCompareOp; - VkStencilOpState dsStencilOpFront; - VkStencilOpState dsStencilOpBack; - - VkBool32 omEnableLogicOp; - VkLogicOp omLogicOp; - VkPipelineColorBlendAttachmentState omBlendAttachments[8]; - VkComponentMapping omComponentMapping[8]; - }; - - - /** - * \brief Version 6 graphics pipeline state - */ - struct DxvkGraphicsPipelineStateInfoV6 { - DxvkBindingMaskV8 bsBindingMask; - - VkPrimitiveTopology iaPrimitiveTopology; - VkBool32 iaPrimitiveRestart; - uint32_t iaPatchVertexCount; - - uint32_t ilAttributeCount; - uint32_t ilBindingCount; - VkVertexInputAttributeDescription ilAttributes[32]; - VkVertexInputBindingDescription ilBindings[32]; - uint32_t ilDivisors[32]; - - VkBool32 rsDepthClipEnable; - VkBool32 rsDepthBiasEnable; - VkPolygonMode rsPolygonMode; - VkCullModeFlags rsCullMode; - VkFrontFace rsFrontFace; - uint32_t rsViewportCount; - VkSampleCountFlags rsSampleCount; - - VkSampleCountFlags msSampleCount; - uint32_t msSampleMask; - VkBool32 msEnableAlphaToCoverage; - - VkBool32 dsEnableDepthTest; - VkBool32 dsEnableDepthWrite; - VkBool32 dsEnableDepthBoundsTest; - VkBool32 dsEnableStencilTest; - VkCompareOp dsDepthCompareOp; - VkStencilOpState dsStencilOpFront; - VkStencilOpState dsStencilOpBack; - - VkBool32 omEnableLogicOp; - VkLogicOp omLogicOp; - VkPipelineColorBlendAttachmentState omBlendAttachments[8]; - VkComponentMapping omComponentMapping[8]; - - uint32_t scSpecConstants[8]; - }; - - - /** - * \brief Version 5 compute pipeline state - */ - struct DxvkComputePipelineStateInfoV5 { - DxvkBindingMaskV8 bsBindingMask; - }; - - - /** - * \brief Version 6 compute pipeline state - */ - struct DxvkComputePipelineStateInfoV6 { - DxvkBindingMaskV8 bsBindingMask; - uint32_t scSpecConstants[8]; - }; - - - /** - * \brief Version 4 state cache entry - */ - struct DxvkStateCacheEntryV4 { - DxvkStateCacheKey shaders; - DxvkGraphicsPipelineStateInfoV4 gpState; - DxvkComputePipelineStateInfoV5 cpState; - DxvkRenderPassFormat format; - Sha1Hash hash; - }; - - - /** - * \brief Version 5 state cache entry - */ - struct DxvkStateCacheEntryV5 { - DxvkStateCacheKey shaders; - DxvkGraphicsPipelineStateInfoV6 gpState; - DxvkComputePipelineStateInfoV5 cpState; - DxvkRenderPassFormat format; - Sha1Hash hash; - }; - - - /** - * \brief Version 6 state cache entry - */ - struct DxvkStateCacheEntryV6 { - DxvkStateCacheKey shaders; - DxvkGraphicsPipelineStateInfoV6 gpState; - DxvkComputePipelineStateInfoV6 cpState; - DxvkRenderPassFormat format; - Sha1Hash hash; - }; - } From e3a63d4faa70531cabf5603a0572e5d4c7b4d5bc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 2 Jul 2022 21:23:00 +0200 Subject: [PATCH 0115/1348] [dxvk] Bump state cache version to v12 And remove its reliance on the old render pass format struct. --- src/dxvk/dxvk_graphics.cpp | 35 ++++---- src/dxvk/dxvk_graphics.h | 26 ++---- src/dxvk/dxvk_state_cache.cpp | 144 ++++++++++++------------------ src/dxvk/dxvk_state_cache.h | 12 +-- src/dxvk/dxvk_state_cache_types.h | 38 +++++++- 5 files changed, 115 insertions(+), 140 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index e1644d103..756abad41 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -51,7 +51,7 @@ namespace dxvk { VkPipeline DxvkGraphicsPipeline::getPipelineHandle( const DxvkGraphicsPipelineStateInfo& state, const DxvkRenderPass* renderPass) { - DxvkGraphicsPipelineInstance* instance = this->findInstance(state, renderPass); + DxvkGraphicsPipelineInstance* instance = this->findInstance(state); if (unlikely(!instance)) { // Exit early if the state vector is invalid @@ -60,13 +60,13 @@ namespace dxvk { // Prevent other threads from adding new instances and check again std::lock_guard lock(m_mutex); - instance = this->findInstance(state, renderPass); + instance = this->findInstance(state); if (!instance) { // Keep pipeline object locked, at worst we're going to stall // a state cache worker and the current thread needs priority. - instance = this->createInstance(state, renderPass); - this->writePipelineStateToCache(state, renderPass->format()); + instance = this->createInstance(state); + this->writePipelineStateToCache(state); } } @@ -75,8 +75,7 @@ namespace dxvk { void DxvkGraphicsPipeline::compilePipeline( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* renderPass) { + const DxvkGraphicsPipelineStateInfo& state) { // Exit early if the state vector is invalid if (!this->validatePipelineState(state, false)) return; @@ -85,26 +84,24 @@ namespace dxvk { // similar pipelines concurrently is fragile on some drivers std::lock_guard lock(m_mutex); - if (!this->findInstance(state, renderPass)) - this->createInstance(state, renderPass); + if (!this->findInstance(state)) + this->createInstance(state); } DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::createInstance( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* renderPass) { - VkPipeline pipeline = this->createPipeline(state, renderPass); + const DxvkGraphicsPipelineStateInfo& state) { + VkPipeline pipeline = this->createPipeline(state); m_pipeMgr->m_numGraphicsPipelines += 1; - return &(*m_pipelines.emplace(state, renderPass, pipeline)); + return &(*m_pipelines.emplace(state, pipeline)); } DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::findInstance( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* renderPass) { + const DxvkGraphicsPipelineStateInfo& state) { for (auto& instance : m_pipelines) { - if (instance.isCompatible(state, renderPass)) + if (instance.isCompatible(state)) return &instance; } @@ -113,8 +110,7 @@ namespace dxvk { VkPipeline DxvkGraphicsPipeline::createPipeline( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* renderPass) const { + const DxvkGraphicsPipelineStateInfo& state) const { if (Logger::logLevel() <= LogLevel::Debug) { Logger::debug("Compiling graphics pipeline..."); this->logPipelineState(LogLevel::Debug, state); @@ -551,8 +547,7 @@ namespace dxvk { void DxvkGraphicsPipeline::writePipelineStateToCache( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPassFormat& format) const { + const DxvkGraphicsPipelineStateInfo& state) const { if (m_pipeMgr->m_stateCache == nullptr) return; @@ -563,7 +558,7 @@ namespace dxvk { if (m_shaders.gs != nullptr) key.gs = m_shaders.gs->getShaderKey(); if (m_shaders.fs != nullptr) key.fs = m_shaders.fs->getShaderKey(); - m_pipeMgr->m_stateCache->addGraphicsPipeline(key, state, format); + m_pipeMgr->m_stateCache->addGraphicsPipeline(key, state); } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 574d5d2cd..9d61570ca 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -94,15 +94,12 @@ namespace dxvk { DxvkGraphicsPipelineInstance() : m_stateVector (), - m_renderPass (nullptr), m_pipeline (VK_NULL_HANDLE) { } DxvkGraphicsPipelineInstance( const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* rp, VkPipeline pipe) : m_stateVector (state), - m_renderPass (rp), m_pipeline (pipe) { } /** @@ -113,10 +110,8 @@ namespace dxvk { * \returns \c true if the specialization is compatible */ bool isCompatible( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* rp) { - return m_renderPass == rp - && m_stateVector == state; + const DxvkGraphicsPipelineStateInfo& state) { + return m_stateVector == state; } /** @@ -130,7 +125,6 @@ namespace dxvk { private: DxvkGraphicsPipelineStateInfo m_stateVector; - const DxvkRenderPass* m_renderPass; VkPipeline m_pipeline; }; @@ -212,11 +206,9 @@ namespace dxvk { * Asynchronously compiles the given pipeline * and stores the result for future use. * \param [in] state Pipeline state vector - * \param [in] renderPass The render pass */ void compilePipeline( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* renderPass); + const DxvkGraphicsPipelineStateInfo& state); private: @@ -238,16 +230,13 @@ namespace dxvk { sync::List m_pipelines; DxvkGraphicsPipelineInstance* createInstance( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* renderPass); + const DxvkGraphicsPipelineStateInfo& state); DxvkGraphicsPipelineInstance* findInstance( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* renderPass); + const DxvkGraphicsPipelineStateInfo& state); VkPipeline createPipeline( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* renderPass) const; + const DxvkGraphicsPipelineStateInfo& state) const; void destroyPipeline( VkPipeline pipeline) const; @@ -264,8 +253,7 @@ namespace dxvk { bool trusted) const; void writePipelineStateToCache( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPassFormat& format) const; + const DxvkGraphicsPipelineStateInfo& state) const; void logPipelineState( LogLevel level, diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 16f965ba6..b9a708330 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -62,6 +62,14 @@ namespace dxvk { return read(data); } + bool read(DxvkRtInfo& data, uint32_t version) { + // v12 introduced this field + if (version < 12) + return true; + + return read(data); + } + bool read(DxvkIlBinding& data, uint32_t version) { if (version < 10) { DxvkIlBindingV9 v9; @@ -76,6 +84,34 @@ namespace dxvk { return read(data); } + + bool read(DxvkRenderPassFormatV11& data, uint32_t version) { + uint8_t sampleCount = 0; + uint8_t imageFormat = 0; + uint8_t imageLayout = 0; + + if (!read(sampleCount) + || !read(imageFormat) + || !read(imageLayout)) + return false; + + data.sampleCount = VkSampleCountFlagBits(sampleCount); + data.depth.format = VkFormat(imageFormat); + data.depth.layout = unpackImageLayoutV11(imageLayout); + + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + if (!read(imageFormat) + || !read(imageLayout)) + return false; + + data.color[i].format = VkFormat(imageFormat); + data.color[i].layout = unpackImageLayoutV11(imageLayout); + } + + return true; + } + + template bool write(const T& data) { if (m_size + sizeof(T) > MaxSize) @@ -114,6 +150,15 @@ namespace dxvk { return true; } + static VkImageLayout unpackImageLayoutV11( + uint8_t layout) { + switch (layout) { + case 0x80: return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; + case 0x81: return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL; + default: return VkImageLayout(layout); + } + } + }; @@ -199,8 +244,7 @@ namespace dxvk { void DxvkStateCache::addGraphicsPipeline( const DxvkStateCacheKey& shaders, - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPassFormat& format) { + const DxvkGraphicsPipelineStateInfo& state) { if (shaders.vs.eq(g_nullShaderKey)) return; @@ -210,7 +254,7 @@ namespace dxvk { for (auto e = entries.first; e != entries.second; e++) { const DxvkStateCacheEntry& entry = m_entries[e->second]; - if (entry.format.eq(format) && entry.gpState == state) + if (entry.gpState == state) return; } @@ -218,8 +262,7 @@ namespace dxvk { std::unique_lock lock(m_writerLock); m_writerQueue.push({ shaders, state, - DxvkComputePipelineStateInfo(), - format, g_nullHash }); + DxvkComputePipelineStateInfo(), g_nullHash }); m_writerCond.notify_one(); createWriter(); @@ -244,8 +287,7 @@ namespace dxvk { std::unique_lock lock(m_writerLock); m_writerQueue.push({ shaders, - DxvkGraphicsPipelineStateInfo(), state, - DxvkRenderPassFormat(), g_nullHash }); + DxvkGraphicsPipelineStateInfo(), state, g_nullHash }); m_writerCond.notify_one(); createWriter(); @@ -360,11 +402,7 @@ namespace dxvk { for (auto e = entries.first; e != entries.second; e++) { const auto& entry = m_entries[e->second]; - - if (m_passManager->validateRenderPassFormat(entry.format)) { - auto rp = m_passManager->getRenderPass(entry.format); - pipeline->compilePipeline(entry.gpState, rp); - } + pipeline->compilePipeline(entry.gpState); } } else { auto pipeline = m_pipeManager->createComputePipeline(item.cp); @@ -504,31 +542,12 @@ namespace dxvk { return false; } else { // Read packed render pass format - uint8_t sampleCount = 0; - uint8_t imageFormat = 0; - uint8_t imageLayout = 0; - - if (!data.read(sampleCount, version) - || !data.read(imageFormat, version) - || !data.read(imageLayout, version)) - return false; - - entry.format.sampleCount = VkSampleCountFlagBits(sampleCount); - entry.format.depth.format = VkFormat(imageFormat); - entry.format.depth.layout = unpackImageLayout(imageLayout); - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (!data.read(imageFormat, version) - || !data.read(imageLayout, version)) - return false; - - entry.format.color[i].format = VkFormat(imageFormat); - entry.format.color[i].layout = unpackImageLayout(imageLayout); + if (version < 12) { + DxvkRenderPassFormatV11 v11; + data.read(v11, version); + entry.gpState.rt = v11.convert(); } - if (!validateRenderPassFormat(entry.format)) - return false; - // Read common pipeline state if (!data.read(dummyBindingMask, version) || !data.read(entry.gpState.ia, version) @@ -537,6 +556,7 @@ namespace dxvk { || !data.read(entry.gpState.ms, version) || !data.read(entry.gpState.ds, version) || !data.read(entry.gpState.om, version) + || !data.read(entry.gpState.rt, version) || !data.read(entry.gpState.dsFront, version) || !data.read(entry.gpState.dsBack, version)) return false; @@ -608,16 +628,6 @@ namespace dxvk { } if (!(stageMask & VK_SHADER_STAGE_COMPUTE_BIT)) { - // Pack render pass format - data.write(uint8_t(entry.format.sampleCount)); - data.write(uint8_t(entry.format.depth.format)); - data.write(packImageLayout(entry.format.depth.layout)); - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - data.write(uint8_t(entry.format.color[i].format)); - data.write(packImageLayout(entry.format.color[i].layout)); - } - // Write out common pipeline state data.write(entry.gpState.ia); data.write(entry.gpState.il); @@ -625,6 +635,7 @@ namespace dxvk { data.write(entry.gpState.ms); data.write(entry.gpState.ds); data.write(entry.gpState.om); + data.write(entry.gpState.rt); data.write(entry.gpState.dsFront); data.write(entry.gpState.dsBack); @@ -785,47 +796,4 @@ namespace dxvk { return env::getEnvVar("DXVK_STATE_CACHE_PATH"); } - - uint8_t DxvkStateCache::packImageLayout( - VkImageLayout layout) { - switch (layout) { - case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return 0x80; - case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return 0x81; - default: return uint8_t(layout); - } - } - - - VkImageLayout DxvkStateCache::unpackImageLayout( - uint8_t layout) { - switch (layout) { - case 0x80: return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; - case 0x81: return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL; - default: return VkImageLayout(layout); - } - } - - - bool DxvkStateCache::validateRenderPassFormat( - const DxvkRenderPassFormat& format) { - bool valid = true; - - if (format.depth.format) { - valid &= format.depth.layout == VK_IMAGE_LAYOUT_GENERAL - || format.depth.layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL - || format.depth.layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL - || format.depth.layout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL - || format.depth.layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL; - } - - for (uint32_t i = 0; i < MaxNumRenderTargets && valid; i++) { - if (format.color[i].format) { - valid &= format.color[i].layout == VK_IMAGE_LAYOUT_GENERAL - || format.color[i].layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - } - } - - return valid; - } - } diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index 6419a797f..11cbac986 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -45,8 +45,7 @@ namespace dxvk { */ void addGraphicsPipeline( const DxvkStateCacheKey& shaders, - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPassFormat& format); + const DxvkGraphicsPipelineStateInfo& state); /** * Adds a compute pipeline to the cache @@ -170,15 +169,6 @@ namespace dxvk { std::string getCacheDir() const; - static uint8_t packImageLayout( - VkImageLayout layout); - - static VkImageLayout unpackImageLayout( - uint8_t layout); - - static bool validateRenderPassFormat( - const DxvkRenderPassFormat& format); - }; } diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index a9c33b2d3..758f7cf65 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -38,7 +38,6 @@ namespace dxvk { DxvkStateCacheKey shaders; DxvkGraphicsPipelineStateInfo gpState; DxvkComputePipelineStateInfo cpState; - DxvkRenderPassFormat format; Sha1Hash hash; }; @@ -52,7 +51,7 @@ namespace dxvk { */ struct DxvkStateCacheHeader { char magic[4] = { 'D', 'X', 'V', 'K' }; - uint32_t version = 11; + uint32_t version = 12; uint32_t entrySize = 0; /* no longer meaningful */ }; @@ -89,4 +88,39 @@ namespace dxvk { }; + /** + * \brief Old attachment format struct + */ + struct DxvkAttachmentFormatV11 { + VkFormat format = VK_FORMAT_UNDEFINED; + VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED; + }; + + + /** + * \brief Old render pass format struct + */ + struct DxvkRenderPassFormatV11 { + VkSampleCountFlagBits sampleCount; + DxvkAttachmentFormatV11 depth; + DxvkAttachmentFormatV11 color[MaxNumRenderTargets]; + + DxvkRtInfo convert() const { + VkImageAspectFlags readOnlyAspects = 0; + auto depthFormatInfo = imageFormatInfo(depth.format); + + if (depth.format && depthFormatInfo) { + readOnlyAspects = depthFormatInfo->aspectMask + & ~vk::getWritableAspectsForLayout(depth.layout); + } + + std::array colorFormats; + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) + colorFormats[i] = color[i].format; + + return DxvkRtInfo(MaxNumRenderTargets, colorFormats.data(), + depth.format, readOnlyAspects); + } + }; + } From e8f3d9b040e2d0d7f0a3fb939f355ad812152e44 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 2 Jul 2022 21:32:17 +0200 Subject: [PATCH 0116/1348] [dxvk] Remove render pass and framebuffer objects --- src/dxvk/dxvk_cmdlist.h | 13 -- src/dxvk/dxvk_context.cpp | 20 +- src/dxvk/dxvk_context.h | 4 - src/dxvk/dxvk_device.cpp | 6 - src/dxvk/dxvk_device.h | 9 - src/dxvk/dxvk_framebuffer.cpp | 81 +-------- src/dxvk/dxvk_framebuffer.h | 71 +------- src/dxvk/dxvk_graphics.cpp | 3 +- src/dxvk/dxvk_graphics.h | 5 +- src/dxvk/dxvk_objects.h | 8 +- src/dxvk/dxvk_pipemanager.cpp | 5 +- src/dxvk/dxvk_pipemanager.h | 3 +- src/dxvk/dxvk_renderpass.cpp | 332 ---------------------------------- src/dxvk/dxvk_renderpass.h | 175 +----------------- src/dxvk/dxvk_state_cache.cpp | 6 +- src/dxvk/dxvk_state_cache.h | 4 +- src/dxvk/meson.build | 1 - 17 files changed, 15 insertions(+), 731 deletions(-) delete mode 100644 src/dxvk/dxvk_renderpass.cpp diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index f6d98855d..9a9427700 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -259,14 +259,6 @@ namespace dxvk { } - void cmdBeginRenderPass( - const VkRenderPassBeginInfo* pRenderPassBegin, - VkSubpassContents contents) { - m_vkd->vkCmdBeginRenderPass(m_execBuffer, - pRenderPassBegin, contents); - } - - void cmdBeginTransformFeedback( uint32_t firstBuffer, uint32_t bufferCount, @@ -600,11 +592,6 @@ namespace dxvk { } - void cmdEndRenderPass() { - m_vkd->vkCmdEndRenderPass(m_execBuffer); - } - - void cmdEndTransformFeedback( uint32_t firstBuffer, uint32_t bufferCount, diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 115f7acaa..765eb679a 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4420,8 +4420,7 @@ namespace dxvk { : DxvkContextFlag::GpDirtyStencilRef); // Retrieve and bind actual Vulkan pipeline handle - VkPipeline pipeline = m_state.gp.pipeline->getPipelineHandle( - m_state.gp.state, m_state.om.framebufferInfo.renderPass()); + VkPipeline pipeline = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state); if (unlikely(!pipeline)) return false; @@ -4660,10 +4659,7 @@ namespace dxvk { DxvkFramebufferInfo DxvkContext::makeFramebufferInfo( const DxvkRenderTargets& renderTargets) { - auto renderPassFormat = DxvkFramebufferInfo::getRenderPassFormat(renderTargets); - auto renderPassObject = m_common->renderPassPool().getRenderPass(renderPassFormat); - - return DxvkFramebufferInfo(renderTargets, m_device->getDefaultFramebufferSize(), renderPassObject); + return DxvkFramebufferInfo(renderTargets, m_device->getDefaultFramebufferSize()); } @@ -5527,18 +5523,6 @@ namespace dxvk { } - Rc DxvkContext::lookupFramebuffer( - const DxvkFramebufferInfo& framebufferInfo) { - DxvkFramebufferKey key = framebufferInfo.key(); - size_t idx = key.hash() % m_framebufferCache.size(); - - if (m_framebufferCache[idx] == nullptr || !m_framebufferCache[idx]->key().eq(key)) - m_framebufferCache[idx] = m_device->createFramebuffer(framebufferInfo); - - return m_framebufferCache[idx]; - } - - Rc DxvkContext::createZeroBuffer( VkDeviceSize size) { if (m_zeroBuffer != nullptr && m_zeroBuffer->info().size >= size) diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index fb6fdddf7..a6a9c3291 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1156,7 +1156,6 @@ namespace dxvk { std::array m_rc; std::array m_gpLookupCache = { }; std::array m_cpLookupCache = { }; - std::array, 512> m_framebufferCache = { }; void blitImageFb( const Rc& dstImage, @@ -1411,9 +1410,6 @@ namespace dxvk { DxvkComputePipeline* lookupComputePipeline( const DxvkComputePipelineShaders& shaders); - Rc lookupFramebuffer( - const DxvkFramebufferInfo& framebufferInfo); - Rc createZeroBuffer( VkDeviceSize size); diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 87a29c568..36d2563a7 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -102,12 +102,6 @@ namespace dxvk { } - Rc DxvkDevice::createFramebuffer( - const DxvkFramebufferInfo& info) { - return new DxvkFramebuffer(m_vkd, info); - } - - Rc DxvkDevice::createBuffer( const DxvkBufferCreateInfo& createInfo, VkMemoryPropertyFlags memoryType) { diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 6877b3107..65730cbd3 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -258,15 +258,6 @@ namespace dxvk { VkQueryControlFlags flags, uint32_t index); - /** - * \brief Creates framebuffer for a set of render targets - * - * \param [in] info Framebuffer info - * \returns The framebuffer object - */ - Rc createFramebuffer( - const DxvkFramebufferInfo& info); - /** * \brief Creates a buffer object * diff --git a/src/dxvk/dxvk_framebuffer.cpp b/src/dxvk/dxvk_framebuffer.cpp index 226e3f11e..e911c0a26 100644 --- a/src/dxvk/dxvk_framebuffer.cpp +++ b/src/dxvk/dxvk_framebuffer.cpp @@ -9,11 +9,9 @@ namespace dxvk { DxvkFramebufferInfo::DxvkFramebufferInfo( const DxvkRenderTargets& renderTargets, - const DxvkFramebufferSize& defaultSize, - DxvkRenderPass* renderPass) + const DxvkFramebufferSize& defaultSize) : m_renderTargets (renderTargets), - m_renderSize (computeRenderSize(defaultSize)), - m_renderPass (renderPass) { + m_renderSize (computeRenderSize(defaultSize)) { for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if (m_renderTargets.color[i].view != nullptr) { @@ -70,24 +68,6 @@ namespace dxvk { } - DxvkFramebufferKey DxvkFramebufferInfo::key() const { - DxvkFramebufferKey result = { }; - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (m_renderTargets.color[i].view != nullptr) - result.colorViews[i] = m_renderTargets.color[i].view->cookie(); - } - - if (m_renderTargets.depth.view != nullptr) - result.depthView = m_renderTargets.depth.view->cookie(); - - if (result.renderPass) - result.renderPass = m_renderPass->getDefaultHandle(); - - return result; - } - - DxvkRtInfo DxvkFramebufferInfo::getRtInfo() const { VkFormat depthStencilFormat = VK_FORMAT_UNDEFINED; VkImageAspectFlags depthStencilReadOnlyAspects = 0; @@ -109,27 +89,6 @@ namespace dxvk { } - DxvkRenderPassFormat DxvkFramebufferInfo::getRenderPassFormat(const DxvkRenderTargets& renderTargets) { - DxvkRenderPassFormat format; - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (renderTargets.color[i].view != nullptr) { - format.sampleCount = renderTargets.color[i].view->imageInfo().sampleCount; - format.color[i].format = renderTargets.color[i].view->info().format; - format.color[i].layout = renderTargets.color[i].layout; - } - } - - if (renderTargets.depth.view != nullptr) { - format.sampleCount = renderTargets.depth.view->imageInfo().sampleCount; - format.depth.format = renderTargets.depth.view->info().format; - format.depth.layout = renderTargets.depth.layout; - } - - return format; - } - - DxvkFramebufferSize DxvkFramebufferInfo::computeRenderSize( const DxvkFramebufferSize& defaultSize) const { // Some games bind render targets of a different size and @@ -163,40 +122,4 @@ namespace dxvk { return DxvkFramebufferSize { extent.width, extent.height, layers }; } - - DxvkFramebuffer::DxvkFramebuffer( - const Rc& vkd, - const DxvkFramebufferInfo& info) - : m_vkd(vkd), m_key(info.key()) { - std::array views; - uint32_t attachmentCount = 0; - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (info.getColorTarget(i).view != nullptr) - views[attachmentCount++] = info.getColorTarget(i).view->handle(); - } - - if (info.getDepthTarget().view != nullptr) - views[attachmentCount++] = info.getDepthTarget().view->handle(); - - VkFramebufferCreateInfo fbInfo; - fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - fbInfo.pNext = nullptr; - fbInfo.flags = 0; - fbInfo.renderPass = info.renderPass()->getDefaultHandle(); - fbInfo.attachmentCount = attachmentCount; - fbInfo.pAttachments = views.data(); - fbInfo.width = info.size().width; - fbInfo.height = info.size().height; - fbInfo.layers = info.size().layers; - - if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &fbInfo, nullptr, &m_handle) != VK_SUCCESS) - Logger::err("DxvkFramebuffer: Failed to create framebuffer object"); - } - - - DxvkFramebuffer::~DxvkFramebuffer() { - m_vkd->vkDestroyFramebuffer(m_vkd->device(), m_handle, nullptr); - } - } \ No newline at end of file diff --git a/src/dxvk/dxvk_framebuffer.h b/src/dxvk/dxvk_framebuffer.h index c0eb8919d..b7cb1d2b4 100644 --- a/src/dxvk/dxvk_framebuffer.h +++ b/src/dxvk/dxvk_framebuffer.h @@ -94,8 +94,7 @@ namespace dxvk { DxvkFramebufferInfo( const DxvkRenderTargets& renderTargets, - const DxvkFramebufferSize& defaultSize, - DxvkRenderPass* renderPass); + const DxvkFramebufferSize& defaultSize); ~DxvkFramebufferInfo(); @@ -115,14 +114,6 @@ namespace dxvk { return m_renderSize; } - /** - * \brief Render pass - * \returns Render pass - */ - DxvkRenderPass* renderPass() const { - return m_renderPass; - } - /** * \brief Framebuffer sample count * @@ -220,35 +211,17 @@ namespace dxvk { */ bool isWritable(uint32_t attachmentIndex, VkImageAspectFlags aspects) const; - /** - * \brief Generates framebuffer key - * \returns Framebuffer key - */ - DxvkFramebufferKey key() const; - /** * \brief Generates render target state * \returns Render target state info */ DxvkRtInfo getRtInfo() const; - /** - * \brief Generatess render pass format - * - * This render pass format can be used to - * look up a compatible render pass. - * \param [in] renderTargets Render targets - * \returns The render pass format - */ - static DxvkRenderPassFormat getRenderPassFormat( - const DxvkRenderTargets& renderTargets); - private: DxvkRenderTargets m_renderTargets; DxvkFramebufferSize m_renderSize = { 0u, 0u, 0u }; VkSampleCountFlags m_sampleCount = 0; - DxvkRenderPass* m_renderPass; uint32_t m_attachmentCount = 0; std::array m_attachments; @@ -260,47 +233,5 @@ namespace dxvk { const Rc& renderTarget) const; }; - - - - /** - * \brief Framebuffer - * - * A framebuffer either stores a set of image views - * that will be used as render targets, or in case - * no render targets are attached, fixed dimensions. - */ - class DxvkFramebuffer : public DxvkResource { - - public: - - DxvkFramebuffer( - const Rc& vkd, - const DxvkFramebufferInfo& info); - - ~DxvkFramebuffer(); - - /** - * \brief Framebuffer handle - * \returns Framebuffer handle - */ - VkFramebuffer handle() const { - return m_handle; - } - - /** - * \brief Framebuffer key - */ - const DxvkFramebufferKey& key() const { - return m_key; - } - - private: - - Rc m_vkd; - VkFramebuffer m_handle; - DxvkFramebufferKey m_key; - - }; } \ No newline at end of file diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 756abad41..09420d705 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -49,8 +49,7 @@ namespace dxvk { VkPipeline DxvkGraphicsPipeline::getPipelineHandle( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* renderPass) { + const DxvkGraphicsPipelineStateInfo& state) { DxvkGraphicsPipelineInstance* instance = this->findInstance(state); if (unlikely(!instance)) { diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 9d61570ca..b457fee9e 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -106,7 +106,6 @@ namespace dxvk { * \brief Checks for matching pipeline state * * \param [in] stateVector Graphics pipeline state - * \param [in] renderPass Render pass handle * \returns \c true if the specialization is compatible */ bool isCompatible( @@ -193,12 +192,10 @@ namespace dxvk { * Retrieves a pipeline handle for the given pipeline * state. If necessary, a new pipeline will be created. * \param [in] state Pipeline state vector - * \param [in] renderPass The render pass * \returns Pipeline handle */ VkPipeline getPipelineHandle( - const DxvkGraphicsPipelineStateInfo& state, - const DxvkRenderPass* renderPass); + const DxvkGraphicsPipelineStateInfo& state); /** * \brief Compiles a pipeline diff --git a/src/dxvk/dxvk_objects.h b/src/dxvk/dxvk_objects.h index aaa9e19bf..c8179d05a 100644 --- a/src/dxvk/dxvk_objects.h +++ b/src/dxvk/dxvk_objects.h @@ -24,8 +24,7 @@ namespace dxvk { DxvkObjects(DxvkDevice* device) : m_device (device), m_memoryManager (device), - m_renderPassPool (device), - m_pipelineManager (device, &m_renderPassPool), + m_pipelineManager (device), m_eventPool (device), m_queryPool (device), m_dummyResources (device) { @@ -36,10 +35,6 @@ namespace dxvk { return m_memoryManager; } - DxvkRenderPassPool& renderPassPool() { - return m_renderPassPool; - } - DxvkPipelineManager& pipelineManager() { return m_pipelineManager; } @@ -81,7 +76,6 @@ namespace dxvk { DxvkDevice* m_device; DxvkMemoryAllocator m_memoryManager; - DxvkRenderPassPool m_renderPassPool; DxvkPipelineManager m_pipelineManager; DxvkGpuEventPool m_eventPool; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 3f0120ccf..da6943e18 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -5,14 +5,13 @@ namespace dxvk { DxvkPipelineManager::DxvkPipelineManager( - DxvkDevice* device, - DxvkRenderPassPool* passManager) + DxvkDevice* device) : m_device (device), m_cache (new DxvkPipelineCache(device->vkd())) { std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE"); if (useStateCache != "0" && device->config().enableStateCache) - m_stateCache = new DxvkStateCache(device, this, passManager); + m_stateCache = new DxvkStateCache(device, this); } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 35e711023..be69be3aa 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -38,8 +38,7 @@ namespace dxvk { public: DxvkPipelineManager( - DxvkDevice* device, - DxvkRenderPassPool* passManager); + DxvkDevice* device); ~DxvkPipelineManager(); diff --git a/src/dxvk/dxvk_renderpass.cpp b/src/dxvk/dxvk_renderpass.cpp deleted file mode 100644 index 2bac17087..000000000 --- a/src/dxvk/dxvk_renderpass.cpp +++ /dev/null @@ -1,332 +0,0 @@ -#include - -#include "dxvk_device.h" -#include "dxvk_renderpass.h" - -namespace dxvk { - - bool DxvkRenderPassFormat::eq(const DxvkRenderPassFormat& fmt) const { - bool eq = sampleCount == fmt.sampleCount; - - for (uint32_t i = 0; i < MaxNumRenderTargets && eq; i++) { - eq &= color[i].format == fmt.color[i].format - && color[i].layout == fmt.color[i].layout; - } - - eq &= depth.format == fmt.depth.format - && depth.layout == fmt.depth.layout; - - return eq; - } - - - size_t DxvkRenderPassFormat::hash() const { - DxvkHashState state; - state.add(uint32_t(sampleCount)); - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - state.add(uint32_t(color[i].format)); - state.add(uint32_t(color[i].layout)); - } - - state.add(uint32_t(depth.format)); - state.add(uint32_t(depth.layout)); - return state; - } - - - DxvkRenderPass::DxvkRenderPass( - const Rc& vkd, - const DxvkRenderPassFormat& fmt) - : m_vkd(vkd), m_format(fmt), - m_default(createRenderPass(DxvkRenderPassOps())) { - - } - - - DxvkRenderPass::~DxvkRenderPass() { - m_vkd->vkDestroyRenderPass(m_vkd->device(), m_default, nullptr); - - for (const auto& i : m_instances) { - m_vkd->vkDestroyRenderPass( - m_vkd->device(), i.handle, nullptr); - } - } - - - bool DxvkRenderPass::hasCompatibleFormat(const DxvkRenderPassFormat& fmt) const { - return m_format.eq(fmt); - } - - - VkRenderPass DxvkRenderPass::getHandle(const DxvkRenderPassOps& ops) { - VkRenderPass handle = this->findHandle(ops); - - if (unlikely(!handle)) { - std::lock_guard lock(m_mutex); - handle = this->findHandle(ops); - - if (!handle) { - handle = this->createRenderPass(ops); - m_instances.insert({ ops, handle }); - } - } - - return handle; - } - - - VkRenderPass DxvkRenderPass::findHandle(const DxvkRenderPassOps& ops) { - for (const auto& i : m_instances) { - if (compareOps(i.ops, ops)) - return i.handle; - } - - return VK_NULL_HANDLE; - } - - - VkRenderPass DxvkRenderPass::createRenderPass(const DxvkRenderPassOps& ops) { - std::vector attachments; - - VkAttachmentReference depthRef; - std::array colorRef; - - // Render passes may not require the previous - // contents of the attachments to be preserved. - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (m_format.color[i].format != VK_FORMAT_UNDEFINED) { - VkAttachmentDescription desc; - desc.flags = 0; - desc.format = m_format.color[i].format; - desc.samples = m_format.sampleCount; - desc.loadOp = ops.colorOps[i].loadOp; - desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - desc.initialLayout = ops.colorOps[i].loadLayout; - desc.finalLayout = ops.colorOps[i].storeLayout; - - colorRef[i].attachment = attachments.size(); - colorRef[i].layout = m_format.color[i].layout; - - attachments.push_back(desc); - } else { - colorRef[i].attachment = VK_ATTACHMENT_UNUSED; - colorRef[i].layout = VK_IMAGE_LAYOUT_UNDEFINED; - } - } - - if (m_format.depth.format != VK_FORMAT_UNDEFINED) { - VkAttachmentDescription desc; - desc.flags = 0; - desc.format = m_format.depth.format; - desc.samples = m_format.sampleCount; - desc.loadOp = ops.depthOps.loadOpD; - desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - desc.stencilLoadOp = ops.depthOps.loadOpS; - desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - desc.initialLayout = ops.depthOps.loadLayout; - desc.finalLayout = ops.depthOps.storeLayout; - - depthRef.attachment = attachments.size(); - depthRef.layout = m_format.depth.layout; - - attachments.push_back(desc); - } else { - depthRef.attachment = VK_ATTACHMENT_UNUSED; - depthRef.layout = VK_IMAGE_LAYOUT_UNDEFINED; - } - - VkSubpassDescription subpass; - subpass.flags = 0; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.inputAttachmentCount = 0; - subpass.pInputAttachments = nullptr; - subpass.colorAttachmentCount = colorRef.size(); - subpass.pColorAttachments = colorRef.data(); - subpass.pResolveAttachments = nullptr; - subpass.pDepthStencilAttachment = &depthRef; - subpass.preserveAttachmentCount = 0; - subpass.pPreserveAttachments = nullptr; - - if (m_format.depth.format == VK_FORMAT_UNDEFINED) - subpass.pDepthStencilAttachment = nullptr; - - std::array subpassDeps; - uint32_t subpassDepCount = 0; - - VkPipelineStageFlags renderStages = 0; - VkAccessFlags renderAccess = 0; - - if (m_format.depth.format) { - renderStages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT - | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; - - VkImageAspectFlags loadAspects = 0; - - if (ops.depthOps.loadOpD == VK_ATTACHMENT_LOAD_OP_LOAD) - loadAspects |= VK_IMAGE_ASPECT_DEPTH_BIT; - if (ops.depthOps.loadOpS == VK_ATTACHMENT_LOAD_OP_LOAD) - loadAspects |= VK_IMAGE_ASPECT_STENCIL_BIT; - - if (loadAspects & imageFormatInfo(m_format.depth.format)->aspectMask) - renderAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - - if (m_format.depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) - renderAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - - if (m_format.depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { - renderStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - renderAccess |= VK_ACCESS_SHADER_READ_BIT; - } - } - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (!m_format.color[i].format) - continue; - - renderStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - renderAccess |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - - if (ops.colorOps[i].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD) - renderAccess |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - } - - if (renderStages) { - subpassDeps[subpassDepCount++] = { - VK_SUBPASS_EXTERNAL, 0, - renderStages, renderStages, - 0, renderAccess }; - } - - if (ops.barrier.srcStages & ( - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | - VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT)) { - subpassDeps[subpassDepCount++] = { 0, 0, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_ACCESS_SHADER_READ_BIT, - VK_DEPENDENCY_BY_REGION_BIT }; - } - - if (ops.barrier.srcStages && ops.barrier.dstStages) { - subpassDeps[subpassDepCount++] = { - 0, VK_SUBPASS_EXTERNAL, - ops.barrier.srcStages, - ops.barrier.dstStages, - ops.barrier.srcAccess, - ops.barrier.dstAccess, 0 }; - } - - VkRenderPassCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.attachmentCount = attachments.size(); - info.pAttachments = attachments.data(); - info.subpassCount = 1; - info.pSubpasses = &subpass; - info.dependencyCount = subpassDepCount; - info.pDependencies = subpassDepCount ? subpassDeps.data() : nullptr; - - VkRenderPass renderPass = VK_NULL_HANDLE; - - if (m_vkd->vkCreateRenderPass(m_vkd->device(), &info, nullptr, &renderPass) != VK_SUCCESS) { - Logger::err("DxvkRenderPass: Failed to create render pass object"); - return VK_NULL_HANDLE; - } - - return renderPass; - } - - - bool DxvkRenderPass::compareOps( - const DxvkRenderPassOps& a, - const DxvkRenderPassOps& b) { - bool eq = a.barrier.srcStages == b.barrier.srcStages - && a.barrier.srcAccess == b.barrier.srcAccess - && a.barrier.dstStages == b.barrier.dstStages - && a.barrier.dstAccess == b.barrier.dstAccess; - - if (eq) { - eq &= a.depthOps.loadOpD == b.depthOps.loadOpD - && a.depthOps.loadOpS == b.depthOps.loadOpS - && a.depthOps.loadLayout == b.depthOps.loadLayout - && a.depthOps.storeLayout == b.depthOps.storeLayout; - } - - for (uint32_t i = 0; i < MaxNumRenderTargets && eq; i++) { - eq &= a.colorOps[i].loadOp == b.colorOps[i].loadOp - && a.colorOps[i].loadLayout == b.colorOps[i].loadLayout - && a.colorOps[i].storeLayout == b.colorOps[i].storeLayout; - } - - return eq; - } - - - DxvkRenderPassPool::DxvkRenderPassPool(const DxvkDevice* device) - : m_device(device) { - - } - - - DxvkRenderPassPool::~DxvkRenderPassPool() { - - } - - - DxvkRenderPass* DxvkRenderPassPool::getRenderPass(const DxvkRenderPassFormat& fmt) { - std::lock_guard lock(m_mutex); - - auto entry = m_renderPasses.find(fmt); - if (entry != m_renderPasses.end()) - return &entry->second; - - auto result = m_renderPasses.emplace(std::piecewise_construct, - std::tuple(fmt), - std::tuple(m_device->vkd(), fmt)); - return &result.first->second; - } - - - bool DxvkRenderPassPool::validateRenderPassFormat( - const DxvkRenderPassFormat& fmt) { - Rc adapter = m_device->adapter(); - - if (fmt.depth.format) { - VkFormatProperties depthInfo = adapter->formatProperties(fmt.depth.format); - VkFormatFeatureFlags depthFlags = depthInfo.linearTilingFeatures | depthInfo.optimalTilingFeatures; - - if (!(depthFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) - return false; - - if (fmt.depth.layout != VK_IMAGE_LAYOUT_GENERAL - && fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL - && fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL - && fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL - && fmt.depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) - return false; - } - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (fmt.color[i].format) { - VkFormatProperties colorInfo = adapter->formatProperties(fmt.color[i].format); - VkFormatFeatureFlags colorFlags = colorInfo.linearTilingFeatures | colorInfo.optimalTilingFeatures; - - if (!(colorFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) - return false; - - if (fmt.color[i].layout != VK_IMAGE_LAYOUT_GENERAL - && fmt.color[i].layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) - return false; - } - } - - return true; - } - -} \ No newline at end of file diff --git a/src/dxvk/dxvk_renderpass.h b/src/dxvk/dxvk_renderpass.h index 2dff87880..f98b34964 100644 --- a/src/dxvk/dxvk_renderpass.h +++ b/src/dxvk/dxvk_renderpass.h @@ -14,35 +14,6 @@ namespace dxvk { class DxvkDevice; - /** - * \brief Format and layout for a render target - * - * Stores the image format of the attachment and - * the image layout that is used while rendering. - */ - struct DxvkAttachmentFormat { - VkFormat format = VK_FORMAT_UNDEFINED; - VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED; - }; - - - /** - * \brief Render pass format - * - * Stores the attachment formats for all depth and - * color attachments, as well as the sample count. - */ - struct DxvkRenderPassFormat { - VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; - DxvkAttachmentFormat depth; - DxvkAttachmentFormat color[MaxNumRenderTargets]; - - bool eq(const DxvkRenderPassFormat& fmt) const; - - size_t hash() const; - }; - - /** * \brief Color attachment transitions * @@ -96,149 +67,5 @@ namespace dxvk { DxvkDepthAttachmentOps depthOps; DxvkColorAttachmentOps colorOps[MaxNumRenderTargets]; }; - - - /** - * \brief Render pass object - * - * Manages a set of compatible render passes, i.e. - * render passes which share the same format but - * may differ in their attachment operations. - */ - class DxvkRenderPass { - - public: - - DxvkRenderPass( - const Rc& vkd, - const DxvkRenderPassFormat& fmt); - - ~DxvkRenderPass(); - - /** - * \brief Retrieves render pass format - * \returns The render pass format - */ - DxvkRenderPassFormat format() const { - return m_format; - } - - /** - * \brief Checks whether a format is compatible - * - * Two render pass formats are considered compatible - * if all the relevant attachment formats match. - * \param [in] fmt The render pass format to check - * \returns \c true if this render pass is compatible. - */ - bool hasCompatibleFormat( - const DxvkRenderPassFormat& fmt) const; - - /** - * \brief Retrieves sample count - * - * If no sample count has been explicitly specitied, - * this will return \c VK_SAMPLE_COUNT_1_BIT. - * \returns Sample count - */ - VkSampleCountFlagBits getSampleCount() const { - return m_format.sampleCount; - } - - /** - * \brief Returns handle of default render pass - * - * The default render pass handle should be used to - * create pipelines and framebuffer objects. It can - * \e not be used for \c vkCmdBeginRenderPass calls. - * \returns The default render pass handle - */ - VkRenderPass getDefaultHandle() const { - return m_default; - } - - /** - * \brief Returns handle to a specialized render pass - * - * Returns a handle to a render pass with the given - * set of parameters. This should be used for calls - * to \c vkCmdBeginRenderPass. - * \param [in] ops Attachment ops - * \returns Render pass handle - */ - VkRenderPass getHandle( - const DxvkRenderPassOps& ops); - - private: - - struct Instance { - DxvkRenderPassOps ops; - VkRenderPass handle; - }; - - Rc m_vkd; - DxvkRenderPassFormat m_format; - VkRenderPass m_default; - - dxvk::mutex m_mutex; - sync::List m_instances; - - VkRenderPass findHandle( - const DxvkRenderPassOps& ops); - - VkRenderPass createRenderPass( - const DxvkRenderPassOps& ops); - - static bool compareOps( - const DxvkRenderPassOps& a, - const DxvkRenderPassOps& b); - - }; - - - /** - * \brief Render pass pool - * - * Manages render pass objects. For each render - * pass format, a new render pass object will - * be created, but no two render pass objects - * will have the same format. - */ - class DxvkRenderPassPool { - - public: - - DxvkRenderPassPool(const DxvkDevice* device); - ~DxvkRenderPassPool(); - - /** - * \brief Retrieves a render pass object - * - * \param [in] fmt The render pass format - * \returns Matching render pass object - */ - DxvkRenderPass* getRenderPass( - const DxvkRenderPassFormat& fmt); - - /** - * \brief Validates render pass format - * - * \param [in] fmt The render pass format - * \returns \c true if the format is supported - */ - bool validateRenderPassFormat( - const DxvkRenderPassFormat& fmt); - - private: - - const DxvkDevice* m_device; - - dxvk::mutex m_mutex; - std::unordered_map< - DxvkRenderPassFormat, - DxvkRenderPass, - DxvkHash, DxvkEq> m_renderPasses; - - }; - + } \ No newline at end of file diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index b9a708330..27d402a35 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -200,11 +200,9 @@ namespace dxvk { DxvkStateCache::DxvkStateCache( DxvkDevice* device, - DxvkPipelineManager* pipeManager, - DxvkRenderPassPool* passManager) + DxvkPipelineManager* pipeManager) : m_device (device), - m_pipeManager (pipeManager), - m_passManager (passManager) { + m_pipeManager (pipeManager) { bool newFile = !readCacheFile(); if (newFile) { diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index 11cbac986..a3033037d 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -29,8 +29,7 @@ namespace dxvk { DxvkStateCache( DxvkDevice* device, - DxvkPipelineManager* pipeManager, - DxvkRenderPassPool* passManager); + DxvkPipelineManager* pipeManager); ~DxvkStateCache(); @@ -94,7 +93,6 @@ namespace dxvk { DxvkDevice* m_device; DxvkPipelineManager* m_pipeManager; - DxvkRenderPassPool* m_passManager; std::vector m_entries; std::atomic m_stopThreads = { false }; diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 3153c8cfa..0ed8caf60 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -93,7 +93,6 @@ dxvk_src = files([ 'dxvk_pipelayout.cpp', 'dxvk_pipemanager.cpp', 'dxvk_queue.cpp', - 'dxvk_renderpass.cpp', 'dxvk_resource.cpp', 'dxvk_sampler.cpp', 'dxvk_shader.cpp', From 605fef10b412fc5780d14913e80c1f818188bf09 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 3 Jul 2022 01:16:56 +0200 Subject: [PATCH 0117/1348] [dxvk] Fix render target readback barrier Dynamic rendering does not allow barriers within a render pass instance, so we have to actually stop rendering. --- src/dxvk/dxvk_context.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 765eb679a..76f11c38d 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1417,13 +1417,14 @@ namespace dxvk { void DxvkContext::emitRenderTargetReadbackBarrier() { - if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) { - emitMemoryBarrier(VK_DEPENDENCY_BY_REGION_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_ACCESS_SHADER_READ_BIT); - } + if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) + this->spillRenderPass(true); + + emitMemoryBarrier(0, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_SHADER_READ_BIT); } From f57a6d485b33a8ece535acacef3bd628aeffd24f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 3 Jul 2022 13:12:40 +0200 Subject: [PATCH 0118/1348] [dxvk] Use dynamic rendering directly for render target clears --- src/dxvk/dxvk_context.cpp | 81 ++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 76f11c38d..b3663d8f2 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1935,10 +1935,28 @@ namespace dxvk { if (attachmentIndex < 0) { if (m_execBarriers.isImageDirty(imageView->image(), imageView->imageSubresources(), DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); - - // Set up and bind a temporary framebuffer - DxvkRenderTargets attachments; - DxvkRenderPassOps ops; + + // Set up a temporary render pass to execute the clear + VkImageLayout imageLayout = ((clearAspects | discardAspects) & VK_IMAGE_ASPECT_COLOR_BIT) + ? imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + : imageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + + VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + attachmentInfo.imageView = imageView->handle(); + attachmentInfo.imageLayout = imageLayout; + attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + attachmentInfo.clearValue = clearValue; + + VkRenderingAttachmentInfoKHR stencilInfo = attachmentInfo; + + VkExtent3D extent = imageView->mipLevelExtent(0); + + VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + renderingInfo.renderArea.extent = { extent.width, extent.height }; + renderingInfo.layerCount = imageView->info().numLayers; + + VkImageLayout loadLayout; + VkImageLayout storeLayout; VkPipelineStageFlags clearStages = 0; VkAccessFlags clearAccess = 0; @@ -1947,28 +1965,55 @@ namespace dxvk { clearStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; clearAccess |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - attachments.color[0].view = imageView; - attachments.color[0].layout = imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - - ops.colorOps[0] = colorOp; + attachmentInfo.loadOp = colorOp.loadOp; + + renderingInfo.colorAttachmentCount = 1; + renderingInfo.pColorAttachments = &attachmentInfo; + + loadLayout = colorOp.loadLayout; + storeLayout = colorOp.storeLayout; } else { clearStages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; clearAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - attachments.depth.view = imageView; - attachments.depth.layout = imageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - - ops.depthOps = depthOp; + if (imageView->info().aspect & VK_IMAGE_ASPECT_DEPTH_BIT) { + renderingInfo.pDepthAttachment = &attachmentInfo; + attachmentInfo.loadOp = depthOp.loadOpD; + } + + if (imageView->info().aspect & VK_IMAGE_ASPECT_STENCIL_BIT) { + renderingInfo.pStencilAttachment = &stencilInfo; + stencilInfo.loadOp = depthOp.loadOpS; + } + + loadLayout = depthOp.loadLayout; + storeLayout = depthOp.storeLayout; } - ops.barrier.srcStages = clearStages; - ops.barrier.srcAccess = clearAccess; - ops.barrier.dstStages = imageView->imageInfo().stages; - ops.barrier.dstAccess = imageView->imageInfo().access; + if (loadLayout != imageLayout) { + m_execAcquires.accessImage( + imageView->image(), + imageView->imageSubresources(), + loadLayout, clearStages, 0, + imageLayout, clearStages, clearAccess); - this->renderPassBindFramebuffer(makeFramebufferInfo(attachments), ops, 1, &clearValue); - this->renderPassUnbindFramebuffer(); + m_execAcquires.recordCommands(m_cmd); + } + + m_cmd->cmdBeginRendering(&renderingInfo); + m_cmd->cmdEndRendering(); + + m_execBarriers.accessImage( + imageView->image(), + imageView->imageSubresources(), + imageLayout, clearStages, clearAccess, + storeLayout, + imageView->imageInfo().stages, + imageView->imageInfo().access); + + m_cmd->trackResource(imageView); + m_cmd->trackResource(imageView->image()); } else { // Perform the operation when starting the next render pass if ((clearAspects | discardAspects) & VK_IMAGE_ASPECT_COLOR_BIT) { From f19607c11e41095b392db255355f01671cac707f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 3 Jul 2022 14:12:45 +0200 Subject: [PATCH 0119/1348] [dxvk] Use dynamic rendering directly for partial image view clears --- src/dxvk/dxvk_context.cpp | 80 ++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b3663d8f2..b66169d8f 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2992,6 +2992,10 @@ namespace dxvk { VkClearValue value) { this->updateFramebuffer(); + VkPipelineStageFlags clearStages = 0; + VkAccessFlags clearAccess = 0; + VkImageLayout clearLayout = VK_IMAGE_LAYOUT_UNDEFINED; + // Find out if the render target view is currently bound, // so that we can avoid spilling the render pass if it is. int32_t attachmentIndex = -1; @@ -3005,53 +3009,57 @@ namespace dxvk { if (attachmentIndex < 0) { this->spillRenderPass(false); - if (m_execBarriers.isImageDirty( - imageView->image(), - imageView->imageSubresources(), - DxvkAccess::Write)) + if (m_execBarriers.isImageDirty(imageView->image(), imageView->imageSubresources(), DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); - - // Set up a temporary framebuffer - DxvkRenderTargets attachments; - DxvkRenderPassOps ops; - VkPipelineStageFlags clearStages = 0; - VkAccessFlags clearAccess = 0; - + clearLayout = (imageView->info().aspect & VK_IMAGE_ASPECT_COLOR_BIT) + ? imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + : imageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + + VkExtent3D extent = imageView->mipLevelExtent(0); + + VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + attachmentInfo.imageView = imageView->handle(); + attachmentInfo.imageLayout = clearLayout; + attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; + + VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + renderingInfo.renderArea.extent = { extent.width, extent.height }; + renderingInfo.layerCount = imageView->info().numLayers; + if (imageView->info().aspect & VK_IMAGE_ASPECT_COLOR_BIT) { clearStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; clearAccess |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - attachments.color[0].view = imageView; - attachments.color[0].layout = imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - - ops.colorOps[0].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - ops.colorOps[0].loadLayout = imageView->imageInfo().layout; - ops.colorOps[0].storeLayout = imageView->imageInfo().layout; + renderingInfo.colorAttachmentCount = 1; + renderingInfo.pColorAttachments = &attachmentInfo; } else { clearStages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; clearAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - attachments.depth.view = imageView; - attachments.depth.layout = imageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + if (imageView->info().aspect & VK_IMAGE_ASPECT_DEPTH_BIT) + renderingInfo.pDepthAttachment = &attachmentInfo; - ops.depthOps.loadOpD = VK_ATTACHMENT_LOAD_OP_LOAD; - ops.depthOps.loadOpS = VK_ATTACHMENT_LOAD_OP_LOAD; - ops.depthOps.loadLayout = imageView->imageInfo().layout; - ops.depthOps.storeLayout = imageView->imageInfo().layout; + if (imageView->info().aspect & VK_IMAGE_ASPECT_STENCIL_BIT) + renderingInfo.pStencilAttachment = &attachmentInfo; } - ops.barrier.srcStages = clearStages; - ops.barrier.srcAccess = clearAccess; - ops.barrier.dstStages = imageView->imageInfo().stages; - ops.barrier.dstAccess = imageView->imageInfo().access; + if (clearLayout != imageView->imageInfo().layout) { + m_execAcquires.accessImage( + imageView->image(), + imageView->imageSubresources(), + imageView->imageInfo().layout, clearStages, 0, + clearLayout, clearStages, clearAccess); + m_execAcquires.recordCommands(m_cmd); + } // We cannot leverage render pass clears // because we clear only part of the view - this->renderPassBindFramebuffer(makeFramebufferInfo(attachments), ops, 0, nullptr); + m_cmd->cmdBeginRendering(&renderingInfo); } else { // Make sure the render pass is active so // that we can actually perform the clear @@ -3078,8 +3086,20 @@ namespace dxvk { m_cmd->cmdClearAttachments(1, &clearInfo, 1, &clearRect); // Unbind temporary framebuffer - if (attachmentIndex < 0) - this->renderPassUnbindFramebuffer(); + if (attachmentIndex < 0) { + m_cmd->cmdEndRendering(); + + m_execBarriers.accessImage( + imageView->image(), + imageView->imageSubresources(), + clearLayout, clearStages, clearAccess, + imageView->imageInfo().layout, + imageView->imageInfo().stages, + imageView->imageInfo().access); + + m_cmd->trackResource(imageView); + m_cmd->trackResource(imageView->image()); + } } From b34421b055df5c81192faac800906be5985fe175 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 4 Jul 2022 16:13:06 +0200 Subject: [PATCH 0120/1348] [dxvk] Always enable extendedDynamicState feature --- src/dxvk/dxvk_adapter.cpp | 2 +- src/dxvk/dxvk_context.cpp | 12 ++---------- src/dxvk/dxvk_context_state.h | 2 +- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 1ceda5249..8ba0359d4 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -328,7 +328,7 @@ namespace dxvk { DxvkNameList extensionNameList = extensionsEnabled.toNameList(); // Enable additional device features if supported - enabledFeatures.extExtendedDynamicState.extendedDynamicState = m_deviceFeatures.extExtendedDynamicState.extendedDynamicState; + enabledFeatures.extExtendedDynamicState.extendedDynamicState = VK_TRUE; enabledFeatures.ext4444Formats.formatA4B4G4R4 = m_deviceFeatures.ext4444Formats.formatA4B4G4R4; enabledFeatures.ext4444Formats.formatA4R4G4B4 = m_deviceFeatures.ext4444Formats.formatA4R4G4B4; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b66169d8f..261752dac 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -19,9 +19,6 @@ namespace dxvk { m_gfxBarriers (DxvkCmdBuffer::ExecBuffer), m_queryManager(m_common->queryPool()), m_staging (device, StagingBufferSize) { - if (m_device->features().extExtendedDynamicState.extendedDynamicState) - m_features.set(DxvkContextFeature::ExtendedDynamicState); - // Init framebuffer info with default render pass in case // the app does not explicitly bind any render targets m_state.om.framebufferInfo = makeFramebufferInfo(m_state.om.renderTargets); @@ -4988,13 +4985,8 @@ namespace dxvk { // Vertex bindigs get remapped when compiling the // pipeline, so this actually does the right thing - if (m_features.test(DxvkContextFeature::ExtendedDynamicState)) { - m_cmd->cmdBindVertexBuffers2(0, m_state.gp.state.il.bindingCount(), - buffers.data(), offsets.data(), lengths.data(), nullptr); - } else { - m_cmd->cmdBindVertexBuffers(0, m_state.gp.state.il.bindingCount(), - buffers.data(), offsets.data()); - } + m_cmd->cmdBindVertexBuffers2(0, m_state.gp.state.il.bindingCount(), + buffers.data(), offsets.data(), lengths.data(), nullptr); } diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 9eb68c11c..2470ddffb 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -54,7 +54,7 @@ namespace dxvk { * \brief Context feature bits */ enum class DxvkContextFeature { - ExtendedDynamicState, + FeatureCount }; using DxvkContextFeatures = Flags; From 4b82a05e05dc0df4225799882a224d90e71ad9fe Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 3 Jul 2022 14:43:36 +0200 Subject: [PATCH 0121/1348] [dxvk] Enable and use dynamic viewport and scissor rect count --- src/dxvk/dxvk_cmdlist.h | 18 ++++++++---------- src/dxvk/dxvk_context.cpp | 29 ++++++++++++----------------- src/dxvk/dxvk_context_state.h | 1 + src/dxvk/dxvk_graphics.cpp | 6 ++---- src/dxvk/dxvk_meta_blit.cpp | 4 ++-- src/dxvk/dxvk_meta_copy.cpp | 4 ++-- src/dxvk/dxvk_meta_resolve.cpp | 4 ++-- 7 files changed, 29 insertions(+), 37 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 9a9427700..6df1fc1bc 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -707,14 +707,13 @@ namespace dxvk { void cmdSetScissor( - uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* scissors) { - m_vkd->vkCmdSetScissor(m_execBuffer, - firstScissor, scissorCount, scissors); + m_vkd->vkCmdSetScissorWithCountEXT( + m_execBuffer, scissorCount, scissors); } - - + + void cmdSetStencilReference( VkStencilFaceFlags faceMask, uint32_t reference) { @@ -724,14 +723,13 @@ namespace dxvk { void cmdSetViewport( - uint32_t firstViewport, uint32_t viewportCount, const VkViewport* viewports) { - m_vkd->vkCmdSetViewport(m_execBuffer, - firstViewport, viewportCount, viewports); + m_vkd->vkCmdSetViewportWithCountEXT( + m_execBuffer, viewportCount, viewports); } - - + + void cmdWriteTimestamp( VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 261752dac..069dbc996 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1661,8 +1661,8 @@ namespace dxvk { m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeLayout, descriptorWrite.dstSet, 0, nullptr); - m_cmd->cmdSetViewport(0, 1, &viewport); - m_cmd->cmdSetScissor (0, 1, &scissor); + m_cmd->cmdSetViewport(1, &viewport); + m_cmd->cmdSetScissor(1, &scissor); m_cmd->cmdPushConstants( pipeInfo.pipeLayout, @@ -2290,13 +2290,8 @@ namespace dxvk { uint32_t viewportCount, const VkViewport* viewports, const VkRect2D* scissorRects) { - if (m_state.gp.state.rs.viewportCount() != viewportCount) { - m_state.gp.state.rs.setViewportCount(viewportCount); - m_flags.set(DxvkContextFlag::GpDirtyPipelineState); - } - for (uint32_t i = 0; i < viewportCount; i++) { - m_state.vp.viewports[i] = viewports[i]; + m_state.vp.viewports[i] = viewports[i]; m_state.vp.scissorRects[i] = scissorRects[i]; // Vulkan viewports are not allowed to have a width or @@ -2311,6 +2306,7 @@ namespace dxvk { } } + m_state.vp.viewportCount = viewportCount; m_flags.set(DxvkContextFlag::GpDirtyViewport); } @@ -2711,8 +2707,8 @@ namespace dxvk { scissor.offset = { dstOffsets[0].x, dstOffsets[0].y }; scissor.extent = { dstExtent.width, dstExtent.height }; - m_cmd->cmdSetViewport(0, 1, &viewport); - m_cmd->cmdSetScissor (0, 1, &scissor); + m_cmd->cmdSetViewport(1, &viewport); + m_cmd->cmdSetScissor(1, &scissor); // Bind source image view VkDescriptorImageInfo descriptorImage; @@ -3508,8 +3504,8 @@ namespace dxvk { m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeLayout, descriptorSet, 0, nullptr); - m_cmd->cmdSetViewport(0, 1, &viewport); - m_cmd->cmdSetScissor (0, 1, &scissor); + m_cmd->cmdSetViewport(1, &viewport); + m_cmd->cmdSetScissor(1, &scissor); VkOffset2D srcCoordOffset = { srcOffset.x - dstOffset.x, @@ -3941,8 +3937,8 @@ namespace dxvk { m_cmd->cmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeHandle); m_cmd->cmdBindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeInfo.pipeLayout, descriptorSet, 0, nullptr); - m_cmd->cmdSetViewport(0, 1, &viewport); - m_cmd->cmdSetScissor (0, 1, &scissor); + m_cmd->cmdSetViewport(1, &viewport); + m_cmd->cmdSetScissor(1, &scissor); m_cmd->cmdPushConstants(pipeInfo.pipeLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(srcOffset), &srcOffset); @@ -5037,9 +5033,8 @@ namespace dxvk { if (m_flags.test(DxvkContextFlag::GpDirtyViewport)) { m_flags.clr(DxvkContextFlag::GpDirtyViewport); - uint32_t viewportCount = m_state.gp.state.rs.viewportCount(); - m_cmd->cmdSetViewport(0, viewportCount, m_state.vp.viewports.data()); - m_cmd->cmdSetScissor (0, viewportCount, m_state.vp.scissorRects.data()); + m_cmd->cmdSetViewport(m_state.vp.viewportCount, m_state.vp.viewports.data()); + m_cmd->cmdSetScissor(m_state.vp.viewportCount, m_state.vp.scissorRects.data()); } if (m_flags.all(DxvkContextFlag::GpDirtyBlendConstants, diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 2470ddffb..7ca7b25df 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -90,6 +90,7 @@ namespace dxvk { struct DxvkViewportState { + uint32_t viewportCount = 0; std::array viewports = { }; std::array scissorRects = { }; }; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 09420d705..3469815f6 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -119,8 +119,8 @@ namespace dxvk { std::array dynamicStates; uint32_t dynamicStateCount = 0; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT; if (state.useDynamicDepthBias()) dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS; @@ -270,8 +270,6 @@ namespace dxvk { tsInfo.patchControlPoints = state.ia.patchVertexCount(); VkPipelineViewportStateCreateInfo vpInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; - vpInfo.viewportCount = state.rs.viewportCount(); - vpInfo.scissorCount = state.rs.viewportCount(); VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT }; conservativeInfo.conservativeRasterizationMode = state.rs.conservativeMode(); diff --git a/src/dxvk/dxvk_meta_blit.cpp b/src/dxvk/dxvk_meta_blit.cpp index 2cf0773f0..58bcc16b9 100644 --- a/src/dxvk/dxvk_meta_blit.cpp +++ b/src/dxvk/dxvk_meta_blit.cpp @@ -307,8 +307,8 @@ namespace dxvk { VK_SHADER_STAGE_FRAGMENT_BIT, psModule, "main" }; std::array dynStates = {{ - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT, }}; VkPipelineDynamicStateCreateInfo dynState = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index 4816172bb..c15f15ebc 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -344,8 +344,8 @@ namespace dxvk { VK_SHADER_STAGE_FRAGMENT_BIT, psModule, "main" }; std::array dynStates = {{ - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT, }}; VkPipelineDynamicStateCreateInfo dynState = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index e95900695..dae17e7ec 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -257,8 +257,8 @@ namespace dxvk { VK_SHADER_STAGE_FRAGMENT_BIT, psModule, "main", &specInfo }; std::array dynStates = {{ - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT, }}; VkPipelineDynamicStateCreateInfo dynState = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; From 95f7aae3e6be99b98342e199ebabab4af4a40e5d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 3 Jul 2022 15:26:08 +0200 Subject: [PATCH 0122/1348] [dxvk] Remove viewport state from graphics pipelines And bump state cache version to v13. --- src/dxvk/dxvk_context.cpp | 1 - src/dxvk/dxvk_graphics_state.h | 41 +++++++++++-------------------- src/dxvk/dxvk_state_cache.cpp | 14 +++++++++++ src/dxvk/dxvk_state_cache_types.h | 28 ++++++++++++++++++++- 4 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 069dbc996..d09daeaf2 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2400,7 +2400,6 @@ namespace dxvk { rs.polygonMode, rs.cullMode, rs.frontFace, - m_state.gp.state.rs.viewportCount(), rs.sampleCount, rs.conservativeMode); diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 2c8ae023e..ebd7c6375 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -223,17 +223,15 @@ namespace dxvk { VkPolygonMode polygonMode, VkCullModeFlags cullMode, VkFrontFace frontFace, - uint32_t viewportCount, VkSampleCountFlags sampleCount, VkConservativeRasterizationModeEXT conservativeMode) - : m_depthClipEnable (uint32_t(depthClipEnable)), - m_depthBiasEnable (uint32_t(depthBiasEnable)), - m_polygonMode (uint32_t(polygonMode)), - m_cullMode (uint32_t(cullMode)), - m_frontFace (uint32_t(frontFace)), - m_viewportCount (uint32_t(viewportCount)), - m_sampleCount (uint32_t(sampleCount)), - m_conservativeMode(uint32_t(conservativeMode)), + : m_depthClipEnable (uint16_t(depthClipEnable)), + m_depthBiasEnable (uint16_t(depthBiasEnable)), + m_polygonMode (uint16_t(polygonMode)), + m_cullMode (uint16_t(cullMode)), + m_frontFace (uint16_t(frontFace)), + m_sampleCount (uint16_t(sampleCount)), + m_conservativeMode(uint16_t(conservativeMode)), m_reserved (0) { } VkBool32 depthClipEnable() const { @@ -256,10 +254,6 @@ namespace dxvk { return VkFrontFace(m_frontFace); } - uint32_t viewportCount() const { - return m_viewportCount; - } - VkSampleCountFlags sampleCount() const { return VkSampleCountFlags(m_sampleCount); } @@ -268,21 +262,16 @@ namespace dxvk { return VkConservativeRasterizationModeEXT(m_conservativeMode); } - void setViewportCount(uint32_t viewportCount) { - m_viewportCount = viewportCount; - } - private: - uint32_t m_depthClipEnable : 1; - uint32_t m_depthBiasEnable : 1; - uint32_t m_polygonMode : 2; - uint32_t m_cullMode : 2; - uint32_t m_frontFace : 1; - uint32_t m_viewportCount : 5; - uint32_t m_sampleCount : 5; - uint32_t m_conservativeMode : 2; - uint32_t m_reserved : 13; + uint16_t m_depthClipEnable : 1; + uint16_t m_depthBiasEnable : 1; + uint16_t m_polygonMode : 2; + uint16_t m_cullMode : 2; + uint16_t m_frontFace : 1; + uint16_t m_sampleCount : 5; + uint16_t m_conservativeMode : 2; + uint16_t m_reserved : 2; }; diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 27d402a35..4ffa58b91 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -62,6 +62,20 @@ namespace dxvk { return read(data); } + bool read(DxvkRsInfo& data, uint32_t version) { + if (version < 13) { + DxvkRsInfoV12 v12; + + if (!read(v12)) + return false; + + data = v12.convert(); + return true; + } + + return read(data); + } + bool read(DxvkRtInfo& data, uint32_t version) { // v12 introduced this field if (version < 12) diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index 758f7cf65..e0098905f 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -51,7 +51,7 @@ namespace dxvk { */ struct DxvkStateCacheHeader { char magic[4] = { 'D', 'X', 'V', 'K' }; - uint32_t version = 12; + uint32_t version = 13; uint32_t entrySize = 0; /* no longer meaningful */ }; @@ -123,4 +123,30 @@ namespace dxvk { } }; + class DxvkRsInfoV12 { + + public: + + uint32_t m_depthClipEnable : 1; + uint32_t m_depthBiasEnable : 1; + uint32_t m_polygonMode : 2; + uint32_t m_cullMode : 2; + uint32_t m_frontFace : 1; + uint32_t m_viewportCount : 5; + uint32_t m_sampleCount : 5; + uint32_t m_conservativeMode : 2; + uint32_t m_reserved : 13; + + DxvkRsInfo convert() const { + return DxvkRsInfo( + VkBool32(m_depthClipEnable), + VkBool32(m_depthBiasEnable), + VkPolygonMode(m_polygonMode), + VkCullModeFlags(m_cullMode), + VkFrontFace(m_frontFace), + VkSampleCountFlags(m_sampleCount), + VkConservativeRasterizationModeEXT(m_conservativeMode)); + } + + }; } From 67d35ecc8d56e0d9d26d8b591ae693e7be3f96da Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 4 Jul 2022 14:00:24 +0200 Subject: [PATCH 0123/1348] [dxvk] Introduce DxvkGlobalPipelineBarrier --- src/dxvk/dxvk_graphics.cpp | 27 ++++++++++++++++++++++++--- src/dxvk/dxvk_graphics.h | 16 +++++++++++++++- src/dxvk/dxvk_pipelayout.cpp | 13 ++++++++----- src/dxvk/dxvk_pipelayout.h | 19 ++++++++++++++++--- 4 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 3469815f6..597cfd19c 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -13,14 +13,22 @@ namespace dxvk { DxvkGraphicsPipelineShaders shaders, DxvkBindingLayoutObjects* layout) : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), - m_shaders(std::move(shaders)), m_bindings(layout) { + m_shaders(std::move(shaders)), m_bindings(layout), + m_barrier(layout->getGlobalBarrier()) { m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->info().inputMask : 0; m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->info().outputMask : 0; - if (m_shaders.gs != nullptr && m_shaders.gs->flags().test(DxvkShaderFlag::HasTransformFeedback)) + if (m_shaders.gs != nullptr && m_shaders.gs->flags().test(DxvkShaderFlag::HasTransformFeedback)) { m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback); + + m_barrier.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT + | VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT; + m_barrier.access |= VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT + | VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT + | VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT; + } - if (layout->getAccessFlags() & VK_ACCESS_SHADER_WRITE_BIT) + if (m_barrier.access & VK_ACCESS_SHADER_WRITE_BIT) m_flags.set(DxvkGraphicsPipelineFlag::HasStorageDescriptors); m_common.msSampleShadingEnable = m_shaders.fs != nullptr && m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading); @@ -48,6 +56,19 @@ namespace dxvk { } + DxvkGlobalPipelineBarrier DxvkGraphicsPipeline::getGlobalBarrier( + const DxvkGraphicsPipelineStateInfo& state) const { + DxvkGlobalPipelineBarrier barrier = m_barrier; + + if (state.il.bindingCount()) { + barrier.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; + barrier.access |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; + } + + return barrier; + } + + VkPipeline DxvkGraphicsPipeline::getPipelineHandle( const DxvkGraphicsPipelineStateInfo& state) { DxvkGraphicsPipelineInstance* instance = this->findInstance(state); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index b457fee9e..651c63dd2 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -185,7 +185,20 @@ namespace dxvk { */ Rc getShader( VkShaderStageFlagBits stage) const; - + + /** + * \brief Queries global resource barrier + * + * Returns the stages that can access resources in this + * pipeline with the given pipeline state, as well as + * the ways in which resources are accessed. This does + * not include render targets. The barrier is meant to + * be executed after the render pass. + * \returns Global barrier + */ + DxvkGlobalPipelineBarrier getGlobalBarrier( + const DxvkGraphicsPipelineStateInfo& state) const; + /** * \brief Pipeline handle * @@ -218,6 +231,7 @@ namespace dxvk { uint32_t m_vsIn = 0; uint32_t m_fsOut = 0; + DxvkGlobalPipelineBarrier m_barrier; DxvkGraphicsPipelineFlags m_flags; DxvkGraphicsCommonPipelineStateInfo m_common; diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index aee75d3bb..bb60cde2e 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -323,15 +323,18 @@ namespace dxvk { } - VkAccessFlags DxvkBindingLayoutObjects::getAccessFlags() const { - VkAccessFlags flags = 0; + DxvkGlobalPipelineBarrier DxvkBindingLayoutObjects::getGlobalBarrier() const { + DxvkGlobalPipelineBarrier barrier = { }; for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { - for (uint32_t j = 0; j < m_layout.getBindingCount(i); j++) - flags |= m_layout.getBinding(i, j).access; + for (uint32_t j = 0; j < m_layout.getBindingCount(i); j++) { + const auto& binding = m_layout.getBinding(i, j); + barrier.stages |= util::pipelineStages(binding.stages); + barrier.access |= binding.access; + } } - return flags; + return barrier; } } \ No newline at end of file diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index c16dce029..46717bc9d 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -356,6 +356,17 @@ namespace dxvk { uint32_t binding; }; + /** + * \brief Global resource barrier + * + * Stores the way any resources will be + * accessed by this pipeline. + */ + struct DxvkGlobalPipelineBarrier { + VkPipelineStageFlags stages; + VkAccessFlags access; + }; + /** * \brief Pipeline and descriptor set layouts for a given binding layout * @@ -435,12 +446,14 @@ namespace dxvk { } /** - * \brief Queries accumulated resource access flags + * \brief Queries global resource barrier * * Can be used to determine whether the pipeline - * reads or writes any resources. + * reads or writes any resources, and which shader + * stages it uses. + * \returns Global barrier */ - VkAccessFlags getAccessFlags() const; + DxvkGlobalPipelineBarrier getGlobalBarrier() const; private: From 0c5773dbb9ed3358a708c930a9d20a31d4ec2404 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 4 Jul 2022 14:59:03 +0200 Subject: [PATCH 0124/1348] [dxvk] Emit smarter post-renderpass barriers Allows folding the old post-renderpass barrier into the same pipeline barrier call as layout transitions from prepareImage or from starting another render pass, thus reducing the overall number of pipeline barriers. Also no longer uses VK_PIPELINE_STAGE_ALL_COMMANDS_BIT. --- src/dxvk/dxvk_barrier.h | 13 +++ src/dxvk/dxvk_context.cpp | 169 +++++++++++++++++++++++++------------ src/dxvk/dxvk_context.h | 6 +- src/dxvk/dxvk_renderpass.h | 15 ---- 4 files changed, 130 insertions(+), 73 deletions(-) diff --git a/src/dxvk/dxvk_barrier.h b/src/dxvk/dxvk_barrier.h index f7a7713d9..18308d1bf 100644 --- a/src/dxvk/dxvk_barrier.h +++ b/src/dxvk/dxvk_barrier.h @@ -333,6 +333,14 @@ namespace dxvk { m_list.clear(); } + /** + * \brief Checks whether set is empty + * \returns \c true if there are no entries + */ + bool empty() const { + return m_used == 0; + } + private: struct ListEntry { @@ -538,6 +546,11 @@ namespace dxvk { void reset(); + bool hasResourceBarriers() const { + return !m_bufSlices.empty() + || !m_imgSlices.empty(); + } + static DxvkAccessFlags getAccessTypes(VkAccessFlags flags); private: diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index d09daeaf2..e68583fc7 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -16,7 +16,6 @@ namespace dxvk { m_initBarriers(DxvkCmdBuffer::InitBuffer), m_execAcquires(DxvkCmdBuffer::ExecBuffer), m_execBarriers(DxvkCmdBuffer::ExecBuffer), - m_gfxBarriers (DxvkCmdBuffer::ExecBuffer), m_queryManager(m_common->queryPool()), m_staging (device, StagingBufferSize) { // Init framebuffer info with default render pass in case @@ -37,6 +36,33 @@ namespace dxvk { } m_descriptorManager = new DxvkDescriptorManager(device.ptr(), type); + + // Default destination barriers for graphics pipelines + m_globalRoGraphicsBarrier.stages = m_device->getShaderPipelineStages() + | VK_PIPELINE_STAGE_TRANSFER_BIT + | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT + | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT + | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + m_globalRoGraphicsBarrier.access = 0; + + if (m_device->features().extTransformFeedback.transformFeedback) + m_globalRoGraphicsBarrier.stages |= VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT; + + m_globalRwGraphicsBarrier = m_globalRoGraphicsBarrier; + m_globalRwGraphicsBarrier.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT + | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; + + m_globalRwGraphicsBarrier.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT + | VK_ACCESS_INDEX_READ_BIT + | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT + | VK_ACCESS_UNIFORM_READ_BIT + | VK_ACCESS_SHADER_READ_BIT + | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT + | VK_ACCESS_TRANSFER_READ_BIT; + + if (m_device->features().extTransformFeedback.transformFeedback) + m_globalRwGraphicsBarrier.access |= VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT; } @@ -4020,15 +4046,15 @@ namespace dxvk { if (suspend) m_flags.set(DxvkContextFlag::GpRenderPassSuspended); else - this->transitionRenderTargetLayouts(m_gfxBarriers, false); + this->transitionRenderTargetLayouts(m_execBarriers, false); - m_gfxBarriers.recordCommands(m_cmd); + m_execBarriers.recordCommands(m_cmd); } else if (!suspend) { // We may end a previously suspended render pass if (m_flags.test(DxvkContextFlag::GpRenderPassSuspended)) { m_flags.clr(DxvkContextFlag::GpRenderPassSuspended); - this->transitionRenderTargetLayouts(m_gfxBarriers, false); - m_gfxBarriers.recordCommands(m_cmd); + this->transitionRenderTargetLayouts(m_execBarriers, false); + m_execBarriers.recordCommands(m_cmd); } // Execute deferred clears if necessary @@ -4123,42 +4149,59 @@ namespace dxvk { const auto& depthAttachment = framebufferInfo.getDepthTarget(); if (depthAttachment.view != nullptr) { - m_execBarriers.accessImage( - depthAttachment.view->image(), - depthAttachment.view->imageSubresources(), - depthAttachment.layout, - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - ops.depthOps.storeLayout, - depthAttachment.view->imageInfo().stages, - depthAttachment.view->imageInfo().access); + if (depthAttachment.layout != ops.depthOps.storeLayout) { + m_execBarriers.accessImage( + depthAttachment.view->image(), + depthAttachment.view->imageSubresources(), + depthAttachment.layout, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + ops.depthOps.storeLayout, + depthAttachment.view->imageInfo().stages, + depthAttachment.view->imageInfo().access); + } else { + VkAccessFlags srcAccess = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + + if (depthAttachment.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) + srcAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + + m_execBarriers.accessMemory( + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + srcAccess, + depthAttachment.view->imageInfo().stages, + depthAttachment.view->imageInfo().access); + } } for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { const auto& colorAttachment = framebufferInfo.getColorTarget(i); if (colorAttachment.view != nullptr) { - m_execBarriers.accessImage( - colorAttachment.view->image(), - colorAttachment.view->imageSubresources(), - colorAttachment.layout, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - ops.colorOps[i].storeLayout, - colorAttachment.view->imageInfo().stages, - colorAttachment.view->imageInfo().access); + if (colorAttachment.layout != ops.colorOps[i].storeLayout) { + m_execBarriers.accessImage( + colorAttachment.view->image(), + colorAttachment.view->imageSubresources(), + colorAttachment.layout, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + ops.colorOps[i].storeLayout, + colorAttachment.view->imageInfo().stages, + colorAttachment.view->imageInfo().access); + } else { + m_execBarriers.accessMemory( + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + colorAttachment.view->imageInfo().stages, + colorAttachment.view->imageInfo().access); + } } } - m_execBarriers.accessMemory( - ops.barrier.srcStages, - ops.barrier.srcAccess, - ops.barrier.dstStages, - ops.barrier.dstAccess); - // Do not flush barriers here. This is intended since // we pre-record them when binding the framebuffer. } @@ -4252,26 +4295,21 @@ namespace dxvk { void DxvkContext::renderPassUnbindFramebuffer() { m_cmd->cmdEndRendering(); - // TODO Try to get rid of this for performance reasons. - // This only exists to emulate render pass barriers. - m_execBarriers.recordCommands(m_cmd); + // If there are pending layout transitions, execute them immediately + // since the backend expects images to be in the store layout after + // a render pass instance. This is expected to be rare. + if (m_execBarriers.hasResourceBarriers()) + m_execBarriers.recordCommands(m_cmd); } void DxvkContext::resetRenderPassOps( const DxvkRenderTargets& renderTargets, DxvkRenderPassOps& renderPassOps) { - VkAccessFlags access = 0; - if (renderTargets.depth.view != nullptr) { renderPassOps.depthOps = DxvkDepthAttachmentOps { VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD, renderTargets.depth.layout, renderTargets.depth.layout }; - - access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - - if (renderTargets.depth.layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) - access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; } else { renderPassOps.depthOps = DxvkDepthAttachmentOps { }; } @@ -4282,18 +4320,10 @@ namespace dxvk { VK_ATTACHMENT_LOAD_OP_LOAD, renderTargets.color[i].layout, renderTargets.color[i].layout }; - - access |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT - | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; } else { renderPassOps.colorOps[i] = DxvkColorAttachmentOps { }; } } - - renderPassOps.barrier.srcStages = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; - renderPassOps.barrier.srcAccess = access; - renderPassOps.barrier.dstStages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - renderPassOps.barrier.dstAccess = access; } @@ -4447,7 +4477,7 @@ namespace dxvk { } - bool DxvkContext::updateGraphicsPipelineState() { + bool DxvkContext::updateGraphicsPipelineState(DxvkGlobalPipelineBarrier srcBarrier) { // Set up vertex buffer strides for active bindings for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) { const uint32_t binding = m_state.gp.state.ilBindings[i].binding(); @@ -4487,6 +4517,21 @@ namespace dxvk { VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + // Emit barrier based on pipeline properties, in order to avoid + // accidental write-after-read hazards after the render pass. + DxvkGlobalPipelineBarrier pipelineBarrier = m_state.gp.pipeline->getGlobalBarrier(m_state.gp.state); + srcBarrier.stages |= pipelineBarrier.stages; + srcBarrier.access |= pipelineBarrier.access; + + DxvkAccessFlags access = DxvkBarrierSet::getAccessTypes(srcBarrier.access); + DxvkGlobalPipelineBarrier dstBarrier = access.test(DxvkAccess::Write) + ? m_globalRwGraphicsBarrier + : m_globalRoGraphicsBarrier; + + m_execBarriers.accessMemory( + srcBarrier.stages, srcBarrier.access, + dstBarrier.stages, dstBarrier.access); + m_flags.clr(DxvkContextFlag::GpDirtyPipelineState); return true; } @@ -5148,7 +5193,19 @@ namespace dxvk { this->updateGraphicsShaderResources(); if (m_flags.test(DxvkContextFlag::GpDirtyPipelineState)) { - if (unlikely(!this->updateGraphicsPipelineState())) + DxvkGlobalPipelineBarrier barrier = { }; + + if (Indexed) { + barrier.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; + barrier.access |= VK_ACCESS_INDEX_READ_BIT; + } + + if (Indirect) { + barrier.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; + barrier.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT; + } + + if (unlikely(!this->updateGraphicsPipelineState(barrier))) return false; } @@ -5462,14 +5519,14 @@ namespace dxvk { VkPipelineStageFlags stages, VkAccessFlags access) { if constexpr (DoEmit) { - m_gfxBarriers.accessBuffer( + m_execBarriers.accessBuffer( slice.getSliceHandle(), stages, access, slice.bufferInfo().stages, slice.bufferInfo().access); return DxvkAccessFlags(); } else { - return m_gfxBarriers.getBufferAccess(slice.getSliceHandle()); + return m_execBarriers.getBufferAccess(slice.getSliceHandle()); } } @@ -5480,7 +5537,7 @@ namespace dxvk { VkPipelineStageFlags stages, VkAccessFlags access) { if constexpr (DoEmit) { - m_gfxBarriers.accessImage( + m_execBarriers.accessImage( imageView->image(), imageView->imageSubresources(), imageView->imageInfo().layout, @@ -5490,7 +5547,7 @@ namespace dxvk { imageView->imageInfo().access); return DxvkAccessFlags(); } else { - return m_gfxBarriers.getImageAccess( + return m_execBarriers.getImageAccess( imageView->image(), imageView->imageSubresources()); } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index a6a9c3291..738ecb494 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1137,12 +1137,14 @@ namespace dxvk { DxvkBarrierSet m_initBarriers; DxvkBarrierSet m_execAcquires; DxvkBarrierSet m_execBarriers; - DxvkBarrierSet m_gfxBarriers; DxvkBarrierControlFlags m_barrierControl; DxvkGpuQueryManager m_queryManager; DxvkStagingBuffer m_staging; + DxvkGlobalPipelineBarrier m_globalRoGraphicsBarrier; + DxvkGlobalPipelineBarrier m_globalRwGraphicsBarrier; + DxvkRenderTargetLayouts m_rtLayouts = { }; DxvkBindingSet m_vbTracked; @@ -1314,7 +1316,7 @@ namespace dxvk { void unbindGraphicsPipeline(); bool updateGraphicsPipeline(); - bool updateGraphicsPipelineState(); + bool updateGraphicsPipelineState(DxvkGlobalPipelineBarrier srcBarrier); void invalidateState(); diff --git a/src/dxvk/dxvk_renderpass.h b/src/dxvk/dxvk_renderpass.h index f98b34964..5688946cb 100644 --- a/src/dxvk/dxvk_renderpass.h +++ b/src/dxvk/dxvk_renderpass.h @@ -41,20 +41,6 @@ namespace dxvk { }; - /** - * \brief Render pass barrier - * - * External subpass dependency that is to be - * executed after a render pass has completed. - */ - struct DxvkRenderPassBarrier { - VkPipelineStageFlags srcStages = 0; - VkAccessFlags srcAccess = 0; - VkPipelineStageFlags dstStages = 0; - VkAccessFlags dstAccess = 0; - }; - - /** * \brief Render pass transitions * @@ -63,7 +49,6 @@ namespace dxvk { * from a group of render passes with the same format. */ struct DxvkRenderPassOps { - DxvkRenderPassBarrier barrier; DxvkDepthAttachmentOps depthOps; DxvkColorAttachmentOps colorOps[MaxNumRenderTargets]; }; From d71e85785c8f2913b4fa6c781b71e23fe6ace29c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 4 Jul 2022 20:33:36 +0200 Subject: [PATCH 0125/1348] [dxvk] Drop barrier before renderPassBindFramebuffer Not necessary since that function emits barriers anyway. --- src/dxvk/dxvk_context.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index e68583fc7..e017cf943 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4008,8 +4008,6 @@ namespace dxvk { m_flags.clr(DxvkContextFlag::GpRenderPassSuspended); - m_execBarriers.recordCommands(m_cmd); - this->renderPassBindFramebuffer( m_state.om.framebufferInfo, m_state.om.renderPassOps, From fcadaec1296848242f391f131dc149ec5bcf5859 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 4 Jul 2022 21:03:20 +0200 Subject: [PATCH 0126/1348] [dxvk] Store clear values inside render pass ops The previous model was designed around vkCmdBeginRenderPass, which was somewhat clunky regarding attachment clears. This is no longer needed. --- src/dxvk/dxvk_context.cpp | 22 ++++++++-------------- src/dxvk/dxvk_context.h | 4 +--- src/dxvk/dxvk_context_state.h | 2 -- src/dxvk/dxvk_renderpass.h | 2 ++ 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index e017cf943..a4e30fe47 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2046,17 +2046,17 @@ namespace dxvk { if (m_state.om.renderPassOps.colorOps[colorIndex].loadOp != VK_ATTACHMENT_LOAD_OP_LOAD && !is3D) m_state.om.renderPassOps.colorOps[colorIndex].loadLayout = VK_IMAGE_LAYOUT_UNDEFINED; - m_state.om.clearValues[attachmentIndex].color = clearValue.color; + m_state.om.renderPassOps.colorOps[colorIndex].clearValue = clearValue.color; } if ((clearAspects | discardAspects) & VK_IMAGE_ASPECT_DEPTH_BIT) { m_state.om.renderPassOps.depthOps.loadOpD = depthOp.loadOpD; - m_state.om.clearValues[attachmentIndex].depthStencil.depth = clearValue.depthStencil.depth; + m_state.om.renderPassOps.depthOps.clearValue.depth = clearValue.depthStencil.depth; } if ((clearAspects | discardAspects) & VK_IMAGE_ASPECT_STENCIL_BIT) { m_state.om.renderPassOps.depthOps.loadOpS = depthOp.loadOpS; - m_state.om.clearValues[attachmentIndex].depthStencil.stencil = clearValue.depthStencil.stencil; + m_state.om.renderPassOps.depthOps.clearValue.stencil = clearValue.depthStencil.stencil; } if ((clearAspects | discardAspects) & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { @@ -4010,9 +4010,7 @@ namespace dxvk { this->renderPassBindFramebuffer( m_state.om.framebufferInfo, - m_state.om.renderPassOps, - m_state.om.framebufferInfo.numAttachments(), - m_state.om.clearValues.data()); + m_state.om.renderPassOps); // Track the final layout of each render target this->applyRenderTargetStoreLayouts(); @@ -4207,15 +4205,12 @@ namespace dxvk { void DxvkContext::renderPassBindFramebuffer( const DxvkFramebufferInfo& framebufferInfo, - const DxvkRenderPassOps& ops, - uint32_t clearValueCount, - const VkClearValue* clearValues) { + const DxvkRenderPassOps& ops) { const DxvkFramebufferSize fbSize = framebufferInfo.size(); this->renderPassEmitInitBarriers(framebufferInfo, ops); this->renderPassEmitPostBarriers(framebufferInfo, ops); - uint32_t clearValueIndex = 0; uint32_t colorInfoCount = 0; std::array colorInfos; @@ -4231,9 +4226,8 @@ namespace dxvk { colorInfos[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; if (ops.colorOps[i].loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) - colorInfos[i].clearValue = clearValues[clearValueIndex]; + colorInfos[i].clearValue.color = ops.colorOps[i].clearValue; - clearValueIndex += 1; colorInfoCount = i + 1; } } @@ -4250,7 +4244,7 @@ namespace dxvk { depthInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; if (ops.depthOps.loadOpD == VK_ATTACHMENT_LOAD_OP_CLEAR) - depthInfo.clearValue = clearValues[clearValueIndex]; + depthInfo.clearValue.depthStencil.depth = ops.depthOps.clearValue.depth; } VkRenderingAttachmentInfoKHR stencilInfo = depthInfo; @@ -4260,7 +4254,7 @@ namespace dxvk { stencilInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; if (ops.depthOps.loadOpS == VK_ATTACHMENT_LOAD_OP_CLEAR) - stencilInfo.clearValue = clearValues[clearValueIndex]; + stencilInfo.clearValue.depthStencil.stencil = ops.depthOps.clearValue.stencil; } VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 738ecb494..29a071555 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1297,9 +1297,7 @@ namespace dxvk { void renderPassBindFramebuffer( const DxvkFramebufferInfo& framebufferInfo, - const DxvkRenderPassOps& ops, - uint32_t clearValueCount, - const VkClearValue* clearValues); + const DxvkRenderPassOps& ops); void renderPassUnbindFramebuffer(); diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 7ca7b25df..762b1ab1e 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -97,8 +97,6 @@ namespace dxvk { struct DxvkOutputMergerState { - std::array clearValues = { }; - DxvkRenderTargets renderTargets; DxvkRenderPassOps renderPassOps; DxvkFramebufferInfo framebufferInfo; diff --git a/src/dxvk/dxvk_renderpass.h b/src/dxvk/dxvk_renderpass.h index 5688946cb..649716502 100644 --- a/src/dxvk/dxvk_renderpass.h +++ b/src/dxvk/dxvk_renderpass.h @@ -24,6 +24,7 @@ namespace dxvk { VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; VkImageLayout loadLayout = VK_IMAGE_LAYOUT_UNDEFINED; VkImageLayout storeLayout = VK_IMAGE_LAYOUT_GENERAL; + VkClearColorValue clearValue = VkClearColorValue(); }; @@ -38,6 +39,7 @@ namespace dxvk { VkAttachmentLoadOp loadOpS = VK_ATTACHMENT_LOAD_OP_DONT_CARE; VkImageLayout loadLayout = VK_IMAGE_LAYOUT_UNDEFINED; VkImageLayout storeLayout = VK_IMAGE_LAYOUT_GENERAL; + VkClearDepthStencilValue clearValue = VkClearDepthStencilValue(); }; From 21ca9b91d00b5ef8921cec580420fa3a1027b079 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jul 2022 23:44:05 +0200 Subject: [PATCH 0127/1348] [dxvk] Mark VK_EXT_extended_dynamic_state as required The device feature is already required anyway. --- src/dxvk/dxvk_extensions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index b3596607b..d94e3480f 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -282,7 +282,7 @@ namespace dxvk { DxvkExt extConservativeRasterization = { VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extCustomBorderColor = { VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extDepthClipEnable = { VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt extExtendedDynamicState = { VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extExtendedDynamicState = { VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt extFullScreenExclusive = { VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extHostQueryReset = { VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extMemoryBudget = { VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, DxvkExtMode::Passive }; From 3733590756e9110a4ed59a789042604f1eebd4a4 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sat, 9 Jul 2022 01:00:21 +0200 Subject: [PATCH 0128/1348] [util] disable allowDoNotWait for Port Royale 3 (#2668) --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index bb55eb738..9a5e53eb4 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -592,6 +592,11 @@ namespace dxvk { { R"(\\bionic_commando\.exe$)", {{ { "d3d9.maxFrameRate", "60" }, }} }, + /* Port Royale 3 * + * Fixes infinite loading screens */ + { R"(\\PortRoyale3\.exe$)", {{ + { "d3d9.allowDoNotWait", "False" }, + }} }, }}; From 2bd062f9d6edba9a8b1b0fa18b9fcea2b13ee0bb Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 5 Jul 2022 15:17:37 +0100 Subject: [PATCH 0129/1348] [util] Implement LUID helpers for non-Windows platforms Initial commit --- src/util/util_luid.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/util/util_luid.cpp b/src/util/util_luid.cpp index 96a2a09a6..11697d838 100644 --- a/src/util/util_luid.cpp +++ b/src/util/util_luid.cpp @@ -5,9 +5,20 @@ #include #include +#include namespace dxvk { +#ifndef _WIN32 + static BOOL AllocateLocallyUniqueId(LUID* luid) { + static std::atomic counter = { 0u }; + // Unsigned bottom part is actually the first + // member of the struct. + *luid = LUID{ ++counter, 0 }; + return TRUE; + } +#endif + LUID GetAdapterLUID(UINT Adapter) { static dxvk::mutex s_mutex; static std::vector s_luids; @@ -18,7 +29,7 @@ namespace dxvk { while (s_luids.size() < newLuidCount) { LUID luid = { 0, 0 }; - if (!::AllocateLocallyUniqueId(&luid)) + if (!AllocateLocallyUniqueId(&luid)) Logger::err("Failed to allocate LUID"); From 97f2d81b25fadc30ffcc823df5db84d8b23cabf8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jul 2022 15:27:24 +0200 Subject: [PATCH 0130/1348] [meta] Update Vulkan headers to 1.3.219 --- include/vulkan/vulkan_core.h | 99 +++++++++++++++++++++++++++++++++++- 1 file changed, 98 insertions(+), 1 deletion(-) diff --git a/include/vulkan/vulkan_core.h b/include/vulkan/vulkan_core.h index 07b4acfe2..aef16f96d 100644 --- a/include/vulkan/vulkan_core.h +++ b/include/vulkan/vulkan_core.h @@ -72,7 +72,7 @@ extern "C" { #define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 // Version of this file -#define VK_HEADER_VERSION 217 +#define VK_HEADER_VERSION 219 // Complete version of this file #define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) @@ -168,6 +168,24 @@ typedef enum VkResult { VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, VK_ERROR_INVALID_SHADER_NV = -1000012000, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR = -1000023000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR = -1000023001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR = -1000023002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR = -1000023003, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR = -1000023004, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR = -1000023005, +#endif VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, VK_ERROR_NOT_PERMITTED_KHR = -1000174001, VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, @@ -944,6 +962,9 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001, VK_STRUCTURE_TYPE_PIPELINE_PROPERTIES_IDENTIFIER_EXT = 1000372000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT = 1000372001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT = 1000376000, + VK_STRUCTURE_TYPE_SUBPASS_RESOLVE_PERFORMANCE_QUERY_EXT = 1000376001, + VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT = 1000376002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000, VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, @@ -971,6 +992,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_CONTROL_EXT = 1000458001, VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000458002, VK_STRUCTURE_TYPE_RENDER_PASS_SUBPASS_FEEDBACK_CREATE_INFO_EXT = 1000458003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT = 1000462000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT = 1000462001, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT = 1000462002, + VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT = 1000462003, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, @@ -2107,6 +2132,7 @@ typedef enum VkImageCreateFlagBits { VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000, VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000, + VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT = 0x00040000, VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT = 0x00020000, VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM = 0x00008000, VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, @@ -5558,6 +5584,7 @@ typedef enum VkDriverId { VK_DRIVER_ID_MESA_PANVK = 20, VK_DRIVER_ID_SAMSUNG_PROPRIETARY = 21, VK_DRIVER_ID_MESA_VENUS = 22, + VK_DRIVER_ID_MESA_DOZEN = 23, VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY, VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE, VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV, @@ -13906,6 +13933,30 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelinePropertiesEXT( #endif +#define VK_EXT_multisampled_render_to_single_sampled 1 +#define VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_SPEC_VERSION 1 +#define VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME "VK_EXT_multisampled_render_to_single_sampled" +typedef struct VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 multisampledRenderToSingleSampled; +} VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT; + +typedef struct VkSubpassResolvePerformanceQueryEXT { + VkStructureType sType; + void* pNext; + VkBool32 optimal; +} VkSubpassResolvePerformanceQueryEXT; + +typedef struct VkMultisampledRenderToSingleSampledInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 multisampledRenderToSingleSampledEnable; + VkSampleCountFlagBits rasterizationSamples; +} VkMultisampledRenderToSingleSampledInfoEXT; + + + #define VK_EXT_extended_dynamic_state2 1 #define VK_EXT_EXTENDED_DYNAMIC_STATE_2_SPEC_VERSION 1 #define VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME "VK_EXT_extended_dynamic_state2" @@ -14274,6 +14325,52 @@ typedef struct VkRenderPassSubpassFeedbackCreateInfoEXT { +#define VK_EXT_shader_module_identifier 1 +#define VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT 32U +#define VK_EXT_SHADER_MODULE_IDENTIFIER_SPEC_VERSION 1 +#define VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME "VK_EXT_shader_module_identifier" +typedef struct VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderModuleIdentifier; +} VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT; + +typedef struct VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT { + VkStructureType sType; + void* pNext; + uint8_t shaderModuleIdentifierAlgorithmUUID[VK_UUID_SIZE]; +} VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT; + +typedef struct VkPipelineShaderStageModuleIdentifierCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t identifierSize; + const uint8_t* pIdentifier; +} VkPipelineShaderStageModuleIdentifierCreateInfoEXT; + +typedef struct VkShaderModuleIdentifierEXT { + VkStructureType sType; + void* pNext; + uint32_t identifierSize; + uint8_t identifier[VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT]; +} VkShaderModuleIdentifierEXT; + +typedef void (VKAPI_PTR *PFN_vkGetShaderModuleIdentifierEXT)(VkDevice device, VkShaderModule shaderModule, VkShaderModuleIdentifierEXT* pIdentifier); +typedef void (VKAPI_PTR *PFN_vkGetShaderModuleCreateInfoIdentifierEXT)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, VkShaderModuleIdentifierEXT* pIdentifier); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetShaderModuleIdentifierEXT( + VkDevice device, + VkShaderModule shaderModule, + VkShaderModuleIdentifierEXT* pIdentifier); + +VKAPI_ATTR void VKAPI_CALL vkGetShaderModuleCreateInfoIdentifierEXT( + VkDevice device, + const VkShaderModuleCreateInfo* pCreateInfo, + VkShaderModuleIdentifierEXT* pIdentifier); +#endif + + #define VK_KHR_acceleration_structure 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) #define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 From d6afe365921e53f67cd6eafedaabde9f02109f72 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 4 Jul 2022 21:03:20 +0200 Subject: [PATCH 0131/1348] [dxvk] Enable VK_EXT_graphics_pipeline_library if supported --- src/dxvk/dxvk_adapter.cpp | 25 ++++++++++++++++++++++++- src/dxvk/dxvk_device_info.h | 2 ++ src/dxvk/dxvk_extensions.h | 2 ++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 8ba0359d4..1182829b1 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -234,6 +234,8 @@ namespace dxvk { || !required.extDepthClipEnable.depthClipEnable) && (m_deviceFeatures.extExtendedDynamicState.extendedDynamicState || !required.extExtendedDynamicState.extendedDynamicState) + && (m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary + || !required.extGraphicsPipelineLibrary.graphicsPipelineLibrary) && (m_deviceFeatures.extHostQueryReset.hostQueryReset || !required.extHostQueryReset.hostQueryReset) && (m_deviceFeatures.extMemoryPriority.memoryPriority @@ -265,7 +267,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -274,6 +276,7 @@ namespace dxvk { &devExtensions.extDepthClipEnable, &devExtensions.extExtendedDynamicState, &devExtensions.extFullScreenExclusive, + &devExtensions.extGraphicsPipelineLibrary, &devExtensions.extHostQueryReset, &devExtensions.extMemoryBudget, &devExtensions.extMemoryPriority, @@ -292,6 +295,7 @@ namespace dxvk { &devExtensions.khrDynamicRendering, &devExtensions.khrExternalMemoryWin32, &devExtensions.khrImageFormatList, + &devExtensions.khrPipelineLibrary, &devExtensions.khrSamplerMirrorClampToEdge, &devExtensions.khrShaderFloatControls, &devExtensions.khrSwapchain, @@ -330,6 +334,8 @@ namespace dxvk { // Enable additional device features if supported enabledFeatures.extExtendedDynamicState.extendedDynamicState = VK_TRUE; + enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary; + enabledFeatures.ext4444Formats.formatA4B4G4R4 = m_deviceFeatures.ext4444Formats.formatA4B4G4R4; enabledFeatures.ext4444Formats.formatA4R4G4B4 = m_deviceFeatures.ext4444Formats.formatA4R4G4B4; @@ -375,6 +381,11 @@ namespace dxvk { enabledFeatures.extExtendedDynamicState.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extExtendedDynamicState); } + if (devExtensions.extGraphicsPipelineLibrary) { + enabledFeatures.extGraphicsPipelineLibrary.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT; + enabledFeatures.extGraphicsPipelineLibrary.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extGraphicsPipelineLibrary); + } + if (devExtensions.extHostQueryReset) { enabledFeatures.extHostQueryReset.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT; enabledFeatures.extHostQueryReset.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extHostQueryReset); @@ -609,6 +620,11 @@ namespace dxvk { m_deviceInfo.extCustomBorderColor.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extCustomBorderColor); } + if (m_deviceExtensions.supports(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME)) { + m_deviceInfo.extGraphicsPipelineLibrary.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT; + m_deviceInfo.extGraphicsPipelineLibrary.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extGraphicsPipelineLibrary); + } + if (m_deviceExtensions.supports(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME)) { m_deviceInfo.extRobustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT; m_deviceInfo.extRobustness2.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extRobustness2); @@ -690,6 +706,11 @@ namespace dxvk { m_deviceFeatures.extExtendedDynamicState.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extExtendedDynamicState); } + if (m_deviceExtensions.supports(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME)) { + m_deviceFeatures.extGraphicsPipelineLibrary.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT; + m_deviceFeatures.extGraphicsPipelineLibrary.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extGraphicsPipelineLibrary); + } + if (m_deviceExtensions.supports(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) { m_deviceFeatures.extHostQueryReset.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT; m_deviceFeatures.extHostQueryReset.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extHostQueryReset); @@ -811,6 +832,8 @@ namespace dxvk { "\n depthClipEnable : ", features.extDepthClipEnable.depthClipEnable ? "1" : "0", "\n", VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, "\n extendedDynamicState : ", features.extExtendedDynamicState.extendedDynamicState ? "1" : "0", + "\n", VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, + "\n graphicsPipelineLibrary : ", features.extGraphicsPipelineLibrary.graphicsPipelineLibrary ? "1" : "0", "\n", VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, "\n hostQueryReset : ", features.extHostQueryReset.hostQueryReset ? "1" : "0", "\n", VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 5f4ee91f2..9cea566f8 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -18,6 +18,7 @@ namespace dxvk { VkPhysicalDeviceSubgroupProperties coreSubgroup; VkPhysicalDeviceConservativeRasterizationPropertiesEXT extConservativeRasterization; VkPhysicalDeviceCustomBorderColorPropertiesEXT extCustomBorderColor; + VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT extGraphicsPipelineLibrary; VkPhysicalDeviceRobustness2PropertiesEXT extRobustness2; VkPhysicalDeviceTransformFeedbackPropertiesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT extVertexAttributeDivisor; @@ -41,6 +42,7 @@ namespace dxvk { VkPhysicalDeviceCustomBorderColorFeaturesEXT extCustomBorderColor; VkPhysicalDeviceDepthClipEnableFeaturesEXT extDepthClipEnable; VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extExtendedDynamicState; + VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT extGraphicsPipelineLibrary; VkPhysicalDeviceHostQueryResetFeaturesEXT extHostQueryReset; VkPhysicalDeviceMemoryPriorityFeaturesEXT extMemoryPriority; VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT extNonSeamlessCubeMap; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index d94e3480f..c4c15de2d 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -284,6 +284,7 @@ namespace dxvk { DxvkExt extDepthClipEnable = { VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extExtendedDynamicState = { VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt extFullScreenExclusive = { VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extGraphicsPipelineLibrary = { VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extHostQueryReset = { VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extMemoryBudget = { VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, DxvkExtMode::Passive }; DxvkExt extMemoryPriority = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, DxvkExtMode::Optional }; @@ -302,6 +303,7 @@ namespace dxvk { DxvkExt khrDynamicRendering = { VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrImageFormatList = { VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, DxvkExtMode::Required }; + DxvkExt khrPipelineLibrary = { VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrSamplerMirrorClampToEdge = { VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrShaderFloatControls = { VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrSwapchain = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtMode::Required }; From 6c756c2dbee0f46ff1d7f13a5c994ce5e2ba9a31 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 00:01:07 +0200 Subject: [PATCH 0132/1348] [dxvk] Add check whether graphics pipeline libraries can be used --- src/dxvk/dxvk_device.cpp | 9 +++++++++ src/dxvk/dxvk_device.h | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 36d2563a7..49421bc85 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -41,6 +41,15 @@ namespace dxvk { } + bool DxvkDevice::canUseGraphicsPipelineLibrary() const { + // Without graphicsPipelineLibraryIndependentInterpolationDecoration, we + // cannot use this effectively in many games since no client API provides + // interpoation qualifiers in vertex shaders. + return m_features.extGraphicsPipelineLibrary.graphicsPipelineLibrary + && m_properties.extGraphicsPipelineLibrary.graphicsPipelineLibraryIndependentInterpolationDecoration; + } + + DxvkFramebufferSize DxvkDevice::getDefaultFramebufferSize() const { return DxvkFramebufferSize { m_properties.core.properties.limits.maxFramebufferWidth, diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 65730cbd3..361640548 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -197,6 +197,12 @@ namespace dxvk { */ bool isUnifiedMemoryArchitecture() const; + /** + * \brief Checks whether graphics pipeline libraries can be used + * \returns \c true if all required features are supported. + */ + bool canUseGraphicsPipelineLibrary() const; + /** * \brief Queries default framebuffer size * \returns Default framebuffer size From 1e56f2b7a0dc039c1992fefa52e79970fc6aefba Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 01:57:22 +0200 Subject: [PATCH 0133/1348] [dxvk] Factor out vertex input state setup --- src/dxvk/dxvk_graphics.cpp | 182 ++++++++++++++++++++++++++----------- src/dxvk/dxvk_graphics.h | 32 ++++++- 2 files changed, 160 insertions(+), 54 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 597cfd19c..a45b16a9e 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -8,6 +8,131 @@ namespace dxvk { + DxvkGraphicsPipelineVertexInputState::DxvkGraphicsPipelineVertexInputState() { + + } + + + DxvkGraphicsPipelineVertexInputState::DxvkGraphicsPipelineVertexInputState( + const DxvkDevice* device, + const DxvkGraphicsPipelineStateInfo& state) { + std::array viBindingMap = { }; + + iaInfo.topology = state.ia.primitiveTopology(); + iaInfo.primitiveRestartEnable = state.ia.primitiveRestart(); + + viInfo.vertexBindingDescriptionCount = state.il.bindingCount(); + viInfo.vertexAttributeDescriptionCount = state.il.attributeCount(); + + // Process vertex bindings. We will compact binding numbers on + // the fly so that vertex buffers can be updated more easily. + for (uint32_t i = 0; i < state.il.bindingCount(); i++) { + viBindingMap[state.ilBindings[i].binding()] = i; + + viBindings[i].binding = i; + viBindings[i].stride = state.ilBindings[i].stride(); + viBindings[i].inputRate = state.ilBindings[i].inputRate(); + + if (state.ilBindings[i].inputRate() == VK_VERTEX_INPUT_RATE_INSTANCE + && state.ilBindings[i].divisor() != 1) { + uint32_t index = viDivisorInfo.vertexBindingDivisorCount++; + + viDivisors[index].binding = i; + viDivisors[index].divisor = state.ilBindings[i].divisor(); + } + } + + if (viInfo.vertexBindingDescriptionCount) + viInfo.pVertexBindingDescriptions = viBindings.data(); + + if (viDivisorInfo.vertexBindingDivisorCount) { + viDivisorInfo.pVertexBindingDivisors = viDivisors.data(); + + if (device->features().extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor) + viInfo.pNext = &viDivisorInfo; + } + + // Process vertex attributes, using binding map generated above + for (uint32_t i = 0; i < state.il.attributeCount(); i++) { + viAttributes[i].location = state.ilAttributes[i].location(); + viAttributes[i].binding = viBindingMap[state.ilAttributes[i].binding()]; + viAttributes[i].format = state.ilAttributes[i].format(); + viAttributes[i].offset = state.ilAttributes[i].offset(); + } + + if (viInfo.vertexAttributeDescriptionCount) + viInfo.pVertexAttributeDescriptions = viAttributes.data(); + } + + + bool DxvkGraphicsPipelineVertexInputState::eq(const DxvkGraphicsPipelineVertexInputState& other) const { + bool eq = iaInfo.topology == other.iaInfo.topology + && iaInfo.primitiveRestartEnable == other.iaInfo.primitiveRestartEnable + && viInfo.vertexBindingDescriptionCount == other.viInfo.vertexBindingDescriptionCount + && viInfo.vertexAttributeDescriptionCount == other.viInfo.vertexAttributeDescriptionCount + && viDivisorInfo.vertexBindingDivisorCount == other.viDivisorInfo.vertexBindingDivisorCount; + + for (uint32_t i = 0; i < viInfo.vertexBindingDescriptionCount && eq; i++) { + const auto& a = viBindings[i]; + const auto& b = other.viBindings[i]; + + eq = a.binding == b.binding + && a.stride == b.stride + && a.inputRate == b.inputRate; + } + + for (uint32_t i = 0; i < viInfo.vertexAttributeDescriptionCount && eq; i++) { + const auto& a = viAttributes[i]; + const auto& b = other.viAttributes[i]; + + eq = a.location == b.location + && a.binding == b.binding + && a.format == b.format + && a.offset == b.offset; + } + + for (uint32_t i = 0; i < viDivisorInfo.vertexBindingDivisorCount; i++) { + const auto& a = viDivisors[i]; + const auto& b = other.viDivisors[i]; + + eq = a.binding == b.binding + && a.divisor == b.divisor; + } + + return eq; + } + + + size_t DxvkGraphicsPipelineVertexInputState::hash() const { + DxvkHashState hash; + hash.add(uint32_t(iaInfo.topology)); + hash.add(uint32_t(iaInfo.primitiveRestartEnable)); + hash.add(uint32_t(viInfo.vertexBindingDescriptionCount)); + hash.add(uint32_t(viInfo.vertexAttributeDescriptionCount)); + hash.add(uint32_t(viDivisorInfo.vertexBindingDivisorCount)); + + for (uint32_t i = 0; i < viInfo.vertexBindingDescriptionCount; i++) { + hash.add(uint32_t(viBindings[i].binding)); + hash.add(uint32_t(viBindings[i].stride)); + hash.add(uint32_t(viBindings[i].inputRate)); + } + + for (uint32_t i = 0; i < viInfo.vertexAttributeDescriptionCount; i++) { + hash.add(uint32_t(viAttributes[i].location)); + hash.add(uint32_t(viAttributes[i].binding)); + hash.add(uint32_t(viAttributes[i].format)); + hash.add(uint32_t(viAttributes[i].offset)); + } + + for (uint32_t i = 0; i < viDivisorInfo.vertexBindingDivisorCount; i++) { + hash.add(uint32_t(viDivisors[i].binding)); + hash.add(uint32_t(viDivisors[i].divisor)); + } + + return hash; + } + + DxvkGraphicsPipeline::DxvkGraphicsPipeline( DxvkPipelineManager* pipeMgr, DxvkGraphicsPipelineShaders shaders, @@ -131,6 +256,8 @@ namespace dxvk { VkPipeline DxvkGraphicsPipeline::createPipeline( const DxvkGraphicsPipelineStateInfo& state) const { + const DxvkDevice* device = m_pipeMgr->m_device; + if (Logger::logLevel() <= LogLevel::Debug) { Logger::debug("Compiling graphics pipeline..."); this->logPipelineState(LogLevel::Debug, state); @@ -232,61 +359,12 @@ namespace dxvk { } } - // Generate per-instance attribute divisors - std::array viDivisorDesc; - uint32_t viDivisorCount = 0; - - for (uint32_t i = 0; i < state.il.bindingCount(); i++) { - if (state.ilBindings[i].inputRate() == VK_VERTEX_INPUT_RATE_INSTANCE - && state.ilBindings[i].divisor() != 1) { - const uint32_t id = viDivisorCount++; - - viDivisorDesc[id].binding = i; /* see below */ - viDivisorDesc[id].divisor = state.ilBindings[i].divisor(); - } - } - int32_t rasterizedStream = m_shaders.gs != nullptr ? m_shaders.gs->info().xfbRasterizedStream : 0; - - // Compact vertex bindings so that we can more easily update vertex buffers - std::array viAttribs; - std::array viBindings; - std::array viBindingMap = { }; - for (uint32_t i = 0; i < state.il.bindingCount(); i++) { - viBindings[i] = state.ilBindings[i].description(); - viBindings[i].binding = i; - viBindingMap[state.ilBindings[i].binding()] = i; - } + DxvkGraphicsPipelineVertexInputState viState(device, state); - for (uint32_t i = 0; i < state.il.attributeCount(); i++) { - viAttribs[i] = state.ilAttributes[i].description(); - viAttribs[i].binding = viBindingMap[state.ilAttributes[i].binding()]; - } - - VkPipelineVertexInputDivisorStateCreateInfoEXT viDivisorInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT }; - viDivisorInfo.vertexBindingDivisorCount = viDivisorCount; - viDivisorInfo.pVertexBindingDivisors = viDivisorDesc.data(); - - VkPipelineVertexInputStateCreateInfo viInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, &viDivisorInfo }; - viInfo.vertexBindingDescriptionCount = state.il.bindingCount(); - viInfo.pVertexBindingDescriptions = viBindings.data(); - viInfo.vertexAttributeDescriptionCount = state.il.attributeCount(); - viInfo.pVertexAttributeDescriptions = viAttribs.data(); - - if (viDivisorCount == 0) - viInfo.pNext = viDivisorInfo.pNext; - - // TODO remove this once the extension is widely supported - if (!m_pipeMgr->m_device->features().extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor) - viInfo.pNext = viDivisorInfo.pNext; - - VkPipelineInputAssemblyStateCreateInfo iaInfo = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; - iaInfo.topology = state.ia.primitiveTopology(); - iaInfo.primitiveRestartEnable = state.ia.primitiveRestart(); - VkPipelineTessellationStateCreateInfo tsInfo = { VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO }; tsInfo.patchControlPoints = state.ia.patchVertexCount(); @@ -369,8 +447,8 @@ namespace dxvk { VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &rtInfo }; info.stageCount = stages.size(); info.pStages = stages.data(); - info.pVertexInputState = &viInfo; - info.pInputAssemblyState = &iaInfo; + info.pVertexInputState = &viState.viInfo; + info.pInputAssemblyState = &viState.iaInfo; info.pTessellationState = &tsInfo; info.pViewportState = &vpInfo; info.pRasterizationState = &rsInfo; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 651c63dd2..9b106575a 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -19,6 +19,34 @@ namespace dxvk { class DxvkDevice; class DxvkPipelineManager; + /** + * \brief Vertex input info for graphics pipelines + * + * Can be used to compile dedicated vertex input pipelines for + * use in a graphics pipeline library, or as part of the data + * required to compile a full graphics pipeline. + */ + struct DxvkGraphicsPipelineVertexInputState { + DxvkGraphicsPipelineVertexInputState(); + + DxvkGraphicsPipelineVertexInputState( + const DxvkDevice* device, + const DxvkGraphicsPipelineStateInfo& state); + + VkPipelineInputAssemblyStateCreateInfo iaInfo = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; + VkPipelineVertexInputStateCreateInfo viInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; + VkPipelineVertexInputDivisorStateCreateInfoEXT viDivisorInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT }; + + std::array viBindings = { }; + std::array viDivisors = { }; + std::array viAttributes = { }; + + bool eq(const DxvkGraphicsPipelineVertexInputState& other) const; + + size_t hash() const; + }; + + /** * \brief Flags that describe pipeline properties */ @@ -68,8 +96,8 @@ namespace dxvk { return shader == nullptr || shader->info().stage == stage; } }; - - + + /** * \brief Common graphics pipeline state * From 08e0e4181b9f85e9c425c188be77ba6876cfbdf6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 03:08:53 +0200 Subject: [PATCH 0134/1348] [dxvk] Factor out fragment output state setup --- src/dxvk/dxvk_graphics.cpp | 256 ++++++++++++++++++++++++------------- src/dxvk/dxvk_graphics.h | 53 +++++--- 2 files changed, 202 insertions(+), 107 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index a45b16a9e..142d2d1bd 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -133,6 +133,164 @@ namespace dxvk { } + DxvkGraphicsPipelineFragmentOutputState::DxvkGraphicsPipelineFragmentOutputState() { + + } + + + DxvkGraphicsPipelineFragmentOutputState::DxvkGraphicsPipelineFragmentOutputState( + const DxvkDevice* device, + const DxvkGraphicsPipelineStateInfo& state, + const DxvkShader* fs) { + // Set up color formats and attachment blend states. Disable the write + // mask for any attachment that the fragment shader does not write to. + uint32_t fsOutputMask = fs ? fs->info().outputMask : 0u; + + const VkColorComponentFlags rgbaWriteMask + = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT + | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + + cbInfo.logicOpEnable = state.om.enableLogicOp(); + cbInfo.logicOp = state.om.logicOp(); + + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + rtColorFormats[i] = state.rt.getColorFormat(i); + + if (rtColorFormats[i]) { + rtInfo.colorAttachmentCount = i + 1; + + auto formatInfo = imageFormatInfo(rtColorFormats[i]); + cbAttachments[i] = state.omBlend[i].state(); + + if (!(fsOutputMask & (1 << i)) || !formatInfo) { + cbAttachments[i].colorWriteMask = 0; + } else { + if (cbAttachments[i].colorWriteMask != rgbaWriteMask) { + cbAttachments[i].colorWriteMask = util::remapComponentMask( + state.omBlend[i].colorWriteMask(), state.omSwizzle[i].mapping()); + } + + cbAttachments[i].colorWriteMask &= formatInfo->componentMask; + + if (cbAttachments[i].colorWriteMask == formatInfo->componentMask) { + cbAttachments[i].colorWriteMask = rgbaWriteMask; + } + } + } + } + + if (rtInfo.colorAttachmentCount) { + rtInfo.pColorAttachmentFormats = rtColorFormats.data(); + + cbInfo.attachmentCount = rtInfo.colorAttachmentCount; + cbInfo.pAttachments = cbAttachments.data(); + } + + // Set up depth-stencil format accordingly. + VkFormat rtDepthFormat = state.rt.getDepthStencilFormat(); + + if (rtDepthFormat) { + auto rtDepthFormatInfo = imageFormatInfo(rtDepthFormat); + + if (rtDepthFormatInfo->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) + rtInfo.depthAttachmentFormat = rtDepthFormat; + + if (rtDepthFormatInfo->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) + rtInfo.stencilAttachmentFormat = rtDepthFormat; + } + + // Set up multisample state based on shader info as well + // as rasterization state and render target sample counts. + if (state.ms.sampleCount()) + msInfo.rasterizationSamples = VkSampleCountFlagBits(state.ms.sampleCount()); + else if (state.rs.sampleCount()) + msInfo.rasterizationSamples = VkSampleCountFlagBits(state.rs.sampleCount()); + else + msInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + + if (fs && fs->flags().test(DxvkShaderFlag::HasSampleRateShading)) { + msInfo.sampleShadingEnable = VK_TRUE; + msInfo.minSampleShading = 1.0f; + } + + msSampleMask = state.ms.sampleMask() & ((1u << msInfo.rasterizationSamples) - 1); + msInfo.pSampleMask = &msSampleMask; + msInfo.alphaToCoverageEnable = state.ms.enableAlphaToCoverage(); + } + + + bool DxvkGraphicsPipelineFragmentOutputState::eq(const DxvkGraphicsPipelineFragmentOutputState& other) const { + bool eq = rtInfo.colorAttachmentCount == other.rtInfo.colorAttachmentCount + && rtInfo.depthAttachmentFormat == other.rtInfo.depthAttachmentFormat + && rtInfo.stencilAttachmentFormat == other.rtInfo.stencilAttachmentFormat + && cbInfo.logicOpEnable == other.cbInfo.logicOpEnable + && cbInfo.logicOp == other.cbInfo.logicOp + && cbInfo.attachmentCount == other.cbInfo.attachmentCount + && msInfo.rasterizationSamples == other.msInfo.rasterizationSamples + && msInfo.sampleShadingEnable == other.msInfo.sampleShadingEnable + && msInfo.minSampleShading == other.msInfo.minSampleShading + && msInfo.alphaToCoverageEnable == other.msInfo.alphaToCoverageEnable + && msInfo.alphaToOneEnable == other.msInfo.alphaToOneEnable + && msSampleMask == other.msSampleMask; + + for (uint32_t i = 0; i < rtInfo.colorAttachmentCount && eq; i++) + eq = rtColorFormats[i] == other.rtColorFormats[i]; + + for (uint32_t i = 0; i < cbInfo.attachmentCount && eq; i++) { + const auto& a = cbAttachments[i]; + const auto& b = other.cbAttachments[i]; + + eq = a.blendEnable == b.blendEnable + && a.colorWriteMask == b.colorWriteMask; + + if (a.blendEnable && eq) { + eq = a.srcColorBlendFactor == b.srcColorBlendFactor + && a.dstColorBlendFactor == b.dstColorBlendFactor + && a.colorBlendOp == b.colorBlendOp + && a.srcAlphaBlendFactor == b.srcAlphaBlendFactor + && a.dstAlphaBlendFactor == b.dstAlphaBlendFactor + && a.alphaBlendOp == b.alphaBlendOp; + } + } + + return eq; + } + + + size_t DxvkGraphicsPipelineFragmentOutputState::hash() const { + DxvkHashState hash; + hash.add(uint32_t(rtInfo.colorAttachmentCount)); + hash.add(uint32_t(rtInfo.depthAttachmentFormat)); + hash.add(uint32_t(rtInfo.stencilAttachmentFormat)); + hash.add(uint32_t(cbInfo.logicOpEnable)); + hash.add(uint32_t(cbInfo.logicOp)); + hash.add(uint32_t(cbInfo.attachmentCount)); + hash.add(uint32_t(msInfo.rasterizationSamples)); + hash.add(uint32_t(msInfo.alphaToCoverageEnable)); + hash.add(uint32_t(msInfo.alphaToOneEnable)); + hash.add(uint32_t(msSampleMask)); + + for (uint32_t i = 0; i < rtInfo.colorAttachmentCount; i++) + hash.add(uint32_t(rtColorFormats[i])); + + for (uint32_t i = 0; i < cbInfo.attachmentCount; i++) { + hash.add(uint32_t(cbAttachments[i].blendEnable)); + hash.add(uint32_t(cbAttachments[i].colorWriteMask)); + + if (cbAttachments[i].blendEnable) { + hash.add(uint32_t(cbAttachments[i].srcColorBlendFactor)); + hash.add(uint32_t(cbAttachments[i].dstColorBlendFactor)); + hash.add(uint32_t(cbAttachments[i].colorBlendOp)); + hash.add(uint32_t(cbAttachments[i].srcAlphaBlendFactor)); + hash.add(uint32_t(cbAttachments[i].dstAlphaBlendFactor)); + hash.add(uint32_t(cbAttachments[i].alphaBlendOp)); + } + } + + return hash; + } + + DxvkGraphicsPipeline::DxvkGraphicsPipeline( DxvkPipelineManager* pipeMgr, DxvkGraphicsPipelineShaders shaders, @@ -155,9 +313,6 @@ namespace dxvk { if (m_barrier.access & VK_ACCESS_SHADER_WRITE_BIT) m_flags.set(DxvkGraphicsPipelineFlag::HasStorageDescriptors); - - m_common.msSampleShadingEnable = m_shaders.fs != nullptr && m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading); - m_common.msSampleShadingFactor = 1.0f; } @@ -282,14 +437,6 @@ namespace dxvk { if (state.useDynamicStencilRef()) dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; - // Figure out the actual sample count to use - VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT; - - if (state.ms.sampleCount()) - sampleCount = VkSampleCountFlagBits(state.ms.sampleCount()); - else if (state.rs.sampleCount()) - sampleCount = VkSampleCountFlagBits(state.rs.sampleCount()); - // Set up some specialization constants DxvkSpecConstants specData; @@ -319,51 +466,12 @@ namespace dxvk { if (gsm) stages.push_back(gsm.stageInfo(&specInfo)); if (fsm) stages.push_back(fsm.stageInfo(&specInfo)); - // Fix up color write masks using the component mappings - VkImageAspectFlags rtReadOnlyAspects = state.rt.getDepthStencilReadOnlyAspects(); - VkFormat rtDepthFormat = state.rt.getDepthStencilFormat(); - auto rtDepthFormatInfo = imageFormatInfo(rtDepthFormat); - - std::array omBlendAttachments = { }; - std::array rtColorFormats; - uint32_t rtColorFormatCount = 0; - - const VkColorComponentFlags fullMask - = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT - | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - rtColorFormats[i] = state.rt.getColorFormat(i); - - if (rtColorFormats[i]) { - rtColorFormatCount = i + 1; - - auto formatInfo = imageFormatInfo(rtColorFormats[i]); - omBlendAttachments[i] = state.omBlend[i].state(); - - if (!(m_fsOut & (1 << i)) || !formatInfo) { - omBlendAttachments[i].colorWriteMask = 0; - } else { - if (omBlendAttachments[i].colorWriteMask != fullMask) { - omBlendAttachments[i].colorWriteMask = util::remapComponentMask( - state.omBlend[i].colorWriteMask(), state.omSwizzle[i].mapping()); - } - - omBlendAttachments[i].colorWriteMask &= formatInfo->componentMask; - - if (omBlendAttachments[i].colorWriteMask == formatInfo->componentMask) { - omBlendAttachments[i].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT - | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - } - } - } - } - int32_t rasterizedStream = m_shaders.gs != nullptr ? m_shaders.gs->info().xfbRasterizedStream : 0; - DxvkGraphicsPipelineVertexInputState viState(device, state); + DxvkGraphicsPipelineVertexInputState viState(device, state); + DxvkGraphicsPipelineFragmentOutputState foState(device, state, m_shaders.fs.ptr()); VkPipelineTessellationStateCreateInfo tsInfo = { VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO }; tsInfo.patchControlPoints = state.ia.patchVertexCount(); @@ -400,51 +508,23 @@ namespace dxvk { else rsInfo.depthClampEnable = !state.rs.depthClipEnable(); - uint32_t sampleMask = state.ms.sampleMask(); - - VkPipelineMultisampleStateCreateInfo msInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; - msInfo.rasterizationSamples = sampleCount; - msInfo.sampleShadingEnable = m_common.msSampleShadingEnable; - msInfo.minSampleShading = m_common.msSampleShadingFactor; - msInfo.pSampleMask = &sampleMask; - msInfo.alphaToCoverageEnable = state.ms.enableAlphaToCoverage(); - msInfo.alphaToOneEnable = VK_FALSE; - VkPipelineDepthStencilStateCreateInfo dsInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; dsInfo.depthTestEnable = state.ds.enableDepthTest(); - dsInfo.depthWriteEnable = state.ds.enableDepthWrite() && !(rtReadOnlyAspects & VK_IMAGE_ASPECT_DEPTH_BIT); + dsInfo.depthWriteEnable = state.ds.enableDepthWrite(); dsInfo.depthCompareOp = state.ds.depthCompareOp(); dsInfo.depthBoundsTestEnable = state.ds.enableDepthBoundsTest(); dsInfo.stencilTestEnable = state.ds.enableStencilTest(); dsInfo.front = state.dsFront.state(); dsInfo.back = state.dsBack.state(); - - VkPipelineColorBlendStateCreateInfo cbInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; - cbInfo.logicOpEnable = state.om.enableLogicOp(); - cbInfo.logicOp = state.om.logicOp(); - cbInfo.attachmentCount = rtColorFormatCount; - cbInfo.pAttachments = omBlendAttachments.data(); - + + if ((state.rt.getDepthStencilReadOnlyAspects() & VK_IMAGE_ASPECT_DEPTH_BIT)) + dsInfo.depthWriteEnable = VK_FALSE; + VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; dyInfo.dynamicStateCount = dynamicStateCount; dyInfo.pDynamicStates = dynamicStates.data(); - VkPipelineRenderingCreateInfoKHR rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; - - if (rtColorFormatCount) { - rtInfo.colorAttachmentCount = rtColorFormatCount; - rtInfo.pColorAttachmentFormats = rtColorFormats.data(); - } - - if (rtDepthFormat) { - if (rtDepthFormatInfo->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) - rtInfo.depthAttachmentFormat = rtDepthFormat; - - if (rtDepthFormatInfo->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) - rtInfo.stencilAttachmentFormat = rtDepthFormat; - } - - VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &rtInfo }; + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &foState.rtInfo }; info.stageCount = stages.size(); info.pStages = stages.data(); info.pVertexInputState = &viState.viInfo; @@ -452,9 +532,9 @@ namespace dxvk { info.pTessellationState = &tsInfo; info.pViewportState = &vpInfo; info.pRasterizationState = &rsInfo; - info.pMultisampleState = &msInfo; + info.pMultisampleState = &foState.msInfo; info.pDepthStencilState = &dsInfo; - info.pColorBlendState = &cbInfo; + info.pColorBlendState = &foState.cbInfo; info.pDynamicState = &dyInfo; info.layout = m_bindings->getPipelineLayout(); info.basePipelineIndex = -1; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 9b106575a..590e75951 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -22,8 +22,8 @@ namespace dxvk { /** * \brief Vertex input info for graphics pipelines * - * Can be used to compile dedicated vertex input pipelines for - * use in a graphics pipeline library, or as part of the data + * Can be used to compile dedicated pipeline objects for use + * in a graphics pipeline library, or as part of the data * required to compile a full graphics pipeline. */ struct DxvkGraphicsPipelineVertexInputState { @@ -47,6 +47,35 @@ namespace dxvk { }; + /** + * \brief Fragment output info for graphics pipelines + * + * Can be used to compile dedicated pipeline objects for use + * in a graphics pipeline library, or as part of the data + * required to compile a full graphics pipeline. + */ + struct DxvkGraphicsPipelineFragmentOutputState { + DxvkGraphicsPipelineFragmentOutputState(); + + DxvkGraphicsPipelineFragmentOutputState( + const DxvkDevice* device, + const DxvkGraphicsPipelineStateInfo& state, + const DxvkShader* fs); + + VkPipelineRenderingCreateInfoKHR rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + VkPipelineColorBlendStateCreateInfo cbInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; + VkPipelineMultisampleStateCreateInfo msInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; + + uint32_t msSampleMask = 0u; + std::array cbAttachments = { }; + std::array rtColorFormats = { }; + + bool eq(const DxvkGraphicsPipelineFragmentOutputState& other) const; + + size_t hash() const; + }; + + /** * \brief Flags that describe pipeline properties */ @@ -98,18 +127,6 @@ namespace dxvk { }; - /** - * \brief Common graphics pipeline state - * - * Non-dynamic pipeline state that cannot - * be changed dynamically. - */ - struct DxvkGraphicsCommonPipelineStateInfo { - bool msSampleShadingEnable; - float msSampleShadingFactor; - }; - - /** * \brief Graphics pipeline instance * @@ -255,14 +272,12 @@ namespace dxvk { DxvkGraphicsPipelineShaders m_shaders; DxvkBindingLayoutObjects* m_bindings; - + DxvkGlobalPipelineBarrier m_barrier; + DxvkGraphicsPipelineFlags m_flags; + uint32_t m_vsIn = 0; uint32_t m_fsOut = 0; - DxvkGlobalPipelineBarrier m_barrier; - DxvkGraphicsPipelineFlags m_flags; - DxvkGraphicsCommonPipelineStateInfo m_common; - // List of pipeline instances, shared between threads alignas(CACHE_LINE_SIZE) dxvk::mutex m_mutex; From 33067f2a23bbed70147aa500319cf29c138d3dbf Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 04:04:15 +0200 Subject: [PATCH 0135/1348] [dxvk] Factor out pre-rasterization state setup --- src/dxvk/dxvk_graphics.cpp | 101 ++++++++++++++++++++----------------- src/dxvk/dxvk_graphics.h | 23 +++++++++ 2 files changed, 79 insertions(+), 45 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 142d2d1bd..0dee2c28c 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -291,6 +291,55 @@ namespace dxvk { } + DxvkGraphicsPipelinePreRasterizationState::DxvkGraphicsPipelinePreRasterizationState() { + + } + + + DxvkGraphicsPipelinePreRasterizationState::DxvkGraphicsPipelinePreRasterizationState( + const DxvkDevice* device, + const DxvkGraphicsPipelineStateInfo& state, + const DxvkShader* gs) { + // Set up tessellation state + tsInfo.patchControlPoints = state.ia.patchVertexCount(); + + // Set up basic rasterization state + rsInfo.depthClampEnable = VK_TRUE; + rsInfo.polygonMode = state.rs.polygonMode(); + rsInfo.cullMode = state.rs.cullMode(); + rsInfo.frontFace = state.rs.frontFace(); + rsInfo.depthBiasEnable = state.rs.depthBiasEnable(); + rsInfo.lineWidth = 1.0f; + + // Set up rasterized stream depending on geometry shader state. + // Rasterizing stream 0 is default behaviour in all situations. + int32_t streamIndex = gs ? gs->info().xfbRasterizedStream : 0; + + if (streamIndex > 0) { + rsXfbStreamInfo.pNext = std::exchange(rsInfo.pNext, &rsXfbStreamInfo); + rsXfbStreamInfo.rasterizationStream = uint32_t(streamIndex); + } else if (streamIndex < 0) { + rsInfo.rasterizerDiscardEnable = VK_TRUE; + } + + // Set up depth clip state. If the extension is not supported, + // use depth clamp instead, even though this is not accurate. + if (device->features().extDepthClipEnable.depthClipEnable) { + rsDepthClipInfo.pNext = std::exchange(rsInfo.pNext, &rsDepthClipInfo); + rsDepthClipInfo.depthClipEnable = state.rs.depthClipEnable(); + } else { + rsInfo.depthClampEnable = !state.rs.depthClipEnable(); + } + + // Set up conservative rasterization if requested by the application. + if (state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT) { + rsConservativeInfo.pNext = std::exchange(rsInfo.pNext, &rsConservativeInfo); + rsConservativeInfo.conservativeRasterizationMode = state.rs.conservativeMode(); + rsConservativeInfo.extraPrimitiveOverestimationSize = 0.0f; + } + } + + DxvkGraphicsPipeline::DxvkGraphicsPipeline( DxvkPipelineManager* pipeMgr, DxvkGraphicsPipelineShaders shaders, @@ -466,47 +515,9 @@ namespace dxvk { if (gsm) stages.push_back(gsm.stageInfo(&specInfo)); if (fsm) stages.push_back(fsm.stageInfo(&specInfo)); - int32_t rasterizedStream = m_shaders.gs != nullptr - ? m_shaders.gs->info().xfbRasterizedStream - : 0; - - DxvkGraphicsPipelineVertexInputState viState(device, state); - DxvkGraphicsPipelineFragmentOutputState foState(device, state, m_shaders.fs.ptr()); - - VkPipelineTessellationStateCreateInfo tsInfo = { VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO }; - tsInfo.patchControlPoints = state.ia.patchVertexCount(); - - VkPipelineViewportStateCreateInfo vpInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; - - VkPipelineRasterizationConservativeStateCreateInfoEXT conservativeInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT }; - conservativeInfo.conservativeRasterizationMode = state.rs.conservativeMode(); - conservativeInfo.extraPrimitiveOverestimationSize = 0.0f; - - VkPipelineRasterizationStateStreamCreateInfoEXT xfbStreamInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT }; - xfbStreamInfo.rasterizationStream = uint32_t(rasterizedStream); - - VkPipelineRasterizationDepthClipStateCreateInfoEXT rsDepthClipInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT }; - rsDepthClipInfo.depthClipEnable = state.rs.depthClipEnable(); - - VkPipelineRasterizationStateCreateInfo rsInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; - rsInfo.depthClampEnable = VK_TRUE; - rsInfo.rasterizerDiscardEnable = rasterizedStream < 0; - rsInfo.polygonMode = state.rs.polygonMode(); - rsInfo.cullMode = state.rs.cullMode(); - rsInfo.frontFace = state.rs.frontFace(); - rsInfo.depthBiasEnable = state.rs.depthBiasEnable(); - rsInfo.lineWidth = 1.0f; - - if (rasterizedStream > 0) - xfbStreamInfo.pNext = std::exchange(rsInfo.pNext, &xfbStreamInfo); - - if (conservativeInfo.conservativeRasterizationMode != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT) - conservativeInfo.pNext = std::exchange(rsInfo.pNext, &conservativeInfo); - - if (m_pipeMgr->m_device->features().extDepthClipEnable.depthClipEnable) - rsDepthClipInfo.pNext = std::exchange(rsInfo.pNext, &rsDepthClipInfo); - else - rsInfo.depthClampEnable = !state.rs.depthClipEnable(); + DxvkGraphicsPipelineVertexInputState viState(device, state); + DxvkGraphicsPipelinePreRasterizationState prState(device, state, m_shaders.gs.ptr()); + DxvkGraphicsPipelineFragmentOutputState foState(device, state, m_shaders.fs.ptr()); VkPipelineDepthStencilStateCreateInfo dsInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; dsInfo.depthTestEnable = state.ds.enableDepthTest(); @@ -529,9 +540,9 @@ namespace dxvk { info.pStages = stages.data(); info.pVertexInputState = &viState.viInfo; info.pInputAssemblyState = &viState.iaInfo; - info.pTessellationState = &tsInfo; - info.pViewportState = &vpInfo; - info.pRasterizationState = &rsInfo; + info.pTessellationState = &prState.tsInfo; + info.pViewportState = &prState.vpInfo; + info.pRasterizationState = &prState.rsInfo; info.pMultisampleState = &foState.msInfo; info.pDepthStencilState = &dsInfo; info.pColorBlendState = &foState.cbInfo; @@ -539,7 +550,7 @@ namespace dxvk { info.layout = m_bindings->getPipelineLayout(); info.basePipelineIndex = -1; - if (!tsInfo.patchControlPoints) + if (!prState.tsInfo.patchControlPoints) info.pTessellationState = nullptr; // Time pipeline compilation for debugging purposes diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 590e75951..1bd2b9880 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -75,6 +75,29 @@ namespace dxvk { size_t hash() const; }; + + /** + * \brief Pre-rasterization info for graphics pipelines + * + * Can only be used when compiling full graphics pipelines + * when all pipeline state is known. + */ + struct DxvkGraphicsPipelinePreRasterizationState { + DxvkGraphicsPipelinePreRasterizationState(); + + DxvkGraphicsPipelinePreRasterizationState( + const DxvkDevice* device, + const DxvkGraphicsPipelineStateInfo& state, + const DxvkShader* gs); + + VkPipelineViewportStateCreateInfo vpInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; + VkPipelineTessellationStateCreateInfo tsInfo = { VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO }; + VkPipelineRasterizationStateCreateInfo rsInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; + VkPipelineRasterizationDepthClipStateCreateInfoEXT rsDepthClipInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT }; + VkPipelineRasterizationStateStreamCreateInfoEXT rsXfbStreamInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT }; + VkPipelineRasterizationConservativeStateCreateInfoEXT rsConservativeInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT }; + }; + /** * \brief Flags that describe pipeline properties From 47ac5f49cb7628a26bf84d2d9f7597434f5de663 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 04:08:58 +0200 Subject: [PATCH 0136/1348] [dxvk] Factor out fragment shader state setup --- src/dxvk/dxvk_graphics.cpp | 41 ++++++++++++++++++++++++++------------ src/dxvk/dxvk_graphics.h | 17 ++++++++++++++++ 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 0dee2c28c..bcefd0c4c 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -340,6 +340,32 @@ namespace dxvk { } + DxvkGraphicsPipelineFragmentShaderState::DxvkGraphicsPipelineFragmentShaderState() { + + } + + + DxvkGraphicsPipelineFragmentShaderState::DxvkGraphicsPipelineFragmentShaderState( + const DxvkDevice* device, + const DxvkGraphicsPipelineStateInfo& state) { + dsInfo.depthTestEnable = state.ds.enableDepthTest(); + dsInfo.depthWriteEnable = state.ds.enableDepthWrite(); + dsInfo.depthCompareOp = state.ds.depthCompareOp(); + dsInfo.depthBoundsTestEnable = state.ds.enableDepthBoundsTest(); + dsInfo.stencilTestEnable = state.ds.enableStencilTest(); + dsInfo.front = state.dsFront.state(); + dsInfo.back = state.dsBack.state(); + + if ((state.rt.getDepthStencilReadOnlyAspects() & VK_IMAGE_ASPECT_DEPTH_BIT)) + dsInfo.depthWriteEnable = VK_FALSE; + + if ((state.rt.getDepthStencilReadOnlyAspects() & VK_IMAGE_ASPECT_STENCIL_BIT)) { + dsInfo.front.writeMask = 0; + dsInfo.back.writeMask = 0; + } + } + + DxvkGraphicsPipeline::DxvkGraphicsPipeline( DxvkPipelineManager* pipeMgr, DxvkGraphicsPipelineShaders shaders, @@ -517,20 +543,9 @@ namespace dxvk { DxvkGraphicsPipelineVertexInputState viState(device, state); DxvkGraphicsPipelinePreRasterizationState prState(device, state, m_shaders.gs.ptr()); + DxvkGraphicsPipelineFragmentShaderState fsState(device, state); DxvkGraphicsPipelineFragmentOutputState foState(device, state, m_shaders.fs.ptr()); - VkPipelineDepthStencilStateCreateInfo dsInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; - dsInfo.depthTestEnable = state.ds.enableDepthTest(); - dsInfo.depthWriteEnable = state.ds.enableDepthWrite(); - dsInfo.depthCompareOp = state.ds.depthCompareOp(); - dsInfo.depthBoundsTestEnable = state.ds.enableDepthBoundsTest(); - dsInfo.stencilTestEnable = state.ds.enableStencilTest(); - dsInfo.front = state.dsFront.state(); - dsInfo.back = state.dsBack.state(); - - if ((state.rt.getDepthStencilReadOnlyAspects() & VK_IMAGE_ASPECT_DEPTH_BIT)) - dsInfo.depthWriteEnable = VK_FALSE; - VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; dyInfo.dynamicStateCount = dynamicStateCount; dyInfo.pDynamicStates = dynamicStates.data(); @@ -544,7 +559,7 @@ namespace dxvk { info.pViewportState = &prState.vpInfo; info.pRasterizationState = &prState.rsInfo; info.pMultisampleState = &foState.msInfo; - info.pDepthStencilState = &dsInfo; + info.pDepthStencilState = &fsState.dsInfo; info.pColorBlendState = &foState.cbInfo; info.pDynamicState = &dyInfo; info.layout = m_bindings->getPipelineLayout(); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 1bd2b9880..20e63787b 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -98,6 +98,23 @@ namespace dxvk { VkPipelineRasterizationConservativeStateCreateInfoEXT rsConservativeInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT }; }; + + /** + * \brief Fragment shader state info for graphics pipelines + * + * Can only be used when compiling full graphics pipelines + * when all pipeline state is known. + */ + struct DxvkGraphicsPipelineFragmentShaderState { + DxvkGraphicsPipelineFragmentShaderState(); + + DxvkGraphicsPipelineFragmentShaderState( + const DxvkDevice* device, + const DxvkGraphicsPipelineStateInfo& state); + + VkPipelineDepthStencilStateCreateInfo dsInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; + }; + /** * \brief Flags that describe pipeline properties From 578c136239b86e3f3cb6bdc40188346898df266f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 12:26:20 +0200 Subject: [PATCH 0137/1348] [dxvk] Implement vertex input pipeline libraries --- src/dxvk/dxvk_graphics.cpp | 31 +++++++++++++++++++++++++++++++ src/dxvk/dxvk_graphics.h | 29 +++++++++++++++++++++++++++++ src/dxvk/dxvk_pipemanager.cpp | 16 ++++++++++++++++ src/dxvk/dxvk_pipemanager.h | 16 +++++++++++++++- 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index bcefd0c4c..2f76185f3 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -133,6 +133,37 @@ namespace dxvk { } + DxvkGraphicsPipelineVertexInputLibrary::DxvkGraphicsPipelineVertexInputLibrary( + DxvkDevice* device, + const DxvkGraphicsPipelineVertexInputState& state, + VkPipelineCache cache) + : m_device(device) { + auto vk = m_device->vkd(); + + VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT }; + libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT; + + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; + info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + info.pVertexInputState = &state.viInfo; + info.pInputAssemblyState = &state.iaInfo; + info.basePipelineIndex = -1; + + VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), + cache, 1, &info, nullptr, &m_pipeline); + + if (vr) + throw DxvkError("Failed to create vertex input pipeline library"); + } + + + DxvkGraphicsPipelineVertexInputLibrary::~DxvkGraphicsPipelineVertexInputLibrary() { + auto vk = m_device->vkd(); + + vk->vkDestroyPipeline(vk->device(), m_pipeline, nullptr); + } + + DxvkGraphicsPipelineFragmentOutputState::DxvkGraphicsPipelineFragmentOutputState() { } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 20e63787b..e640c1be9 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -47,6 +47,35 @@ namespace dxvk { }; + /** + * \brief Vertex input pipeline library + * + * Creates a Vulkan pipeline object for a + * given vertex input state vector. + */ + class DxvkGraphicsPipelineVertexInputLibrary { + + public: + + DxvkGraphicsPipelineVertexInputLibrary( + DxvkDevice* device, + const DxvkGraphicsPipelineVertexInputState& state, + VkPipelineCache cache); + + ~DxvkGraphicsPipelineVertexInputLibrary(); + + VkPipeline getHandle() const { + return m_pipeline; + } + + private: + + DxvkDevice* m_device; + VkPipeline m_pipeline; + + }; + + /** * \brief Fragment output info for graphics pipelines * diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index da6943e18..9fca1ccb7 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -77,6 +77,22 @@ namespace dxvk { } + DxvkGraphicsPipelineVertexInputLibrary* DxvkPipelineManager::createVertexInputLibrary( + const DxvkGraphicsPipelineVertexInputState& state) { + std::lock_guard lock(m_mutex); + + auto pair = m_vertexInputLibraries.find(state); + if (pair != m_vertexInputLibraries.end()) + return &pair->second; + + auto iter = m_vertexInputLibraries.emplace( + std::piecewise_construct, + std::tuple(state), + std::tuple(m_device, state, m_cache->handle())); + return &iter.first->second; + } + + void DxvkPipelineManager::registerShader( const Rc& shader) { if (m_stateCache != nullptr) diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index be69be3aa..508e8ac72 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -65,7 +65,16 @@ namespace dxvk { */ DxvkGraphicsPipeline* createGraphicsPipeline( const DxvkGraphicsPipelineShaders& shaders); - + + /** + * \brief Retrieves a vertex input pipeline library + * + * \param [in] state Vertex input state + * \returns Pipeline library object + */ + DxvkGraphicsPipelineVertexInputLibrary* createVertexInputLibrary( + const DxvkGraphicsPipelineVertexInputState& state); + /* * \brief Registers a shader * @@ -125,6 +134,11 @@ namespace dxvk { DxvkGraphicsPipeline, DxvkHash, DxvkEq> m_graphicsPipelines; + std::unordered_map< + DxvkGraphicsPipelineVertexInputState, + DxvkGraphicsPipelineVertexInputLibrary, + DxvkHash, DxvkEq> m_vertexInputLibraries; + DxvkBindingSetLayout* createDescriptorSetLayout( const DxvkBindingSetLayoutKey& key); From 3b10efbc3034da8dbd8ef2f476093c8a6b004682 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 12:56:56 +0200 Subject: [PATCH 0138/1348] [dxvk] Implement fragment output pipeline libraries --- src/dxvk/dxvk_graphics.cpp | 60 ++++++++++++++++++++++++++++++++++- src/dxvk/dxvk_graphics.h | 31 ++++++++++++++++++ src/dxvk/dxvk_pipemanager.cpp | 16 ++++++++++ src/dxvk/dxvk_pipemanager.h | 14 ++++++++ 4 files changed, 120 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 2f76185f3..b1338970f 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -141,7 +141,7 @@ namespace dxvk { auto vk = m_device->vkd(); VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT }; - libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT; + libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT; VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; @@ -250,6 +250,21 @@ namespace dxvk { } + bool DxvkGraphicsPipelineFragmentOutputState::useDynamicBlendConstants() const { + bool result = false; + + for (uint32_t i = 0; i < MaxNumRenderTargets && !result; i++) { + result = cbAttachments[i].blendEnable + && (util::isBlendConstantBlendFactor(cbAttachments[i].srcColorBlendFactor) + || util::isBlendConstantBlendFactor(cbAttachments[i].dstColorBlendFactor) + || util::isBlendConstantBlendFactor(cbAttachments[i].srcAlphaBlendFactor) + || util::isBlendConstantBlendFactor(cbAttachments[i].dstAlphaBlendFactor)); + } + + return result; + } + + bool DxvkGraphicsPipelineFragmentOutputState::eq(const DxvkGraphicsPipelineFragmentOutputState& other) const { bool eq = rtInfo.colorAttachmentCount == other.rtInfo.colorAttachmentCount && rtInfo.depthAttachmentFormat == other.rtInfo.depthAttachmentFormat @@ -322,6 +337,49 @@ namespace dxvk { } + DxvkGraphicsPipelineFragmentOutputLibrary::DxvkGraphicsPipelineFragmentOutputLibrary( + DxvkDevice* device, + const DxvkGraphicsPipelineFragmentOutputState& state, + VkPipelineCache cache) + : m_device(device) { + auto vk = m_device->vkd(); + + VkDynamicState dynamicState = VK_DYNAMIC_STATE_BLEND_CONSTANTS; + VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + + if (state.useDynamicBlendConstants()) { + dyInfo.dynamicStateCount = 1; + dyInfo.pDynamicStates = &dynamicState; + } + + // pNext is non-const for some reason, but this is only an input + // structure, so we should be able to safely use const_cast. + VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT }; + libInfo.pNext = const_cast(&state.rtInfo); + libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT; + + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; + info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + info.pColorBlendState = &state.cbInfo; + info.pMultisampleState = &state.msInfo; + info.pDynamicState = &dyInfo; + info.basePipelineIndex = -1; + + VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), + cache, 1, &info, nullptr, &m_pipeline); + + if (vr) + throw DxvkError("Failed to create vertex input pipeline library"); + } + + + DxvkGraphicsPipelineFragmentOutputLibrary::~DxvkGraphicsPipelineFragmentOutputLibrary() { + auto vk = m_device->vkd(); + + vk->vkDestroyPipeline(vk->device(), m_pipeline, nullptr); + } + + DxvkGraphicsPipelinePreRasterizationState::DxvkGraphicsPipelinePreRasterizationState() { } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index e640c1be9..f2757f2be 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -99,12 +99,43 @@ namespace dxvk { std::array cbAttachments = { }; std::array rtColorFormats = { }; + bool useDynamicBlendConstants() const; + bool eq(const DxvkGraphicsPipelineFragmentOutputState& other) const; size_t hash() const; }; + /** + * \brief Vertex input pipeline library + * + * Creates a Vulkan pipeline object for a + * given vertex input state vector. + */ + class DxvkGraphicsPipelineFragmentOutputLibrary { + + public: + + DxvkGraphicsPipelineFragmentOutputLibrary( + DxvkDevice* device, + const DxvkGraphicsPipelineFragmentOutputState& state, + VkPipelineCache cache); + + ~DxvkGraphicsPipelineFragmentOutputLibrary(); + + VkPipeline getHandle() const { + return m_pipeline; + } + + private: + + DxvkDevice* m_device; + VkPipeline m_pipeline; + + }; + + /** * \brief Pre-rasterization info for graphics pipelines * diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 9fca1ccb7..5c58cc134 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -93,6 +93,22 @@ namespace dxvk { } + DxvkGraphicsPipelineFragmentOutputLibrary* DxvkPipelineManager::createFragmentOutputLibrary( + const DxvkGraphicsPipelineFragmentOutputState& state) { + std::lock_guard lock(m_mutex); + + auto pair = m_fragmentOutputLibraries.find(state); + if (pair != m_fragmentOutputLibraries.end()) + return &pair->second; + + auto iter = m_fragmentOutputLibraries.emplace( + std::piecewise_construct, + std::tuple(state), + std::tuple(m_device, state, m_cache->handle())); + return &iter.first->second; + } + + void DxvkPipelineManager::registerShader( const Rc& shader) { if (m_stateCache != nullptr) diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 508e8ac72..fbb764522 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -75,6 +75,15 @@ namespace dxvk { DxvkGraphicsPipelineVertexInputLibrary* createVertexInputLibrary( const DxvkGraphicsPipelineVertexInputState& state); + /** + * \brief Retrieves a fragment output pipeline library + * + * \param [in] state Fragment output state + * \returns Pipeline library object + */ + DxvkGraphicsPipelineFragmentOutputLibrary* createFragmentOutputLibrary( + const DxvkGraphicsPipelineFragmentOutputState& state); + /* * \brief Registers a shader * @@ -139,6 +148,11 @@ namespace dxvk { DxvkGraphicsPipelineVertexInputLibrary, DxvkHash, DxvkEq> m_vertexInputLibraries; + std::unordered_map< + DxvkGraphicsPipelineFragmentOutputState, + DxvkGraphicsPipelineFragmentOutputLibrary, + DxvkHash, DxvkEq> m_fragmentOutputLibraries; + DxvkBindingSetLayout* createDescriptorSetLayout( const DxvkBindingSetLayoutKey& key); From 30c25ee1f0ea19ca52c6f0e9be52dad3c03ab3f7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 13:17:10 +0200 Subject: [PATCH 0139/1348] [dxvk] Add way to create partial pipeline layouts --- src/dxvk/dxvk_pipelayout.cpp | 54 ++++++++++++++++++++++++++--------- src/dxvk/dxvk_pipelayout.h | 11 ++++++- src/dxvk/dxvk_pipemanager.cpp | 9 ++++-- src/dxvk/dxvk_shader.cpp | 2 +- 4 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index bb60cde2e..407366358 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -208,8 +208,8 @@ namespace dxvk { } - DxvkBindingLayout::DxvkBindingLayout() - : m_pushConst { 0, 0, 0 } { + DxvkBindingLayout::DxvkBindingLayout(VkShaderStageFlags stages) + : m_pushConst { 0, 0, 0 }, m_stages(stages) { } @@ -219,6 +219,21 @@ namespace dxvk { } + uint32_t DxvkBindingLayout::getSetMask() const { + uint32_t mask = 0; + + if (m_stages & (VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT)) { + mask |= (1u << DxvkDescriptorSets::FsViews) + | (1u << DxvkDescriptorSets::FsBuffers); + } + + if (m_stages & (VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT)) + mask |= (1u << DxvkDescriptorSets::VsAll); + + return mask; + } + + void DxvkBindingLayout::addBinding(const DxvkBindingInfo& binding) { uint32_t set = binding.computeSetIndex(); m_bindings[set].addBinding(binding); @@ -244,6 +259,9 @@ namespace dxvk { bool DxvkBindingLayout::eq(const DxvkBindingLayout& other) const { + if (m_stages != other.m_stages) + return false; + for (uint32_t i = 0; i < m_bindings.size(); i++) { if (!m_bindings[i].eq(other.m_bindings[i])) return false; @@ -260,6 +278,7 @@ namespace dxvk { size_t DxvkBindingLayout::hash() const { DxvkHashState hash; + hash.add(m_stages); for (uint32_t i = 0; i < m_bindings.size(); i++) hash.add(m_bindings[i].hash()); @@ -278,26 +297,30 @@ namespace dxvk { : m_device(device), m_layout(layout) { auto vk = m_device->vkd(); - std::array setLayouts; + std::array setLayouts = { }; for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { m_bindingObjects[i] = setObjects[i]; - setLayouts[i] = setObjects[i]->getSetLayout(); - uint32_t bindingCount = m_layout.getBindingCount(i); + // Sets can be null for partial layouts + if (setObjects[i]) { + setLayouts[i] = setObjects[i]->getSetLayout(); - for (uint32_t j = 0; j < bindingCount; j++) { - const DxvkBindingInfo& binding = m_layout.getBinding(i, j); + uint32_t bindingCount = m_layout.getBindingCount(i); - DxvkBindingMapping mapping; - mapping.set = i; - mapping.binding = j; + for (uint32_t j = 0; j < bindingCount; j++) { + const DxvkBindingInfo& binding = m_layout.getBinding(i, j); - m_mapping.insert({ binding.resourceBinding, mapping }); + DxvkBindingMapping mapping; + mapping.set = i; + mapping.binding = j; + + m_mapping.insert({ binding.resourceBinding, mapping }); + } + + if (bindingCount) + m_setMask |= 1u << i; } - - if (bindingCount) - m_setMask |= 1u << i; } VkPushConstantRange pushConst = m_layout.getPushConstantRange(); @@ -306,6 +329,9 @@ namespace dxvk { pipelineLayoutInfo.setLayoutCount = setLayouts.size(); pipelineLayoutInfo.pSetLayouts = setLayouts.data(); + if (m_layout.getSetMask() != (1u << DxvkDescriptorSets::SetCount) - 1) + pipelineLayoutInfo.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT; + if (pushConst.stageFlags && pushConst.size) { pipelineLayoutInfo.pushConstantRangeCount = 1; pipelineLayoutInfo.pPushConstantRanges = &pushConst; diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 46717bc9d..ae4ad78f9 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -261,7 +261,7 @@ namespace dxvk { public: - DxvkBindingLayout(); + DxvkBindingLayout(VkShaderStageFlags stages); ~DxvkBindingLayout(); /** @@ -304,6 +304,14 @@ namespace dxvk { return m_pushConst; } + /** + * \brief Queries defined descriptor set layouts + * + * Any set layout not included in this must be null. + * \returns Bit mask of defined descriptor sets + */ + uint32_t getSetMask() const; + /** * \brief Adds a binding to the layout * \param [in] binding Binding info @@ -345,6 +353,7 @@ namespace dxvk { std::array m_bindings; VkPushConstantRange m_pushConst; + VkShaderStageFlags m_stages; }; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 5c58cc134..3e4d92b82 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -52,7 +52,7 @@ namespace dxvk { if (pair != m_graphicsPipelines.end()) return &pair->second; - DxvkBindingLayout mergedLayout; + DxvkBindingLayout mergedLayout(VK_SHADER_STAGE_ALL_GRAPHICS); mergedLayout.merge(shaders.vs->getBindings()); if (shaders.tcs != nullptr) @@ -157,9 +157,12 @@ namespace dxvk { return &pair->second; std::array setLayouts = { }; + uint32_t setMask = layout.getSetMask(); - for (uint32_t i = 0; i < setLayouts.size(); i++) - setLayouts[i] = createDescriptorSetLayout(layout.getBindingList(i)); + for (uint32_t i = 0; i < setLayouts.size(); i++) { + if (setMask & (1u << i)) + setLayouts[i] = createDescriptorSetLayout(layout.getBindingList(i)); + } auto iter = m_pipelineLayouts.emplace( std::piecewise_construct, diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index f8c5fdce9..a3ed01d73 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -63,7 +63,7 @@ namespace dxvk { DxvkShader::DxvkShader( const DxvkShaderCreateInfo& info, SpirvCodeBuffer&& spirv) - : m_info(info), m_code(spirv) { + : m_info(info), m_code(spirv), m_bindings(info.stage) { m_info.uniformData = nullptr; m_info.bindings = nullptr; From dbcd0333d9a6c2f4a2a8b6eb7118d814a5d73c38 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 16:37:12 +0200 Subject: [PATCH 0140/1348] [dxvk] Implement shader-based pipeline libraries --- src/dxvk/dxvk_shader.cpp | 266 ++++++++++++++++++++++++++++++++++++++- src/dxvk/dxvk_shader.h | 93 ++++++++++++++ 2 files changed, 353 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index a3ed01d73..6fa9338ff 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -1,3 +1,4 @@ +#include "dxvk_device.h" #include "dxvk_shader.h" #include @@ -159,10 +160,9 @@ namespace dxvk { } - DxvkShaderModule DxvkShader::createShaderModule( - const Rc& vkd, + SpirvCodeBuffer DxvkShader::getCode( const DxvkBindingLayoutObjects* layout, - const DxvkShaderModuleCreateInfo& info) { + const DxvkShaderModuleCreateInfo& state) const { SpirvCodeBuffer spirvCode = m_code.decompress(); uint32_t* code = spirvCode.data(); @@ -180,14 +180,22 @@ namespace dxvk { // For dual-source blending we need to re-map // location 1, index 0 to location 0, index 1 - if (info.fsDualSrcBlend && m_o1IdxOffset && m_o1LocOffset) + if (state.fsDualSrcBlend && m_o1IdxOffset && m_o1LocOffset) std::swap(code[m_o1IdxOffset], code[m_o1LocOffset]); // Replace undefined input variables with zero - for (uint32_t u : bit::BitMask(info.undefinedInputs)) + for (uint32_t u : bit::BitMask(state.undefinedInputs)) eliminateInput(spirvCode, u); - return DxvkShaderModule(vkd, this, spirvCode); + return spirvCode; + } + + + DxvkShaderModule DxvkShader::createShaderModule( + const Rc& vkd, + const DxvkBindingLayoutObjects* layout, + const DxvkShaderModuleCreateInfo& info) { + return DxvkShaderModule(vkd, this, getCode(layout, info)); } @@ -402,4 +410,250 @@ namespace dxvk { } } + + DxvkShaderPipelineLibrary::DxvkShaderPipelineLibrary( + const DxvkDevice* device, + const DxvkShader* shader, + const DxvkBindingLayoutObjects* layout) + : m_device(device), m_shader(shader), m_layout(layout) { + + } + + + DxvkShaderPipelineLibrary::~DxvkShaderPipelineLibrary() { + auto vk = m_device->vkd(); + + vk->vkDestroyPipeline(vk->device(), m_pipeline, nullptr); + vk->vkDestroyPipeline(vk->device(), m_pipelineNoDepthClip, nullptr); + } + + + VkPipeline DxvkShaderPipelineLibrary::getPipelineHandle( + VkPipelineCache cache, + const DxvkShaderPipelineLibraryCompileArgs& args) { + std::lock_guard lock(m_mutex); + + VkPipeline& pipeline = (m_shader->info().stage == VK_SHADER_STAGE_VERTEX_BIT && !args.depthClipEnable) + ? m_pipelineNoDepthClip + : m_pipeline; + + if (pipeline) + return pipeline; + + switch (m_shader->info().stage) { + case VK_SHADER_STAGE_VERTEX_BIT: + pipeline = compileVertexShaderPipeline(cache, args); + break; + + case VK_SHADER_STAGE_FRAGMENT_BIT: + pipeline = compileFragmentShaderPipeline(cache); + break; + + case VK_SHADER_STAGE_COMPUTE_BIT: + pipeline = compileComputeShaderPipeline(cache); + break; + + default: + // Should be unreachable + pipeline = VK_NULL_HANDLE; + } + + return pipeline; + } + + + void DxvkShaderPipelineLibrary::compilePipeline(VkPipelineCache cache) { + // Just compile the pipeline with default args. Implicitly skips + // this step if another thread has compiled the pipeline in the + // meantime, in order to avoid duplicate work. + getPipelineHandle(cache, DxvkShaderPipelineLibraryCompileArgs()); + } + + + VkPipeline DxvkShaderPipelineLibrary::compileVertexShaderPipeline( + VkPipelineCache cache, + const DxvkShaderPipelineLibraryCompileArgs& args) { + auto vk = m_device->vkd(); + + // Set up shader stage. Do not create a shader module. + SpirvCodeBuffer spirv = m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()); + + VkShaderModuleCreateInfo codeInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; + codeInfo.codeSize = spirv.size(); + codeInfo.pCode = spirv.data(); + + VkPipelineShaderStageCreateInfo stageInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, &codeInfo }; + stageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; + stageInfo.pName = "main"; + + // Set up dynamic state. We do not know any pipeline state + // at this time, so make as much state dynamic as we can. + std::array dynamicStates = {{ + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT, + VK_DYNAMIC_STATE_DEPTH_BIAS, + VK_DYNAMIC_STATE_CULL_MODE_EXT, + VK_DYNAMIC_STATE_FRONT_FACE_EXT, + }}; + + VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + dyInfo.dynamicStateCount = dynamicStates.size(); + dyInfo.pDynamicStates = dynamicStates.data(); + + // All viewport state is dynamic, so we do not need to initialize this. + VkPipelineViewportStateCreateInfo vpInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; + + // Set up rasterizer state. Depth bias, cull mode and front face are all + // dynamic, but we do not have dynamic state for depth bias enablement + // with the original version of VK_EXT_extended_dynamic_state, so always + // enable that. Do not support any polygon modes other than FILL. + VkPipelineRasterizationDepthClipStateCreateInfoEXT rsDepthClipInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT }; + + VkPipelineRasterizationStateCreateInfo rsInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; + rsInfo.depthClampEnable = VK_TRUE; + rsInfo.rasterizerDiscardEnable = VK_FALSE; + rsInfo.polygonMode = VK_POLYGON_MODE_FILL; + rsInfo.depthBiasEnable = VK_TRUE; + rsInfo.lineWidth = 1.0f; + + if (m_device->features().extDepthClipEnable.depthClipEnable) { + rsDepthClipInfo.pNext = std::exchange(rsInfo.pNext, &rsDepthClipInfo); + rsDepthClipInfo.depthClipEnable = args.depthClipEnable; + } else { + rsInfo.depthClampEnable = !args.depthClipEnable; + } + + // Only the view mask is used as input, and since we do not use MultiView, it is always 0 + VkPipelineRenderingCreateInfo rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + + VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT, &rtInfo }; + libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT; + + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; + info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + info.stageCount = 1; + info.pStages = &stageInfo; + info.pViewportState = &vpInfo; + info.pRasterizationState = &rsInfo; + info.pDynamicState = &dyInfo; + info.layout = m_layout->getPipelineLayout(); + info.basePipelineIndex = -1; + + VkPipeline pipeline = VK_NULL_HANDLE; + + if (vk->vkCreateGraphicsPipelines(vk->device(), cache, 1, &info, nullptr, &pipeline)) + throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); + + return pipeline; + } + + + VkPipeline DxvkShaderPipelineLibrary::compileFragmentShaderPipeline(VkPipelineCache cache) { + auto vk = m_device->vkd(); + + // Set up shader stage. Do not create a shader module. + SpirvCodeBuffer spirv = m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()); + + VkShaderModuleCreateInfo codeInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; + codeInfo.codeSize = spirv.size(); + codeInfo.pCode = spirv.data(); + + VkPipelineShaderStageCreateInfo stageInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, &codeInfo }; + stageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + stageInfo.pName = "main"; + + // Set up dynamic state. We do not know any pipeline state + // at this time, so make as much state dynamic as we can. + uint32_t dynamicStateCount = 0; + std::array dynamicStates; + + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_OP_EXT; + + if (m_device->features().core.features.depthBounds) { + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS; + } + + VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + dyInfo.dynamicStateCount = dynamicStateCount; + dyInfo.pDynamicStates = dynamicStates.data(); + + // Set up multisample state. If sample shading is enabled, assume that + // we only have one sample enabled, with a non-zero sample mask and no + // alpha-to-coverage. + uint32_t msSampleMask = 0x1; + + VkPipelineMultisampleStateCreateInfo msInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; + msInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + msInfo.pSampleMask = &msSampleMask; + msInfo.sampleShadingEnable = VK_TRUE; + msInfo.minSampleShading = 1.0f; + + // All depth-stencil state is dynamic, so no need to initialize this. + // Depth bounds testing is disabled on devices which don't support it. + VkPipelineDepthStencilStateCreateInfo dsInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; + + // Only the view mask is used as input, and since we do not use MultiView, it is always 0 + VkPipelineRenderingCreateInfo rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + + VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT, &rtInfo }; + libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT; + + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; + info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + info.stageCount = 1; + info.pStages = &stageInfo; + info.pDepthStencilState = &dsInfo; + info.pDynamicState = &dyInfo; + info.layout = m_layout->getPipelineLayout(); + info.basePipelineIndex = -1; + + if (m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading)) + info.pMultisampleState = &msInfo; + + VkPipeline pipeline = VK_NULL_HANDLE; + + if (vk->vkCreateGraphicsPipelines(vk->device(), cache, 1, &info, nullptr, &pipeline)) + throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); + + return pipeline; + } + + + VkPipeline DxvkShaderPipelineLibrary::compileComputeShaderPipeline(VkPipelineCache cache) { + auto vk = m_device->vkd(); + + // Set up shader stage. Do not create a shader module since we only + // ever call this if graphics pipeline libraries are supported. + SpirvCodeBuffer spirv = m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()); + + VkShaderModuleCreateInfo codeInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; + codeInfo.codeSize = spirv.size(); + codeInfo.pCode = spirv.data(); + + VkPipelineShaderStageCreateInfo stageInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, &codeInfo }; + stageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; + stageInfo.pName = "main"; + + // Compile the compute pipeline as normal + VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; + info.stage = stageInfo; + info.layout = m_layout->getPipelineLayout(); + info.basePipelineIndex = -1; + + VkPipeline pipeline = VK_NULL_HANDLE; + + if (vk->vkCreateComputePipelines(vk->device(), cache, 1, &info, nullptr, &pipeline)) + throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); + + return pipeline; + } + } \ No newline at end of file diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index ba798aea5..40e2023bd 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -120,6 +120,19 @@ namespace dxvk { const DxvkBindingLayout& getBindings() const { return m_bindings; } + + /** + * \brief Patches code using given info + * + * Rewrites binding IDs and potentially fixes up other + * parts of the code depending on pipeline state. + * \param [in] layout Biding layout + * \param [in] state Pipeline state info + * \returns Uncompressed SPIR-V code buffer + */ + SpirvCodeBuffer getCode( + const DxvkBindingLayoutObjects* layout, + const DxvkShaderModuleCreateInfo& state) const; /** * \brief Creates a shader module @@ -273,5 +286,85 @@ namespace dxvk { VkPipelineShaderStageCreateInfo m_stage; }; + + + /** + * \brief Shader pipeline library compile args + */ + struct DxvkShaderPipelineLibraryCompileArgs { + VkBool32 depthClipEnable = VK_TRUE; + + bool operator == (const DxvkShaderPipelineLibraryCompileArgs& other) const { + return depthClipEnable == other.depthClipEnable; + } + + bool operator != (const DxvkShaderPipelineLibraryCompileArgs& other) const { + return !this->operator == (other); + } + }; + + + /** + * \brief Shader pipeline library + * + * Stores a pipeline object for either a complete compute + * pipeline, a pre-rasterization pipeline library consisting + * of a single vertex shader, or a fragment shader pipeline + * library. All state unknown at shader compile time will + * be made dynamic. + */ + class DxvkShaderPipelineLibrary { + + public: + + DxvkShaderPipelineLibrary( + const DxvkDevice* device, + const DxvkShader* shader, + const DxvkBindingLayoutObjects* layout); + + ~DxvkShaderPipelineLibrary(); + + /** + * \brief Queries pipeline handle for the given set of arguments + * + * Either returns an already compiled pipeline library object, or + * performs the compilation step if that has not happened yet. + * \param [in] cache Pipeline cache handle + * \param [in] args Compile arguments + * \returns Vulkan pipeline handle + */ + VkPipeline getPipelineHandle( + VkPipelineCache cache, + const DxvkShaderPipelineLibraryCompileArgs& args); + + /** + * \brief Compiles the pipeline with default arguments + * + * This is meant to be called from a worker thread in + * order to reduce the amount of work done on the app's + * main thread. + * \param [in] cache Pipeline cache handle + */ + void compilePipeline(VkPipelineCache cache); + + private: + + const DxvkDevice* m_device; + const DxvkShader* m_shader; + const DxvkBindingLayoutObjects* m_layout; + + dxvk::mutex m_mutex; + VkPipeline m_pipeline = VK_NULL_HANDLE; + VkPipeline m_pipelineNoDepthClip = VK_NULL_HANDLE; + + VkPipeline compileVertexShaderPipeline( + VkPipelineCache cache, + const DxvkShaderPipelineLibraryCompileArgs& args); + + VkPipeline compileFragmentShaderPipeline(VkPipelineCache cache); + + VkPipeline compileComputeShaderPipeline(VkPipelineCache cache); + + }; } \ No newline at end of file From 8b645f8563c132f673e05df6e3e93ba91a1be119 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 17:44:02 +0200 Subject: [PATCH 0141/1348] [dxvk] Rework DxvkPipelineCache --- src/dxvk/dxvk_compute.cpp | 2 +- src/dxvk/dxvk_graphics.cpp | 3 +-- src/dxvk/dxvk_pipecache.cpp | 26 ++++++++++++-------------- src/dxvk/dxvk_pipecache.h | 18 ++++++------------ src/dxvk/dxvk_pipemanager.cpp | 6 +++--- src/dxvk/dxvk_pipemanager.h | 10 +++++----- 6 files changed, 28 insertions(+), 37 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 64d7ace74..9b4411378 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -111,7 +111,7 @@ namespace dxvk { VkPipeline pipeline = VK_NULL_HANDLE; if (m_vkd->vkCreateComputePipelines(m_vkd->device(), - m_pipeMgr->m_cache->handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { + m_pipeMgr->m_cache.handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { Logger::err("DxvkComputePipeline: Failed to compile pipeline"); Logger::err(str::format(" cs : ", m_shaders.cs->debugName())); return VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index b1338970f..18a538af6 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -664,8 +664,7 @@ namespace dxvk { t0 = dxvk::high_resolution_clock::now(); VkPipeline pipeline = VK_NULL_HANDLE; - if (m_vkd->vkCreateGraphicsPipelines(m_vkd->device(), - m_pipeMgr->m_cache->handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { + if (m_vkd->vkCreateGraphicsPipelines(m_vkd->device(), m_pipeMgr->m_cache.handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { Logger::err("DxvkGraphicsPipeline: Failed to compile pipeline"); this->logPipelineState(LogLevel::Error, state); return VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_pipecache.cpp b/src/dxvk/dxvk_pipecache.cpp index 0ea775bce..8029e225a 100644 --- a/src/dxvk/dxvk_pipecache.cpp +++ b/src/dxvk/dxvk_pipecache.cpp @@ -1,26 +1,24 @@ #include "dxvk_pipecache.h" +#include "dxvk_device.h" namespace dxvk { - DxvkPipelineCache::DxvkPipelineCache( - const Rc& vkd) - : m_vkd(vkd) { - VkPipelineCacheCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.initialDataSize = 0; - info.pInitialData = nullptr; + DxvkPipelineCache::DxvkPipelineCache(DxvkDevice* device) + : m_device(device) { + auto vk = m_device->vkd(); + + // It's not critical if this fails since this is only an in-memory cache + VkPipelineCacheCreateInfo info = { VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; - if (m_vkd->vkCreatePipelineCache(m_vkd->device(), - &info, nullptr, &m_handle) != VK_SUCCESS) - throw DxvkError("DxvkPipelineCache: Failed to create cache"); + if (vk->vkCreatePipelineCache(vk->device(), &info, nullptr, &m_handle)) + Logger::err("DxvkPipelineCache: Failed to create cache"); } DxvkPipelineCache::~DxvkPipelineCache() { - m_vkd->vkDestroyPipelineCache( - m_vkd->device(), m_handle, nullptr); + auto vk = m_device->vkd(); + + vk->vkDestroyPipelineCache(vk->device(), m_handle, nullptr); } } diff --git a/src/dxvk/dxvk_pipecache.h b/src/dxvk/dxvk_pipecache.h index b39bf47c0..78e9a7981 100644 --- a/src/dxvk/dxvk_pipecache.h +++ b/src/dxvk/dxvk_pipecache.h @@ -1,28 +1,22 @@ #pragma once -#include -#include -#include - #include "dxvk_include.h" -#include "../util/sha1/sha1_util.h" -#include "../util/util_env.h" -#include "../util/util_time.h" - namespace dxvk { + class DxvkDevice; + /** * \brief Pipeline cache * * Allows the Vulkan implementation to * re-use previously compiled pipelines. */ - class DxvkPipelineCache : public RcObject { + class DxvkPipelineCache { public: - DxvkPipelineCache(const Rc& vkd); + DxvkPipelineCache(DxvkDevice* device); ~DxvkPipelineCache(); /** @@ -35,8 +29,8 @@ namespace dxvk { private: - Rc m_vkd; - VkPipelineCache m_handle; + DxvkDevice* m_device; + VkPipelineCache m_handle = VK_NULL_HANDLE; }; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 3e4d92b82..dc23bbf88 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -7,7 +7,7 @@ namespace dxvk { DxvkPipelineManager::DxvkPipelineManager( DxvkDevice* device) : m_device (device), - m_cache (new DxvkPipelineCache(device->vkd())) { + m_cache (device) { std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE"); if (useStateCache != "0" && device->config().enableStateCache) @@ -88,7 +88,7 @@ namespace dxvk { auto iter = m_vertexInputLibraries.emplace( std::piecewise_construct, std::tuple(state), - std::tuple(m_device, state, m_cache->handle())); + std::tuple(m_device, state, m_cache.handle())); return &iter.first->second; } @@ -104,7 +104,7 @@ namespace dxvk { auto iter = m_fragmentOutputLibraries.emplace( std::piecewise_construct, std::tuple(state), - std::tuple(m_device, state, m_cache->handle())); + std::tuple(m_device, state, m_cache.handle())); return &iter.first->second; } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index fbb764522..709c1227a 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -114,12 +114,12 @@ namespace dxvk { private: - DxvkDevice* m_device; - Rc m_cache; - Rc m_stateCache; + DxvkDevice* m_device; + DxvkPipelineCache m_cache; + Rc m_stateCache; - std::atomic m_numComputePipelines = { 0 }; - std::atomic m_numGraphicsPipelines = { 0 }; + std::atomic m_numComputePipelines = { 0 }; + std::atomic m_numGraphicsPipelines = { 0 }; dxvk::mutex m_mutex; From 1c573a7fd5afdf110b8ed9e542d6abb1c98d5d21 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 17:53:31 +0200 Subject: [PATCH 0142/1348] [dxvk] Rework state cache object creation --- src/dxvk/dxvk_compute.cpp | 5 +---- src/dxvk/dxvk_graphics.cpp | 5 +---- src/dxvk/dxvk_pipemanager.cpp | 18 ++++++------------ src/dxvk/dxvk_pipemanager.h | 9 +++++---- src/dxvk/dxvk_state_cache.cpp | 10 ++++++++-- src/dxvk/dxvk_state_cache.h | 5 +++-- src/dxvk/dxvk_state_cache_types.h | 3 ++- 7 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 9b4411378..52849d8d0 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -134,15 +134,12 @@ namespace dxvk { void DxvkComputePipeline::writePipelineStateToCache( const DxvkComputePipelineStateInfo& state) const { - if (m_pipeMgr->m_stateCache == nullptr) - return; - DxvkStateCacheKey key; if (m_shaders.cs != nullptr) key.cs = m_shaders.cs->getShaderKey(); - m_pipeMgr->m_stateCache->addComputePipeline(key, state); + m_pipeMgr->m_stateCache.addComputePipeline(key, state); } } diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 18a538af6..614f8a3ee 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -838,9 +838,6 @@ namespace dxvk { void DxvkGraphicsPipeline::writePipelineStateToCache( const DxvkGraphicsPipelineStateInfo& state) const { - if (m_pipeMgr->m_stateCache == nullptr) - return; - DxvkStateCacheKey key; if (m_shaders.vs != nullptr) key.vs = m_shaders.vs->getShaderKey(); if (m_shaders.tcs != nullptr) key.tcs = m_shaders.tcs->getShaderKey(); @@ -848,7 +845,7 @@ namespace dxvk { if (m_shaders.gs != nullptr) key.gs = m_shaders.gs->getShaderKey(); if (m_shaders.fs != nullptr) key.fs = m_shaders.fs->getShaderKey(); - m_pipeMgr->m_stateCache->addGraphicsPipeline(key, state); + m_pipeMgr->m_stateCache.addGraphicsPipeline(key, state); } diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index dc23bbf88..680c45728 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -7,11 +7,8 @@ namespace dxvk { DxvkPipelineManager::DxvkPipelineManager( DxvkDevice* device) : m_device (device), - m_cache (device) { - std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE"); - - if (useStateCache != "0" && device->config().enableStateCache) - m_stateCache = new DxvkStateCache(device, this); + m_cache (device), + m_stateCache(device, this) { } @@ -111,8 +108,7 @@ namespace dxvk { void DxvkPipelineManager::registerShader( const Rc& shader) { - if (m_stateCache != nullptr) - m_stateCache->registerShader(shader); + m_stateCache.registerShader(shader); } @@ -125,14 +121,12 @@ namespace dxvk { bool DxvkPipelineManager::isCompilingShaders() const { - return m_stateCache != nullptr - && m_stateCache->isCompilingShaders(); + return m_stateCache.isCompilingShaders(); } - void DxvkPipelineManager::stopWorkerThreads() const { - if (m_stateCache != nullptr) - m_stateCache->stopWorkerThreads(); + void DxvkPipelineManager::stopWorkerThreads() { + m_stateCache.stopWorkerThreads(); } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 709c1227a..ba18f50ed 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -6,6 +6,7 @@ #include "dxvk_compute.h" #include "dxvk_graphics.h" +#include "dxvk_state_cache.h" namespace dxvk { @@ -110,13 +111,13 @@ namespace dxvk { /** * \brief Stops async compiler threads */ - void stopWorkerThreads() const; + void stopWorkerThreads(); private: - DxvkDevice* m_device; - DxvkPipelineCache m_cache; - Rc m_stateCache; + DxvkDevice* m_device; + DxvkPipelineCache m_cache; + DxvkStateCache m_stateCache; std::atomic m_numComputePipelines = { 0 }; std::atomic m_numGraphicsPipelines = { 0 }; diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 4ffa58b91..e3a6466f2 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -217,6 +217,9 @@ namespace dxvk { DxvkPipelineManager* pipeManager) : m_device (device), m_pipeManager (pipeManager) { + std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE"); + m_enable = useStateCache != "0" && device->config().enableStateCache; + bool newFile = !readCacheFile(); if (newFile) { @@ -257,7 +260,7 @@ namespace dxvk { void DxvkStateCache::addGraphicsPipeline( const DxvkStateCacheKey& shaders, const DxvkGraphicsPipelineStateInfo& state) { - if (shaders.vs.eq(g_nullShaderKey)) + if (!m_enable || shaders.vs.eq(g_nullShaderKey)) return; // Do not add an entry that is already in the cache @@ -284,7 +287,7 @@ namespace dxvk { void DxvkStateCache::addComputePipeline( const DxvkStateCacheKey& shaders, const DxvkComputePipelineStateInfo& state) { - if (shaders.cs.eq(g_nullShaderKey)) + if (!m_enable || shaders.cs.eq(g_nullShaderKey)) return; // Do not add an entry that is already in the cache @@ -307,6 +310,9 @@ namespace dxvk { void DxvkStateCache::registerShader(const Rc& shader) { + if (!m_enable) + return; + DxvkShaderKey key = shader->getShaderKey(); if (key.eq(g_nullShaderKey)) diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index a3033037d..9fb6b52a9 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -23,7 +23,7 @@ namespace dxvk { * of time instead of compiling them on the first * draw. */ - class DxvkStateCache : public RcObject { + class DxvkStateCache { public: @@ -78,7 +78,7 @@ namespace dxvk { * \brief Checks whether compiler threads are busy * \returns \c true if we're compiling shaders */ - bool isCompilingShaders() { + bool isCompilingShaders() const { return m_workerBusy.load() > 0; } @@ -93,6 +93,7 @@ namespace dxvk { DxvkDevice* m_device; DxvkPipelineManager* m_pipeManager; + bool m_enable = false; std::vector m_entries; std::atomic m_stopThreads = { false }; diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index e0098905f..1e65b4260 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -1,6 +1,7 @@ #pragma once -#include "dxvk_pipemanager.h" +#include "dxvk_compute.h" +#include "dxvk_graphics.h" #include "dxvk_renderpass.h" namespace dxvk { From 02e6a212bbb85825afe1ce9c2c3e9c5a4554954b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 18:01:50 +0200 Subject: [PATCH 0143/1348] [dxvk] Introduce new pipeline manager worker thread system --- src/dxvk/dxvk_pipemanager.cpp | 157 ++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_pipemanager.h | 99 ++++++++++++++++++++- 2 files changed, 254 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 680c45728..9c2d96ba2 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -1,9 +1,166 @@ +#include + #include "dxvk_device.h" #include "dxvk_pipemanager.h" #include "dxvk_state_cache.h" namespace dxvk { + DxvkPipelineWorkers::DxvkPipelineWorkers( + DxvkDevice* device, + DxvkPipelineCache* cache) + : m_cache(cache) { + // Use a reasonably large number of threads for compiling, but + // leave some cores to the application to avoid excessive stutter + uint32_t numCpuCores = dxvk::thread::hardware_concurrency(); + m_workerCount = ((std::max(1u, numCpuCores) - 1) * 5) / 7; + + if (m_workerCount < 1) m_workerCount = 1; + if (m_workerCount > 32) m_workerCount = 32; + + if (device->config().numCompilerThreads > 0) + m_workerCount = device->config().numCompilerThreads; + } + + + DxvkPipelineWorkers::~DxvkPipelineWorkers() { + this->stopWorkers(); + } + + + void DxvkPipelineWorkers::compilePipelineLibrary( + DxvkShaderPipelineLibrary* library) { + std::unique_lock lock(m_queueLock); + this->startWorkers(); + + m_pendingTasks += 1; + + PipelineLibraryEntry e = { }; + e.pipelineLibrary = library; + + m_queuedLibraries.push(e); + m_queueCond.notify_one(); + } + + + void DxvkPipelineWorkers::compileComputePipeline( + DxvkComputePipeline* pipeline, + const DxvkComputePipelineStateInfo& state) { + std::unique_lock lock(m_queueLock); + this->startWorkers(); + + m_pendingTasks += 1; + + PipelineEntry e = { }; + e.computePipeline = pipeline; + e.computeState = state; + + m_queuedPipelines.push(e); + m_queueCond.notify_one(); + } + + + void DxvkPipelineWorkers::compileGraphicsPipeline( + DxvkGraphicsPipeline* pipeline, + const DxvkGraphicsPipelineStateInfo& state) { + std::unique_lock lock(m_queueLock); + this->startWorkers(); + + m_pendingTasks += 1; + + PipelineEntry e = { }; + e.graphicsPipeline = pipeline; + e.graphicsState = state; + + m_queuedPipelines.push(e); + m_queueCond.notify_one(); + } + + + bool DxvkPipelineWorkers::isBusy() const { + return m_pendingTasks.load() != 0ull; + } + + + void DxvkPipelineWorkers::stopWorkers() { + { std::unique_lock lock(m_queueLock); + + if (!m_workersRunning) + return; + + m_workersRunning = false; + m_queueCond.notify_all(); + } + + for (auto& worker : m_workers) + worker.join(); + + m_workers.clear(); + } + + + void DxvkPipelineWorkers::startWorkers() { + if (!m_workersRunning) { + m_workersRunning = true; + + Logger::info(str::format("DXVK: Using ", m_workerCount, " compiler threads")); + m_workers.resize(m_workerCount); + + for (auto& worker : m_workers) { + worker = dxvk::thread([this] { runWorker(); }); + worker.set_priority(ThreadPriority::Lowest); + } + } + } + + + void DxvkPipelineWorkers::runWorker() { + env::setThreadName("dxvk-shader"); + + while (true) { + std::optional p; + std::optional l; + + { std::unique_lock lock(m_queueLock); + + m_queueCond.wait(lock, [this] { + return !m_workersRunning + || !m_queuedLibraries.empty() + || !m_queuedPipelines.empty(); + }); + + if (!m_workersRunning) { + // Skip pending work, exiting early is + // more important in this case. + break; + } else if (!m_queuedLibraries.empty()) { + l = m_queuedLibraries.front(); + m_queuedLibraries.pop(); + } else if (!m_queuedPipelines.empty()) { + p = m_queuedPipelines.front(); + m_queuedPipelines.pop(); + } + } + + if (l) { + if (l->pipelineLibrary) + l->pipelineLibrary->compilePipeline(m_cache->handle()); + + m_pendingTasks -= 1; + } + + if (p) { + if (p->computePipeline) + p->computePipeline->compilePipeline(p->computeState); + else if (p->graphicsPipeline) + p->graphicsPipeline->compilePipeline(p->graphicsState); + + m_pendingTasks -= 1; + } + } + } + + DxvkPipelineManager::DxvkPipelineManager( DxvkDevice* device) : m_device (device), diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index ba18f50ed..959259765 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -2,6 +2,7 @@ #pragma once #include +#include #include #include "dxvk_compute.h" @@ -10,7 +11,7 @@ namespace dxvk { - class DxvkStateCache; + class DxvkDevice; /** * \brief Pipeline count @@ -22,7 +23,101 @@ namespace dxvk { uint32_t numGraphicsPipelines; uint32_t numComputePipelines; }; - + + + /** + * \brief Pipeline manager worker threads + * + * Spawns worker threads to compile shader pipeline + * libraries and optimized pipelines asynchronously. + */ + class DxvkPipelineWorkers { + + public: + + DxvkPipelineWorkers( + DxvkDevice* device, + DxvkPipelineCache* cache); + + ~DxvkPipelineWorkers(); + + /** + * \brief Compiles a pipeline library + * + * Asynchronously compiles a basic variant of + * the pipeline with default compile arguments. + * Note that pipeline libraries are high priority. + * \param [in] library The pipeline library + */ + void compilePipelineLibrary( + DxvkShaderPipelineLibrary* library); + + /** + * \brief Compiles an optimized compute pipeline + * + * \param [in] pipeline Compute pipeline + * \param [in] state Pipeline state + */ + void compileComputePipeline( + DxvkComputePipeline* pipeline, + const DxvkComputePipelineStateInfo& state); + + /** + * \brief Compiles an optimized graphics pipeline + * + * \param [in] pipeline Compute pipeline + * \param [in] state Pipeline state + */ + void compileGraphicsPipeline( + DxvkGraphicsPipeline* pipeline, + const DxvkGraphicsPipelineStateInfo& state); + + /** + * \brief Checks whether workers are busy + * \returns \c true if there is unfinished work + */ + bool isBusy() const; + + /** + * \brief Stops all worker threads + * + * Stops threads and waits for their current work + * to complete. Queued work will be discarded. + */ + void stopWorkers(); + + private: + + struct PipelineEntry { + DxvkComputePipeline* computePipeline; + DxvkGraphicsPipeline* graphicsPipeline; + DxvkComputePipelineStateInfo computeState; + DxvkGraphicsPipelineStateInfo graphicsState; + }; + + struct PipelineLibraryEntry { + DxvkShaderPipelineLibrary* pipelineLibrary; + }; + + DxvkPipelineCache* m_cache; + std::atomic m_pendingTasks = { 0ull }; + + dxvk::mutex m_queueLock; + dxvk::condition_variable m_queueCond; + + std::queue m_queuedLibraries; + std::queue m_queuedPipelines; + + uint32_t m_workerCount = 0; + bool m_workersRunning = false; + std::vector m_workers; + + void startWorkers(); + + void runWorker(); + + }; + /** * \brief Pipeline manager From f2f1f86500b1dd85ec8ef46806f8bfea1d845be9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 18:11:42 +0200 Subject: [PATCH 0144/1348] [dxvk] Use new worker thread system in state cache --- src/dxvk/dxvk_pipemanager.cpp | 12 ++++----- src/dxvk/dxvk_pipemanager.h | 5 +++- src/dxvk/dxvk_state_cache.cpp | 51 +++++++++++------------------------ src/dxvk/dxvk_state_cache.h | 23 +++++++--------- 4 files changed, 33 insertions(+), 58 deletions(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 9c2d96ba2..195528bdc 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -165,7 +165,9 @@ namespace dxvk { DxvkDevice* device) : m_device (device), m_cache (device), - m_stateCache(device, this) { + m_workers (device, &m_cache), + m_stateCache(device, this, &m_workers) { + } @@ -277,13 +279,9 @@ namespace dxvk { } - bool DxvkPipelineManager::isCompilingShaders() const { - return m_stateCache.isCompilingShaders(); - } - - void DxvkPipelineManager::stopWorkerThreads() { - m_stateCache.stopWorkerThreads(); + m_workers.stopWorkers(); + m_stateCache.stopWorkers(); } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 959259765..c0cc476eb 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -201,7 +201,9 @@ namespace dxvk { * \brief Checks whether async compiler is busy * \returns \c true if shaders are being compiled */ - bool isCompilingShaders() const; + bool isCompilingShaders() const { + return m_workers.isBusy(); + } /** * \brief Stops async compiler threads @@ -212,6 +214,7 @@ namespace dxvk { DxvkDevice* m_device; DxvkPipelineCache m_cache; + DxvkPipelineWorkers m_workers; DxvkStateCache m_stateCache; std::atomic m_numComputePipelines = { 0 }; diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index e3a6466f2..8c0412b84 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -214,9 +214,11 @@ namespace dxvk { DxvkStateCache::DxvkStateCache( DxvkDevice* device, - DxvkPipelineManager* pipeManager) + DxvkPipelineManager* pipeManager, + DxvkPipelineWorkers* pipeWorkers) : m_device (device), - m_pipeManager (pipeManager) { + m_pipeManager (pipeManager), + m_pipeWorkers (pipeWorkers) { std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE"); m_enable = useStateCache != "0" && device->config().enableStateCache; @@ -253,7 +255,7 @@ namespace dxvk { DxvkStateCache::~DxvkStateCache() { - this->stopWorkerThreads(); + this->stopWorkers(); } @@ -346,12 +348,12 @@ namespace dxvk { if (workerLock) { m_workerCond.notify_all(); - createWorkers(); + createWorker(); } } - void DxvkStateCache::stopWorkerThreads() { + void DxvkStateCache::stopWorkers() { { std::lock_guard workerLock(m_workerLock); std::lock_guard writerLock(m_writerLock); @@ -362,8 +364,8 @@ namespace dxvk { m_writerCond.notify_all(); } - for (auto& worker : m_workerThreads) - worker.join(); + if (m_workerThread.joinable()) + m_workerThread.join(); if (m_writerThread.joinable()) m_writerThread.join(); @@ -420,7 +422,7 @@ namespace dxvk { for (auto e = entries.first; e != entries.second; e++) { const auto& entry = m_entries[e->second]; - pipeline->compilePipeline(entry.gpState); + m_pipeWorkers->compileGraphicsPipeline(pipeline, entry.gpState); } } else { auto pipeline = m_pipeManager->createComputePipeline(item.cp); @@ -428,7 +430,7 @@ namespace dxvk { for (auto e = entries.first; e != entries.second; e++) { const auto& entry = m_entries[e->second]; - pipeline->compilePipeline(entry.cpState); + m_pipeWorkers->compileComputePipeline(pipeline, entry.cpState); } } } @@ -704,7 +706,7 @@ namespace dxvk { void DxvkStateCache::workerFunc() { - env::setThreadName("dxvk-shader"); + env::setThreadName("dxvk-worker"); while (!m_stopThreads.load()) { WorkerItem item; @@ -712,14 +714,10 @@ namespace dxvk { { std::unique_lock lock(m_workerLock); if (m_workerQueue.empty()) { - m_workerBusy -= 1; m_workerCond.wait(lock, [this] () { return m_workerQueue.size() || m_stopThreads.load(); }); - - if (!m_workerQueue.empty()) - m_workerBusy += 1; } if (m_workerQueue.empty()) @@ -767,28 +765,9 @@ namespace dxvk { } - void DxvkStateCache::createWorkers() { - if (m_workerThreads.empty()) { - // Use half the available CPU cores for pipeline compilation - uint32_t numCpuCores = dxvk::thread::hardware_concurrency(); - uint32_t numWorkers = ((std::max(1u, numCpuCores) - 1) * 5) / 7; - - if (numWorkers < 1) numWorkers = 1; - if (numWorkers > 32) numWorkers = 32; - - if (m_device->config().numCompilerThreads > 0) - numWorkers = m_device->config().numCompilerThreads; - - Logger::info(str::format("DXVK: Using ", numWorkers, " compiler threads")); - - // Start the worker threads and the file writer - m_workerBusy.store(numWorkers); - - for (uint32_t i = 0; i < numWorkers; i++) { - m_workerThreads.emplace_back([this] () { workerFunc(); }); - m_workerThreads[i].set_priority(ThreadPriority::Lowest); - } - } + void DxvkStateCache::createWorker() { + if (!m_workerThread.joinable()) + m_workerThread = dxvk::thread([this] () { workerFunc(); }); } diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index 9fb6b52a9..1fae1b097 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -13,6 +13,8 @@ namespace dxvk { class DxvkDevice; + class DxvkPipelineManager; + class DxvkPipelineWorkers; /** * \brief State cache @@ -29,8 +31,9 @@ namespace dxvk { DxvkStateCache( DxvkDevice* device, - DxvkPipelineManager* pipeManager); - + DxvkPipelineManager* pipeManager, + DxvkPipelineWorkers* pipeWorkers); + ~DxvkStateCache(); /** @@ -72,15 +75,7 @@ namespace dxvk { /** * \brief Explicitly stops worker threads */ - void stopWorkerThreads(); - - /** - * \brief Checks whether compiler threads are busy - * \returns \c true if we're compiling shaders - */ - bool isCompilingShaders() const { - return m_workerBusy.load() > 0; - } + void stopWorkers(); private: @@ -93,6 +88,7 @@ namespace dxvk { DxvkDevice* m_device; DxvkPipelineManager* m_pipeManager; + DxvkPipelineWorkers* m_pipeWorkers; bool m_enable = false; std::vector m_entries; @@ -115,8 +111,7 @@ namespace dxvk { dxvk::mutex m_workerLock; dxvk::condition_variable m_workerCond; std::queue m_workerQueue; - std::atomic m_workerBusy; - std::vector m_workerThreads; + dxvk::thread m_workerThread; dxvk::mutex m_writerLock; dxvk::condition_variable m_writerCond; @@ -160,7 +155,7 @@ namespace dxvk { void writerFunc(); - void createWorkers(); + void createWorker(); void createWriter(); From 06c084616f93876b093fb4aa85cae56fdad23b55 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 18:46:11 +0200 Subject: [PATCH 0145/1348] [dxvk] Clean up graphics and compute pipeline constructors --- src/dxvk/dxvk_compute.cpp | 31 +++++++++++++----------- src/dxvk/dxvk_compute.h | 12 +++++++--- src/dxvk/dxvk_graphics.cpp | 44 +++++++++++++++++++++-------------- src/dxvk/dxvk_graphics.h | 12 +++++++--- src/dxvk/dxvk_pipemanager.cpp | 8 +++---- src/dxvk/dxvk_pipemanager.h | 11 ++++++--- 6 files changed, 73 insertions(+), 45 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 52849d8d0..d85070f24 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -11,11 +11,16 @@ namespace dxvk { DxvkComputePipeline::DxvkComputePipeline( + DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkComputePipelineShaders shaders, DxvkBindingLayoutObjects* layout) - : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), - m_shaders(std::move(shaders)), m_bindings(layout) { + : m_device (device), + m_cache (&pipeMgr->m_cache), + m_stateCache (&pipeMgr->m_stateCache), + m_stats (&pipeMgr->m_stats), + m_shaders (std::move(shaders)), + m_bindings (layout) { } @@ -57,7 +62,7 @@ namespace dxvk { const DxvkComputePipelineStateInfo& state) { VkPipeline newPipelineHandle = this->createPipeline(state); - m_pipeMgr->m_numComputePipelines += 1; + m_stats->numComputePipelines += 1; return &(*m_pipelines.emplace(state, newPipelineHandle)); } @@ -75,7 +80,7 @@ namespace dxvk { VkPipeline DxvkComputePipeline::createPipeline( const DxvkComputePipelineStateInfo& state) const { - std::vector bindings; + auto vk = m_device->vkd(); if (Logger::logLevel() <= LogLevel::Debug) { Logger::debug("Compiling compute pipeline..."); @@ -92,15 +97,11 @@ namespace dxvk { DxvkShaderModuleCreateInfo moduleInfo; moduleInfo.fsDualSrcBlend = false; - auto csm = m_shaders.cs->createShaderModule(m_vkd, m_bindings, moduleInfo); + auto csm = m_shaders.cs->createShaderModule(vk, m_bindings, moduleInfo); - VkComputePipelineCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; info.stage = csm.stageInfo(&specInfo); info.layout = m_bindings->getPipelineLayout(); - info.basePipelineHandle = VK_NULL_HANDLE; info.basePipelineIndex = -1; // Time pipeline compilation for debugging purposes @@ -110,8 +111,8 @@ namespace dxvk { t0 = dxvk::high_resolution_clock::now(); VkPipeline pipeline = VK_NULL_HANDLE; - if (m_vkd->vkCreateComputePipelines(m_vkd->device(), - m_pipeMgr->m_cache.handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { + if (vk->vkCreateComputePipelines(vk->device(), + m_cache->handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { Logger::err("DxvkComputePipeline: Failed to compile pipeline"); Logger::err(str::format(" cs : ", m_shaders.cs->debugName())); return VK_NULL_HANDLE; @@ -128,7 +129,9 @@ namespace dxvk { void DxvkComputePipeline::destroyPipeline(VkPipeline pipeline) { - m_vkd->vkDestroyPipeline(m_vkd->device(), pipeline, nullptr); + auto vk = m_device->vkd(); + + vk->vkDestroyPipeline(vk->device(), pipeline, nullptr); } @@ -139,7 +142,7 @@ namespace dxvk { if (m_shaders.cs != nullptr) key.cs = m_shaders.cs->getShaderKey(); - m_pipeMgr->m_stateCache.addComputePipeline(key, state); + m_stateCache->addComputePipeline(key, state); } } diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index 51566389d..4da2c14ac 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -15,8 +15,11 @@ namespace dxvk { class DxvkDevice; + class DxvkStateCache; class DxvkPipelineManager; - + struct DxvkPipelineStats; + + /** * \brief Shaders used in compute pipelines */ @@ -90,6 +93,7 @@ namespace dxvk { public: DxvkComputePipeline( + DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkComputePipelineShaders shaders, DxvkBindingLayoutObjects* layout); @@ -137,8 +141,10 @@ namespace dxvk { private: - Rc m_vkd; - DxvkPipelineManager* m_pipeMgr; + DxvkDevice* m_device; + DxvkPipelineCache* m_cache; + DxvkStateCache* m_stateCache; + DxvkPipelineStats* m_stats; DxvkComputePipelineShaders m_shaders; DxvkBindingLayoutObjects* m_bindings; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 614f8a3ee..2f5ea8c38 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -456,12 +456,17 @@ namespace dxvk { DxvkGraphicsPipeline::DxvkGraphicsPipeline( + DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkGraphicsPipelineShaders shaders, DxvkBindingLayoutObjects* layout) - : m_vkd(pipeMgr->m_device->vkd()), m_pipeMgr(pipeMgr), - m_shaders(std::move(shaders)), m_bindings(layout), - m_barrier(layout->getGlobalBarrier()) { + : m_device (device), + m_cache (&pipeMgr->m_cache), + m_stateCache (&pipeMgr->m_stateCache), + m_stats (&pipeMgr->m_stats), + m_shaders (std::move(shaders)), + m_bindings (layout), + m_barrier (layout->getGlobalBarrier()) { m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->info().inputMask : 0; m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->info().outputMask : 0; @@ -557,7 +562,7 @@ namespace dxvk { const DxvkGraphicsPipelineStateInfo& state) { VkPipeline pipeline = this->createPipeline(state); - m_pipeMgr->m_numGraphicsPipelines += 1; + m_stats->numGraphicsPipelines += 1; return &(*m_pipelines.emplace(state, pipeline)); } @@ -575,7 +580,7 @@ namespace dxvk { VkPipeline DxvkGraphicsPipeline::createPipeline( const DxvkGraphicsPipelineStateInfo& state) const { - const DxvkDevice* device = m_pipeMgr->m_device; + auto vk = m_device->vkd(); if (Logger::logLevel() <= LogLevel::Debug) { Logger::debug("Compiling graphics pipeline..."); @@ -630,10 +635,10 @@ namespace dxvk { if (gsm) stages.push_back(gsm.stageInfo(&specInfo)); if (fsm) stages.push_back(fsm.stageInfo(&specInfo)); - DxvkGraphicsPipelineVertexInputState viState(device, state); - DxvkGraphicsPipelinePreRasterizationState prState(device, state, m_shaders.gs.ptr()); - DxvkGraphicsPipelineFragmentShaderState fsState(device, state); - DxvkGraphicsPipelineFragmentOutputState foState(device, state, m_shaders.fs.ptr()); + DxvkGraphicsPipelineVertexInputState viState(m_device, state); + DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr()); + DxvkGraphicsPipelineFragmentShaderState fsState(m_device, state); + DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; dyInfo.dynamicStateCount = dynamicStateCount; @@ -664,7 +669,7 @@ namespace dxvk { t0 = dxvk::high_resolution_clock::now(); VkPipeline pipeline = VK_NULL_HANDLE; - if (m_vkd->vkCreateGraphicsPipelines(m_vkd->device(), m_pipeMgr->m_cache.handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { + if (vk->vkCreateGraphicsPipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { Logger::err("DxvkGraphicsPipeline: Failed to compile pipeline"); this->logPipelineState(LogLevel::Error, state); return VK_NULL_HANDLE; @@ -681,13 +686,17 @@ namespace dxvk { void DxvkGraphicsPipeline::destroyPipeline(VkPipeline pipeline) const { - m_vkd->vkDestroyPipeline(m_vkd->device(), pipeline, nullptr); + auto vk = m_device->vkd(); + + vk->vkDestroyPipeline(vk->device(), pipeline, nullptr); } DxvkShaderModule DxvkGraphicsPipeline::createShaderModule( const Rc& shader, const DxvkGraphicsPipelineStateInfo& state) const { + auto vk = m_device->vkd(); + if (shader == nullptr) return DxvkShaderModule(); @@ -720,7 +729,7 @@ namespace dxvk { } info.undefinedInputs = (providedInputs & consumedInputs) ^ consumedInputs; - return shader->createShaderModule(m_vkd, m_bindings, info); + return shader->createShaderModule(vk, m_bindings, info); } @@ -782,7 +791,6 @@ namespace dxvk { } // Validate vertex input layout - const DxvkDevice* device = m_pipeMgr->m_device; uint32_t ilLocationMask = 0; uint32_t ilBindingMask = 0; @@ -802,7 +810,7 @@ namespace dxvk { return false; } - VkFormatProperties formatInfo = device->adapter()->formatProperties(attribute.format()); + VkFormatProperties formatInfo = m_device->adapter()->formatProperties(attribute.format()); if (!(formatInfo.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) { Logger::err(str::format("Invalid pipeline: Format ", attribute.format(), " not supported for vertex buffers")); @@ -814,20 +822,20 @@ namespace dxvk { // Validate rasterization state if (state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT) { - if (!device->extensions().extConservativeRasterization) { + if (!m_device->extensions().extConservativeRasterization) { Logger::err("Conservative rasterization not supported by device"); return false; } if (state.rs.conservativeMode() == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT - && !device->properties().extConservativeRasterization.primitiveUnderestimation) { + && !m_device->properties().extConservativeRasterization.primitiveUnderestimation) { Logger::err("Primitive underestimation not supported by device"); return false; } } // Validate depth-stencil state - if (state.ds.enableDepthBoundsTest() && !device->features().core.features.depthBounds) { + if (state.ds.enableDepthBoundsTest() && !m_device->features().core.features.depthBounds) { Logger::err("Depth bounds not supported by device"); return false; } @@ -845,7 +853,7 @@ namespace dxvk { if (m_shaders.gs != nullptr) key.gs = m_shaders.gs->getShaderKey(); if (m_shaders.fs != nullptr) key.fs = m_shaders.fs->getShaderKey(); - m_pipeMgr->m_stateCache.addGraphicsPipeline(key, state); + m_stateCache->addGraphicsPipeline(key, state); } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index f2757f2be..50a056f54 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -17,7 +17,10 @@ namespace dxvk { class DxvkDevice; + class DxvkStateCache; class DxvkPipelineManager; + class DxvkPipelineWorkers; + struct DxvkPipelineStats; /** * \brief Vertex input info for graphics pipelines @@ -286,6 +289,7 @@ namespace dxvk { public: DxvkGraphicsPipeline( + DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkGraphicsPipelineShaders shaders, DxvkBindingLayoutObjects* layout); @@ -366,9 +370,11 @@ namespace dxvk { const DxvkGraphicsPipelineStateInfo& state); private: - - Rc m_vkd; - DxvkPipelineManager* m_pipeMgr; + + DxvkDevice* m_device; + DxvkPipelineCache* m_cache; + DxvkStateCache* m_stateCache; + DxvkPipelineStats* m_stats; DxvkGraphicsPipelineShaders m_shaders; DxvkBindingLayoutObjects* m_bindings; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 195528bdc..c6c7ab891 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -192,7 +192,7 @@ namespace dxvk { auto iter = m_computePipelines.emplace( std::piecewise_construct, std::tuple(shaders), - std::tuple(this, shaders, layout)); + std::tuple(m_device, this, shaders, layout)); return &iter.first->second; } @@ -228,7 +228,7 @@ namespace dxvk { auto iter = m_graphicsPipelines.emplace( std::piecewise_construct, std::tuple(shaders), - std::tuple(this, shaders, layout)); + std::tuple(m_device, this, shaders, layout)); return &iter.first->second; } @@ -273,8 +273,8 @@ namespace dxvk { DxvkPipelineCount DxvkPipelineManager::getPipelineCount() const { DxvkPipelineCount result; - result.numComputePipelines = m_numComputePipelines.load(); - result.numGraphicsPipelines = m_numGraphicsPipelines.load(); + result.numComputePipelines = m_stats.numComputePipelines.load(); + result.numGraphicsPipelines = m_stats.numGraphicsPipelines.load(); return result; } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index c0cc476eb..9d6434329 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -24,6 +24,13 @@ namespace dxvk { uint32_t numComputePipelines; }; + /** + * \brief Pipeline stats + */ + struct DxvkPipelineStats { + std::atomic numGraphicsPipelines = { 0u }; + std::atomic numComputePipelines = { 0u }; + }; /** * \brief Pipeline manager worker threads @@ -216,9 +223,7 @@ namespace dxvk { DxvkPipelineCache m_cache; DxvkPipelineWorkers m_workers; DxvkStateCache m_stateCache; - - std::atomic m_numComputePipelines = { 0 }; - std::atomic m_numGraphicsPipelines = { 0 }; + DxvkPipelineStats m_stats; dxvk::mutex m_mutex; From a6b0783a5108aca10b54908d6a76e9d0649d9d61 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 18:56:43 +0200 Subject: [PATCH 0146/1348] [dxvk] Add config option for graphics pipeline library enablement --- dxvk.conf | 14 ++++++++++++++ src/dxvk/dxvk_device.cpp | 3 ++- src/dxvk/dxvk_options.cpp | 1 + src/dxvk/dxvk_options.h | 3 +++ src/dxvk/dxvk_pipemanager.cpp | 3 ++- 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index ebab35571..dbb0e2253 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -272,6 +272,20 @@ # dxvk.shrinkNvidiaHvvHeap = Auto +# Controls graphics pipeline library behaviour +# +# Can be used to change VK_EXT_graphics_pipeline_library usage for +# debugging purpose. Doing so will likely result in increased stutter +# or degraded performance. +# +# Supported values: +# - Auto: Enable if supported, and compile optimized pipelines in the background +# - True: Enable if supported, but do not compile optimized pipelines +# - False: Always disable the feature + +# dxvk.enableGraphicsPipelineLibrary = Auto + + # Sets enabled HUD elements # # Behaves like the DXVK_HUD environment variable if the diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 49421bc85..74b2d0b9a 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -46,7 +46,8 @@ namespace dxvk { // cannot use this effectively in many games since no client API provides // interpoation qualifiers in vertex shaders. return m_features.extGraphicsPipelineLibrary.graphicsPipelineLibrary - && m_properties.extGraphicsPipelineLibrary.graphicsPipelineLibraryIndependentInterpolationDecoration; + && m_properties.extGraphicsPipelineLibrary.graphicsPipelineLibraryIndependentInterpolationDecoration + && m_options.enableGraphicsPipelineLibrary != Tristate::False; } diff --git a/src/dxvk/dxvk_options.cpp b/src/dxvk/dxvk_options.cpp index ea82eedc7..87f26186c 100644 --- a/src/dxvk/dxvk_options.cpp +++ b/src/dxvk/dxvk_options.cpp @@ -6,6 +6,7 @@ namespace dxvk { enableDebugUtils = config.getOption ("dxvk.enableDebugUtils", false); enableStateCache = config.getOption ("dxvk.enableStateCache", true); numCompilerThreads = config.getOption ("dxvk.numCompilerThreads", 0); + enableGraphicsPipelineLibrary = config.getOption("dxvk.enableGraphicsPipelineLibrary", Tristate::Auto); useRawSsbo = config.getOption("dxvk.useRawSsbo", Tristate::Auto); shrinkNvidiaHvvHeap = config.getOption("dxvk.shrinkNvidiaHvvHeap", Tristate::Auto); hud = config.getOption("dxvk.hud", ""); diff --git a/src/dxvk/dxvk_options.h b/src/dxvk/dxvk_options.h index 992ec764a..18210fa64 100644 --- a/src/dxvk/dxvk_options.h +++ b/src/dxvk/dxvk_options.h @@ -18,6 +18,9 @@ namespace dxvk { /// when using the state cache int32_t numCompilerThreads; + /// Enable graphics pipeline library + Tristate enableGraphicsPipelineLibrary; + /// Shader-related options Tristate useRawSsbo; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index c6c7ab891..7aa02b81b 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -167,7 +167,8 @@ namespace dxvk { m_cache (device), m_workers (device, &m_cache), m_stateCache(device, this, &m_workers) { - + Logger::info(str::format("DXVK: Graphics pipeline libraries ", + (m_device->canUseGraphicsPipelineLibrary() ? "supported" : "not supported"))); } From a49333cd87d0c764167107a4c5277ae214ae657e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 18:59:40 +0200 Subject: [PATCH 0147/1348] [dxvk] Add pass to check whether a shader has spec constants Pipeline libraries cannot be used for shaders with user spec constants. --- src/dxvk/dxvk_shader.cpp | 3 +++ src/dxvk/dxvk_shader.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 6fa9338ff..aca093b20 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -115,6 +115,9 @@ namespace dxvk { bindingOffsets[varId].setOffset = ins.offset() + 3; } + if (ins.arg(2) == spv::DecorationSpecId && ins.arg(3) < MaxNumSpecConstants) + m_flags.set(DxvkShaderFlag::HasSpecConstants); + if (ins.arg(2) == spv::DecorationLocation && ins.arg(3) == 1) { m_o1LocOffset = ins.offset() + 3; o1VarId = ins.arg(1); diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 40e2023bd..56e0f6f50 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -39,6 +39,7 @@ namespace dxvk { enum DxvkShaderFlag : uint64_t { HasSampleRateShading, HasTransformFeedback, + HasSpecConstants, ExportsStencilRef, ExportsViewportIndexLayerFromVertexStage, }; From 5019ce4b9c92390541f738d348a8fbb4fb4f65cf Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 5 Jul 2022 19:14:38 +0200 Subject: [PATCH 0148/1348] [dxvk] Compile pipeline libraries in registerShader if supported --- src/dxvk/dxvk_pipemanager.cpp | 21 +++++++++++++++++++++ src/dxvk/dxvk_pipemanager.h | 8 ++++++++ src/dxvk/dxvk_shader.cpp | 14 ++++++++++++++ src/dxvk/dxvk_shader.h | 25 +++++++++++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 7aa02b81b..a2980ebcd 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -268,6 +268,11 @@ namespace dxvk { void DxvkPipelineManager::registerShader( const Rc& shader) { + if (m_device->canUseGraphicsPipelineLibrary() && shader->canUsePipelineLibrary()) { + auto library = createPipelineLibrary(shader); + m_workers.compilePipelineLibrary(library); + } + m_stateCache.registerShader(shader); } @@ -320,5 +325,21 @@ namespace dxvk { std::tuple(m_device, layout, setLayouts.data())); return &iter.first->second; } + + + DxvkShaderPipelineLibrary* DxvkPipelineManager::createPipelineLibrary( + const Rc& shader) { + std::lock_guard lock(m_mutex); + auto layout = createPipelineLayout(shader->getBindings()); + + DxvkShaderPipelineLibraryKey key; + key.shader = shader; + + auto iter = m_shaderLibraries.emplace( + std::piecewise_construct, + std::tuple(key), + std::tuple(m_device, shader.ptr(), layout)); + return &iter.first->second; + } } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 9d6434329..b10389a72 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -257,12 +257,20 @@ namespace dxvk { DxvkGraphicsPipelineFragmentOutputLibrary, DxvkHash, DxvkEq> m_fragmentOutputLibraries; + std::unordered_map< + DxvkShaderPipelineLibraryKey, + DxvkShaderPipelineLibrary, + DxvkHash, DxvkEq> m_shaderLibraries; + DxvkBindingSetLayout* createDescriptorSetLayout( const DxvkBindingSetLayoutKey& key); DxvkBindingLayoutObjects* createPipelineLayout( const DxvkBindingLayout& layout); + DxvkShaderPipelineLibrary* createPipelineLibrary( + const Rc& shader); + }; } \ No newline at end of file diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index aca093b20..883365051 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -202,6 +202,20 @@ namespace dxvk { } + bool DxvkShader::canUsePipelineLibrary() const { + // Pipeline libraries are unsupported for geometry and + // tessellation stages since we'd need to compile them + // all into one library + if (m_info.stage != VK_SHADER_STAGE_VERTEX_BIT + && m_info.stage != VK_SHADER_STAGE_FRAGMENT_BIT + && m_info.stage != VK_SHADER_STAGE_COMPUTE_BIT) + return false; + + // Ignore shaders that have user-defined spec constants + return !m_flags.test(DxvkShaderFlag::HasSpecConstants); + } + + void DxvkShader::dump(std::ostream& outputStream) const { m_code.decompress().store(outputStream); } diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 56e0f6f50..0a0d29c51 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -150,6 +150,15 @@ namespace dxvk { const DxvkBindingLayoutObjects* layout, const DxvkShaderModuleCreateInfo& info); + /** + * \brief Tests whether this shader supports pipeline libraries + * + * This is true for any vertex, fragment, or compute shader that does not + * require additional pipeline state to be compiled into something useful. + * \returns \c true if this shader can be used with pipeline libraries + */ + bool canUsePipelineLibrary() const; + /** * \brief Dumps SPIR-V shader * @@ -305,6 +314,22 @@ namespace dxvk { }; + /** + * \brief Shader pipeline library key + */ + struct DxvkShaderPipelineLibraryKey { + Rc shader; + + bool eq(const DxvkShaderPipelineLibraryKey& other) const { + return shader == other.shader; + } + + size_t hash() const { + return DxvkShader::getHash(shader); + } + }; + + /** * \brief Shader pipeline library * From e6470b6d1068f242d85af516b30a50ccd1a79848 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 00:40:47 +0200 Subject: [PATCH 0149/1348] [dxvk] Rework DxvkShaderModule into DxvkShaderStageInfo Separates the whole thing from DxvkShader instances so that we can use this in other places too. Only creates a shader module if necessary for the given pipeline or device. --- src/dxvk/dxvk_compute.cpp | 10 ++-- src/dxvk/dxvk_graphics.cpp | 38 ++++++------ src/dxvk/dxvk_graphics.h | 2 +- src/dxvk/dxvk_shader.cpp | 118 ++++++++++++++++++------------------- src/dxvk/dxvk_shader.h | 82 +++++++++++--------------- 5 files changed, 117 insertions(+), 133 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index d85070f24..ee908d203 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -94,13 +94,13 @@ namespace dxvk { VkSpecializationInfo specInfo = specData.getSpecInfo(); - DxvkShaderModuleCreateInfo moduleInfo; - moduleInfo.fsDualSrcBlend = false; - - auto csm = m_shaders.cs->createShaderModule(vk, m_bindings, moduleInfo); + DxvkShaderStageInfo stageInfo(m_device); + stageInfo.addStage(VK_SHADER_STAGE_COMPUTE_BIT, + m_shaders.cs->getCode(m_bindings, DxvkShaderModuleCreateInfo()), + &specInfo); VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; - info.stage = csm.stageInfo(&specInfo); + info.stage = *stageInfo.getStageInfos(); info.layout = m_bindings->getPipelineLayout(); info.basePipelineIndex = -1; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 2f5ea8c38..a51ca90c0 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -1,3 +1,5 @@ +#include + #include "../util/util_time.h" #include "dxvk_device.h" @@ -621,19 +623,19 @@ namespace dxvk { specData.set(getSpecId(i), state.sc.specConstants[i], 0u); VkSpecializationInfo specInfo = specData.getSpecInfo(); - - auto vsm = createShaderModule(m_shaders.vs, state); - auto tcsm = createShaderModule(m_shaders.tcs, state); - auto tesm = createShaderModule(m_shaders.tes, state); - auto gsm = createShaderModule(m_shaders.gs, state); - auto fsm = createShaderModule(m_shaders.fs, state); - std::vector stages; - if (vsm) stages.push_back(vsm.stageInfo(&specInfo)); - if (tcsm) stages.push_back(tcsm.stageInfo(&specInfo)); - if (tesm) stages.push_back(tesm.stageInfo(&specInfo)); - if (gsm) stages.push_back(gsm.stageInfo(&specInfo)); - if (fsm) stages.push_back(fsm.stageInfo(&specInfo)); + // Build stage infos for all provided shaders + DxvkShaderStageInfo stageInfo(m_device); + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, state), &specInfo); + + if (m_shaders.tcs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, state), &specInfo); + if (m_shaders.tes != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, state), &specInfo); + if (m_shaders.gs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, state), &specInfo); + if (m_shaders.fs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, state), &specInfo); DxvkGraphicsPipelineVertexInputState viState(m_device, state); DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr()); @@ -645,8 +647,8 @@ namespace dxvk { dyInfo.pDynamicStates = dynamicStates.data(); VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &foState.rtInfo }; - info.stageCount = stages.size(); - info.pStages = stages.data(); + info.stageCount = stageInfo.getStageCount(); + info.pStages = stageInfo.getStageInfos(); info.pVertexInputState = &viState.viInfo; info.pInputAssemblyState = &viState.iaInfo; info.pTessellationState = &prState.tsInfo; @@ -692,14 +694,11 @@ namespace dxvk { } - DxvkShaderModule DxvkGraphicsPipeline::createShaderModule( + SpirvCodeBuffer DxvkGraphicsPipeline::getShaderCode( const Rc& shader, const DxvkGraphicsPipelineStateInfo& state) const { auto vk = m_device->vkd(); - if (shader == nullptr) - return DxvkShaderModule(); - const DxvkShaderCreateInfo& shaderInfo = shader->info(); DxvkShaderModuleCreateInfo info; @@ -729,7 +728,8 @@ namespace dxvk { } info.undefinedInputs = (providedInputs & consumedInputs) ^ consumedInputs; - return shader->createShaderModule(vk, m_bindings, info); + + return shader->getCode(m_bindings, info); } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 50a056f54..c4c616a31 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -401,7 +401,7 @@ namespace dxvk { void destroyPipeline( VkPipeline pipeline) const; - DxvkShaderModule createShaderModule( + SpirvCodeBuffer getShaderCode( const Rc& shader, const DxvkGraphicsPipelineStateInfo& state) const; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 883365051..856aa897a 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -7,60 +7,6 @@ namespace dxvk { - DxvkShaderModule::DxvkShaderModule() - : m_vkd(nullptr), m_stage() { - - } - - - DxvkShaderModule::DxvkShaderModule(DxvkShaderModule&& other) - : m_vkd(std::move(other.m_vkd)) { - this->m_stage = other.m_stage; - other.m_stage = VkPipelineShaderStageCreateInfo(); - } - - - DxvkShaderModule::DxvkShaderModule( - const Rc& vkd, - const Rc& shader, - const SpirvCodeBuffer& code) - : m_vkd(vkd), m_stage() { - m_stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - m_stage.pNext = nullptr; - m_stage.flags = 0; - m_stage.stage = shader->info().stage; - m_stage.module = VK_NULL_HANDLE; - m_stage.pName = "main"; - m_stage.pSpecializationInfo = nullptr; - - VkShaderModuleCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; - info.codeSize = code.size(); - info.pCode = code.data(); - - if (m_vkd->vkCreateShaderModule(m_vkd->device(), &info, nullptr, &m_stage.module) != VK_SUCCESS) - throw DxvkError("DxvkComputePipeline::DxvkComputePipeline: Failed to create shader module"); - } - - - DxvkShaderModule::~DxvkShaderModule() { - if (m_vkd != nullptr) { - m_vkd->vkDestroyShaderModule( - m_vkd->device(), m_stage.module, nullptr); - } - } - - - DxvkShaderModule& DxvkShaderModule::operator = (DxvkShaderModule&& other) { - this->m_vkd = std::move(other.m_vkd); - this->m_stage = other.m_stage; - other.m_stage = VkPipelineShaderStageCreateInfo(); - return *this; - } - - DxvkShader::DxvkShader( const DxvkShaderCreateInfo& info, SpirvCodeBuffer&& spirv) @@ -194,14 +140,6 @@ namespace dxvk { } - DxvkShaderModule DxvkShader::createShaderModule( - const Rc& vkd, - const DxvkBindingLayoutObjects* layout, - const DxvkShaderModuleCreateInfo& info) { - return DxvkShaderModule(vkd, this, getCode(layout, info)); - } - - bool DxvkShader::canUsePipelineLibrary() const { // Pipeline libraries are unsupported for geometry and // tessellation stages since we'd need to compile them @@ -428,6 +366,62 @@ namespace dxvk { } + DxvkShaderStageInfo::DxvkShaderStageInfo(const DxvkDevice* device) + : m_device(device) { + + } + + void DxvkShaderStageInfo::addStage( + VkShaderStageFlagBits stage, + SpirvCodeBuffer&& code, + const VkSpecializationInfo* specInfo) { + // Take ownership of the SPIR-V code buffer + auto& codeBuffer = m_codeBuffers[m_stageCount]; + codeBuffer = std::move(code); + + // For graphics pipelines, as long as graphics pipeline libraries are + // enabled, we do not need to create a shader module object and can + // instead chain the create info to the shader stage info struct. + // For compute pipelines, this doesn't work and we still need a module. + auto& moduleInfo = m_moduleInfos[m_stageCount]; + moduleInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; + moduleInfo.codeSize = codeBuffer.size(); + moduleInfo.pCode = codeBuffer.data(); + + VkShaderModule shaderModule = VK_NULL_HANDLE; + if (!m_device->features().extGraphicsPipelineLibrary.graphicsPipelineLibrary || stage == VK_SHADER_STAGE_COMPUTE_BIT) { + auto vk = m_device->vkd(); + + if (vk->vkCreateShaderModule(vk->device(), &moduleInfo, nullptr, &shaderModule)) + throw DxvkError("DxvkShaderStageInfo: Failed to create shader module"); + } + + // Set up shader stage info with the data provided + auto& stageInfo = m_stageInfos[m_stageCount]; + stageInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO }; + + if (!stageInfo.module) + stageInfo.pNext = &moduleInfo; + + stageInfo.stage = stage; + stageInfo.module = shaderModule; + stageInfo.pName = "main"; + stageInfo.pSpecializationInfo = specInfo; + + m_stageCount++; + } + + + DxvkShaderStageInfo::~DxvkShaderStageInfo() { + auto vk = m_device->vkd(); + + for (uint32_t i = 0; i < m_stageCount; i++) { + if (m_stageInfos[i].module) + vk->vkDestroyShaderModule(vk->device(), m_stageInfos[i].module, nullptr); + } + } + + DxvkShaderPipelineLibrary::DxvkShaderPipelineLibrary( const DxvkDevice* device, const DxvkShader* shader, diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 0a0d29c51..1f5592158 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -135,21 +135,6 @@ namespace dxvk { const DxvkBindingLayoutObjects* layout, const DxvkShaderModuleCreateInfo& state) const; - /** - * \brief Creates a shader module - * - * Remaps resource binding and descriptor set - * numbers to match the given binding layout. - * \param [in] vkd Vulkan device functions - * \param [in] layout Binding layout - * \param [in] info Module create info - * \returns The shader module - */ - DxvkShaderModule createShaderModule( - const Rc& vkd, - const DxvkBindingLayoutObjects* layout, - const DxvkShaderModuleCreateInfo& info); - /** * \brief Tests whether this shader supports pipeline libraries * @@ -252,49 +237,54 @@ namespace dxvk { * context will create pipeline objects on the * fly when executing draw calls. */ - class DxvkShaderModule { + class DxvkShaderStageInfo { public: - DxvkShaderModule(); + DxvkShaderStageInfo(const DxvkDevice* device); - DxvkShaderModule(DxvkShaderModule&& other); - - DxvkShaderModule( - const Rc& vkd, - const Rc& shader, - const SpirvCodeBuffer& code); - - ~DxvkShaderModule(); + DxvkShaderStageInfo (DxvkShaderStageInfo&& other) = delete; + DxvkShaderStageInfo& operator = (DxvkShaderStageInfo&& other) = delete; + + ~DxvkShaderStageInfo(); - DxvkShaderModule& operator = (DxvkShaderModule&& other); - /** - * \brief Shader stage creation info - * - * \param [in] specInfo Specialization info - * \returns Shader stage create info + * \brief Counts shader stages + * \returns Shader stage count */ - VkPipelineShaderStageCreateInfo stageInfo( - const VkSpecializationInfo* specInfo) const { - VkPipelineShaderStageCreateInfo stage = m_stage; - stage.pSpecializationInfo = specInfo; - return stage; + uint32_t getStageCount() const { + return m_stageCount; } - + /** - * \brief Checks whether module is valid - * \returns \c true if module is valid + * \brief Queries shader stage infos + * \returns Pointer to shader stage infos */ - operator bool () const { - return m_stage.module != VK_NULL_HANDLE; + const VkPipelineShaderStageCreateInfo* getStageInfos() const { + return m_stageInfos.data(); } - + + /** + * \brief Adds a shader stage with specialization info + * + * \param [in] stage Shader stage + * \param [in] code SPIR-V code + * \param [in] specinfo Specialization info + */ + void addStage( + VkShaderStageFlagBits stage, + SpirvCodeBuffer&& code, + const VkSpecializationInfo* specInfo); + private: - - Rc m_vkd; - VkPipelineShaderStageCreateInfo m_stage; - + + const DxvkDevice* m_device; + + std::array m_codeBuffers; + std::array m_moduleInfos = { }; + std::array m_stageInfos = { }; + uint32_t m_stageCount = 0; + }; From 6265b5b8097b3f02a321572bef384a96dbad9028 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 00:49:21 +0200 Subject: [PATCH 0150/1348] [dxvk] Use new shader stage info objects in DxvkShaderPipelineLibrary Avoids crashing on drivers which do not support NULL modules for compute pipelines and just reduces the amount of code by a small amount. --- src/dxvk/dxvk_shader.cpp | 50 +++++++++++----------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 856aa897a..acd8f822d 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -486,16 +486,9 @@ namespace dxvk { const DxvkShaderPipelineLibraryCompileArgs& args) { auto vk = m_device->vkd(); - // Set up shader stage. Do not create a shader module. - SpirvCodeBuffer spirv = m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()); - - VkShaderModuleCreateInfo codeInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; - codeInfo.codeSize = spirv.size(); - codeInfo.pCode = spirv.data(); - - VkPipelineShaderStageCreateInfo stageInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, &codeInfo }; - stageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; - stageInfo.pName = "main"; + DxvkShaderStageInfo stageInfo(m_device); + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, + m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()), nullptr); // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. @@ -542,8 +535,8 @@ namespace dxvk { VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; - info.stageCount = 1; - info.pStages = &stageInfo; + info.stageCount = stageInfo.getStageCount(); + info.pStages = stageInfo.getStageInfos(); info.pViewportState = &vpInfo; info.pRasterizationState = &rsInfo; info.pDynamicState = &dyInfo; @@ -562,16 +555,9 @@ namespace dxvk { VkPipeline DxvkShaderPipelineLibrary::compileFragmentShaderPipeline(VkPipelineCache cache) { auto vk = m_device->vkd(); - // Set up shader stage. Do not create a shader module. - SpirvCodeBuffer spirv = m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()); - - VkShaderModuleCreateInfo codeInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; - codeInfo.codeSize = spirv.size(); - codeInfo.pCode = spirv.data(); - - VkPipelineShaderStageCreateInfo stageInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, &codeInfo }; - stageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - stageInfo.pName = "main"; + DxvkShaderStageInfo stageInfo(m_device); + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, + m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()), nullptr); // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. @@ -619,8 +605,8 @@ namespace dxvk { VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; - info.stageCount = 1; - info.pStages = &stageInfo; + info.stageCount = stageInfo.getStageCount(); + info.pStages = stageInfo.getStageInfos(); info.pDepthStencilState = &dsInfo; info.pDynamicState = &dyInfo; info.layout = m_layout->getPipelineLayout(); @@ -641,21 +627,13 @@ namespace dxvk { VkPipeline DxvkShaderPipelineLibrary::compileComputeShaderPipeline(VkPipelineCache cache) { auto vk = m_device->vkd(); - // Set up shader stage. Do not create a shader module since we only - // ever call this if graphics pipeline libraries are supported. - SpirvCodeBuffer spirv = m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()); - - VkShaderModuleCreateInfo codeInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; - codeInfo.codeSize = spirv.size(); - codeInfo.pCode = spirv.data(); - - VkPipelineShaderStageCreateInfo stageInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, &codeInfo }; - stageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; - stageInfo.pName = "main"; + DxvkShaderStageInfo stageInfo(m_device); + stageInfo.addStage(VK_SHADER_STAGE_COMPUTE_BIT, + m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()), nullptr); // Compile the compute pipeline as normal VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; - info.stage = stageInfo; + info.stage = *stageInfo.getStageInfos(); info.layout = m_layout->getPipelineLayout(); info.basePipelineIndex = -1; From cb56e16a4b6743e43e1c2ed783e4a58830b5caf6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 01:14:02 +0200 Subject: [PATCH 0151/1348] [dxvk] Use precompiled compute pipelines whenever possible --- src/dxvk/dxvk_compute.cpp | 48 ++++++++++++++++++++++++----------- src/dxvk/dxvk_compute.h | 6 ++++- src/dxvk/dxvk_pipemanager.cpp | 16 +++++++++++- src/dxvk/dxvk_pipemanager.h | 3 +++ 4 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index ee908d203..ffe8c9837 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -14,11 +14,14 @@ namespace dxvk { DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkComputePipelineShaders shaders, - DxvkBindingLayoutObjects* layout) + DxvkBindingLayoutObjects* layout, + DxvkShaderPipelineLibrary* library) : m_device (device), m_cache (&pipeMgr->m_cache), m_stateCache (&pipeMgr->m_stateCache), m_stats (&pipeMgr->m_stats), + m_library (library), + m_libraryHandle (VK_NULL_HANDLE), m_shaders (std::move(shaders)), m_bindings (layout) { @@ -33,28 +36,43 @@ namespace dxvk { VkPipeline DxvkComputePipeline::getPipelineHandle( const DxvkComputePipelineStateInfo& state) { - DxvkComputePipelineInstance* instance = this->findInstance(state); - - if (unlikely(!instance)) { - std::lock_guard lock(m_mutex); - instance = this->findInstance(state); - - if (!instance) { - instance = this->createInstance(state); - this->writePipelineStateToCache(state); + if (m_library) { + // For compute pipelines that can be precompiled, we can use that + // pipeline variant unconditionally since there is no state for us + // to worry about other than specialization constants + if (unlikely(!m_libraryHandle)) { + m_libraryHandle = m_library->getPipelineHandle(m_cache->handle(), + DxvkShaderPipelineLibraryCompileArgs()); + m_stats->numComputePipelines += 1; } - } - return instance->pipeline(); + return m_libraryHandle; + } else { + DxvkComputePipelineInstance* instance = this->findInstance(state); + + if (unlikely(!instance)) { + std::lock_guard lock(m_mutex); + instance = this->findInstance(state); + + if (!instance) { + instance = this->createInstance(state); + this->writePipelineStateToCache(state); + } + } + + return instance->pipeline(); + } } void DxvkComputePipeline::compilePipeline( const DxvkComputePipelineStateInfo& state) { - std::lock_guard lock(m_mutex); + if (!m_library) { + std::lock_guard lock(m_mutex); - if (!this->findInstance(state)) - this->createInstance(state); + if (!this->findInstance(state)) + this->createInstance(state); + } } diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index 4da2c14ac..d492f4d68 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -96,7 +96,8 @@ namespace dxvk { DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkComputePipelineShaders shaders, - DxvkBindingLayoutObjects* layout); + DxvkBindingLayoutObjects* layout, + DxvkShaderPipelineLibrary* library); ~DxvkComputePipeline(); @@ -146,6 +147,9 @@ namespace dxvk { DxvkStateCache* m_stateCache; DxvkPipelineStats* m_stats; + DxvkShaderPipelineLibrary* m_library; + VkPipeline m_libraryHandle; + DxvkComputePipelineShaders m_shaders; DxvkBindingLayoutObjects* m_bindings; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index a2980ebcd..578dda390 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -189,11 +189,12 @@ namespace dxvk { return &pair->second; auto layout = createPipelineLayout(shaders.cs->getBindings()); + auto library = findPipelineLibrary(shaders.cs); auto iter = m_computePipelines.emplace( std::piecewise_construct, std::tuple(shaders), - std::tuple(m_device, this, shaders, layout)); + std::tuple(m_device, this, shaders, layout, library)); return &iter.first->second; } @@ -341,5 +342,18 @@ namespace dxvk { std::tuple(m_device, shader.ptr(), layout)); return &iter.first->second; } + + + DxvkShaderPipelineLibrary* DxvkPipelineManager::findPipelineLibrary( + const Rc& shader) { + DxvkShaderPipelineLibraryKey key; + key.shader = shader; + + auto pair = m_shaderLibraries.find(key); + if (pair == m_shaderLibraries.end()) + return nullptr; + + return &pair->second; + } } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index b10389a72..a3739acda 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -271,6 +271,9 @@ namespace dxvk { DxvkShaderPipelineLibrary* createPipelineLibrary( const Rc& shader); + DxvkShaderPipelineLibrary* findPipelineLibrary( + const Rc& shader); + }; } \ No newline at end of file From a72bf023741de5d8c57253a848ec12aa3c4c2508 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 02:07:17 +0200 Subject: [PATCH 0152/1348] [dxvk] Pass VS and FS libraries to graphics pipelines --- src/dxvk/dxvk_graphics.cpp | 8 ++++++-- src/dxvk/dxvk_graphics.h | 7 ++++++- src/dxvk/dxvk_pipemanager.cpp | 12 +++++++++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index a51ca90c0..f06174883 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -461,14 +461,18 @@ namespace dxvk { DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkGraphicsPipelineShaders shaders, - DxvkBindingLayoutObjects* layout) + DxvkBindingLayoutObjects* layout, + DxvkShaderPipelineLibrary* vsLibrary, + DxvkShaderPipelineLibrary* fsLibrary) : m_device (device), m_cache (&pipeMgr->m_cache), m_stateCache (&pipeMgr->m_stateCache), m_stats (&pipeMgr->m_stats), m_shaders (std::move(shaders)), m_bindings (layout), - m_barrier (layout->getGlobalBarrier()) { + m_barrier (layout->getGlobalBarrier()), + m_vsLibrary (vsLibrary), + m_fsLibrary (fsLibrary) { m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->info().inputMask : 0; m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->info().outputMask : 0; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index c4c616a31..f69e83033 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -292,7 +292,9 @@ namespace dxvk { DxvkDevice* device, DxvkPipelineManager* pipeMgr, DxvkGraphicsPipelineShaders shaders, - DxvkBindingLayoutObjects* layout); + DxvkBindingLayoutObjects* layout, + DxvkShaderPipelineLibrary* vsLibrary, + DxvkShaderPipelineLibrary* fsLibrary); ~DxvkGraphicsPipeline(); @@ -381,6 +383,9 @@ namespace dxvk { DxvkGlobalPipelineBarrier m_barrier; DxvkGraphicsPipelineFlags m_flags; + DxvkShaderPipelineLibrary* m_vsLibrary; + DxvkShaderPipelineLibrary* m_fsLibrary; + uint32_t m_vsIn = 0; uint32_t m_fsOut = 0; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 578dda390..f4b8ac258 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -227,10 +227,20 @@ namespace dxvk { auto layout = createPipelineLayout(mergedLayout); + DxvkShaderPipelineLibrary* vsLibrary = nullptr; + DxvkShaderPipelineLibrary* fsLibrary = nullptr; + + if (shaders.tcs == nullptr && shaders.tes == nullptr && shaders.gs == nullptr) { + // TODO handle null fs properly + vsLibrary = findPipelineLibrary(shaders.vs); + fsLibrary = findPipelineLibrary(shaders.fs); + } + auto iter = m_graphicsPipelines.emplace( std::piecewise_construct, std::tuple(shaders), - std::tuple(m_device, this, shaders, layout)); + std::tuple(m_device, this, shaders, + layout, vsLibrary, fsLibrary)); return &iter.first->second; } From 2cb9ceba1dfd5b18d923c05f0bd168fa928850fb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 02:23:44 +0200 Subject: [PATCH 0153/1348] [dxvk] Simplify pipeline instance data --- src/dxvk/dxvk_compute.cpp | 6 +++--- src/dxvk/dxvk_compute.h | 43 +++++++------------------------------- src/dxvk/dxvk_graphics.cpp | 6 +++--- src/dxvk/dxvk_graphics.h | 43 +++++++------------------------------- 4 files changed, 20 insertions(+), 78 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index ffe8c9837..50ffbd96f 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -30,7 +30,7 @@ namespace dxvk { DxvkComputePipeline::~DxvkComputePipeline() { for (const auto& instance : m_pipelines) - this->destroyPipeline(instance.pipeline()); + this->destroyPipeline(instance.handle); } @@ -60,7 +60,7 @@ namespace dxvk { } } - return instance->pipeline(); + return instance->handle; } } @@ -88,7 +88,7 @@ namespace dxvk { DxvkComputePipelineInstance* DxvkComputePipeline::findInstance( const DxvkComputePipelineStateInfo& state) { for (auto& instance : m_pipelines) { - if (instance.isCompatible(state)) + if (instance.state == state) return &instance; } diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index d492f4d68..8dcfc3142 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -39,44 +39,15 @@ namespace dxvk { /** * \brief Compute pipeline instance */ - class DxvkComputePipelineInstance { - - public: - - DxvkComputePipelineInstance() - : m_stateVector (), - m_pipeline (VK_NULL_HANDLE) { } - + struct DxvkComputePipelineInstance { + DxvkComputePipelineInstance() { } DxvkComputePipelineInstance( - const DxvkComputePipelineStateInfo& state, - VkPipeline pipe) - : m_stateVector (state), - m_pipeline (pipe) { } - - /** - * \brief Checks for matching pipeline state - * - * \param [in] stateVector Graphics pipeline state - * \param [in] renderPass Render pass handle - * \returns \c true if the specialization is compatible - */ - bool isCompatible(const DxvkComputePipelineStateInfo& state) const { - return m_stateVector == state; - } - - /** - * \brief Retrieves pipeline - * \returns The pipeline handle - */ - VkPipeline pipeline() const { - return m_pipeline; - } - - private: - - DxvkComputePipelineStateInfo m_stateVector; - VkPipeline m_pipeline; + const DxvkComputePipelineStateInfo& state_, + VkPipeline handle_) + : state(state_), handle(handle_) { } + DxvkComputePipelineStateInfo state; + VkPipeline handle = VK_NULL_HANDLE; }; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index f06174883..a24059fd7 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -493,7 +493,7 @@ namespace dxvk { DxvkGraphicsPipeline::~DxvkGraphicsPipeline() { for (const auto& instance : m_pipelines) - this->destroyPipeline(instance.pipeline()); + this->destroyPipeline(instance.handle); } @@ -545,7 +545,7 @@ namespace dxvk { } } - return instance->pipeline(); + return instance->handle; } @@ -576,7 +576,7 @@ namespace dxvk { DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::findInstance( const DxvkGraphicsPipelineStateInfo& state) { for (auto& instance : m_pipelines) { - if (instance.isCompatible(state)) + if (instance.state == state) return &instance; } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index f69e83033..de4e48465 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -236,44 +236,15 @@ namespace dxvk { * Stores a state vector and the * corresponding pipeline handle. */ - class DxvkGraphicsPipelineInstance { - - public: - - DxvkGraphicsPipelineInstance() - : m_stateVector (), - m_pipeline (VK_NULL_HANDLE) { } - + struct DxvkGraphicsPipelineInstance { + DxvkGraphicsPipelineInstance() { } DxvkGraphicsPipelineInstance( - const DxvkGraphicsPipelineStateInfo& state, - VkPipeline pipe) - : m_stateVector (state), - m_pipeline (pipe) { } - - /** - * \brief Checks for matching pipeline state - * - * \param [in] stateVector Graphics pipeline state - * \returns \c true if the specialization is compatible - */ - bool isCompatible( - const DxvkGraphicsPipelineStateInfo& state) { - return m_stateVector == state; - } - - /** - * \brief Retrieves pipeline - * \returns The pipeline handle - */ - VkPipeline pipeline() const { - return m_pipeline; - } - - private: - - DxvkGraphicsPipelineStateInfo m_stateVector; - VkPipeline m_pipeline; + const DxvkGraphicsPipelineStateInfo& state_, + VkPipeline handle_) + : state(state_), handle(handle_) { } + DxvkGraphicsPipelineStateInfo state; + VkPipeline handle = VK_NULL_HANDLE; }; From a0d1ef7f619a330ea2807fb0eb6c5e55c438b470 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 02:51:05 +0200 Subject: [PATCH 0154/1348] [dxvk] Handle null shader in DxvkShaderPipelineLibrary --- src/dxvk/dxvk_shader.cpp | 26 +++++++++++++++++++++----- src/dxvk/meson.build | 2 ++ src/dxvk/shaders/dxvk_dummy_frag.frag | 5 +++++ 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 src/dxvk/shaders/dxvk_dummy_frag.frag diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index acd8f822d..361cbd9e1 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -1,6 +1,8 @@ #include "dxvk_device.h" #include "dxvk_shader.h" +#include + #include #include #include @@ -444,14 +446,19 @@ namespace dxvk { const DxvkShaderPipelineLibraryCompileArgs& args) { std::lock_guard lock(m_mutex); - VkPipeline& pipeline = (m_shader->info().stage == VK_SHADER_STAGE_VERTEX_BIT && !args.depthClipEnable) + VkShaderStageFlagBits stage = VK_SHADER_STAGE_FRAGMENT_BIT; + + if (m_shader) + stage = m_shader->info().stage; + + VkPipeline& pipeline = (stage == VK_SHADER_STAGE_VERTEX_BIT && !args.depthClipEnable) ? m_pipelineNoDepthClip : m_pipeline; if (pipeline) return pipeline; - switch (m_shader->info().stage) { + switch (stage) { case VK_SHADER_STAGE_VERTEX_BIT: pipeline = compileVertexShaderPipeline(cache, args); break; @@ -555,9 +562,18 @@ namespace dxvk { VkPipeline DxvkShaderPipelineLibrary::compileFragmentShaderPipeline(VkPipelineCache cache) { auto vk = m_device->vkd(); + // Initialize code buffer. As a special case, it is possible that + // we have to deal with a null shader, but the pipeline library + // extension requires us to always specify a fragment shader. DxvkShaderStageInfo stageInfo(m_device); - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, - m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()), nullptr); + + if (m_shader) { + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, + m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()), nullptr); + } else { + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, + SpirvCodeBuffer(dxvk_dummy_frag), nullptr); + } // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. @@ -612,7 +628,7 @@ namespace dxvk { info.layout = m_layout->getPipelineLayout(); info.basePipelineIndex = -1; - if (m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading)) + if (m_shader && m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading)) info.pMultisampleState = &msInfo; VkPipeline pipeline = VK_NULL_HANDLE; diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 0ed8caf60..e49c49b9e 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -27,6 +27,8 @@ dxvk_shaders = files([ 'shaders/dxvk_copy_depth_stencil_2d.frag', 'shaders/dxvk_copy_depth_stencil_ms.frag', + 'shaders/dxvk_dummy_frag.frag', + 'shaders/dxvk_fullscreen_geom.geom', 'shaders/dxvk_fullscreen_vert.vert', 'shaders/dxvk_fullscreen_layer_vert.vert', diff --git a/src/dxvk/shaders/dxvk_dummy_frag.frag b/src/dxvk/shaders/dxvk_dummy_frag.frag new file mode 100644 index 000000000..0afc2bd14 --- /dev/null +++ b/src/dxvk/shaders/dxvk_dummy_frag.frag @@ -0,0 +1,5 @@ +#version 450 + +void main() { + +} From a683ecd525a119a88b8e5971245e0e606f255a8a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 03:04:27 +0200 Subject: [PATCH 0155/1348] [dxvk] Create pipeline library for null shader --- src/dxvk/dxvk_pipemanager.cpp | 19 ++++++++++++++++++- src/dxvk/dxvk_pipemanager.h | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index f4b8ac258..a1392e0c9 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -169,6 +169,11 @@ namespace dxvk { m_stateCache(device, this, &m_workers) { Logger::info(str::format("DXVK: Graphics pipeline libraries ", (m_device->canUseGraphicsPipelineLibrary() ? "supported" : "not supported"))); + + if (m_device->canUseGraphicsPipelineLibrary()) { + auto library = createNullFsPipelineLibrary(); + library->compilePipeline(m_cache.handle()); + } } @@ -231,7 +236,6 @@ namespace dxvk { DxvkShaderPipelineLibrary* fsLibrary = nullptr; if (shaders.tcs == nullptr && shaders.tes == nullptr && shaders.gs == nullptr) { - // TODO handle null fs properly vsLibrary = findPipelineLibrary(shaders.vs); fsLibrary = findPipelineLibrary(shaders.fs); } @@ -354,6 +358,19 @@ namespace dxvk { } + DxvkShaderPipelineLibrary* DxvkPipelineManager::createNullFsPipelineLibrary() { + std::lock_guard lock(m_mutex); + auto layout = createPipelineLayout(DxvkBindingLayout( + VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT)); + + auto iter = m_shaderLibraries.emplace( + std::piecewise_construct, + std::tuple(), + std::tuple(m_device, nullptr, layout)); + return &iter.first->second; + } + + DxvkShaderPipelineLibrary* DxvkPipelineManager::findPipelineLibrary( const Rc& shader) { DxvkShaderPipelineLibraryKey key; diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index a3739acda..154fbb0d7 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -271,6 +271,8 @@ namespace dxvk { DxvkShaderPipelineLibrary* createPipelineLibrary( const Rc& shader); + DxvkShaderPipelineLibrary* createNullFsPipelineLibrary(); + DxvkShaderPipelineLibrary* findPipelineLibrary( const Rc& shader); From e01ffc02a8753ca7107e6e1e6de577cbe54aedca Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 03:46:32 +0200 Subject: [PATCH 0156/1348] [dxvk] Add more dynamic state to DxvkCommandList --- src/dxvk/dxvk_cmdlist.h | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 6df1fc1bc..0d81ec52a 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -699,12 +699,39 @@ namespace dxvk { } + void cmdSetDepthBoundsState( + VkBool32 depthBoundsTestEnable) { + m_vkd->vkCmdSetDepthBoundsTestEnableEXT(m_execBuffer, depthBoundsTestEnable); + } + + + void cmdSetDepthState( + VkBool32 depthTestEnable, + VkBool32 depthWriteEnable, + VkCompareOp depthCompareOp) { + m_vkd->vkCmdSetDepthTestEnableEXT(m_execBuffer, depthTestEnable); + + if (depthTestEnable) { + m_vkd->vkCmdSetDepthWriteEnableEXT(m_execBuffer, depthWriteEnable); + m_vkd->vkCmdSetDepthCompareOpEXT(m_execBuffer, depthCompareOp); + } + } + + void cmdSetEvent( VkEvent event, VkPipelineStageFlags stages) { m_vkd->vkCmdSetEvent(m_execBuffer, event, stages); } + + void cmdSetRasterizerState( + VkCullModeFlags cullMode, + VkFrontFace frontFace) { + m_vkd->vkCmdSetCullModeEXT(m_execBuffer, cullMode); + m_vkd->vkCmdSetFrontFaceEXT(m_execBuffer, frontFace); + } + void cmdSetScissor( uint32_t scissorCount, @@ -714,6 +741,33 @@ namespace dxvk { } + void cmdSetStencilState( + VkBool32 enableStencilTest, + const VkStencilOpState& front, + const VkStencilOpState& back) { + m_vkd->vkCmdSetStencilTestEnableEXT( + m_execBuffer, enableStencilTest); + + if (enableStencilTest) { + m_vkd->vkCmdSetStencilOpEXT(m_execBuffer, + VK_STENCIL_FACE_FRONT_BIT, front.failOp, + front.passOp, front.depthFailOp, front.compareOp); + m_vkd->vkCmdSetStencilCompareMask(m_execBuffer, + VK_STENCIL_FACE_FRONT_BIT, front.compareMask); + m_vkd->vkCmdSetStencilWriteMask(m_execBuffer, + VK_STENCIL_FACE_FRONT_BIT, front.writeMask); + + m_vkd->vkCmdSetStencilOpEXT(m_execBuffer, + VK_STENCIL_FACE_BACK_BIT, back.failOp, + back.passOp, back.depthFailOp, back.compareOp); + m_vkd->vkCmdSetStencilCompareMask(m_execBuffer, + VK_STENCIL_FACE_BACK_BIT, back.compareMask); + m_vkd->vkCmdSetStencilWriteMask(m_execBuffer, + VK_STENCIL_FACE_BACK_BIT, back.writeMask); + } + } + + void cmdSetStencilReference( VkStencilFaceFlags faceMask, uint32_t reference) { From 90454438b2fb2392ba0686e64f79bb70b858bb17 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 03:39:43 +0200 Subject: [PATCH 0157/1348] [dxvk] Introduce distinction between base and optimized pipelines We need to know what kind of pipeline we're binding in order to apply the correct dynamic state. --- src/dxvk/dxvk_context.cpp | 32 +++++++++++++++++++++++++++++--- src/dxvk/dxvk_graphics.cpp | 6 +++--- src/dxvk/dxvk_graphics.h | 13 +++++++++++-- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index a4e30fe47..da1cf882b 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4500,14 +4500,40 @@ namespace dxvk { : DxvkContextFlag::GpDirtyStencilRef); // Retrieve and bind actual Vulkan pipeline handle - VkPipeline pipeline = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state); + auto pipelineInfo = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state); - if (unlikely(!pipeline)) + if (unlikely(!pipelineInfo.first)) return false; m_cmd->cmdBindPipeline( VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline); + pipelineInfo.first); + + // For pipelines created from graphics pipeline libraries, we need + // to apply a bunch of dynamic state that is otherwise static + if (pipelineInfo.second == DxvkGraphicsPipelineType::BasePipeline) { + m_cmd->cmdSetRasterizerState( + m_state.gp.state.rs.cullMode(), + m_state.gp.state.rs.frontFace()); + + m_cmd->cmdSetDepthState( + m_state.gp.state.ds.enableDepthTest(), + m_state.gp.state.ds.enableDepthWrite(), + m_state.gp.state.ds.depthCompareOp()); + + m_cmd->cmdSetStencilState( + m_state.gp.state.ds.enableStencilTest(), + m_state.gp.state.dsFront.state(), + m_state.gp.state.dsBack.state()); + + if (m_device->features().core.features.depthBounds) { + m_cmd->cmdSetDepthBoundsState( + m_state.gp.state.ds.enableDepthBoundsTest()); + } + + if (!m_state.gp.state.rs.depthBiasEnable()) + m_cmd->cmdSetDepthBias(0.0f, 0.0f, 0.0f); + } // Emit barrier based on pipeline properties, in order to avoid // accidental write-after-read hazards after the render pass. diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index a24059fd7..020afd29a 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -524,14 +524,14 @@ namespace dxvk { } - VkPipeline DxvkGraphicsPipeline::getPipelineHandle( + std::pair DxvkGraphicsPipeline::getPipelineHandle( const DxvkGraphicsPipelineStateInfo& state) { DxvkGraphicsPipelineInstance* instance = this->findInstance(state); if (unlikely(!instance)) { // Exit early if the state vector is invalid if (!this->validatePipelineState(state, true)) - return VK_NULL_HANDLE; + return std::make_pair(VK_NULL_HANDLE, DxvkGraphicsPipelineType::FastPipeline); // Prevent other threads from adding new instances and check again std::lock_guard lock(m_mutex); @@ -545,7 +545,7 @@ namespace dxvk { } } - return instance->handle; + return std::make_pair(instance->handle, DxvkGraphicsPipelineType::FastPipeline); } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index de4e48465..b4623bd26 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -230,6 +230,15 @@ namespace dxvk { }; + /** + * \brief Graphics pipeline type + */ + enum class DxvkGraphicsPipelineType : uint32_t { + BasePipeline = 0, ///< Unoptimized pipeline using graphics pipeline libraries + FastPipeline = 1, ///< Monolithic pipeline with less dynamic state + }; + + /** * \brief Graphics pipeline instance * @@ -327,9 +336,9 @@ namespace dxvk { * Retrieves a pipeline handle for the given pipeline * state. If necessary, a new pipeline will be created. * \param [in] state Pipeline state vector - * \returns Pipeline handle + * \returns Pipeline handle and handle type */ - VkPipeline getPipelineHandle( + std::pair getPipelineHandle( const DxvkGraphicsPipelineStateInfo& state); /** From b50ed2ceca7232089130125caf719b53f8df50c7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 04:15:31 +0200 Subject: [PATCH 0158/1348] [dxvk] Deal with multiple pipeline handles for graphics pipeline instances Also make the handles atomic since worker threads may access them when compiling optimized pipeline variants. --- src/dxvk/dxvk_graphics.cpp | 17 +++++++++++++---- src/dxvk/dxvk_graphics.h | 12 +++++++++--- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 020afd29a..5dc946a5c 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -492,8 +492,10 @@ namespace dxvk { DxvkGraphicsPipeline::~DxvkGraphicsPipeline() { - for (const auto& instance : m_pipelines) - this->destroyPipeline(instance.handle); + for (const auto& instance : m_pipelines) { + this->destroyPipeline(instance.baseHandle.load()); + this->destroyPipeline(instance.fastHandle.load()); + } } @@ -545,7 +547,14 @@ namespace dxvk { } } - return std::make_pair(instance->handle, DxvkGraphicsPipelineType::FastPipeline); + // Find a pipeline handle to use. If no optimized pipeline has + // been compiled yet, use the slower base pipeline instead. + VkPipeline fastHandle = instance->fastHandle.load(); + + if (likely(fastHandle != VK_NULL_HANDLE)) + return std::make_pair(fastHandle, DxvkGraphicsPipelineType::FastPipeline); + + return std::make_pair(instance->baseHandle.load(), DxvkGraphicsPipelineType::BasePipeline); } @@ -569,7 +578,7 @@ namespace dxvk { VkPipeline pipeline = this->createPipeline(state); m_stats->numGraphicsPipelines += 1; - return &(*m_pipelines.emplace(state, pipeline)); + return &(*m_pipelines.emplace(state, VK_NULL_HANDLE, pipeline)); } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index b4623bd26..967e81349 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -249,11 +249,17 @@ namespace dxvk { DxvkGraphicsPipelineInstance() { } DxvkGraphicsPipelineInstance( const DxvkGraphicsPipelineStateInfo& state_, - VkPipeline handle_) - : state(state_), handle(handle_) { } + VkPipeline baseHandle_, + VkPipeline fastHandle_) + : state (state_), + baseHandle (baseHandle_), + fastHandle (fastHandle_), + isCompiling (fastHandle_ != VK_NULL_HANDLE) { } DxvkGraphicsPipelineStateInfo state; - VkPipeline handle = VK_NULL_HANDLE; + std::atomic baseHandle = { VK_NULL_HANDLE }; + std::atomic fastHandle = { VK_NULL_HANDLE }; + std::atomic isCompiling = { VK_FALSE }; }; From cc1575e8b7dab0f25a8b89b86704b490dd06e6e5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 12:09:03 +0200 Subject: [PATCH 0159/1348] [dxvk] Compile optimized graphics pipelines on worker threads if necessary --- src/dxvk/dxvk_graphics.cpp | 6 ++++++ src/dxvk/dxvk_graphics.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 5dc946a5c..86a9de93d 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -465,6 +465,8 @@ namespace dxvk { DxvkShaderPipelineLibrary* vsLibrary, DxvkShaderPipelineLibrary* fsLibrary) : m_device (device), + m_manager (pipeMgr), + m_workers (&pipeMgr->m_workers), m_cache (&pipeMgr->m_cache), m_stateCache (&pipeMgr->m_stateCache), m_stats (&pipeMgr->m_stats), @@ -544,6 +546,10 @@ namespace dxvk { // a state cache worker and the current thread needs priority. instance = this->createInstance(state); this->writePipelineStateToCache(state); + + // If necessary, compile an optimized pipeline variant + if (!instance->fastHandle.load()) + m_workers->compileGraphicsPipeline(this, state); } } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 967e81349..c4b257211 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -360,6 +360,8 @@ namespace dxvk { private: DxvkDevice* m_device; + DxvkPipelineManager* m_manager; + DxvkPipelineWorkers* m_workers; DxvkPipelineCache* m_cache; DxvkStateCache* m_stateCache; DxvkPipelineStats* m_stats; From 7f9a04fd59627c0ce6c6b3c9887c22def834c10c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 12:42:47 +0200 Subject: [PATCH 0160/1348] [dxvk] Don't keep pipeline locked when building optimized variant Only lock when creating base variant, otherwise we'll have stutter. --- src/dxvk/dxvk_graphics.cpp | 35 ++++++++++++++++++++++++++--------- src/dxvk/dxvk_graphics.h | 2 +- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 86a9de93d..888498c3c 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -566,22 +566,39 @@ namespace dxvk { void DxvkGraphicsPipeline::compilePipeline( const DxvkGraphicsPipelineStateInfo& state) { - // Exit early if the state vector is invalid - if (!this->validatePipelineState(state, false)) + if (m_device->config().enableGraphicsPipelineLibrary == Tristate::True) return; - // Keep the object locked while compiling a pipeline since compiling - // similar pipelines concurrently is fragile on some drivers - std::lock_guard lock(m_mutex); + // Try to find an existing instance that contains a base pipeline + DxvkGraphicsPipelineInstance* instance = this->findInstance(state); - if (!this->findInstance(state)) - this->createInstance(state); + if (!instance) { + // Exit early if the state vector is invalid + if (!this->validatePipelineState(state, false)) + return; + + // Prevent other threads from adding new instances and check again + std::lock_guard lock(m_mutex); + instance = this->findInstance(state); + + if (!instance) + instance = this->createInstance(state); + } + + // Exit if another thread is already compiling + // an optimized version of this pipeline + if (instance->isCompiling.load() + || instance->isCompiling.exchange(VK_TRUE, std::memory_order_acquire)) + return; + + VkPipeline pipeline = this->createOptimizedPipeline(state); + instance->fastHandle.store(pipeline, std::memory_order_release); } DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::createInstance( const DxvkGraphicsPipelineStateInfo& state) { - VkPipeline pipeline = this->createPipeline(state); + VkPipeline pipeline = this->createOptimizedPipeline(state); m_stats->numGraphicsPipelines += 1; return &(*m_pipelines.emplace(state, VK_NULL_HANDLE, pipeline)); @@ -599,7 +616,7 @@ namespace dxvk { } - VkPipeline DxvkGraphicsPipeline::createPipeline( + VkPipeline DxvkGraphicsPipeline::createOptimizedPipeline( const DxvkGraphicsPipelineStateInfo& state) const { auto vk = m_device->vkd(); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index c4b257211..268e4ac81 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -388,7 +388,7 @@ namespace dxvk { DxvkGraphicsPipelineInstance* findInstance( const DxvkGraphicsPipelineStateInfo& state); - VkPipeline createPipeline( + VkPipeline createOptimizedPipeline( const DxvkGraphicsPipelineStateInfo& state) const; void destroyPipeline( From 6256ab2a191c447ac95cafae0f54fc3986bad643 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 13:03:05 +0200 Subject: [PATCH 0161/1348] [dxvk] Use pipeline libraries to link base pipelines if possible --- src/dxvk/dxvk_graphics.cpp | 109 ++++++++++++++++++++++++++++++--- src/dxvk/dxvk_graphics.h | 13 ++++ src/dxvk/dxvk_graphics_state.h | 10 ++- 3 files changed, 122 insertions(+), 10 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 888498c3c..e651f0c5b 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -598,10 +598,26 @@ namespace dxvk { DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::createInstance( const DxvkGraphicsPipelineStateInfo& state) { - VkPipeline pipeline = this->createOptimizedPipeline(state); + VkPipeline baseHandle = VK_NULL_HANDLE; + VkPipeline fastHandle = VK_NULL_HANDLE; + + if (this->canCreateBasePipeline(state)) { + DxvkGraphicsPipelineVertexInputState viState(m_device, state); + DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); + + DxvkGraphicsPipelineBaseInstanceKey key; + key.viLibrary = m_manager->createVertexInputLibrary(viState); + key.foLibrary = m_manager->createFragmentOutputLibrary(foState); + key.args.depthClipEnable = state.rs.depthClipEnable(); + + baseHandle = this->createBasePipeline(key); + } else { + // Create optimized variant right away, no choice + fastHandle = this->createOptimizedPipeline(state); + } m_stats->numGraphicsPipelines += 1; - return &(*m_pipelines.emplace(state, VK_NULL_HANDLE, pipeline)); + return &(*m_pipelines.emplace(state, baseHandle, fastHandle)); } @@ -616,6 +632,86 @@ namespace dxvk { } + bool DxvkGraphicsPipeline::canCreateBasePipeline( + const DxvkGraphicsPipelineStateInfo& state) const { + if (!m_vsLibrary || !m_fsLibrary) + return false; + + // Certain rasterization states cannot be set dynamically, + // so we're assuming defaults for them, most notably the + // polygon mode and conservative rasterization settings + if (state.rs.polygonMode() != VK_POLYGON_MODE_FILL + || state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT) + return false; + + if (m_shaders.fs != nullptr) { + // If the fragment shader has inputs not produced by the + // vertex shader, we need to patch the fragment shader + uint32_t vsIoMask = m_shaders.vs->info().outputMask; + uint32_t fsIoMask = m_shaders.fs->info().inputMask; + + if ((vsIoMask & fsIoMask) != fsIoMask) + return false; + + // Dual-source blending requires patching the fragment shader + if (state.useDualSourceBlending()) + return false; + + // Multisample state must match in this case, and the + // library assumes that MSAA is disabled in this case. + if (m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading)) { + if (state.ms.sampleCount() != VK_SAMPLE_COUNT_1_BIT + || state.ms.sampleMask() == 0 + || state.ms.enableAlphaToCoverage()) + return false; + } + } + + // Remapping fragment shader outputs would require spec constants + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + VkFormat rtFormat = state.rt.getColorFormat(i); + + if (rtFormat && (m_fsOut & (1u << i)) && state.omBlend[i].colorWriteMask()) { + auto mapping = state.omSwizzle[i].mapping(); + + if (mapping.r != VK_COMPONENT_SWIZZLE_R + || mapping.g != VK_COMPONENT_SWIZZLE_G + || mapping.b != VK_COMPONENT_SWIZZLE_B + || mapping.a != VK_COMPONENT_SWIZZLE_A) + return false; + } + } + + return true; + } + + + VkPipeline DxvkGraphicsPipeline::createBasePipeline( + const DxvkGraphicsPipelineBaseInstanceKey& key) const { + auto vk = m_device->vkd(); + + std::array libraries = {{ + key.viLibrary->getHandle(), + m_vsLibrary->getPipelineHandle(m_cache->handle(), key.args), + m_fsLibrary->getPipelineHandle(m_cache->handle(), key.args), + key.foLibrary->getHandle(), + }}; + + VkPipelineLibraryCreateInfoKHR libInfo = { VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR }; + libInfo.libraryCount = libraries.size(); + libInfo.pLibraries = libraries.data(); + + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; + + VkPipeline pipeline = VK_NULL_HANDLE; + + if ((vk->vkCreateGraphicsPipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline))) + Logger::err("DxvkGraphicsPipeline: Failed to create base pipeline"); + + return pipeline; + } + + VkPipeline DxvkGraphicsPipeline::createOptimizedPipeline( const DxvkGraphicsPipelineStateInfo& state) const { auto vk = m_device->vkd(); @@ -739,13 +835,8 @@ namespace dxvk { DxvkShaderModuleCreateInfo info; // Fix up fragment shader outputs for dual-source blending - if (shaderInfo.stage == VK_SHADER_STAGE_FRAGMENT_BIT) { - info.fsDualSrcBlend = state.omBlend[0].blendEnable() && ( - util::isDualSourceBlendFactor(state.omBlend[0].srcColorBlendFactor()) || - util::isDualSourceBlendFactor(state.omBlend[0].dstColorBlendFactor()) || - util::isDualSourceBlendFactor(state.omBlend[0].srcAlphaBlendFactor()) || - util::isDualSourceBlendFactor(state.omBlend[0].dstAlphaBlendFactor())); - } + if (shaderInfo.stage == VK_SHADER_STAGE_FRAGMENT_BIT) + info.fsDualSrcBlend = state.useDualSourceBlending(); // Deal with undefined shader inputs uint32_t consumedInputs = shaderInfo.inputMask; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 268e4ac81..9201e8bd2 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -262,6 +262,13 @@ namespace dxvk { std::atomic isCompiling = { VK_FALSE }; }; + + struct DxvkGraphicsPipelineBaseInstanceKey { + const DxvkGraphicsPipelineVertexInputLibrary* viLibrary; + const DxvkGraphicsPipelineFragmentOutputLibrary* foLibrary; + DxvkShaderPipelineLibraryCompileArgs args; + }; + /** * \brief Graphics pipeline @@ -387,6 +394,12 @@ namespace dxvk { DxvkGraphicsPipelineInstance* findInstance( const DxvkGraphicsPipelineStateInfo& state); + + bool canCreateBasePipeline( + const DxvkGraphicsPipelineStateInfo& state) const; + + VkPipeline createBasePipeline( + const DxvkGraphicsPipelineBaseInstanceKey& key) const; VkPipeline createOptimizedPipeline( const DxvkGraphicsPipelineStateInfo& state) const; diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index ebd7c6375..189249260 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -758,7 +758,15 @@ namespace dxvk { return result; } - + + bool useDualSourceBlending() const { + return omBlend[0].blendEnable() && ( + util::isDualSourceBlendFactor(omBlend[0].srcColorBlendFactor()) || + util::isDualSourceBlendFactor(omBlend[0].dstColorBlendFactor()) || + util::isDualSourceBlendFactor(omBlend[0].srcAlphaBlendFactor()) || + util::isDualSourceBlendFactor(omBlend[0].dstAlphaBlendFactor())); + } + DxvkIaInfo ia; DxvkIlInfo il; DxvkRsInfo rs; From b51d7a3cc03aeef03e965b7f489ab97ad9190601 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 6 Jul 2022 16:38:32 +0200 Subject: [PATCH 0162/1348] [dxvk] Update descriptor sets after binding pipeline --- src/dxvk/dxvk_context.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index da1cf882b..f00fbb57c 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5165,14 +5165,14 @@ namespace dxvk { return false; } - if (m_descriptorState.hasDirtyComputeSets()) - this->updateComputeShaderResources(); - if (m_flags.test(DxvkContextFlag::CpDirtyPipelineState)) { if (unlikely(!this->updateComputePipelineState())) return false; } + if (m_descriptorState.hasDirtyComputeSets()) + this->updateComputeShaderResources(); + if (m_flags.test(DxvkContextFlag::DirtyPushConstants)) this->updatePushConstants(); @@ -5207,9 +5207,6 @@ namespace dxvk { if (m_flags.test(DxvkContextFlag::GpDirtyVertexBuffers)) this->updateVertexBufferBindings(); - if (m_descriptorState.hasDirtyGraphicsSets()) - this->updateGraphicsShaderResources(); - if (m_flags.test(DxvkContextFlag::GpDirtyPipelineState)) { DxvkGlobalPipelineBarrier barrier = { }; @@ -5227,6 +5224,9 @@ namespace dxvk { return false; } + if (m_descriptorState.hasDirtyGraphicsSets()) + this->updateGraphicsShaderResources(); + if (m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasTransformFeedback)) this->updateTransformFeedbackState(); From 5e1569593aee57afac34a1090ad2dda0bb19ee1f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 7 Jul 2022 10:38:39 +0200 Subject: [PATCH 0163/1348] [dxvk] Create full pipeline layout with INDEPENDENT_SETS_BIT And use it to link pipelines as well as descriptor binding. Should fix issues related to descriptors. --- src/dxvk/dxvk_compute.cpp | 2 +- src/dxvk/dxvk_context.cpp | 34 +++++++++++++++++++++++++++------- src/dxvk/dxvk_context_state.h | 1 + src/dxvk/dxvk_descriptor.cpp | 4 ++-- src/dxvk/dxvk_graphics.cpp | 8 +++++--- src/dxvk/dxvk_pipelayout.cpp | 23 +++++++++++++++++------ src/dxvk/dxvk_pipelayout.h | 23 ++++++++++++++++++----- src/dxvk/dxvk_shader.cpp | 6 +++--- 8 files changed, 74 insertions(+), 27 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 50ffbd96f..9341f82cd 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -119,7 +119,7 @@ namespace dxvk { VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; info.stage = *stageInfo.getStageInfos(); - info.layout = m_bindings->getPipelineLayout(); + info.layout = m_bindings->getPipelineLayout(false); info.basePipelineIndex = -1; // Time pipeline compilation for debugging purposes diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index f00fbb57c..74e887aa3 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -84,7 +84,8 @@ namespace dxvk { // before any draw or dispatch command is recorded. m_flags.clr( DxvkContextFlag::GpRenderPassBound, - DxvkContextFlag::GpXfbActive); + DxvkContextFlag::GpXfbActive, + DxvkContextFlag::GpIndependentSets); m_flags.set( DxvkContextFlag::GpDirtyFramebuffer, @@ -3995,6 +3996,7 @@ namespace dxvk { m_flags.set( DxvkContextFlag::GpRenderPassBound, + DxvkContextFlag::GpDirtyPipeline, DxvkContextFlag::GpDirtyPipelineState, DxvkContextFlag::GpDirtyVertexBuffers, DxvkContextFlag::GpDirtyIndexBuffer, @@ -4006,7 +4008,9 @@ namespace dxvk { DxvkContextFlag::GpDirtyDepthBounds, DxvkContextFlag::DirtyPushConstants); - m_flags.clr(DxvkContextFlag::GpRenderPassSuspended); + m_flags.clr( + DxvkContextFlag::GpRenderPassSuspended, + DxvkContextFlag::GpIndependentSets); this->renderPassBindFramebuffer( m_state.om.framebufferInfo, @@ -4470,18 +4474,21 @@ namespace dxvk { bool DxvkContext::updateGraphicsPipelineState(DxvkGlobalPipelineBarrier srcBarrier) { + bool oldIndependentSets = m_flags.test(DxvkContextFlag::GpIndependentSets); + // Set up vertex buffer strides for active bindings for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) { const uint32_t binding = m_state.gp.state.ilBindings[i].binding(); m_state.gp.state.ilBindings[i].setStride(m_state.vi.vertexStrides[binding]); } - + // Check which dynamic states need to be active. States that // are not dynamic will be invalidated in the command buffer. m_flags.clr(DxvkContextFlag::GpDynamicBlendConstants, DxvkContextFlag::GpDynamicDepthBias, DxvkContextFlag::GpDynamicDepthBounds, - DxvkContextFlag::GpDynamicStencilRef); + DxvkContextFlag::GpDynamicStencilRef, + DxvkContextFlag::GpIndependentSets); m_flags.set(m_state.gp.state.useDynamicBlendConstants() ? DxvkContextFlag::GpDynamicBlendConstants @@ -4533,8 +4540,16 @@ namespace dxvk { if (!m_state.gp.state.rs.depthBiasEnable()) m_cmd->cmdSetDepthBias(0.0f, 0.0f, 0.0f); + + m_flags.set(DxvkContextFlag::GpIndependentSets); } + // If necessary, dirty descriptor sets due to layout incompatibilities + bool newIndependentSets = m_flags.test(DxvkContextFlag::GpIndependentSets); + + if (newIndependentSets != oldIndependentSets) + m_descriptorState.dirtyStages(VK_SHADER_STAGE_ALL_GRAPHICS); + // Emit barrier based on pipeline properties, in order to avoid // accidental write-after-read hazards after the render pass. DxvkGlobalPipelineBarrier pipelineBarrier = m_state.gp.pipeline->getGlobalBarrier(m_state.gp.state); @@ -4570,6 +4585,9 @@ namespace dxvk { // For 64-bit applications, using templates is slower on some drivers. constexpr bool useDescriptorTemplates = env::is32BitHostPlatform(); + bool independentSets = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS + && m_flags.test(DxvkContextFlag::GpIndependentSets); + uint32_t layoutSetMask = layout->getSetMask(); uint32_t dirtySetMask = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ? m_descriptorState.getDirtyGraphicsSets() @@ -4752,7 +4770,7 @@ namespace dxvk { uint32_t firstSet = setIndex + 1 - bindCount; m_cmd->cmdBindDescriptorSets(BindPoint, - layout->getPipelineLayout(), + layout->getPipelineLayout(independentSets), firstSet, bindCount, &sets[firstSet], 0, nullptr); @@ -5147,9 +5165,11 @@ namespace dxvk { if (!pushConstRange.size) return; - + + // Push constants should be compatible between complete and + // independent layouts, so always ask for the complete one m_cmd->cmdPushConstants( - bindings->getPipelineLayout(), + bindings->getPipelineLayout(false), pushConstRange.stageFlags, pushConstRange.offset, pushConstRange.size, diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 762b1ab1e..9694369cd 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -39,6 +39,7 @@ namespace dxvk { GpDynamicDepthBias, ///< Depth bias is dynamic GpDynamicDepthBounds, ///< Depth bounds are dynamic GpDynamicStencilRef, ///< Stencil reference is dynamic + GpIndependentSets, ///< Graphics pipeline layout was created with independent sets CpDirtyPipeline, ///< Compute pipeline binding are out of date CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index fa1e1e77d..112011cb1 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -164,14 +164,14 @@ namespace dxvk { DxvkDescriptorSetMap* DxvkDescriptorPool::getSetMap( const DxvkBindingLayoutObjects* layout) { - auto pair = m_setMaps.find(layout->getPipelineLayout()); + auto pair = m_setMaps.find(layout->getPipelineLayout(false)); if (likely(pair != m_setMaps.end())) { return &pair->second; } auto iter = m_setMaps.emplace( std::piecewise_construct, - std::tuple(layout->getPipelineLayout()), + std::tuple(layout->getPipelineLayout(false)), std::tuple()); for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index e651f0c5b..80048c8eb 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -698,10 +698,12 @@ namespace dxvk { }}; VkPipelineLibraryCreateInfoKHR libInfo = { VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR }; - libInfo.libraryCount = libraries.size(); - libInfo.pLibraries = libraries.data(); + libInfo.libraryCount = libraries.size(); + libInfo.pLibraries = libraries.data(); VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; + info.layout = m_bindings->getPipelineLayout(true); + info.basePipelineIndex = -1; VkPipeline pipeline = VK_NULL_HANDLE; @@ -790,7 +792,7 @@ namespace dxvk { info.pDepthStencilState = &fsState.dsInfo; info.pColorBlendState = &foState.cbInfo; info.pDynamicState = &dyInfo; - info.layout = m_bindings->getPipelineLayout(); + info.layout = m_bindings->getPipelineLayout(false); info.basePipelineIndex = -1; if (!prState.tsInfo.patchControlPoints) diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index 407366358..895b685b3 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -323,29 +323,40 @@ namespace dxvk { } } + // Create pipeline layout objects VkPushConstantRange pushConst = m_layout.getPushConstantRange(); VkPipelineLayoutCreateInfo pipelineLayoutInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; pipelineLayoutInfo.setLayoutCount = setLayouts.size(); pipelineLayoutInfo.pSetLayouts = setLayouts.data(); - if (m_layout.getSetMask() != (1u << DxvkDescriptorSets::SetCount) - 1) - pipelineLayoutInfo.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT; - if (pushConst.stageFlags && pushConst.size) { pipelineLayoutInfo.pushConstantRangeCount = 1; pipelineLayoutInfo.pPushConstantRanges = &pushConst; } - if (vk->vkCreatePipelineLayout(vk->device(), &pipelineLayoutInfo, nullptr, &m_pipelineLayout)) - throw DxvkError("DxvkBindingLayoutObjects: Failed to create pipeline layout"); + // If the full set is defined, create a layout without INDEPENDENT_SET_BITS + if (m_layout.getSetMask() == (1u << DxvkDescriptorSets::SetCount) - 1) { + if (vk->vkCreatePipelineLayout(vk->device(), &pipelineLayoutInfo, nullptr, &m_completeLayout)) + throw DxvkError("DxvkBindingLayoutObjects: Failed to create pipeline layout"); + } + + // If graphics pipeline libraries are supported, also create a variand with the + // bit. It will be used to create shader-based libraries and link pipelines. + if (m_device->canUseGraphicsPipelineLibrary() && (m_layout.getStages() & VK_SHADER_STAGE_ALL_GRAPHICS)) { + pipelineLayoutInfo.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT; + + if (vk->vkCreatePipelineLayout(vk->device(), &pipelineLayoutInfo, nullptr, &m_independentLayout)) + throw DxvkError("DxvkBindingLayoutObjects: Failed to create pipeline layout"); + } } DxvkBindingLayoutObjects::~DxvkBindingLayoutObjects() { auto vk = m_device->vkd(); - vk->vkDestroyPipelineLayout(vk->device(), m_pipelineLayout, nullptr); + vk->vkDestroyPipelineLayout(vk->device(), m_completeLayout, nullptr); + vk->vkDestroyPipelineLayout(vk->device(), m_independentLayout, nullptr); } diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index ae4ad78f9..4cfcf50ff 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -304,6 +304,14 @@ namespace dxvk { return m_pushConst; } + /** + * \brief Queries shader stages + * \returns Shader stages + */ + VkShaderStageFlags getStages() const { + return m_stages; + } + /** * \brief Queries defined descriptor set layouts * @@ -433,10 +441,14 @@ namespace dxvk { /** * \brief Retrieves pipeline layout - * \returns Pipeline layout + * + * \param [in] independent Request INDEPENDENT_SETS_BIT + * \returns Pipeline layout handle */ - VkPipelineLayout getPipelineLayout() const { - return m_pipelineLayout; + VkPipelineLayout getPipelineLayout(bool independent) const { + return independent + ? m_independentLayout + : m_completeLayout; } /** @@ -468,9 +480,10 @@ namespace dxvk { DxvkDevice* m_device; DxvkBindingLayout m_layout; - VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; + VkPipelineLayout m_completeLayout = VK_NULL_HANDLE; + VkPipelineLayout m_independentLayout = VK_NULL_HANDLE; - uint32_t m_setMask = 0; + uint32_t m_setMask = 0; std::array m_bindingObjects = { }; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 361cbd9e1..4ad9d0631 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -547,7 +547,7 @@ namespace dxvk { info.pViewportState = &vpInfo; info.pRasterizationState = &rsInfo; info.pDynamicState = &dyInfo; - info.layout = m_layout->getPipelineLayout(); + info.layout = m_layout->getPipelineLayout(true); info.basePipelineIndex = -1; VkPipeline pipeline = VK_NULL_HANDLE; @@ -625,7 +625,7 @@ namespace dxvk { info.pStages = stageInfo.getStageInfos(); info.pDepthStencilState = &dsInfo; info.pDynamicState = &dyInfo; - info.layout = m_layout->getPipelineLayout(); + info.layout = m_layout->getPipelineLayout(true); info.basePipelineIndex = -1; if (m_shader && m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading)) @@ -650,7 +650,7 @@ namespace dxvk { // Compile the compute pipeline as normal VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; info.stage = *stageInfo.getStageInfos(); - info.layout = m_layout->getPipelineLayout(); + info.layout = m_layout->getPipelineLayout(false); info.basePipelineIndex = -1; VkPipeline pipeline = VK_NULL_HANDLE; From 5d340e48b406a6092cfa202aaba754a2aa9359e8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 7 Jul 2022 15:01:53 +0200 Subject: [PATCH 0164/1348] [dxvk] Improve pipeline state logging --- src/dxvk/dxvk_graphics.cpp | 169 ++++++++++++++++++++++++++++++++++--- 1 file changed, 155 insertions(+), 14 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 80048c8eb..3b837397d 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -1,4 +1,4 @@ -#include +#include #include "../util/util_time.h" @@ -989,22 +989,163 @@ namespace dxvk { void DxvkGraphicsPipeline::logPipelineState( LogLevel level, const DxvkGraphicsPipelineStateInfo& state) const { - if (m_shaders.vs != nullptr) Logger::log(level, str::format(" vs : ", m_shaders.vs ->debugName())); - if (m_shaders.tcs != nullptr) Logger::log(level, str::format(" tcs : ", m_shaders.tcs->debugName())); - if (m_shaders.tes != nullptr) Logger::log(level, str::format(" tes : ", m_shaders.tes->debugName())); - if (m_shaders.gs != nullptr) Logger::log(level, str::format(" gs : ", m_shaders.gs ->debugName())); - if (m_shaders.fs != nullptr) Logger::log(level, str::format(" fs : ", m_shaders.fs ->debugName())); + std::stringstream sstr; + sstr << "Shader stages:" << std::endl; + if (m_shaders.vs != nullptr) sstr << " vs : " << m_shaders.vs ->debugName() << std::endl; + if (m_shaders.tcs != nullptr) sstr << " tcs : " << m_shaders.tcs->debugName() << std::endl; + if (m_shaders.tes != nullptr) sstr << " tes : " << m_shaders.tes->debugName() << std::endl; + if (m_shaders.gs != nullptr) sstr << " gs : " << m_shaders.gs ->debugName() << std::endl; + if (m_shaders.fs != nullptr) sstr << " fs : " << m_shaders.fs ->debugName() << std::endl; - for (uint32_t i = 0; i < state.il.attributeCount(); i++) { - const auto& attr = state.ilAttributes[i]; - Logger::log(level, str::format(" attr ", i, " : location ", attr.location(), ", binding ", attr.binding(), ", format ", attr.format(), ", offset ", attr.offset())); - } + // Log input assembly state + VkPrimitiveTopology topology = state.ia.primitiveTopology(); + sstr << std::dec << "Primitive topology: " << topology; + + if (topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) + sstr << " [" << state.ia.patchVertexCount() << "]" << std::endl; + else + sstr << " [restart: " << (state.ia.primitiveRestart() ? "yes]" : "no]") << std::endl; + + // Log vertex input state for (uint32_t i = 0; i < state.il.bindingCount(); i++) { - const auto& bind = state.ilBindings[i]; - Logger::log(level, str::format(" binding ", i, " : binding ", bind.binding(), ", stride ", bind.stride(), ", rate ", bind.inputRate(), ", divisor ", bind.divisor())); + const auto& binding = state.ilBindings[i]; + sstr << "Vertex binding " << binding.binding() << " [" << binding.stride() << "]" << std::endl; + + for (uint32_t j = 0; j < state.il.attributeCount(); j++) { + const auto& attribute = state.ilAttributes[j]; + + if (attribute.binding() == binding.binding()) + sstr << " " << attribute.location() << " [" << attribute.offset() << "]: " << attribute.format() << std::endl; + } } - - // TODO log more pipeline state + + // Log rasterizer state + std::string cullMode; + + switch (state.rs.cullMode()) { + case VK_CULL_MODE_NONE: cullMode = "VK_CULL_MODE_NONE"; break; + case VK_CULL_MODE_BACK_BIT: cullMode = "VK_CULL_MODE_BACK_BIT"; break; + case VK_CULL_MODE_FRONT_BIT: cullMode = "VK_CULL_MODE_FRONT_BIT"; break; + case VK_CULL_MODE_FRONT_AND_BACK: cullMode = "VK_CULL_MODE_FRONT_AND_BACK"; break; + default: cullMode = str::format(state.rs.cullMode()); + } + + sstr << "Rasterizer state:" << std::endl + << " depth clip: " << (state.rs.depthClipEnable() ? "yes" : "no") << std::endl + << " depth bias: " << (state.rs.depthBiasEnable() ? "yes" : "no") << std::endl + << " polygon mode: " << state.rs.polygonMode() << std::endl + << " cull mode: " << cullMode << std::endl + << " front face: " << state.rs.frontFace() << std::endl + << " conservative: " << (state.rs.conservativeMode() == VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT ? "no" : "yes") << std::endl; + + // Log multisample state + VkSampleCountFlags sampleCount = VK_SAMPLE_COUNT_1_BIT; + + if (state.ms.sampleCount()) + sampleCount = state.ms.sampleCount(); + else if (state.rs.sampleCount()) + sampleCount = state.rs.sampleCount(); + + sstr << "Sample count: " << sampleCount << " [0x" << std::hex << state.ms.sampleMask() << std::dec << "]" << std::endl + << " alphaToCoverage: " << (state.ms.enableAlphaToCoverage() ? "yes" : "no") << std::endl; + + // Log depth-stencil state + sstr << "Depth test: "; + + if (state.ds.enableDepthTest()) + sstr << "yes [write: " << (state.ds.enableDepthWrite() ? "yes" : "no") << ", op: " << state.ds.depthCompareOp() << "]" << std::endl; + else + sstr << "no" << std::endl; + + sstr << "Depth bounds test: " << (state.ds.enableDepthBoundsTest() ? "yes" : "no") << std::endl + << "Stencil test: " << (state.ds.enableStencilTest() ? "yes" : "no") << std::endl; + + if (state.ds.enableStencilTest()) { + std::array states = {{ + state.dsFront.state(), + state.dsBack.state(), + }}; + + for (size_t i = 0; i < states.size(); i++) { + sstr << std::hex << (i ? " back: " : " front: ") + << "[c=0x" << states[i].compareMask << ",w=0x" << states[i].writeMask << ",op=" << states[i].compareOp << "] " + << "fail=" << states[i].failOp << ",pass=" << states[i].passOp << ",depthFail=" << states[i].depthFailOp << std::dec << std::endl; + } + } + + // Log logic op state + sstr << "Logic op: "; + + if (state.om.enableLogicOp()) + sstr << "yes [" << state.om.logicOp() << "]" << std::endl; + else + sstr << "no" << std::endl; + + // Log render target and blend state + auto depthFormat = state.rt.getDepthStencilFormat(); + auto depthFormatInfo = imageFormatInfo(depthFormat); + + VkImageAspectFlags writableAspects = depthFormat + ? (depthFormatInfo->aspectMask & ~state.rt.getDepthStencilReadOnlyAspects()) + : 0u; + + sstr << "Depth attachment: " << depthFormat; + + if (depthFormat) { + sstr << " [" + << ((writableAspects & VK_IMAGE_ASPECT_DEPTH_BIT) ? "d" : " ") + << ((writableAspects & VK_IMAGE_ASPECT_STENCIL_BIT) ? "s" : " ") + << "]" << std::endl; + } else { + sstr << std::endl; + } + + bool hasColorAttachments = false; + + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + auto format = state.rt.getColorFormat(i); + + if (format) { + if (!hasColorAttachments) { + sstr << "Color attachments:" << std::endl; + hasColorAttachments = true; + } + + const char* components = "rgba"; + const auto& blend = state.omBlend[i]; + const auto& swizzle = state.omSwizzle[i]; + + VkColorComponentFlags writeMask = blend.colorWriteMask(); + char r = (writeMask & (1u << swizzle.rIndex())) ? components[swizzle.rIndex()] : ' '; + char g = (writeMask & (1u << swizzle.gIndex())) ? components[swizzle.gIndex()] : ' '; + char b = (writeMask & (1u << swizzle.bIndex())) ? components[swizzle.bIndex()] : ' '; + char a = (writeMask & (1u << swizzle.aIndex())) ? components[swizzle.aIndex()] : ' '; + + sstr << " " << i << ": " << format << " [" << r << g << b << a << "] blend: "; + + if (blend.blendEnable()) + sstr << "yes (c:" << blend.srcColorBlendFactor() << "," << blend.dstColorBlendFactor() << "," << blend.colorBlendOp() + << ";a:" << blend.srcAlphaBlendFactor() << "," << blend.dstAlphaBlendFactor() << "," << blend.alphaBlendOp() << ")" << std::endl; + else + sstr << "no" << std::endl; + } + } + + // Log spec constants + bool hasSpecConstants = false; + + for (uint32_t i = 0; i < MaxNumSpecConstants; i++) { + if (state.sc.specConstants[i]) { + if (!hasSpecConstants) { + sstr << "Specialization constants:" << std::endl; + hasSpecConstants = true; + } + + sstr << " " << i << ": 0x" << std::hex << std::setw(8) << std::setfill('0') << state.sc.specConstants[i] << std::dec << std::endl; + } + } + + Logger::log(level, sstr.str()); } } From 5562ff44729db0994da59ffff0886ce6988ec4e8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 7 Jul 2022 15:02:46 +0200 Subject: [PATCH 0165/1348] [dxvk] Remove pipeline compile timing Meaningless now. --- src/dxvk/dxvk_graphics.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 3b837397d..eb2574df4 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -798,12 +798,6 @@ namespace dxvk { if (!prState.tsInfo.patchControlPoints) info.pTessellationState = nullptr; - // Time pipeline compilation for debugging purposes - dxvk::high_resolution_clock::time_point t0, t1; - - if (Logger::logLevel() <= LogLevel::Debug) - t0 = dxvk::high_resolution_clock::now(); - VkPipeline pipeline = VK_NULL_HANDLE; if (vk->vkCreateGraphicsPipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { Logger::err("DxvkGraphicsPipeline: Failed to compile pipeline"); @@ -811,12 +805,6 @@ namespace dxvk { return VK_NULL_HANDLE; } - if (Logger::logLevel() <= LogLevel::Debug) { - t1 = dxvk::high_resolution_clock::now(); - auto td = std::chrono::duration_cast(t1 - t0); - Logger::debug(str::format("DxvkGraphicsPipeline: Finished in ", td.count(), " ms")); - } - return pipeline; } From 498444f1a8926f44f0bd8a94272f815f720524dc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 7 Jul 2022 15:29:10 +0200 Subject: [PATCH 0166/1348] [dxvk] Reuse linked base pipelines if possible No reason to create identical pipelines multiple times. --- src/dxvk/dxvk_graphics.cpp | 23 +++++++++++++++++++---- src/dxvk/dxvk_graphics.h | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index eb2574df4..089c84c6e 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -494,10 +494,11 @@ namespace dxvk { DxvkGraphicsPipeline::~DxvkGraphicsPipeline() { - for (const auto& instance : m_pipelines) { - this->destroyPipeline(instance.baseHandle.load()); + for (const auto& instance : m_pipelines) this->destroyPipeline(instance.fastHandle.load()); - } + + for (const auto& instance : m_basePipelines) + this->destroyPipeline(instance.handle); } @@ -610,7 +611,7 @@ namespace dxvk { key.foLibrary = m_manager->createFragmentOutputLibrary(foState); key.args.depthClipEnable = state.rs.depthClipEnable(); - baseHandle = this->createBasePipeline(key); + baseHandle = this->createBaseInstance(key)->handle; } else { // Create optimized variant right away, no choice fastHandle = this->createOptimizedPipeline(state); @@ -632,6 +633,20 @@ namespace dxvk { } + DxvkGraphicsPipelineBaseInstance* DxvkGraphicsPipeline::createBaseInstance( + const DxvkGraphicsPipelineBaseInstanceKey& key) { + for (auto& instance : m_basePipelines) { + if (instance.key.viLibrary == key.viLibrary + && instance.key.foLibrary == key.foLibrary + && instance.key.args == key.args) + return &instance; + } + + VkPipeline handle = createBasePipeline(key); + return &(*m_basePipelines.emplace(key, handle)); + } + + bool DxvkGraphicsPipeline::canCreateBasePipeline( const DxvkGraphicsPipelineStateInfo& state) const { if (!m_vsLibrary || !m_fsLibrary) diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 9201e8bd2..413013d93 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -263,12 +263,35 @@ namespace dxvk { }; + /** + * \brief Base instance key + * + * Stores the libraries and arguments used to + * compile a base pipeline. + */ struct DxvkGraphicsPipelineBaseInstanceKey { - const DxvkGraphicsPipelineVertexInputLibrary* viLibrary; - const DxvkGraphicsPipelineFragmentOutputLibrary* foLibrary; + const DxvkGraphicsPipelineVertexInputLibrary* viLibrary = nullptr; + const DxvkGraphicsPipelineFragmentOutputLibrary* foLibrary = nullptr; DxvkShaderPipelineLibraryCompileArgs args; }; + + /** + * \brief Base pipeline instance + * + * Stores the key and handle of a base pipeline. + */ + struct DxvkGraphicsPipelineBaseInstance { + DxvkGraphicsPipelineBaseInstance() { } + DxvkGraphicsPipelineBaseInstance( + const DxvkGraphicsPipelineBaseInstanceKey& key_, + VkPipeline handle_) + : key(key_), handle(handle_) { } + + DxvkGraphicsPipelineBaseInstanceKey key; + VkPipeline handle = VK_NULL_HANDLE; + }; + /** * \brief Graphics pipeline @@ -386,8 +409,9 @@ namespace dxvk { // List of pipeline instances, shared between threads alignas(CACHE_LINE_SIZE) - dxvk::mutex m_mutex; - sync::List m_pipelines; + dxvk::mutex m_mutex; + sync::List m_pipelines; + sync::List m_basePipelines; DxvkGraphicsPipelineInstance* createInstance( const DxvkGraphicsPipelineStateInfo& state); @@ -395,6 +419,9 @@ namespace dxvk { DxvkGraphicsPipelineInstance* findInstance( const DxvkGraphicsPipelineStateInfo& state); + DxvkGraphicsPipelineBaseInstance* createBaseInstance( + const DxvkGraphicsPipelineBaseInstanceKey& key); + bool canCreateBasePipeline( const DxvkGraphicsPipelineStateInfo& state) const; From 4535fdc336aacd42d837fba1ef8640eb4c9b7b3c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jul 2022 11:33:07 +0200 Subject: [PATCH 0167/1348] [dxvk] Pass pipeline manager to pipeline library constructor --- src/dxvk/dxvk_compute.cpp | 2 +- src/dxvk/dxvk_graphics.cpp | 4 ++-- src/dxvk/dxvk_pipemanager.cpp | 8 ++++---- src/dxvk/dxvk_pipemanager.h | 1 + src/dxvk/dxvk_shader.cpp | 30 +++++++++++++++++------------- src/dxvk/dxvk_shader.h | 16 +++++++++------- 6 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 9341f82cd..0720386ac 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -41,7 +41,7 @@ namespace dxvk { // pipeline variant unconditionally since there is no state for us // to worry about other than specialization constants if (unlikely(!m_libraryHandle)) { - m_libraryHandle = m_library->getPipelineHandle(m_cache->handle(), + m_libraryHandle = m_library->getPipelineHandle( DxvkShaderPipelineLibraryCompileArgs()); m_stats->numComputePipelines += 1; } diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 089c84c6e..bf42de826 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -707,8 +707,8 @@ namespace dxvk { std::array libraries = {{ key.viLibrary->getHandle(), - m_vsLibrary->getPipelineHandle(m_cache->handle(), key.args), - m_fsLibrary->getPipelineHandle(m_cache->handle(), key.args), + m_vsLibrary->getPipelineHandle(key.args), + m_fsLibrary->getPipelineHandle(key.args), key.foLibrary->getHandle(), }}; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index a1392e0c9..87e5c0ff5 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -144,7 +144,7 @@ namespace dxvk { if (l) { if (l->pipelineLibrary) - l->pipelineLibrary->compilePipeline(m_cache->handle()); + l->pipelineLibrary->compilePipeline(); m_pendingTasks -= 1; } @@ -172,7 +172,7 @@ namespace dxvk { if (m_device->canUseGraphicsPipelineLibrary()) { auto library = createNullFsPipelineLibrary(); - library->compilePipeline(m_cache.handle()); + library->compilePipeline(); } } @@ -353,7 +353,7 @@ namespace dxvk { auto iter = m_shaderLibraries.emplace( std::piecewise_construct, std::tuple(key), - std::tuple(m_device, shader.ptr(), layout)); + std::tuple(m_device, this, shader.ptr(), layout)); return &iter.first->second; } @@ -366,7 +366,7 @@ namespace dxvk { auto iter = m_shaderLibraries.emplace( std::piecewise_construct, std::tuple(), - std::tuple(m_device, nullptr, layout)); + std::tuple(m_device, this, nullptr, layout)); return &iter.first->second; } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 154fbb0d7..8a9ad2245 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -138,6 +138,7 @@ namespace dxvk { class DxvkPipelineManager { friend class DxvkComputePipeline; friend class DxvkGraphicsPipeline; + friend class DxvkShaderPipelineLibrary; public: DxvkPipelineManager( diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 4ad9d0631..295897dc6 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -1,4 +1,5 @@ #include "dxvk_device.h" +#include "dxvk_pipemanager.h" #include "dxvk_shader.h" #include @@ -426,9 +427,14 @@ namespace dxvk { DxvkShaderPipelineLibrary::DxvkShaderPipelineLibrary( const DxvkDevice* device, + DxvkPipelineManager* manager, const DxvkShader* shader, const DxvkBindingLayoutObjects* layout) - : m_device(device), m_shader(shader), m_layout(layout) { + : m_device (device), + m_cache (&manager->m_cache), + m_stats (&manager->m_stats), + m_shader (shader), + m_layout (layout) { } @@ -442,7 +448,6 @@ namespace dxvk { VkPipeline DxvkShaderPipelineLibrary::getPipelineHandle( - VkPipelineCache cache, const DxvkShaderPipelineLibraryCompileArgs& args) { std::lock_guard lock(m_mutex); @@ -460,15 +465,15 @@ namespace dxvk { switch (stage) { case VK_SHADER_STAGE_VERTEX_BIT: - pipeline = compileVertexShaderPipeline(cache, args); + pipeline = compileVertexShaderPipeline(args); break; case VK_SHADER_STAGE_FRAGMENT_BIT: - pipeline = compileFragmentShaderPipeline(cache); + pipeline = compileFragmentShaderPipeline(); break; case VK_SHADER_STAGE_COMPUTE_BIT: - pipeline = compileComputeShaderPipeline(cache); + pipeline = compileComputeShaderPipeline(); break; default: @@ -480,16 +485,15 @@ namespace dxvk { } - void DxvkShaderPipelineLibrary::compilePipeline(VkPipelineCache cache) { + void DxvkShaderPipelineLibrary::compilePipeline() { // Just compile the pipeline with default args. Implicitly skips // this step if another thread has compiled the pipeline in the // meantime, in order to avoid duplicate work. - getPipelineHandle(cache, DxvkShaderPipelineLibraryCompileArgs()); + getPipelineHandle(DxvkShaderPipelineLibraryCompileArgs()); } VkPipeline DxvkShaderPipelineLibrary::compileVertexShaderPipeline( - VkPipelineCache cache, const DxvkShaderPipelineLibraryCompileArgs& args) { auto vk = m_device->vkd(); @@ -552,14 +556,14 @@ namespace dxvk { VkPipeline pipeline = VK_NULL_HANDLE; - if (vk->vkCreateGraphicsPipelines(vk->device(), cache, 1, &info, nullptr, &pipeline)) + if (vk->vkCreateGraphicsPipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline)) throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); return pipeline; } - VkPipeline DxvkShaderPipelineLibrary::compileFragmentShaderPipeline(VkPipelineCache cache) { + VkPipeline DxvkShaderPipelineLibrary::compileFragmentShaderPipeline() { auto vk = m_device->vkd(); // Initialize code buffer. As a special case, it is possible that @@ -633,14 +637,14 @@ namespace dxvk { VkPipeline pipeline = VK_NULL_HANDLE; - if (vk->vkCreateGraphicsPipelines(vk->device(), cache, 1, &info, nullptr, &pipeline)) + if (vk->vkCreateGraphicsPipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline)) throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); return pipeline; } - VkPipeline DxvkShaderPipelineLibrary::compileComputeShaderPipeline(VkPipelineCache cache) { + VkPipeline DxvkShaderPipelineLibrary::compileComputeShaderPipeline() { auto vk = m_device->vkd(); DxvkShaderStageInfo stageInfo(m_device); @@ -655,7 +659,7 @@ namespace dxvk { VkPipeline pipeline = VK_NULL_HANDLE; - if (vk->vkCreateComputePipelines(vk->device(), cache, 1, &info, nullptr, &pipeline)) + if (vk->vkCreateComputePipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline)) throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); return pipeline; diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 1f5592158..605e53243 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -4,6 +4,7 @@ #include "dxvk_include.h" #include "dxvk_limits.h" +#include "dxvk_pipecache.h" #include "dxvk_pipelayout.h" #include "dxvk_shader_key.h" @@ -14,6 +15,8 @@ namespace dxvk { class DxvkShader; class DxvkShaderModule; + class DxvkPipelineManager; + struct DxvkPipelineStats; /** * \brief Built-in specialization constants @@ -335,6 +338,7 @@ namespace dxvk { DxvkShaderPipelineLibrary( const DxvkDevice* device, + DxvkPipelineManager* manager, const DxvkShader* shader, const DxvkBindingLayoutObjects* layout); @@ -345,12 +349,10 @@ namespace dxvk { * * Either returns an already compiled pipeline library object, or * performs the compilation step if that has not happened yet. - * \param [in] cache Pipeline cache handle * \param [in] args Compile arguments * \returns Vulkan pipeline handle */ VkPipeline getPipelineHandle( - VkPipelineCache cache, const DxvkShaderPipelineLibraryCompileArgs& args); /** @@ -359,13 +361,14 @@ namespace dxvk { * This is meant to be called from a worker thread in * order to reduce the amount of work done on the app's * main thread. - * \param [in] cache Pipeline cache handle */ - void compilePipeline(VkPipelineCache cache); + void compilePipeline(); private: const DxvkDevice* m_device; + DxvkPipelineCache* m_cache; + DxvkPipelineStats* m_stats; const DxvkShader* m_shader; const DxvkBindingLayoutObjects* m_layout; @@ -374,12 +377,11 @@ namespace dxvk { VkPipeline m_pipelineNoDepthClip = VK_NULL_HANDLE; VkPipeline compileVertexShaderPipeline( - VkPipelineCache cache, const DxvkShaderPipelineLibraryCompileArgs& args); - VkPipeline compileFragmentShaderPipeline(VkPipelineCache cache); + VkPipeline compileFragmentShaderPipeline(); - VkPipeline compileComputeShaderPipeline(VkPipelineCache cache); + VkPipeline compileComputeShaderPipeline(); }; From 35529830842ec4657460ce03deb6512ec0b70e07 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jul 2022 11:33:45 +0200 Subject: [PATCH 0168/1348] [dxvk] Add stat counter for pipeline libraries --- src/dxvk/dxvk_device.cpp | 1 + src/dxvk/dxvk_pipemanager.cpp | 3 ++- src/dxvk/dxvk_pipemanager.h | 2 ++ src/dxvk/dxvk_shader.cpp | 5 ++++- src/dxvk/dxvk_stats.h | 1 + 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 74b2d0b9a..76fed23ed 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -157,6 +157,7 @@ namespace dxvk { DxvkStatCounters result; result.setCtr(DxvkStatCounter::PipeCountGraphics, pipe.numGraphicsPipelines); + result.setCtr(DxvkStatCounter::PipeCountLibrary, pipe.numGraphicsLibraries); result.setCtr(DxvkStatCounter::PipeCountCompute, pipe.numComputePipelines); result.setCtr(DxvkStatCounter::PipeCompilerBusy, m_objects.pipelineManager().isCompilingShaders()); result.setCtr(DxvkStatCounter::GpuIdleTicks, m_submissionQueue.gpuIdleTicks()); diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 87e5c0ff5..a116af9cb 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -294,8 +294,9 @@ namespace dxvk { DxvkPipelineCount DxvkPipelineManager::getPipelineCount() const { DxvkPipelineCount result; - result.numComputePipelines = m_stats.numComputePipelines.load(); result.numGraphicsPipelines = m_stats.numGraphicsPipelines.load(); + result.numGraphicsLibraries = m_stats.numGraphicsLibraries.load(); + result.numComputePipelines = m_stats.numComputePipelines.load(); return result; } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 8a9ad2245..0cc5150dc 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -21,6 +21,7 @@ namespace dxvk { */ struct DxvkPipelineCount { uint32_t numGraphicsPipelines; + uint32_t numGraphicsLibraries; uint32_t numComputePipelines; }; @@ -29,6 +30,7 @@ namespace dxvk { */ struct DxvkPipelineStats { std::atomic numGraphicsPipelines = { 0u }; + std::atomic numGraphicsLibraries = { 0u }; std::atomic numComputePipelines = { 0u }; }; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 295897dc6..b3c640127 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -478,9 +478,12 @@ namespace dxvk { default: // Should be unreachable - pipeline = VK_NULL_HANDLE; + return VK_NULL_HANDLE; } + if (args == DxvkShaderPipelineLibraryCompileArgs()) + m_stats->numGraphicsLibraries += 1; + return pipeline; } diff --git a/src/dxvk/dxvk_stats.h b/src/dxvk/dxvk_stats.h index 4d274bba4..211570f52 100644 --- a/src/dxvk/dxvk_stats.h +++ b/src/dxvk/dxvk_stats.h @@ -16,6 +16,7 @@ namespace dxvk { CmdRenderPassCount, ///< Number of render passes CmdBarrierCount, ///< Number of pipeline barriers PipeCountGraphics, ///< Number of graphics pipelines + PipeCountLibrary, ///< Number of graphics shader libraries PipeCountCompute, ///< Number of compute pipelines PipeCompilerBusy, ///< Boolean indicating compiler activity QueueSubmitCount, ///< Number of command buffer submissions From 645886db8d977e73dbe12e62caa90814d99e9c04 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jul 2022 11:33:58 +0200 Subject: [PATCH 0169/1348] [hud] Display pipeline library count in HUD --- src/dxvk/hud/dxvk_hud_item.cpp | 16 +++++++++++++++- src/dxvk/hud/dxvk_hud_item.h | 5 +++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/dxvk/hud/dxvk_hud_item.cpp b/src/dxvk/hud/dxvk_hud_item.cpp index 59ca3ffe0..4b7b0ea54 100644 --- a/src/dxvk/hud/dxvk_hud_item.cpp +++ b/src/dxvk/hud/dxvk_hud_item.cpp @@ -466,6 +466,7 @@ namespace dxvk::hud { DxvkStatCounters counters = m_device->getStatCounters(); m_graphicsPipelines = counters.getCtr(DxvkStatCounter::PipeCountGraphics); + m_graphicsLibraries = counters.getCtr(DxvkStatCounter::PipeCountLibrary); m_computePipelines = counters.getCtr(DxvkStatCounter::PipeCountCompute); } @@ -483,7 +484,20 @@ namespace dxvk::hud { { position.x + 240.0f, position.y }, { 1.0f, 1.0f, 1.0f, 1.0f }, str::format(m_graphicsPipelines)); - + + if (m_graphicsLibraries) { + position.y += 20.0f; + renderer.drawText(16.0f, + { position.x, position.y }, + { 1.0f, 0.25f, 1.0f, 1.0f }, + "Graphics shaders:"); + + renderer.drawText(16.0f, + { position.x + 240.0f, position.y }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + str::format(m_graphicsLibraries)); + } + position.y += 20.0f; renderer.drawText(16.0f, { position.x, position.y }, diff --git a/src/dxvk/hud/dxvk_hud_item.h b/src/dxvk/hud/dxvk_hud_item.h index a868c9293..b91f4d710 100644 --- a/src/dxvk/hud/dxvk_hud_item.h +++ b/src/dxvk/hud/dxvk_hud_item.h @@ -330,8 +330,9 @@ namespace dxvk::hud { Rc m_device; - uint64_t m_graphicsPipelines = 0; - uint64_t m_computePipelines = 0; + uint64_t m_graphicsPipelines = 0; + uint64_t m_graphicsLibraries = 0; + uint64_t m_computePipelines = 0; }; From f4fd8c6c65d7b03543043c54ef133f27aa70d05a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jul 2022 19:25:19 +0200 Subject: [PATCH 0170/1348] [dxvk] Remove in-memory pipeline cache Doesn't really do much and only prevents Nvidia's disk cache from working on 515.49.06 drivers. --- src/dxvk/dxvk_compute.cpp | 3 +-- src/dxvk/dxvk_compute.h | 2 -- src/dxvk/dxvk_device.h | 1 - src/dxvk/dxvk_graphics.cpp | 15 ++++++-------- src/dxvk/dxvk_graphics.h | 8 ++------ src/dxvk/dxvk_pipecache.cpp | 24 ----------------------- src/dxvk/dxvk_pipecache.h | 37 ----------------------------------- src/dxvk/dxvk_pipemanager.cpp | 11 ++++------- src/dxvk/dxvk_pipemanager.h | 5 +---- src/dxvk/dxvk_shader.cpp | 7 +++---- src/dxvk/dxvk_shader.h | 2 -- src/dxvk/meson.build | 1 - 12 files changed, 17 insertions(+), 99 deletions(-) delete mode 100644 src/dxvk/dxvk_pipecache.cpp delete mode 100644 src/dxvk/dxvk_pipecache.h diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 0720386ac..5e83fbe6e 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -17,7 +17,6 @@ namespace dxvk { DxvkBindingLayoutObjects* layout, DxvkShaderPipelineLibrary* library) : m_device (device), - m_cache (&pipeMgr->m_cache), m_stateCache (&pipeMgr->m_stateCache), m_stats (&pipeMgr->m_stats), m_library (library), @@ -130,7 +129,7 @@ namespace dxvk { VkPipeline pipeline = VK_NULL_HANDLE; if (vk->vkCreateComputePipelines(vk->device(), - m_cache->handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { + VK_NULL_HANDLE, 1, &info, nullptr, &pipeline) != VK_SUCCESS) { Logger::err("DxvkComputePipeline: Failed to compile pipeline"); Logger::err(str::format(" cs : ", m_shaders.cs->debugName())); return VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index 8dcfc3142..a921e7d63 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -6,7 +6,6 @@ #include "dxvk_bind_mask.h" #include "dxvk_graphics_state.h" -#include "dxvk_pipecache.h" #include "dxvk_pipelayout.h" #include "dxvk_resource.h" #include "dxvk_shader.h" @@ -114,7 +113,6 @@ namespace dxvk { private: DxvkDevice* m_device; - DxvkPipelineCache* m_cache; DxvkStateCache* m_stateCache; DxvkPipelineStats* m_stats; diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 361640548..29c7a1f28 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -13,7 +13,6 @@ #include "dxvk_meta_clear.h" #include "dxvk_objects.h" #include "dxvk_options.h" -#include "dxvk_pipecache.h" #include "dxvk_pipemanager.h" #include "dxvk_queue.h" #include "dxvk_recycler.h" diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index bf42de826..743c8a1ae 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -137,8 +137,7 @@ namespace dxvk { DxvkGraphicsPipelineVertexInputLibrary::DxvkGraphicsPipelineVertexInputLibrary( DxvkDevice* device, - const DxvkGraphicsPipelineVertexInputState& state, - VkPipelineCache cache) + const DxvkGraphicsPipelineVertexInputState& state) : m_device(device) { auto vk = m_device->vkd(); @@ -152,7 +151,7 @@ namespace dxvk { info.basePipelineIndex = -1; VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), - cache, 1, &info, nullptr, &m_pipeline); + VK_NULL_HANDLE, 1, &info, nullptr, &m_pipeline); if (vr) throw DxvkError("Failed to create vertex input pipeline library"); @@ -341,8 +340,7 @@ namespace dxvk { DxvkGraphicsPipelineFragmentOutputLibrary::DxvkGraphicsPipelineFragmentOutputLibrary( DxvkDevice* device, - const DxvkGraphicsPipelineFragmentOutputState& state, - VkPipelineCache cache) + const DxvkGraphicsPipelineFragmentOutputState& state) : m_device(device) { auto vk = m_device->vkd(); @@ -368,7 +366,7 @@ namespace dxvk { info.basePipelineIndex = -1; VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), - cache, 1, &info, nullptr, &m_pipeline); + VK_NULL_HANDLE, 1, &info, nullptr, &m_pipeline); if (vr) throw DxvkError("Failed to create vertex input pipeline library"); @@ -467,7 +465,6 @@ namespace dxvk { : m_device (device), m_manager (pipeMgr), m_workers (&pipeMgr->m_workers), - m_cache (&pipeMgr->m_cache), m_stateCache (&pipeMgr->m_stateCache), m_stats (&pipeMgr->m_stats), m_shaders (std::move(shaders)), @@ -722,7 +719,7 @@ namespace dxvk { VkPipeline pipeline = VK_NULL_HANDLE; - if ((vk->vkCreateGraphicsPipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline))) + if ((vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline))) Logger::err("DxvkGraphicsPipeline: Failed to create base pipeline"); return pipeline; @@ -814,7 +811,7 @@ namespace dxvk { info.pTessellationState = nullptr; VkPipeline pipeline = VK_NULL_HANDLE; - if (vk->vkCreateGraphicsPipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline) != VK_SUCCESS) { + if (vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline) != VK_SUCCESS) { Logger::err("DxvkGraphicsPipeline: Failed to compile pipeline"); this->logPipelineState(LogLevel::Error, state); return VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 413013d93..d0abc0604 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -7,7 +7,6 @@ #include "dxvk_bind_mask.h" #include "dxvk_constant_state.h" #include "dxvk_graphics_state.h" -#include "dxvk_pipecache.h" #include "dxvk_pipelayout.h" #include "dxvk_renderpass.h" #include "dxvk_resource.h" @@ -62,8 +61,7 @@ namespace dxvk { DxvkGraphicsPipelineVertexInputLibrary( DxvkDevice* device, - const DxvkGraphicsPipelineVertexInputState& state, - VkPipelineCache cache); + const DxvkGraphicsPipelineVertexInputState& state); ~DxvkGraphicsPipelineVertexInputLibrary(); @@ -122,8 +120,7 @@ namespace dxvk { DxvkGraphicsPipelineFragmentOutputLibrary( DxvkDevice* device, - const DxvkGraphicsPipelineFragmentOutputState& state, - VkPipelineCache cache); + const DxvkGraphicsPipelineFragmentOutputState& state); ~DxvkGraphicsPipelineFragmentOutputLibrary(); @@ -392,7 +389,6 @@ namespace dxvk { DxvkDevice* m_device; DxvkPipelineManager* m_manager; DxvkPipelineWorkers* m_workers; - DxvkPipelineCache* m_cache; DxvkStateCache* m_stateCache; DxvkPipelineStats* m_stats; diff --git a/src/dxvk/dxvk_pipecache.cpp b/src/dxvk/dxvk_pipecache.cpp deleted file mode 100644 index 8029e225a..000000000 --- a/src/dxvk/dxvk_pipecache.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "dxvk_pipecache.h" -#include "dxvk_device.h" - -namespace dxvk { - - DxvkPipelineCache::DxvkPipelineCache(DxvkDevice* device) - : m_device(device) { - auto vk = m_device->vkd(); - - // It's not critical if this fails since this is only an in-memory cache - VkPipelineCacheCreateInfo info = { VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; - - if (vk->vkCreatePipelineCache(vk->device(), &info, nullptr, &m_handle)) - Logger::err("DxvkPipelineCache: Failed to create cache"); - } - - - DxvkPipelineCache::~DxvkPipelineCache() { - auto vk = m_device->vkd(); - - vk->vkDestroyPipelineCache(vk->device(), m_handle, nullptr); - } - -} diff --git a/src/dxvk/dxvk_pipecache.h b/src/dxvk/dxvk_pipecache.h deleted file mode 100644 index 78e9a7981..000000000 --- a/src/dxvk/dxvk_pipecache.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "dxvk_include.h" - -namespace dxvk { - - class DxvkDevice; - - /** - * \brief Pipeline cache - * - * Allows the Vulkan implementation to - * re-use previously compiled pipelines. - */ - class DxvkPipelineCache { - - public: - - DxvkPipelineCache(DxvkDevice* device); - ~DxvkPipelineCache(); - - /** - * \brief Pipeline cache handle - * \returns Pipeline cache handle - */ - VkPipelineCache handle() const { - return m_handle; - } - - private: - - DxvkDevice* m_device; - VkPipelineCache m_handle = VK_NULL_HANDLE; - - }; - -} diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index a116af9cb..d14469d51 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -7,9 +7,7 @@ namespace dxvk { DxvkPipelineWorkers::DxvkPipelineWorkers( - DxvkDevice* device, - DxvkPipelineCache* cache) - : m_cache(cache) { + DxvkDevice* device) { // Use a reasonably large number of threads for compiling, but // leave some cores to the application to avoid excessive stutter uint32_t numCpuCores = dxvk::thread::hardware_concurrency(); @@ -164,8 +162,7 @@ namespace dxvk { DxvkPipelineManager::DxvkPipelineManager( DxvkDevice* device) : m_device (device), - m_cache (device), - m_workers (device, &m_cache), + m_workers (device), m_stateCache(device, this, &m_workers) { Logger::info(str::format("DXVK: Graphics pipeline libraries ", (m_device->canUseGraphicsPipelineLibrary() ? "supported" : "not supported"))); @@ -260,7 +257,7 @@ namespace dxvk { auto iter = m_vertexInputLibraries.emplace( std::piecewise_construct, std::tuple(state), - std::tuple(m_device, state, m_cache.handle())); + std::tuple(m_device, state)); return &iter.first->second; } @@ -276,7 +273,7 @@ namespace dxvk { auto iter = m_fragmentOutputLibraries.emplace( std::piecewise_construct, std::tuple(state), - std::tuple(m_device, state, m_cache.handle())); + std::tuple(m_device, state)); return &iter.first->second; } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 0cc5150dc..6a0bccd5f 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -45,8 +45,7 @@ namespace dxvk { public: DxvkPipelineWorkers( - DxvkDevice* device, - DxvkPipelineCache* cache); + DxvkDevice* device); ~DxvkPipelineWorkers(); @@ -108,7 +107,6 @@ namespace dxvk { DxvkShaderPipelineLibrary* pipelineLibrary; }; - DxvkPipelineCache* m_cache; std::atomic m_pendingTasks = { 0ull }; dxvk::mutex m_queueLock; @@ -223,7 +221,6 @@ namespace dxvk { private: DxvkDevice* m_device; - DxvkPipelineCache m_cache; DxvkPipelineWorkers m_workers; DxvkStateCache m_stateCache; DxvkPipelineStats m_stats; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index b3c640127..ef55cee3a 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -431,7 +431,6 @@ namespace dxvk { const DxvkShader* shader, const DxvkBindingLayoutObjects* layout) : m_device (device), - m_cache (&manager->m_cache), m_stats (&manager->m_stats), m_shader (shader), m_layout (layout) { @@ -559,7 +558,7 @@ namespace dxvk { VkPipeline pipeline = VK_NULL_HANDLE; - if (vk->vkCreateGraphicsPipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline)) + if (vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline)) throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); return pipeline; @@ -640,7 +639,7 @@ namespace dxvk { VkPipeline pipeline = VK_NULL_HANDLE; - if (vk->vkCreateGraphicsPipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline)) + if (vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline)) throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); return pipeline; @@ -662,7 +661,7 @@ namespace dxvk { VkPipeline pipeline = VK_NULL_HANDLE; - if (vk->vkCreateComputePipelines(vk->device(), m_cache->handle(), 1, &info, nullptr, &pipeline)) + if (vk->vkCreateComputePipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline)) throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); return pipeline; diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 605e53243..4ccc7b618 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -4,7 +4,6 @@ #include "dxvk_include.h" #include "dxvk_limits.h" -#include "dxvk_pipecache.h" #include "dxvk_pipelayout.h" #include "dxvk_shader_key.h" @@ -367,7 +366,6 @@ namespace dxvk { private: const DxvkDevice* m_device; - DxvkPipelineCache* m_cache; DxvkPipelineStats* m_stats; const DxvkShader* m_shader; const DxvkBindingLayoutObjects* m_layout; diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index e49c49b9e..b82be6aac 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -91,7 +91,6 @@ dxvk_src = files([ 'dxvk_openvr.cpp', 'dxvk_openxr.cpp', 'dxvk_options.cpp', - 'dxvk_pipecache.cpp', 'dxvk_pipelayout.cpp', 'dxvk_pipemanager.cpp', 'dxvk_queue.cpp', From 04545ab00a944ebbc2096fef710c409f2c32f98b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jul 2022 13:53:49 +0200 Subject: [PATCH 0171/1348] [dxvk] Enable VK_EXT_pipeline_creation_cache_control if supported --- src/dxvk/dxvk_adapter.cpp | 23 +++++++++++++++++++++-- src/dxvk/dxvk_device_info.h | 1 + src/dxvk/dxvk_extensions.h | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 1182829b1..320111ac0 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -242,6 +242,8 @@ namespace dxvk { || !required.extMemoryPriority.memoryPriority) && (m_deviceFeatures.extNonSeamlessCubeMap.nonSeamlessCubeMap || !required.extNonSeamlessCubeMap.nonSeamlessCubeMap) + && (m_deviceFeatures.extPipelineCreationCacheControl.pipelineCreationCacheControl + || !required.extPipelineCreationCacheControl.pipelineCreationCacheControl) && (m_deviceFeatures.extRobustness2.robustBufferAccess2 || !required.extRobustness2.robustBufferAccess2) && (m_deviceFeatures.extRobustness2.robustImageAccess2 @@ -267,7 +269,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -281,6 +283,7 @@ namespace dxvk { &devExtensions.extMemoryBudget, &devExtensions.extMemoryPriority, &devExtensions.extNonSeamlessCubeMap, + &devExtensions.extPipelineCreationCacheControl, &devExtensions.extRobustness2, &devExtensions.extShaderDemoteToHelperInvocation, &devExtensions.extShaderStencilExport, @@ -334,7 +337,11 @@ namespace dxvk { // Enable additional device features if supported enabledFeatures.extExtendedDynamicState.extendedDynamicState = VK_TRUE; - enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary; + enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = + m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary; + + enabledFeatures.extPipelineCreationCacheControl.pipelineCreationCacheControl = + m_deviceFeatures.extPipelineCreationCacheControl.pipelineCreationCacheControl; enabledFeatures.ext4444Formats.formatA4B4G4R4 = m_deviceFeatures.ext4444Formats.formatA4B4G4R4; enabledFeatures.ext4444Formats.formatA4R4G4B4 = m_deviceFeatures.ext4444Formats.formatA4R4G4B4; @@ -401,6 +408,11 @@ namespace dxvk { enabledFeatures.extNonSeamlessCubeMap.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extNonSeamlessCubeMap); } + if (devExtensions.extPipelineCreationCacheControl) { + enabledFeatures.extPipelineCreationCacheControl.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT; + enabledFeatures.extPipelineCreationCacheControl.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extPipelineCreationCacheControl); + } + if (devExtensions.extShaderDemoteToHelperInvocation) { enabledFeatures.extShaderDemoteToHelperInvocation.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT; enabledFeatures.extShaderDemoteToHelperInvocation.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extShaderDemoteToHelperInvocation); @@ -726,6 +738,11 @@ namespace dxvk { m_deviceFeatures.extNonSeamlessCubeMap.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extNonSeamlessCubeMap); } + if (m_deviceExtensions.supports(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME)) { + m_deviceFeatures.extPipelineCreationCacheControl.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT; + m_deviceFeatures.extPipelineCreationCacheControl.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extPipelineCreationCacheControl); + } + if (m_deviceExtensions.supports(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME)) { m_deviceFeatures.extRobustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; m_deviceFeatures.extRobustness2.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extRobustness2); @@ -840,6 +857,8 @@ namespace dxvk { "\n memoryPriority : ", features.extMemoryPriority.memoryPriority ? "1" : "0", "\n", VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, "\n nonSeamlessCubeMap : ", features.extNonSeamlessCubeMap.nonSeamlessCubeMap ? "1" : "0", + "\n", VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME, + "\n pipelineCreationCacheControl : ", features.extPipelineCreationCacheControl.pipelineCreationCacheControl ? "1" : "0", "\n", VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, "\n robustBufferAccess2 : ", features.extRobustness2.robustBufferAccess2 ? "1" : "0", "\n robustImageAccess2 : ", features.extRobustness2.robustImageAccess2 ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 9cea566f8..f92470f5c 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -46,6 +46,7 @@ namespace dxvk { VkPhysicalDeviceHostQueryResetFeaturesEXT extHostQueryReset; VkPhysicalDeviceMemoryPriorityFeaturesEXT extMemoryPriority; VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT extNonSeamlessCubeMap; + VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT extPipelineCreationCacheControl; VkPhysicalDeviceRobustness2FeaturesEXT extRobustness2; VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT extShaderDemoteToHelperInvocation; VkPhysicalDeviceTransformFeedbackFeaturesEXT extTransformFeedback; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index c4c15de2d..6398db3c7 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -289,6 +289,7 @@ namespace dxvk { DxvkExt extMemoryBudget = { VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, DxvkExtMode::Passive }; DxvkExt extMemoryPriority = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extNonSeamlessCubeMap = { VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extPipelineCreationCacheControl = { VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extRobustness2 = { VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt extShaderDemoteToHelperInvocation = { VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; From 331c7905925cf11717cff6d314e9f5cfc6051b95 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jul 2022 15:34:16 +0200 Subject: [PATCH 0172/1348] [dxvk] Enable VK_EXT_shader_module_identifier if supported --- src/dxvk/dxvk_adapter.cpp | 20 +++++++++++++++++++- src/dxvk/dxvk_device_info.h | 1 + src/dxvk/dxvk_extensions.h | 1 + src/vulkan/vulkan_loader.h | 5 +++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 320111ac0..7d78fae4a 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -250,6 +250,8 @@ namespace dxvk { || !required.extRobustness2.robustImageAccess2) && (m_deviceFeatures.extRobustness2.nullDescriptor || !required.extRobustness2.nullDescriptor) + && (m_deviceFeatures.extShaderModuleIdentifier.shaderModuleIdentifier + || !required.extShaderModuleIdentifier.shaderModuleIdentifier) && (m_deviceFeatures.extTransformFeedback.transformFeedback || !required.extTransformFeedback.transformFeedback) && (m_deviceFeatures.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor @@ -269,7 +271,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -286,6 +288,7 @@ namespace dxvk { &devExtensions.extPipelineCreationCacheControl, &devExtensions.extRobustness2, &devExtensions.extShaderDemoteToHelperInvocation, + &devExtensions.extShaderModuleIdentifier, &devExtensions.extShaderStencilExport, &devExtensions.extShaderViewportIndexLayer, &devExtensions.extTransformFeedback, @@ -348,6 +351,9 @@ namespace dxvk { enabledFeatures.extRobustness2.nullDescriptor = VK_TRUE; + enabledFeatures.extShaderModuleIdentifier.shaderModuleIdentifier = + m_deviceFeatures.extShaderModuleIdentifier.shaderModuleIdentifier; + enabledFeatures.khrDynamicRendering.dynamicRendering = VK_TRUE; Logger::info(str::format("Device properties:" @@ -418,6 +424,11 @@ namespace dxvk { enabledFeatures.extShaderDemoteToHelperInvocation.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extShaderDemoteToHelperInvocation); } + if (devExtensions.extShaderModuleIdentifier) { + enabledFeatures.extShaderModuleIdentifier.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT; + enabledFeatures.extShaderModuleIdentifier.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extShaderModuleIdentifier); + } + if (devExtensions.extRobustness2) { enabledFeatures.extRobustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; enabledFeatures.extRobustness2.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extRobustness2); @@ -753,6 +764,11 @@ namespace dxvk { m_deviceFeatures.extShaderDemoteToHelperInvocation.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extShaderDemoteToHelperInvocation); } + if (m_deviceExtensions.supports(VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME)) { + m_deviceFeatures.extShaderModuleIdentifier.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT; + m_deviceFeatures.extShaderModuleIdentifier.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extShaderModuleIdentifier); + } + if (m_deviceExtensions.supports(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) { m_deviceFeatures.extTransformFeedback.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; m_deviceFeatures.extTransformFeedback.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extTransformFeedback); @@ -865,6 +881,8 @@ namespace dxvk { "\n nullDescriptor : ", features.extRobustness2.nullDescriptor ? "1" : "0", "\n", VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, "\n shaderDemoteToHelperInvocation : ", features.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation ? "1" : "0", + "\n", VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME, + "\n shaderModuleIdentifier : ", features.extShaderModuleIdentifier.shaderModuleIdentifier ? "1" : "0", "\n", VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, "\n transformFeedback : ", features.extTransformFeedback.transformFeedback ? "1" : "0", "\n geometryStreams : ", features.extTransformFeedback.geometryStreams ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index f92470f5c..55ae18233 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -49,6 +49,7 @@ namespace dxvk { VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT extPipelineCreationCacheControl; VkPhysicalDeviceRobustness2FeaturesEXT extRobustness2; VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT extShaderDemoteToHelperInvocation; + VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT extShaderModuleIdentifier; VkPhysicalDeviceTransformFeedbackFeaturesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT extVertexAttributeDivisor; VkPhysicalDeviceBufferDeviceAddressFeaturesKHR khrBufferDeviceAddress; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 6398db3c7..b17d48ff4 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -292,6 +292,7 @@ namespace dxvk { DxvkExt extPipelineCreationCacheControl = { VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extRobustness2 = { VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt extShaderDemoteToHelperInvocation = { VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extShaderModuleIdentifier = { VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderViewportIndexLayer = { VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index ba5def691..28d4fd014 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -339,6 +339,11 @@ namespace dxvk::vk { VULKAN_FN(vkResetQueryPoolEXT); #endif + #ifdef VK_EXT_shader_module_identifier + VULKAN_FN(vkGetShaderModuleCreateInfoIdentifierEXT); + VULKAN_FN(vkGetShaderModuleIdentifierEXT); + #endif + #ifdef VK_EXT_transform_feedback VULKAN_FN(vkCmdBindTransformFeedbackBuffersEXT); VULKAN_FN(vkCmdBeginTransformFeedbackEXT); From 52cc0a366e6d00b4937c8e1690c52218a0b9cc3b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jul 2022 17:49:16 +0200 Subject: [PATCH 0173/1348] [dxvk] Query shader module identifiers from shader pipeline libraries --- src/dxvk/dxvk_shader.cpp | 81 ++++++++++++++++++++++++++++++++-------- src/dxvk/dxvk_shader.h | 21 +++++++++++ 2 files changed, 87 insertions(+), 15 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index ef55cee3a..0a5a50f68 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -446,6 +446,20 @@ namespace dxvk { } + VkShaderModuleIdentifierEXT DxvkShaderPipelineLibrary::getModuleIdentifier() { + std::lock_guard lock(m_identifierMutex); + + if (!m_identifier.identifierSize) { + // Unfortunate, but we'll have to decode the + // shader code here to retrieve the identifier + SpirvCodeBuffer spirvCode = this->getShaderCode(); + this->generateModuleIdentifierLocked(spirvCode); + } + + return m_identifier; + } + + VkPipeline DxvkShaderPipelineLibrary::getPipelineHandle( const DxvkShaderPipelineLibraryCompileArgs& args) { std::lock_guard lock(m_mutex); @@ -499,9 +513,12 @@ namespace dxvk { const DxvkShaderPipelineLibraryCompileArgs& args) { auto vk = m_device->vkd(); + SpirvCodeBuffer spirvCode = this->getShaderCode(); + this->generateModuleIdentifier(spirvCode); + + // Set up shader stage info DxvkShaderStageInfo stageInfo(m_device); - stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, - m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()), nullptr); + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, std::move(spirvCode), nullptr); // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. @@ -568,18 +585,12 @@ namespace dxvk { VkPipeline DxvkShaderPipelineLibrary::compileFragmentShaderPipeline() { auto vk = m_device->vkd(); - // Initialize code buffer. As a special case, it is possible that - // we have to deal with a null shader, but the pipeline library - // extension requires us to always specify a fragment shader. - DxvkShaderStageInfo stageInfo(m_device); + SpirvCodeBuffer spirvCode = this->getShaderCode(); + this->generateModuleIdentifier(spirvCode); - if (m_shader) { - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, - m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()), nullptr); - } else { - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, - SpirvCodeBuffer(dxvk_dummy_frag), nullptr); - } + // Set up shader stage info with the given code + DxvkShaderStageInfo stageInfo(m_device); + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, std::move(spirvCode), nullptr); // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. @@ -649,9 +660,12 @@ namespace dxvk { VkPipeline DxvkShaderPipelineLibrary::compileComputeShaderPipeline() { auto vk = m_device->vkd(); + SpirvCodeBuffer spirvCode = this->getShaderCode(); + this->generateModuleIdentifier(spirvCode); + + // Set up shader stage info DxvkShaderStageInfo stageInfo(m_device); - stageInfo.addStage(VK_SHADER_STAGE_COMPUTE_BIT, - m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()), nullptr); + stageInfo.addStage(VK_SHADER_STAGE_COMPUTE_BIT, std::move(spirvCode), nullptr); // Compile the compute pipeline as normal VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; @@ -667,4 +681,41 @@ namespace dxvk { return pipeline; } + + SpirvCodeBuffer DxvkShaderPipelineLibrary::getShaderCode() const { + // As a special case, it is possible that we have to deal with + // a null shader, but the pipeline library extension requires + // us to always specify a fragment shader for fragment stages, + // so we need to return a dummy shader in that case. + if (!m_shader) + return SpirvCodeBuffer(dxvk_dummy_frag); + + return m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()); + } + + + void DxvkShaderPipelineLibrary::generateModuleIdentifier( + const SpirvCodeBuffer& spirvCode) { + if (!m_device->features().extShaderModuleIdentifier.shaderModuleIdentifier) + return; + + std::lock_guard lock(m_identifierMutex); + + if (!m_identifier.identifierSize) + this->generateModuleIdentifierLocked(spirvCode); + } + + + void DxvkShaderPipelineLibrary::generateModuleIdentifierLocked( + const SpirvCodeBuffer& spirvCode) { + auto vk = m_device->vkd(); + + VkShaderModuleCreateInfo info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; + info.codeSize = spirvCode.size(); + info.pCode = spirvCode.data(); + + vk->vkGetShaderModuleCreateInfoIdentifierEXT( + vk->device(), &info, &m_identifier); + } + } \ No newline at end of file diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 4ccc7b618..4d596488c 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -343,6 +343,16 @@ namespace dxvk { ~DxvkShaderPipelineLibrary(); + /** + * \brief Queries shader module identifier + * + * Can be used to compile an optimized pipeline using the same + * shader code, but without having to wait for the pipeline + * library for this shader shader to compile first. + * \returns Shader module identifier + */ + VkShaderModuleIdentifierEXT getModuleIdentifier(); + /** * \brief Queries pipeline handle for the given set of arguments * @@ -374,6 +384,9 @@ namespace dxvk { VkPipeline m_pipeline = VK_NULL_HANDLE; VkPipeline m_pipelineNoDepthClip = VK_NULL_HANDLE; + dxvk::mutex m_identifierMutex; + VkShaderModuleIdentifierEXT m_identifier = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT }; + VkPipeline compileVertexShaderPipeline( const DxvkShaderPipelineLibraryCompileArgs& args); @@ -381,6 +394,14 @@ namespace dxvk { VkPipeline compileComputeShaderPipeline(); + SpirvCodeBuffer getShaderCode() const; + + void generateModuleIdentifier( + const SpirvCodeBuffer& spirvCode); + + void generateModuleIdentifierLocked( + const SpirvCodeBuffer& spirvCode); + }; } \ No newline at end of file From df1908f7bf2be5570b726ca8ee6f8510a9025346 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jul 2022 17:51:31 +0200 Subject: [PATCH 0174/1348] [dxvk] Support creating shader stage infos with module identifiers --- src/dxvk/dxvk_shader.cpp | 27 ++++++++++++++++++++++++++- src/dxvk/dxvk_shader.h | 24 +++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 0a5a50f68..c48b08eaa 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -386,7 +386,7 @@ namespace dxvk { // enabled, we do not need to create a shader module object and can // instead chain the create info to the shader stage info struct. // For compute pipelines, this doesn't work and we still need a module. - auto& moduleInfo = m_moduleInfos[m_stageCount]; + auto& moduleInfo = m_moduleInfos[m_stageCount].moduleInfo; moduleInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; moduleInfo.codeSize = codeBuffer.size(); moduleInfo.pCode = codeBuffer.data(); @@ -415,6 +415,31 @@ namespace dxvk { } + void DxvkShaderStageInfo::addStage( + VkShaderStageFlagBits stage, + const VkShaderModuleIdentifierEXT& identifier, + const VkSpecializationInfo* specInfo) { + // Copy relevant bits of the module identifier + uint32_t identifierSize = std::min(identifier.identifierSize, VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT); + + auto& moduleId = m_moduleInfos[m_stageCount].moduleIdentifier; + moduleId.createInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT }; + moduleId.createInfo.identifierSize = identifierSize; + moduleId.createInfo.pIdentifier = moduleId.data.data(); + std::memcpy(moduleId.data.data(), identifier.identifier, identifierSize); + + // Set up stage info using the module identifier + auto& stageInfo = m_stageInfos[m_stageCount]; + stageInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO }; + stageInfo.pNext = &moduleId.createInfo; + stageInfo.stage = stage; + stageInfo.pName = "main"; + stageInfo.pSpecializationInfo = specInfo; + + m_stageCount++; + } + + DxvkShaderStageInfo::~DxvkShaderStageInfo() { auto vk = m_device->vkd(); diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 4d596488c..cae24b640 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -278,12 +278,34 @@ namespace dxvk { SpirvCodeBuffer&& code, const VkSpecializationInfo* specInfo); + /** + * \brief Adds stage using a module identifier + * + * \param [in] stage Shader stage + * \param [in] identifier Shader module identifier + * \param [in] specinfo Specialization info + */ + void addStage( + VkShaderStageFlagBits stage, + const VkShaderModuleIdentifierEXT& identifier, + const VkSpecializationInfo* specInfo); + private: const DxvkDevice* m_device; + struct ShaderModuleIdentifier { + VkPipelineShaderStageModuleIdentifierCreateInfoEXT createInfo; + std::array data; + }; + + union ShaderModuleInfo { + ShaderModuleIdentifier moduleIdentifier; + VkShaderModuleCreateInfo moduleInfo; + }; + std::array m_codeBuffers; - std::array m_moduleInfos = { }; + std::array m_moduleInfos = { }; std::array m_stageInfos = { }; uint32_t m_stageCount = 0; From 02aa1736f56c8b36316008a026922f50537428cd Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 8 Jul 2022 18:00:08 +0200 Subject: [PATCH 0175/1348] [dxvk] Try to create cached optimized pipeline whenever possible --- src/dxvk/dxvk_device.cpp | 10 ++++++ src/dxvk/dxvk_device.h | 6 ++++ src/dxvk/dxvk_graphics.cpp | 72 ++++++++++++++++++++++++++------------ src/dxvk/dxvk_graphics.h | 3 +- 4 files changed, 68 insertions(+), 23 deletions(-) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 76fed23ed..fab902065 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -51,6 +51,16 @@ namespace dxvk { } + bool DxvkDevice::canUsePipelineCacheControl() const { + // Don't bother with this unless the device also supports shader module + // identifiers, since decoding and hashing the shaders is slow otherwise + // and likely provides no benefit over linking pipeline libraries. + return m_features.extPipelineCreationCacheControl.pipelineCreationCacheControl + && m_features.extShaderModuleIdentifier.shaderModuleIdentifier + && m_options.enableGraphicsPipelineLibrary != Tristate::True; + } + + DxvkFramebufferSize DxvkDevice::getDefaultFramebufferSize() const { return DxvkFramebufferSize { m_properties.core.properties.limits.maxFramebufferWidth, diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 29c7a1f28..3cf743a65 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -202,6 +202,12 @@ namespace dxvk { */ bool canUseGraphicsPipelineLibrary() const; + /** + * \brief Checks whether pipeline creation cache control can be used + * \returns \c true if all required features are supported. + */ + bool canUsePipelineCacheControl() const; + /** * \brief Queries default framebuffer size * \returns Default framebuffer size diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 743c8a1ae..a8a00da30 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -589,7 +589,7 @@ namespace dxvk { || instance->isCompiling.exchange(VK_TRUE, std::memory_order_acquire)) return; - VkPipeline pipeline = this->createOptimizedPipeline(state); + VkPipeline pipeline = this->createOptimizedPipeline(state, 0); instance->fastHandle.store(pipeline, std::memory_order_release); } @@ -600,18 +600,29 @@ namespace dxvk { VkPipeline fastHandle = VK_NULL_HANDLE; if (this->canCreateBasePipeline(state)) { - DxvkGraphicsPipelineVertexInputState viState(m_device, state); - DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); + // Try to create an optimized pipeline from the cache + // first, since this is expected to be the fastest path. + if (m_device->canUsePipelineCacheControl()) { + fastHandle = this->createOptimizedPipeline(state, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT); + } - DxvkGraphicsPipelineBaseInstanceKey key; - key.viLibrary = m_manager->createVertexInputLibrary(viState); - key.foLibrary = m_manager->createFragmentOutputLibrary(foState); - key.args.depthClipEnable = state.rs.depthClipEnable(); + if (!fastHandle) { + // If that didn't succeed, link a pipeline using the + // pre-compiled fragment and vertex shader libraries. + DxvkGraphicsPipelineVertexInputState viState(m_device, state); + DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); - baseHandle = this->createBaseInstance(key)->handle; + DxvkGraphicsPipelineBaseInstanceKey key; + key.viLibrary = m_manager->createVertexInputLibrary(viState); + key.foLibrary = m_manager->createFragmentOutputLibrary(foState); + key.args.depthClipEnable = state.rs.depthClipEnable(); + + baseHandle = this->createBaseInstance(key)->handle; + } } else { // Create optimized variant right away, no choice - fastHandle = this->createOptimizedPipeline(state); + fastHandle = this->createOptimizedPipeline(state, 0); } m_stats->numGraphicsPipelines += 1; @@ -727,7 +738,8 @@ namespace dxvk { VkPipeline DxvkGraphicsPipeline::createOptimizedPipeline( - const DxvkGraphicsPipelineStateInfo& state) const { + const DxvkGraphicsPipelineStateInfo& state, + VkPipelineCreateFlags flags) const { auto vk = m_device->vkd(); if (Logger::logLevel() <= LogLevel::Debug) { @@ -772,16 +784,24 @@ namespace dxvk { // Build stage infos for all provided shaders DxvkShaderStageInfo stageInfo(m_device); - stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, state), &specInfo); - if (m_shaders.tcs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, state), &specInfo); - if (m_shaders.tes != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, state), &specInfo); - if (m_shaders.gs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, state), &specInfo); - if (m_shaders.fs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, state), &specInfo); + if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT) { + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, m_vsLibrary->getModuleIdentifier(), &specInfo); + + if (m_shaders.fs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, m_fsLibrary->getModuleIdentifier(), &specInfo); + } else { + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, state), &specInfo); + + if (m_shaders.tcs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, state), &specInfo); + if (m_shaders.tes != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, state), &specInfo); + if (m_shaders.gs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, state), &specInfo); + if (m_shaders.fs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, state), &specInfo); + } DxvkGraphicsPipelineVertexInputState viState(m_device, state); DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr()); @@ -793,6 +813,7 @@ namespace dxvk { dyInfo.pDynamicStates = dynamicStates.data(); VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &foState.rtInfo }; + info.flags = flags; info.stageCount = stageInfo.getStageCount(); info.pStages = stageInfo.getStageInfos(); info.pVertexInputState = &viState.viInfo; @@ -811,9 +832,16 @@ namespace dxvk { info.pTessellationState = nullptr; VkPipeline pipeline = VK_NULL_HANDLE; - if (vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline) != VK_SUCCESS) { - Logger::err("DxvkGraphicsPipeline: Failed to compile pipeline"); - this->logPipelineState(LogLevel::Error, state); + VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline); + + if (vr != VK_SUCCESS) { + // Ignore any error if we're trying to create a cached pipeline. If linking or + // compiling an optimized pipeline fail later, we'll still be printing errors. + if (!(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT)) { + Logger::err(str::format("DxvkGraphicsPipeline: Failed to compile pipeline: ", vr)); + this->logPipelineState(LogLevel::Error, state); + } + return VK_NULL_HANDLE; } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index d0abc0604..29e316d6a 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -425,7 +425,8 @@ namespace dxvk { const DxvkGraphicsPipelineBaseInstanceKey& key) const; VkPipeline createOptimizedPipeline( - const DxvkGraphicsPipelineStateInfo& state) const; + const DxvkGraphicsPipelineStateInfo& state, + VkPipelineCreateFlags flags) const; void destroyPipeline( VkPipeline pipeline) const; From 021aff1fc0def3043e52e87160ff04b58d2fbc4a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 9 Jul 2022 11:51:25 +0200 Subject: [PATCH 0176/1348] [dxvk] Support fomatting more Vulkan enum names --- src/vulkan/vulkan_names.cpp | 99 +++++++++++++++++++++++++++++++++++++ src/vulkan/vulkan_names.h | 7 +++ 2 files changed, 106 insertions(+) diff --git a/src/vulkan/vulkan_names.cpp b/src/vulkan/vulkan_names.cpp index 1dd6d7cf6..4d5f1a88e 100644 --- a/src/vulkan/vulkan_names.cpp +++ b/src/vulkan/vulkan_names.cpp @@ -313,6 +313,105 @@ std::ostream& operator << (std::ostream& os, VkColorSpaceKHR e) { } +std::ostream& operator << (std::ostream& os, VkFrontFace e) { + switch (e) { + ENUM_NAME(VK_FRONT_FACE_COUNTER_CLOCKWISE); + ENUM_NAME(VK_FRONT_FACE_CLOCKWISE); + ENUM_DEFAULT(e); + } + return os; +} + +std::ostream& operator << (std::ostream& os, VkPolygonMode e) { + switch (e) { + ENUM_NAME(VK_POLYGON_MODE_FILL); + ENUM_NAME(VK_POLYGON_MODE_LINE); + ENUM_NAME(VK_POLYGON_MODE_POINT); + ENUM_DEFAULT(e); + } + return os; +} + +std::ostream& operator << (std::ostream& os, VkBlendFactor e) { + switch (e) { + ENUM_NAME(VK_BLEND_FACTOR_ZERO); + ENUM_NAME(VK_BLEND_FACTOR_ONE); + ENUM_NAME(VK_BLEND_FACTOR_SRC_COLOR); + ENUM_NAME(VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR); + ENUM_NAME(VK_BLEND_FACTOR_DST_COLOR); + ENUM_NAME(VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR); + ENUM_NAME(VK_BLEND_FACTOR_SRC_ALPHA); + ENUM_NAME(VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA); + ENUM_NAME(VK_BLEND_FACTOR_DST_ALPHA); + ENUM_NAME(VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA); + ENUM_NAME(VK_BLEND_FACTOR_CONSTANT_COLOR); + ENUM_NAME(VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR); + ENUM_NAME(VK_BLEND_FACTOR_CONSTANT_ALPHA); + ENUM_NAME(VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA); + ENUM_NAME(VK_BLEND_FACTOR_SRC_ALPHA_SATURATE); + ENUM_NAME(VK_BLEND_FACTOR_SRC1_COLOR); + ENUM_NAME(VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR); + ENUM_NAME(VK_BLEND_FACTOR_SRC1_ALPHA); + ENUM_NAME(VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA); + ENUM_DEFAULT(e); + } + return os; +} + +std::ostream& operator << (std::ostream& os, VkBlendOp e) { + switch (e) { + ENUM_NAME(VK_BLEND_OP_ADD); + ENUM_NAME(VK_BLEND_OP_SUBTRACT); + ENUM_NAME(VK_BLEND_OP_REVERSE_SUBTRACT); + ENUM_NAME(VK_BLEND_OP_MIN); + ENUM_NAME(VK_BLEND_OP_MAX); + ENUM_DEFAULT(e); + } + return os; +} + +std::ostream& operator << (std::ostream& os, VkCompareOp e) { + switch (e) { + ENUM_NAME(VK_COMPARE_OP_NEVER); + ENUM_NAME(VK_COMPARE_OP_LESS); + ENUM_NAME(VK_COMPARE_OP_EQUAL); + ENUM_NAME(VK_COMPARE_OP_LESS_OR_EQUAL); + ENUM_NAME(VK_COMPARE_OP_GREATER); + ENUM_NAME(VK_COMPARE_OP_NOT_EQUAL); + ENUM_NAME(VK_COMPARE_OP_GREATER_OR_EQUAL); + ENUM_NAME(VK_COMPARE_OP_ALWAYS); + ENUM_DEFAULT(e); + } + return os; +} + +std::ostream& operator << (std::ostream& os, VkVertexInputRate e) { + switch (e) { + ENUM_NAME(VK_VERTEX_INPUT_RATE_VERTEX); + ENUM_NAME(VK_VERTEX_INPUT_RATE_INSTANCE); + ENUM_DEFAULT(e); + } + return os; +} + +std::ostream& operator << (std::ostream& os, VkPrimitiveTopology e) { + switch (e) { + ENUM_NAME(VK_PRIMITIVE_TOPOLOGY_POINT_LIST); + ENUM_NAME(VK_PRIMITIVE_TOPOLOGY_LINE_LIST); + ENUM_NAME(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP); + ENUM_NAME(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + ENUM_NAME(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP); + ENUM_NAME(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN); + ENUM_NAME(VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY); + ENUM_NAME(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY); + ENUM_NAME(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY); + ENUM_NAME(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY); + ENUM_NAME(VK_PRIMITIVE_TOPOLOGY_PATCH_LIST); + ENUM_DEFAULT(e); + } + return os; +} + std::ostream& operator << (std::ostream& os, VkOffset2D e) { return os << "(" << e.x << "," << e.y << ")"; } diff --git a/src/vulkan/vulkan_names.h b/src/vulkan/vulkan_names.h index 6752a12c4..e421fdfca 100644 --- a/src/vulkan/vulkan_names.h +++ b/src/vulkan/vulkan_names.h @@ -15,6 +15,13 @@ std::ostream& operator << (std::ostream& os, VkImageLayout e); std::ostream& operator << (std::ostream& os, VkImageViewType e); std::ostream& operator << (std::ostream& os, VkPresentModeKHR e); std::ostream& operator << (std::ostream& os, VkColorSpaceKHR e); +std::ostream& operator << (std::ostream& os, VkFrontFace e); +std::ostream& operator << (std::ostream& os, VkPolygonMode e); +std::ostream& operator << (std::ostream& os, VkBlendFactor e); +std::ostream& operator << (std::ostream& os, VkBlendOp e); +std::ostream& operator << (std::ostream& os, VkCompareOp e); +std::ostream& operator << (std::ostream& os, VkVertexInputRate e); +std::ostream& operator << (std::ostream& os, VkPrimitiveTopology e); std::ostream& operator << (std::ostream& os, VkOffset2D e); std::ostream& operator << (std::ostream& os, VkOffset3D e); std::ostream& operator << (std::ostream& os, VkExtent2D e); From c6168179bddc5dd802307620d27fbb317b0921d8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 9 Jul 2022 13:44:52 +0200 Subject: [PATCH 0177/1348] [dxvk] Re-add render target format validation This was lost during the state cache and render target state rework. --- src/dxvk/dxvk_graphics.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index a8a00da30..9009f638d 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -997,6 +997,31 @@ namespace dxvk { return false; } + // Validate render target format support + VkFormat depthFormat = state.rt.getDepthStencilFormat(); + + if (depthFormat) { + VkFormatProperties formatInfo = m_device->adapter()->formatProperties(depthFormat); + + if (!(formatInfo.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) { + Logger::err(str::format(depthFormat, " not supported as depth-stencil attachment")); + return false; + } + } + + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + VkFormat colorFormat = state.rt.getColorFormat(i); + + if (colorFormat) { + VkFormatProperties formatInfo = m_device->adapter()->formatProperties(colorFormat); + + if (!(formatInfo.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) { + Logger::err(str::format(depthFormat, " not supported as color attachment")); + return false; + } + } + } + return true; } From 2832083fe569b5ba380099cb27b32dcd1af74fcd Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 9 Jul 2022 13:53:20 +0200 Subject: [PATCH 0178/1348] [dxvk] Properly log pipeline state on error --- src/dxvk/dxvk_graphics.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 9009f638d..777ed181c 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -591,6 +591,10 @@ namespace dxvk { VkPipeline pipeline = this->createOptimizedPipeline(state, 0); instance->fastHandle.store(pipeline, std::memory_order_release); + + // Log pipeline state on error + if (!pipeline) + this->logPipelineState(LogLevel::Error, state); } @@ -625,6 +629,10 @@ namespace dxvk { fastHandle = this->createOptimizedPipeline(state, 0); } + // Log pipeline state if requested, or on failure + if (!fastHandle && !baseHandle) + this->logPipelineState(LogLevel::Error, state); + m_stats->numGraphicsPipelines += 1; return &(*m_pipelines.emplace(state, baseHandle, fastHandle)); } @@ -729,9 +737,10 @@ namespace dxvk { info.basePipelineIndex = -1; VkPipeline pipeline = VK_NULL_HANDLE; + VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline); - if ((vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline))) - Logger::err("DxvkGraphicsPipeline: Failed to create base pipeline"); + if (vr != VK_SUCCESS) + Logger::err(str::format("DxvkGraphicsPipeline: Failed to create base pipeline: ", vr)); return pipeline; } @@ -742,11 +751,6 @@ namespace dxvk { VkPipelineCreateFlags flags) const { auto vk = m_device->vkd(); - if (Logger::logLevel() <= LogLevel::Debug) { - Logger::debug("Compiling graphics pipeline..."); - this->logPipelineState(LogLevel::Debug, state); - } - // Set up dynamic states as needed std::array dynamicStates; uint32_t dynamicStateCount = 0; @@ -837,10 +841,8 @@ namespace dxvk { if (vr != VK_SUCCESS) { // Ignore any error if we're trying to create a cached pipeline. If linking or // compiling an optimized pipeline fail later, we'll still be printing errors. - if (!(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT)) { + if (!(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT)) Logger::err(str::format("DxvkGraphicsPipeline: Failed to compile pipeline: ", vr)); - this->logPipelineState(LogLevel::Error, state); - } return VK_NULL_HANDLE; } From 1b89394aa0fb4f226e68e8d297f5c3582019c09e Mon Sep 17 00:00:00 2001 From: Matej Dian Date: Sat, 9 Jul 2022 15:51:04 +0200 Subject: [PATCH 0179/1348] [util] Enable cached dynamic resources for DayZ (#2709) --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 9a5e53eb4..0bceb5bed 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -301,6 +301,10 @@ namespace dxvk { { R"(\\GW2.Main_Win64_Retail\.exe$)", {{ { "dxgi.customVendorId", "10de" }, }} }, + /* DayZ */ + { R"(\\DayZ_x64\.exe$)", {{ + { "d3d11.cachedDynamicResources", "cr" }, + }} }, /**********************************************/ /* D3D9 GAMES */ From 00cfee9d1750fec59c14324a1e4efb4f2b17f64d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 1 Jul 2022 17:21:39 +0200 Subject: [PATCH 0180/1348] [d3d11] Ignore OMSetRenderTargets calls with incompatible view sizes Fixes #2701. --- src/d3d11/d3d11_context.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 1f9cafe46..469ed9c72 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -4487,6 +4487,13 @@ namespace dxvk { if (curView->imageInfo().sampleCount != refView->imageInfo().sampleCount) return false; + + VkExtent3D curExtent = curView->mipLevelExtent(0); + VkExtent3D refExtent = refView->mipLevelExtent(0); + + if (curExtent.width != refExtent.width + || curExtent.height != refExtent.height) + return false; } else { // Set reference view. All remaining views // must be compatible to the reference view. From ca52c5a67f11bbfd09f1f07bc146450c36199a2b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 11 Jul 2022 01:19:09 +0200 Subject: [PATCH 0181/1348] [dxvk] Don't read or create state cache file if state cache is disabled --- src/dxvk/dxvk_state_cache.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 8c0412b84..5c1471921 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -222,6 +222,9 @@ namespace dxvk { std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE"); m_enable = useStateCache != "0" && device->config().enableStateCache; + if (!m_enable) + return; + bool newFile = !readCacheFile(); if (newFile) { From 52038b2f83e8ca419dc834ae4ee24927f7434335 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 11 Jul 2022 16:23:14 +0200 Subject: [PATCH 0182/1348] [dxvk] Ignore state cache for pipelines that can be fast linked --- src/dxvk/dxvk_graphics.cpp | 21 ++++++++++++++++----- src/dxvk/dxvk_graphics.h | 3 ++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 777ed181c..95852cf36 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -542,12 +542,17 @@ namespace dxvk { if (!instance) { // Keep pipeline object locked, at worst we're going to stall // a state cache worker and the current thread needs priority. - instance = this->createInstance(state); - this->writePipelineStateToCache(state); + bool canCreateBasePipeline = this->canCreateBasePipeline(state); + instance = this->createInstance(state, canCreateBasePipeline); // If necessary, compile an optimized pipeline variant if (!instance->fastHandle.load()) m_workers->compileGraphicsPipeline(this, state); + + // Only store pipelines in the state cache that cannot benefit + // from pipeline libraries, or if that feature is disabled. + if (!canCreateBasePipeline) + this->writePipelineStateToCache(state); } } @@ -575,12 +580,17 @@ namespace dxvk { if (!this->validatePipelineState(state, false)) return; + // Do not compile if this pipeline can be fast linked. This essentially + // disables the state cache for pipelines that do not benefit from it. + if (this->canCreateBasePipeline(state)) + return; + // Prevent other threads from adding new instances and check again std::lock_guard lock(m_mutex); instance = this->findInstance(state); if (!instance) - instance = this->createInstance(state); + instance = this->createInstance(state, false); } // Exit if another thread is already compiling @@ -599,11 +609,12 @@ namespace dxvk { DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::createInstance( - const DxvkGraphicsPipelineStateInfo& state) { + const DxvkGraphicsPipelineStateInfo& state, + bool doCreateBasePipeline) { VkPipeline baseHandle = VK_NULL_HANDLE; VkPipeline fastHandle = VK_NULL_HANDLE; - if (this->canCreateBasePipeline(state)) { + if (doCreateBasePipeline) { // Try to create an optimized pipeline from the cache // first, since this is expected to be the fastest path. if (m_device->canUsePipelineCacheControl()) { diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 29e316d6a..12a752b89 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -410,7 +410,8 @@ namespace dxvk { sync::List m_basePipelines; DxvkGraphicsPipelineInstance* createInstance( - const DxvkGraphicsPipelineStateInfo& state); + const DxvkGraphicsPipelineStateInfo& state, + bool doCreateBasePipeline); DxvkGraphicsPipelineInstance* findInstance( const DxvkGraphicsPipelineStateInfo& state); From 379c2e545e137fb1de784b9297c4dc9da08d19bb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 11 Jul 2022 19:23:42 +0200 Subject: [PATCH 0183/1348] [util] Work around silly compiler warnings on GCC 12.1 No, we're not actually reading 64 bytes from a 1-byte area. --- src/util/sha1/sha1.c | 2 +- src/util/sha1/sha1.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/sha1/sha1.c b/src/util/sha1/sha1.c index 39e60675e..2782dd5a9 100644 --- a/src/util/sha1/sha1.c +++ b/src/util/sha1/sha1.c @@ -48,7 +48,7 @@ typedef union { * Hash a single 512-bit block. This is the core of the algorithm. */ void -SHA1Transform(uint32_t state[5], const uint8_t buffer[SHA1_BLOCK_LENGTH]) +SHA1Transform(uint32_t state[5], const uint8_t* buffer) { uint32_t a, b, c, d, e; uint8_t workspace[SHA1_BLOCK_LENGTH]; diff --git a/src/util/sha1/sha1.h b/src/util/sha1/sha1.h index 029a0ae87..06867b395 100644 --- a/src/util/sha1/sha1.h +++ b/src/util/sha1/sha1.h @@ -28,7 +28,7 @@ typedef struct _SHA1_CTX { void SHA1Init(SHA1_CTX *); void SHA1Pad(SHA1_CTX *); -void SHA1Transform(uint32_t [5], const uint8_t [SHA1_BLOCK_LENGTH]); +void SHA1Transform(uint32_t [5], const uint8_t*); void SHA1Update(SHA1_CTX *, const uint8_t *, size_t); void SHA1Final(uint8_t [SHA1_DIGEST_LENGTH], SHA1_CTX *); From 6482898167d9970250b9d73a7ee83ac615414ae2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 12 Jul 2022 00:54:24 +0200 Subject: [PATCH 0184/1348] [dxvk] Mark VK_KHR_create_renderpass_2 as required Dependency of VK_KHR_dynamic_rendering. --- src/dxvk/dxvk_extensions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index b17d48ff4..e0e6c4602 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -298,7 +298,7 @@ namespace dxvk { DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrBufferDeviceAddress = { VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, DxvkExtMode::Disabled }; - DxvkExt khrCreateRenderPass2 = { VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt khrCreateRenderPass2 = { VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrDepthStencilResolve = { VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrDrawIndirectCount = { VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrDriverProperties = { VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, DxvkExtMode::Optional }; From 6f5ae58ccc939af1ef9bdf22b3f2278b8f559edf Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 12 Jul 2022 01:54:22 +0200 Subject: [PATCH 0185/1348] [dxvk] Remove dummy resources that are no longer needed --- src/dxvk/dxvk_adapter.cpp | 4 +- src/dxvk/dxvk_device.cpp | 5 -- src/dxvk/dxvk_device.h | 9 --- src/dxvk/dxvk_unbound.cpp | 144 ++------------------------------------ src/dxvk/dxvk_unbound.h | 129 +--------------------------------- 5 files changed, 8 insertions(+), 283 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 7d78fae4a..ad8713252 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -525,11 +525,9 @@ namespace dxvk { if (vr != VK_SUCCESS) throw DxvkError("DxvkAdapter: Failed to create device"); - Rc result = new DxvkDevice(instance, this, + return new DxvkDevice(instance, this, new vk::DeviceFn(true, m_vki->instance(), device), devExtensions, enabledFeatures); - result->initResources(); - return result; } diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index fab902065..c532ba81f 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -188,11 +188,6 @@ namespace dxvk { } - void DxvkDevice::initResources() { - m_objects.dummyResources().clearResources(this); - } - - void DxvkDevice::registerShader(const Rc& shader) { m_objects.pipelineManager().registerShader(shader); } diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 3cf743a65..89de0e6f5 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -356,15 +356,6 @@ namespace dxvk { */ uint32_t getCurrentFrameId() const; - /** - * \brief Initializes dummy resources - * - * Should be called after creating the device in - * case the device initialization was successful - * and the device is usable. - */ - void initResources(); - /** * \brief Registers a shader * \param [in] shader Newly compiled shader diff --git a/src/dxvk/dxvk_unbound.cpp b/src/dxvk/dxvk_unbound.cpp index cb8f665de..39f390ce8 100644 --- a/src/dxvk/dxvk_unbound.cpp +++ b/src/dxvk/dxvk_unbound.cpp @@ -4,13 +4,7 @@ namespace dxvk { DxvkUnboundResources::DxvkUnboundResources(DxvkDevice* dev) : m_sampler (createSampler(dev)), - m_buffer (createBuffer(dev)), - m_bufferView (createBufferView(dev, m_buffer)), - m_image1D (createImage(dev, VK_IMAGE_TYPE_1D, 1)), - m_image2D (createImage(dev, VK_IMAGE_TYPE_2D, 6)), - m_image3D (createImage(dev, VK_IMAGE_TYPE_3D, 1)), - m_viewsSampled (createImageViews(dev, VK_FORMAT_R32_SFLOAT)), - m_viewsStorage (createImageViews(dev, VK_FORMAT_R32_UINT)) { + m_buffer (createBuffer(dev)) { } @@ -20,22 +14,6 @@ namespace dxvk { } - void DxvkUnboundResources::clearResources(DxvkDevice* dev) { - const Rc ctx = dev->createContext(DxvkContextType::Supplementary); - ctx->beginRecording(dev->createCommandList()); - - this->clearBuffer(ctx, m_buffer); - this->clearImage(ctx, m_image1D); - this->clearImage(ctx, m_image2D); - this->clearImage(ctx, m_image3D); - - dev->submitCommandList( - ctx->endRecording(), - VK_NULL_HANDLE, - VK_NULL_HANDLE); - } - - Rc DxvkUnboundResources::createSampler(DxvkDevice* dev) { DxvkSamplerCreateInfo info; info.minFilter = VK_FILTER_LINEAR; @@ -76,123 +54,13 @@ namespace dxvk { | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; - return dev->createBuffer(info, + Rc buffer = dev->createBuffer(info, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - } - - - Rc DxvkUnboundResources::createBufferView( - DxvkDevice* dev, - const Rc& buffer) { - DxvkBufferViewCreateInfo info; - info.format = VK_FORMAT_R32_UINT; - info.rangeOffset = 0; - info.rangeLength = buffer->info().size; - - return dev->createBufferView(buffer, info); - } - - - Rc DxvkUnboundResources::createImage( - DxvkDevice* dev, - VkImageType type, - uint32_t layers) { - DxvkImageCreateInfo info; - info.type = type; - info.format = VK_FORMAT_R32_UINT; - info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; - info.sampleCount = VK_SAMPLE_COUNT_1_BIT; - info.extent = { 1, 1, 1 }; - info.numLayers = layers; - info.mipLevels = 1; - info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT - | VK_IMAGE_USAGE_SAMPLED_BIT - | VK_IMAGE_USAGE_STORAGE_BIT; - info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT - | dev->getShaderPipelineStages(); - info.access = VK_ACCESS_SHADER_READ_BIT; - info.layout = VK_IMAGE_LAYOUT_GENERAL; - info.tiling = VK_IMAGE_TILING_OPTIMAL; - - if (type == VK_IMAGE_TYPE_2D) - info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; - - return dev->createImage(info, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - } - - - Rc DxvkUnboundResources::createImageView( - DxvkDevice* dev, - const Rc& image, - VkFormat format, - VkImageViewType type, - uint32_t layers) { - DxvkImageViewCreateInfo info; - info.type = type; - info.format = format; - info.usage = VK_IMAGE_USAGE_SAMPLED_BIT - | VK_IMAGE_USAGE_STORAGE_BIT; - info.aspect = VK_IMAGE_ASPECT_COLOR_BIT; - info.minLevel = 0; - info.numLevels = 1; - info.minLayer = 0; - info.numLayers = layers; - info.swizzle = VkComponentMapping { - VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, - VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO }; - - return dev->createImageView(image, info); - } - - - DxvkUnboundResources::UnboundViews DxvkUnboundResources::createImageViews(DxvkDevice* dev, VkFormat format) { - UnboundViews result; - result.view1D = createImageView(dev, m_image1D, format, VK_IMAGE_VIEW_TYPE_1D, 1); - result.view1DArr = createImageView(dev, m_image1D, format, VK_IMAGE_VIEW_TYPE_1D_ARRAY, 1); - result.view2D = createImageView(dev, m_image2D, format, VK_IMAGE_VIEW_TYPE_2D, 1); - result.view2DArr = createImageView(dev, m_image2D, format, VK_IMAGE_VIEW_TYPE_2D_ARRAY, 1); - result.viewCube = createImageView(dev, m_image2D, format, VK_IMAGE_VIEW_TYPE_CUBE, 6); - result.viewCubeArr = createImageView(dev, m_image2D, format, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, 6); - result.view3D = createImageView(dev, m_image3D, format, VK_IMAGE_VIEW_TYPE_3D, 1); - return result; - } - - const DxvkImageView* DxvkUnboundResources::getImageView(VkImageViewType type, bool sampled) const { - auto views = sampled ? &m_viewsSampled : &m_viewsStorage; - - switch (type) { - case VK_IMAGE_VIEW_TYPE_1D: return views->view1D.ptr(); - case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return views->view1DArr.ptr(); - // When implicit samplers are unbound -- we assume 2D in the shader. - case VK_IMAGE_VIEW_TYPE_MAX_ENUM: - case VK_IMAGE_VIEW_TYPE_2D: return views->view2D.ptr(); - case VK_IMAGE_VIEW_TYPE_2D_ARRAY: return views->view2DArr.ptr(); - case VK_IMAGE_VIEW_TYPE_CUBE: return views->viewCube.ptr(); - case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return views->viewCubeArr.ptr(); - case VK_IMAGE_VIEW_TYPE_3D: return views->view3D.ptr(); - default: return nullptr; - } - } - - - void DxvkUnboundResources::clearBuffer( - const Rc& ctx, - const Rc& buffer) { - ctx->initBuffer(buffer); - } - - - void DxvkUnboundResources::clearImage( - const Rc& ctx, - const Rc& image) { - ctx->initImage(image, - VkImageSubresourceRange { - VK_IMAGE_ASPECT_COLOR_BIT, - 0, image->info().mipLevels, - 0, image->info().numLayers }, - VK_IMAGE_LAYOUT_UNDEFINED); + std::memset(buffer->mapPtr(0), 0, info.size); + return buffer; } } \ No newline at end of file diff --git a/src/dxvk/dxvk_unbound.h b/src/dxvk/dxvk_unbound.h index d9ae01e0c..cd057b6e0 100644 --- a/src/dxvk/dxvk_unbound.h +++ b/src/dxvk/dxvk_unbound.h @@ -34,36 +34,6 @@ namespace dxvk { return m_buffer->getSliceHandle().handle; } - /** - * \brief Dummy buffer descriptor - * - * Points to a small buffer filled with zeroes. - * Do not write to this buffer, and do not use - * it if out-of-bounds read access is possible. - * \returns Dummy buffer descriptor - */ - VkDescriptorBufferInfo bufferDescriptor() const { - auto slice = m_buffer->getSliceHandle(); - - VkDescriptorBufferInfo result; - result.buffer = slice.handle; - result.offset = slice.offset; - result.range = slice.length; - return result; - } - - /** - * \brief Dummy buffer view - * - * Returns an \c R32_UINT view into the - * dummy buffer, which will contain one - * element with undefined value. - * \returns Dummy buffer view - */ - VkBufferView bufferViewDescriptor() const { - return m_bufferView->handle(); - } - /** * \brief Dummy sampler descriptor * @@ -80,112 +50,15 @@ namespace dxvk { return result; } - /** - * \brief Dummy combined image sampler descriptor - * - * Contains both an image view and a sampler - * descriptor for the given image view type. - * \param [in] type Image view type - * \returns Dummy image view descriptor - */ - VkDescriptorImageInfo imageSamplerDescriptor(VkImageViewType type) const { - auto view = getImageView(type, true); - - VkDescriptorImageInfo result; - result.sampler = m_sampler->handle(); - result.imageView = view->handle(); - result.imageLayout = view->imageInfo().layout; - return result; - } - - /** - * \brief Dummy image view descriptor - * - * Points to an image view which, instead of - * reading image data, will return zeroes for - * all components unconditionally. - * \param [in] type Image view type - * \param [in] sampled Format selector - * \returns Dummy image view descriptor - */ - VkDescriptorImageInfo imageViewDescriptor(VkImageViewType type, bool sampled) const { - auto view = getImageView(type, sampled); - - VkDescriptorImageInfo result; - result.sampler = VK_NULL_HANDLE; - result.imageView = view->handle(); - result.imageLayout = view->imageInfo().layout; - return result; - } - - /** - * \brief Clears the resources - * - * Initializes all images and buffers to zero. - * \param [in] dev The DXVK device handle - */ - void clearResources(DxvkDevice* dev); - private: - struct UnboundViews { - Rc view1D; - Rc view1DArr; - Rc view2D; - Rc view2DArr; - Rc viewCube; - Rc viewCubeArr; - Rc view3D; - }; - Rc m_sampler; - - Rc m_buffer; - Rc m_bufferView; - - Rc m_image1D; - Rc m_image2D; - Rc m_image3D; - - UnboundViews m_viewsSampled; - UnboundViews m_viewsStorage; + Rc m_buffer; Rc createSampler(DxvkDevice* dev); Rc createBuffer(DxvkDevice* dev); - Rc createBufferView( - DxvkDevice* dev, - const Rc& buffer); - - Rc createImage( - DxvkDevice* dev, - VkImageType type, - uint32_t layers); - - Rc createImageView( - DxvkDevice* dev, - const Rc& image, - VkFormat format, - VkImageViewType type, - uint32_t layers); - - UnboundViews createImageViews( - DxvkDevice* dev, - VkFormat format); - - const DxvkImageView* getImageView( - VkImageViewType type, - bool sampled) const; - - void clearBuffer( - const Rc& ctx, - const Rc& buffer); - - void clearImage( - const Rc& ctx, - const Rc& image); - }; } \ No newline at end of file From e8f48c71abecf9619e0113b353bfe8cb15db9340 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 12 Jul 2022 02:08:22 +0200 Subject: [PATCH 0186/1348] [dxvk] Always enable robustBufferAccess2 feature And respect the required alignments when creating buffers. --- src/d3d11/d3d11_device.cpp | 3 --- src/d3d9/d3d9_device.cpp | 1 - src/dxvk/dxvk_adapter.cpp | 2 ++ src/dxvk/dxvk_buffer.cpp | 22 +++++++++++++--------- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 7b982cecd..ac6e79d37 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1929,9 +1929,6 @@ namespace dxvk { enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; - enabled.extRobustness2.robustBufferAccess2 = supported.extRobustness2.robustBufferAccess2; - enabled.extRobustness2.robustImageAccess2 = supported.extRobustness2.robustImageAccess2; - enabled.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation = supported.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation; enabled.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor = supported.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 97acadbcb..7ff58a5b5 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3894,7 +3894,6 @@ namespace dxvk { // Geometry shaders are used for some meta ops enabled.core.features.geometryShader = VK_TRUE; enabled.core.features.robustBufferAccess = VK_TRUE; - enabled.extRobustness2.robustBufferAccess2 = supported.extRobustness2.robustBufferAccess2; enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index ad8713252..0a489fab5 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -349,6 +349,8 @@ namespace dxvk { enabledFeatures.ext4444Formats.formatA4B4G4R4 = m_deviceFeatures.ext4444Formats.formatA4B4G4R4; enabledFeatures.ext4444Formats.formatA4R4G4B4 = m_deviceFeatures.ext4444Formats.formatA4R4G4B4; + enabledFeatures.extRobustness2.robustBufferAccess2 = VK_TRUE; + enabledFeatures.extRobustness2.robustImageAccess2 = m_deviceFeatures.extRobustness2.robustImageAccess2; enabledFeatures.extRobustness2.nullDescriptor = VK_TRUE; enabledFeatures.extShaderModuleIdentifier.shaderModuleIdentifier = diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 3de5b4d7b..2419c4bea 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -135,31 +135,35 @@ namespace dxvk { VkDeviceSize DxvkBuffer::computeSliceAlignment() const { - const auto& devInfo = m_device->properties().core.properties; + const auto& devInfo = m_device->properties(); VkDeviceSize result = sizeof(uint32_t); - if (m_info.usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) - result = std::max(result, devInfo.limits.minUniformBufferOffsetAlignment); + if (m_info.usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) { + result = std::max(result, devInfo.core.properties.limits.minUniformBufferOffsetAlignment); + result = std::max(result, devInfo.extRobustness2.robustUniformBufferAccessSizeAlignment); + } - if (m_info.usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) - result = std::max(result, devInfo.limits.minStorageBufferOffsetAlignment); + if (m_info.usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) { + result = std::max(result, devInfo.core.properties.limits.minStorageBufferOffsetAlignment); + result = std::max(result, devInfo.extRobustness2.robustStorageBufferAccessSizeAlignment); + } if (m_info.usage & (VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) { - result = std::max(result, devInfo.limits.minTexelBufferOffsetAlignment); + result = std::max(result, devInfo.core.properties.limits.minTexelBufferOffsetAlignment); result = std::max(result, VkDeviceSize(16)); } if (m_info.usage & (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) - && m_info.size > (devInfo.limits.optimalBufferCopyOffsetAlignment / 2)) - result = std::max(result, devInfo.limits.optimalBufferCopyOffsetAlignment); + && m_info.size > (devInfo.core.properties.limits.optimalBufferCopyOffsetAlignment / 2)) + result = std::max(result, devInfo.core.properties.limits.optimalBufferCopyOffsetAlignment); // For some reason, Warhammer Chaosbane breaks otherwise if (m_info.usage & (VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT)) result = std::max(result, VkDeviceSize(256)); if (m_memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - result = std::max(result, devInfo.limits.nonCoherentAtomSize); + result = std::max(result, devInfo.core.properties.limits.nonCoherentAtomSize); result = std::max(result, VkDeviceSize(64)); } From f99a833f51990157e29b880b49182ceb3c936495 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 12 Jul 2022 02:09:39 +0200 Subject: [PATCH 0187/1348] [d3d11] Remove d3d11.constantBufferRangeCheck option --- dxvk.conf | 9 --------- src/d3d11/d3d11_buffer.cpp | 3 --- src/d3d11/d3d11_options.cpp | 3 --- src/d3d11/d3d11_options.h | 5 ----- src/dxbc/dxbc_compiler.cpp | 24 +++++------------------- src/dxbc/dxbc_compiler.h | 3 +-- src/dxbc/dxbc_options.cpp | 1 - src/dxbc/dxbc_options.h | 4 ---- src/util/config/config.cpp | 32 -------------------------------- 9 files changed, 6 insertions(+), 78 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index dbb0e2253..6839cd3d6 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -113,15 +113,6 @@ # d3d9.tearFree = Auto -# Performs range check on dynamically indexed constant buffers in shaders. -# This may be needed to work around a certain type of game bug, but may -# also introduce incorrect behaviour. -# -# Supported values: True, False - -# d3d11.constantBufferRangeCheck = False - - # Assume single-use mode for command lists created on deferred contexts. # This may need to be disabled for some applications to avoid rendering # issues, which may come at a significant performance cost. diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index eb72fc1b9..c53003a05 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -37,9 +37,6 @@ namespace dxvk { info.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; info.stages |= m_parent->GetEnabledShaderStages(); info.access |= VK_ACCESS_UNIFORM_READ_BIT; - - if (m_parent->GetOptions()->constantBufferRangeCheck) - info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; } if (pDesc->BindFlags & D3D11_BIND_SHADER_RESOURCE) { diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index e78c51981..25e452291 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -35,9 +35,6 @@ namespace dxvk { ? VkDeviceSize(maxDynamicImageBufferSize) << 10 : VkDeviceSize(~0ull); - this->constantBufferRangeCheck = config.getOption("d3d11.constantBufferRangeCheck", false) - && DxvkGpuVendor(devInfo.core.properties.vendorID) != DxvkGpuVendor::Amd; - auto cachedDynamicResources = config.getOption("d3d11.cachedDynamicResources", std::string()); if (::GetModuleHandle("dxgitrace.dll")) { diff --git a/src/d3d11/d3d11_options.h b/src/d3d11/d3d11_options.h index 99353b302..3c3a26169 100644 --- a/src/d3d11/d3d11_options.h +++ b/src/d3d11/d3d11_options.h @@ -24,11 +24,6 @@ namespace dxvk { /// outputs with zero bool enableRtOutputNanFixup; - /// Enables out-of-bounds access check for constant - /// buffers. Workaround for a few broken games that - /// access random data inside their shaders. - bool constantBufferRangeCheck; - /// Zero-initialize workgroup memory /// /// Workargound for games that don't initialize diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index b86919a95..2fdf24d79 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -774,19 +774,15 @@ namespace dxvk { const uint32_t bufferId = ins.dst[0].idx[0].offset; const uint32_t elementCount = ins.dst[0].idx[1].offset; - bool asSsbo = m_moduleInfo.options.dynamicIndexedConstantBufferAsSsbo - && ins.controls.accessType() == DxbcConstantBufferAccessType::DynamicallyIndexed; - this->emitDclConstantBufferVar(bufferId, elementCount, - str::format("cb", bufferId).c_str(), asSsbo); + str::format("cb", bufferId).c_str()); } void DxbcCompiler::emitDclConstantBufferVar( uint32_t regIdx, uint32_t numConstants, - const char* name, - bool asSsbo) { + const char* name) { // Uniform buffer data is stored as a fixed-size array // of 4x32-bit vectors. SPIR-V requires explicit strides. const uint32_t arrayType = m_module.defArrayTypeUnique( @@ -798,9 +794,7 @@ namespace dxvk { // struct and decorate that struct as a block. const uint32_t structType = m_module.defStructTypeUnique(1, &arrayType); - m_module.decorate(structType, asSsbo - ? spv::DecorationBufferBlock - : spv::DecorationBlock); + m_module.decorate(structType, spv::DecorationBlock); m_module.memberDecorateOffset(structType, 0, 0); m_module.setDebugName (structType, str::format(name, "_t").c_str()); @@ -821,20 +815,13 @@ namespace dxvk { m_module.decorateDescriptorSet(varId, 0); m_module.decorateBinding(varId, bindingId); - if (asSsbo) - m_module.decorate(varId, spv::DecorationNonWritable); - DxbcConstantBuffer buf; buf.varId = varId; buf.size = numConstants; m_constantBuffers.at(regIdx) = buf; // Store descriptor info for the shader interface - VkDescriptorType descriptorType = asSsbo - ? VK_DESCRIPTOR_TYPE_STORAGE_BUFFER - : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - - DxvkBindingInfo binding = { descriptorType }; + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; binding.resourceBinding = bindingId; @@ -1507,8 +1494,7 @@ namespace dxvk { void DxbcCompiler::emitDclImmediateConstantBufferUbo( uint32_t dwordCount, const uint32_t* dwordArray) { - this->emitDclConstantBufferVar(Icb_BindingSlotId, dwordCount / 4, "icb", - m_moduleInfo.options.dynamicIndexedConstantBufferAsSsbo); + this->emitDclConstantBufferVar(Icb_BindingSlotId, dwordCount / 4, "icb"); m_immConstData.resize(dwordCount * sizeof(uint32_t)); std::memcpy(m_immConstData.data(), dwordArray, m_immConstData.size()); } diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index b38412cf0..af2d00e8e 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -583,8 +583,7 @@ namespace dxvk { void emitDclConstantBufferVar( uint32_t regIdx, uint32_t numConstants, - const char* name, - bool asSsbo); + const char* name); void emitDclSampler( const DxbcShaderInstruction& ins); diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index fc89f74b7..df05d3caf 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -42,7 +42,6 @@ namespace dxvk { zeroInitWorkgroupMemory = options.zeroInitWorkgroupMemory; forceTgsmBarriers = options.forceTgsmBarriers; disableMsaa = options.disableMsaa; - dynamicIndexedConstantBufferAsSsbo = options.constantBufferRangeCheck; // Disable subgroup early discard on Nvidia because it may hurt performance if (adapter->matchesDriver(DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0)) diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index d21f3b1a4..ed3993746 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -44,10 +44,6 @@ namespace dxvk { /// Enables NaN fixup for render target outputs bool enableRtOutputNanFixup = false; - /// Implement dynamically indexed uniform buffers - /// with storage buffers for tight bounds checking - bool dynamicIndexedConstantBufferAsSsbo = false; - /// Clear thread-group shared memory to zero bool zeroInitWorkgroupMemory = false; diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 0bceb5bed..b448cf75c 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -107,18 +107,6 @@ namespace dxvk { { R"(\\starwarsbattlefront(trial)?\.exe$)", {{ { "dxgi.nvapiHack", "False" }, }} }, - /* Dark Souls Remastered */ - { R"(\\DarkSoulsRemastered\.exe$)", {{ - { "d3d11.constantBufferRangeCheck", "True" }, - }} }, - /* Grim Dawn */ - { R"(\\Grim Dawn\.exe$)", {{ - { "d3d11.constantBufferRangeCheck", "True" }, - }} }, - /* NieR:Automata */ - { R"(\\NieRAutomata\.exe$)", {{ - { "d3d11.constantBufferRangeCheck", "True" }, - }} }, /* NieR Replicant */ { R"(\\NieR Replicant ver\.1\.22474487139\.exe)", {{ { "dxgi.syncInterval", "1" }, @@ -137,18 +125,6 @@ namespace dxvk { { R"(\\h1_[ms]p64_ship\.exe$)", {{ { "dxgi.customVendorId", "10de" }, }} }, - /* Titan Quest */ - { R"(\\TQ\.exe$)", {{ - { "d3d11.constantBufferRangeCheck", "True" }, - }} }, - /* Saints Row IV */ - { R"(\\SaintsRowIV\.exe$)", {{ - { "d3d11.constantBufferRangeCheck", "True" }, - }} }, - /* Saints Row: The Third */ - { R"(\\SaintsRowTheThird_DX11\.exe$)", {{ - { "d3d11.constantBufferRangeCheck", "True" }, - }} }, /* Crysis 3 - slower if it notices AMD card * * Apitrace mode helps massively in cpu bound * * game parts */ @@ -201,14 +177,6 @@ namespace dxvk { { R"(\\F1_20(1[89]|[2-9][0-9])\.exe$)", {{ { "d3d11.forceTgsmBarriers", "True" }, }} }, - /* Blue Reflection */ - { R"(\\BLUE_REFLECTION\.exe$)", {{ - { "d3d11.constantBufferRangeCheck", "True" }, - }} }, - /* Secret World Legends */ - { R"(\\SecretWorldLegendsDX11\.exe$)", {{ - { "d3d11.constantBufferRangeCheck", "True" }, - }} }, /* Darksiders Warmastered - apparently reads * * from write-only mapped buffers */ { R"(\\darksiders1\.exe$)", {{ From 77891d71db06ab8ead0b5d12cdeecd26dca83bd0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 12 Jul 2022 11:39:56 +0200 Subject: [PATCH 0188/1348] [d3d11] Fix unused variable warning --- src/d3d11/d3d11_options.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index 25e452291..5744a0bfb 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -5,8 +5,6 @@ namespace dxvk { D3D11Options::D3D11Options(const Config& config, const Rc& device) { - const DxvkDeviceInfo& devInfo = device->properties(); - this->dcSingleUseMode = config.getOption("d3d11.dcSingleUseMode", true); this->enableRtOutputNanFixup = config.getOption("d3d11.enableRtOutputNanFixup", false); this->zeroInitWorkgroupMemory = config.getOption("d3d11.zeroInitWorkgroupMemory", false); From 18d4a87333a016a306a2d271d74660e60205888f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 12 Jul 2022 11:42:24 +0200 Subject: [PATCH 0189/1348] [dxvk] Add pipeline flag for rasterizer discard --- src/dxvk/dxvk_graphics.cpp | 19 ++++++++++++------- src/dxvk/dxvk_graphics.h | 1 + 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 95852cf36..5e2b20391 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -475,14 +475,19 @@ namespace dxvk { m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->info().inputMask : 0; m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->info().outputMask : 0; - if (m_shaders.gs != nullptr && m_shaders.gs->flags().test(DxvkShaderFlag::HasTransformFeedback)) { - m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback); + if (m_shaders.gs != nullptr) { + if (m_shaders.gs->flags().test(DxvkShaderFlag::HasTransformFeedback)) { + m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback); - m_barrier.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT - | VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT; - m_barrier.access |= VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT - | VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT - | VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT; + m_barrier.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT + | VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT; + m_barrier.access |= VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT + | VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT + | VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT; + } + + if (m_shaders.gs->info().xfbRasterizedStream < 0) + m_flags.set(DxvkGraphicsPipelineFlag::HasRasterizerDiscard); } if (m_barrier.access & VK_ACCESS_SHADER_WRITE_BIT) diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 12a752b89..4a0c79dc2 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -180,6 +180,7 @@ namespace dxvk { * \brief Flags that describe pipeline properties */ enum class DxvkGraphicsPipelineFlag { + HasRasterizerDiscard, HasTransformFeedback, HasStorageDescriptors, }; From d3c8d210471446f7b00c74f3b117d60f65cc4d08 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 12 Jul 2022 12:03:05 +0200 Subject: [PATCH 0190/1348] [dxvk] Make cull mode and front face dynamic state --- src/dxvk/dxvk_context.cpp | 62 ++++++++++++++++++++++++++--------- src/dxvk/dxvk_context_state.h | 4 +++ src/dxvk/dxvk_graphics.cpp | 7 +++- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 74e887aa3..3218771a0 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -96,6 +96,7 @@ namespace dxvk { DxvkContextFlag::GpDirtyXfbBuffers, DxvkContextFlag::GpDirtyBlendConstants, DxvkContextFlag::GpDirtyStencilRef, + DxvkContextFlag::GpDirtyRasterizerState, DxvkContextFlag::GpDirtyViewport, DxvkContextFlag::GpDirtyDepthBias, DxvkContextFlag::GpDirtyDepthBounds, @@ -2421,16 +2422,29 @@ namespace dxvk { void DxvkContext::setRasterizerState(const DxvkRasterizerState& rs) { - m_state.gp.state.rs = DxvkRsInfo( - rs.depthClipEnable, - rs.depthBiasEnable, - rs.polygonMode, - rs.cullMode, - rs.frontFace, - rs.sampleCount, - rs.conservativeMode); + if (m_state.dyn.cullMode != rs.cullMode || m_state.dyn.frontFace != rs.frontFace) { + m_state.dyn.cullMode = rs.cullMode; + m_state.dyn.frontFace = rs.frontFace; - m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + m_flags.set(DxvkContextFlag::GpDirtyRasterizerState); + } + + if (m_state.gp.state.rs.depthClipEnable() != rs.depthClipEnable + || m_state.gp.state.rs.depthBiasEnable() != rs.depthBiasEnable + || m_state.gp.state.rs.polygonMode() != rs.polygonMode + || m_state.gp.state.rs.sampleCount() != rs.sampleCount + || m_state.gp.state.rs.conservativeMode() != rs.conservativeMode) { + m_state.gp.state.rs = DxvkRsInfo( + rs.depthClipEnable, + rs.depthBiasEnable, + rs.polygonMode, + rs.cullMode, + rs.frontFace, + rs.sampleCount, + rs.conservativeMode); + + m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + } } @@ -4003,6 +4017,7 @@ namespace dxvk { DxvkContextFlag::GpDirtyXfbBuffers, DxvkContextFlag::GpDirtyBlendConstants, DxvkContextFlag::GpDirtyStencilRef, + DxvkContextFlag::GpDirtyRasterizerState, DxvkContextFlag::GpDirtyViewport, DxvkContextFlag::GpDirtyDepthBias, DxvkContextFlag::GpDirtyDepthBounds, @@ -4428,6 +4443,7 @@ namespace dxvk { DxvkContextFlag::GpDirtyXfbBuffers, DxvkContextFlag::GpDirtyBlendConstants, DxvkContextFlag::GpDirtyStencilRef, + DxvkContextFlag::GpDirtyRasterizerState, DxvkContextFlag::GpDirtyViewport, DxvkContextFlag::GpDirtyDepthBias, DxvkContextFlag::GpDirtyDepthBounds); @@ -4488,6 +4504,7 @@ namespace dxvk { DxvkContextFlag::GpDynamicDepthBias, DxvkContextFlag::GpDynamicDepthBounds, DxvkContextFlag::GpDynamicStencilRef, + DxvkContextFlag::GpDynamicRasterizerState, DxvkContextFlag::GpIndependentSets); m_flags.set(m_state.gp.state.useDynamicBlendConstants() @@ -4505,7 +4522,11 @@ namespace dxvk { m_flags.set(m_state.gp.state.useDynamicStencilRef() ? DxvkContextFlag::GpDynamicStencilRef : DxvkContextFlag::GpDirtyStencilRef); - + + m_flags.set((!m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasRasterizerDiscard)) + ? DxvkContextFlag::GpDynamicRasterizerState + : DxvkContextFlag::GpDirtyRasterizerState); + // Retrieve and bind actual Vulkan pipeline handle auto pipelineInfo = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state); @@ -4519,10 +4540,6 @@ namespace dxvk { // For pipelines created from graphics pipeline libraries, we need // to apply a bunch of dynamic state that is otherwise static if (pipelineInfo.second == DxvkGraphicsPipelineType::BasePipeline) { - m_cmd->cmdSetRasterizerState( - m_state.gp.state.rs.cullMode(), - m_state.gp.state.rs.frontFace()); - m_cmd->cmdSetDepthState( m_state.gp.state.ds.enableDepthTest(), m_state.gp.state.ds.enableDepthWrite(), @@ -4538,9 +4555,12 @@ namespace dxvk { m_state.gp.state.ds.enableDepthBoundsTest()); } - if (!m_state.gp.state.rs.depthBiasEnable()) + if (!m_flags.test(DxvkContextFlag::GpDynamicDepthBias)) m_cmd->cmdSetDepthBias(0.0f, 0.0f, 0.0f); + if (!m_flags.test(DxvkContextFlag::GpDynamicRasterizerState)) + m_cmd->cmdSetRasterizerState(VK_CULL_MODE_FRONT_AND_BACK, VK_FRONT_FACE_CLOCKWISE); + m_flags.set(DxvkContextFlag::GpIndependentSets); } @@ -5117,6 +5137,15 @@ namespace dxvk { m_cmd->cmdSetScissor(m_state.vp.viewportCount, m_state.vp.scissorRects.data()); } + if (m_flags.all(DxvkContextFlag::GpDirtyRasterizerState, + DxvkContextFlag::GpDynamicRasterizerState)) { + m_flags.clr(DxvkContextFlag::GpDirtyRasterizerState); + + m_cmd->cmdSetRasterizerState( + m_state.dyn.cullMode, + m_state.dyn.frontFace); + } + if (m_flags.all(DxvkContextFlag::GpDirtyBlendConstants, DxvkContextFlag::GpDynamicBlendConstants)) { m_flags.clr(DxvkContextFlag::GpDirtyBlendConstants); @@ -5255,7 +5284,8 @@ namespace dxvk { DxvkContextFlag::GpDirtyBlendConstants, DxvkContextFlag::GpDirtyStencilRef, DxvkContextFlag::GpDirtyDepthBias, - DxvkContextFlag::GpDirtyDepthBounds)) + DxvkContextFlag::GpDirtyDepthBounds, + DxvkContextFlag::GpDirtyRasterizerState)) this->updateDynamicState(); if (m_flags.test(DxvkContextFlag::DirtyPushConstants)) diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 9694369cd..8fffb5545 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -34,11 +34,13 @@ namespace dxvk { GpDirtyDepthBias, ///< Depth bias has changed GpDirtyDepthBounds, ///< Depth bounds have changed GpDirtyStencilRef, ///< Stencil reference has changed + GpDirtyRasterizerState, ///< Cull mode and front face have changed GpDirtyViewport, ///< Viewport state has changed GpDynamicBlendConstants, ///< Blend constants are dynamic GpDynamicDepthBias, ///< Depth bias is dynamic GpDynamicDepthBounds, ///< Depth bounds are dynamic GpDynamicStencilRef, ///< Stencil reference is dynamic + GpDynamicRasterizerState, ///< Cull mode and front face are dynamic GpIndependentSets, ///< Graphics pipeline layout was created with independent sets CpDirtyPipeline, ///< Compute pipeline binding are out of date @@ -135,6 +137,8 @@ namespace dxvk { DxvkDepthBias depthBias = { 0.0f, 0.0f, 0.0f }; DxvkDepthBounds depthBounds = { false, 0.0f, 1.0f }; uint32_t stencilReference = 0; + VkCullModeFlags cullMode = VK_CULL_MODE_BACK_BIT; + VkFrontFace frontFace = VK_FRONT_FACE_CLOCKWISE; }; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 5e2b20391..92d26a6bc 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -768,7 +768,7 @@ namespace dxvk { auto vk = m_device->vkd(); // Set up dynamic states as needed - std::array dynamicStates; + std::array dynamicStates; uint32_t dynamicStateCount = 0; dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT; @@ -786,6 +786,11 @@ namespace dxvk { if (state.useDynamicStencilRef()) dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; + if (!m_flags.test(DxvkGraphicsPipelineFlag::HasRasterizerDiscard)) { + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_CULL_MODE_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_FRONT_FACE_EXT; + } + // Set up some specialization constants DxvkSpecConstants specData; From 59475fb05355246b6f59419aef0930aa7f2913a9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 12 Jul 2022 12:07:25 +0200 Subject: [PATCH 0191/1348] [dxvk] Remove cull mode and front face from pipeline state And bump state cache version to v14. --- src/dxvk/dxvk_context.cpp | 2 -- src/dxvk/dxvk_graphics.cpp | 14 -------------- src/dxvk/dxvk_graphics_state.h | 16 +--------------- src/dxvk/dxvk_state_cache.cpp | 10 ++++++++++ src/dxvk/dxvk_state_cache_types.h | 30 +++++++++++++++++++++++++++--- 5 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 3218771a0..0e722406b 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2438,8 +2438,6 @@ namespace dxvk { rs.depthClipEnable, rs.depthBiasEnable, rs.polygonMode, - rs.cullMode, - rs.frontFace, rs.sampleCount, rs.conservativeMode); diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 92d26a6bc..fb38c3deb 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -395,8 +395,6 @@ namespace dxvk { // Set up basic rasterization state rsInfo.depthClampEnable = VK_TRUE; rsInfo.polygonMode = state.rs.polygonMode(); - rsInfo.cullMode = state.rs.cullMode(); - rsInfo.frontFace = state.rs.frontFace(); rsInfo.depthBiasEnable = state.rs.depthBiasEnable(); rsInfo.lineWidth = 1.0f; @@ -1096,22 +1094,10 @@ namespace dxvk { } // Log rasterizer state - std::string cullMode; - - switch (state.rs.cullMode()) { - case VK_CULL_MODE_NONE: cullMode = "VK_CULL_MODE_NONE"; break; - case VK_CULL_MODE_BACK_BIT: cullMode = "VK_CULL_MODE_BACK_BIT"; break; - case VK_CULL_MODE_FRONT_BIT: cullMode = "VK_CULL_MODE_FRONT_BIT"; break; - case VK_CULL_MODE_FRONT_AND_BACK: cullMode = "VK_CULL_MODE_FRONT_AND_BACK"; break; - default: cullMode = str::format(state.rs.cullMode()); - } - sstr << "Rasterizer state:" << std::endl << " depth clip: " << (state.rs.depthClipEnable() ? "yes" : "no") << std::endl << " depth bias: " << (state.rs.depthBiasEnable() ? "yes" : "no") << std::endl << " polygon mode: " << state.rs.polygonMode() << std::endl - << " cull mode: " << cullMode << std::endl - << " front face: " << state.rs.frontFace() << std::endl << " conservative: " << (state.rs.conservativeMode() == VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT ? "no" : "yes") << std::endl; // Log multisample state diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 189249260..9a733999e 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -221,15 +221,11 @@ namespace dxvk { VkBool32 depthClipEnable, VkBool32 depthBiasEnable, VkPolygonMode polygonMode, - VkCullModeFlags cullMode, - VkFrontFace frontFace, VkSampleCountFlags sampleCount, VkConservativeRasterizationModeEXT conservativeMode) : m_depthClipEnable (uint16_t(depthClipEnable)), m_depthBiasEnable (uint16_t(depthBiasEnable)), m_polygonMode (uint16_t(polygonMode)), - m_cullMode (uint16_t(cullMode)), - m_frontFace (uint16_t(frontFace)), m_sampleCount (uint16_t(sampleCount)), m_conservativeMode(uint16_t(conservativeMode)), m_reserved (0) { } @@ -246,14 +242,6 @@ namespace dxvk { return VkPolygonMode(m_polygonMode); } - VkCullModeFlags cullMode() const { - return VkCullModeFlags(m_cullMode); - } - - VkFrontFace frontFace() const { - return VkFrontFace(m_frontFace); - } - VkSampleCountFlags sampleCount() const { return VkSampleCountFlags(m_sampleCount); } @@ -267,11 +255,9 @@ namespace dxvk { uint16_t m_depthClipEnable : 1; uint16_t m_depthBiasEnable : 1; uint16_t m_polygonMode : 2; - uint16_t m_cullMode : 2; - uint16_t m_frontFace : 1; uint16_t m_sampleCount : 5; uint16_t m_conservativeMode : 2; - uint16_t m_reserved : 2; + uint16_t m_reserved : 5; }; diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 5c1471921..63a982c3e 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -73,6 +73,16 @@ namespace dxvk { return true; } + if (version < 14) { + DxvkRsInfoV13 v13; + + if (!read(v13)) + return false; + + data = v13.convert(); + return true; + } + return read(data); } diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index 1e65b4260..71577b1af 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -52,7 +52,7 @@ namespace dxvk { */ struct DxvkStateCacheHeader { char magic[4] = { 'D', 'X', 'V', 'K' }; - uint32_t version = 13; + uint32_t version = 14; uint32_t entrySize = 0; /* no longer meaningful */ }; @@ -143,11 +143,35 @@ namespace dxvk { VkBool32(m_depthClipEnable), VkBool32(m_depthBiasEnable), VkPolygonMode(m_polygonMode), - VkCullModeFlags(m_cullMode), - VkFrontFace(m_frontFace), VkSampleCountFlags(m_sampleCount), VkConservativeRasterizationModeEXT(m_conservativeMode)); } }; + + + class DxvkRsInfoV13 { + + public: + + uint16_t m_depthClipEnable : 1; + uint16_t m_depthBiasEnable : 1; + uint16_t m_polygonMode : 2; + uint16_t m_cullMode : 2; + uint16_t m_frontFace : 1; + uint16_t m_sampleCount : 5; + uint16_t m_conservativeMode : 2; + uint16_t m_reserved : 2; + + DxvkRsInfo convert() const { + return DxvkRsInfo( + VkBool32(m_depthClipEnable), + VkBool32(m_depthBiasEnable), + VkPolygonMode(m_polygonMode), + VkSampleCountFlags(m_sampleCount), + VkConservativeRasterizationModeEXT(m_conservativeMode)); + } + + }; + } From 5ff6f3a2ca05bc15dd404ece231d35e79517d4c0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 12 Jul 2022 14:26:52 +0200 Subject: [PATCH 0192/1348] [dxvk] Fix graphics UAV barriers We broke this when replacing gfxBarriers with execBarriers, since starting a render pass instance clears queued up barriers. --- src/dxvk/dxvk_context.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 0e722406b..71d79b328 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5234,18 +5234,25 @@ namespace dxvk { return false; } - if (m_state.gp.flags.any(DxvkGraphicsPipelineFlag::HasStorageDescriptors, - DxvkGraphicsPipelineFlag::HasTransformFeedback)) { - this->commitGraphicsBarriers(); - this->commitGraphicsBarriers(); - } - if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) this->updateFramebuffer(); if (!m_flags.test(DxvkContextFlag::GpRenderPassBound)) this->startRenderPass(); + if (m_state.gp.flags.any( + DxvkGraphicsPipelineFlag::HasStorageDescriptors, + DxvkGraphicsPipelineFlag::HasTransformFeedback)) { + this->commitGraphicsBarriers(); + + // This can only happen if the render pass was active before, + // so we'll never strat the render pass twice in one draw + if (!m_flags.test(DxvkContextFlag::GpRenderPassBound)) + this->startRenderPass(); + + this->commitGraphicsBarriers(); + } + if (m_flags.test(DxvkContextFlag::GpDirtyIndexBuffer) && Indexed) { if (unlikely(!this->updateIndexBufferBinding())) return false; From bd68f05c9bfc922ecd513140e605ad3cb4f017d9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 12 Jul 2022 16:51:17 +0200 Subject: [PATCH 0193/1348] [dxvk] Make emitRenderTargetReadbackBarrier more generic And also remove the redundant pipeline barrier. --- src/d3d9/d3d9_device.cpp | 2 +- src/dxvk/dxvk_context.cpp | 18 ++++++------------ src/dxvk/dxvk_context.h | 10 ++++++---- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 7ff58a5b5..d2c24b3e5 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -6084,7 +6084,7 @@ namespace dxvk { void D3D9DeviceEx::PrepareDraw(D3DPRIMITIVETYPE PrimitiveType) { if (unlikely(m_activeHazardsRT != 0)) { EmitCs([](DxvkContext* ctx) { - ctx->emitRenderTargetReadbackBarrier(); + ctx->emitGraphicsBarrier(); }); if (m_d3d9Options.generalHazards) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 71d79b328..b51c43290 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1441,18 +1441,6 @@ namespace dxvk { } - void DxvkContext::emitRenderTargetReadbackBarrier() { - if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) - this->spillRenderPass(true); - - emitMemoryBarrier(0, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_ACCESS_SHADER_READ_BIT); - } - - void DxvkContext::initBuffer( const Rc& buffer) { auto slice = buffer->getSliceHandle(); @@ -1570,6 +1558,12 @@ namespace dxvk { } + void DxvkContext::emitGraphicsBarrier() { + if (!m_barrierControl.test(DxvkBarrierControl::IgnoreGraphicsBarriers)) + this->spillRenderPass(true); + } + + void DxvkContext::generateMipmaps( const Rc& imageView, VkFilter filter) { diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 29a071555..d61ef9f6f 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -707,12 +707,14 @@ namespace dxvk { uint32_t counterBias); /** - * \brief Emits barrier for render target readback + * \brief Emits graphics barrier * - * Use between draw calls if the fragment shader - * reads one of the currently bound render targets. + * Needs to be used when the fragment shader reads a bound + * render target, or when subsequent draw calls access any + * given resource for writing. It is assumed that no hazards + * can happen between storage descriptors and other resources. */ - void emitRenderTargetReadbackBarrier(); + void emitGraphicsBarrier(); /** * \brief Generates mip maps From 10b174b52c04195c445a110c0dce181832b1eb83 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Tue, 12 Jul 2022 21:17:52 +0200 Subject: [PATCH 0194/1348] [d3d9] Fix barriers with staging buffers --- src/d3d9/d3d9_device.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index d2c24b3e5..0fc7efb0a 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4027,8 +4027,8 @@ namespace dxvk { info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; } else { info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; - info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT; - info.access = VK_ACCESS_TRANSFER_READ_BIT; + info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + info.access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT; } D3D9BufferSlice result; From 95995041b070517917bc4a20010c7c8ed2a57154 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 13 Jul 2022 12:35:33 +0200 Subject: [PATCH 0195/1348] [d3d9] Explicitly check for Unknown in CheckDeviceFormatConversion --- src/d3d9/d3d9_adapter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_adapter.cpp b/src/d3d9/d3d9_adapter.cpp index d86da523e..4e93fb1ad 100644 --- a/src/d3d9/d3d9_adapter.cpp +++ b/src/d3d9/d3d9_adapter.cpp @@ -236,7 +236,8 @@ namespace dxvk { D3DDEVTYPE DeviceType, D3D9Format SourceFormat, D3D9Format TargetFormat) { - bool sourceSupported = IsSupportedBackBufferFormat(D3D9Format::Unknown, SourceFormat, TRUE); + bool sourceSupported = SourceFormat != D3D9Format::Unknown + && IsSupportedBackBufferFormat(SourceFormat); bool targetSupported = TargetFormat == D3D9Format::X1R5G5B5 || TargetFormat == D3D9Format::A1R5G5B5 || TargetFormat == D3D9Format::R5G6B5 From 64d22606561433d9ae3f28b45290915849245b65 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Fri, 8 Jul 2022 21:00:12 +0200 Subject: [PATCH 0196/1348] [d3d9] add D3DFMT_UNKNOWN to windowed BackBufferFormat --- src/d3d9/d3d9_monitor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_monitor.cpp b/src/d3d9/d3d9_monitor.cpp index 8a5656cdd..51167afd2 100644 --- a/src/d3d9/d3d9_monitor.cpp +++ b/src/d3d9/d3d9_monitor.cpp @@ -57,7 +57,8 @@ namespace dxvk { || BackBufferFormat == D3D9Format::X8R8G8B8 || BackBufferFormat == D3D9Format::A1R5G5B5 || BackBufferFormat == D3D9Format::X1R5G5B5 - || BackBufferFormat == D3D9Format::R5G6B5; + || BackBufferFormat == D3D9Format::R5G6B5 + || BackBufferFormat == D3D9Format::Unknown; } } From ce48b57f94722e9f9eb5156a5a5d367d0d73ada2 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sun, 10 Jul 2022 13:56:20 +0200 Subject: [PATCH 0197/1348] [d3d9] Allow POOL_SCRATCH targets in GetFrontBufferData --- src/d3d9/d3d9_swapchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 7fbf75a5e..07f8e5cd2 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -333,7 +333,7 @@ namespace dxvk { D3D9CommonTexture* dstTexInfo = dst->GetCommonTexture(); D3D9CommonTexture* srcTexInfo = m_backBuffers.back()->GetCommonTexture(); - if (unlikely(dstTexInfo->Desc()->Pool != D3DPOOL_SYSTEMMEM)) + if (unlikely(dstTexInfo->Desc()->Pool != D3DPOOL_SYSTEMMEM && dstTexInfo->Desc()->Pool != D3DPOOL_SCRATCH)) return D3DERR_INVALIDCALL; Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource()); From 57445227acc3e24632abfc210587ff415cea2006 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 12:39:14 +0200 Subject: [PATCH 0198/1348] [d3d11] Fix render target validation (again) This behaviour is rather obscure and undocumented, but testing shows that DSV <-> RTV mismatches are allowed under some circumstances. Fixes #2555. --- src/d3d11/d3d11_context.cpp | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 469ed9c72..070766302 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -4466,20 +4466,28 @@ namespace dxvk { ID3D11RenderTargetView* const* ppRenderTargetViews, ID3D11DepthStencilView* pDepthStencilView) { Rc refView; - + + VkExtent3D dsvExtent = { 0u, 0u, 0u }; + VkExtent3D rtvExtent = { 0u, 0u, 0u }; + if (pDepthStencilView != nullptr) { refView = static_cast( pDepthStencilView)->GetImageView(); + dsvExtent = refView->mipLevelExtent(0); } for (uint32_t i = 0; i < NumViews; i++) { if (ppRenderTargetViews[i] != nullptr) { auto curView = static_cast( ppRenderTargetViews[i])->GetImageView(); - + + if (!rtvExtent.width) + rtvExtent = curView->mipLevelExtent(0); + if (refView != nullptr) { - // Render target views must all have the same - // size, sample count, layer count, and type + // Render target views must all have the same sample count, + // layer count, and type. The size can mismatch under certain + // conditions, the D3D11 documentation is wrong here. if (curView->info().type != refView->info().type || curView->info().numLayers != refView->info().numLayers) return false; @@ -4488,11 +4496,11 @@ namespace dxvk { != refView->imageInfo().sampleCount) return false; + // Color targets must all be the same size VkExtent3D curExtent = curView->mipLevelExtent(0); - VkExtent3D refExtent = refView->mipLevelExtent(0); - if (curExtent.width != refExtent.width - || curExtent.height != refExtent.height) + if (curExtent.width != rtvExtent.width + || curExtent.height != rtvExtent.height) return false; } else { // Set reference view. All remaining views @@ -4501,7 +4509,15 @@ namespace dxvk { } } } - + + // Based on testing, the depth-stencil target is allowed + // to be larger than all color targets, but not smaller + if (rtvExtent.width && dsvExtent.width) { + if (rtvExtent.width > dsvExtent.width + || rtvExtent.height > dsvExtent.height) + return false; + } + return true; } From ce3eae59a90aeed44283205dcf86f2cd0ce282d8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 14:56:13 +0200 Subject: [PATCH 0199/1348] [dxvk] Introduce bindResourceBufferRange --- src/dxvk/dxvk_buffer.h | 13 ++++++++++++- src/dxvk/dxvk_context.h | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 139098104..5fc50f44b 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -518,7 +518,18 @@ namespace dxvk { return this->m_offset == other.m_offset && this->m_length == other.m_length; } - + + /** + * \brief Sets buffer range + * + * \param [in] offset New offset + * \param [in] length New length + */ + void setRange(VkDeviceSize offset, VkDeviceSize length) { + m_offset = offset; + m_length = length; + } + private: Rc m_buffer = nullptr; diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index d61ef9f6f..6047617a6 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -165,6 +165,22 @@ namespace dxvk { m_descriptorState.dirtyBuffers(stages); } + /** + * \brief Changes bound range of a resource buffer + * + * Can be used to quickly bind a new sub-range of + * a buffer rather than re-binding the entire buffer. + */ + void bindResourceBufferRange( + VkShaderStageFlags stages, + uint32_t slot, + VkDeviceSize offset, + VkDeviceSize length) { + m_rc[slot].bufferSlice.setRange(offset, length); + + m_descriptorState.dirtyBuffers(stages); + } + /** * \brief Binds image or buffer view * From aef2eb14df1fe5a518ca9b20096d416820b1f429 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 15:10:48 +0200 Subject: [PATCH 0200/1348] [dxvk] Use BindConstantBufferRange for SetConstantBuffers1 if possible Reduces ref counting overhead in the few games that use this. --- src/d3d11/d3d11_context.cpp | 40 ++++++++++++++++++++++++++++++------- src/d3d11/d3d11_context.h | 6 ++++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 070766302..226899629 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3291,7 +3291,7 @@ namespace dxvk { UINT Length) { EmitCs([ cSlotId = Slot, - cBufferSlice = Length ? pBuffer->GetBufferSlice(16 * Offset, 16 * Length) : DxvkBufferSlice() + cBufferSlice = pBuffer ? pBuffer->GetBufferSlice(16 * Offset, 16 * Length) : DxvkBufferSlice() ] (DxvkContext* ctx) { VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); ctx->bindResourceBuffer(stage, cSlotId, cBufferSlice); @@ -3299,6 +3299,22 @@ namespace dxvk { } + template + void D3D11DeviceContext::BindConstantBufferRange( + UINT Slot, + UINT Offset, + UINT Length) { + EmitCs([ + cSlotId = Slot, + cOffset = 16 * Offset, + cLength = 16 * Length + ] (DxvkContext* ctx) { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceBufferRange(stage, cSlotId, cOffset, cLength); + }); + } + + template void D3D11DeviceContext::BindSampler( UINT Slot, @@ -3959,20 +3975,30 @@ namespace dxvk { constantBound = 0; } + // Do a full rebind if either the buffer changes, or if either the current or + // the previous number of bound constants were zero, since we're binding a null + // buffer to the backend in that case. bool needsUpdate = Bindings[StartSlot + i].buffer != newBuffer; - if (needsUpdate) - Bindings[StartSlot + i].buffer = newBuffer; + if (!needsUpdate) { + needsUpdate |= !constantBound; + needsUpdate |= !Bindings[StartSlot + i].constantBound; + } - needsUpdate |= Bindings[StartSlot + i].constantOffset != constantOffset - || Bindings[StartSlot + i].constantCount != constantCount; - if (needsUpdate) { + Bindings[StartSlot + i].buffer = newBuffer; Bindings[StartSlot + i].constantOffset = constantOffset; Bindings[StartSlot + i].constantCount = constantCount; Bindings[StartSlot + i].constantBound = constantBound; - + BindConstantBuffer(slotId + i, newBuffer, constantOffset, constantBound); + } else if (Bindings[StartSlot + i].constantOffset != constantOffset + || Bindings[StartSlot + i].constantCount != constantCount) { + Bindings[StartSlot + i].constantOffset = constantOffset; + Bindings[StartSlot + i].constantCount = constantCount; + Bindings[StartSlot + i].constantBound = constantBound; + + BindConstantBufferRange(slotId + i, constantOffset, constantBound); } } } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 1f1d19302..b9eba9c19 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -760,6 +760,12 @@ namespace dxvk { UINT Offset, UINT Length); + template + void BindConstantBufferRange( + UINT Slot, + UINT Offset, + UINT Length); + template void BindSampler( UINT Slot, From bcd2be069835a3895f01624a3ab2ceeeeab3532d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 15:14:25 +0200 Subject: [PATCH 0201/1348] [d3d11] Fix subtle bug in constant buffer rebinding Previously, if the app called SetConstantBuffers1 with a non-zero offset and a full UBO range, and then SetConstantBuffers with the same buffer, we would not rebind that buffer at offset zero. --- src/d3d11/d3d11_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 226899629..9bebbe48a 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3922,7 +3922,7 @@ namespace dxvk { constantCount = std::min(newBuffer->Desc()->ByteWidth / 16, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)); if (Bindings[StartSlot + i].buffer != newBuffer - || Bindings[StartSlot + i].constantCount != constantCount) { + || Bindings[StartSlot + i].constantBound != constantCount) { Bindings[StartSlot + i].buffer = newBuffer; Bindings[StartSlot + i].constantOffset = 0; Bindings[StartSlot + i].constantCount = constantCount; From e8d5ce94eaa957e60889168d676943d1eff5f027 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 13:52:29 +0200 Subject: [PATCH 0202/1348] [d3d9] Introduce D3D9ConstantBuffer --- src/d3d9/d3d9_constant_buffer.cpp | 121 ++++++++++++++++++++++++++++++ src/d3d9/d3d9_constant_buffer.h | 77 +++++++++++++++++++ src/d3d9/d3d9_device.h | 2 + src/d3d9/meson.build | 1 + 4 files changed, 201 insertions(+) create mode 100644 src/d3d9/d3d9_constant_buffer.cpp create mode 100644 src/d3d9/d3d9_constant_buffer.h diff --git a/src/d3d9/d3d9_constant_buffer.cpp b/src/d3d9/d3d9_constant_buffer.cpp new file mode 100644 index 000000000..f717d95ec --- /dev/null +++ b/src/d3d9/d3d9_constant_buffer.cpp @@ -0,0 +1,121 @@ +#include "d3d9_constant_buffer.h" +#include "d3d9_device.h" + +namespace dxvk { + + D3D9ConstantBuffer::D3D9ConstantBuffer() { + + } + + + D3D9ConstantBuffer::D3D9ConstantBuffer( + D3D9DeviceEx* pDevice, + DxsoProgramType ShaderStage, + DxsoConstantBuffers BufferType, + VkDeviceSize Size) + : m_device (pDevice) + , m_binding (computeResourceSlotId(ShaderStage, DxsoBindingType::ConstantBuffer, BufferType)) + , m_stages (GetShaderStage(ShaderStage)) + , m_size (Size) + , m_align (getAlignment(pDevice->GetDXVKDevice())) { + + } + + + D3D9ConstantBuffer::~D3D9ConstantBuffer() { + + } + + + void* D3D9ConstantBuffer::Alloc(VkDeviceSize size) { + if (unlikely(m_buffer == nullptr)) { + this->createBuffer(); + m_slice = m_buffer->getSliceHandle(); + } + + size = align(size, m_align); + + if (unlikely(m_offset + size > m_size)) { + m_slice = m_buffer->allocSlice(); + m_offset = 0; + + m_device->EmitCs([ + cBuffer = m_buffer, + cSlice = m_slice + ] (DxvkContext* ctx) { + ctx->invalidateBuffer(cBuffer, cSlice); + }); + } + + m_device->EmitCs([ + cStages = m_stages, + cBinding = m_binding, + cOffset = m_offset, + cLength = size + ] (DxvkContext* ctx) { + ctx->bindResourceBufferRange(cStages, cBinding, cOffset, cLength); + }); + + void* mapPtr = reinterpret_cast(m_slice.mapPtr) + m_offset; + m_offset += size; + return mapPtr; + } + + + void* D3D9ConstantBuffer::AllocSlice() { + if (unlikely(m_buffer == nullptr)) + this->createBuffer(); + + m_slice = m_buffer->allocSlice(); + + m_device->EmitCs([ + cBuffer = m_buffer, + cSlice = m_slice + ] (DxvkContext* ctx) { + ctx->invalidateBuffer(cBuffer, cSlice); + }); + + return m_slice.mapPtr; + } + + + void D3D9ConstantBuffer::createBuffer() { + auto options = m_device->GetOptions(); + + // Buffer usage and access flags don't make much of a difference + // in the backend, so set both STORAGE and UNIFORM usage/access. + DxvkBufferCreateInfo bufferInfo; + bufferInfo.size = align(m_size, m_align); + bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT + | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + bufferInfo.access = VK_ACCESS_UNIFORM_READ_BIT + | VK_ACCESS_SHADER_READ_BIT; + bufferInfo.stages = util::pipelineStages(m_stages); + + VkMemoryPropertyFlags memoryFlags + = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT + | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + + if (options->deviceLocalConstantBuffers) + memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + + m_buffer = m_device->GetDXVKDevice()->createBuffer(bufferInfo, memoryFlags); + + m_device->EmitCs([ + cStages = m_stages, + cBinding = m_binding, + cSlice = DxvkBufferSlice(m_buffer) + ] (DxvkContext* ctx) { + ctx->bindResourceBuffer(cStages, cBinding, cSlice); + }); + } + + + VkDeviceSize D3D9ConstantBuffer::getAlignment(const Rc& device) const { + return std::max(std::max( + device->properties().core.properties.limits.minUniformBufferOffsetAlignment, + device->properties().core.properties.limits.minStorageBufferOffsetAlignment), + device->properties().extRobustness2.robustUniformBufferAccessSizeAlignment); + } + +} diff --git a/src/d3d9/d3d9_constant_buffer.h b/src/d3d9/d3d9_constant_buffer.h new file mode 100644 index 000000000..1dff07a96 --- /dev/null +++ b/src/d3d9/d3d9_constant_buffer.h @@ -0,0 +1,77 @@ +#pragma once + +#include "../dxvk/dxvk_buffer.h" + +#include "../dxso/dxso_util.h" + +#include "../util/util_math.h" + +#include "d3d9_include.h" + +namespace dxvk { + + class D3D9DeviceEx; + + /** + * \brief Constant buffer + */ + class D3D9ConstantBuffer { + + public: + + D3D9ConstantBuffer(); + + D3D9ConstantBuffer( + D3D9DeviceEx* pDevice, + DxsoProgramType ShaderStage, + DxsoConstantBuffers BufferType, + VkDeviceSize Size); + + ~D3D9ConstantBuffer(); + + /** + * \brief Queries alignment + * + * Useful to pad copies with initialized data. + * \returns Data alignment + */ + VkDeviceSize GetAlignment() const { + return m_align; + } + + /** + * \brief Allocates a given amount of memory + * + * \param [in] size Number of bytes to allocate + * \returns Map pointer of the allocated region + */ + void* Alloc(VkDeviceSize size); + + /** + * \brief Allocates a full buffer slice + * + * This must not be called if \ref Alloc is used. + * \returns Map pointer of the allocated region + */ + void* AllocSlice(); + + private: + + D3D9DeviceEx* m_device = nullptr; + + uint32_t m_binding = 0u; + VkShaderStageFlags m_stages = 0u; + VkDeviceSize m_size = 0ull; + VkDeviceSize m_align = 0ull; + VkDeviceSize m_offset = 0ull; + + Rc m_buffer = nullptr; + DxvkBufferSliceHandle m_slice = { }; + + void createBuffer(); + + VkDeviceSize getAlignment(const Rc& device) const; + + }; + +} \ No newline at end of file diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index ae48ba0a1..28f427f0c 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -8,6 +8,7 @@ #include "d3d9_format.h" #include "d3d9_multithread.h" #include "d3d9_adapter.h" +#include "d3d9_constant_buffer.h" #include "d3d9_constant_set.h" #include "d3d9_state.h" @@ -99,6 +100,7 @@ namespace dxvk { constexpr static uint32_t NullStreamIdx = caps::MaxStreams; friend class D3D9SwapChainEx; + friend class D3D9ConstantBuffer; friend class D3D9UserDefinedAnnotation; public: diff --git a/src/d3d9/meson.build b/src/d3d9/meson.build index 2cd8951e2..476525cc4 100644 --- a/src/d3d9/meson.build +++ b/src/d3d9/meson.build @@ -20,6 +20,7 @@ d3d9_src = [ 'd3d9_swapchain.cpp', 'd3d9_format.cpp', 'd3d9_common_texture.cpp', + 'd3d9_constant_buffer.cpp', 'd3d9_texture.cpp', 'd3d9_surface.cpp', 'd3d9_volume.cpp', From 08c3c4585396a6a340631ea39e443d6295284ffe Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 14:29:52 +0200 Subject: [PATCH 0203/1348] [d3d9] Use generic constant buffer implementation --- src/d3d9/d3d9_constant_set.h | 3 +- src/d3d9/d3d9_device.cpp | 162 +++++++++++------------------------ src/d3d9/d3d9_device.h | 10 +-- 3 files changed, 55 insertions(+), 120 deletions(-) diff --git a/src/d3d9/d3d9_constant_set.h b/src/d3d9/d3d9_constant_set.h index a927a1b15..9f3d4ad74 100644 --- a/src/d3d9/d3d9_constant_set.h +++ b/src/d3d9/d3d9_constant_set.h @@ -1,6 +1,7 @@ #pragma once #include "d3d9_caps.h" +#include "d3d9_constant_buffer.h" #include "../dxvk/dxvk_buffer.h" @@ -46,7 +47,7 @@ namespace dxvk { struct D3D9ConstantSets { D3D9SwvpConstantBuffers swvpBuffers; - Rc buffer; + D3D9ConstantBuffer buffer; DxsoShaderMetaInfo meta = {}; bool dirty = true; }; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 0fc7efb0a..f459d4cac 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4905,51 +4905,47 @@ namespace dxvk { void D3D9DeviceEx::CreateConstantBuffers() { + constexpr VkDeviceSize DefaultConstantBufferSize = 1024ull << 10; + if (!m_isSWVP) { - m_consts[DxsoProgramTypes::VertexShader].buffer = - CreateConstantBuffer(false, - m_vsLayout.totalSize(), - DxsoProgramType::VertexShader, - DxsoConstantBuffers::VSConstantBuffer); + m_consts[DxsoProgramTypes::VertexShader].buffer = D3D9ConstantBuffer(this, + DxsoProgramType::VertexShader, + DxsoConstantBuffers::VSConstantBuffer, + DefaultConstantBufferSize); } + // SWVP constant buffers are created late based on the amount of constants set by the application - m_consts[DxsoProgramTypes::PixelShader].buffer = - CreateConstantBuffer(false, - m_psLayout.totalSize(), - DxsoProgramType::PixelShader, - DxsoConstantBuffers::PSConstantBuffer); + m_consts[DxsoProgramTypes::PixelShader].buffer = D3D9ConstantBuffer(this, + DxsoProgramType::PixelShader, + DxsoConstantBuffers::PSConstantBuffer, + DefaultConstantBufferSize); - m_vsClipPlanes = - CreateConstantBuffer(false, - caps::MaxClipPlanes * sizeof(D3D9ClipPlane), - DxsoProgramType::VertexShader, - DxsoConstantBuffers::VSClipPlanes); + m_vsClipPlanes = D3D9ConstantBuffer(this, + DxsoProgramType::VertexShader, + DxsoConstantBuffers::VSClipPlanes, + caps::MaxClipPlanes * sizeof(D3D9ClipPlane)); - m_vsFixedFunction = - CreateConstantBuffer(false, - sizeof(D3D9FixedFunctionVS), - DxsoProgramType::VertexShader, - DxsoConstantBuffers::VSFixedFunction); + m_vsFixedFunction = D3D9ConstantBuffer(this, + DxsoProgramType::VertexShader, + DxsoConstantBuffers::VSFixedFunction, + sizeof(D3D9FixedFunctionVS)); - m_psFixedFunction = - CreateConstantBuffer(false, - sizeof(D3D9FixedFunctionPS), - DxsoProgramType::PixelShader, - DxsoConstantBuffers::PSFixedFunction); + m_psFixedFunction = D3D9ConstantBuffer(this, + DxsoProgramType::PixelShader, + DxsoConstantBuffers::PSFixedFunction, + sizeof(D3D9FixedFunctionPS)); - m_psShared = - CreateConstantBuffer(false, - sizeof(D3D9SharedPS), - DxsoProgramType::PixelShader, - DxsoConstantBuffers::PSShared); + m_psShared = D3D9ConstantBuffer(this, + DxsoProgramType::PixelShader, + DxsoConstantBuffers::PSShared, + sizeof(D3D9SharedPS)); - m_vsVertexBlend = - CreateConstantBuffer(true, - CanSWVP() - ? sizeof(D3D9FixedFunctionVertexBlendDataSW) - : sizeof(D3D9FixedFunctionVertexBlendDataHW), - DxsoProgramType::VertexShader, - DxsoConstantBuffers::VSVertexBlendData); + m_vsVertexBlend = D3D9ConstantBuffer(this, + DxsoProgramType::VertexShader, + DxsoConstantBuffers::VSVertexBlendData, + CanSWVP() + ? sizeof(D3D9FixedFunctionVertexBlendDataSW) + : sizeof(D3D9FixedFunctionVertexBlendDataHW)); } @@ -5059,36 +5055,12 @@ namespace dxvk { const uint32_t intRange = caps::MaxOtherConstants * sizeof(Vector4i); const uint32_t intDataSize = constSet.meta.maxConstIndexI * sizeof(Vector4i); uint32_t floatDataSize = floatCount * sizeof(Vector4); - const uint32_t alignment = std::max(m_robustUBOAlignment, 64u); // Make sure we do not recreate the buffer because the new one has to be a tiny bit larger + const uint32_t alignment = constSet.buffer.GetAlignment(); const uint32_t bufferSize = align(std::max(floatDataSize + intRange, alignment), alignment); - floatDataSize = bufferSize - intRange; // Read additional floats for padding so we don't end up with garbage data + floatDataSize = bufferSize - intRange; - VkDeviceSize& boundConstantBufferSize = ShaderStage == DxsoProgramType::VertexShader ? m_boundVSConstantsBufferSize : m_boundPSConstantsBufferSize; - if (boundConstantBufferSize < bufferSize) { - constexpr uint32_t slotId = computeResourceSlotId(ShaderStage, DxsoBindingType::ConstantBuffer, 0); - EmitCs([ - cBuffer = constSet.buffer, - cSlotId = slotId, - cSize = bufferSize - ] (DxvkContext* ctx) { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - - ctx->bindResourceBuffer(stage, cSlotId, - DxvkBufferSlice(cBuffer, 0, cSize)); - }); - boundConstantBufferSize = bufferSize; - } - - DxvkBufferSliceHandle slice = constSet.buffer->allocSlice(); - - EmitCs([ - cBuffer = constSet.buffer, - cSlice = slice - ] (DxvkContext* ctx) { - ctx->invalidateBuffer(cBuffer, cSlice); - }); - - auto* dst = reinterpret_cast(slice.mapPtr); + void* mapPtr = constSet.buffer.Alloc(bufferSize); + auto* dst = reinterpret_cast(mapPtr); if (constSet.meta.maxConstIndexI != 0) std::memcpy(dst->iConsts, Src.iConsts, intDataSize); @@ -5124,21 +5096,14 @@ namespace dxvk { void D3D9DeviceEx::UpdateClipPlanes() { m_flags.clr(D3D9DeviceFlag::DirtyClipPlanes); - auto slice = m_vsClipPlanes->allocSlice(); - auto dst = reinterpret_cast(slice.mapPtr); + auto mapPtr = m_vsClipPlanes.AllocSlice(); + auto dst = reinterpret_cast(mapPtr); for (uint32_t i = 0; i < caps::MaxClipPlanes; i++) { dst[i] = (m_state.renderStates[D3DRS_CLIPPLANEENABLE] & (1 << i)) ? m_state.clipPlanes[i] : D3D9ClipPlane(); } - - EmitCs([ - cBuffer = m_vsClipPlanes, - cSlice = slice - ] (DxvkContext* ctx) { - ctx->invalidateBuffer(cBuffer, cSlice); - }); } @@ -6216,16 +6181,8 @@ namespace dxvk { if (m_flags.test(D3D9DeviceFlag::DirtySharedPixelShaderData)) { m_flags.clr(D3D9DeviceFlag::DirtySharedPixelShaderData); - DxvkBufferSliceHandle slice = m_psShared->allocSlice(); - - EmitCs([ - cBuffer = m_psShared, - cSlice = slice - ] (DxvkContext* ctx) { - ctx->invalidateBuffer(cBuffer, cSlice); - }); - - D3D9SharedPS* data = reinterpret_cast(slice.mapPtr); + auto mapPtr = m_psShared.AllocSlice(); + D3D9SharedPS* data = reinterpret_cast(mapPtr); for (uint32_t i = 0; i < caps::TextureStageCount; i++) { DecodeD3DCOLOR(D3DCOLOR(m_state.textureStages[i][DXVK_TSS_CONSTANT]), data->Stages[i].Constant); @@ -6683,19 +6640,12 @@ namespace dxvk { if (m_flags.test(D3D9DeviceFlag::DirtyFFVertexData)) { m_flags.clr(D3D9DeviceFlag::DirtyFFVertexData); - DxvkBufferSliceHandle slice = m_vsFixedFunction->allocSlice(); - - EmitCs([ - cBuffer = m_vsFixedFunction, - cSlice = slice - ] (DxvkContext* ctx) { - ctx->invalidateBuffer(cBuffer, cSlice); - }); + auto mapPtr = m_vsFixedFunction.AllocSlice(); auto WorldView = m_state.transforms[GetTransformIndex(D3DTS_VIEW)] * m_state.transforms[GetTransformIndex(D3DTS_WORLD)]; auto NormalMatrix = inverse(WorldView); - D3D9FixedFunctionVS* data = reinterpret_cast(slice.mapPtr); + D3D9FixedFunctionVS* data = reinterpret_cast(mapPtr); data->WorldView = WorldView; data->NormalMatrix = NormalMatrix; data->InverseView = transpose(inverse(m_state.transforms[GetTransformIndex(D3DTS_VIEW)])); @@ -6724,23 +6674,15 @@ namespace dxvk { if (m_flags.test(D3D9DeviceFlag::DirtyFFVertexBlend) && vertexBlendMode == D3D9FF_VertexBlendMode_Normal) { m_flags.clr(D3D9DeviceFlag::DirtyFFVertexBlend); - DxvkBufferSliceHandle slice = m_vsVertexBlend->allocSlice(); - - EmitCs([ - cBuffer = m_vsVertexBlend, - cSlice = slice - ] (DxvkContext* ctx) { - ctx->invalidateBuffer(cBuffer, cSlice); - }); - + auto mapPtr = m_vsVertexBlend.AllocSlice(); auto UploadVertexBlendData = [&](auto data) { for (uint32_t i = 0; i < std::size(data->WorldView); i++) data->WorldView[i] = m_state.transforms[GetTransformIndex(D3DTS_VIEW)] * m_state.transforms[GetTransformIndex(D3DTS_WORLDMATRIX(i))]; }; (m_isSWVP && indexedVertexBlend) - ? UploadVertexBlendData(reinterpret_cast(slice.mapPtr)) - : UploadVertexBlendData(reinterpret_cast(slice.mapPtr)); + ? UploadVertexBlendData(reinterpret_cast(mapPtr)) + : UploadVertexBlendData(reinterpret_cast(mapPtr)); } } @@ -6842,18 +6784,10 @@ namespace dxvk { if (m_flags.test(D3D9DeviceFlag::DirtyFFPixelData)) { m_flags.clr(D3D9DeviceFlag::DirtyFFPixelData); - DxvkBufferSliceHandle slice = m_psFixedFunction->allocSlice(); - - EmitCs([ - cBuffer = m_psFixedFunction, - cSlice = slice - ] (DxvkContext* ctx) { - ctx->invalidateBuffer(cBuffer, cSlice); - }); - + auto mapPtr = m_psFixedFunction.AllocSlice(); auto& rs = m_state.renderStates; - D3D9FixedFunctionPS* data = reinterpret_cast(slice.mapPtr); + D3D9FixedFunctionPS* data = reinterpret_cast(mapPtr); DecodeD3DCOLOR((D3DCOLOR)rs[D3DRS_TEXTUREFACTOR], data->textureFactor.data); } } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 28f427f0c..f498a01ec 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1162,12 +1162,12 @@ namespace dxvk { Rc m_shaderModules; - Rc m_vsClipPlanes; + D3D9ConstantBuffer m_vsClipPlanes; - Rc m_vsFixedFunction; - Rc m_vsVertexBlend; - Rc m_psFixedFunction; - Rc m_psShared; + D3D9ConstantBuffer m_vsFixedFunction; + D3D9ConstantBuffer m_vsVertexBlend; + D3D9ConstantBuffer m_psFixedFunction; + D3D9ConstantBuffer m_psShared; D3D9BufferSlice m_upBuffer; D3D9BufferSlice m_managedUploadBuffer; From 4635c72e9527e950f5f2fefe19a1e31a178b77dc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 15:31:29 +0200 Subject: [PATCH 0204/1348] [d3d9] Use generic constant buffers for SWVP --- src/d3d9/d3d9_constant_set.h | 7 ++-- src/d3d9/d3d9_device.cpp | 65 +++++++++++++++--------------------- src/d3d9/d3d9_device.h | 2 +- 3 files changed, 31 insertions(+), 43 deletions(-) diff --git a/src/d3d9/d3d9_constant_set.h b/src/d3d9/d3d9_constant_set.h index 9f3d4ad74..fb64a586b 100644 --- a/src/d3d9/d3d9_constant_set.h +++ b/src/d3d9/d3d9_constant_set.h @@ -40,13 +40,12 @@ namespace dxvk { }; struct D3D9SwvpConstantBuffers { - Rc floatBuffer; - Rc intBuffer; - Rc boolBuffer; + D3D9ConstantBuffer intBuffer; + D3D9ConstantBuffer boolBuffer; }; struct D3D9ConstantSets { - D3D9SwvpConstantBuffers swvpBuffers; + D3D9SwvpConstantBuffers swvp; D3D9ConstantBuffer buffer; DxsoShaderMetaInfo meta = {}; bool dirty = true; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index f459d4cac..dcb1ab6af 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4906,15 +4906,23 @@ namespace dxvk { void D3D9DeviceEx::CreateConstantBuffers() { constexpr VkDeviceSize DefaultConstantBufferSize = 1024ull << 10; + constexpr VkDeviceSize SmallConstantBufferSize = 64ull << 10; - if (!m_isSWVP) { - m_consts[DxsoProgramTypes::VertexShader].buffer = D3D9ConstantBuffer(this, - DxsoProgramType::VertexShader, - DxsoConstantBuffers::VSConstantBuffer, - DefaultConstantBufferSize); - } + m_consts[DxsoProgramTypes::VertexShader].buffer = D3D9ConstantBuffer(this, + DxsoProgramType::VertexShader, + DxsoConstantBuffers::VSConstantBuffer, + DefaultConstantBufferSize); + + m_consts[DxsoProgramTypes::VertexShader].swvp.intBuffer = D3D9ConstantBuffer(this, + DxsoProgramType::VertexShader, + DxsoConstantBuffers::VSIntConstantBuffer, + SmallConstantBufferSize); + + m_consts[DxsoProgramTypes::VertexShader].swvp.boolBuffer = D3D9ConstantBuffer(this, + DxsoProgramType::VertexShader, + DxsoConstantBuffers::VSBoolConstantBuffer, + SmallConstantBufferSize); - // SWVP constant buffers are created late based on the amount of constants set by the application m_consts[DxsoProgramTypes::PixelShader].buffer = D3D9ConstantBuffer(this, DxsoProgramType::PixelShader, DxsoConstantBuffers::PSConstantBuffer, @@ -4975,14 +4983,13 @@ namespace dxvk { const uint32_t intDataSize = std::min(constSet.meta.maxConstIndexI, m_vsIntConstsCount) * sizeof(Vector4i); const uint32_t boolDataSize = divCeil(std::min(constSet.meta.maxConstIndexB, m_vsBoolConstsCount), 32u) * uint32_t(sizeof(uint32_t)); - Rc& floatBuffer = constSet.swvpBuffers.floatBuffer; // Max copy source size is 8192 * 16 => always aligned to any plausible value // => we won't copy out of bounds - if (likely(constSet.meta.maxConstIndexF != 0 || floatBuffer == nullptr)) { - DxvkBufferSliceHandle floatBufferSlice = CopySoftwareConstants(DxsoConstantBuffers::VSFloatConstantBuffer, floatBuffer, Src.fConsts, floatDataSize, m_dxsoOptions.vertexFloatConstantBufferAsSSBO); + if (likely(constSet.meta.maxConstIndexF != 0)) { + auto mapPtr = CopySoftwareConstants(constSet.buffer, Src.fConsts, floatDataSize); if (constSet.meta.needsConstantCopies) { - Vector4* data = reinterpret_cast(floatBufferSlice.mapPtr); + Vector4* data = reinterpret_cast(mapPtr); auto& shaderConsts = GetCommonShader(m_state.vertexShader)->GetConstants(); @@ -4993,42 +5000,24 @@ namespace dxvk { } } - Rc& intBuffer = constSet.swvpBuffers.intBuffer; // Max copy source size is 2048 * 16 => always aligned to any plausible value // => we won't copy out of bounds - if (likely(constSet.meta.maxConstIndexI != 0 || intBuffer == nullptr)) { - CopySoftwareConstants(DxsoConstantBuffers::VSIntConstantBuffer, intBuffer, Src.iConsts, intDataSize, false); - } + if (likely(constSet.meta.maxConstIndexI != 0)) + CopySoftwareConstants(constSet.swvp.intBuffer, Src.iConsts, intDataSize); - Rc& boolBuffer = constSet.swvpBuffers.boolBuffer; - if (likely(constSet.meta.maxConstIndexB != 0 || boolBuffer == nullptr)) { - CopySoftwareConstants(DxsoConstantBuffers::VSBoolConstantBuffer, boolBuffer, Src.bConsts, boolDataSize, false); - } + if (likely(constSet.meta.maxConstIndexB != 0)) + CopySoftwareConstants(constSet.swvp.boolBuffer, Src.bConsts, boolDataSize); } - inline DxvkBufferSliceHandle D3D9DeviceEx::CopySoftwareConstants(DxsoConstantBuffers cBufferTarget, Rc& dstBuffer, const void* src, uint32_t size, bool useSSBO) { - uint32_t alignment = useSSBO ? m_robustSSBOAlignment : m_robustUBOAlignment; - alignment = std::max(alignment, 64u); + inline void* D3D9DeviceEx::CopySoftwareConstants(D3D9ConstantBuffer& dstBuffer, const void* src, uint32_t size) { + uint32_t alignment = dstBuffer.GetAlignment(); size = std::max(size, alignment); size = align(size, alignment); - DxvkBufferSliceHandle slice; - if (unlikely(dstBuffer == nullptr || dstBuffer->info().size < size)) { - dstBuffer = CreateConstantBuffer(useSSBO, size, DxsoProgramType::VertexShader, cBufferTarget); - slice = dstBuffer->getSliceHandle(); - } else { - slice = dstBuffer->allocSlice(); - EmitCs([ - cBuffer = dstBuffer, - cSlice = slice - ] (DxvkContext* ctx) { - ctx->invalidateBuffer(cBuffer, cSlice); - }); - } - - std::memcpy(slice.mapPtr, src, size); - return slice; + auto mapPtr = dstBuffer.Alloc(size); + std::memcpy(mapPtr, src, size); + return mapPtr; } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index f498a01ec..bb814d9ed 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -829,7 +829,7 @@ namespace dxvk { inline void UploadSoftwareConstantSet(const D3D9ShaderConstantsVSSoftware& Src, const D3D9ConstantLayout& Layout); - inline DxvkBufferSliceHandle CopySoftwareConstants(DxsoConstantBuffers cBufferTarget, Rc& dstBuffer, const void* src, uint32_t copySize, bool useSSBO); + inline void* CopySoftwareConstants(D3D9ConstantBuffer& dstBuffer, const void* src, uint32_t size); template inline void UploadConstantSet(const SoftwareLayoutType& Src, const D3D9ConstantLayout& Layout, const ShaderType& Shader); From 74a8bfb7749ffe5a781bd6278d341e8295fcae77 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 15:32:56 +0200 Subject: [PATCH 0205/1348] [d3d9] Remove CreateConstantBuffer method --- src/d3d9/d3d9_device.cpp | 43 ---------------------------------------- src/d3d9/d3d9_device.h | 6 ------ 2 files changed, 49 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index dcb1ab6af..83b387a78 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4861,49 +4861,6 @@ namespace dxvk { } - Rc D3D9DeviceEx::CreateConstantBuffer( - bool SSBO, - VkDeviceSize Size, - DxsoProgramType ShaderStage, - DxsoConstantBuffers BufferType) { - DxvkBufferCreateInfo info = { }; - info.usage = SSBO ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - info.access = SSBO ? VK_ACCESS_SHADER_READ_BIT : VK_ACCESS_UNIFORM_READ_BIT; - info.size = Size; - info.stages = ShaderStage == DxsoProgramType::VertexShader - ? VK_PIPELINE_STAGE_VERTEX_SHADER_BIT - : VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - - VkMemoryPropertyFlags memoryFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT - | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - - if (m_d3d9Options.deviceLocalConstantBuffers) - memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - - Rc buffer = m_dxvkDevice->createBuffer(info, memoryFlags); - - const uint32_t slotId = computeResourceSlotId( - ShaderStage, DxsoBindingType::ConstantBuffer, - BufferType); - - EmitCs([ - cShaderStage = GetShaderStage(ShaderStage), - cSlotId = slotId, - cBuffer = buffer - ] (DxvkContext* ctx) { - ctx->bindResourceBuffer(cShaderStage, cSlotId, - DxvkBufferSlice(cBuffer, 0, cBuffer->info().size)); - }); - - if (ShaderStage == DxsoProgramType::PixelShader) - m_boundPSConstantsBufferSize = buffer->info().size; - else - m_boundVSConstantsBufferSize = buffer->info().size; - - return buffer; - } - - void D3D9DeviceEx::CreateConstantBuffers() { constexpr VkDeviceSize DefaultConstantBufferSize = 1024ull << 10; constexpr VkDeviceSize SmallConstantBufferSize = 64ull << 10; diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index bb814d9ed..949728ad8 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -737,12 +737,6 @@ namespace dxvk { int64_t DetermineInitialTextureMemory(); - Rc CreateConstantBuffer( - bool SSBO, - VkDeviceSize Size, - DxsoProgramType ShaderStage, - DxsoConstantBuffers BufferType); - void CreateConstantBuffers(); void SynchronizeCsThread(uint64_t SequenceNumber); From 9e110cd3e5816bfa612fe8c967699d4cb108730f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 13 Jul 2022 13:44:08 +0200 Subject: [PATCH 0206/1348] [d3d9] Fix up unsupported sample counts --- src/d3d9/d3d9_common_texture.cpp | 4 ++-- src/d3d9/d3d9_device.cpp | 4 ++-- src/d3d9/d3d9_util.cpp | 13 ++++++++++--- src/d3d9/d3d9_util.h | 7 ++++--- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index b0681d495..22bc37c91 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -134,7 +134,7 @@ namespace dxvk { if (pDesc->Width == 0 || pDesc->Height == 0 || pDesc->Depth == 0) return D3DERR_INVALIDCALL; - if (FAILED(DecodeMultiSampleType(pDesc->MultiSample, pDesc->MultisampleQuality, nullptr))) + if (FAILED(DecodeMultiSampleType(pDevice->GetDXVKDevice(), pDesc->MultiSample, pDesc->MultisampleQuality, nullptr))) return D3DERR_INVALIDCALL; // Using MANAGED pool with DYNAMIC usage is illegal @@ -258,7 +258,7 @@ namespace dxvk { imageInfo.stages |= VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; } - DecodeMultiSampleType(m_desc.MultiSample, m_desc.MultisampleQuality, &imageInfo.sampleCount); + DecodeMultiSampleType(m_device->GetDXVKDevice(), m_desc.MultiSample, m_desc.MultisampleQuality, &imageInfo.sampleCount); // The image must be marked as mutable if it can be reinterpreted // by a view with a different format. Depth-stencil formats cannot diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 83b387a78..d1ce4ed1d 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -6836,7 +6836,7 @@ namespace dxvk { const D3D9_COMMON_TEXTURE_DESC* dstDesc = dstTextureInfo->Desc(); VkSampleCountFlagBits dstSampleCount; - DecodeMultiSampleType(dstDesc->MultiSample, dstDesc->MultisampleQuality, &dstSampleCount); + DecodeMultiSampleType(m_dxvkDevice, dstDesc->MultiSample, dstDesc->MultisampleQuality, &dstSampleCount); if (unlikely(dstSampleCount != VK_SAMPLE_COUNT_1_BIT)) { Logger::warn("D3D9DeviceEx::ResolveZ: dstSampleCount != 1. Discarding."); @@ -6868,7 +6868,7 @@ namespace dxvk { srcSubresource.arrayLayer, 1 }; VkSampleCountFlagBits srcSampleCount; - DecodeMultiSampleType(srcDesc->MultiSample, srcDesc->MultisampleQuality, &srcSampleCount); + DecodeMultiSampleType(m_dxvkDevice, srcDesc->MultiSample, srcDesc->MultisampleQuality, &srcSampleCount); if (srcSampleCount == VK_SAMPLE_COUNT_1_BIT) { EmitCs([ diff --git a/src/d3d9/d3d9_util.cpp b/src/d3d9/d3d9_util.cpp index b278fed73..b5d24f44c 100644 --- a/src/d3d9/d3d9_util.cpp +++ b/src/d3d9/d3d9_util.cpp @@ -37,9 +37,10 @@ namespace dxvk { HRESULT DecodeMultiSampleType( + const Rc& pDevice, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, - VkSampleCountFlagBits* pCount) { + VkSampleCountFlagBits* pSampleCount) { uint32_t sampleCount = std::max(MultiSample, 1u); // Check if this is a power of two... @@ -49,8 +50,14 @@ namespace dxvk { if (MultiSample == D3DMULTISAMPLE_NONMASKABLE) sampleCount = 1u << MultisampleQuality; - if (pCount != nullptr) - *pCount = VkSampleCountFlagBits(sampleCount); + const auto& limits = pDevice->properties().core.properties.limits; + VkSampleCountFlags supportedSampleCounts = limits.framebufferColorSampleCounts & limits.framebufferDepthSampleCounts; + + while (sampleCount > supportedSampleCounts) + sampleCount >>= 1; + + if (pSampleCount) + *pSampleCount = VkSampleCountFlagBits(sampleCount); return D3D_OK; } diff --git a/src/d3d9/d3d9_util.h b/src/d3d9/d3d9_util.h index 4f337abbc..5899cd4c5 100644 --- a/src/d3d9/d3d9_util.h +++ b/src/d3d9/d3d9_util.h @@ -95,9 +95,10 @@ namespace dxvk { ID3DBlob** ppDisassembly); HRESULT DecodeMultiSampleType( - D3DMULTISAMPLE_TYPE MultiSample, - DWORD MultisampleQuality, - VkSampleCountFlagBits* pCount); + const Rc& pDevice, + D3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, + VkSampleCountFlagBits* pSampleCount); VkFormat GetPackedDepthStencilFormat(D3D9Format Format); From 5ae5476d71f6363b72dda093d9a605bf423a5c25 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Thu, 14 Jul 2022 16:20:20 +0200 Subject: [PATCH 0207/1348] [d3d9] Make reported sample counts consistent with DecodeMultiSampleType behavior. --- src/d3d9/d3d9_adapter.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/d3d9/d3d9_adapter.cpp b/src/d3d9/d3d9_adapter.cpp index 4e93fb1ad..ac8da7978 100644 --- a/src/d3d9/d3d9_adapter.cpp +++ b/src/d3d9/d3d9_adapter.cpp @@ -195,9 +195,8 @@ namespace dxvk { // Therefore... VkSampleCountFlags sampleFlags = VkSampleCountFlags(sampleCount); - auto availableFlags = !IsDepthFormat(SurfaceFormat) - ? m_adapter->deviceProperties().limits.framebufferColorSampleCounts - : m_adapter->deviceProperties().limits.framebufferDepthSampleCounts; + auto availableFlags = m_adapter->deviceProperties().limits.framebufferColorSampleCounts + & m_adapter->deviceProperties().limits.framebufferDepthSampleCounts; if (!(availableFlags & sampleFlags)) return D3DERR_NOTAVAILABLE; From e884413c492a1632320ee620862f2c5bc897c630 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 6 Jul 2022 17:11:58 +0100 Subject: [PATCH 0208/1348] [dxvk] Don't synchronize device if going for DLL shutdown All our other threads have been destroyed and we can no longer synchronize with them properly. Co-authored-by: Paul Gofman --- src/d3d11/d3d11_context_imm.cpp | 5 +++++ src/d3d11/d3d11_swapchain.cpp | 5 +++++ src/d3d9/d3d9_device.cpp | 5 +++++ src/d3d9/d3d9_swapchain.cpp | 5 +++++ src/dxvk/dxvk_device.cpp | 7 +++++++ src/util/thread.cpp | 17 ++++++++++++++++- src/util/thread.h | 6 ++++++ 7 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 15e4accfe..489e77bce 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -39,6 +39,11 @@ namespace dxvk { D3D11ImmediateContext::~D3D11ImmediateContext() { + // Avoids hanging when in this state, see comment + // in DxvkDevice::~DxvkDevice. + if (this_thread::isInModuleDetachment()) + return; + Flush(); SynchronizeCsThread(DxvkCsThread::SynchronizeAll); SynchronizeDevice(); diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 771ade123..9cc114625 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -35,6 +35,11 @@ namespace dxvk { D3D11SwapChain::~D3D11SwapChain() { + // Avoids hanging when in this state, see comment + // in DxvkDevice::~DxvkDevice. + if (this_thread::isInModuleDetachment()) + return; + m_device->waitForSubmission(&m_presentStatus); m_device->waitForIdle(); diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index d1ce4ed1d..5df944908 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -145,6 +145,11 @@ namespace dxvk { D3D9DeviceEx::~D3D9DeviceEx() { + // Avoids hanging when in this state, see comment + // in DxvkDevice::~DxvkDevice. + if (this_thread::isInModuleDetachment()) + return; + Flush(); SynchronizeCsThread(DxvkCsThread::SynchronizeAll); diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 07f8e5cd2..f2c08bc0e 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -215,6 +215,11 @@ namespace dxvk { D3D9SwapChainEx::~D3D9SwapChainEx() { + // Avoids hanging when in this state, see comment + // in DxvkDevice::~DxvkDevice. + if (this_thread::isInModuleDetachment()) + return; + DestroyBackBuffers(); ResetWindowProc(m_window); diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index c532ba81f..979e1623a 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -26,6 +26,13 @@ namespace dxvk { DxvkDevice::~DxvkDevice() { + // If we are being destroyed during/after DLL process detachment + // from TerminateProcess, etc, our CS threads are already destroyed + // and we cannot synchronize against them. + // The best we can do is just wait for the Vulkan device to be idle. + if (this_thread::isInModuleDetachment()) + return; + // Wait for all pending Vulkan commands to be // executed before we destroy any resources. this->waitForIdle(); diff --git a/src/util/thread.cpp b/src/util/thread.cpp index eed45d34b..044ae6967 100644 --- a/src/util/thread.cpp +++ b/src/util/thread.cpp @@ -3,7 +3,22 @@ #include -#ifndef _WIN32 +#ifdef _WIN32 + +namespace dxvk::this_thread { + + bool isInModuleDetachment() { + using PFN_RtlDllShutdownInProgress = BOOLEAN (WINAPI *)(); + + static auto RtlDllShutdownInProgress = reinterpret_cast( + ::GetProcAddress(::GetModuleHandleW(L"ntdll.dll"), "RtlDllShutdownInProgress")); + + return RtlDllShutdownInProgress(); + } + +} + +#else namespace dxvk::this_thread { diff --git a/src/util/thread.h b/src/util/thread.h index bc58d229e..41750a99c 100644 --- a/src/util/thread.h +++ b/src/util/thread.h @@ -153,6 +153,8 @@ namespace dxvk { inline uint32_t get_id() { return uint32_t(GetCurrentThreadId()); } + + bool isInModuleDetachment(); } @@ -341,6 +343,10 @@ namespace dxvk { } uint32_t get_id(); + + inline bool isInModuleDetachment() { + return false; + } } #endif From f07a6e160c3f04d7da1522e1ec702205cb1a23d1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 16:15:59 +0200 Subject: [PATCH 0209/1348] [d3d9] Rework UP buffer allocation --- src/d3d9/d3d9_device.cpp | 93 ++++++++++++++++++++++++++-------------- src/d3d9/d3d9_device.h | 8 +++- 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 5df944908..0ce3ec290 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2489,7 +2489,7 @@ namespace dxvk { const uint32_t dataSize = GetUPDataSize(drawInfo.vertexCount, VertexStreamZeroStride); const uint32_t bufferSize = GetUPBufferSize(drawInfo.vertexCount, VertexStreamZeroStride); - auto upSlice = AllocTempBuffer(bufferSize); + auto upSlice = AllocUPBuffer(bufferSize); FillUPVertexBuffer(upSlice.mapPtr, pVertexStreamZeroData, dataSize, bufferSize); EmitCs([this, @@ -2547,7 +2547,7 @@ namespace dxvk { const uint32_t upSize = vertexBufferSize + indicesSize; - auto upSlice = AllocTempBuffer(upSize); + auto upSlice = AllocUPBuffer(upSize); uint8_t* data = reinterpret_cast(upSlice.mapPtr); FillUPVertexBuffer(data, pVertexStreamZeroData, vertexDataSize, vertexBufferSize); std::memcpy(data + vertexBufferSize, pIndexData, indicesSize); @@ -3967,7 +3967,52 @@ namespace dxvk { } - template + D3D9BufferSlice D3D9DeviceEx::AllocUPBuffer(VkDeviceSize size) { + constexpr VkDeviceSize UPBufferSize = 1 << 20; + + if (unlikely(m_upBuffer == nullptr)) { + VkMemoryPropertyFlags memoryFlags + = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT + | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT + | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + + DxvkBufferCreateInfo info; + info.size = UPBufferSize; + info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT + | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT + | VK_ACCESS_INDEX_READ_BIT; + info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; + + m_upBuffer = m_dxvkDevice->createBuffer(info, memoryFlags); + m_upBufferMapPtr = m_upBuffer->mapPtr(0); + } + + VkDeviceSize alignedSize = align(size, CACHE_LINE_SIZE); + + if (unlikely(m_upBufferOffset + alignedSize > UPBufferSize)) { + auto sliceHandle = m_upBuffer->allocSlice(); + + m_upBufferOffset = 0; + m_upBufferMapPtr = sliceHandle.mapPtr; + + EmitCs([ + cBuffer = m_upBuffer, + cSlice = sliceHandle + ] (DxvkContext* ctx) { + ctx->invalidateBuffer(cBuffer, cSlice); + }); + } + + D3D9BufferSlice result; + result.slice = DxvkBufferSlice(m_upBuffer, m_upBufferOffset, size); + result.mapPtr = reinterpret_cast(m_upBufferMapPtr) + m_upBufferOffset; + + m_upBufferOffset += alignedSize; + return result; + } + + D3D9BufferSlice D3D9DeviceEx::AllocTempBuffer(VkDeviceSize size) { constexpr VkDeviceSize DefaultSize = 1 << 20; @@ -3975,27 +4020,15 @@ namespace dxvk { = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - if constexpr (UpBuffer) { - memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - } - - D3D9BufferSlice& currentSlice = UpBuffer ? m_upBuffer : m_managedUploadBuffer; + D3D9BufferSlice& currentSlice = m_managedUploadBuffer; if (size <= DefaultSize) { if (unlikely(!currentSlice.slice.defined())) { DxvkBufferCreateInfo info; info.size = DefaultSize; - if constexpr (UpBuffer) { - info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT - | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; - info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT - | VK_ACCESS_INDEX_READ_BIT; - info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; - } else { - info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; - info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - info.access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT; - } + info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; + info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + info.access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT; currentSlice.slice = DxvkBufferSlice(m_dxvkDevice->createBuffer(info, memoryFlags)); currentSlice.mapPtr = currentSlice.slice.mapPtr(0); @@ -4024,17 +4057,11 @@ namespace dxvk { // Create a temporary buffer for very large allocations DxvkBufferCreateInfo info; info.size = size; - if constexpr (UpBuffer) { - info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT - | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; - info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT - | VK_ACCESS_INDEX_READ_BIT; - info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; - } else { - info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; - info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - info.access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT; - } + info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT + | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT + | VK_ACCESS_INDEX_READ_BIT; + info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; D3D9BufferSlice result; result.slice = DxvkBufferSlice(m_dxvkDevice->createBuffer(info, memoryFlags)); @@ -4502,7 +4529,7 @@ namespace dxvk { DxvkBufferSlice copySrcSlice; if (pSrcTexture->DoesStagingBufferUploads(SrcSubresource)) { VkDeviceSize dirtySize = extentBlockCount.width * extentBlockCount.height * extentBlockCount.depth * formatInfo->elementSize; - D3D9BufferSlice slice = AllocTempBuffer(dirtySize); + D3D9BufferSlice slice = AllocTempBuffer(dirtySize); copySrcSlice = slice.slice; void* srcData = reinterpret_cast(srcSlice.mapPtr) + copySrcOffset; util::packImageData( @@ -4552,7 +4579,7 @@ namespace dxvk { } // the converter can not handle the 4 aligned pitch so we always repack into a staging buffer - D3D9BufferSlice slice = AllocTempBuffer(srcSlice.length); + D3D9BufferSlice slice = AllocTempBuffer(srcSlice.length); VkDeviceSize pitch = align(srcTexLevelExtentBlockCount.width * formatInfo->elementSize, 4); util::packImageData( @@ -4712,7 +4739,7 @@ namespace dxvk { DxvkBufferSlice copySrcSlice; if (pResource->DoesStagingBufferUploads()) { - D3D9BufferSlice slice = AllocTempBuffer(range.max - range.min); + D3D9BufferSlice slice = AllocTempBuffer(range.max - range.min); copySrcSlice = slice.slice; void* srcData = reinterpret_cast(srcSlice.mapPtr) + range.min; memcpy(slice.mapPtr, srcData, range.max - range.min); diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 949728ad8..2d3339512 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -969,7 +969,8 @@ namespace dxvk { void DetermineConstantLayouts(bool canSWVP); - template + D3D9BufferSlice AllocUPBuffer(VkDeviceSize size); + D3D9BufferSlice AllocTempBuffer(VkDeviceSize size); bool ShouldRecord(); @@ -1163,7 +1164,10 @@ namespace dxvk { D3D9ConstantBuffer m_psFixedFunction; D3D9ConstantBuffer m_psShared; - D3D9BufferSlice m_upBuffer; + Rc m_upBuffer; + VkDeviceSize m_upBufferOffset = 0ull; + void* m_upBufferMapPtr = nullptr; + D3D9BufferSlice m_managedUploadBuffer; D3D9Cursor m_cursor; From 6ac5ca3bff2e2477aba4c0946056635d1de9c3fb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 16:19:58 +0200 Subject: [PATCH 0210/1348] [d3d9] Use existing staging buffer implementation for managed uploads --- src/d3d9/d3d9_device.cpp | 67 ++++++---------------------------------- src/d3d9/d3d9_device.h | 7 +++-- 2 files changed, 14 insertions(+), 60 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 0ce3ec290..ddd190ae8 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -46,6 +46,7 @@ namespace dxvk { , m_adapter ( pAdapter ) , m_dxvkDevice ( dxvkDevice ) , m_shaderModules ( new D3D9ShaderModuleSet ) + , m_stagingBuffer ( dxvkDevice, StagingBufferSize ) , m_d3d9Options ( dxvkDevice, pParent->GetInstance()->config() ) , m_multithread ( BehaviorFlags & D3DCREATE_MULTITHREADED ) , m_isSWVP ( (BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) ? true : false ) @@ -4013,61 +4014,11 @@ namespace dxvk { } - D3D9BufferSlice D3D9DeviceEx::AllocTempBuffer(VkDeviceSize size) { - constexpr VkDeviceSize DefaultSize = 1 << 20; - - VkMemoryPropertyFlags memoryFlags - = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT - | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - - D3D9BufferSlice& currentSlice = m_managedUploadBuffer; - - if (size <= DefaultSize) { - if (unlikely(!currentSlice.slice.defined())) { - DxvkBufferCreateInfo info; - info.size = DefaultSize; - info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; - info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - info.access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT; - - currentSlice.slice = DxvkBufferSlice(m_dxvkDevice->createBuffer(info, memoryFlags)); - currentSlice.mapPtr = currentSlice.slice.mapPtr(0); - } else if (unlikely(currentSlice.slice.length() < size)) { - auto physSlice = currentSlice.slice.buffer()->allocSlice(); - - currentSlice.slice = DxvkBufferSlice(currentSlice.slice.buffer()); - currentSlice.mapPtr = physSlice.mapPtr; - - EmitCs([ - cBuffer = currentSlice.slice.buffer(), - cSlice = physSlice - ] (DxvkContext* ctx) { - ctx->invalidateBuffer(cBuffer, cSlice); - }); - } - - D3D9BufferSlice result; - result.slice = currentSlice.slice.subSlice(0, size); - result.mapPtr = reinterpret_cast(currentSlice.mapPtr) + currentSlice.slice.offset(); - - VkDeviceSize adjust = align(size, CACHE_LINE_SIZE); - currentSlice.slice = currentSlice.slice.subSlice(adjust, currentSlice.slice.length() - adjust); - return result; - } else { - // Create a temporary buffer for very large allocations - DxvkBufferCreateInfo info; - info.size = size; - info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT - | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; - info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT - | VK_ACCESS_INDEX_READ_BIT; - info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; - - D3D9BufferSlice result; - result.slice = DxvkBufferSlice(m_dxvkDevice->createBuffer(info, memoryFlags)); - result.mapPtr = result.slice.mapPtr(0); - return result; - } + D3D9BufferSlice D3D9DeviceEx::AllocStagingBuffer(VkDeviceSize size) { + D3D9BufferSlice result; + result.slice = m_stagingBuffer.alloc(256, size); + result.mapPtr = result.slice.mapPtr(0); + return result; } bool D3D9DeviceEx::ShouldRecord() { @@ -4529,7 +4480,7 @@ namespace dxvk { DxvkBufferSlice copySrcSlice; if (pSrcTexture->DoesStagingBufferUploads(SrcSubresource)) { VkDeviceSize dirtySize = extentBlockCount.width * extentBlockCount.height * extentBlockCount.depth * formatInfo->elementSize; - D3D9BufferSlice slice = AllocTempBuffer(dirtySize); + D3D9BufferSlice slice = AllocStagingBuffer(dirtySize); copySrcSlice = slice.slice; void* srcData = reinterpret_cast(srcSlice.mapPtr) + copySrcOffset; util::packImageData( @@ -4579,7 +4530,7 @@ namespace dxvk { } // the converter can not handle the 4 aligned pitch so we always repack into a staging buffer - D3D9BufferSlice slice = AllocTempBuffer(srcSlice.length); + D3D9BufferSlice slice = AllocStagingBuffer(srcSlice.length); VkDeviceSize pitch = align(srcTexLevelExtentBlockCount.width * formatInfo->elementSize, 4); util::packImageData( @@ -4739,7 +4690,7 @@ namespace dxvk { DxvkBufferSlice copySrcSlice; if (pResource->DoesStagingBufferUploads()) { - D3D9BufferSlice slice = AllocTempBuffer(range.max - range.min); + D3D9BufferSlice slice = AllocStagingBuffer(range.max - range.min); copySrcSlice = slice.slice; void* srcData = reinterpret_cast(srcSlice.mapPtr) + range.min; memcpy(slice.mapPtr, srcData, range.max - range.min); diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 2d3339512..8090f1b55 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -2,6 +2,7 @@ #include "../dxvk/dxvk_device.h" #include "../dxvk/dxvk_cs.h" +#include "../dxvk/dxvk_staging.h" #include "d3d9_include.h" #include "d3d9_cursor.h" @@ -99,6 +100,8 @@ namespace dxvk { constexpr static uint32_t NullStreamIdx = caps::MaxStreams; + constexpr static VkDeviceSize StagingBufferSize = 4ull << 20; + friend class D3D9SwapChainEx; friend class D3D9ConstantBuffer; friend class D3D9UserDefinedAnnotation; @@ -971,7 +974,7 @@ namespace dxvk { D3D9BufferSlice AllocUPBuffer(VkDeviceSize size); - D3D9BufferSlice AllocTempBuffer(VkDeviceSize size); + D3D9BufferSlice AllocStagingBuffer(VkDeviceSize size); bool ShouldRecord(); @@ -1168,7 +1171,7 @@ namespace dxvk { VkDeviceSize m_upBufferOffset = 0ull; void* m_upBufferMapPtr = nullptr; - D3D9BufferSlice m_managedUploadBuffer; + DxvkStagingBuffer m_stagingBuffer; D3D9Cursor m_cursor; From fd15795a0bcdcac351c8e4a96229fd01b6db9f12 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 18:37:28 +0200 Subject: [PATCH 0211/1348] [dxvk] Require Vulkan 1.3 adapter --- src/dxvk/dxvk_device_filter.cpp | 7 +++++-- src/dxvk/dxvk_instance.cpp | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_device_filter.cpp b/src/dxvk/dxvk_device_filter.cpp index 02d8329ee..23d182480 100644 --- a/src/dxvk/dxvk_device_filter.cpp +++ b/src/dxvk/dxvk_device_filter.cpp @@ -17,8 +17,11 @@ namespace dxvk { bool DxvkDeviceFilter::testAdapter(const VkPhysicalDeviceProperties& properties) const { - if (properties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) { - Logger::warn(str::format("Skipping Vulkan 1.0 adapter: ", properties.deviceName)); + if (properties.apiVersion < VK_MAKE_VERSION(1, 3, 0)) { + Logger::warn(str::format("Skipping Vulkan ", + VK_VERSION_MAJOR(properties.apiVersion), ".", + VK_VERSION_MINOR(properties.apiVersion), " adapter: ", + properties.deviceName)); return false; } diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index e49d71f70..f093ed440 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -129,7 +129,7 @@ namespace dxvk { appInfo.applicationVersion = 0; appInfo.pEngineName = "DXVK"; appInfo.engineVersion = VK_MAKE_VERSION(1, 10, 1); - appInfo.apiVersion = VK_MAKE_VERSION(1, 1, 0); + appInfo.apiVersion = VK_MAKE_VERSION(1, 3, 0); VkInstanceCreateInfo info; info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; From 2774a041957625589db1cada328b5875ecf24c86 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 19:30:35 +0200 Subject: [PATCH 0212/1348] [dxvk] Use VkPhysicalDeviceVulkan11{Features,Properties} where appropriate --- src/d3d11/d3d11_device.cpp | 2 +- src/d3d9/d3d9_adapter.cpp | 8 ++++---- src/dxbc/dxbc_options.cpp | 10 +++++----- src/dxgi/dxgi_adapter.cpp | 6 +++--- src/dxso/dxso_options.cpp | 6 +++--- src/dxvk/dxvk_adapter.cpp | 21 ++++++++++----------- src/dxvk/dxvk_device_info.h | 5 ++--- src/dxvk/dxvk_instance.cpp | 2 +- 8 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index ac6e79d37..1023858af 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1925,7 +1925,7 @@ namespace dxvk { enabled.core.features.shaderStorageImageWriteWithoutFormat = VK_TRUE; enabled.core.features.depthBounds = supported.core.features.depthBounds; - enabled.shaderDrawParameters.shaderDrawParameters = VK_TRUE; + enabled.vk11.shaderDrawParameters = VK_TRUE; enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; diff --git a/src/d3d9/d3d9_adapter.cpp b/src/d3d9/d3d9_adapter.cpp index ac8da7978..7ca05fffe 100644 --- a/src/d3d9/d3d9_adapter.cpp +++ b/src/d3d9/d3d9_adapter.cpp @@ -67,7 +67,7 @@ namespace dxvk { return D3DERR_INVALIDCALL; } - GUID guid = bit::cast(m_adapter->devicePropertiesExt().coreDeviceId.deviceUUID); + GUID guid = bit::cast(m_adapter->devicePropertiesExt().vk11.deviceUUID); uint32_t vendorId = options.customVendorId == -1 ? props.vendorID : uint32_t(options.customVendorId); uint32_t deviceId = options.customDeviceId == -1 ? props.deviceID : uint32_t(options.customDeviceId); @@ -702,10 +702,10 @@ namespace dxvk { if (pLUID == nullptr) return D3DERR_INVALIDCALL; - auto& deviceId = m_adapter->devicePropertiesExt().coreDeviceId; + auto& vk11 = m_adapter->devicePropertiesExt().vk11; - if (deviceId.deviceLUIDValid) - *pLUID = bit::cast(deviceId.deviceLUID); + if (vk11.deviceLUIDValid) + *pLUID = bit::cast(vk11.deviceLUID); else *pLUID = dxvk::GetAdapterLUID(m_ordinal); diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index df05d3caf..154d25079 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -20,14 +20,14 @@ namespace dxvk { useStorageImageReadWithoutFormat = devFeatures.core.features.shaderStorageImageReadWithoutFormat; useSubgroupOpsForAtomicCounters - = (devInfo.coreSubgroup.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT) - && (devInfo.coreSubgroup.supportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); + = (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_COMPUTE_BIT) + && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); useDemoteToHelperInvocation = (devFeatures.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation); useSubgroupOpsForEarlyDiscard - = (devInfo.coreSubgroup.subgroupSize >= 4) - && (devInfo.coreSubgroup.supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) - && (devInfo.coreSubgroup.supportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); + = (devInfo.vk11.subgroupSize >= 4) + && (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) + && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); useSdivForBufferIndex = adapter->matchesDriver(DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0); diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index 3e8f6307e..81c471746 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -244,7 +244,7 @@ namespace dxvk { auto deviceProp = m_adapter->deviceProperties(); auto memoryProp = m_adapter->memoryProperties(); - auto deviceId = m_adapter->devicePropertiesExt().coreDeviceId; + auto vk11 = m_adapter->devicePropertiesExt().vk11; // Custom Vendor / Device ID if (options->customVendorId >= 0) @@ -322,8 +322,8 @@ namespace dxvk { pDesc->GraphicsPreemptionGranularity = DXGI_GRAPHICS_PREEMPTION_DMA_BUFFER_BOUNDARY; pDesc->ComputePreemptionGranularity = DXGI_COMPUTE_PREEMPTION_DMA_BUFFER_BOUNDARY; - if (deviceId.deviceLUIDValid) - std::memcpy(&pDesc->AdapterLuid, deviceId.deviceLUID, VK_LUID_SIZE); + if (vk11.deviceLUIDValid) + std::memcpy(&pDesc->AdapterLuid, vk11.deviceLUID, VK_LUID_SIZE); else pDesc->AdapterLuid = GetAdapterLUID(m_index); diff --git a/src/dxso/dxso_options.cpp b/src/dxso/dxso_options.cpp index 5e05ee650..e7c94e589 100644 --- a/src/dxso/dxso_options.cpp +++ b/src/dxso/dxso_options.cpp @@ -18,9 +18,9 @@ namespace dxvk { = (devFeatures.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation); useSubgroupOpsForEarlyDiscard - = (devInfo.coreSubgroup.subgroupSize >= 4) - && (devInfo.coreSubgroup.supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) - && (devInfo.coreSubgroup.supportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); + = (devInfo.vk11.subgroupSize >= 4) + && (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) + && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); // Disable early discard on Nvidia because it may hurt performance if (adapter->matchesDriver(DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0)) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 0a489fab5..7dec71d0b 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -220,8 +220,8 @@ namespace dxvk { || !required.core.features.variableMultisampleRate) && (m_deviceFeatures.core.features.inheritedQueries || !required.core.features.inheritedQueries) - && (m_deviceFeatures.shaderDrawParameters.shaderDrawParameters - || !required.shaderDrawParameters.shaderDrawParameters) + && (m_deviceFeatures.vk11.shaderDrawParameters + || !required.vk11.shaderDrawParameters) && (m_deviceFeatures.ext4444Formats.formatA4R4G4B4 || !required.ext4444Formats.formatA4R4G4B4) && (m_deviceFeatures.ext4444Formats.formatA4B4G4R4 @@ -373,8 +373,8 @@ namespace dxvk { enabledFeatures.core.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; enabledFeatures.core.pNext = nullptr; - enabledFeatures.shaderDrawParameters.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES; - enabledFeatures.shaderDrawParameters.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.shaderDrawParameters); + enabledFeatures.vk11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; + enabledFeatures.vk11.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.vk11); if (devExtensions.ext4444Formats) { enabledFeatures.ext4444Formats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; @@ -627,11 +627,8 @@ namespace dxvk { // Query info now so that we have basic device properties available m_vki->vkGetPhysicalDeviceProperties2(m_handle, &m_deviceInfo.core); - m_deviceInfo.coreDeviceId.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; - m_deviceInfo.coreDeviceId.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.coreDeviceId); - - m_deviceInfo.coreSubgroup.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES; - m_deviceInfo.coreSubgroup.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.coreSubgroup); + m_deviceInfo.vk11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES; + m_deviceInfo.vk11.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.vk11); if (m_deviceExtensions.supports(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) { m_deviceInfo.extConservativeRasterization.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT; @@ -706,8 +703,8 @@ namespace dxvk { m_deviceFeatures.core.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; m_deviceFeatures.core.pNext = nullptr; - m_deviceFeatures.shaderDrawParameters.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES; - m_deviceFeatures.shaderDrawParameters.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.shaderDrawParameters); + m_deviceFeatures.vk11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; + m_deviceFeatures.vk11.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.vk11); if (m_deviceExtensions.supports(VK_EXT_4444_FORMATS_EXTENSION_NAME)) { m_deviceFeatures.ext4444Formats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; @@ -855,6 +852,8 @@ namespace dxvk { "\n shaderFloat64 : ", features.core.features.shaderFloat64 ? "1" : "0", "\n shaderInt64 : ", features.core.features.shaderInt64 ? "1" : "0", "\n variableMultisampleRate : ", features.core.features.variableMultisampleRate ? "1" : "0", + "\nVulkan 1.1", + "\n shaderDrawParameters : ", features.vk11.shaderDrawParameters, "\n", VK_EXT_4444_FORMATS_EXTENSION_NAME, "\n formatA4R4G4B4 : ", features.ext4444Formats.formatA4R4G4B4 ? "1" : "0", "\n formatA4B4G4R4 : ", features.ext4444Formats.formatA4B4G4R4 ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 55ae18233..501acb093 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -14,8 +14,7 @@ namespace dxvk { */ struct DxvkDeviceInfo { VkPhysicalDeviceProperties2 core; - VkPhysicalDeviceIDProperties coreDeviceId; - VkPhysicalDeviceSubgroupProperties coreSubgroup; + VkPhysicalDeviceVulkan11Properties vk11; VkPhysicalDeviceConservativeRasterizationPropertiesEXT extConservativeRasterization; VkPhysicalDeviceCustomBorderColorPropertiesEXT extCustomBorderColor; VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT extGraphicsPipelineLibrary; @@ -37,7 +36,7 @@ namespace dxvk { */ struct DxvkDeviceFeatures { VkPhysicalDeviceFeatures2 core; - VkPhysicalDeviceShaderDrawParametersFeatures shaderDrawParameters; + VkPhysicalDeviceVulkan11Features vk11; VkPhysicalDevice4444FormatsFeaturesEXT ext4444Formats; VkPhysicalDeviceCustomBorderColorFeaturesEXT extCustomBorderColor; VkPhysicalDeviceDepthClipEnableFeaturesEXT extDepthClipEnable; diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index f093ed440..e6fabd8c2 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -61,7 +61,7 @@ namespace dxvk { Rc DxvkInstance::findAdapterByLuid(const void* luid) const { for (const auto& adapter : m_adapters) { - const auto& props = adapter->devicePropertiesExt().coreDeviceId; + const auto& props = adapter->devicePropertiesExt().vk11; if (props.deviceLUIDValid && !std::memcmp(luid, props.deviceLUID, VK_LUID_SIZE)) return adapter; From 73f313f90435bd023c8ece0eda10e71d6d3b87c1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 19:41:40 +0200 Subject: [PATCH 0213/1348] [dxvk] Enable Vulkan 1.2 feature structs --- src/dxvk/dxvk_adapter.cpp | 31 +++++++++++++++++++++++++++++++ src/dxvk/dxvk_device_info.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 7dec71d0b..0bfd2d1b6 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -222,6 +222,20 @@ namespace dxvk { || !required.core.features.inheritedQueries) && (m_deviceFeatures.vk11.shaderDrawParameters || !required.vk11.shaderDrawParameters) + && (m_deviceFeatures.vk12.samplerMirrorClampToEdge + || !required.vk12.samplerMirrorClampToEdge) + && (m_deviceFeatures.vk12.drawIndirectCount + || !required.vk12.drawIndirectCount) + && (m_deviceFeatures.vk12.hostQueryReset + || !required.vk12.hostQueryReset) + && (m_deviceFeatures.vk12.timelineSemaphore + || !required.vk12.timelineSemaphore) + && (m_deviceFeatures.vk12.bufferDeviceAddress + || !required.vk12.bufferDeviceAddress) + && (m_deviceFeatures.vk12.shaderOutputViewportIndex + || !required.vk12.shaderOutputViewportIndex) + && (m_deviceFeatures.vk12.shaderOutputLayer + || !required.vk12.shaderOutputLayer) && (m_deviceFeatures.ext4444Formats.formatA4R4G4B4 || !required.ext4444Formats.formatA4R4G4B4) && (m_deviceFeatures.ext4444Formats.formatA4B4G4R4 @@ -376,6 +390,9 @@ namespace dxvk { enabledFeatures.vk11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; enabledFeatures.vk11.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.vk11); + enabledFeatures.vk12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; + enabledFeatures.vk12.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.vk12); + if (devExtensions.ext4444Formats) { enabledFeatures.ext4444Formats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; enabledFeatures.ext4444Formats.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.ext4444Formats); @@ -630,6 +647,9 @@ namespace dxvk { m_deviceInfo.vk11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES; m_deviceInfo.vk11.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.vk11); + m_deviceInfo.vk12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES; + m_deviceInfo.vk12.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.vk12); + if (m_deviceExtensions.supports(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) { m_deviceInfo.extConservativeRasterization.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT; m_deviceInfo.extConservativeRasterization.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extConservativeRasterization); @@ -706,6 +726,9 @@ namespace dxvk { m_deviceFeatures.vk11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; m_deviceFeatures.vk11.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.vk11); + m_deviceFeatures.vk12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; + m_deviceFeatures.vk12.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.vk12); + if (m_deviceExtensions.supports(VK_EXT_4444_FORMATS_EXTENSION_NAME)) { m_deviceFeatures.ext4444Formats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; m_deviceFeatures.ext4444Formats.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.ext4444Formats); @@ -854,6 +877,14 @@ namespace dxvk { "\n variableMultisampleRate : ", features.core.features.variableMultisampleRate ? "1" : "0", "\nVulkan 1.1", "\n shaderDrawParameters : ", features.vk11.shaderDrawParameters, + "\nVulkan 1.2", + "\n samplerMirrorClampToEdge : ", features.vk12.samplerMirrorClampToEdge, + "\n drawIndirectCount : ", features.vk12.drawIndirectCount, + "\n hostQueryReset : ", features.vk12.hostQueryReset, + "\n timelineSemaphore : ", features.vk12.timelineSemaphore, + "\n bufferDeviceAddress : ", features.vk12.bufferDeviceAddress, + "\n shaderOutputViewportIndex : ", features.vk12.shaderOutputViewportIndex, + "\n shaderOutputLayer : ", features.vk12.shaderOutputLayer, "\n", VK_EXT_4444_FORMATS_EXTENSION_NAME, "\n formatA4R4G4B4 : ", features.ext4444Formats.formatA4R4G4B4 ? "1" : "0", "\n formatA4B4G4R4 : ", features.ext4444Formats.formatA4B4G4R4 ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 501acb093..ffe5e5240 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -15,6 +15,7 @@ namespace dxvk { struct DxvkDeviceInfo { VkPhysicalDeviceProperties2 core; VkPhysicalDeviceVulkan11Properties vk11; + VkPhysicalDeviceVulkan12Properties vk12; VkPhysicalDeviceConservativeRasterizationPropertiesEXT extConservativeRasterization; VkPhysicalDeviceCustomBorderColorPropertiesEXT extCustomBorderColor; VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT extGraphicsPipelineLibrary; @@ -37,6 +38,7 @@ namespace dxvk { struct DxvkDeviceFeatures { VkPhysicalDeviceFeatures2 core; VkPhysicalDeviceVulkan11Features vk11; + VkPhysicalDeviceVulkan12Features vk12; VkPhysicalDevice4444FormatsFeaturesEXT ext4444Formats; VkPhysicalDeviceCustomBorderColorFeaturesEXT extCustomBorderColor; VkPhysicalDeviceDepthClipEnableFeaturesEXT extDepthClipEnable; From eee4ac1e91e988bd34d6b046faa84704926160b8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 19:45:37 +0200 Subject: [PATCH 0214/1348] [dxvk] Replace VK_KHR_sampler_mirror_clamp_to_edge with core features And make it a hard requirement. We're not checking for feature support anyway and all relevant drivers support this feature anyway. --- src/d3d11/d3d11_device.cpp | 2 ++ src/d3d9/d3d9_device.cpp | 2 ++ src/dxvk/dxvk_adapter.cpp | 3 +-- src/dxvk/dxvk_extensions.h | 1 - 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 1023858af..9416c8b4d 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1927,6 +1927,8 @@ namespace dxvk { enabled.vk11.shaderDrawParameters = VK_TRUE; + enabled.vk12.samplerMirrorClampToEdge = VK_TRUE; + enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; enabled.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation = supported.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index ddd190ae8..48952b387 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3901,6 +3901,8 @@ namespace dxvk { enabled.core.features.geometryShader = VK_TRUE; enabled.core.features.robustBufferAccess = VK_TRUE; + enabled.vk12.samplerMirrorClampToEdge = VK_TRUE; + enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; enabled.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation = supported.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation; diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 0bfd2d1b6..414a3a419 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -285,7 +285,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -316,7 +316,6 @@ namespace dxvk { &devExtensions.khrExternalMemoryWin32, &devExtensions.khrImageFormatList, &devExtensions.khrPipelineLibrary, - &devExtensions.khrSamplerMirrorClampToEdge, &devExtensions.khrShaderFloatControls, &devExtensions.khrSwapchain, &devExtensions.nvxBinaryImport, diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index e0e6c4602..b3b518194 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -306,7 +306,6 @@ namespace dxvk { DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrImageFormatList = { VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrPipelineLibrary = { VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt khrSamplerMirrorClampToEdge = { VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrShaderFloatControls = { VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrSwapchain = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt nvxBinaryImport = { VK_NVX_BINARY_IMPORT_EXTENSION_NAME, DxvkExtMode::Disabled }; From f07ba07ad8286bacdf8a7e7795a580a6f2bdf792 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 19:50:38 +0200 Subject: [PATCH 0215/1348] [dxvk] Replace VK_KHR_draw_indirect_count with core feature And enable it optionally in the backend, since we provide the functionality. --- src/d3d11/d3d11_device.cpp | 2 +- src/dxvk/dxvk_adapter.cpp | 5 +++-- src/dxvk/dxvk_cmdlist.h | 4 ++-- src/dxvk/dxvk_extensions.h | 1 - src/vulkan/vulkan_loader.h | 7 ++----- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 9416c8b4d..3f4e1ef73 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2491,7 +2491,7 @@ namespace dxvk { case D3D11_VK_EXT_MULTI_DRAW_INDIRECT_COUNT: return deviceFeatures.core.features.multiDrawIndirect - && deviceExtensions.khrDrawIndirectCount; + && deviceFeatures.vk12.drawIndirectCount; case D3D11_VK_EXT_DEPTH_BOUNDS: return deviceFeatures.core.features.depthBounds; diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 414a3a419..bdc4409bd 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -285,7 +285,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -310,7 +310,6 @@ namespace dxvk { &devExtensions.khrBufferDeviceAddress, &devExtensions.khrCreateRenderPass2, &devExtensions.khrDepthStencilResolve, - &devExtensions.khrDrawIndirectCount, &devExtensions.khrDriverProperties, &devExtensions.khrDynamicRendering, &devExtensions.khrExternalMemoryWin32, @@ -351,6 +350,8 @@ namespace dxvk { DxvkNameList extensionNameList = extensionsEnabled.toNameList(); // Enable additional device features if supported + enabledFeatures.vk12.drawIndirectCount = m_deviceFeatures.vk12.drawIndirectCount; + enabledFeatures.extExtendedDynamicState.extendedDynamicState = VK_TRUE; enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 0d81ec52a..70948295a 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -518,7 +518,7 @@ namespace dxvk { VkDeviceSize countOffset, uint32_t maxDrawCount, uint32_t stride) { - m_vkd->vkCmdDrawIndirectCountKHR(m_execBuffer, + m_vkd->vkCmdDrawIndirectCount(m_execBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride); } @@ -553,7 +553,7 @@ namespace dxvk { VkDeviceSize countOffset, uint32_t maxDrawCount, uint32_t stride) { - m_vkd->vkCmdDrawIndexedIndirectCountKHR(m_execBuffer, + m_vkd->vkCmdDrawIndexedIndirectCount(m_execBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride); } diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index b3b518194..c8a9e4d0c 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -300,7 +300,6 @@ namespace dxvk { DxvkExt khrBufferDeviceAddress = { VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, DxvkExtMode::Disabled }; DxvkExt khrCreateRenderPass2 = { VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrDepthStencilResolve = { VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, DxvkExtMode::Required }; - DxvkExt khrDrawIndirectCount = { VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrDriverProperties = { VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrDynamicRendering = { VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 28d4fd014..0802b2f51 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -260,7 +260,9 @@ namespace dxvk::vk { VULKAN_FN(vkCmdDraw); VULKAN_FN(vkCmdDrawIndexed); VULKAN_FN(vkCmdDrawIndirect); + VULKAN_FN(vkCmdDrawIndirectCount); VULKAN_FN(vkCmdDrawIndexedIndirect); + VULKAN_FN(vkCmdDrawIndexedIndirectCount); VULKAN_FN(vkCmdDispatch); VULKAN_FN(vkCmdDispatchIndirect); VULKAN_FN(vkCmdCopyBuffer); @@ -296,11 +298,6 @@ namespace dxvk::vk { VULKAN_FN(vkCmdEndRenderPass2KHR); #endif - #ifdef VK_KHR_draw_indirect_count - VULKAN_FN(vkCmdDrawIndirectCountKHR); - VULKAN_FN(vkCmdDrawIndexedIndirectCountKHR); - #endif - #ifdef VK_KHR_swapchain VULKAN_FN(vkCreateSwapchainKHR); VULKAN_FN(vkDestroySwapchainKHR); From 0b47297b7d02aaefb8fa9079232a799f4be973dc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 19:54:14 +0200 Subject: [PATCH 0216/1348] [dxvk] Replace VK_EXT_host_query_reset with core feature And make it a hard requirement in the backend. We no longer support the old fallback path for queries anyway. --- src/d3d11/d3d11_device.cpp | 1 - src/d3d9/d3d9_device.cpp | 1 - src/dxvk/dxvk_adapter.cpp | 23 ++--------------------- src/dxvk/dxvk_cmdlist.h | 2 +- src/dxvk/dxvk_device_info.h | 1 - src/dxvk/dxvk_extensions.h | 1 - src/vulkan/vulkan_loader.h | 5 +---- 7 files changed, 4 insertions(+), 30 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 3f4e1ef73..29a7faf56 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1952,7 +1952,6 @@ namespace dxvk { enabled.core.features.shaderCullDistance = VK_TRUE; enabled.core.features.textureCompressionBC = VK_TRUE; enabled.extDepthClipEnable.depthClipEnable = supported.extDepthClipEnable.depthClipEnable; - enabled.extHostQueryReset.hostQueryReset = VK_TRUE; } if (featureLevel >= D3D_FEATURE_LEVEL_9_2) { diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 48952b387..9e1581c24 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3931,7 +3931,6 @@ namespace dxvk { enabled.core.features.textureCompressionBC = VK_TRUE; enabled.extDepthClipEnable.depthClipEnable = supported.extDepthClipEnable.depthClipEnable; - enabled.extHostQueryReset.hostQueryReset = VK_TRUE; // SM2 level hardware enabled.core.features.occlusionQueryPrecise = VK_TRUE; diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index bdc4409bd..723c64baf 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -250,8 +250,6 @@ namespace dxvk { || !required.extExtendedDynamicState.extendedDynamicState) && (m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary || !required.extGraphicsPipelineLibrary.graphicsPipelineLibrary) - && (m_deviceFeatures.extHostQueryReset.hostQueryReset - || !required.extHostQueryReset.hostQueryReset) && (m_deviceFeatures.extMemoryPriority.memoryPriority || !required.extMemoryPriority.memoryPriority) && (m_deviceFeatures.extNonSeamlessCubeMap.nonSeamlessCubeMap @@ -285,7 +283,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -295,7 +293,6 @@ namespace dxvk { &devExtensions.extExtendedDynamicState, &devExtensions.extFullScreenExclusive, &devExtensions.extGraphicsPipelineLibrary, - &devExtensions.extHostQueryReset, &devExtensions.extMemoryBudget, &devExtensions.extMemoryPriority, &devExtensions.extNonSeamlessCubeMap, @@ -351,6 +348,7 @@ namespace dxvk { // Enable additional device features if supported enabledFeatures.vk12.drawIndirectCount = m_deviceFeatures.vk12.drawIndirectCount; + enabledFeatures.vk12.hostQueryReset = VK_TRUE; enabledFeatures.extExtendedDynamicState.extendedDynamicState = VK_TRUE; @@ -418,11 +416,6 @@ namespace dxvk { enabledFeatures.extGraphicsPipelineLibrary.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extGraphicsPipelineLibrary); } - if (devExtensions.extHostQueryReset) { - enabledFeatures.extHostQueryReset.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT; - enabledFeatures.extHostQueryReset.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extHostQueryReset); - } - if (devExtensions.extMemoryPriority) { enabledFeatures.extMemoryPriority.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT; enabledFeatures.extMemoryPriority.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extMemoryPriority); @@ -463,11 +456,6 @@ namespace dxvk { enabledFeatures.extVertexAttributeDivisor.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extVertexAttributeDivisor); } - if (devExtensions.khrBufferDeviceAddress) { - enabledFeatures.khrBufferDeviceAddress.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR; - enabledFeatures.khrBufferDeviceAddress.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.khrBufferDeviceAddress); - } - if (devExtensions.khrDynamicRendering) { enabledFeatures.khrDynamicRendering.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR; enabledFeatures.khrDynamicRendering.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.khrDynamicRendering); @@ -754,11 +742,6 @@ namespace dxvk { m_deviceFeatures.extGraphicsPipelineLibrary.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extGraphicsPipelineLibrary); } - if (m_deviceExtensions.supports(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) { - m_deviceFeatures.extHostQueryReset.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT; - m_deviceFeatures.extHostQueryReset.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extHostQueryReset); - } - if (m_deviceExtensions.supports(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME)) { m_deviceFeatures.extMemoryPriority.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT; m_deviceFeatures.extMemoryPriority.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extMemoryPriority); @@ -897,8 +880,6 @@ namespace dxvk { "\n extendedDynamicState : ", features.extExtendedDynamicState.extendedDynamicState ? "1" : "0", "\n", VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, "\n graphicsPipelineLibrary : ", features.extGraphicsPipelineLibrary.graphicsPipelineLibrary ? "1" : "0", - "\n", VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, - "\n hostQueryReset : ", features.extHostQueryReset.hostQueryReset ? "1" : "0", "\n", VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, "\n memoryPriority : ", features.extMemoryPriority.memoryPriority ? "1" : "0", "\n", VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 70948295a..4cdabb582 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -801,7 +801,7 @@ namespace dxvk { void resetQuery( VkQueryPool queryPool, uint32_t queryId) { - m_vkd->vkResetQueryPoolEXT( + m_vkd->vkResetQueryPool( m_vkd->device(), queryPool, queryId, 1); } diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index ffe5e5240..e9e54c667 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -44,7 +44,6 @@ namespace dxvk { VkPhysicalDeviceDepthClipEnableFeaturesEXT extDepthClipEnable; VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extExtendedDynamicState; VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT extGraphicsPipelineLibrary; - VkPhysicalDeviceHostQueryResetFeaturesEXT extHostQueryReset; VkPhysicalDeviceMemoryPriorityFeaturesEXT extMemoryPriority; VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT extNonSeamlessCubeMap; VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT extPipelineCreationCacheControl; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index c8a9e4d0c..965e275d1 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -285,7 +285,6 @@ namespace dxvk { DxvkExt extExtendedDynamicState = { VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt extFullScreenExclusive = { VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extGraphicsPipelineLibrary = { VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt extHostQueryReset = { VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extMemoryBudget = { VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, DxvkExtMode::Passive }; DxvkExt extMemoryPriority = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extNonSeamlessCubeMap = { VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 0802b2f51..89ccae446 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -244,6 +244,7 @@ namespace dxvk::vk { VULKAN_FN(vkCreateDescriptorUpdateTemplate); VULKAN_FN(vkDestroyDescriptorUpdateTemplate); VULKAN_FN(vkUpdateDescriptorSetWithTemplate); + VULKAN_FN(vkResetQueryPool); VULKAN_FN(vkCmdBindPipeline); VULKAN_FN(vkCmdSetViewport); VULKAN_FN(vkCmdSetScissor); @@ -332,10 +333,6 @@ namespace dxvk::vk { VULKAN_FN(vkGetDeviceGroupSurfacePresentModes2EXT); #endif - #ifdef VK_EXT_host_query_reset - VULKAN_FN(vkResetQueryPoolEXT); - #endif - #ifdef VK_EXT_shader_module_identifier VULKAN_FN(vkGetShaderModuleCreateInfoIdentifierEXT); VULKAN_FN(vkGetShaderModuleIdentifierEXT); From afdaba6cafe2709fb2d82b462038bd3276c7c2f9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 19:59:20 +0200 Subject: [PATCH 0217/1348] [dxvk] Replace VK_KHR_buffer_device_address with core feature --- src/d3d11/d3d11_device.cpp | 7 ++++--- src/dxvk/dxvk_adapter.cpp | 21 ++++----------------- src/dxvk/dxvk_device_info.h | 1 - src/dxvk/dxvk_extensions.h | 1 - src/vulkan/vulkan_loader.h | 5 +---- 5 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 29a7faf56..563a6cdae 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2500,7 +2500,7 @@ namespace dxvk { case D3D11_VK_NVX_BINARY_IMPORT: return deviceExtensions.nvxBinaryImport - && deviceExtensions.khrBufferDeviceAddress; + && deviceFeatures.vk12.bufferDeviceAddress; default: return false; @@ -2659,9 +2659,10 @@ namespace dxvk { const DxvkBufferSliceHandle bufSliceHandle = buffer->GetBuffer()->getSliceHandle(); VkBuffer vkBuffer = bufSliceHandle.handle; - VkBufferDeviceAddressInfoKHR bdaInfo = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR }; + VkBufferDeviceAddressInfo bdaInfo = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO }; bdaInfo.buffer = vkBuffer; - VkDeviceAddress bufAddr = dxvkDevice->vkd()->vkGetBufferDeviceAddressKHR(vkDevice, &bdaInfo); + + VkDeviceAddress bufAddr = dxvkDevice->vkd()->vkGetBufferDeviceAddress(vkDevice, &bdaInfo); *gpuVAStart = uint64_t(bufAddr) + bufSliceHandle.offset; *gpuVASize = bufSliceHandle.length; } diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 723c64baf..63445ca94 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -283,7 +283,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -304,7 +304,6 @@ namespace dxvk { &devExtensions.extShaderViewportIndexLayer, &devExtensions.extTransformFeedback, &devExtensions.extVertexAttributeDivisor, - &devExtensions.khrBufferDeviceAddress, &devExtensions.khrCreateRenderPass2, &devExtensions.khrDepthStencilResolve, &devExtensions.khrDriverProperties, @@ -324,14 +323,13 @@ namespace dxvk { bool enableCudaInterop = !env::is32BitHostPlatform() && m_deviceExtensions.supports(devExtensions.nvxBinaryImport.name()) && m_deviceExtensions.supports(devExtensions.nvxImageViewHandle.name()) && - m_deviceFeatures.khrBufferDeviceAddress.bufferDeviceAddress; + m_deviceFeatures.vk12.bufferDeviceAddress; if (enableCudaInterop) { devExtensions.nvxBinaryImport.setMode(DxvkExtMode::Optional); devExtensions.nvxImageViewHandle.setMode(DxvkExtMode::Optional); - devExtensions.khrBufferDeviceAddress.setMode(DxvkExtMode::Optional); - enabledFeatures.khrBufferDeviceAddress.bufferDeviceAddress = VK_TRUE; + enabledFeatures.vk12.bufferDeviceAddress = VK_TRUE; } DxvkNameSet extensionsEnabled; @@ -513,14 +511,10 @@ namespace dxvk { // that in advance since the extensions are reported as supported anyway. Logger::err("DxvkAdapter: Failed to create device, retrying without CUDA interop extensions"); - extensionsEnabled.disableExtension(devExtensions.khrBufferDeviceAddress); extensionsEnabled.disableExtension(devExtensions.nvxBinaryImport); extensionsEnabled.disableExtension(devExtensions.nvxImageViewHandle); - enabledFeatures.khrBufferDeviceAddress.bufferDeviceAddress = VK_FALSE; - - vk::removeStructFromPNextChain(&enabledFeatures.core.pNext, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR); + enabledFeatures.vk12.bufferDeviceAddress = VK_FALSE; extensionNameList = extensionsEnabled.toNameList(); info.enabledExtensionCount = extensionNameList.count(); @@ -782,11 +776,6 @@ namespace dxvk { m_deviceFeatures.extVertexAttributeDivisor.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extVertexAttributeDivisor); } - if (m_deviceExtensions.supports(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) { - m_deviceFeatures.khrBufferDeviceAddress.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR; - m_deviceFeatures.khrBufferDeviceAddress.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.khrBufferDeviceAddress); - } - if (m_deviceExtensions.supports(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME)) { m_deviceFeatures.khrDynamicRendering.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR; m_deviceFeatures.khrDynamicRendering.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.khrDynamicRendering); @@ -900,8 +889,6 @@ namespace dxvk { "\n", VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, "\n vertexAttributeInstanceRateDivisor : ", features.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor ? "1" : "0", "\n vertexAttributeInstanceRateZeroDivisor : ", features.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor ? "1" : "0", - "\n", VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, - "\n bufferDeviceAddress : ", features.khrBufferDeviceAddress.bufferDeviceAddress ? "1" : "0", "\n", VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, "\n dynamicRendering : ", features.khrDynamicRendering.dynamicRendering ? "1" : "0")); } diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index e9e54c667..69fb1263c 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -52,7 +52,6 @@ namespace dxvk { VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT extShaderModuleIdentifier; VkPhysicalDeviceTransformFeedbackFeaturesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT extVertexAttributeDivisor; - VkPhysicalDeviceBufferDeviceAddressFeaturesKHR khrBufferDeviceAddress; VkPhysicalDeviceDynamicRenderingFeaturesKHR khrDynamicRendering; }; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 965e275d1..3a5a1eae8 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -296,7 +296,6 @@ namespace dxvk { DxvkExt extShaderViewportIndexLayer = { VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt khrBufferDeviceAddress = { VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, DxvkExtMode::Disabled }; DxvkExt khrCreateRenderPass2 = { VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrDepthStencilResolve = { VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrDriverProperties = { VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 89ccae446..c972b48a5 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -245,6 +245,7 @@ namespace dxvk::vk { VULKAN_FN(vkDestroyDescriptorUpdateTemplate); VULKAN_FN(vkUpdateDescriptorSetWithTemplate); VULKAN_FN(vkResetQueryPool); + VULKAN_FN(vkGetBufferDeviceAddress); VULKAN_FN(vkCmdBindPipeline); VULKAN_FN(vkCmdSetViewport); VULKAN_FN(vkCmdSetScissor); @@ -360,10 +361,6 @@ namespace dxvk::vk { VULKAN_FN(vkCmdCuLaunchKernelNVX); #endif - #ifdef VK_KHR_buffer_device_address - VULKAN_FN(vkGetBufferDeviceAddressKHR); - #endif - #ifdef VK_KHR_dynamic_rendering VULKAN_FN(vkCmdBeginRenderingKHR); VULKAN_FN(vkCmdEndRenderingKHR); From d657a526ae7879ef94c94634f93ccf17728b8677 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:03:53 +0200 Subject: [PATCH 0218/1348] [dxvk] Replace VK_EXT_shader_viewport_index_layer with core features And enable them optionally in the backend, since we use this for meta operations. --- src/d3d11/d3d11_device.cpp | 9 ++++++--- src/dxvk/dxvk_adapter.cpp | 5 +++-- src/dxvk/dxvk_extensions.h | 1 - src/dxvk/dxvk_meta_blit.cpp | 2 +- src/dxvk/dxvk_meta_copy.cpp | 2 +- src/dxvk/dxvk_meta_resolve.cpp | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 563a6cdae..1545438b8 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1712,10 +1712,12 @@ namespace dxvk { if (FeatureSupportDataSize != sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS3)) return E_INVALIDARG; - const auto& extensions = m_dxvkDevice->extensions(); + const auto& features = m_dxvkDevice->features(); auto info = static_cast(pFeatureSupportData); - info->VPAndRTArrayIndexFromAnyShaderFeedingRasterizer = extensions.extShaderViewportIndexLayer; + info->VPAndRTArrayIndexFromAnyShaderFeedingRasterizer = + features.vk12.shaderOutputViewportIndex && + features.vk12.shaderOutputLayer; } return S_OK; case D3D11_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT: { @@ -2023,7 +2025,8 @@ namespace dxvk { return E_INVALIDARG; if (shader->flags().test(DxvkShaderFlag::ExportsViewportIndexLayerFromVertexStage) - && !m_dxvkDevice->extensions().extShaderViewportIndexLayer) + && (!m_dxvkDevice->features().vk12.shaderOutputViewportIndex + || !m_dxvkDevice->features().vk12.shaderOutputLayer)) return E_INVALIDARG; *pShaderModule = std::move(commonShader); diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 63445ca94..4707a8052 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -283,7 +283,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -301,7 +301,6 @@ namespace dxvk { &devExtensions.extShaderDemoteToHelperInvocation, &devExtensions.extShaderModuleIdentifier, &devExtensions.extShaderStencilExport, - &devExtensions.extShaderViewportIndexLayer, &devExtensions.extTransformFeedback, &devExtensions.extVertexAttributeDivisor, &devExtensions.khrCreateRenderPass2, @@ -347,6 +346,8 @@ namespace dxvk { // Enable additional device features if supported enabledFeatures.vk12.drawIndirectCount = m_deviceFeatures.vk12.drawIndirectCount; enabledFeatures.vk12.hostQueryReset = VK_TRUE; + enabledFeatures.vk12.shaderOutputViewportIndex = m_deviceFeatures.vk12.shaderOutputViewportIndex; + enabledFeatures.vk12.shaderOutputLayer = m_deviceFeatures.vk12.shaderOutputLayer; enabledFeatures.extExtendedDynamicState.extendedDynamicState = VK_TRUE; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 3a5a1eae8..58419d698 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -293,7 +293,6 @@ namespace dxvk { DxvkExt extShaderDemoteToHelperInvocation = { VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderModuleIdentifier = { VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt extShaderViewportIndexLayer = { VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrCreateRenderPass2 = { VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, DxvkExtMode::Required }; diff --git a/src/dxvk/dxvk_meta_blit.cpp b/src/dxvk/dxvk_meta_blit.cpp index 58bcc16b9..b069b0a99 100644 --- a/src/dxvk/dxvk_meta_blit.cpp +++ b/src/dxvk/dxvk_meta_blit.cpp @@ -133,7 +133,7 @@ namespace dxvk { m_shaderFrag1D(createShaderModule(dxvk_blit_frag_1d)), m_shaderFrag2D(createShaderModule(dxvk_blit_frag_2d)), m_shaderFrag3D(createShaderModule(dxvk_blit_frag_3d)) { - if (device->extensions().extShaderViewportIndexLayer) { + if (device->features().vk12.shaderOutputLayer) { m_shaderVert = createShaderModule(dxvk_fullscreen_layer_vert); } else { m_shaderVert = createShaderModule(dxvk_fullscreen_vert); diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index c15f15ebc..a4c62488b 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -89,7 +89,7 @@ namespace dxvk { createShaderModule(dxvk_copy_depth_1d), createShaderModule(dxvk_copy_depth_2d), createShaderModule(dxvk_copy_depth_ms) } { - if (device->extensions().extShaderViewportIndexLayer) { + if (device->features().vk12.shaderOutputLayer) { m_shaderVert = createShaderModule(dxvk_fullscreen_layer_vert); } else { m_shaderVert = createShaderModule(dxvk_fullscreen_vert); diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index dae17e7ec..3e84e87af 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -64,7 +64,7 @@ namespace dxvk { if (device->extensions().extShaderStencilExport) m_shaderFragDS = createShaderModule(dxvk_resolve_frag_ds); - if (device->extensions().extShaderViewportIndexLayer) { + if (device->features().vk12.shaderOutputLayer) { m_shaderVert = createShaderModule(dxvk_fullscreen_layer_vert); } else { m_shaderVert = createShaderModule(dxvk_fullscreen_vert); From b701dd497feccb80a8f0f3347d0978719a2cb87f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:08:15 +0200 Subject: [PATCH 0219/1348] [dxvk] Drop VK_KHR_create_renderpass2 --- src/dxvk/dxvk_adapter.cpp | 3 +-- src/dxvk/dxvk_extensions.h | 1 - src/vulkan/vulkan_loader.h | 11 ++++------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 4707a8052..6ad12f6d4 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -283,7 +283,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -303,7 +303,6 @@ namespace dxvk { &devExtensions.extShaderStencilExport, &devExtensions.extTransformFeedback, &devExtensions.extVertexAttributeDivisor, - &devExtensions.khrCreateRenderPass2, &devExtensions.khrDepthStencilResolve, &devExtensions.khrDriverProperties, &devExtensions.khrDynamicRendering, diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 58419d698..cab5dd48f 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -295,7 +295,6 @@ namespace dxvk { DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt khrCreateRenderPass2 = { VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrDepthStencilResolve = { VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrDriverProperties = { VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrDynamicRendering = { VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, DxvkExtMode::Required }; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index c972b48a5..f9c5ccc92 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -231,6 +231,7 @@ namespace dxvk::vk { VULKAN_FN(vkCreateFramebuffer); VULKAN_FN(vkDestroyFramebuffer); VULKAN_FN(vkCreateRenderPass); + VULKAN_FN(vkCreateRenderPass2); VULKAN_FN(vkDestroyRenderPass); VULKAN_FN(vkGetRenderAreaGranularity); VULKAN_FN(vkCreateCommandPool); @@ -289,17 +290,13 @@ namespace dxvk::vk { VULKAN_FN(vkCmdCopyQueryPoolResults); VULKAN_FN(vkCmdPushConstants); VULKAN_FN(vkCmdBeginRenderPass); + VULKAN_FN(vkCmdBeginRenderPass2); VULKAN_FN(vkCmdNextSubpass); + VULKAN_FN(vkCmdNextSubpass2); VULKAN_FN(vkCmdEndRenderPass); + VULKAN_FN(vkCmdEndRenderPass2); VULKAN_FN(vkCmdExecuteCommands); - #ifdef VK_KHR_create_renderpass2 - VULKAN_FN(vkCreateRenderPass2KHR); - VULKAN_FN(vkCmdBeginRenderPass2KHR); - VULKAN_FN(vkCmdNextSubpass2KHR); - VULKAN_FN(vkCmdEndRenderPass2KHR); - #endif - #ifdef VK_KHR_swapchain VULKAN_FN(vkCreateSwapchainKHR); VULKAN_FN(vkDestroySwapchainKHR); From 956f293a69fafc34a1069d92b4679d5a08ac11d1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:13:38 +0200 Subject: [PATCH 0220/1348] [dxvk] Replace VK_KHR_depth_stencil_resolve with core feature --- src/d3d9/d3d9_device.cpp | 10 ++++---- src/dxvk/dxvk_adapter.cpp | 8 +------ src/dxvk/dxvk_context.cpp | 24 +++++++++---------- src/dxvk/dxvk_context.h | 12 +++++----- src/dxvk/dxvk_device_info.h | 1 - src/dxvk/dxvk_extensions.h | 1 - src/dxvk/dxvk_meta_resolve.cpp | 14 +++++------ src/dxvk/dxvk_meta_resolve.h | 8 +++---- src/dxvk/shaders/dxvk_resolve_frag_d.frag | 20 ++++++++-------- src/dxvk/shaders/dxvk_resolve_frag_ds.frag | 28 +++++++++++----------- 10 files changed, 59 insertions(+), 67 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 9e1581c24..a09ee6347 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -1071,8 +1071,8 @@ namespace dxvk { else { ctx->resolveDepthStencilImage( cDstImage, cSrcImage, cRegion, - VK_RESOLVE_MODE_AVERAGE_BIT_KHR, - VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR); + VK_RESOLVE_MODE_AVERAGE_BIT, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT); } }); }; @@ -4250,8 +4250,8 @@ namespace dxvk { else { ctx->resolveDepthStencilImage( cResolveImage, cMainImage, region, - VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR, - VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR); + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT); } }); } @@ -6876,7 +6876,7 @@ namespace dxvk { // We should resolve using the first sample according to // http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2012/10/Advanced-DX9-Capabilities-for-ATI-Radeon-Cards_v2.pdf // "The resolve operation copies the depth value from the *first sample only* into the resolved depth stencil texture." - constexpr auto resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR; + constexpr auto resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; VkImageResolve region; region.srcSubresource = cSrcSubres; diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 6ad12f6d4..4cf6a4027 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -283,7 +283,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -303,7 +303,6 @@ namespace dxvk { &devExtensions.extShaderStencilExport, &devExtensions.extTransformFeedback, &devExtensions.extVertexAttributeDivisor, - &devExtensions.khrDepthStencilResolve, &devExtensions.khrDriverProperties, &devExtensions.khrDynamicRendering, &devExtensions.khrExternalMemoryWin32, @@ -662,11 +661,6 @@ namespace dxvk { m_deviceInfo.extVertexAttributeDivisor.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extVertexAttributeDivisor); } - if (m_deviceExtensions.supports(VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME)) { - m_deviceInfo.khrDepthStencilResolve.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR; - m_deviceInfo.khrDepthStencilResolve.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.khrDepthStencilResolve); - } - if (m_deviceExtensions.supports(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) { m_deviceInfo.khrDeviceDriverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR; m_deviceInfo.khrDeviceDriverProperties.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.khrDeviceDriverProperties); diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b51c43290..f77d24207 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1809,8 +1809,8 @@ namespace dxvk { } else { this->resolveImageFb( dstImage, srcImage, region, format, - VK_RESOLVE_MODE_NONE_KHR, - VK_RESOLVE_MODE_NONE_KHR); + VK_RESOLVE_MODE_NONE, + VK_RESOLVE_MODE_NONE); } } @@ -1819,8 +1819,8 @@ namespace dxvk { const Rc& dstImage, const Rc& srcImage, const VkImageResolve& region, - VkResolveModeFlagBitsKHR depthMode, - VkResolveModeFlagBitsKHR stencilMode) { + VkResolveModeFlagBits depthMode, + VkResolveModeFlagBits stencilMode) { this->spillRenderPass(true); this->prepareImage(m_execBarriers, dstImage, vk::makeSubresourceRange(region.dstSubresource)); this->prepareImage(m_execBarriers, srcImage, vk::makeSubresourceRange(region.srcSubresource)); @@ -1834,7 +1834,7 @@ namespace dxvk { if (!(region.dstSubresource.aspectMask & region.srcSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)) - stencilMode = VK_RESOLVE_MODE_NONE_KHR; + stencilMode = VK_RESOLVE_MODE_NONE; // We can only use the depth-stencil resolve path if we are resolving // a full subresource and both images have the same format. @@ -1844,7 +1844,7 @@ namespace dxvk { if (!useFb) { // Additionally, the given mode combination must be supported. - const auto& properties = m_device->properties().khrDepthStencilResolve; + const auto& properties = m_device->properties().vk12; useFb |= (properties.supportedDepthResolveModes & depthMode) != depthMode || (properties.supportedStencilResolveModes & stencilMode) != stencilMode; @@ -3711,8 +3711,8 @@ namespace dxvk { const Rc& dstImage, const Rc& srcImage, const VkImageResolve& region, - VkResolveModeFlagBitsKHR depthMode, - VkResolveModeFlagBitsKHR stencilMode) { + VkResolveModeFlagBits depthMode, + VkResolveModeFlagBits stencilMode) { auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource); auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource); @@ -3813,8 +3813,8 @@ namespace dxvk { const Rc& srcImage, const VkImageResolve& region, VkFormat format, - VkResolveModeFlagBitsKHR depthMode, - VkResolveModeFlagBitsKHR stencilMode) { + VkResolveModeFlagBits depthMode, + VkResolveModeFlagBits stencilMode) { this->invalidateState(); auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource); @@ -3829,9 +3829,9 @@ namespace dxvk { bool doDiscard = dstImage->isFullSubresource(region.dstSubresource, region.extent); if (region.dstSubresource.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) - doDiscard &= depthMode != VK_RESOLVE_MODE_NONE_KHR; + doDiscard &= depthMode != VK_RESOLVE_MODE_NONE; if (region.dstSubresource.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) - doDiscard &= stencilMode != VK_RESOLVE_MODE_NONE_KHR; + doDiscard &= stencilMode != VK_RESOLVE_MODE_NONE; VkPipelineStageFlags dstStages; VkImageLayout dstLayout; diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 6047617a6..5f4528124 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -832,8 +832,8 @@ namespace dxvk { const Rc& dstImage, const Rc& srcImage, const VkImageResolve& region, - VkResolveModeFlagBitsKHR depthMode, - VkResolveModeFlagBitsKHR stencilMode); + VkResolveModeFlagBits depthMode, + VkResolveModeFlagBits stencilMode); /** * \brief Transforms image subresource layouts @@ -1270,16 +1270,16 @@ namespace dxvk { const Rc& dstImage, const Rc& srcImage, const VkImageResolve& region, - VkResolveModeFlagBitsKHR depthMode, - VkResolveModeFlagBitsKHR stencilMode); + VkResolveModeFlagBits depthMode, + VkResolveModeFlagBits stencilMode); void resolveImageFb( const Rc& dstImage, const Rc& srcImage, const VkImageResolve& region, VkFormat format, - VkResolveModeFlagBitsKHR depthMode, - VkResolveModeFlagBitsKHR stencilMode); + VkResolveModeFlagBits depthMode, + VkResolveModeFlagBits stencilMode); void performClear( const Rc& imageView, diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 69fb1263c..611d94a8b 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -22,7 +22,6 @@ namespace dxvk { VkPhysicalDeviceRobustness2PropertiesEXT extRobustness2; VkPhysicalDeviceTransformFeedbackPropertiesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT extVertexAttributeDivisor; - VkPhysicalDeviceDepthStencilResolvePropertiesKHR khrDepthStencilResolve; VkPhysicalDeviceDriverPropertiesKHR khrDeviceDriverProperties; VkPhysicalDeviceFloatControlsPropertiesKHR khrShaderFloatControls; }; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index cab5dd48f..b012e590b 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -295,7 +295,6 @@ namespace dxvk { DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt khrDepthStencilResolve = { VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrDriverProperties = { VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrDynamicRendering = { VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index 3e84e87af..d1f00697a 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -95,8 +95,8 @@ namespace dxvk { DxvkMetaResolvePipeline DxvkMetaResolveObjects::getPipeline( VkFormat format, VkSampleCountFlagBits samples, - VkResolveModeFlagBitsKHR depthResolveMode, - VkResolveModeFlagBitsKHR stencilResolveMode) { + VkResolveModeFlagBits depthResolveMode, + VkResolveModeFlagBits stencilResolveMode) { std::lock_guard lock(m_mutex); DxvkMetaResolvePipelineKey key; @@ -214,8 +214,8 @@ namespace dxvk { std::array specEntries = {{ { 0, offsetof(DxvkMetaResolvePipelineKey, samples), sizeof(VkSampleCountFlagBits) }, - { 1, offsetof(DxvkMetaResolvePipelineKey, modeD), sizeof(VkResolveModeFlagBitsKHR) }, - { 2, offsetof(DxvkMetaResolvePipelineKey, modeS), sizeof(VkResolveModeFlagBitsKHR) }, + { 1, offsetof(DxvkMetaResolvePipelineKey, modeD), sizeof(VkResolveModeFlagBits) }, + { 2, offsetof(DxvkMetaResolvePipelineKey, modeS), sizeof(VkResolveModeFlagBits) }, }}; VkSpecializationInfo specInfo; @@ -304,10 +304,10 @@ namespace dxvk { stencilOp.writeMask = 0xFFFFFFFF; VkPipelineDepthStencilStateCreateInfo dsState = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; - dsState.depthTestEnable = key.modeD != VK_RESOLVE_MODE_NONE_KHR; - dsState.depthWriteEnable = key.modeD != VK_RESOLVE_MODE_NONE_KHR; + dsState.depthTestEnable = key.modeD != VK_RESOLVE_MODE_NONE; + dsState.depthWriteEnable = key.modeD != VK_RESOLVE_MODE_NONE; dsState.depthCompareOp = VK_COMPARE_OP_ALWAYS; - dsState.stencilTestEnable = key.modeS != VK_RESOLVE_MODE_NONE_KHR; + dsState.stencilTestEnable = key.modeS != VK_RESOLVE_MODE_NONE; dsState.front = stencilOp; dsState.back = stencilOp; diff --git a/src/dxvk/dxvk_meta_resolve.h b/src/dxvk/dxvk_meta_resolve.h index 0f738e01a..5bf26301a 100644 --- a/src/dxvk/dxvk_meta_resolve.h +++ b/src/dxvk/dxvk_meta_resolve.h @@ -32,8 +32,8 @@ namespace dxvk { struct DxvkMetaResolvePipelineKey { VkFormat format; VkSampleCountFlagBits samples; - VkResolveModeFlagBitsKHR modeD; - VkResolveModeFlagBitsKHR modeS; + VkResolveModeFlagBits modeD; + VkResolveModeFlagBits modeS; bool eq(const DxvkMetaResolvePipelineKey& other) const { return this->format == other.format @@ -105,8 +105,8 @@ namespace dxvk { DxvkMetaResolvePipeline getPipeline( VkFormat format, VkSampleCountFlagBits samples, - VkResolveModeFlagBitsKHR depthResolveMode, - VkResolveModeFlagBitsKHR stencilResolveMode); + VkResolveModeFlagBits depthResolveMode, + VkResolveModeFlagBits stencilResolveMode); private: diff --git a/src/dxvk/shaders/dxvk_resolve_frag_d.frag b/src/dxvk/shaders/dxvk_resolve_frag_d.frag index 0b726c97e..dd913bee9 100644 --- a/src/dxvk/shaders/dxvk_resolve_frag_d.frag +++ b/src/dxvk/shaders/dxvk_resolve_frag_d.frag @@ -1,13 +1,13 @@ #version 450 -#define VK_RESOLVE_MODE_NONE_KHR (0) -#define VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR (1 << 0) -#define VK_RESOLVE_MODE_AVERAGE_BIT_KHR (1 << 1) -#define VK_RESOLVE_MODE_MIN_BIT_KHR (1 << 2) -#define VK_RESOLVE_MODE_MAX_BIT_KHR (1 << 3) +#define VK_RESOLVE_MODE_NONE (0) +#define VK_RESOLVE_MODE_SAMPLE_ZERO_BIT (1 << 0) +#define VK_RESOLVE_MODE_AVERAGE_BIT (1 << 1) +#define VK_RESOLVE_MODE_MIN_BIT (1 << 2) +#define VK_RESOLVE_MODE_MAX_BIT (1 << 3) layout(constant_id = 0) const int c_samples = 1; -layout(constant_id = 1) const int c_mode_d = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR; +layout(constant_id = 1) const int c_mode_d = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; layout(binding = 0) uniform sampler2DMSArray s_depth; @@ -20,24 +20,24 @@ float resolve_depth(ivec3 coord) { float depth = 0.0f; switch (c_mode_d) { - case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR: + case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT: depth = texelFetch(s_depth, coord, 0).r; break; - case VK_RESOLVE_MODE_AVERAGE_BIT_KHR: + case VK_RESOLVE_MODE_AVERAGE_BIT: depth = texelFetch(s_depth, coord, 0).r; for (int i = 1; i < c_samples; i++) depth += texelFetch(s_depth, coord, i).r; depth /= float(c_samples); break; - case VK_RESOLVE_MODE_MIN_BIT_KHR: + case VK_RESOLVE_MODE_MIN_BIT: depth = texelFetch(s_depth, coord, 0).r; for (int i = 1; i < c_samples; i++) depth = min(depth, texelFetch(s_depth, coord, i).r); break; - case VK_RESOLVE_MODE_MAX_BIT_KHR: + case VK_RESOLVE_MODE_MAX_BIT: depth = texelFetch(s_depth, coord, 0).r; for (int i = 1; i < c_samples; i++) depth = max(depth, texelFetch(s_depth, coord, i).r); diff --git a/src/dxvk/shaders/dxvk_resolve_frag_ds.frag b/src/dxvk/shaders/dxvk_resolve_frag_ds.frag index 734fe0fbb..3c9564685 100644 --- a/src/dxvk/shaders/dxvk_resolve_frag_ds.frag +++ b/src/dxvk/shaders/dxvk_resolve_frag_ds.frag @@ -2,15 +2,15 @@ #extension GL_ARB_shader_stencil_export : enable -#define VK_RESOLVE_MODE_NONE_KHR (0) -#define VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR (1 << 0) -#define VK_RESOLVE_MODE_AVERAGE_BIT_KHR (1 << 1) -#define VK_RESOLVE_MODE_MIN_BIT_KHR (1 << 2) -#define VK_RESOLVE_MODE_MAX_BIT_KHR (1 << 3) +#define VK_RESOLVE_MODE_NONE (0) +#define VK_RESOLVE_MODE_SAMPLE_ZERO_BIT (1 << 0) +#define VK_RESOLVE_MODE_AVERAGE_BIT (1 << 1) +#define VK_RESOLVE_MODE_MIN_BIT (1 << 2) +#define VK_RESOLVE_MODE_MAX_BIT (1 << 3) layout(constant_id = 0) const int c_samples = 1; -layout(constant_id = 1) const int c_mode_d = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR; -layout(constant_id = 2) const int c_mode_s = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR; +layout(constant_id = 1) const int c_mode_d = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; +layout(constant_id = 2) const int c_mode_s = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; layout(binding = 0) uniform sampler2DMSArray s_depth; layout(binding = 1) uniform usampler2DMSArray s_stencil; @@ -24,24 +24,24 @@ float resolve_depth(ivec3 coord) { float depth = 0.0f; switch (c_mode_d) { - case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR: + case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT: depth = texelFetch(s_depth, coord, 0).r; break; - case VK_RESOLVE_MODE_AVERAGE_BIT_KHR: + case VK_RESOLVE_MODE_AVERAGE_BIT: depth = texelFetch(s_depth, coord, 0).r; for (int i = 1; i < c_samples; i++) depth += texelFetch(s_depth, coord, i).r; depth /= float(c_samples); break; - case VK_RESOLVE_MODE_MIN_BIT_KHR: + case VK_RESOLVE_MODE_MIN_BIT: depth = texelFetch(s_depth, coord, 0).r; for (int i = 1; i < c_samples; i++) depth = min(depth, texelFetch(s_depth, coord, i).r); break; - case VK_RESOLVE_MODE_MAX_BIT_KHR: + case VK_RESOLVE_MODE_MAX_BIT: depth = texelFetch(s_depth, coord, 0).r; for (int i = 1; i < c_samples; i++) depth = max(depth, texelFetch(s_depth, coord, i).r); @@ -55,17 +55,17 @@ int resolve_stencil(ivec3 coord) { uint stencil = 0u; switch (c_mode_s) { - case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR: + case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT: stencil = texelFetch(s_stencil, coord, 0).r; break; - case VK_RESOLVE_MODE_MIN_BIT_KHR: + case VK_RESOLVE_MODE_MIN_BIT: stencil = texelFetch(s_stencil, coord, 0).r; for (int i = 1; i < c_samples; i++) stencil = min(stencil, texelFetch(s_stencil, coord, i).r); break; - case VK_RESOLVE_MODE_MAX_BIT_KHR: + case VK_RESOLVE_MODE_MAX_BIT: stencil = texelFetch(s_stencil, coord, 0).r; for (int i = 1; i < c_samples; i++) stencil = max(stencil, texelFetch(s_stencil, coord, i).r); From 000e3cb9607057bbe0543e3d95606227290f5eb7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:16:17 +0200 Subject: [PATCH 0221/1348] [dxvk] Replace VK_KHR_image_format_list with core feature --- src/dxvk/dxvk_adapter.cpp | 3 +-- src/dxvk/dxvk_extensions.h | 1 - src/dxvk/dxvk_image.cpp | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 4cf6a4027..db9e70491 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -283,7 +283,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -306,7 +306,6 @@ namespace dxvk { &devExtensions.khrDriverProperties, &devExtensions.khrDynamicRendering, &devExtensions.khrExternalMemoryWin32, - &devExtensions.khrImageFormatList, &devExtensions.khrPipelineLibrary, &devExtensions.khrShaderFloatControls, &devExtensions.khrSwapchain, diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index b012e590b..092c211a8 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -298,7 +298,6 @@ namespace dxvk { DxvkExt khrDriverProperties = { VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrDynamicRendering = { VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt khrImageFormatList = { VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrPipelineLibrary = { VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrShaderFloatControls = { VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrSwapchain = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtMode::Required }; diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index 851bbc53a..c8dd3f53d 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -22,8 +22,8 @@ namespace dxvk { // If defined, we should provide a format list, which // allows some drivers to enable image compression - VkImageFormatListCreateInfoKHR formatList; - formatList.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR; + VkImageFormatListCreateInfo formatList; + formatList.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO; formatList.pNext = nullptr; formatList.viewFormatCount = createInfo.viewFormatCount; formatList.pViewFormats = createInfo.viewFormats; From 78c5ef88bc5a5313561cc95ce388e20546674266 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:18:05 +0200 Subject: [PATCH 0222/1348] [dxvk] Replace VK_KHR_shader_float_controls with core feature --- src/dxbc/dxbc_options.cpp | 12 ++++++------ src/dxvk/dxvk_adapter.cpp | 8 +------- src/dxvk/dxvk_device_info.h | 1 - src/dxvk/dxvk_extensions.h | 1 - 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 154d25079..1bf7e4639 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -49,20 +49,20 @@ namespace dxvk { // Figure out float control flags to match D3D11 rules if (options.floatControls) { - if (devInfo.khrShaderFloatControls.shaderSignedZeroInfNanPreserveFloat32) + if (devInfo.vk12.shaderSignedZeroInfNanPreserveFloat32) floatControl.set(DxbcFloatControlFlag::PreserveNan32); - if (devInfo.khrShaderFloatControls.shaderSignedZeroInfNanPreserveFloat64) + if (devInfo.vk12.shaderSignedZeroInfNanPreserveFloat64) floatControl.set(DxbcFloatControlFlag::PreserveNan64); - if (devInfo.khrShaderFloatControls.denormBehaviorIndependence != VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE) { - if (devInfo.khrShaderFloatControls.shaderDenormFlushToZeroFloat32) + if (devInfo.vk12.denormBehaviorIndependence != VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE) { + if (devInfo.vk12.shaderDenormFlushToZeroFloat32) floatControl.set(DxbcFloatControlFlag::DenormFlushToZero32); - if (devInfo.khrShaderFloatControls.shaderDenormPreserveFloat64) + if (devInfo.vk12.shaderDenormPreserveFloat64) floatControl.set(DxbcFloatControlFlag::DenormPreserve64); } } - if (!devInfo.khrShaderFloatControls.shaderSignedZeroInfNanPreserveFloat32 + if (!devInfo.vk12.shaderSignedZeroInfNanPreserveFloat32 || adapter->matchesDriver(DxvkGpuVendor::Amd, VK_DRIVER_ID_MESA_RADV_KHR, 0, VK_MAKE_VERSION(20, 3, 0))) enableRtOutputNanFixup = true; } diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index db9e70491..c9027f18b 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -283,7 +283,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -307,7 +307,6 @@ namespace dxvk { &devExtensions.khrDynamicRendering, &devExtensions.khrExternalMemoryWin32, &devExtensions.khrPipelineLibrary, - &devExtensions.khrShaderFloatControls, &devExtensions.khrSwapchain, &devExtensions.nvxBinaryImport, &devExtensions.nvxImageViewHandle, @@ -665,11 +664,6 @@ namespace dxvk { m_deviceInfo.khrDeviceDriverProperties.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.khrDeviceDriverProperties); } - if (m_deviceExtensions.supports(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME)) { - m_deviceInfo.khrShaderFloatControls.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR; - m_deviceInfo.khrShaderFloatControls.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.khrShaderFloatControls); - } - // Query full device properties for all enabled extensions m_vki->vkGetPhysicalDeviceProperties2(m_handle, &m_deviceInfo.core); diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 611d94a8b..fad5ed454 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -23,7 +23,6 @@ namespace dxvk { VkPhysicalDeviceTransformFeedbackPropertiesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT extVertexAttributeDivisor; VkPhysicalDeviceDriverPropertiesKHR khrDeviceDriverProperties; - VkPhysicalDeviceFloatControlsPropertiesKHR khrShaderFloatControls; }; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 092c211a8..cc90e9b78 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -299,7 +299,6 @@ namespace dxvk { DxvkExt khrDynamicRendering = { VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrPipelineLibrary = { VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt khrShaderFloatControls = { VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrSwapchain = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt nvxBinaryImport = { VK_NVX_BINARY_IMPORT_EXTENSION_NAME, DxvkExtMode::Disabled }; DxvkExt nvxImageViewHandle = { VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME, DxvkExtMode::Disabled }; From 131af0d677d9d4dbbaa6495d052ac279d22bdbcb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:24:33 +0200 Subject: [PATCH 0223/1348] [dxvk] Replace VK_KHR_driver_properties with core feature --- src/d3d9/d3d9_options.cpp | 4 +--- src/dxbc/dxbc_options.cpp | 6 +++--- src/dxso/dxso_options.cpp | 2 +- src/dxvk/dxvk_adapter.cpp | 15 +++------------ src/dxvk/dxvk_adapter.h | 5 +---- src/dxvk/dxvk_device.cpp | 10 +++++----- src/dxvk/dxvk_device_info.h | 1 - src/dxvk/dxvk_extensions.h | 1 - src/dxvk/dxvk_memory.cpp | 2 +- 9 files changed, 15 insertions(+), 31 deletions(-) diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index 29d2c60a6..e038bf215 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -78,7 +78,6 @@ namespace dxvk { // If we are not Nvidia, enable general hazards. this->generalHazards = adapter != nullptr && !adapter->matchesDriver( - DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0); applyTristate(this->generalHazards, config.getOption("d3d9.generalHazards", Tristate::Auto)); @@ -92,8 +91,7 @@ namespace dxvk { d3d9FloatEmulation = D3D9FloatEmulation::Enabled; } else { bool hasMulz = adapter != nullptr - && adapter->matchesDriver(DxvkGpuVendor::Amd, - VK_DRIVER_ID_MESA_RADV, + && adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV, VK_MAKE_VERSION(21, 99, 99), 0); d3d9FloatEmulation = hasMulz ? D3D9FloatEmulation::Strict : D3D9FloatEmulation::Enabled; diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 1bf7e4639..17b239775 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -29,7 +29,7 @@ namespace dxvk { && (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); useSdivForBufferIndex - = adapter->matchesDriver(DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0); + = adapter->matchesDriver(VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0); switch (device->config().useRawSsbo) { case Tristate::Auto: minSsboAlignment = devInfo.core.properties.limits.minStorageBufferOffsetAlignment; break; @@ -44,7 +44,7 @@ namespace dxvk { disableMsaa = options.disableMsaa; // Disable subgroup early discard on Nvidia because it may hurt performance - if (adapter->matchesDriver(DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0)) + if (adapter->matchesDriver(VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0)) useSubgroupOpsForEarlyDiscard = false; // Figure out float control flags to match D3D11 rules @@ -63,7 +63,7 @@ namespace dxvk { } if (!devInfo.vk12.shaderSignedZeroInfNanPreserveFloat32 - || adapter->matchesDriver(DxvkGpuVendor::Amd, VK_DRIVER_ID_MESA_RADV_KHR, 0, VK_MAKE_VERSION(20, 3, 0))) + || adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV_KHR, 0, VK_MAKE_VERSION(20, 3, 0))) enableRtOutputNanFixup = true; } diff --git a/src/dxso/dxso_options.cpp b/src/dxso/dxso_options.cpp index e7c94e589..71e47613e 100644 --- a/src/dxso/dxso_options.cpp +++ b/src/dxso/dxso_options.cpp @@ -23,7 +23,7 @@ namespace dxvk { && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); // Disable early discard on Nvidia because it may hurt performance - if (adapter->matchesDriver(DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0)) + if (adapter->matchesDriver(VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0)) useSubgroupOpsForEarlyDiscard = false; // Apply shader-related options diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index c9027f18b..e66d5c9b3 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -283,7 +283,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -303,7 +303,6 @@ namespace dxvk { &devExtensions.extShaderStencilExport, &devExtensions.extTransformFeedback, &devExtensions.extVertexAttributeDivisor, - &devExtensions.khrDriverProperties, &devExtensions.khrDynamicRendering, &devExtensions.khrExternalMemoryWin32, &devExtensions.khrPipelineLibrary, @@ -546,13 +545,10 @@ namespace dxvk { bool DxvkAdapter::matchesDriver( - DxvkGpuVendor vendor, VkDriverIdKHR driver, uint32_t minVer, uint32_t maxVer) const { - bool driverMatches = m_deviceInfo.khrDeviceDriverProperties.driverID - ? driver == m_deviceInfo.khrDeviceDriverProperties.driverID - : vendor == DxvkGpuVendor(m_deviceInfo.core.properties.vendorID); + bool driverMatches = driver == m_deviceInfo.vk12.driverID; if (minVer) driverMatches &= m_deviceInfo.core.properties.driverVersion >= minVer; if (maxVer) driverMatches &= m_deviceInfo.core.properties.driverVersion < maxVer; @@ -659,16 +655,11 @@ namespace dxvk { m_deviceInfo.extVertexAttributeDivisor.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extVertexAttributeDivisor); } - if (m_deviceExtensions.supports(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) { - m_deviceInfo.khrDeviceDriverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR; - m_deviceInfo.khrDeviceDriverProperties.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.khrDeviceDriverProperties); - } - // Query full device properties for all enabled extensions m_vki->vkGetPhysicalDeviceProperties2(m_handle, &m_deviceInfo.core); // Some drivers reports the driver version in a slightly different format - switch (m_deviceInfo.khrDeviceDriverProperties.driverID) { + switch (m_deviceInfo.vk12.driverID) { case VK_DRIVER_ID_NVIDIA_PROPRIETARY: m_deviceInfo.core.properties.driverVersion = VK_MAKE_VERSION( (m_deviceInfo.core.properties.driverVersion >> 22) & 0x3ff, diff --git a/src/dxvk/dxvk_adapter.h b/src/dxvk/dxvk_adapter.h index f2fb1f0af..42af9d153 100644 --- a/src/dxvk/dxvk_adapter.h +++ b/src/dxvk/dxvk_adapter.h @@ -226,15 +226,12 @@ namespace dxvk { /** * \brief Tests if the driver matches certain criteria * - * \param [in] vendor GPU vendor - * \param [in] driver Driver. Ignored when the - * driver properties extension is not supported. + * \param [in] driver Driver ID * \param [in] minVer Match versions starting with this one * \param [in] maxVer Match versions lower than this one * \returns \c True if the driver matches these criteria */ bool matchesDriver( - DxvkGpuVendor vendor, VkDriverIdKHR driver, uint32_t minVer, uint32_t maxVer) const; diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 979e1623a..2bae86395 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -271,12 +271,12 @@ namespace dxvk { DxvkDevicePerfHints DxvkDevice::getPerfHints() { DxvkDevicePerfHints hints; hints.preferFbDepthStencilCopy = m_extensions.extShaderStencilExport - && (m_adapter->matchesDriver(DxvkGpuVendor::Amd, VK_DRIVER_ID_MESA_RADV_KHR, 0, 0) - || m_adapter->matchesDriver(DxvkGpuVendor::Amd, VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR, 0, 0) - || m_adapter->matchesDriver(DxvkGpuVendor::Amd, VK_DRIVER_ID_AMD_PROPRIETARY_KHR, 0, 0)); + && (m_adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV_KHR, 0, 0) + || m_adapter->matchesDriver(VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR, 0, 0) + || m_adapter->matchesDriver(VK_DRIVER_ID_AMD_PROPRIETARY_KHR, 0, 0)); hints.preferFbResolve = m_extensions.amdShaderFragmentMask - && (m_adapter->matchesDriver(DxvkGpuVendor::Amd, VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR, 0, 0) - || m_adapter->matchesDriver(DxvkGpuVendor::Amd, VK_DRIVER_ID_AMD_PROPRIETARY_KHR, 0, 0)); + && (m_adapter->matchesDriver(VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR, 0, 0) + || m_adapter->matchesDriver(VK_DRIVER_ID_AMD_PROPRIETARY_KHR, 0, 0)); return hints; } diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index fad5ed454..68f558641 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -22,7 +22,6 @@ namespace dxvk { VkPhysicalDeviceRobustness2PropertiesEXT extRobustness2; VkPhysicalDeviceTransformFeedbackPropertiesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT extVertexAttributeDivisor; - VkPhysicalDeviceDriverPropertiesKHR khrDeviceDriverProperties; }; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index cc90e9b78..f88a8998a 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -295,7 +295,6 @@ namespace dxvk { DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt khrDriverProperties = { VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrDynamicRendering = { VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrPipelineLibrary = { VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index a33772c70..fdbb0d4c7 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -217,7 +217,7 @@ namespace dxvk { /* Work around an issue on Nvidia drivers where using the entire * device_local | host_visible heap can cause crashes or slowdowns */ if (m_device->properties().core.properties.vendorID == uint16_t(DxvkGpuVendor::Nvidia)) { - bool shrinkNvidiaHvvHeap = device->adapter()->matchesDriver(DxvkGpuVendor::Nvidia, + bool shrinkNvidiaHvvHeap = device->adapter()->matchesDriver( VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, VK_MAKE_VERSION(465, 0, 0)); applyTristate(shrinkNvidiaHvvHeap, device->config().shrinkNvidiaHvvHeap); From 81b89cf31d8a065524beda7742d55aa5d98b04f3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:29:53 +0200 Subject: [PATCH 0224/1348] [dxvk] Simplify Nvidia HVV workaround We no longer support 465 series drivers, so the check was obsolete. --- dxvk.conf | 13 ++++++------- src/dxvk/dxvk_memory.cpp | 24 +++++++++--------------- src/dxvk/dxvk_options.cpp | 2 +- src/dxvk/dxvk_options.h | 2 +- 4 files changed, 17 insertions(+), 24 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index 6839cd3d6..fedc28148 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -251,16 +251,15 @@ # Controls Nvidia HVV behaviour. # -# Disables the host-visible, device-local heap on Nvidia drivers. This -# is used to avoid NVIDIA driver bug 3114283 on affected drivers, as -# well as in specific games on newer drivers.being enabled on all -# affected drivers. +# Restricts use of the host-visible, device-local heap on Nvidia drivers. +# This is used to avoid NVIDIA driver bug 3114283 on affected drivers, as +# well as in specific games on newer drivers. # # Supported values: -# - Auto: Don't change the default -# - True, False: Always enable / disable +# - True: Restrict HVV usage +# - False: Do not restrict HVV usage -# dxvk.shrinkNvidiaHvvHeap = Auto +# dxvk.shrinkNvidiaHvvHeap = False # Controls graphics pipeline library behaviour diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index fdbb0d4c7..279700d85 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -214,22 +214,16 @@ namespace dxvk { largestDeviceLocalHeap = std::max(largestDeviceLocalHeap, m_memTypes[i].heap->properties.size); } - /* Work around an issue on Nvidia drivers where using the entire - * device_local | host_visible heap can cause crashes or slowdowns */ - if (m_device->properties().core.properties.vendorID == uint16_t(DxvkGpuVendor::Nvidia)) { - bool shrinkNvidiaHvvHeap = device->adapter()->matchesDriver( - VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, VK_MAKE_VERSION(465, 0, 0)); + /* Work around an issue on Nvidia drivers where using the + * entire HVV heap can cause slowdowns in specific games */ + if (device->adapter()->matchesDriver(VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0) + && device->config().shrinkNvidiaHvvHeap) { + for (uint32_t i = 0; i < m_memProps.memoryTypeCount; i++) { + VkMemoryPropertyFlags hvvFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - applyTristate(shrinkNvidiaHvvHeap, device->config().shrinkNvidiaHvvHeap); - - if (shrinkNvidiaHvvHeap) { - for (uint32_t i = 0; i < m_memProps.memoryTypeCount; i++) { - VkMemoryPropertyFlags hvvFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - - if ((m_memTypes[i].memType.propertyFlags & hvvFlags) == hvvFlags - && (m_memTypes[i].heap->properties.size < largestDeviceLocalHeap)) - m_memTypes[i].heap->budget = 32 << 20; - } + if ((m_memTypes[i].memType.propertyFlags & hvvFlags) == hvvFlags + && (m_memTypes[i].heap->properties.size < largestDeviceLocalHeap)) + m_memTypes[i].heap->budget = 32 << 20; } } } diff --git a/src/dxvk/dxvk_options.cpp b/src/dxvk/dxvk_options.cpp index 87f26186c..d251cbcf6 100644 --- a/src/dxvk/dxvk_options.cpp +++ b/src/dxvk/dxvk_options.cpp @@ -8,7 +8,7 @@ namespace dxvk { numCompilerThreads = config.getOption ("dxvk.numCompilerThreads", 0); enableGraphicsPipelineLibrary = config.getOption("dxvk.enableGraphicsPipelineLibrary", Tristate::Auto); useRawSsbo = config.getOption("dxvk.useRawSsbo", Tristate::Auto); - shrinkNvidiaHvvHeap = config.getOption("dxvk.shrinkNvidiaHvvHeap", Tristate::Auto); + shrinkNvidiaHvvHeap = config.getOption ("dxvk.shrinkNvidiaHvvHeap", false); hud = config.getOption("dxvk.hud", ""); } diff --git a/src/dxvk/dxvk_options.h b/src/dxvk/dxvk_options.h index 18210fa64..c2f7f11ba 100644 --- a/src/dxvk/dxvk_options.h +++ b/src/dxvk/dxvk_options.h @@ -25,7 +25,7 @@ namespace dxvk { Tristate useRawSsbo; /// Workaround for NVIDIA driver bug 3114283 - Tristate shrinkNvidiaHvvHeap; + bool shrinkNvidiaHvvHeap; /// HUD elements std::string hud; From 223a4fd18648196d59d0d7ab2e1f9f8a51b35744 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:30:39 +0200 Subject: [PATCH 0225/1348] [d3d9] Always assume RADV has fast mulz support All supported Mesa version support this. --- src/d3d9/d3d9_options.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index e038bf215..a3944d892 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -91,9 +91,7 @@ namespace dxvk { d3d9FloatEmulation = D3D9FloatEmulation::Enabled; } else { bool hasMulz = adapter != nullptr - && adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV, - VK_MAKE_VERSION(21, 99, 99), - 0); + && adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV, 0, 0); d3d9FloatEmulation = hasMulz ? D3D9FloatEmulation::Strict : D3D9FloatEmulation::Enabled; } } From 1dd3f24b436cec25250118f088a7e3e5f5f3100d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:32:30 +0200 Subject: [PATCH 0226/1348] [dxbc] Drop workarounds for unsupported drivers --- src/dxbc/dxbc_compiler.cpp | 12 +++--------- src/dxbc/dxbc_options.cpp | 9 +-------- src/dxbc/dxbc_options.h | 4 ---- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 2fdf24d79..8e9d49cf8 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -5366,11 +5366,8 @@ namespace dxvk { result.type.ctype = DxbcScalarType::Sint32; result.type.ccount = 1; - const uint32_t typeId = getVectorTypeId(result.type); - - uint32_t offset = m_moduleInfo.options.useSdivForBufferIndex - ? m_module.opSDiv (typeId, structOffset.id, m_module.consti32(4)) - : m_module.opShiftRightLogical(typeId, structOffset.id, m_module.consti32(2)); + uint32_t typeId = getVectorTypeId(result.type); + uint32_t offset = m_module.opShiftRightLogical(typeId, structOffset.id, m_module.consti32(2)); result.id = m_module.opIAdd(typeId, m_module.opIMul(typeId, structId.id, m_module.consti32(structStride / 4)), @@ -5386,10 +5383,7 @@ namespace dxvk { result.type.ccount = 1; uint32_t typeId = getVectorTypeId(result.type); - - result.id = m_moduleInfo.options.useSdivForBufferIndex - ? m_module.opSDiv (typeId, byteOffset.id, m_module.consti32(4)) - : m_module.opShiftRightLogical(typeId, byteOffset.id, m_module.consti32(2)); + result.id = m_module.opShiftRightLogical(typeId, byteOffset.id, m_module.consti32(2)); return result; } diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 17b239775..6d064e1f2 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -28,8 +28,6 @@ namespace dxvk { = (devInfo.vk11.subgroupSize >= 4) && (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); - useSdivForBufferIndex - = adapter->matchesDriver(VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0); switch (device->config().useRawSsbo) { case Tristate::Auto: minSsboAlignment = devInfo.core.properties.limits.minStorageBufferOffsetAlignment; break; @@ -43,10 +41,6 @@ namespace dxvk { forceTgsmBarriers = options.forceTgsmBarriers; disableMsaa = options.disableMsaa; - // Disable subgroup early discard on Nvidia because it may hurt performance - if (adapter->matchesDriver(VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0)) - useSubgroupOpsForEarlyDiscard = false; - // Figure out float control flags to match D3D11 rules if (options.floatControls) { if (devInfo.vk12.shaderSignedZeroInfNanPreserveFloat32) @@ -62,8 +56,7 @@ namespace dxvk { } } - if (!devInfo.vk12.shaderSignedZeroInfNanPreserveFloat32 - || adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV_KHR, 0, VK_MAKE_VERSION(20, 3, 0))) + if (!devInfo.vk12.shaderSignedZeroInfNanPreserveFloat32) enableRtOutputNanFixup = true; } diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index ed3993746..1edec4c7b 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -37,10 +37,6 @@ namespace dxvk { /// shader invocations if derivatives remain valid. bool useSubgroupOpsForEarlyDiscard = false; - /// Use SDiv instead of SHR to converte byte offsets to - /// dword offsets. Fixes RE2 and DMC5 on Nvidia drivers. - bool useSdivForBufferIndex = false; - /// Enables NaN fixup for render target outputs bool enableRtOutputNanFixup = false; From e79a2e8dfa29465ad216d71d63375e94c4db2f44 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:43:50 +0200 Subject: [PATCH 0227/1348] [dxvk] Enable Vulkan 1.3 feature structs --- src/dxvk/dxvk_adapter.cpp | 33 +++++++++++++++++++++++++++++++++ src/dxvk/dxvk_device_info.h | 2 ++ 2 files changed, 35 insertions(+) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index e66d5c9b3..de23069c1 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -236,6 +236,18 @@ namespace dxvk { || !required.vk12.shaderOutputViewportIndex) && (m_deviceFeatures.vk12.shaderOutputLayer || !required.vk12.shaderOutputLayer) + && (m_deviceFeatures.vk13.pipelineCreationCacheControl + || !required.vk13.pipelineCreationCacheControl) + && (m_deviceFeatures.vk13.shaderDemoteToHelperInvocation + || !required.vk13.shaderDemoteToHelperInvocation) + && (m_deviceFeatures.vk13.shaderZeroInitializeWorkgroupMemory + || !required.vk13.shaderZeroInitializeWorkgroupMemory) + && (m_deviceFeatures.vk13.synchronization2 + || !required.vk13.synchronization2) + && (m_deviceFeatures.vk13.dynamicRendering + || !required.vk13.dynamicRendering) + && (m_deviceFeatures.vk13.maintenance4 + || !required.vk13.maintenance4) && (m_deviceFeatures.ext4444Formats.formatA4R4G4B4 || !required.ext4444Formats.formatA4R4G4B4) && (m_deviceFeatures.ext4444Formats.formatA4B4G4R4 @@ -344,6 +356,11 @@ namespace dxvk { enabledFeatures.vk12.shaderOutputViewportIndex = m_deviceFeatures.vk12.shaderOutputViewportIndex; enabledFeatures.vk12.shaderOutputLayer = m_deviceFeatures.vk12.shaderOutputLayer; + enabledFeatures.vk13.pipelineCreationCacheControl = m_deviceFeatures.vk13.pipelineCreationCacheControl; + enabledFeatures.vk13.synchronization2 = VK_TRUE; + enabledFeatures.vk13.dynamicRendering = VK_TRUE; + enabledFeatures.vk13.maintenance4 = VK_TRUE; + enabledFeatures.extExtendedDynamicState.extendedDynamicState = VK_TRUE; enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = @@ -385,6 +402,9 @@ namespace dxvk { enabledFeatures.vk12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; enabledFeatures.vk12.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.vk12); + enabledFeatures.vk13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; + enabledFeatures.vk13.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.vk13); + if (devExtensions.ext4444Formats) { enabledFeatures.ext4444Formats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; enabledFeatures.ext4444Formats.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.ext4444Formats); @@ -625,6 +645,9 @@ namespace dxvk { m_deviceInfo.vk12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES; m_deviceInfo.vk12.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.vk12); + m_deviceInfo.vk13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES; + m_deviceInfo.vk13.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.vk13); + if (m_deviceExtensions.supports(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) { m_deviceInfo.extConservativeRasterization.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT; m_deviceInfo.extConservativeRasterization.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extConservativeRasterization); @@ -689,6 +712,9 @@ namespace dxvk { m_deviceFeatures.vk12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; m_deviceFeatures.vk12.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.vk12); + m_deviceFeatures.vk13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; + m_deviceFeatures.vk13.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.vk13); + if (m_deviceExtensions.supports(VK_EXT_4444_FORMATS_EXTENSION_NAME)) { m_deviceFeatures.ext4444Formats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; m_deviceFeatures.ext4444Formats.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.ext4444Formats); @@ -835,6 +861,13 @@ namespace dxvk { "\n bufferDeviceAddress : ", features.vk12.bufferDeviceAddress, "\n shaderOutputViewportIndex : ", features.vk12.shaderOutputViewportIndex, "\n shaderOutputLayer : ", features.vk12.shaderOutputLayer, + "\nVulkan 1.3", + "\n pipelineCreationCacheControl : ", features.vk13.pipelineCreationCacheControl, + "\n shaderDemoteToHelperInvocation : ", features.vk13.shaderDemoteToHelperInvocation, + "\n shaderZeroInitializeWorkgroupMemory : ", features.vk13.shaderZeroInitializeWorkgroupMemory, + "\n synchronization2 : ", features.vk13.synchronization2, + "\n dynamicRendering : ", features.vk13.dynamicRendering, + "\n maintenance4 : ", features.vk13.maintenance4, "\n", VK_EXT_4444_FORMATS_EXTENSION_NAME, "\n formatA4R4G4B4 : ", features.ext4444Formats.formatA4R4G4B4 ? "1" : "0", "\n formatA4B4G4R4 : ", features.ext4444Formats.formatA4B4G4R4 ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 68f558641..202db3fb4 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -16,6 +16,7 @@ namespace dxvk { VkPhysicalDeviceProperties2 core; VkPhysicalDeviceVulkan11Properties vk11; VkPhysicalDeviceVulkan12Properties vk12; + VkPhysicalDeviceVulkan13Properties vk13; VkPhysicalDeviceConservativeRasterizationPropertiesEXT extConservativeRasterization; VkPhysicalDeviceCustomBorderColorPropertiesEXT extCustomBorderColor; VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT extGraphicsPipelineLibrary; @@ -36,6 +37,7 @@ namespace dxvk { VkPhysicalDeviceFeatures2 core; VkPhysicalDeviceVulkan11Features vk11; VkPhysicalDeviceVulkan12Features vk12; + VkPhysicalDeviceVulkan13Features vk13; VkPhysicalDevice4444FormatsFeaturesEXT ext4444Formats; VkPhysicalDeviceCustomBorderColorFeaturesEXT extCustomBorderColor; VkPhysicalDeviceDepthClipEnableFeaturesEXT extDepthClipEnable; From 3cfc3e77144c8058683868c35e4ce1dbee84d6ed Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:51:00 +0200 Subject: [PATCH 0228/1348] [dxvk] Replace VK_KHR_dynamic_rendering with core feature --- src/dxvk/dxvk_adapter.cpp | 19 ++------------- src/dxvk/dxvk_cmdlist.h | 6 ++--- src/dxvk/dxvk_context.cpp | 42 +++++++++++++++++----------------- src/dxvk/dxvk_device_info.h | 1 - src/dxvk/dxvk_extensions.h | 1 - src/dxvk/dxvk_graphics.cpp | 2 +- src/dxvk/dxvk_graphics.h | 2 +- src/dxvk/dxvk_meta_blit.cpp | 2 +- src/dxvk/dxvk_meta_copy.cpp | 2 +- src/dxvk/dxvk_meta_resolve.cpp | 2 +- src/dxvk/dxvk_shader.cpp | 4 ++-- src/vulkan/vulkan_loader.h | 7 ++---- 12 files changed, 35 insertions(+), 55 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index de23069c1..101db97f8 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -295,7 +295,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -315,7 +315,6 @@ namespace dxvk { &devExtensions.extShaderStencilExport, &devExtensions.extTransformFeedback, &devExtensions.extVertexAttributeDivisor, - &devExtensions.khrDynamicRendering, &devExtensions.khrExternalMemoryWin32, &devExtensions.khrPipelineLibrary, &devExtensions.khrSwapchain, @@ -379,8 +378,6 @@ namespace dxvk { enabledFeatures.extShaderModuleIdentifier.shaderModuleIdentifier = m_deviceFeatures.extShaderModuleIdentifier.shaderModuleIdentifier; - enabledFeatures.khrDynamicRendering.dynamicRendering = VK_TRUE; - Logger::info(str::format("Device properties:" "\n Device name: : ", m_deviceInfo.core.properties.deviceName, "\n Driver version : ", @@ -470,11 +467,6 @@ namespace dxvk { enabledFeatures.extVertexAttributeDivisor.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extVertexAttributeDivisor); } - if (devExtensions.khrDynamicRendering) { - enabledFeatures.khrDynamicRendering.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR; - enabledFeatures.khrDynamicRendering.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.khrDynamicRendering); - } - // Report the desired overallocation behaviour to the driver VkDeviceMemoryOverallocationCreateInfoAMD overallocInfo; overallocInfo.sType = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD; @@ -780,11 +772,6 @@ namespace dxvk { m_deviceFeatures.extVertexAttributeDivisor.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extVertexAttributeDivisor); } - if (m_deviceExtensions.supports(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME)) { - m_deviceFeatures.khrDynamicRendering.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR; - m_deviceFeatures.khrDynamicRendering.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.khrDynamicRendering); - } - m_vki->vkGetPhysicalDeviceFeatures2(m_handle, &m_deviceFeatures.core); } @@ -899,9 +886,7 @@ namespace dxvk { "\n geometryStreams : ", features.extTransformFeedback.geometryStreams ? "1" : "0", "\n", VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, "\n vertexAttributeInstanceRateDivisor : ", features.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor ? "1" : "0", - "\n vertexAttributeInstanceRateZeroDivisor : ", features.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor ? "1" : "0", - "\n", VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, - "\n dynamicRendering : ", features.khrDynamicRendering.dynamicRendering ? "1" : "0")); + "\n vertexAttributeInstanceRateZeroDivisor : ", features.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor ? "1" : "0")); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 4cdabb582..687f787eb 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -254,8 +254,8 @@ namespace dxvk { void cmdBeginRendering( - const VkRenderingInfoKHR* pRenderingInfo) { - m_vkd->vkCmdBeginRenderingKHR(m_execBuffer, pRenderingInfo); + const VkRenderingInfo* pRenderingInfo) { + m_vkd->vkCmdBeginRendering(m_execBuffer, pRenderingInfo); } @@ -588,7 +588,7 @@ namespace dxvk { void cmdEndRendering() { - m_vkd->vkCmdEndRenderingKHR(m_execBuffer); + m_vkd->vkCmdEndRendering(m_execBuffer); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index f77d24207..b364c78f7 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1620,12 +1620,12 @@ namespace dxvk { descriptorWrite.pImageInfo = &descriptorImage; // Common render pass info - VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + VkRenderingAttachmentInfo attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; attachmentInfo.imageLayout = dstLayout; attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + VkRenderingInfo renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO }; renderingInfo.colorAttachmentCount = 1; renderingInfo.pColorAttachments = &attachmentInfo; @@ -1960,17 +1960,17 @@ namespace dxvk { ? imageView->pickLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) : imageView->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + VkRenderingAttachmentInfo attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; attachmentInfo.imageView = imageView->handle(); attachmentInfo.imageLayout = imageLayout; attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachmentInfo.clearValue = clearValue; - VkRenderingAttachmentInfoKHR stencilInfo = attachmentInfo; + VkRenderingAttachmentInfo stencilInfo = attachmentInfo; VkExtent3D extent = imageView->mipLevelExtent(0); - VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + VkRenderingInfo renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO }; renderingInfo.renderArea.extent = { extent.width, extent.height }; renderingInfo.layerCount = imageView->info().numLayers; @@ -2704,13 +2704,13 @@ namespace dxvk { VkExtent3D imageExtent = dstImage->mipLevelExtent(region.dstSubresource.mipLevel); - VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + VkRenderingAttachmentInfo attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; attachmentInfo.imageView = pass->getDstView(); attachmentInfo.imageLayout = dstLayout; attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + VkRenderingInfo renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO }; renderingInfo.renderArea = VkRect2D { VkOffset2D { 0, 0 }, VkExtent2D { imageExtent.width, imageExtent.height } }; @@ -3043,13 +3043,13 @@ namespace dxvk { VkExtent3D extent = imageView->mipLevelExtent(0); - VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + VkRenderingAttachmentInfo attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; attachmentInfo.imageView = imageView->handle(); attachmentInfo.imageLayout = clearLayout; attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + VkRenderingInfo renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO }; renderingInfo.renderArea.extent = { extent.width, extent.height }; renderingInfo.layerCount = imageView->info().numLayers; @@ -3504,7 +3504,7 @@ namespace dxvk { VkExtent3D mipExtent = dstImage->mipLevelExtent(dstSubresource.mipLevel); - VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + VkRenderingAttachmentInfo attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; attachmentInfo.imageView = views->getDstView(); attachmentInfo.imageLayout = dstLayout; attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; @@ -3513,7 +3513,7 @@ namespace dxvk { if (doDiscard) attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + VkRenderingInfo renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO }; renderingInfo.renderArea.offset = VkOffset2D { 0, 0 }; renderingInfo.renderArea.extent = VkExtent2D { mipExtent.width, mipExtent.height }; renderingInfo.layerCount = dstSubresource.layerCount; @@ -3755,7 +3755,7 @@ namespace dxvk { dstImage, region.dstSubresource, srcImage, region.srcSubresource, dstImage->info().format); - VkRenderingAttachmentInfoKHR depthAttachment = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + VkRenderingAttachmentInfo depthAttachment = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; depthAttachment.imageView = views->getSrcView(); depthAttachment.imageLayout = srcLayout; depthAttachment.resolveMode = depthMode; @@ -3764,12 +3764,12 @@ namespace dxvk { depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - VkRenderingAttachmentInfoKHR stencilAttachment = depthAttachment; + VkRenderingAttachmentInfo stencilAttachment = depthAttachment; stencilAttachment.resolveMode = stencilMode; VkExtent3D extent = dstImage->mipLevelExtent(region.dstSubresource.mipLevel); - VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + VkRenderingInfo renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO }; renderingInfo.renderArea.offset = VkOffset2D { 0, 0 }; renderingInfo.renderArea.extent = VkExtent2D { extent.width, extent.height }; renderingInfo.layerCount = region.dstSubresource.layerCount; @@ -3934,7 +3934,7 @@ namespace dxvk { scissor.offset = { region.dstOffset.x, region.dstOffset.y }; scissor.extent = { region.extent.width, region.extent.height }; - VkRenderingAttachmentInfoKHR attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + VkRenderingAttachmentInfo attachmentInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; attachmentInfo.imageView = views->getDstView(); attachmentInfo.imageLayout = dstLayout; attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; @@ -3943,7 +3943,7 @@ namespace dxvk { if (doDiscard) attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + VkRenderingInfo renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO }; renderingInfo.renderArea.offset = VkOffset2D { 0, 0 }; renderingInfo.renderArea.extent = VkExtent2D { passExtent.width, passExtent.height }; renderingInfo.layerCount = region.dstSubresource.layerCount; @@ -4224,11 +4224,11 @@ namespace dxvk { uint32_t colorInfoCount = 0; - std::array colorInfos; + std::array colorInfos; for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { const auto& colorTarget = framebufferInfo.getColorTarget(i); - colorInfos[i] = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + colorInfos[i] = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; if (colorTarget.view != nullptr) { colorInfos[i].imageView = colorTarget.view->handle(); @@ -4243,7 +4243,7 @@ namespace dxvk { } } - VkRenderingAttachmentInfoKHR depthInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR }; + VkRenderingAttachmentInfo depthInfo = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; VkImageAspectFlags depthStencilAspects = 0; if (framebufferInfo.getDepthTarget().view != nullptr) { @@ -4258,7 +4258,7 @@ namespace dxvk { depthInfo.clearValue.depthStencil.depth = ops.depthOps.clearValue.depth; } - VkRenderingAttachmentInfoKHR stencilInfo = depthInfo; + VkRenderingAttachmentInfo stencilInfo = depthInfo; if (framebufferInfo.getDepthTarget().view != nullptr) { stencilInfo.loadOp = ops.depthOps.loadOpS; @@ -4268,7 +4268,7 @@ namespace dxvk { stencilInfo.clearValue.depthStencil.stencil = ops.depthOps.clearValue.stencil; } - VkRenderingInfoKHR renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO_KHR }; + VkRenderingInfo renderingInfo = { VK_STRUCTURE_TYPE_RENDERING_INFO }; renderingInfo.renderArea.offset = VkOffset2D { 0, 0 }; renderingInfo.renderArea.extent = VkExtent2D { fbSize.width, fbSize.height }; renderingInfo.layerCount = fbSize.layers; diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 202db3fb4..95de74975 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -51,7 +51,6 @@ namespace dxvk { VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT extShaderModuleIdentifier; VkPhysicalDeviceTransformFeedbackFeaturesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT extVertexAttributeDivisor; - VkPhysicalDeviceDynamicRenderingFeaturesKHR khrDynamicRendering; }; } \ No newline at end of file diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index f88a8998a..668807a2b 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -295,7 +295,6 @@ namespace dxvk { DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt khrDynamicRendering = { VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrPipelineLibrary = { VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrSwapchain = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtMode::Required }; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index fb38c3deb..96e8938f1 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -355,7 +355,7 @@ namespace dxvk { // pNext is non-const for some reason, but this is only an input // structure, so we should be able to safely use const_cast. VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT }; - libInfo.pNext = const_cast(&state.rtInfo); + libInfo.pNext = const_cast(&state.rtInfo); libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT; VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 4a0c79dc2..21631d3f4 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -92,7 +92,7 @@ namespace dxvk { const DxvkGraphicsPipelineStateInfo& state, const DxvkShader* fs); - VkPipelineRenderingCreateInfoKHR rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + VkPipelineRenderingCreateInfo rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO }; VkPipelineColorBlendStateCreateInfo cbInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; VkPipelineMultisampleStateCreateInfo msInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; diff --git a/src/dxvk/dxvk_meta_blit.cpp b/src/dxvk/dxvk_meta_blit.cpp index b069b0a99..aaf33a788 100644 --- a/src/dxvk/dxvk_meta_blit.cpp +++ b/src/dxvk/dxvk_meta_blit.cpp @@ -345,7 +345,7 @@ namespace dxvk { cbState.attachmentCount = 1; cbState.pAttachments = &cbAttachment; - VkPipelineRenderingCreateInfoKHR rtState = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + VkPipelineRenderingCreateInfo rtState = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO }; rtState.colorAttachmentCount = 1; rtState.pColorAttachmentFormats = &format; diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index a4c62488b..621ba0118 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -400,7 +400,7 @@ namespace dxvk { dsState.front = stencilOp; dsState.back = stencilOp; - VkPipelineRenderingCreateInfoKHR rtState = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + VkPipelineRenderingCreateInfo rtState = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO }; if (aspect & VK_IMAGE_ASPECT_COLOR_BIT) { rtState.colorAttachmentCount = 1; diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index d1f00697a..c0a5e919d 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -311,7 +311,7 @@ namespace dxvk { dsState.front = stencilOp; dsState.back = stencilOp; - VkPipelineRenderingCreateInfoKHR rtState = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + VkPipelineRenderingCreateInfo rtState = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO }; if (formatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { rtState.colorAttachmentCount = 1; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index c48b08eaa..88d75a811 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -583,7 +583,7 @@ namespace dxvk { } // Only the view mask is used as input, and since we do not use MultiView, it is always 0 - VkPipelineRenderingCreateInfo rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + VkPipelineRenderingCreateInfo rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO }; VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT, &rtInfo }; libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT; @@ -656,7 +656,7 @@ namespace dxvk { VkPipelineDepthStencilStateCreateInfo dsInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; // Only the view mask is used as input, and since we do not use MultiView, it is always 0 - VkPipelineRenderingCreateInfo rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR }; + VkPipelineRenderingCreateInfo rtInfo = { VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO }; VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT, &rtInfo }; libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index f9c5ccc92..2e6034617 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -295,6 +295,8 @@ namespace dxvk::vk { VULKAN_FN(vkCmdNextSubpass2); VULKAN_FN(vkCmdEndRenderPass); VULKAN_FN(vkCmdEndRenderPass2); + VULKAN_FN(vkCmdBeginRendering); + VULKAN_FN(vkCmdEndRendering); VULKAN_FN(vkCmdExecuteCommands); #ifdef VK_KHR_swapchain @@ -358,11 +360,6 @@ namespace dxvk::vk { VULKAN_FN(vkCmdCuLaunchKernelNVX); #endif - #ifdef VK_KHR_dynamic_rendering - VULKAN_FN(vkCmdBeginRenderingKHR); - VULKAN_FN(vkCmdEndRenderingKHR); - #endif - #ifdef VK_KHR_external_memory_win32 VULKAN_FN(vkGetMemoryWin32HandleKHR); VULKAN_FN(vkGetMemoryWin32HandlePropertiesKHR); From 7677db33718c362d1aa28a09fd3421ea6352cd9e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 20:56:56 +0200 Subject: [PATCH 0229/1348] [dxvk] Replace VK_EXT_extended_dynamic_state with core feature --- src/dxvk/dxvk_adapter.cpp | 19 +------------------ src/dxvk/dxvk_cmdlist.h | 34 ++++++++++++---------------------- src/dxvk/dxvk_context.cpp | 2 +- src/dxvk/dxvk_device_info.h | 1 - src/dxvk/dxvk_extensions.h | 1 - src/dxvk/dxvk_graphics.cpp | 8 ++++---- src/dxvk/dxvk_meta_blit.cpp | 4 ++-- src/dxvk/dxvk_meta_copy.cpp | 4 ++-- src/dxvk/dxvk_meta_resolve.cpp | 4 ++-- src/dxvk/dxvk_shader.cpp | 20 ++++++++++---------- src/vulkan/vulkan_loader.h | 30 +++++++++++++++--------------- 11 files changed, 49 insertions(+), 78 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 101db97f8..f9c2bf369 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -258,8 +258,6 @@ namespace dxvk { || !required.extCustomBorderColor.customBorderColorWithoutFormat) && (m_deviceFeatures.extDepthClipEnable.depthClipEnable || !required.extDepthClipEnable.depthClipEnable) - && (m_deviceFeatures.extExtendedDynamicState.extendedDynamicState - || !required.extExtendedDynamicState.extendedDynamicState) && (m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary || !required.extGraphicsPipelineLibrary.graphicsPipelineLibrary) && (m_deviceFeatures.extMemoryPriority.memoryPriority @@ -295,14 +293,13 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, &devExtensions.extConservativeRasterization, &devExtensions.extCustomBorderColor, &devExtensions.extDepthClipEnable, - &devExtensions.extExtendedDynamicState, &devExtensions.extFullScreenExclusive, &devExtensions.extGraphicsPipelineLibrary, &devExtensions.extMemoryBudget, @@ -360,8 +357,6 @@ namespace dxvk { enabledFeatures.vk13.dynamicRendering = VK_TRUE; enabledFeatures.vk13.maintenance4 = VK_TRUE; - enabledFeatures.extExtendedDynamicState.extendedDynamicState = VK_TRUE; - enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary; @@ -417,11 +412,6 @@ namespace dxvk { enabledFeatures.extDepthClipEnable.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extDepthClipEnable); } - if (devExtensions.extExtendedDynamicState) { - enabledFeatures.extExtendedDynamicState.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT; - enabledFeatures.extExtendedDynamicState.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extExtendedDynamicState); - } - if (devExtensions.extGraphicsPipelineLibrary) { enabledFeatures.extGraphicsPipelineLibrary.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT; enabledFeatures.extGraphicsPipelineLibrary.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extGraphicsPipelineLibrary); @@ -722,11 +712,6 @@ namespace dxvk { m_deviceFeatures.extDepthClipEnable.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extDepthClipEnable); } - if (m_deviceExtensions.supports(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME)) { - m_deviceFeatures.extExtendedDynamicState.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT; - m_deviceFeatures.extExtendedDynamicState.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extExtendedDynamicState); - } - if (m_deviceExtensions.supports(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME)) { m_deviceFeatures.extGraphicsPipelineLibrary.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT; m_deviceFeatures.extGraphicsPipelineLibrary.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extGraphicsPipelineLibrary); @@ -863,8 +848,6 @@ namespace dxvk { "\n customBorderColorWithoutFormat : ", features.extCustomBorderColor.customBorderColorWithoutFormat ? "1" : "0", "\n", VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, "\n depthClipEnable : ", features.extDepthClipEnable.depthClipEnable ? "1" : "0", - "\n", VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, - "\n extendedDynamicState : ", features.extExtendedDynamicState.extendedDynamicState ? "1" : "0", "\n", VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, "\n graphicsPipelineLibrary : ", features.extGraphicsPipelineLibrary.graphicsPipelineLibrary ? "1" : "0", "\n", VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 687f787eb..43267db11 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -327,20 +327,10 @@ namespace dxvk { uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, - const VkDeviceSize* pOffsets) { - m_vkd->vkCmdBindVertexBuffers(m_execBuffer, - firstBinding, bindingCount, pBuffers, pOffsets); - } - - - void cmdBindVertexBuffers2( - uint32_t firstBinding, - uint32_t bindingCount, - const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides) { - m_vkd->vkCmdBindVertexBuffers2EXT(m_execBuffer, + m_vkd->vkCmdBindVertexBuffers2(m_execBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes, pStrides); } @@ -701,7 +691,7 @@ namespace dxvk { void cmdSetDepthBoundsState( VkBool32 depthBoundsTestEnable) { - m_vkd->vkCmdSetDepthBoundsTestEnableEXT(m_execBuffer, depthBoundsTestEnable); + m_vkd->vkCmdSetDepthBoundsTestEnable(m_execBuffer, depthBoundsTestEnable); } @@ -709,11 +699,11 @@ namespace dxvk { VkBool32 depthTestEnable, VkBool32 depthWriteEnable, VkCompareOp depthCompareOp) { - m_vkd->vkCmdSetDepthTestEnableEXT(m_execBuffer, depthTestEnable); + m_vkd->vkCmdSetDepthTestEnable(m_execBuffer, depthTestEnable); if (depthTestEnable) { - m_vkd->vkCmdSetDepthWriteEnableEXT(m_execBuffer, depthWriteEnable); - m_vkd->vkCmdSetDepthCompareOpEXT(m_execBuffer, depthCompareOp); + m_vkd->vkCmdSetDepthWriteEnable(m_execBuffer, depthWriteEnable); + m_vkd->vkCmdSetDepthCompareOp(m_execBuffer, depthCompareOp); } } @@ -728,15 +718,15 @@ namespace dxvk { void cmdSetRasterizerState( VkCullModeFlags cullMode, VkFrontFace frontFace) { - m_vkd->vkCmdSetCullModeEXT(m_execBuffer, cullMode); - m_vkd->vkCmdSetFrontFaceEXT(m_execBuffer, frontFace); + m_vkd->vkCmdSetCullMode(m_execBuffer, cullMode); + m_vkd->vkCmdSetFrontFace(m_execBuffer, frontFace); } void cmdSetScissor( uint32_t scissorCount, const VkRect2D* scissors) { - m_vkd->vkCmdSetScissorWithCountEXT( + m_vkd->vkCmdSetScissorWithCount( m_execBuffer, scissorCount, scissors); } @@ -745,11 +735,11 @@ namespace dxvk { VkBool32 enableStencilTest, const VkStencilOpState& front, const VkStencilOpState& back) { - m_vkd->vkCmdSetStencilTestEnableEXT( + m_vkd->vkCmdSetStencilTestEnable( m_execBuffer, enableStencilTest); if (enableStencilTest) { - m_vkd->vkCmdSetStencilOpEXT(m_execBuffer, + m_vkd->vkCmdSetStencilOp(m_execBuffer, VK_STENCIL_FACE_FRONT_BIT, front.failOp, front.passOp, front.depthFailOp, front.compareOp); m_vkd->vkCmdSetStencilCompareMask(m_execBuffer, @@ -757,7 +747,7 @@ namespace dxvk { m_vkd->vkCmdSetStencilWriteMask(m_execBuffer, VK_STENCIL_FACE_FRONT_BIT, front.writeMask); - m_vkd->vkCmdSetStencilOpEXT(m_execBuffer, + m_vkd->vkCmdSetStencilOp(m_execBuffer, VK_STENCIL_FACE_BACK_BIT, back.failOp, back.passOp, back.depthFailOp, back.compareOp); m_vkd->vkCmdSetStencilCompareMask(m_execBuffer, @@ -779,7 +769,7 @@ namespace dxvk { void cmdSetViewport( uint32_t viewportCount, const VkViewport* viewports) { - m_vkd->vkCmdSetViewportWithCountEXT( + m_vkd->vkCmdSetViewportWithCount( m_execBuffer, viewportCount, viewports); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b364c78f7..3bbee0777 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5073,7 +5073,7 @@ namespace dxvk { // Vertex bindigs get remapped when compiling the // pipeline, so this actually does the right thing - m_cmd->cmdBindVertexBuffers2(0, m_state.gp.state.il.bindingCount(), + m_cmd->cmdBindVertexBuffers(0, m_state.gp.state.il.bindingCount(), buffers.data(), offsets.data(), lengths.data(), nullptr); } diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 95de74975..0555c5a80 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -41,7 +41,6 @@ namespace dxvk { VkPhysicalDevice4444FormatsFeaturesEXT ext4444Formats; VkPhysicalDeviceCustomBorderColorFeaturesEXT extCustomBorderColor; VkPhysicalDeviceDepthClipEnableFeaturesEXT extDepthClipEnable; - VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extExtendedDynamicState; VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT extGraphicsPipelineLibrary; VkPhysicalDeviceMemoryPriorityFeaturesEXT extMemoryPriority; VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT extNonSeamlessCubeMap; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 668807a2b..324bdad4b 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -282,7 +282,6 @@ namespace dxvk { DxvkExt extConservativeRasterization = { VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extCustomBorderColor = { VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extDepthClipEnable = { VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt extExtendedDynamicState = { VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt extFullScreenExclusive = { VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extGraphicsPipelineLibrary = { VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extMemoryBudget = { VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, DxvkExtMode::Passive }; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 96e8938f1..eef9e3caf 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -769,8 +769,8 @@ namespace dxvk { std::array dynamicStates; uint32_t dynamicStateCount = 0; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT; if (state.useDynamicDepthBias()) dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS; @@ -785,8 +785,8 @@ namespace dxvk { dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; if (!m_flags.test(DxvkGraphicsPipelineFlag::HasRasterizerDiscard)) { - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_CULL_MODE_EXT; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_FRONT_FACE_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_CULL_MODE; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_FRONT_FACE; } // Set up some specialization constants diff --git a/src/dxvk/dxvk_meta_blit.cpp b/src/dxvk/dxvk_meta_blit.cpp index aaf33a788..5b292752a 100644 --- a/src/dxvk/dxvk_meta_blit.cpp +++ b/src/dxvk/dxvk_meta_blit.cpp @@ -307,8 +307,8 @@ namespace dxvk { VK_SHADER_STAGE_FRAGMENT_BIT, psModule, "main" }; std::array dynStates = {{ - VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT, - VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, }}; VkPipelineDynamicStateCreateInfo dynState = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index 621ba0118..f853d923e 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -344,8 +344,8 @@ namespace dxvk { VK_SHADER_STAGE_FRAGMENT_BIT, psModule, "main" }; std::array dynStates = {{ - VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT, - VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, }}; VkPipelineDynamicStateCreateInfo dynState = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index c0a5e919d..9eb9ea108 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -257,8 +257,8 @@ namespace dxvk { VK_SHADER_STAGE_FRAGMENT_BIT, psModule, "main", &specInfo }; std::array dynStates = {{ - VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT, - VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, }}; VkPipelineDynamicStateCreateInfo dynState = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 88d75a811..ece845a43 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -548,11 +548,11 @@ namespace dxvk { // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. std::array dynamicStates = {{ - VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT, - VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, VK_DYNAMIC_STATE_DEPTH_BIAS, - VK_DYNAMIC_STATE_CULL_MODE_EXT, - VK_DYNAMIC_STATE_FRONT_FACE_EXT, + VK_DYNAMIC_STATE_CULL_MODE, + VK_DYNAMIC_STATE_FRONT_FACE, }}; VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; @@ -622,17 +622,17 @@ namespace dxvk { uint32_t dynamicStateCount = 0; std::array dynamicStates; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP; dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK; dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK; dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_OP_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_OP; if (m_device->features().core.features.depthBounds) { - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE; dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS; } diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 2e6034617..e0e221b3e 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -257,6 +257,21 @@ namespace dxvk::vk { VULKAN_FN(vkCmdSetStencilCompareMask); VULKAN_FN(vkCmdSetStencilWriteMask); VULKAN_FN(vkCmdSetStencilReference); + VULKAN_FN(vkCmdBindVertexBuffers2); + VULKAN_FN(vkCmdSetCullMode); + VULKAN_FN(vkCmdSetDepthBoundsTestEnable); + VULKAN_FN(vkCmdSetDepthCompareOp); + VULKAN_FN(vkCmdSetDepthTestEnable); + VULKAN_FN(vkCmdSetDepthWriteEnable); + VULKAN_FN(vkCmdSetFrontFace); + VULKAN_FN(vkCmdSetPrimitiveTopology); + VULKAN_FN(vkCmdSetScissorWithCount); + VULKAN_FN(vkCmdSetStencilOp); + VULKAN_FN(vkCmdSetStencilTestEnable); + VULKAN_FN(vkCmdSetViewportWithCount); + VULKAN_FN(vkCmdSetRasterizerDiscardEnable); + VULKAN_FN(vkCmdSetDepthBiasEnable); + VULKAN_FN(vkCmdSetPrimitiveRestartEnable); VULKAN_FN(vkCmdBindDescriptorSets); VULKAN_FN(vkCmdBindIndexBuffer); VULKAN_FN(vkCmdBindVertexBuffers); @@ -312,21 +327,6 @@ namespace dxvk::vk { VULKAN_FN(vkCmdEndConditionalRenderingEXT); #endif - #ifdef VK_EXT_extended_dynamic_state - VULKAN_FN(vkCmdBindVertexBuffers2EXT); - VULKAN_FN(vkCmdSetCullModeEXT); - VULKAN_FN(vkCmdSetDepthBoundsTestEnableEXT); - VULKAN_FN(vkCmdSetDepthCompareOpEXT); - VULKAN_FN(vkCmdSetDepthTestEnableEXT); - VULKAN_FN(vkCmdSetDepthWriteEnableEXT); - VULKAN_FN(vkCmdSetFrontFaceEXT); - VULKAN_FN(vkCmdSetPrimitiveTopologyEXT); - VULKAN_FN(vkCmdSetScissorWithCountEXT); - VULKAN_FN(vkCmdSetStencilOpEXT); - VULKAN_FN(vkCmdSetStencilTestEnableEXT); - VULKAN_FN(vkCmdSetViewportWithCountEXT); - #endif - #ifdef VK_EXT_full_screen_exclusive VULKAN_FN(vkAcquireFullScreenExclusiveModeEXT); VULKAN_FN(vkReleaseFullScreenExclusiveModeEXT); From 13425eb39b6e9e42a08a56d412237fb58d43f82e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 21:01:29 +0200 Subject: [PATCH 0230/1348] [dxvk] Replace VK_EXT_pipeline_creation_cache_control with core feature --- src/dxvk/dxvk_adapter.cpp | 20 +------------------- src/dxvk/dxvk_device.cpp | 2 +- src/dxvk/dxvk_device_info.h | 1 - src/dxvk/dxvk_extensions.h | 1 - src/dxvk/dxvk_graphics.cpp | 6 +++--- 5 files changed, 5 insertions(+), 25 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index f9c2bf369..e4c0d4ce9 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -264,8 +264,6 @@ namespace dxvk { || !required.extMemoryPriority.memoryPriority) && (m_deviceFeatures.extNonSeamlessCubeMap.nonSeamlessCubeMap || !required.extNonSeamlessCubeMap.nonSeamlessCubeMap) - && (m_deviceFeatures.extPipelineCreationCacheControl.pipelineCreationCacheControl - || !required.extPipelineCreationCacheControl.pipelineCreationCacheControl) && (m_deviceFeatures.extRobustness2.robustBufferAccess2 || !required.extRobustness2.robustBufferAccess2) && (m_deviceFeatures.extRobustness2.robustImageAccess2 @@ -293,7 +291,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -305,7 +303,6 @@ namespace dxvk { &devExtensions.extMemoryBudget, &devExtensions.extMemoryPriority, &devExtensions.extNonSeamlessCubeMap, - &devExtensions.extPipelineCreationCacheControl, &devExtensions.extRobustness2, &devExtensions.extShaderDemoteToHelperInvocation, &devExtensions.extShaderModuleIdentifier, @@ -360,9 +357,6 @@ namespace dxvk { enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary; - enabledFeatures.extPipelineCreationCacheControl.pipelineCreationCacheControl = - m_deviceFeatures.extPipelineCreationCacheControl.pipelineCreationCacheControl; - enabledFeatures.ext4444Formats.formatA4B4G4R4 = m_deviceFeatures.ext4444Formats.formatA4B4G4R4; enabledFeatures.ext4444Formats.formatA4R4G4B4 = m_deviceFeatures.ext4444Formats.formatA4R4G4B4; @@ -427,11 +421,6 @@ namespace dxvk { enabledFeatures.extNonSeamlessCubeMap.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extNonSeamlessCubeMap); } - if (devExtensions.extPipelineCreationCacheControl) { - enabledFeatures.extPipelineCreationCacheControl.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT; - enabledFeatures.extPipelineCreationCacheControl.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extPipelineCreationCacheControl); - } - if (devExtensions.extShaderDemoteToHelperInvocation) { enabledFeatures.extShaderDemoteToHelperInvocation.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT; enabledFeatures.extShaderDemoteToHelperInvocation.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extShaderDemoteToHelperInvocation); @@ -727,11 +716,6 @@ namespace dxvk { m_deviceFeatures.extNonSeamlessCubeMap.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extNonSeamlessCubeMap); } - if (m_deviceExtensions.supports(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME)) { - m_deviceFeatures.extPipelineCreationCacheControl.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT; - m_deviceFeatures.extPipelineCreationCacheControl.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extPipelineCreationCacheControl); - } - if (m_deviceExtensions.supports(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME)) { m_deviceFeatures.extRobustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; m_deviceFeatures.extRobustness2.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extRobustness2); @@ -854,8 +838,6 @@ namespace dxvk { "\n memoryPriority : ", features.extMemoryPriority.memoryPriority ? "1" : "0", "\n", VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, "\n nonSeamlessCubeMap : ", features.extNonSeamlessCubeMap.nonSeamlessCubeMap ? "1" : "0", - "\n", VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME, - "\n pipelineCreationCacheControl : ", features.extPipelineCreationCacheControl.pipelineCreationCacheControl ? "1" : "0", "\n", VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, "\n robustBufferAccess2 : ", features.extRobustness2.robustBufferAccess2 ? "1" : "0", "\n robustImageAccess2 : ", features.extRobustness2.robustImageAccess2 ? "1" : "0", diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 2bae86395..5255be402 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -62,7 +62,7 @@ namespace dxvk { // Don't bother with this unless the device also supports shader module // identifiers, since decoding and hashing the shaders is slow otherwise // and likely provides no benefit over linking pipeline libraries. - return m_features.extPipelineCreationCacheControl.pipelineCreationCacheControl + return m_features.vk13.pipelineCreationCacheControl && m_features.extShaderModuleIdentifier.shaderModuleIdentifier && m_options.enableGraphicsPipelineLibrary != Tristate::True; } diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 0555c5a80..4d87c615c 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -44,7 +44,6 @@ namespace dxvk { VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT extGraphicsPipelineLibrary; VkPhysicalDeviceMemoryPriorityFeaturesEXT extMemoryPriority; VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT extNonSeamlessCubeMap; - VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT extPipelineCreationCacheControl; VkPhysicalDeviceRobustness2FeaturesEXT extRobustness2; VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT extShaderDemoteToHelperInvocation; VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT extShaderModuleIdentifier; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 324bdad4b..ffd220bbd 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -287,7 +287,6 @@ namespace dxvk { DxvkExt extMemoryBudget = { VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, DxvkExtMode::Passive }; DxvkExt extMemoryPriority = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extNonSeamlessCubeMap = { VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt extPipelineCreationCacheControl = { VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extRobustness2 = { VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt extShaderDemoteToHelperInvocation = { VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderModuleIdentifier = { VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index eef9e3caf..d8b568ac7 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -622,7 +622,7 @@ namespace dxvk { // first, since this is expected to be the fastest path. if (m_device->canUsePipelineCacheControl()) { fastHandle = this->createOptimizedPipeline(state, - VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT); + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT); } if (!fastHandle) { @@ -808,7 +808,7 @@ namespace dxvk { // Build stage infos for all provided shaders DxvkShaderStageInfo stageInfo(m_device); - if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT) { + if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) { stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, m_vsLibrary->getModuleIdentifier(), &specInfo); if (m_shaders.fs != nullptr) @@ -860,7 +860,7 @@ namespace dxvk { if (vr != VK_SUCCESS) { // Ignore any error if we're trying to create a cached pipeline. If linking or // compiling an optimized pipeline fail later, we'll still be printing errors. - if (!(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT)) + if (!(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT)) Logger::err(str::format("DxvkGraphicsPipeline: Failed to compile pipeline: ", vr)); return VK_NULL_HANDLE; From f60bdcbcbf684f7b9e986a37291c5389e932e702 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 21:04:32 +0200 Subject: [PATCH 0231/1348] [dxvk] Replace VK_EXT_shader_demote_to_helper_invocation with core feature --- src/d3d11/d3d11_device.cpp | 4 ++-- src/d3d9/d3d9_device.cpp | 4 ++-- src/dxbc/dxbc_options.cpp | 2 +- src/dxso/dxso_options.cpp | 2 +- src/dxvk/dxvk_adapter.cpp | 15 +-------------- src/dxvk/dxvk_device_info.h | 1 - src/dxvk/dxvk_extensions.h | 1 - 7 files changed, 7 insertions(+), 22 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 1545438b8..f5ffc3490 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1931,9 +1931,9 @@ namespace dxvk { enabled.vk12.samplerMirrorClampToEdge = VK_TRUE; - enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; + enabled.vk13.shaderDemoteToHelperInvocation = supported.vk13.shaderDemoteToHelperInvocation; - enabled.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation = supported.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation; + enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; enabled.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor = supported.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor; enabled.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor = supported.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index a09ee6347..0fb2fe5a1 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3903,9 +3903,9 @@ namespace dxvk { enabled.vk12.samplerMirrorClampToEdge = VK_TRUE; - enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; + enabled.vk13.shaderDemoteToHelperInvocation = supported.vk13.shaderDemoteToHelperInvocation; - enabled.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation = supported.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation; + enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; enabled.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor = supported.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor; enabled.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor = supported.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor; diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 6d064e1f2..f4f8b1726 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -23,7 +23,7 @@ namespace dxvk { = (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_COMPUTE_BIT) && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); useDemoteToHelperInvocation - = (devFeatures.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation); + = (devFeatures.vk13.shaderDemoteToHelperInvocation); useSubgroupOpsForEarlyDiscard = (devInfo.vk11.subgroupSize >= 4) && (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) diff --git a/src/dxso/dxso_options.cpp b/src/dxso/dxso_options.cpp index 71e47613e..a4382c7b4 100644 --- a/src/dxso/dxso_options.cpp +++ b/src/dxso/dxso_options.cpp @@ -15,7 +15,7 @@ namespace dxvk { const DxvkDeviceInfo& devInfo = adapter->devicePropertiesExt(); useDemoteToHelperInvocation - = (devFeatures.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation); + = (devFeatures.vk13.shaderDemoteToHelperInvocation); useSubgroupOpsForEarlyDiscard = (devInfo.vk11.subgroupSize >= 4) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index e4c0d4ce9..9abfc6cb8 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -291,7 +291,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.ext4444Formats, @@ -304,7 +304,6 @@ namespace dxvk { &devExtensions.extMemoryPriority, &devExtensions.extNonSeamlessCubeMap, &devExtensions.extRobustness2, - &devExtensions.extShaderDemoteToHelperInvocation, &devExtensions.extShaderModuleIdentifier, &devExtensions.extShaderStencilExport, &devExtensions.extTransformFeedback, @@ -421,11 +420,6 @@ namespace dxvk { enabledFeatures.extNonSeamlessCubeMap.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extNonSeamlessCubeMap); } - if (devExtensions.extShaderDemoteToHelperInvocation) { - enabledFeatures.extShaderDemoteToHelperInvocation.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT; - enabledFeatures.extShaderDemoteToHelperInvocation.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extShaderDemoteToHelperInvocation); - } - if (devExtensions.extShaderModuleIdentifier) { enabledFeatures.extShaderModuleIdentifier.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT; enabledFeatures.extShaderModuleIdentifier.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extShaderModuleIdentifier); @@ -721,11 +715,6 @@ namespace dxvk { m_deviceFeatures.extRobustness2.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extRobustness2); } - if (m_deviceExtensions.supports(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME)) { - m_deviceFeatures.extShaderDemoteToHelperInvocation.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT; - m_deviceFeatures.extShaderDemoteToHelperInvocation.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extShaderDemoteToHelperInvocation); - } - if (m_deviceExtensions.supports(VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME)) { m_deviceFeatures.extShaderModuleIdentifier.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT; m_deviceFeatures.extShaderModuleIdentifier.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extShaderModuleIdentifier); @@ -842,8 +831,6 @@ namespace dxvk { "\n robustBufferAccess2 : ", features.extRobustness2.robustBufferAccess2 ? "1" : "0", "\n robustImageAccess2 : ", features.extRobustness2.robustImageAccess2 ? "1" : "0", "\n nullDescriptor : ", features.extRobustness2.nullDescriptor ? "1" : "0", - "\n", VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, - "\n shaderDemoteToHelperInvocation : ", features.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation ? "1" : "0", "\n", VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME, "\n shaderModuleIdentifier : ", features.extShaderModuleIdentifier.shaderModuleIdentifier ? "1" : "0", "\n", VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 4d87c615c..fe20e98df 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -45,7 +45,6 @@ namespace dxvk { VkPhysicalDeviceMemoryPriorityFeaturesEXT extMemoryPriority; VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT extNonSeamlessCubeMap; VkPhysicalDeviceRobustness2FeaturesEXT extRobustness2; - VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT extShaderDemoteToHelperInvocation; VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT extShaderModuleIdentifier; VkPhysicalDeviceTransformFeedbackFeaturesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT extVertexAttributeDivisor; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index ffd220bbd..0f66a52e4 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -288,7 +288,6 @@ namespace dxvk { DxvkExt extMemoryPriority = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extNonSeamlessCubeMap = { VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extRobustness2 = { VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, DxvkExtMode::Required }; - DxvkExt extShaderDemoteToHelperInvocation = { VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderModuleIdentifier = { VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; From d6d7d5137b30c9dc0a65f2bc2b90b32171f5964c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 21:13:06 +0200 Subject: [PATCH 0232/1348] [dxvk] Drop VK_EXT_4444_formats These formats are core in Vulkan 1.3 and all relevant drivers support them. --- src/d3d9/d3d9_format.cpp | 21 ++------------------- src/d3d9/d3d9_format.h | 1 - src/dxgi/dxgi_format.cpp | 8 +------- src/dxvk/dxvk_adapter.cpp | 23 +---------------------- src/dxvk/dxvk_device_info.h | 1 - src/dxvk/dxvk_extensions.h | 1 - src/dxvk/dxvk_format.cpp | 6 +++--- src/dxvk/dxvk_graphics_state.h | 6 +++--- 8 files changed, 10 insertions(+), 57 deletions(-) diff --git a/src/d3d9/d3d9_format.cpp b/src/d3d9/d3d9_format.cpp index 5654337d7..28da31584 100644 --- a/src/d3d9/d3d9_format.cpp +++ b/src/d3d9/d3d9_format.cpp @@ -39,7 +39,7 @@ namespace dxvk { VK_IMAGE_ASPECT_COLOR_BIT }; case D3D9Format::A4R4G4B4: return { - VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT, + VK_FORMAT_A4R4G4B4_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_IMAGE_ASPECT_COLOR_BIT }; @@ -55,7 +55,7 @@ namespace dxvk { case D3D9Format::A8R3G3B2: return {}; // Unsupported case D3D9Format::X4R4G4B4: return { - VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT, + VK_FORMAT_A4R4G4B4_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_IMAGE_ASPECT_COLOR_BIT }; @@ -445,9 +445,6 @@ namespace dxvk { VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); // VK_EXT_4444_formats - m_a4r4g4b4Support = CheckImageFormatSupport(adapter, VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); - if (!m_d24s8Support) Logger::info("D3D9: VK_FORMAT_D24_UNORM_S8_UINT -> VK_FORMAT_D32_SFLOAT_S8_UINT"); @@ -457,9 +454,6 @@ namespace dxvk { else Logger::info("D3D9: VK_FORMAT_D16_UNORM_S8_UINT -> VK_FORMAT_D32_SFLOAT_S8_UINT"); } - - if (!m_a4r4g4b4Support) - Logger::warn("D3D9: VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT -> VK_FORMAT_B4G4R4A4_UNORM_PACK16"); } D3D9_VK_FORMAT_MAPPING D3D9VkFormatTable::GetFormatMapping( @@ -484,17 +478,6 @@ namespace dxvk { if (!m_d16s8Support && mapping.FormatColor == VK_FORMAT_D16_UNORM_S8_UINT) mapping.FormatColor = m_d24s8Support ? VK_FORMAT_D24_UNORM_S8_UINT : VK_FORMAT_D32_SFLOAT_S8_UINT; - if (!m_a4r4g4b4Support && mapping.FormatColor == VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT) { - VkComponentSwizzle alphaSwizzle = Format == D3D9Format::A4R4G4B4 - ? VK_COMPONENT_SWIZZLE_B - : VK_COMPONENT_SWIZZLE_ONE; - - mapping.FormatColor = VK_FORMAT_B4G4R4A4_UNORM_PACK16; - mapping.Swizzle = { - VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, - VK_COMPONENT_SWIZZLE_A, alphaSwizzle }; - } - return mapping; } diff --git a/src/d3d9/d3d9_format.h b/src/d3d9/d3d9_format.h index 0c9ab1688..1b9f72a78 100644 --- a/src/d3d9/d3d9_format.h +++ b/src/d3d9/d3d9_format.h @@ -211,7 +211,6 @@ namespace dxvk { VkFormat Format, VkFormatFeatureFlags Features) const; - bool m_a4r4g4b4Support; bool m_d24s8Support; bool m_d16s8Support; diff --git a/src/dxgi/dxgi_format.cpp b/src/dxgi/dxgi_format.cpp index a8551da6f..7c8278909 100644 --- a/src/dxgi/dxgi_format.cpp +++ b/src/dxgi/dxgi_format.cpp @@ -529,7 +529,7 @@ namespace dxvk { // DXGI_FORMAT_A8P8 { }, // Unsupported // DXGI_FORMAT_B4G4R4A4_UNORM - { VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT, + { VK_FORMAT_A4R4G4B4_UNORM_PACK16, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, VK_IMAGE_ASPECT_COLOR_BIT }, @@ -860,12 +860,6 @@ namespace dxvk { RemapDepthFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT); RemapDepthFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT); } - - if (!adapter->features().ext4444Formats.formatA4R4G4B4) { - RemapColorFormat(DXGI_FORMAT_B4G4R4A4_UNORM, VK_FORMAT_B4G4R4A4_UNORM_PACK16, - { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, - VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_B }); - } } diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 9abfc6cb8..f35790596 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -248,10 +248,6 @@ namespace dxvk { || !required.vk13.dynamicRendering) && (m_deviceFeatures.vk13.maintenance4 || !required.vk13.maintenance4) - && (m_deviceFeatures.ext4444Formats.formatA4R4G4B4 - || !required.ext4444Formats.formatA4R4G4B4) - && (m_deviceFeatures.ext4444Formats.formatA4B4G4R4 - || !required.ext4444Formats.formatA4B4G4R4) && (m_deviceFeatures.extCustomBorderColor.customBorderColors || !required.extCustomBorderColor.customBorderColors) && (m_deviceFeatures.extCustomBorderColor.customBorderColorWithoutFormat @@ -291,10 +287,9 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, - &devExtensions.ext4444Formats, &devExtensions.extConservativeRasterization, &devExtensions.extCustomBorderColor, &devExtensions.extDepthClipEnable, @@ -356,9 +351,6 @@ namespace dxvk { enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary; - enabledFeatures.ext4444Formats.formatA4B4G4R4 = m_deviceFeatures.ext4444Formats.formatA4B4G4R4; - enabledFeatures.ext4444Formats.formatA4R4G4B4 = m_deviceFeatures.ext4444Formats.formatA4R4G4B4; - enabledFeatures.extRobustness2.robustBufferAccess2 = VK_TRUE; enabledFeatures.extRobustness2.robustImageAccess2 = m_deviceFeatures.extRobustness2.robustImageAccess2; enabledFeatures.extRobustness2.nullDescriptor = VK_TRUE; @@ -390,11 +382,6 @@ namespace dxvk { enabledFeatures.vk13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; enabledFeatures.vk13.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.vk13); - if (devExtensions.ext4444Formats) { - enabledFeatures.ext4444Formats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; - enabledFeatures.ext4444Formats.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.ext4444Formats); - } - if (devExtensions.extCustomBorderColor) { enabledFeatures.extCustomBorderColor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT; enabledFeatures.extCustomBorderColor.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extCustomBorderColor); @@ -680,11 +667,6 @@ namespace dxvk { m_deviceFeatures.vk13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; m_deviceFeatures.vk13.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.vk13); - if (m_deviceExtensions.supports(VK_EXT_4444_FORMATS_EXTENSION_NAME)) { - m_deviceFeatures.ext4444Formats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; - m_deviceFeatures.ext4444Formats.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.ext4444Formats); - } - if (m_deviceExtensions.supports(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME)) { m_deviceFeatures.extCustomBorderColor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT; m_deviceFeatures.extCustomBorderColor.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extCustomBorderColor); @@ -813,9 +795,6 @@ namespace dxvk { "\n synchronization2 : ", features.vk13.synchronization2, "\n dynamicRendering : ", features.vk13.dynamicRendering, "\n maintenance4 : ", features.vk13.maintenance4, - "\n", VK_EXT_4444_FORMATS_EXTENSION_NAME, - "\n formatA4R4G4B4 : ", features.ext4444Formats.formatA4R4G4B4 ? "1" : "0", - "\n formatA4B4G4R4 : ", features.ext4444Formats.formatA4B4G4R4 ? "1" : "0", "\n", VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, "\n customBorderColors : ", features.extCustomBorderColor.customBorderColors ? "1" : "0", "\n customBorderColorWithoutFormat : ", features.extCustomBorderColor.customBorderColorWithoutFormat ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index fe20e98df..545c88cdc 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -38,7 +38,6 @@ namespace dxvk { VkPhysicalDeviceVulkan11Features vk11; VkPhysicalDeviceVulkan12Features vk12; VkPhysicalDeviceVulkan13Features vk13; - VkPhysicalDevice4444FormatsFeaturesEXT ext4444Formats; VkPhysicalDeviceCustomBorderColorFeaturesEXT extCustomBorderColor; VkPhysicalDeviceDepthClipEnableFeaturesEXT extDepthClipEnable; VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT extGraphicsPipelineLibrary; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 0f66a52e4..cbf4ba09d 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -278,7 +278,6 @@ namespace dxvk { struct DxvkDeviceExtensions { DxvkExt amdMemoryOverallocationBehaviour = { VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt amdShaderFragmentMask = { VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME, DxvkExtMode::Optional }; - DxvkExt ext4444Formats = { VK_EXT_4444_FORMATS_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extConservativeRasterization = { VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extCustomBorderColor = { VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extDepthClipEnable = { VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/dxvk/dxvk_format.cpp b/src/dxvk/dxvk_format.cpp index 1b76510ac..4ec42e6ea 100644 --- a/src/dxvk/dxvk_format.cpp +++ b/src/dxvk/dxvk_format.cpp @@ -550,10 +550,10 @@ namespace dxvk { DxvkFormatFlag::BlockCompressed, VkExtent3D { 2, 1, 1 } }, - // VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT + // VK_FORMAT_A4R4G4B4_UNORM_PACK16 { 2, RGBA, VK_IMAGE_ASPECT_COLOR_BIT }, - // VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT + // VK_FORMAT_A4B4G4R4_UNORM_PACK16 { 2, RGBA, VK_IMAGE_ASPECT_COLOR_BIT }, // VK_FORMAT_G8_B8R8_2PLANE_420_UNORM @@ -567,7 +567,7 @@ namespace dxvk { const std::array, 4> g_formatGroups = {{ { VK_FORMAT_UNDEFINED, VK_FORMAT_BC7_SRGB_BLOCK }, { VK_FORMAT_G8B8G8R8_422_UNORM_KHR, VK_FORMAT_B8G8R8G8_422_UNORM_KHR }, - { VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT, VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT }, + { VK_FORMAT_A4R4G4B4_UNORM_PACK16, VK_FORMAT_A4B4G4R4_UNORM_PACK16 }, { VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM }, }}; diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 9a733999e..25fd921a2 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -507,8 +507,8 @@ namespace dxvk { static uint64_t encodeColorFormat(VkFormat format, uint32_t index) { uint64_t value = uint64_t(format); - if (value >= uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT)) { - value -= uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT); + if (value >= uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16)) { + value -= uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16); value += uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) + 1; } else if (value > uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)) { value = 0; @@ -534,7 +534,7 @@ namespace dxvk { if (value > uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)) { value -= uint64_t(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) + 1ull; - value += uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT); + value += uint64_t(VK_FORMAT_A4R4G4B4_UNORM_PACK16); } return VkFormat(value); From 0b59af996a56adcd6d13da9da63ea89bfec686c6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 21:19:22 +0200 Subject: [PATCH 0233/1348] [dxvk] Use dynamic depth bias enable for base pipelines This is always supported in Vulkan 1.3. --- src/dxvk/dxvk_cmdlist.h | 6 ++++++ src/dxvk/dxvk_context.cpp | 4 ++-- src/dxvk/dxvk_shader.cpp | 10 ++++------ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 43267db11..a0b3be0ed 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -669,6 +669,12 @@ namespace dxvk { } + void cmdSetDepthBiasState( + VkBool32 depthBiasEnable) { + m_vkd->vkCmdSetDepthBiasEnable(m_execBuffer, depthBiasEnable); + } + + void cmdSetDepthBias( float depthBiasConstantFactor, float depthBiasClamp, diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 3bbee0777..9650f0de1 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4547,8 +4547,8 @@ namespace dxvk { m_state.gp.state.ds.enableDepthBoundsTest()); } - if (!m_flags.test(DxvkContextFlag::GpDynamicDepthBias)) - m_cmd->cmdSetDepthBias(0.0f, 0.0f, 0.0f); + m_cmd->cmdSetDepthBiasState( + m_state.gp.state.rs.depthBiasEnable()); if (!m_flags.test(DxvkContextFlag::GpDynamicRasterizerState)) m_cmd->cmdSetRasterizerState(VK_CULL_MODE_FRONT_AND_BACK, VK_FRONT_FACE_CLOCKWISE); diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index ece845a43..b65931892 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -547,10 +547,11 @@ namespace dxvk { // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. - std::array dynamicStates = {{ + std::array dynamicStates = {{ VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, VK_DYNAMIC_STATE_DEPTH_BIAS, + VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE, VK_DYNAMIC_STATE_CULL_MODE, VK_DYNAMIC_STATE_FRONT_FACE, }}; @@ -562,17 +563,14 @@ namespace dxvk { // All viewport state is dynamic, so we do not need to initialize this. VkPipelineViewportStateCreateInfo vpInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; - // Set up rasterizer state. Depth bias, cull mode and front face are all - // dynamic, but we do not have dynamic state for depth bias enablement - // with the original version of VK_EXT_extended_dynamic_state, so always - // enable that. Do not support any polygon modes other than FILL. + // Set up rasterizer state. Depth bias, cull mode and front face are + // all dynamic. Do not support any polygon modes other than FILL. VkPipelineRasterizationDepthClipStateCreateInfoEXT rsDepthClipInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT }; VkPipelineRasterizationStateCreateInfo rsInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rsInfo.depthClampEnable = VK_TRUE; rsInfo.rasterizerDiscardEnable = VK_FALSE; rsInfo.polygonMode = VK_POLYGON_MODE_FILL; - rsInfo.depthBiasEnable = VK_TRUE; rsInfo.lineWidth = 1.0f; if (m_device->features().extDepthClipEnable.depthClipEnable) { From 70a71237cfc06bc9c82247bdf2bf886c247a2870 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 21:45:22 +0200 Subject: [PATCH 0234/1348] [dxvk] Always initialize dynamic depth/stencil state Spec says we must set any dynamic state before making a draw call, there doesn't seem to be an exception if we don't enable depth or stencil tests. --- src/dxvk/dxvk_cmdlist.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index a0b3be0ed..36374b147 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -710,6 +710,9 @@ namespace dxvk { if (depthTestEnable) { m_vkd->vkCmdSetDepthWriteEnable(m_execBuffer, depthWriteEnable); m_vkd->vkCmdSetDepthCompareOp(m_execBuffer, depthCompareOp); + } else { + m_vkd->vkCmdSetDepthWriteEnable(m_execBuffer, VK_FALSE); + m_vkd->vkCmdSetDepthCompareOp(m_execBuffer, VK_COMPARE_OP_ALWAYS); } } @@ -760,6 +763,15 @@ namespace dxvk { VK_STENCIL_FACE_BACK_BIT, back.compareMask); m_vkd->vkCmdSetStencilWriteMask(m_execBuffer, VK_STENCIL_FACE_BACK_BIT, back.writeMask); + } else { + m_vkd->vkCmdSetStencilOp(m_execBuffer, + VK_STENCIL_FACE_FRONT_AND_BACK, + VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, + VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS); + m_vkd->vkCmdSetStencilCompareMask(m_execBuffer, + VK_STENCIL_FACE_FRONT_AND_BACK, 0x0); + m_vkd->vkCmdSetStencilWriteMask(m_execBuffer, + VK_STENCIL_FACE_FRONT_AND_BACK, 0x0); } } From b00d7f35f5f6d7f107d23bf69f3e04bea4241098 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 21:47:32 +0200 Subject: [PATCH 0235/1348] [dxvk] Mark more pipeline state as dynamic for base pipelines Otherwise we might never set depth bias and friends. --- src/dxvk/dxvk_context.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 9650f0de1..d87d129a3 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4545,6 +4545,8 @@ namespace dxvk { if (m_device->features().core.features.depthBounds) { m_cmd->cmdSetDepthBoundsState( m_state.gp.state.ds.enableDepthBoundsTest()); + + m_flags.set(DxvkContextFlag::GpDynamicDepthBounds); } m_cmd->cmdSetDepthBiasState( @@ -4553,7 +4555,10 @@ namespace dxvk { if (!m_flags.test(DxvkContextFlag::GpDynamicRasterizerState)) m_cmd->cmdSetRasterizerState(VK_CULL_MODE_FRONT_AND_BACK, VK_FRONT_FACE_CLOCKWISE); - m_flags.set(DxvkContextFlag::GpIndependentSets); + m_flags.set( + DxvkContextFlag::GpDynamicDepthBias, + DxvkContextFlag::GpDynamicStencilRef, + DxvkContextFlag::GpIndependentSets); } // If necessary, dirty descriptor sets due to layout incompatibilities From 0f6ba59f16f76898d919ed5e4f9e8cda1cb0e9cd Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 14 Jul 2022 22:10:44 +0200 Subject: [PATCH 0236/1348] [dxvk] Normalize dynamic depth-stencil state based on bound attachment We already do the same for monolothic pipelines. SpellForce 3 tries to write depth with a read-only layout, which is a bad idea. --- src/dxvk/dxvk_context.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index d87d129a3..7c8c519aa 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4532,16 +4532,14 @@ namespace dxvk { // For pipelines created from graphics pipeline libraries, we need // to apply a bunch of dynamic state that is otherwise static if (pipelineInfo.second == DxvkGraphicsPipelineType::BasePipeline) { + VkImageAspectFlags dsReadOnlyAspects = m_state.gp.state.rt.getDepthStencilReadOnlyAspects(); + m_cmd->cmdSetDepthState( m_state.gp.state.ds.enableDepthTest(), - m_state.gp.state.ds.enableDepthWrite(), + m_state.gp.state.ds.enableDepthWrite() && + !(dsReadOnlyAspects & VK_IMAGE_ASPECT_DEPTH_BIT), m_state.gp.state.ds.depthCompareOp()); - m_cmd->cmdSetStencilState( - m_state.gp.state.ds.enableStencilTest(), - m_state.gp.state.dsFront.state(), - m_state.gp.state.dsBack.state()); - if (m_device->features().core.features.depthBounds) { m_cmd->cmdSetDepthBoundsState( m_state.gp.state.ds.enableDepthBoundsTest()); @@ -4549,12 +4547,21 @@ namespace dxvk { m_flags.set(DxvkContextFlag::GpDynamicDepthBounds); } + VkStencilOpState dsFront = m_state.gp.state.dsFront.state(); + VkStencilOpState dsBack = m_state.gp.state.dsBack.state(); + + if (dsReadOnlyAspects & VK_IMAGE_ASPECT_STENCIL_BIT) { + dsFront.writeMask = 0; + dsBack.writeMask = 0; + } + + m_cmd->cmdSetStencilState( + m_state.gp.state.ds.enableStencilTest(), + dsFront, dsBack); + m_cmd->cmdSetDepthBiasState( m_state.gp.state.rs.depthBiasEnable()); - if (!m_flags.test(DxvkContextFlag::GpDynamicRasterizerState)) - m_cmd->cmdSetRasterizerState(VK_CULL_MODE_FRONT_AND_BACK, VK_FRONT_FACE_CLOCKWISE); - m_flags.set( DxvkContextFlag::GpDynamicDepthBias, DxvkContextFlag::GpDynamicStencilRef, From b59571ab22e691803cc4503b159aa09f8e1b90da Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 15:58:18 +0200 Subject: [PATCH 0237/1348] [dxvk] Explicitly initialize null descriptor structs There's a weird rule that requires null buffer descriptors to specify VK_WHOLE_SIZE. Silences a bunch of validation errors in God of War. --- src/dxvk/dxvk_context.cpp | 40 +++++++++++++++++++++++++-------------- src/dxvk/dxvk_unbound.h | 8 ++------ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 7c8c519aa..03838d391 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4646,14 +4646,16 @@ namespace dxvk { const auto& res = m_rc[binding.resourceBinding]; if (res.sampler != nullptr) { - m_descriptors[k].image.sampler = res.sampler->handle(); - m_descriptors[k].image.imageView = VK_NULL_HANDLE; + m_descriptors[k].image.sampler = res.sampler->handle(); + m_descriptors[k].image.imageView = VK_NULL_HANDLE; m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.sampler); } else { - m_descriptors[k].image = m_common->dummyResources().samplerDescriptor(); + m_descriptors[k].image.sampler = m_common->dummyResources().samplerHandle(); + m_descriptors[k].image.imageView = VK_NULL_HANDLE; + m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; } } break; @@ -4661,8 +4663,8 @@ namespace dxvk { const auto& res = m_rc[binding.resourceBinding]; if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - m_descriptors[k].image.sampler = VK_NULL_HANDLE; - m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); + m_descriptors[k].image.sampler = VK_NULL_HANDLE; + m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout; if (m_rcTracked.set(binding.resourceBinding)) { @@ -4670,7 +4672,9 @@ namespace dxvk { m_cmd->trackResource(res.imageView->image()); } } else { - m_descriptors[k].image = VkDescriptorImageInfo(); + m_descriptors[k].image.sampler = VK_NULL_HANDLE; + m_descriptors[k].image.imageView = VK_NULL_HANDLE; + m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; } } break; @@ -4678,8 +4682,8 @@ namespace dxvk { const auto& res = m_rc[binding.resourceBinding]; if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - m_descriptors[k].image.sampler = VK_NULL_HANDLE; - m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); + m_descriptors[k].image.sampler = VK_NULL_HANDLE; + m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout; if (m_rcTracked.set(binding.resourceBinding)) { @@ -4687,7 +4691,9 @@ namespace dxvk { m_cmd->trackResource(res.imageView->image()); } } else { - m_descriptors[k].image = VkDescriptorImageInfo(); + m_descriptors[k].image.sampler = VK_NULL_HANDLE; + m_descriptors[k].image.imageView = VK_NULL_HANDLE; + m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; } } break; @@ -4696,8 +4702,8 @@ namespace dxvk { if (res.sampler != nullptr && res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - m_descriptors[k].image.sampler = res.sampler->handle(); - m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); + m_descriptors[k].image.sampler = res.sampler->handle(); + m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout; if (m_rcTracked.set(binding.resourceBinding)) { @@ -4706,7 +4712,9 @@ namespace dxvk { m_cmd->trackResource(res.imageView->image()); } } else { - m_descriptors[k].image = m_common->dummyResources().samplerDescriptor(); + m_descriptors[k].image.sampler = m_common->dummyResources().samplerHandle(); + m_descriptors[k].image.imageView = VK_NULL_HANDLE; + m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; } } break; @@ -4751,7 +4759,9 @@ namespace dxvk { if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.bufferSlice.buffer()); } else { - m_descriptors[k].buffer = VkDescriptorBufferInfo(); + m_descriptors[k].buffer.buffer = VK_NULL_HANDLE; + m_descriptors[k].buffer.offset = 0; + m_descriptors[k].buffer.range = VK_WHOLE_SIZE; } } break; @@ -4764,7 +4774,9 @@ namespace dxvk { if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.bufferSlice.buffer()); } else { - m_descriptors[k].buffer = VkDescriptorBufferInfo(); + m_descriptors[k].buffer.buffer = VK_NULL_HANDLE; + m_descriptors[k].buffer.offset = 0; + m_descriptors[k].buffer.range = VK_WHOLE_SIZE; } } break; diff --git a/src/dxvk/dxvk_unbound.h b/src/dxvk/dxvk_unbound.h index cd057b6e0..8668f38b6 100644 --- a/src/dxvk/dxvk_unbound.h +++ b/src/dxvk/dxvk_unbound.h @@ -42,12 +42,8 @@ namespace dxvk { * still require different behaviour. * \returns Dummy sampler descriptor */ - VkDescriptorImageInfo samplerDescriptor() const { - VkDescriptorImageInfo result; - result.sampler = m_sampler->handle(); - result.imageView = VK_NULL_HANDLE; - result.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; - return result; + VkSampler samplerHandle() const { + return m_sampler->handle(); } private: From 686df3ec1bba1a4721aab3e5636f3a9bf1843ae2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 14:07:18 +0200 Subject: [PATCH 0238/1348] [dxvk] Don't set scissor and viewport count for meta pipelines Oversight from when we changed these to be unconditionally dynamic. Fixes a bunch of validation errors. --- src/dxvk/dxvk_meta_blit.cpp | 2 -- src/dxvk/dxvk_meta_copy.cpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/dxvk/dxvk_meta_blit.cpp b/src/dxvk/dxvk_meta_blit.cpp index 5b292752a..e36debc7f 100644 --- a/src/dxvk/dxvk_meta_blit.cpp +++ b/src/dxvk/dxvk_meta_blit.cpp @@ -322,8 +322,6 @@ namespace dxvk { iaState.primitiveRestartEnable = VK_FALSE; VkPipelineViewportStateCreateInfo vpState = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; - vpState.viewportCount = 1; - vpState.scissorCount = 1; VkPipelineRasterizationStateCreateInfo rsState = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rsState.polygonMode = VK_POLYGON_MODE_FILL; diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index f853d923e..b724e6331 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -358,8 +358,6 @@ namespace dxvk { iaState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; VkPipelineViewportStateCreateInfo vpState = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; - vpState.viewportCount = 1; - vpState.scissorCount = 1; VkPipelineRasterizationStateCreateInfo rsState = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rsState.depthClampEnable = VK_TRUE; From 5ecd11fbd09f1d8cc6fdfdbd38572be399bc4af1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 14:48:13 +0200 Subject: [PATCH 0239/1348] [meta] Update SPIR-V headers --- include/spirv/spirv.hpp | 640 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 634 insertions(+), 6 deletions(-) diff --git a/include/spirv/spirv.hpp b/include/spirv/spirv.hpp index 50cc20da3..5947d6f7e 100644 --- a/include/spirv/spirv.hpp +++ b/include/spirv/spirv.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2019 The Khronos Group Inc. +// Copyright (c) 2014-2020 The Khronos Group Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and/or associated documentation files (the "Materials"), @@ -26,7 +26,7 @@ // the Binary Section of the SPIR-V specification. // Enumeration tokens for SPIR-V, in various styles: -// C, C++, C++11, JSON, Lua, Python, C#, D +// C, C++, C++11, JSON, Lua, Python, C#, D, Beef // // - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL // - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL @@ -36,6 +36,8 @@ // - C# will use enum classes in the Specification class located in the "Spv" namespace, // e.g.: Spv.Specification.SourceLanguage.GLSL // - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +// - Beef will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL // // Some tokens act like mask values, which can be OR'd together, // while others are mutually exclusive. The mask-like ones have @@ -49,11 +51,11 @@ namespace spv { typedef unsigned int Id; -#define SPV_VERSION 0x10400 +#define SPV_VERSION 0x10600 #define SPV_REVISION 1 static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010400; +static const unsigned int Version = 0x00010600; static const unsigned int Revision = 1; static const unsigned int OpCodeMask = 0xffff; static const unsigned int WordCountShift = 16; @@ -65,6 +67,8 @@ enum SourceLanguage { SourceLanguageOpenCL_C = 3, SourceLanguageOpenCL_CPP = 4, SourceLanguageHLSL = 5, + SourceLanguageCPP_for_OpenCL = 6, + SourceLanguageSYCL = 7, SourceLanguageMax = 0x7fffffff, }; @@ -78,11 +82,17 @@ enum ExecutionModel { ExecutionModelKernel = 6, ExecutionModelTaskNV = 5267, ExecutionModelMeshNV = 5268, + ExecutionModelRayGenerationKHR = 5313, ExecutionModelRayGenerationNV = 5313, + ExecutionModelIntersectionKHR = 5314, ExecutionModelIntersectionNV = 5314, + ExecutionModelAnyHitKHR = 5315, ExecutionModelAnyHitNV = 5315, + ExecutionModelClosestHitKHR = 5316, ExecutionModelClosestHitNV = 5316, + ExecutionModelMissKHR = 5317, ExecutionModelMissNV = 5317, + ExecutionModelCallableKHR = 5318, ExecutionModelCallableNV = 5318, ExecutionModelMax = 0x7fffffff, }; @@ -91,6 +101,7 @@ enum AddressingModel { AddressingModelLogical = 0, AddressingModelPhysical32 = 1, AddressingModelPhysical64 = 2, + AddressingModelPhysicalStorageBuffer64 = 5348, AddressingModelPhysicalStorageBuffer64EXT = 5348, AddressingModelMax = 0x7fffffff, }; @@ -99,6 +110,7 @@ enum MemoryModel { MemoryModelSimple = 0, MemoryModelGLSL450 = 1, MemoryModelOpenCL = 2, + MemoryModelVulkan = 3, MemoryModelVulkanKHR = 3, MemoryModelMax = 0x7fffffff, }; @@ -142,13 +154,21 @@ enum ExecutionMode { ExecutionModeSubgroupsPerWorkgroupId = 37, ExecutionModeLocalSizeId = 38, ExecutionModeLocalSizeHintId = 39, + ExecutionModeSubgroupUniformControlFlowKHR = 4421, ExecutionModePostDepthCoverage = 4446, ExecutionModeDenormPreserve = 4459, ExecutionModeDenormFlushToZero = 4460, ExecutionModeSignedZeroInfNanPreserve = 4461, ExecutionModeRoundingModeRTE = 4462, ExecutionModeRoundingModeRTZ = 4463, + ExecutionModeEarlyAndLateFragmentTestsAMD = 5017, ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeStencilRefUnchangedFrontAMD = 5079, + ExecutionModeStencilRefGreaterFrontAMD = 5080, + ExecutionModeStencilRefLessFrontAMD = 5081, + ExecutionModeStencilRefUnchangedBackAMD = 5082, + ExecutionModeStencilRefGreaterBackAMD = 5083, + ExecutionModeStencilRefLessBackAMD = 5084, ExecutionModeOutputLinesNV = 5269, ExecutionModeOutputPrimitivesNV = 5270, ExecutionModeDerivativeGroupQuadsNV = 5289, @@ -160,6 +180,17 @@ enum ExecutionMode { ExecutionModeSampleInterlockUnorderedEXT = 5369, ExecutionModeShadingRateInterlockOrderedEXT = 5370, ExecutionModeShadingRateInterlockUnorderedEXT = 5371, + ExecutionModeSharedLocalMemorySizeINTEL = 5618, + ExecutionModeRoundingModeRTPINTEL = 5620, + ExecutionModeRoundingModeRTNINTEL = 5621, + ExecutionModeFloatingPointModeALTINTEL = 5622, + ExecutionModeFloatingPointModeIEEEINTEL = 5623, + ExecutionModeMaxWorkgroupSizeINTEL = 5893, + ExecutionModeMaxWorkDimINTEL = 5894, + ExecutionModeNoGlobalOffsetINTEL = 5895, + ExecutionModeNumSIMDWorkitemsINTEL = 5896, + ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, + ExecutionModeNamedBarrierCountINTEL = 6417, ExecutionModeMax = 0x7fffffff, }; @@ -177,13 +208,23 @@ enum StorageClass { StorageClassAtomicCounter = 10, StorageClassImage = 11, StorageClassStorageBuffer = 12, + StorageClassCallableDataKHR = 5328, StorageClassCallableDataNV = 5328, + StorageClassIncomingCallableDataKHR = 5329, StorageClassIncomingCallableDataNV = 5329, + StorageClassRayPayloadKHR = 5338, StorageClassRayPayloadNV = 5338, + StorageClassHitAttributeKHR = 5339, StorageClassHitAttributeNV = 5339, + StorageClassIncomingRayPayloadKHR = 5342, StorageClassIncomingRayPayloadNV = 5342, + StorageClassShaderRecordBufferKHR = 5343, StorageClassShaderRecordBufferNV = 5343, + StorageClassPhysicalStorageBuffer = 5349, StorageClassPhysicalStorageBufferEXT = 5349, + StorageClassCodeSectionINTEL = 5605, + StorageClassDeviceOnlyINTEL = 5936, + StorageClassHostOnlyINTEL = 5937, StorageClassMax = 0x7fffffff, }; @@ -254,6 +295,8 @@ enum ImageFormat { ImageFormatRg8ui = 37, ImageFormatR16ui = 38, ImageFormatR8ui = 39, + ImageFormatR64ui = 40, + ImageFormatR64i = 41, ImageFormatMax = 0x7fffffff, }; @@ -311,12 +354,18 @@ enum ImageOperandsShift { ImageOperandsConstOffsetsShift = 5, ImageOperandsSampleShift = 6, ImageOperandsMinLodShift = 7, + ImageOperandsMakeTexelAvailableShift = 8, ImageOperandsMakeTexelAvailableKHRShift = 8, + ImageOperandsMakeTexelVisibleShift = 9, ImageOperandsMakeTexelVisibleKHRShift = 9, + ImageOperandsNonPrivateTexelShift = 10, ImageOperandsNonPrivateTexelKHRShift = 10, + ImageOperandsVolatileTexelShift = 11, ImageOperandsVolatileTexelKHRShift = 11, ImageOperandsSignExtendShift = 12, ImageOperandsZeroExtendShift = 13, + ImageOperandsNontemporalShift = 14, + ImageOperandsOffsetsShift = 16, ImageOperandsMax = 0x7fffffff, }; @@ -330,12 +379,18 @@ enum ImageOperandsMask { ImageOperandsConstOffsetsMask = 0x00000020, ImageOperandsSampleMask = 0x00000040, ImageOperandsMinLodMask = 0x00000080, + ImageOperandsMakeTexelAvailableMask = 0x00000100, ImageOperandsMakeTexelAvailableKHRMask = 0x00000100, + ImageOperandsMakeTexelVisibleMask = 0x00000200, ImageOperandsMakeTexelVisibleKHRMask = 0x00000200, + ImageOperandsNonPrivateTexelMask = 0x00000400, ImageOperandsNonPrivateTexelKHRMask = 0x00000400, + ImageOperandsVolatileTexelMask = 0x00000800, ImageOperandsVolatileTexelKHRMask = 0x00000800, ImageOperandsSignExtendMask = 0x00001000, ImageOperandsZeroExtendMask = 0x00002000, + ImageOperandsNontemporalMask = 0x00004000, + ImageOperandsOffsetsMask = 0x00010000, }; enum FPFastMathModeShift { @@ -344,6 +399,8 @@ enum FPFastMathModeShift { FPFastMathModeNSZShift = 2, FPFastMathModeAllowRecipShift = 3, FPFastMathModeFastShift = 4, + FPFastMathModeAllowContractFastINTELShift = 16, + FPFastMathModeAllowReassocINTELShift = 17, FPFastMathModeMax = 0x7fffffff, }; @@ -354,6 +411,8 @@ enum FPFastMathModeMask { FPFastMathModeNSZMask = 0x00000004, FPFastMathModeAllowRecipMask = 0x00000008, FPFastMathModeFastMask = 0x00000010, + FPFastMathModeAllowContractFastINTELMask = 0x00010000, + FPFastMathModeAllowReassocINTELMask = 0x00020000, }; enum FPRoundingMode { @@ -367,6 +426,7 @@ enum FPRoundingMode { enum LinkageType { LinkageTypeExport = 0, LinkageTypeImport = 1, + LinkageTypeLinkOnceODR = 2, LinkageTypeMax = 0x7fffffff, }; @@ -447,15 +507,60 @@ enum Decoration { DecorationPerPrimitiveNV = 5271, DecorationPerViewNV = 5272, DecorationPerTaskNV = 5273, + DecorationPerVertexKHR = 5285, DecorationPerVertexNV = 5285, + DecorationNonUniform = 5300, DecorationNonUniformEXT = 5300, + DecorationRestrictPointer = 5355, DecorationRestrictPointerEXT = 5355, + DecorationAliasedPointer = 5356, DecorationAliasedPointerEXT = 5356, + DecorationBindlessSamplerNV = 5398, + DecorationBindlessImageNV = 5399, + DecorationBoundSamplerNV = 5400, + DecorationBoundImageNV = 5401, + DecorationSIMTCallINTEL = 5599, + DecorationReferencedIndirectlyINTEL = 5602, + DecorationClobberINTEL = 5607, + DecorationSideEffectsINTEL = 5608, + DecorationVectorComputeVariableINTEL = 5624, + DecorationFuncParamIOKindINTEL = 5625, + DecorationVectorComputeFunctionINTEL = 5626, + DecorationStackCallINTEL = 5627, + DecorationGlobalVariableOffsetINTEL = 5628, DecorationCounterBuffer = 5634, DecorationHlslCounterBufferGOOGLE = 5634, DecorationHlslSemanticGOOGLE = 5635, DecorationUserSemantic = 5635, DecorationUserTypeGOOGLE = 5636, + DecorationFunctionRoundingModeINTEL = 5822, + DecorationFunctionDenormModeINTEL = 5823, + DecorationRegisterINTEL = 5825, + DecorationMemoryINTEL = 5826, + DecorationNumbanksINTEL = 5827, + DecorationBankwidthINTEL = 5828, + DecorationMaxPrivateCopiesINTEL = 5829, + DecorationSinglepumpINTEL = 5830, + DecorationDoublepumpINTEL = 5831, + DecorationMaxReplicatesINTEL = 5832, + DecorationSimpleDualPortINTEL = 5833, + DecorationMergeINTEL = 5834, + DecorationBankBitsINTEL = 5835, + DecorationForcePow2DepthINTEL = 5836, + DecorationBurstCoalesceINTEL = 5899, + DecorationCacheSizeINTEL = 5900, + DecorationDontStaticallyCoalesceINTEL = 5901, + DecorationPrefetchINTEL = 5902, + DecorationStallEnableINTEL = 5905, + DecorationFuseLoopsInFunctionINTEL = 5907, + DecorationAliasScopeINTEL = 5914, + DecorationNoAliasINTEL = 5915, + DecorationBufferLocationINTEL = 5921, + DecorationIOPipeStorageINTEL = 5944, + DecorationFunctionFloatingPointModeINTEL = 6080, + DecorationSingleElementVectorINTEL = 6085, + DecorationVectorComputeCallableFunctionINTEL = 6087, + DecorationMediaBlockIOINTEL = 6140, DecorationMax = 0x7fffffff, }; @@ -514,8 +619,10 @@ enum BuiltIn { BuiltInBaseVertex = 4424, BuiltInBaseInstance = 4425, BuiltInDrawIndex = 4426, + BuiltInPrimitiveShadingRateKHR = 4432, BuiltInDeviceIndex = 4438, BuiltInViewIndex = 4440, + BuiltInShadingRateKHR = 4444, BuiltInBaryCoordNoPerspAMD = 4992, BuiltInBaryCoordNoPerspCentroidAMD = 4993, BuiltInBaryCoordNoPerspSampleAMD = 4994, @@ -538,30 +645,48 @@ enum BuiltIn { BuiltInLayerPerViewNV = 5279, BuiltInMeshViewCountNV = 5280, BuiltInMeshViewIndicesNV = 5281, + BuiltInBaryCoordKHR = 5286, BuiltInBaryCoordNV = 5286, + BuiltInBaryCoordNoPerspKHR = 5287, BuiltInBaryCoordNoPerspNV = 5287, BuiltInFragSizeEXT = 5292, BuiltInFragmentSizeNV = 5292, BuiltInFragInvocationCountEXT = 5293, BuiltInInvocationsPerPixelNV = 5293, + BuiltInLaunchIdKHR = 5319, BuiltInLaunchIdNV = 5319, + BuiltInLaunchSizeKHR = 5320, BuiltInLaunchSizeNV = 5320, + BuiltInWorldRayOriginKHR = 5321, BuiltInWorldRayOriginNV = 5321, + BuiltInWorldRayDirectionKHR = 5322, BuiltInWorldRayDirectionNV = 5322, + BuiltInObjectRayOriginKHR = 5323, BuiltInObjectRayOriginNV = 5323, + BuiltInObjectRayDirectionKHR = 5324, BuiltInObjectRayDirectionNV = 5324, + BuiltInRayTminKHR = 5325, BuiltInRayTminNV = 5325, + BuiltInRayTmaxKHR = 5326, BuiltInRayTmaxNV = 5326, + BuiltInInstanceCustomIndexKHR = 5327, BuiltInInstanceCustomIndexNV = 5327, + BuiltInObjectToWorldKHR = 5330, BuiltInObjectToWorldNV = 5330, + BuiltInWorldToObjectKHR = 5331, BuiltInWorldToObjectNV = 5331, BuiltInHitTNV = 5332, + BuiltInHitKindKHR = 5333, BuiltInHitKindNV = 5333, + BuiltInCurrentRayTimeNV = 5334, + BuiltInIncomingRayFlagsKHR = 5351, BuiltInIncomingRayFlagsNV = 5351, + BuiltInRayGeometryIndexKHR = 5352, BuiltInWarpsPerSMNV = 5374, BuiltInSMCountNV = 5375, BuiltInWarpIDNV = 5376, BuiltInSMIDNV = 5377, + BuiltInCullMaskKHR = 6021, BuiltInMax = 0x7fffffff, }; @@ -587,6 +712,14 @@ enum LoopControlShift { LoopControlIterationMultipleShift = 6, LoopControlPeelCountShift = 7, LoopControlPartialCountShift = 8, + LoopControlInitiationIntervalINTELShift = 16, + LoopControlMaxConcurrencyINTELShift = 17, + LoopControlDependencyArrayINTELShift = 18, + LoopControlPipelineEnableINTELShift = 19, + LoopControlLoopCoalesceINTELShift = 20, + LoopControlMaxInterleavingINTELShift = 21, + LoopControlSpeculatedIterationsINTELShift = 22, + LoopControlNoFusionINTELShift = 23, LoopControlMax = 0x7fffffff, }; @@ -601,6 +734,14 @@ enum LoopControlMask { LoopControlIterationMultipleMask = 0x00000040, LoopControlPeelCountMask = 0x00000080, LoopControlPartialCountMask = 0x00000100, + LoopControlInitiationIntervalINTELMask = 0x00010000, + LoopControlMaxConcurrencyINTELMask = 0x00020000, + LoopControlDependencyArrayINTELMask = 0x00040000, + LoopControlPipelineEnableINTELMask = 0x00080000, + LoopControlLoopCoalesceINTELMask = 0x00100000, + LoopControlMaxInterleavingINTELMask = 0x00200000, + LoopControlSpeculatedIterationsINTELMask = 0x00400000, + LoopControlNoFusionINTELMask = 0x00800000, }; enum FunctionControlShift { @@ -608,6 +749,7 @@ enum FunctionControlShift { FunctionControlDontInlineShift = 1, FunctionControlPureShift = 2, FunctionControlConstShift = 3, + FunctionControlOptNoneINTELShift = 16, FunctionControlMax = 0x7fffffff, }; @@ -617,6 +759,7 @@ enum FunctionControlMask { FunctionControlDontInlineMask = 0x00000002, FunctionControlPureMask = 0x00000004, FunctionControlConstMask = 0x00000008, + FunctionControlOptNoneINTELMask = 0x00010000, }; enum MemorySemanticsShift { @@ -630,8 +773,11 @@ enum MemorySemanticsShift { MemorySemanticsCrossWorkgroupMemoryShift = 9, MemorySemanticsAtomicCounterMemoryShift = 10, MemorySemanticsImageMemoryShift = 11, + MemorySemanticsOutputMemoryShift = 12, MemorySemanticsOutputMemoryKHRShift = 12, + MemorySemanticsMakeAvailableShift = 13, MemorySemanticsMakeAvailableKHRShift = 13, + MemorySemanticsMakeVisibleShift = 14, MemorySemanticsMakeVisibleKHRShift = 14, MemorySemanticsVolatileShift = 15, MemorySemanticsMax = 0x7fffffff, @@ -649,8 +795,11 @@ enum MemorySemanticsMask { MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, MemorySemanticsAtomicCounterMemoryMask = 0x00000400, MemorySemanticsImageMemoryMask = 0x00000800, + MemorySemanticsOutputMemoryMask = 0x00001000, MemorySemanticsOutputMemoryKHRMask = 0x00001000, + MemorySemanticsMakeAvailableMask = 0x00002000, MemorySemanticsMakeAvailableKHRMask = 0x00002000, + MemorySemanticsMakeVisibleMask = 0x00004000, MemorySemanticsMakeVisibleKHRMask = 0x00004000, MemorySemanticsVolatileMask = 0x00008000, }; @@ -659,9 +808,14 @@ enum MemoryAccessShift { MemoryAccessVolatileShift = 0, MemoryAccessAlignedShift = 1, MemoryAccessNontemporalShift = 2, + MemoryAccessMakePointerAvailableShift = 3, MemoryAccessMakePointerAvailableKHRShift = 3, + MemoryAccessMakePointerVisibleShift = 4, MemoryAccessMakePointerVisibleKHRShift = 4, + MemoryAccessNonPrivatePointerShift = 5, MemoryAccessNonPrivatePointerKHRShift = 5, + MemoryAccessAliasScopeINTELMaskShift = 16, + MemoryAccessNoAliasINTELMaskShift = 17, MemoryAccessMax = 0x7fffffff, }; @@ -670,9 +824,14 @@ enum MemoryAccessMask { MemoryAccessVolatileMask = 0x00000001, MemoryAccessAlignedMask = 0x00000002, MemoryAccessNontemporalMask = 0x00000004, + MemoryAccessMakePointerAvailableMask = 0x00000008, MemoryAccessMakePointerAvailableKHRMask = 0x00000008, + MemoryAccessMakePointerVisibleMask = 0x00000010, MemoryAccessMakePointerVisibleKHRMask = 0x00000010, + MemoryAccessNonPrivatePointerMask = 0x00000020, MemoryAccessNonPrivatePointerKHRMask = 0x00000020, + MemoryAccessAliasScopeINTELMaskMask = 0x00010000, + MemoryAccessNoAliasINTELMaskMask = 0x00020000, }; enum Scope { @@ -681,7 +840,9 @@ enum Scope { ScopeWorkgroup = 2, ScopeSubgroup = 3, ScopeInvocation = 4, + ScopeQueueFamily = 5, ScopeQueueFamilyKHR = 5, + ScopeShaderCallKHR = 6, ScopeMax = 0x7fffffff, }; @@ -781,8 +942,15 @@ enum Capability { CapabilityGroupNonUniformShuffleRelative = 66, CapabilityGroupNonUniformClustered = 67, CapabilityGroupNonUniformQuad = 68, + CapabilityShaderLayer = 69, + CapabilityShaderViewportIndex = 70, + CapabilityUniformDecoration = 71, + CapabilityFragmentShadingRateKHR = 4422, CapabilitySubgroupBallotKHR = 4423, CapabilityDrawParameters = 4427, + CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, + CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, CapabilitySubgroupVoteKHR = 4431, CapabilityStorageBuffer16BitAccess = 4433, CapabilityStorageUniformBufferBlock16 = 4433, @@ -804,11 +972,17 @@ enum Capability { CapabilitySignedZeroInfNanPreserve = 4466, CapabilityRoundingModeRTE = 4467, CapabilityRoundingModeRTZ = 4468, + CapabilityRayQueryProvisionalKHR = 4471, + CapabilityRayQueryKHR = 4472, + CapabilityRayTraversalPrimitiveCullingKHR = 4478, + CapabilityRayTracingKHR = 4479, CapabilityFloat16ImageAMD = 5008, CapabilityImageGatherBiasLodAMD = 5009, CapabilityFragmentMaskAMD = 5010, CapabilityStencilExportEXT = 5013, CapabilityImageReadWriteLodAMD = 5015, + CapabilityInt64ImageEXT = 5016, + CapabilityShaderClockKHR = 5055, CapabilitySampleMaskOverrideCoverageNV = 5249, CapabilityGeometryShaderPassthroughNV = 5251, CapabilityShaderViewportIndexLayerEXT = 5254, @@ -819,45 +993,216 @@ enum Capability { CapabilityFragmentFullyCoveredEXT = 5265, CapabilityMeshShadingNV = 5266, CapabilityImageFootprintNV = 5282, + CapabilityFragmentBarycentricKHR = 5284, CapabilityFragmentBarycentricNV = 5284, CapabilityComputeDerivativeGroupQuadsNV = 5288, CapabilityFragmentDensityEXT = 5291, CapabilityShadingRateNV = 5291, CapabilityGroupNonUniformPartitionedNV = 5297, + CapabilityShaderNonUniform = 5301, CapabilityShaderNonUniformEXT = 5301, + CapabilityRuntimeDescriptorArray = 5302, CapabilityRuntimeDescriptorArrayEXT = 5302, + CapabilityInputAttachmentArrayDynamicIndexing = 5303, CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, + CapabilityUniformTexelBufferArrayDynamicIndexing = 5304, CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, + CapabilityStorageTexelBufferArrayDynamicIndexing = 5305, CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, + CapabilityUniformBufferArrayNonUniformIndexing = 5306, CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, + CapabilitySampledImageArrayNonUniformIndexing = 5307, CapabilitySampledImageArrayNonUniformIndexingEXT = 5307, + CapabilityStorageBufferArrayNonUniformIndexing = 5308, CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, + CapabilityStorageImageArrayNonUniformIndexing = 5309, CapabilityStorageImageArrayNonUniformIndexingEXT = 5309, + CapabilityInputAttachmentArrayNonUniformIndexing = 5310, CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, + CapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, + CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, CapabilityRayTracingNV = 5340, + CapabilityRayTracingMotionBlurNV = 5341, + CapabilityVulkanMemoryModel = 5345, CapabilityVulkanMemoryModelKHR = 5345, + CapabilityVulkanMemoryModelDeviceScope = 5346, CapabilityVulkanMemoryModelDeviceScopeKHR = 5346, + CapabilityPhysicalStorageBufferAddresses = 5347, CapabilityPhysicalStorageBufferAddressesEXT = 5347, CapabilityComputeDerivativeGroupLinearNV = 5350, + CapabilityRayTracingProvisionalKHR = 5353, CapabilityCooperativeMatrixNV = 5357, CapabilityFragmentShaderSampleInterlockEXT = 5363, CapabilityFragmentShaderShadingRateInterlockEXT = 5372, CapabilityShaderSMBuiltinsNV = 5373, CapabilityFragmentShaderPixelInterlockEXT = 5378, + CapabilityDemoteToHelperInvocation = 5379, CapabilityDemoteToHelperInvocationEXT = 5379, + CapabilityBindlessTextureNV = 5390, CapabilitySubgroupShuffleINTEL = 5568, CapabilitySubgroupBufferBlockIOINTEL = 5569, CapabilitySubgroupImageBlockIOINTEL = 5570, CapabilitySubgroupImageMediaBlockIOINTEL = 5579, + CapabilityRoundToInfinityINTEL = 5582, + CapabilityFloatingPointModeINTEL = 5583, CapabilityIntegerFunctions2INTEL = 5584, + CapabilityFunctionPointersINTEL = 5603, + CapabilityIndirectReferencesINTEL = 5604, + CapabilityAsmINTEL = 5606, + CapabilityAtomicFloat32MinMaxEXT = 5612, + CapabilityAtomicFloat64MinMaxEXT = 5613, + CapabilityAtomicFloat16MinMaxEXT = 5616, + CapabilityVectorComputeINTEL = 5617, + CapabilityVectorAnyINTEL = 5619, + CapabilityExpectAssumeKHR = 5629, CapabilitySubgroupAvcMotionEstimationINTEL = 5696, CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + CapabilityVariableLengthArrayINTEL = 5817, + CapabilityFunctionFloatControlINTEL = 5821, + CapabilityFPGAMemoryAttributesINTEL = 5824, + CapabilityFPFastMathModeINTEL = 5837, + CapabilityArbitraryPrecisionIntegersINTEL = 5844, + CapabilityArbitraryPrecisionFloatingPointINTEL = 5845, + CapabilityUnstructuredLoopControlsINTEL = 5886, + CapabilityFPGALoopControlsINTEL = 5888, + CapabilityKernelAttributesINTEL = 5892, + CapabilityFPGAKernelAttributesINTEL = 5897, + CapabilityFPGAMemoryAccessesINTEL = 5898, + CapabilityFPGAClusterAttributesINTEL = 5904, + CapabilityLoopFuseINTEL = 5906, + CapabilityMemoryAccessAliasingINTEL = 5910, + CapabilityFPGABufferLocationINTEL = 5920, + CapabilityArbitraryPrecisionFixedPointINTEL = 5922, + CapabilityUSMStorageClassesINTEL = 5935, + CapabilityIOPipesINTEL = 5943, + CapabilityBlockingPipesINTEL = 5945, + CapabilityFPGARegINTEL = 5948, + CapabilityDotProductInputAll = 6016, + CapabilityDotProductInputAllKHR = 6016, + CapabilityDotProductInput4x8Bit = 6017, + CapabilityDotProductInput4x8BitKHR = 6017, + CapabilityDotProductInput4x8BitPacked = 6018, + CapabilityDotProductInput4x8BitPackedKHR = 6018, + CapabilityDotProduct = 6019, + CapabilityDotProductKHR = 6019, + CapabilityRayCullMaskKHR = 6020, + CapabilityBitInstructions = 6025, + CapabilityGroupNonUniformRotateKHR = 6026, + CapabilityAtomicFloat32AddEXT = 6033, + CapabilityAtomicFloat64AddEXT = 6034, + CapabilityLongConstantCompositeINTEL = 6089, + CapabilityOptNoneINTEL = 6094, + CapabilityAtomicFloat16AddEXT = 6095, + CapabilityDebugInfoModuleINTEL = 6114, + CapabilitySplitBarrierINTEL = 6141, + CapabilityGroupUniformArithmeticKHR = 6400, CapabilityMax = 0x7fffffff, }; +enum RayFlagsShift { + RayFlagsOpaqueKHRShift = 0, + RayFlagsNoOpaqueKHRShift = 1, + RayFlagsTerminateOnFirstHitKHRShift = 2, + RayFlagsSkipClosestHitShaderKHRShift = 3, + RayFlagsCullBackFacingTrianglesKHRShift = 4, + RayFlagsCullFrontFacingTrianglesKHRShift = 5, + RayFlagsCullOpaqueKHRShift = 6, + RayFlagsCullNoOpaqueKHRShift = 7, + RayFlagsSkipTrianglesKHRShift = 8, + RayFlagsSkipAABBsKHRShift = 9, + RayFlagsMax = 0x7fffffff, +}; + +enum RayFlagsMask { + RayFlagsMaskNone = 0, + RayFlagsOpaqueKHRMask = 0x00000001, + RayFlagsNoOpaqueKHRMask = 0x00000002, + RayFlagsTerminateOnFirstHitKHRMask = 0x00000004, + RayFlagsSkipClosestHitShaderKHRMask = 0x00000008, + RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, + RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, + RayFlagsCullOpaqueKHRMask = 0x00000040, + RayFlagsCullNoOpaqueKHRMask = 0x00000080, + RayFlagsSkipTrianglesKHRMask = 0x00000100, + RayFlagsSkipAABBsKHRMask = 0x00000200, +}; + +enum RayQueryIntersection { + RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, + RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, + RayQueryIntersectionMax = 0x7fffffff, +}; + +enum RayQueryCommittedIntersectionType { + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, + RayQueryCommittedIntersectionTypeMax = 0x7fffffff, +}; + +enum RayQueryCandidateIntersectionType { + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, + RayQueryCandidateIntersectionTypeMax = 0x7fffffff, +}; + +enum FragmentShadingRateShift { + FragmentShadingRateVertical2PixelsShift = 0, + FragmentShadingRateVertical4PixelsShift = 1, + FragmentShadingRateHorizontal2PixelsShift = 2, + FragmentShadingRateHorizontal4PixelsShift = 3, + FragmentShadingRateMax = 0x7fffffff, +}; + +enum FragmentShadingRateMask { + FragmentShadingRateMaskNone = 0, + FragmentShadingRateVertical2PixelsMask = 0x00000001, + FragmentShadingRateVertical4PixelsMask = 0x00000002, + FragmentShadingRateHorizontal2PixelsMask = 0x00000004, + FragmentShadingRateHorizontal4PixelsMask = 0x00000008, +}; + +enum FPDenormMode { + FPDenormModePreserve = 0, + FPDenormModeFlushToZero = 1, + FPDenormModeMax = 0x7fffffff, +}; + +enum FPOperationMode { + FPOperationModeIEEE = 0, + FPOperationModeALT = 1, + FPOperationModeMax = 0x7fffffff, +}; + +enum QuantizationModes { + QuantizationModesTRN = 0, + QuantizationModesTRN_ZERO = 1, + QuantizationModesRND = 2, + QuantizationModesRND_ZERO = 3, + QuantizationModesRND_INF = 4, + QuantizationModesRND_MIN_INF = 5, + QuantizationModesRND_CONV = 6, + QuantizationModesRND_CONV_ODD = 7, + QuantizationModesMax = 0x7fffffff, +}; + +enum OverflowModes { + OverflowModesWRAP = 0, + OverflowModesSAT = 1, + OverflowModesSAT_ZERO = 2, + OverflowModesSAT_SYM = 3, + OverflowModesMax = 0x7fffffff, +}; + +enum PackedVectorFormat { + PackedVectorFormatPackedVectorFormat4x8Bit = 0, + PackedVectorFormatPackedVectorFormat4x8BitKHR = 0, + PackedVectorFormatMax = 0x7fffffff, +}; + enum Op { OpNop = 0, OpUndef = 1, @@ -1203,12 +1548,38 @@ enum Op { OpPtrEqual = 401, OpPtrNotEqual = 402, OpPtrDiff = 403, + OpTerminateInvocation = 4416, OpSubgroupBallotKHR = 4421, OpSubgroupFirstInvocationKHR = 4422, OpSubgroupAllKHR = 4428, OpSubgroupAnyKHR = 4429, OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, OpGroupIAddNonUniformAMD = 5000, OpGroupFAddNonUniformAMD = 5001, OpGroupFMinNonUniformAMD = 5002, @@ -1219,13 +1590,18 @@ enum Op { OpGroupSMaxNonUniformAMD = 5007, OpFragmentMaskFetchAMD = 5011, OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, OpImageSampleFootprintNV = 5283, OpGroupNonUniformPartitionNV = 5296, OpWritePackedPrimitiveIndices4x8NV = 5299, + OpReportIntersectionKHR = 5334, OpReportIntersectionNV = 5334, OpIgnoreIntersectionNV = 5335, OpTerminateRayNV = 5336, OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpTypeAccelerationStructureKHR = 5341, OpTypeAccelerationStructureNV = 5341, OpExecuteCallableNV = 5344, OpTypeCooperativeMatrixNV = 5358, @@ -1235,8 +1611,16 @@ enum Op { OpCooperativeMatrixLengthNV = 5362, OpBeginInvocationInterlockEXT = 5364, OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, OpDemoteToHelperInvocationEXT = 5380, OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, OpSubgroupShuffleINTEL = 5571, OpSubgroupShuffleDownINTEL = 5572, OpSubgroupShuffleUpINTEL = 5573, @@ -1261,6 +1645,15 @@ enum Op { OpUSubSatINTEL = 5596, OpIMul32x16INTEL = 5597, OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, OpDecorateString = 5632, OpDecorateStringGOOGLE = 5632, OpMemberDecorateString = 5633, @@ -1383,10 +1776,109 @@ enum Op { OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, OpMax = 0x7fffffff, }; #ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include +#endif inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { *hasResult = *hasResultType = false; switch (opcode) { @@ -1735,12 +2227,32 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpPtrEqual: *hasResult = true; *hasResultType = true; break; case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; case OpPtrDiff: *hasResult = true; *hasResultType = true; break; + case OpTerminateInvocation: *hasResult = false; *hasResultType = false; break; case OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; case OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case OpSDot: *hasResult = true; *hasResultType = true; break; + case OpUDot: *hasResult = true; *hasResultType = true; break; + case OpSUDot: *hasResult = true; *hasResultType = true; break; + case OpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpSUDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; @@ -1751,6 +2263,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case OpReadClockKHR: *hasResult = true; *hasResultType = true; break; case OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; case OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; case OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; @@ -1758,6 +2271,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; case OpTraceNV: *hasResult = false; *hasResultType = false; break; + case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; @@ -1767,8 +2282,15 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; - case OpDemoteToHelperInvocationEXT: *hasResult = false; *hasResultType = false; break; + case OpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case OpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case OpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case OpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case OpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; @@ -1793,6 +2315,15 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case OpExpectKHR: *hasResult = true; *hasResultType = true; break; case OpDecorateString: *hasResult = false; *hasResultType = false; break; case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; @@ -1913,6 +2444,102 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; + case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; + case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; } } #endif /* SPV_ENABLE_UTILITY_CODE */ @@ -1927,8 +2554,9 @@ inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } +inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); } +inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); } } // end namespace spv #endif // #ifndef spirv_HPP - From 10c5c17bc13a021360bfe2550e2e8c3b9a539c85 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 14:19:00 +0200 Subject: [PATCH 0240/1348] [meta] Build meta shaders against Vulkan 1.2 Silences some validation errors regarding layer export. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 13b1edd89..b61342331 100644 --- a/meson.build +++ b/meson.build @@ -82,7 +82,7 @@ dll_ext = '' def_spec_ext = '.def' glsl_compiler = find_program('glslangValidator') -glsl_args = [ '-V', '--vn', '@BASENAME@', '@INPUT@', '-o', '@OUTPUT@' ] +glsl_args = [ '--target-env', 'vulkan1.2', '--vn', '@BASENAME@', '@INPUT@', '-o', '@OUTPUT@' ] if run_command(glsl_compiler, [ '--quiet', '--version' ], check : false).returncode() == 0 glsl_args += [ '--quiet' ] endif From 320534cb342d74897e5457f23dd26119432dba79 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 14:42:55 +0200 Subject: [PATCH 0241/1348] [spirv] Automatically track interface variables --- src/d3d9/d3d9_fixed_function.cpp | 13 +++---------- src/d3d9/d3d9_fixed_function.h | 2 +- src/d3d9/d3d9_swvp_emu.cpp | 8 +------- src/dxbc/dxbc_compiler.cpp | 21 ++------------------- src/dxbc/dxbc_compiler.h | 1 - src/dxso/dxso_compiler.cpp | 16 ++-------------- src/dxso/dxso_compiler.h | 1 - src/spirv/spirv_module.cpp | 30 +++++++++++++++++++++++------- src/spirv/spirv_module.h | 13 ++++++++----- 9 files changed, 40 insertions(+), 65 deletions(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 62073c6a8..69198eace 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -343,7 +343,7 @@ namespace dxvk { } - uint32_t GetPointCoord(SpirvModule& spvModule, std::vector& entryPointInterfaces) { + uint32_t GetPointCoord(SpirvModule& spvModule) { uint32_t floatType = spvModule.defFloatType(32); uint32_t vec2Type = spvModule.defVectorType(floatType, 2); uint32_t vec4Type = spvModule.defVectorType(floatType, 4); @@ -352,7 +352,6 @@ namespace dxvk { uint32_t pointCoordPtr = spvModule.newVar(vec2Ptr, spv::StorageClassInput); spvModule.decorateBuiltIn(pointCoordPtr, spv::BuiltInPointCoord); - entryPointInterfaces.push_back(pointCoordPtr); uint32_t pointCoord = spvModule.opLoad(vec2Type, pointCoordPtr); @@ -603,7 +602,6 @@ namespace dxvk { SpirvModule m_module; std::vector m_bindings; - std::vector m_entryPointInterfaces; uint32_t m_inputMask = 0u; uint32_t m_outputMask = 0u; @@ -705,9 +703,7 @@ namespace dxvk { // Declare the entry point, we now have all the // information we need, including the interfaces m_module.addEntryPoint(m_entryPointId, - isVS() ? spv::ExecutionModelVertex : spv::ExecutionModelFragment, "main", - m_entryPointInterfaces.size(), - m_entryPointInterfaces.data()); + isVS() ? spv::ExecutionModelVertex : spv::ExecutionModelFragment, "main"); // Create the shader module object DxvkShaderCreateInfo info; @@ -773,8 +769,6 @@ namespace dxvk { std::string name = str::format(input ? "in_" : "out_", semantic.usage, semantic.usageIndex); m_module.setDebugName(ptr, name.c_str()); - m_entryPointInterfaces.push_back(ptr); - if (input) return m_module.opLoad(type, ptr); @@ -1974,7 +1968,7 @@ namespace dxvk { m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeOriginUpperLeft); - uint32_t pointCoord = GetPointCoord(m_module, m_entryPointInterfaces); + uint32_t pointCoord = GetPointCoord(m_module); auto pointInfo = GetPointSizeInfoPS(m_module, m_rsBlock); // We need to replace TEXCOORD inputs with gl_PointCoord @@ -2164,7 +2158,6 @@ namespace dxvk { spv::StorageClassOutput); m_module.decorateBuiltIn(clipDistArray, spv::BuiltInClipDistance); - m_entryPointInterfaces.push_back(clipDistArray); // Compute clip distances for (uint32_t i = 0; i < caps::MaxClipPlanes; i++) { diff --git a/src/d3d9/d3d9_fixed_function.h b/src/d3d9/d3d9_fixed_function.h index 8e312aa2d..3c0158c75 100644 --- a/src/d3d9/d3d9_fixed_function.h +++ b/src/d3d9/d3d9_fixed_function.h @@ -64,7 +64,7 @@ namespace dxvk { D3D9PointSizeInfoPS GetPointSizeInfoPS(SpirvModule& spvModule, uint32_t rsBlock); - uint32_t GetPointCoord(SpirvModule& spvModule, std::vector& entryPointInterfaces); + uint32_t GetPointCoord(SpirvModule& spvModule); uint32_t GetSharedConstants(SpirvModule& spvModule); diff --git a/src/d3d9/d3d9_swvp_emu.cpp b/src/d3d9/d3d9_swvp_emu.cpp index f02d4a20e..4c5eeaddb 100644 --- a/src/d3d9/d3d9_swvp_emu.cpp +++ b/src/d3d9/d3d9_swvp_emu.cpp @@ -139,7 +139,6 @@ namespace dxvk { // Load our builtins uint32_t primitiveIdPtr = m_module.newVar(m_module.defPointerType(uint_t, spv::StorageClassInput), spv::StorageClassInput); m_module.decorateBuiltIn(primitiveIdPtr, spv::BuiltInPrimitiveId); - m_entryPointInterfaces.push_back(primitiveIdPtr); uint32_t primitiveId = m_module.opLoad(uint_t, primitiveIdPtr); @@ -174,8 +173,6 @@ namespace dxvk { elementVar = m_module.opAccessChain(m_module.defPointerType(vec4_t, spv::StorageClassInput), elementPtr, 1, &zero); elementVar = m_module.opLoad(vec4_t, elementVar); - m_entryPointInterfaces.push_back(elementPtr); - // The offset of this element from the beginning of any given vertex uint32_t perVertexElementOffset = m_module.constu32(element.Offset / sizeof(uint32_t)); @@ -277,9 +274,7 @@ namespace dxvk { m_module.functionEnd(); m_module.addEntryPoint(m_entryPointId, - spv::ExecutionModelGeometry, "main", - m_entryPointInterfaces.size(), - m_entryPointInterfaces.data()); + spv::ExecutionModelGeometry, "main"); m_module.setDebugName(m_entryPointId, "main"); DxvkShaderCreateInfo info; @@ -295,7 +290,6 @@ namespace dxvk { SpirvModule m_module; - std::vector m_entryPointInterfaces; uint32_t m_entryPointId = 0; uint32_t m_inputMask = 0u; DxvkBindingInfo m_bufferBinding; diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 8e9d49cf8..045da8d97 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -243,9 +243,7 @@ namespace dxvk { // Declare the entry point, we now have all the // information we need, including the interfaces m_module.addEntryPoint(m_entryPointId, - m_programInfo.executionModel(), "main", - m_entryPointInterfaces.size(), - m_entryPointInterfaces.data()); + m_programInfo.executionModel(), "main"); m_module.setDebugName(m_entryPointId, "main"); // Create the shader object @@ -665,7 +663,6 @@ namespace dxvk { m_module.decorateLocation(varId, regIdx); m_module.setDebugName(varId, str::format("v", regIdx).c_str()); - m_entryPointInterfaces.push_back(varId); m_vRegs.at(regIdx) = { regType, varId }; @@ -747,7 +744,6 @@ namespace dxvk { if (info.sclass == spv::StorageClassOutput) { m_module.decorateLocation(varId, regIdx); - m_entryPointInterfaces.push_back(varId); // Add index decoration for potential dual-source blending if (m_programInfo.type() == DxbcProgramType::PixelShader) @@ -6631,7 +6627,6 @@ namespace dxvk { m_perVertexOut = m_module.newVar( perVertexPointer, spv::StorageClassOutput); - m_entryPointInterfaces.push_back(m_perVertexOut); m_module.setDebugName(m_perVertexOut, "vs_vertex_out"); // Standard input array @@ -6704,7 +6699,6 @@ namespace dxvk { m_perVertexOut = m_module.newVar( perVertexPointer, spv::StorageClassOutput); - m_entryPointInterfaces.push_back(m_perVertexOut); m_module.setDebugName(m_perVertexOut, "ds_vertex_out"); // Main function of the domain shader @@ -6743,7 +6737,6 @@ namespace dxvk { m_perVertexOut = m_module.newVar( perVertexPointer, spv::StorageClassOutput); - m_entryPointInterfaces.push_back(m_perVertexOut); m_module.setDebugName(m_perVertexOut, "gs_vertex_out"); } @@ -6996,7 +6989,6 @@ namespace dxvk { xfbVar.dstMask = DxbcRegMask(dstComponentMask); m_xfbVars.push_back(xfbVar); - m_entryPointInterfaces.push_back(xfbVar.varId); m_module.setDebugName(xfbVar.varId, str::format("xfb", i).c_str()); @@ -7118,8 +7110,6 @@ namespace dxvk { m_perVertexIn = m_module.newVar( ptrTypeId, spv::StorageClassInput); m_module.setDebugName(m_perVertexIn, varName); - - m_entryPointInterfaces.push_back(m_perVertexIn); } @@ -7141,7 +7131,6 @@ namespace dxvk { ? "clip_distances" : "cull_distances"); - m_entryPointInterfaces.push_back(varId); return varId; } @@ -7332,8 +7321,6 @@ namespace dxvk { if (storageClass != spv::StorageClassPrivate) { m_module.decorate (varId, spv::DecorationPatch); m_module.decorateLocation (varId, 0); - - m_entryPointInterfaces.push_back(varId); } return varId; @@ -7362,9 +7349,6 @@ namespace dxvk { m_module.setDebugName (varId, isInput ? "vVertex" : "oVertex"); m_module.decorateLocation (varId, locIdx); - - if (storageClass != spv::StorageClassPrivate) - m_entryPointInterfaces.push_back(varId); return varId; } @@ -7484,8 +7468,7 @@ namespace dxvk { && info.type.ctype != DxbcScalarType::Bool && info.sclass == spv::StorageClassInput) m_module.decorate(varId, spv::DecorationFlat); - - m_entryPointInterfaces.push_back(varId); + return varId; } diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index af2d00e8e..65c331f16 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -517,7 +517,6 @@ namespace dxvk { /////////////////////////////////////////////////// // Entry point description - we'll need to declare // the function ID and all input/output variables. - std::vector m_entryPointInterfaces; uint32_t m_entryPointId = 0; //////////////////////////////////////////// diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 1b2413fc5..b17c4c556 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -216,9 +216,7 @@ namespace dxvk { // Declare the entry point, we now have all the // information we need, including the interfaces m_module.addEntryPoint(m_entryPointId, - m_programInfo.executionModel(), "main", - m_entryPointInterfaces.size(), - m_entryPointInterfaces.data()); + m_programInfo.executionModel(), "main"); m_module.setDebugName(m_entryPointId, "main"); } @@ -664,7 +662,6 @@ namespace dxvk { && info.sclass == spv::StorageClassInput) m_module.decorate(varId, spv::DecorationFlat); - m_entryPointInterfaces.push_back(varId); return varId; } @@ -1208,8 +1205,6 @@ namespace dxvk { input ? 0 : m_module.constf32(1.0f), input ? spv::StorageClassInput : spv::StorageClassOutput); - m_entryPointInterfaces.push_back(m_fog.id); - m_module.decorateLocation(m_fog.id, slot); } return m_fog; @@ -1244,7 +1239,6 @@ namespace dxvk { m_module.decorateLocation(m_ps.oColor[idx].id, idx); m_module.decorateIndex(m_ps.oColor[idx].id, 0); - m_entryPointInterfaces.push_back(m_ps.oColor[idx].id); m_usedRTs |= (1u << idx); } return m_ps.oColor[idx]; @@ -3371,7 +3365,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( D3D9PointSizeInfoPS pointInfo; if (m_programInfo.type() == DxsoProgramType::PixelShader) { - pointCoord = GetPointCoord(m_module, m_entryPointInterfaces); + pointCoord = GetPointCoord(m_module); pointInfo = GetPointSizeInfoPS(m_module, m_rsBlock); } @@ -3399,8 +3393,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( if (elem.centroid) m_module.decorate(inputPtr.id, spv::DecorationCentroid); - m_entryPointInterfaces.push_back(inputPtr.id); - uint32_t typeId = this->getVectorTypeId({ DxsoScalarType::Float32, 4 }); uint32_t ptrTypeId = m_module.defPointerType(typeId, spv::StorageClassPrivate); @@ -3520,8 +3512,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( } } - m_entryPointInterfaces.push_back(outputPtr.id); - uint32_t typeId = this->getVectorTypeId({ DxsoScalarType::Float32, 4 }); uint32_t ptrTypeId = m_module.defPointerType(typeId, spv::StorageClassPrivate); @@ -3598,7 +3588,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( m_module.setDebugName(outputPtr, name.c_str()); m_outputMask |= 1u << slot; - m_entryPointInterfaces.push_back(outputPtr); }; if (!outputtedColor0) @@ -3668,7 +3657,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( spv::StorageClassOutput); m_module.decorateBuiltIn(clipDistArray, spv::BuiltInClipDistance); - m_entryPointInterfaces.push_back(clipDistArray); if (m_moduleInfo.options.invariantPosition) m_module.decorate(m_vs.oPos.id, spv::DecorationInvariant); diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h index 1d1699d60..93ee78fc5 100644 --- a/src/dxso/dxso_compiler.h +++ b/src/dxso/dxso_compiler.h @@ -348,7 +348,6 @@ namespace dxvk { /////////////////////////////////////////////////// // Entry point description - we'll need to declare // the function ID and all input/output variables. - std::vector m_entryPointInterfaces; uint32_t m_entryPointId = 0; //////////////////////////////////////////// diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 7811bae9a..f107f7f27 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -69,16 +69,14 @@ namespace dxvk { void SpirvModule::addEntryPoint( uint32_t entryPointId, spv::ExecutionModel executionModel, - const char* name, - uint32_t interfaceCount, - const uint32_t* interfaceIds) { - m_entryPoints.putIns (spv::OpEntryPoint, 3 + m_entryPoints.strLen(name) + interfaceCount); + const char* name) { + m_entryPoints.putIns (spv::OpEntryPoint, 3 + m_entryPoints.strLen(name) + m_interfaceVars.size()); m_entryPoints.putWord (executionModel); m_entryPoints.putWord (entryPointId); m_entryPoints.putStr (name); - for (uint32_t i = 0; i < interfaceCount; i++) - m_entryPoints.putWord(interfaceIds[i]); + for (uint32_t varId : m_interfaceVars) + m_entryPoints.putWord(varId); } @@ -884,9 +882,12 @@ namespace dxvk { spv::StorageClass storageClass) { uint32_t resultId = this->allocateId(); + if (isInterfaceVar(storageClass)) + m_interfaceVars.push_back(resultId); + auto& code = storageClass != spv::StorageClassFunction ? m_variables : m_code; - + code.putIns (spv::OpVariable, 4); code.putWord (pointerType); code.putWord (resultId); @@ -901,6 +902,9 @@ namespace dxvk { uint32_t initialValue) { uint32_t resultId = this->allocateId(); + if (isInterfaceVar(storageClass)) + m_interfaceVars.push_back(resultId); + auto& code = storageClass != spv::StorageClassFunction ? m_variables : m_code; @@ -3738,4 +3742,16 @@ namespace dxvk { } } + + bool SpirvModule::isInterfaceVar( + spv::StorageClass sclass) const { + if (m_version < spvVersion(1, 4)) { + return sclass == spv::StorageClassInput + || sclass == spv::StorageClassOutput; + } else { + // All global variables need to be declared + return sclass != spv::StorageClassFunction; + } + } + } \ No newline at end of file diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index 7ce5b8f15..e9be24d6f 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -77,9 +77,7 @@ namespace dxvk { void addEntryPoint( uint32_t entryPointId, spv::ExecutionModel executionModel, - const char* name, - uint32_t interfaceCount, - const uint32_t* interfaceIds); + const char* name); void setMemoryModel( spv::AddressingModel addressModel, @@ -1255,7 +1253,9 @@ namespace dxvk { SpirvCodeBuffer m_code; std::unordered_set m_lateConsts; - + + std::vector m_interfaceVars; + uint32_t defType( spv::Op op, uint32_t argCount, @@ -1274,7 +1274,10 @@ namespace dxvk { void putImageOperands( const SpirvImageOperands& op); - + + bool isInterfaceVar( + spv::StorageClass sclass) const; + }; } \ No newline at end of file From e5c45d4ce061cbe743fe50d7c64d6c5b61172952 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 15:01:25 +0200 Subject: [PATCH 0242/1348] [dxbc] Use StorageBuffer storage class instead of BufferBlock --- src/dxbc/dxbc_compiler.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 045da8d97..bb4701b8a 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -1099,13 +1099,13 @@ namespace dxvk { uint32_t elemType = getScalarTypeId(DxbcScalarType::Uint32); uint32_t arrayType = m_module.defRuntimeArrayTypeUnique(elemType); uint32_t structType = m_module.defStructTypeUnique(1, &arrayType); - uint32_t ptrType = m_module.defPointerType(structType, spv::StorageClassUniform); + uint32_t ptrType = m_module.defPointerType(structType, spv::StorageClassStorageBuffer); - resTypeId = m_module.defPointerType(elemType, spv::StorageClassUniform); - varId = m_module.newVar(ptrType, spv::StorageClassUniform); + resTypeId = m_module.defPointerType(elemType, spv::StorageClassStorageBuffer); + varId = m_module.newVar(ptrType, spv::StorageClassStorageBuffer); m_module.decorateArrayStride(arrayType, sizeof(uint32_t)); - m_module.decorate(structType, spv::DecorationBufferBlock); + m_module.decorate(structType, spv::DecorationBlock); m_module.memberDecorateOffset(structType, 0, 0); m_module.setDebugName(structType, @@ -1388,7 +1388,7 @@ namespace dxvk { const uint32_t t_u32 = m_module.defIntType(32, 0); const uint32_t t_struct = m_module.defStructTypeUnique(1, &t_u32); - m_module.decorate(t_struct, spv::DecorationBufferBlock); + m_module.decorate(t_struct, spv::DecorationBlock); m_module.memberDecorateOffset(t_struct, 0, 0); m_module.setDebugName (t_struct, "uav_meta"); @@ -1396,12 +1396,12 @@ namespace dxvk { m_uavCtrStructType = t_struct; m_uavCtrPointerType = m_module.defPointerType( - t_struct, spv::StorageClassUniform); + t_struct, spv::StorageClassStorageBuffer); } // Declare the buffer variable const uint32_t varId = m_module.newVar( - m_uavCtrPointerType, spv::StorageClassUniform); + m_uavCtrPointerType, spv::StorageClassStorageBuffer); m_module.setDebugName(varId, str::format("u", regId, "_meta").c_str()); @@ -2496,7 +2496,7 @@ namespace dxvk { ptrType.type.ctype = DxbcScalarType::Uint32; ptrType.type.ccount = 1; ptrType.type.alength = 0; - ptrType.sclass = spv::StorageClassUniform; + ptrType.sclass = spv::StorageClassStorageBuffer; uint32_t zeroId = m_module.consti32(0); uint32_t ptrId = m_module.opAccessChain( From c3af42356f3e86b8b48f0e7fd136e31aca66287f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 15:06:23 +0200 Subject: [PATCH 0243/1348] [dxbc] Enable SPIR-V 1.6 --- src/dxbc/dxbc_compiler.cpp | 22 +++++++--------------- src/dxbc/dxbc_compiler.h | 20 -------------------- src/spirv/spirv_module.cpp | 2 +- 3 files changed, 8 insertions(+), 36 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index bb4701b8a..8ea7c9a7a 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -19,7 +19,7 @@ namespace dxvk { const DxbcAnalysisInfo& analysis) : m_moduleInfo (moduleInfo), m_programInfo(programInfo), - m_module (spvVersion(1, 3)), + m_module (spvVersion(1, 6)), m_isgn (isgn), m_osgn (osgn), m_psgn (psgn), @@ -1483,7 +1483,9 @@ namespace dxvk { m_immConstBuf = m_module.newVarInit( pointerTypeId, spv::StorageClassPrivate, arrayId); + m_module.setDebugName(m_immConstBuf, "icb"); + m_module.decorate(m_immConstBuf, spv::DecorationNonWritable); } @@ -6262,7 +6264,7 @@ namespace dxvk { case DxbcSystemValue::RenderTargetId: { if (m_programInfo.type() != DxbcProgramType::GeometryShader) - enableShaderViewportIndexLayer(); + m_module.enableCapability(spv::CapabilityShaderLayer); if (m_gs.builtinLayer == 0) { m_module.enableCapability(spv::CapabilityGeometry); @@ -6285,7 +6287,7 @@ namespace dxvk { case DxbcSystemValue::ViewportId: { if (m_programInfo.type() != DxbcProgramType::GeometryShader) - enableShaderViewportIndexLayer(); + m_module.enableCapability(spv::CapabilityShaderViewportIndex); if (m_gs.builtinViewportId == 0) { m_module.enableCapability(spv::CapabilityMultiViewport); @@ -6801,8 +6803,7 @@ namespace dxvk { if (m_analysis->usesKill && m_moduleInfo.options.useDemoteToHelperInvocation) { // This extension basically implements D3D-style discard - m_module.enableExtension("SPV_EXT_demote_to_helper_invocation"); - m_module.enableCapability(spv::CapabilityDemoteToHelperInvocationEXT); + m_module.enableCapability(spv::CapabilityDemoteToHelperInvocation); } else if (m_analysis->usesKill && m_analysis->usesDerivatives) { // We may have to defer kill operations to the end of // the shader in order to keep derivatives correct. @@ -7409,6 +7410,7 @@ namespace dxvk { spv::StorageClassPrivate, samplePosArray); m_module.setDebugName(varId, "g_sample_pos"); + m_module.decorate(varId, spv::DecorationNonWritable); return varId; } @@ -7515,16 +7517,6 @@ namespace dxvk { } - void DxbcCompiler::enableShaderViewportIndexLayer() { - if (!m_extensions.shaderViewportIndexLayer) { - m_extensions.shaderViewportIndexLayer = true; - - m_module.enableExtension("SPV_EXT_shader_viewport_index_layer"); - m_module.enableCapability(spv::CapabilityShaderViewportIndexLayerEXT); - } - } - - DxbcCfgBlock* DxbcCompiler::cfgFindBlock( const std::initializer_list& types) { for (auto cur = m_controlFlowBlocks.rbegin(); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 65c331f16..a3ac717a9 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -353,18 +353,6 @@ namespace dxvk { }; - /** - * \brief SPIR-V extension set - * - * Keeps track of which optional SPIR-V extensions - * are enabled so that any required setup code is - * only run once. - */ - struct DxbcSpirvExtensions { - bool shaderViewportIndexLayer = false; - }; - - /** * \brief DXBC to SPIR-V shader compiler * @@ -534,10 +522,6 @@ namespace dxvk { DxbcCompilerPsPart m_ps; DxbcCompilerCsPart m_cs; - ///////////////////////////// - // Enabled SPIR-V extensions - DxbcSpirvExtensions m_extensions; - ////////////////////// // Global state stuff bool m_precise = true; @@ -1198,10 +1182,6 @@ namespace dxvk { uint32_t emitPushConstants(); - //////////////////////////////// - // Extension enablement methods - void enableShaderViewportIndexLayer(); - //////////////// // Misc methods DxbcCfgBlock* cfgFindBlock( diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index f107f7f27..c253c6a3d 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -3593,7 +3593,7 @@ namespace dxvk { void SpirvModule::opDemoteToHelperInvocation() { - m_code.putIns (spv::OpDemoteToHelperInvocationEXT, 1); + m_code.putIns (spv::OpDemoteToHelperInvocation, 1); } From 5c4b44c97cb5f6d3176a9795c0ab6f5c83d65d0d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 16:12:03 +0200 Subject: [PATCH 0244/1348] [dxvk] Correctly detect viewport index or layer exports in DxvkShader --- src/dxvk/dxvk_shader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index b65931892..e3e99d71d 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -88,7 +88,8 @@ namespace dxvk { if (ins.arg(1) == spv::CapabilitySampleRateShading) m_flags.set(DxvkShaderFlag::HasSampleRateShading); - if (ins.arg(1) == spv::CapabilityShaderViewportIndexLayerEXT) + if (ins.arg(1) == spv::CapabilityShaderViewportIndex + || ins.arg(1) == spv::CapabilityShaderLayer) m_flags.set(DxvkShaderFlag::ExportsViewportIndexLayerFromVertexStage); } From cdf22a4086d85eaf407d3ee79dbb8876fa3bd41e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 17:23:54 +0200 Subject: [PATCH 0245/1348] [dxvk] Rename imageFormatInfo -> lookupFormatInfo --- src/d3d11/d3d11_context.cpp | 22 +++++++++++----------- src/d3d11/d3d11_context_def.cpp | 2 +- src/d3d11/d3d11_context_imm.cpp | 4 ++-- src/d3d11/d3d11_device.cpp | 8 ++++---- src/d3d11/d3d11_initializer.cpp | 2 +- src/d3d11/d3d11_texture.cpp | 16 ++++++++-------- src/d3d11/d3d11_video.cpp | 4 ++-- src/d3d11/d3d11_view_dsv.cpp | 2 +- src/d3d11/d3d11_view_rtv.cpp | 2 +- src/d3d11/d3d11_view_srv.cpp | 2 +- src/d3d11/d3d11_view_uav.cpp | 2 +- src/d3d9/d3d9_common_texture.cpp | 6 +++--- src/d3d9/d3d9_device.cpp | 22 +++++++++++----------- src/d3d9/d3d9_initializer.cpp | 4 ++-- src/d3d9/d3d9_swapchain.cpp | 6 +++--- src/dxvk/dxvk_buffer.h | 4 ++-- src/dxvk/dxvk_context.cpp | 10 +++++----- src/dxvk/dxvk_format.cpp | 2 +- src/dxvk/dxvk_format.h | 2 +- src/dxvk/dxvk_graphics.cpp | 6 +++--- src/dxvk/dxvk_image.h | 4 ++-- src/dxvk/dxvk_meta_copy.cpp | 2 +- src/dxvk/dxvk_meta_resolve.cpp | 4 ++-- src/dxvk/dxvk_state_cache_types.h | 2 +- src/dxvk/dxvk_util.cpp | 2 +- src/dxvk/dxvk_util.h | 2 +- src/dxvk/hud/dxvk_hud.cpp | 2 +- src/vulkan/vulkan_presenter.cpp | 4 ++-- 28 files changed, 75 insertions(+), 75 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 9bebbe48a..8aff2312e 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -355,8 +355,8 @@ namespace dxvk { || SrcSubresource >= srcTexture->CountSubresources()) return; - auto dstFormatInfo = imageFormatInfo(dstTexture->GetPackedFormat()); - auto srcFormatInfo = imageFormatInfo(srcTexture->GetPackedFormat()); + auto dstFormatInfo = lookupFormatInfo(dstTexture->GetPackedFormat()); + auto srcFormatInfo = lookupFormatInfo(srcTexture->GetPackedFormat()); auto dstLayers = vk::makeSubresourceLayers(dstTexture->GetSubresourceFromIndex(dstFormatInfo->aspectMask, DstSubresource)); auto srcLayers = vk::makeSubresourceLayers(srcTexture->GetSubresourceFromIndex(srcFormatInfo->aspectMask, SrcSubresource)); @@ -433,8 +433,8 @@ namespace dxvk { return; } - auto dstFormatInfo = imageFormatInfo(dstTexture->GetPackedFormat()); - auto srcFormatInfo = imageFormatInfo(srcTexture->GetPackedFormat()); + auto dstFormatInfo = lookupFormatInfo(dstTexture->GetPackedFormat()); + auto srcFormatInfo = lookupFormatInfo(srcTexture->GetPackedFormat()); for (uint32_t i = 0; i < dstDesc->MipLevels; i++) { VkImageSubresourceLayers dstLayers = { dstFormatInfo->aspectMask, i, 0, dstDesc->ArraySize }; @@ -870,7 +870,7 @@ namespace dxvk { // We'll need the format info to determine the buffer // element size, and we also need it for depth images. - const DxvkFormatInfo* formatInfo = imageFormatInfo(format); + const DxvkFormatInfo* formatInfo = lookupFormatInfo(format); // Convert the clear color format. ClearView takes // the clear value for integer formats as a set of @@ -1077,8 +1077,8 @@ namespace dxvk { const DXGI_VK_FORMAT_INFO dstFormatInfo = m_parent->LookupFormat(dstDesc.Format, DXGI_VK_FORMAT_MODE_ANY); const DXGI_VK_FORMAT_INFO srcFormatInfo = m_parent->LookupFormat(srcDesc.Format, DXGI_VK_FORMAT_MODE_ANY); - auto dstVulkanFormatInfo = imageFormatInfo(dstFormatInfo.Format); - auto srcVulkanFormatInfo = imageFormatInfo(srcFormatInfo.Format); + auto dstVulkanFormatInfo = lookupFormatInfo(dstFormatInfo.Format); + auto srcVulkanFormatInfo = lookupFormatInfo(srcFormatInfo.Format); if (DstSubresource >= dstTextureInfo->CountSubresources() || SrcSubresource >= srcTextureInfo->CountSubresources()) @@ -3428,8 +3428,8 @@ namespace dxvk { VkOffset3D SrcOffset, VkExtent3D SrcExtent) { // Image formats must be size-compatible - auto dstFormatInfo = imageFormatInfo(pDstTexture->GetPackedFormat()); - auto srcFormatInfo = imageFormatInfo(pSrcTexture->GetPackedFormat()); + auto dstFormatInfo = lookupFormatInfo(pDstTexture->GetPackedFormat()); + auto srcFormatInfo = lookupFormatInfo(pSrcTexture->GetPackedFormat()); if (dstFormatInfo->elementSize != srcFormatInfo->elementSize) { Logger::err("D3D11: CopyImage: Incompatible texel size"); @@ -3753,7 +3753,7 @@ namespace dxvk { VkFormat packedFormat = pDstTexture->GetPackedFormat(); - auto formatInfo = imageFormatInfo(packedFormat); + auto formatInfo = lookupFormatInfo(packedFormat); auto subresource = pDstTexture->GetSubresourceFromIndex( formatInfo->aspectMask, DstSubresource); @@ -3837,7 +3837,7 @@ namespace dxvk { VkExtent3D dstMipExtent = pDstTexture->MipLevelExtent(pDstSubresource->mipLevel); auto dstFormat = pDstTexture->GetPackedFormat(); - auto dstFormatInfo = imageFormatInfo(dstFormat); + auto dstFormatInfo = lookupFormatInfo(dstFormat); uint32_t planeCount = 1; diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 552cfcc81..57695bf25 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -333,7 +333,7 @@ namespace dxvk { VkFormat packedFormat = pTexture->GetPackedFormat(); - auto formatInfo = imageFormatInfo(packedFormat); + auto formatInfo = lookupFormatInfo(packedFormat); auto subresource = pTexture->GetSubresourceFromIndex( formatInfo->aspectMask, Subresource); diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 489e77bce..0c4ea85e3 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -477,7 +477,7 @@ namespace dxvk { uint64_t sequenceNumber = pResource->GetSequenceNumber(Subresource); - auto formatInfo = imageFormatInfo(packedFormat); + auto formatInfo = lookupFormatInfo(packedFormat); void* mapPtr; if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) { @@ -609,7 +609,7 @@ namespace dxvk { (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER)) { // Now that data has been written into the buffer, // we need to copy its contents into the image - VkImageAspectFlags aspectMask = imageFormatInfo(pResource->GetPackedFormat())->aspectMask; + VkImageAspectFlags aspectMask = lookupFormatInfo(pResource->GetPackedFormat())->aspectMask; VkImageSubresource subresource = pResource->GetSubresourceFromIndex(aspectMask, Subresource); UpdateImage(pResource, &subresource, VkOffset3D { 0, 0, 0 }, diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index f5ffc3490..f71aa1561 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -629,7 +629,7 @@ namespace dxvk { // generate the exact vertex layout. In that case we'll // pack attributes on the same binding in the order they // are declared, aligning each attribute to four bytes. - const DxvkFormatInfo* formatInfo = imageFormatInfo(attrib.format); + const DxvkFormatInfo* formatInfo = lookupFormatInfo(attrib.format); VkDeviceSize alignment = std::min(formatInfo->elementSize, 4); if (attrib.offset == D3D11_APPEND_ALIGNED_ELEMENT) { @@ -639,7 +639,7 @@ namespace dxvk { const DxvkVertexAttribute& prev = attrList.at(i - j); if (prev.binding == attrib.binding) { - attrib.offset = align(prev.offset + imageFormatInfo(prev.format)->elementSize, alignment); + attrib.offset = align(prev.offset + lookupFormatInfo(prev.format)->elementSize, alignment); break; } } @@ -2046,7 +2046,7 @@ namespace dxvk { return E_FAIL; // Query Vulkan format properties and supported features for it - const DxvkFormatInfo* fmtProperties = imageFormatInfo(fmtMapping.Format); + const DxvkFormatInfo* fmtProperties = lookupFormatInfo(fmtMapping.Format); VkFormatProperties fmtSupport = fmtMapping.Format != VK_FORMAT_UNDEFINED ? m_dxvkAdapter->formatProperties(fmtMapping.Format) @@ -2338,7 +2338,7 @@ namespace dxvk { texture->Desc()->Format, texture->GetFormatMode()).Format; - auto formatInfo = imageFormatInfo(packedFormat); + auto formatInfo = lookupFormatInfo(packedFormat); // Validate box against subresource dimensions Rc image = texture->GetImage(); diff --git a/src/d3d11/d3d11_initializer.cpp b/src/d3d11/d3d11_initializer.cpp index cfe0e9bcc..9aa9ac672 100644 --- a/src/d3d11/d3d11_initializer.cpp +++ b/src/d3d11/d3d11_initializer.cpp @@ -123,7 +123,7 @@ namespace dxvk { auto desc = pTexture->Desc(); VkFormat packedFormat = m_parent->LookupPackedFormat(desc->Format, pTexture->GetFormatMode()).Format; - auto formatInfo = imageFormatInfo(packedFormat); + auto formatInfo = lookupFormatInfo(packedFormat); if (pInitialData != nullptr && pInitialData->pSysMem != nullptr) { // pInitialData is an array that stores an entry for diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 08b6351d6..e1846559a 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -70,7 +70,7 @@ namespace dxvk { // The image must be marked as mutable if it can be reinterpreted // by a view with a different format. Depth-stencil formats cannot // be reinterpreted in Vulkan, so we'll ignore those. - auto formatProperties = imageFormatInfo(formatInfo.Format); + auto formatProperties = lookupFormatInfo(formatInfo.Format); bool isMutable = formatFamily.FormatCount > 1; bool isMultiPlane = (formatProperties->aspectMask & VK_IMAGE_ASPECT_PLANE_0_BIT) != 0; @@ -229,7 +229,7 @@ namespace dxvk { VkDeviceSize D3D11CommonTexture::ComputeMappedOffset(UINT Subresource, UINT Plane, VkOffset3D Offset) const { - auto packedFormatInfo = imageFormatInfo(m_packedFormat); + auto packedFormatInfo = lookupFormatInfo(m_packedFormat); VkImageAspectFlags aspectMask = packedFormatInfo->aspectMask; VkDeviceSize elementSize = packedFormatInfo->elementSize; @@ -281,7 +281,7 @@ namespace dxvk { case D3D11_COMMON_TEXTURE_MAP_MODE_NONE: case D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER: case D3D11_COMMON_TEXTURE_MAP_MODE_STAGING: { - auto packedFormatInfo = imageFormatInfo(m_packedFormat); + auto packedFormatInfo = lookupFormatInfo(m_packedFormat); VkImageAspectFlags aspects = packedFormatInfo->aspectMask; VkExtent3D mipExtent = MipLevelExtent(subresource.mipLevel); @@ -379,8 +379,8 @@ namespace dxvk { // Otherwise, all bit-compatible formats can be used. if (imageInfo.viewFormatCount == 0 && planeCount == 1) { - auto baseFormatInfo = imageFormatInfo(baseFormat.Format); - auto viewFormatInfo = imageFormatInfo(viewFormat.Format); + auto baseFormatInfo = lookupFormatInfo(baseFormat.Format); + auto viewFormatInfo = lookupFormatInfo(viewFormat.Format); return baseFormatInfo->aspectMask == viewFormatInfo->aspectMask && baseFormatInfo->elementSize == viewFormatInfo->elementSize; @@ -530,7 +530,7 @@ namespace dxvk { const auto dsMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; - auto formatInfo = imageFormatInfo(Format); + auto formatInfo = lookupFormatInfo(Format); return formatInfo->aspectMask == dsMask ? VK_IMAGE_USAGE_SAMPLED_BIT @@ -572,7 +572,7 @@ namespace dxvk { return D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER; // Multi-plane images have a special memory layout in D3D11 - if (imageFormatInfo(pImageInfo->format)->flags.test(DxvkFormatFlag::MultiPlane)) + if (lookupFormatInfo(pImageInfo->format)->flags.test(DxvkFormatFlag::MultiPlane)) return D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER; // If we can't use linear tiling for this image, we have to use a buffer @@ -644,7 +644,7 @@ namespace dxvk { D3D11CommonTexture::MappedBuffer D3D11CommonTexture::CreateMappedBuffer(UINT MipLevel) const { - const DxvkFormatInfo* formatInfo = imageFormatInfo( + const DxvkFormatInfo* formatInfo = lookupFormatInfo( m_device->LookupPackedFormat(m_desc.Format, GetFormatMode()).Format); DxvkBufferCreateInfo info; diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 883f9188e..75dc373aa 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -159,7 +159,7 @@ namespace dxvk { DXGI_VK_FORMAT_INFO formatInfo = pDevice->LookupFormat(resourceDesc.Format, DXGI_VK_FORMAT_MODE_COLOR); DXGI_VK_FORMAT_FAMILY formatFamily = pDevice->LookupFamily(resourceDesc.Format, DXGI_VK_FORMAT_MODE_COLOR); - VkImageAspectFlags aspectMask = imageFormatInfo(formatInfo.Format)->aspectMask; + VkImageAspectFlags aspectMask = lookupFormatInfo(formatInfo.Format)->aspectMask; DxvkImageViewCreateInfo viewInfo; viewInfo.format = formatInfo.Format; @@ -257,7 +257,7 @@ namespace dxvk { DxvkImageViewCreateInfo viewInfo; viewInfo.format = formatInfo.Format; - viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; + viewInfo.aspect = lookupFormatInfo(viewInfo.format)->aspectMask; viewInfo.swizzle = formatInfo.Swizzle; viewInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; diff --git a/src/d3d11/d3d11_view_dsv.cpp b/src/d3d11/d3d11_view_dsv.cpp index f0520c645..62e79fedb 100644 --- a/src/d3d11/d3d11_view_dsv.cpp +++ b/src/d3d11/d3d11_view_dsv.cpp @@ -19,7 +19,7 @@ namespace dxvk { DxvkImageViewCreateInfo viewInfo; viewInfo.format = pDevice->LookupFormat(pDesc->Format, DXGI_VK_FORMAT_MODE_DEPTH).Format; - viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; + viewInfo.aspect = lookupFormatInfo(viewInfo.format)->aspectMask; viewInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; switch (pDesc->ViewDimension) { diff --git a/src/d3d11/d3d11_view_rtv.cpp b/src/d3d11/d3d11_view_rtv.cpp index 86460502a..09153d0a0 100644 --- a/src/d3d11/d3d11_view_rtv.cpp +++ b/src/d3d11/d3d11_view_rtv.cpp @@ -24,7 +24,7 @@ namespace dxvk { DxvkImageViewCreateInfo viewInfo; viewInfo.format = formatInfo.Format; - viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; + viewInfo.aspect = lookupFormatInfo(viewInfo.format)->aspectMask; viewInfo.swizzle = formatInfo.Swizzle; viewInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; diff --git a/src/d3d11/d3d11_view_srv.cpp b/src/d3d11/d3d11_view_srv.cpp index 1c3d4d8dd..73c179b09 100644 --- a/src/d3d11/d3d11_view_srv.cpp +++ b/src/d3d11/d3d11_view_srv.cpp @@ -58,7 +58,7 @@ namespace dxvk { } else { viewInfo.format = pDevice->LookupFormat(pDesc->Format, DXGI_VK_FORMAT_MODE_COLOR).Format; - const DxvkFormatInfo* formatInfo = imageFormatInfo(viewInfo.format); + const DxvkFormatInfo* formatInfo = lookupFormatInfo(viewInfo.format); viewInfo.rangeOffset = formatInfo->elementSize * bufInfo.FirstElement; viewInfo.rangeLength = formatInfo->elementSize * bufInfo.NumElements; } diff --git a/src/d3d11/d3d11_view_uav.cpp b/src/d3d11/d3d11_view_uav.cpp index 54f826e79..562626acd 100644 --- a/src/d3d11/d3d11_view_uav.cpp +++ b/src/d3d11/d3d11_view_uav.cpp @@ -38,7 +38,7 @@ namespace dxvk { } else { viewInfo.format = pDevice->LookupFormat(pDesc->Format, DXGI_VK_FORMAT_MODE_COLOR).Format; - const DxvkFormatInfo* formatInfo = imageFormatInfo(viewInfo.format); + const DxvkFormatInfo* formatInfo = lookupFormatInfo(viewInfo.format); viewInfo.rangeOffset = formatInfo->elementSize * pDesc->Buffer.FirstElement; viewInfo.rangeLength = formatInfo->elementSize * pDesc->Buffer.NumElements; } diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 22bc37c91..ef93e9473 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -199,7 +199,7 @@ namespace dxvk { const UINT MipLevel = Subresource % m_desc.MipLevels; const DxvkFormatInfo* formatInfo = m_mapping.FormatColor != VK_FORMAT_UNDEFINED - ? imageFormatInfo(m_mapping.FormatColor) + ? lookupFormatInfo(m_mapping.FormatColor) : m_device->UnsupportedFormatInfo(m_desc.Format); const VkExtent3D mipExtent = util::computeMipLevelExtent( @@ -263,7 +263,7 @@ namespace dxvk { // The image must be marked as mutable if it can be reinterpreted // by a view with a different format. Depth-stencil formats cannot // be reinterpreted in Vulkan, so we'll ignore those. - auto formatProperties = imageFormatInfo(m_mapping.FormatColor); + auto formatProperties = lookupFormatInfo(m_mapping.FormatColor); bool isMutable = m_mapping.FormatSrgb != VK_FORMAT_UNDEFINED; bool isColorFormat = (formatProperties->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0; @@ -541,7 +541,7 @@ namespace dxvk { viewInfo.format = m_mapping.ConversionFormatInfo.FormatColor != VK_FORMAT_UNDEFINED ? PickSRGB(m_mapping.ConversionFormatInfo.FormatColor, m_mapping.ConversionFormatInfo.FormatSrgb, Srgb) : PickSRGB(m_mapping.FormatColor, m_mapping.FormatSrgb, Srgb); - viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; + viewInfo.aspect = lookupFormatInfo(viewInfo.format)->aspectMask; viewInfo.swizzle = m_mapping.Swizzle; viewInfo.usage = UsageFlags; viewInfo.type = GetImageViewTypeFromResourceType(m_type, Layer); diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 0fb2fe5a1..86cc93904 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -735,7 +735,7 @@ namespace dxvk { if (unlikely(srcTextureInfo->Desc()->Format != dstTextureInfo->Desc()->Format)) return D3DERR_INVALIDCALL; - const DxvkFormatInfo* formatInfo = imageFormatInfo(dstTextureInfo->GetFormatMapping().FormatColor); + const DxvkFormatInfo* formatInfo = lookupFormatInfo(dstTextureInfo->GetFormatMapping().FormatColor); VkOffset3D srcOffset = { 0u, 0u, 0u }; VkOffset3D dstOffset = { 0u, 0u, 0u }; @@ -878,7 +878,7 @@ namespace dxvk { Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource()); Rc srcImage = srcTexInfo->GetImage(); - const DxvkFormatInfo* srcFormatInfo = imageFormatInfo(srcImage->info().format); + const DxvkFormatInfo* srcFormatInfo = lookupFormatInfo(srcImage->info().format); const VkImageSubresource srcSubresource = srcTexInfo->GetSubresourceFromIndex(srcFormatInfo->aspectMask, src->GetSubresource()); VkImageSubresourceLayers srcSubresourceLayers = { @@ -953,8 +953,8 @@ namespace dxvk { if (dstImage == nullptr || srcImage == nullptr) return D3DERR_INVALIDCALL; - const DxvkFormatInfo* dstFormatInfo = imageFormatInfo(dstImage->info().format); - const DxvkFormatInfo* srcFormatInfo = imageFormatInfo(srcImage->info().format); + const DxvkFormatInfo* dstFormatInfo = lookupFormatInfo(dstImage->info().format); + const DxvkFormatInfo* srcFormatInfo = lookupFormatInfo(srcImage->info().format); const VkImageSubresource dstSubresource = dstTextureInfo->GetSubresourceFromIndex(dstFormatInfo->aspectMask, dst->GetSubresource()); const VkImageSubresource srcSubresource = srcTextureInfo->GetSubresourceFromIndex(srcFormatInfo->aspectMask, src->GetSubresource()); @@ -1464,7 +1464,7 @@ namespace dxvk { if (Flags & D3DCLEAR_STENCIL) depthAspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - depthAspectMask &= imageFormatInfo(m_state.depthStencil->GetCommonTexture()->GetFormatMapping().FormatColor)->aspectMask; + depthAspectMask &= lookupFormatInfo(m_state.depthStencil->GetCommonTexture()->GetFormatMapping().FormatColor)->aspectMask; } auto ClearImageView = [this]( @@ -4134,7 +4134,7 @@ namespace dxvk { auto& formatMapping = pResource->GetFormatMapping(); const DxvkFormatInfo* formatInfo = formatMapping.IsValid() - ? imageFormatInfo(formatMapping.FormatColor) : UnsupportedFormatInfo(pResource->Desc()->Format); + ? lookupFormatInfo(formatMapping.FormatColor) : UnsupportedFormatInfo(pResource->Desc()->Format); auto subresource = pResource->GetSubresourceFromIndex( formatInfo->aspectMask, Subresource); @@ -4401,7 +4401,7 @@ namespace dxvk { UINT Subresource) { const Rc image = pResource->GetImage(); - auto formatInfo = imageFormatInfo(image->info().format); + auto formatInfo = lookupFormatInfo(image->info().format); auto subresource = pResource->GetSubresourceFromIndex( formatInfo->aspectMask, Subresource); @@ -4435,7 +4435,7 @@ namespace dxvk { // we need to copy its contents into the image const DxvkBufferSliceHandle srcSlice = pSrcTexture->GetMappedSlice(SrcSubresource); - auto formatInfo = imageFormatInfo(image->info().format); + auto formatInfo = lookupFormatInfo(image->info().format); auto srcSubresource = pSrcTexture->GetSubresourceFromIndex( formatInfo->aspectMask, SrcSubresource); @@ -4513,7 +4513,7 @@ namespace dxvk { TrackTextureMappingBufferSequenceNumber(pSrcTexture, SrcSubresource); } else { - const DxvkFormatInfo* formatInfo = imageFormatInfo(pDestTexture->GetFormatMapping().FormatColor); + const DxvkFormatInfo* formatInfo = lookupFormatInfo(pDestTexture->GetFormatMapping().FormatColor); // Add more blocks for the other planes that we might have. // TODO: PLEASE CLEAN ME @@ -6830,8 +6830,8 @@ namespace dxvk { const D3D9_VK_FORMAT_MAPPING srcFormatInfo = LookupFormat(srcDesc->Format); const D3D9_VK_FORMAT_MAPPING dstFormatInfo = LookupFormat(dstDesc->Format); - auto srcVulkanFormatInfo = imageFormatInfo(srcFormatInfo.FormatColor); - auto dstVulkanFormatInfo = imageFormatInfo(dstFormatInfo.FormatColor); + auto srcVulkanFormatInfo = lookupFormatInfo(srcFormatInfo.FormatColor); + auto dstVulkanFormatInfo = lookupFormatInfo(dstFormatInfo.FormatColor); const VkImageSubresource dstSubresource = dstTextureInfo->GetSubresourceFromIndex( diff --git a/src/d3d9/d3d9_initializer.cpp b/src/d3d9/d3d9_initializer.cpp index daf60cb0a..2695bdaf5 100644 --- a/src/d3d9/d3d9_initializer.cpp +++ b/src/d3d9/d3d9_initializer.cpp @@ -82,7 +82,7 @@ namespace dxvk { if (image == nullptr) return; - auto formatInfo = imageFormatInfo(image->info().format); + auto formatInfo = lookupFormatInfo(image->info().format); m_transferCommands += 1; @@ -119,7 +119,7 @@ namespace dxvk { if (pInitialData != nullptr) { VkExtent3D mipExtent = pTexture->GetExtentMip(m); - const DxvkFormatInfo* formatInfo = imageFormatInfo(pTexture->GetFormatMapping().FormatColor); + const DxvkFormatInfo* formatInfo = lookupFormatInfo(pTexture->GetFormatMapping().FormatColor); VkExtent3D blockCount = util::computeBlockCount(mipExtent, formatInfo->blockSize); uint32_t pitch = blockCount.width * formatInfo->elementSize; uint32_t alignedPitch = align(pitch, 4); diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index f2c08bc0e..41a373ef2 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -424,8 +424,8 @@ namespace dxvk { Rc blittedSrc = m_device->createImage( blitCreateInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - const DxvkFormatInfo* dstFormatInfo = imageFormatInfo(blittedSrc->info().format); - const DxvkFormatInfo* srcFormatInfo = imageFormatInfo(srcImage->info().format); + const DxvkFormatInfo* dstFormatInfo = lookupFormatInfo(blittedSrc->info().format); + const DxvkFormatInfo* srcFormatInfo = lookupFormatInfo(srcImage->info().format); const VkImageSubresource dstSubresource = dstTexInfo->GetSubresourceFromIndex(dstFormatInfo->aspectMask, 0); const VkImageSubresource srcSubresource = srcTexInfo->GetSubresourceFromIndex(srcFormatInfo->aspectMask, 0); @@ -467,7 +467,7 @@ namespace dxvk { srcImage = std::move(blittedSrc); } - const DxvkFormatInfo* srcFormatInfo = imageFormatInfo(srcImage->info().format); + const DxvkFormatInfo* srcFormatInfo = lookupFormatInfo(srcImage->info().format); const VkImageSubresource srcSubresource = srcTexInfo->GetSubresourceFromIndex(srcFormatInfo->aspectMask, 0); VkImageSubresourceLayers srcSubresourceLayers = { srcSubresource.aspectMask, diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 5fc50f44b..3dbbf5b9a 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -574,7 +574,7 @@ namespace dxvk { * \returns Element count */ VkDeviceSize elementCount() const { - auto format = imageFormatInfo(m_info.format); + auto format = lookupFormatInfo(m_info.format); return m_info.rangeLength / format->elementSize; } @@ -607,7 +607,7 @@ namespace dxvk { * \returns View format info */ const DxvkFormatInfo* formatInfo() const { - return imageFormatInfo(m_info.format); + return lookupFormatInfo(m_info.format); } /** diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 03838d391..2fbaf92f9 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -320,7 +320,7 @@ namespace dxvk { // Query pipeline objects to use for this clear operation DxvkMetaClearPipeline pipeInfo = m_common->metaClear().getClearBufferPipeline( - imageFormatInfo(bufferView->info().format)->flags); + lookupFormatInfo(bufferView->info().format)->flags); // Create a descriptor set pointing to the view VkBufferView viewObject = bufferView->handle(); @@ -1098,8 +1098,8 @@ namespace dxvk { // Create temporary buffer for depth/stencil data VkDeviceSize pixelCount = dstExtent.width * dstExtent.height * dstSubresource.layerCount; - VkDeviceSize dataSizeD = align(pixelCount * imageFormatInfo(dataFormatD)->elementSize, 256); - VkDeviceSize dataSizeS = align(pixelCount * imageFormatInfo(dataFormatS)->elementSize, 256); + VkDeviceSize dataSizeD = align(pixelCount * lookupFormatInfo(dataFormatD)->elementSize, 256); + VkDeviceSize dataSizeS = align(pixelCount * lookupFormatInfo(dataFormatS)->elementSize, 256); DxvkBufferCreateInfo tmpBufferInfo; tmpBufferInfo.size = dataSizeD + dataSizeS; @@ -2189,7 +2189,7 @@ namespace dxvk { VkDeviceSize pitchPerRow, VkDeviceSize pitchPerLayer, VkFormat format) { - auto formatInfo = imageFormatInfo(format); + auto formatInfo = lookupFormatInfo(format); VkExtent3D extent3D; extent3D.width = imageExtent.width; @@ -3144,7 +3144,7 @@ namespace dxvk { // Query pipeline objects to use for this clear operation DxvkMetaClearPipeline pipeInfo = m_common->metaClear().getClearImagePipeline( - imageView->type(), imageFormatInfo(imageView->info().format)->flags); + imageView->type(), lookupFormatInfo(imageView->info().format)->flags); // Create a descriptor set pointing to the view VkDescriptorSet descriptorSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); diff --git a/src/dxvk/dxvk_format.cpp b/src/dxvk/dxvk_format.cpp index 4ec42e6ea..cc4c4adba 100644 --- a/src/dxvk/dxvk_format.cpp +++ b/src/dxvk/dxvk_format.cpp @@ -572,7 +572,7 @@ namespace dxvk { }}; - const DxvkFormatInfo* imageFormatInfo(VkFormat format) { + const DxvkFormatInfo* lookupFormatInfo(VkFormat format) { uint32_t indexOffset = 0; for (const auto& group : g_formatGroups) { diff --git a/src/dxvk/dxvk_format.h b/src/dxvk/dxvk_format.h index 8541508e8..2554fe693 100644 --- a/src/dxvk/dxvk_format.h +++ b/src/dxvk/dxvk_format.h @@ -55,6 +55,6 @@ namespace dxvk { - const DxvkFormatInfo* imageFormatInfo(VkFormat format); + const DxvkFormatInfo* lookupFormatInfo(VkFormat format); } \ No newline at end of file diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index d8b568ac7..34ceaea09 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -191,7 +191,7 @@ namespace dxvk { if (rtColorFormats[i]) { rtInfo.colorAttachmentCount = i + 1; - auto formatInfo = imageFormatInfo(rtColorFormats[i]); + auto formatInfo = lookupFormatInfo(rtColorFormats[i]); cbAttachments[i] = state.omBlend[i].state(); if (!(fsOutputMask & (1 << i)) || !formatInfo) { @@ -222,7 +222,7 @@ namespace dxvk { VkFormat rtDepthFormat = state.rt.getDepthStencilFormat(); if (rtDepthFormat) { - auto rtDepthFormatInfo = imageFormatInfo(rtDepthFormat); + auto rtDepthFormatInfo = lookupFormatInfo(rtDepthFormat); if (rtDepthFormatInfo->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) rtInfo.depthAttachmentFormat = rtDepthFormat; @@ -1145,7 +1145,7 @@ namespace dxvk { // Log render target and blend state auto depthFormat = state.rt.getDepthStencilFormat(); - auto depthFormatInfo = imageFormatInfo(depthFormat); + auto depthFormatInfo = lookupFormatInfo(depthFormat); VkImageAspectFlags writableAspects = depthFormat ? (depthFormatInfo->aspectMask & ~state.rt.getDepthStencilReadOnlyAspects()) diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index b3b8a58e7..314584139 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -202,7 +202,7 @@ namespace dxvk { * \returns Image format info */ const DxvkFormatInfo* formatInfo() const { - return imageFormatInfo(m_info.format); + return lookupFormatInfo(m_info.format); } /** @@ -428,7 +428,7 @@ namespace dxvk { * \returns View format info */ const DxvkFormatInfo* formatInfo() const { - return imageFormatInfo(m_info.format); + return lookupFormatInfo(m_info.format); } /** diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index b724e6331..7f7e11a29 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -299,7 +299,7 @@ namespace dxvk { VkPipeline DxvkMetaCopyObjects::createPipelineObject( const DxvkMetaCopyPipelineKey& key, VkPipelineLayout pipelineLayout) { - auto aspect = imageFormatInfo(key.format)->aspectMask; + auto aspect = lookupFormatInfo(key.format)->aspectMask; std::array stages; uint32_t stageCount = 0; diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index 9eb9ea108..b71b686bc 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -23,7 +23,7 @@ namespace dxvk { VkFormat format) : m_vkd(vkd) { VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; - usageInfo.usage = (imageFormatInfo(format)->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) + usageInfo.usage = (lookupFormatInfo(format)->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT : VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; @@ -207,7 +207,7 @@ namespace dxvk { VkPipeline DxvkMetaResolveObjects::createPipelineObject( const DxvkMetaResolvePipelineKey& key, VkPipelineLayout pipelineLayout) { - auto formatInfo = imageFormatInfo(key.format); + auto formatInfo = lookupFormatInfo(key.format); std::array stages; uint32_t stageCount = 0; diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index 71577b1af..aa5d6848f 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -108,7 +108,7 @@ namespace dxvk { DxvkRtInfo convert() const { VkImageAspectFlags readOnlyAspects = 0; - auto depthFormatInfo = imageFormatInfo(depth.format); + auto depthFormatInfo = lookupFormatInfo(depth.format); if (depth.format && depthFormatInfo) { readOnlyAspects = depthFormatInfo->aspectMask diff --git a/src/dxvk/dxvk_util.cpp b/src/dxvk/dxvk_util.cpp index 508686967..ba689c5ca 100644 --- a/src/dxvk/dxvk_util.cpp +++ b/src/dxvk/dxvk_util.cpp @@ -144,7 +144,7 @@ namespace dxvk::util { VkDeviceSize computeImageDataSize(VkFormat format, VkExtent3D extent) { - const DxvkFormatInfo* formatInfo = imageFormatInfo(format); + const DxvkFormatInfo* formatInfo = lookupFormatInfo(format); VkDeviceSize size = 0; diff --git a/src/dxvk/dxvk_util.h b/src/dxvk/dxvk_util.h index 181e448db..cf26e9c5b 100644 --- a/src/dxvk/dxvk_util.h +++ b/src/dxvk/dxvk_util.h @@ -174,7 +174,7 @@ namespace dxvk::util { */ inline VkExtent3D computeMipLevelExtent(VkExtent3D size, uint32_t level, VkFormat format, VkImageAspectFlags aspect) { if (unlikely(!(aspect & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)))) { - auto plane = &imageFormatInfo(format)->planes[vk::getPlaneIndex(aspect)]; + auto plane = &lookupFormatInfo(format)->planes[vk::getPlaneIndex(aspect)]; size.width /= plane->blockSize.width; size.height /= plane->blockSize.height; } diff --git a/src/dxvk/hud/dxvk_hud.cpp b/src/dxvk/hud/dxvk_hud.cpp index f5e725044..892d5d431 100644 --- a/src/dxvk/hud/dxvk_hud.cpp +++ b/src/dxvk/hud/dxvk_hud.cpp @@ -79,7 +79,7 @@ namespace dxvk::hud { const Rc& ctx, VkSurfaceFormatKHR surfaceFormat, VkExtent2D surfaceSize) { - bool isSrgb = imageFormatInfo(surfaceFormat.format)->flags.test(DxvkFormatFlag::ColorSpaceSrgb); + bool isSrgb = lookupFormatInfo(surfaceFormat.format)->flags.test(DxvkFormatFlag::ColorSpaceSrgb); VkViewport viewport; viewport.x = 0.0f; diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index b02869e36..17e1067a3 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -378,10 +378,10 @@ namespace dxvk::vk { // If that didn't work, we'll fall back to a format // which has similar properties to the preferred one - DxvkFormatFlags prefFlags = imageFormatInfo(pDesired[0].format)->flags; + DxvkFormatFlags prefFlags = lookupFormatInfo(pDesired[0].format)->flags; for (uint32_t j = 0; j < numSupported; j++) { - auto currFlags = imageFormatInfo(pSupported[j].format)->flags; + auto currFlags = lookupFormatInfo(pSupported[j].format)->flags; if ((currFlags & DxvkFormatFlag::ColorSpaceSrgb) == (prefFlags & DxvkFormatFlag::ColorSpaceSrgb)) From fc525d5b702a547a90fe5001463c19d08310268f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 12:17:46 +0200 Subject: [PATCH 0246/1348] [dxvk] Optimize format lookup for simple formats --- src/dxvk/dxvk_format.cpp | 4 ++-- src/dxvk/dxvk_format.h | 34 +++++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/dxvk/dxvk_format.cpp b/src/dxvk/dxvk_format.cpp index cc4c4adba..09fb9087c 100644 --- a/src/dxvk/dxvk_format.cpp +++ b/src/dxvk/dxvk_format.cpp @@ -7,7 +7,7 @@ namespace dxvk { constexpr VkColorComponentFlags RG = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT; constexpr VkColorComponentFlags R = VK_COLOR_COMPONENT_R_BIT; - const std::array g_formatInfos = {{ + const std::array g_formatInfos = {{ // VK_FORMAT_UNDEFINED { }, @@ -572,7 +572,7 @@ namespace dxvk { }}; - const DxvkFormatInfo* lookupFormatInfo(VkFormat format) { + const DxvkFormatInfo* lookupFormatInfoSlow(VkFormat format) { uint32_t indexOffset = 0; for (const auto& group : g_formatGroups) { diff --git a/src/dxvk/dxvk_format.h b/src/dxvk/dxvk_format.h index 2554fe693..383df60c6 100644 --- a/src/dxvk/dxvk_format.h +++ b/src/dxvk/dxvk_format.h @@ -52,9 +52,33 @@ namespace dxvk { /// Plane info for multi-planar formats std::array planes; }; - - - - const DxvkFormatInfo* lookupFormatInfo(VkFormat format); - + + /// Number of formats defined in lookup table + constexpr size_t DxvkFormatCount = 152; + + /// Format lookup table + extern const std::array g_formatInfos; + + /** + * \brief Looks up format info + * + * \param [in] format Format to look up + * \returns Info for the given format + */ + const DxvkFormatInfo* lookupFormatInfoSlow(VkFormat format); + + /** + * \brief Queries image format info + * + * Provides a fast path for the most common base formats. + * \param [in] format Format to look up + * \returns Info for the given format + */ + inline const DxvkFormatInfo* lookupFormatInfo(VkFormat format) { + if (likely(format <= VK_FORMAT_BC7_SRGB_BLOCK)) + return &g_formatInfos[uint32_t(format)]; + else + return lookupFormatInfo(format); + } + } \ No newline at end of file From 35fad0aa6c3279154689923156d90bcd384de56c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 12:18:51 +0200 Subject: [PATCH 0247/1348] [dxvk] Use dynamic vertex strides whenever possible May reduce the number of pipeline permutations, as well as the overhead of the bindVertexBuffer call. --- src/dxvk/dxvk_context.cpp | 67 +++++++++++++++++++++++++--------- src/dxvk/dxvk_context.h | 6 +-- src/dxvk/dxvk_context_state.h | 2 + src/dxvk/dxvk_graphics.cpp | 29 ++++++++++++++- src/dxvk/dxvk_graphics.h | 2 + src/dxvk/dxvk_graphics_state.h | 12 ++++++ 6 files changed, 94 insertions(+), 24 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 2fbaf92f9..19efd460b 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2392,25 +2392,30 @@ namespace dxvk { m_flags.set( DxvkContextFlag::GpDirtyPipelineState, DxvkContextFlag::GpDirtyVertexBuffers); + + for (uint32_t i = 0; i < bindingCount; i++) { + m_state.gp.state.ilBindings[i] = DxvkIlBinding( + bindings[i].binding, 0, bindings[i].inputRate, + bindings[i].fetchRate); + m_state.vi.vertexExtents[bindings[i].binding] = 0; + } + + for (uint32_t i = bindingCount; i < m_state.gp.state.il.bindingCount(); i++) + m_state.gp.state.ilBindings[i] = DxvkIlBinding(); for (uint32_t i = 0; i < attributeCount; i++) { m_state.gp.state.ilAttributes[i] = DxvkIlAttribute( attributes[i].location, attributes[i].binding, attributes[i].format, attributes[i].offset); + + uint32_t extent = attributes[i].offset + lookupFormatInfo(attributes[i].format)->elementSize; + m_state.vi.vertexExtents[attributes[i].binding] = std::max(extent, + m_state.vi.vertexExtents[attributes[i].binding]); } for (uint32_t i = attributeCount; i < m_state.gp.state.il.attributeCount(); i++) m_state.gp.state.ilAttributes[i] = DxvkIlAttribute(); - for (uint32_t i = 0; i < bindingCount; i++) { - m_state.gp.state.ilBindings[i] = DxvkIlBinding( - bindings[i].binding, 0, bindings[i].inputRate, - bindings[i].fetchRate); - } - - for (uint32_t i = bindingCount; i < m_state.gp.state.il.bindingCount(); i++) - m_state.gp.state.ilBindings[i] = DxvkIlBinding(); - m_state.gp.state.il = DxvkIlInfo(attributeCount, bindingCount); } @@ -4484,12 +4489,6 @@ namespace dxvk { bool DxvkContext::updateGraphicsPipelineState(DxvkGlobalPipelineBarrier srcBarrier) { bool oldIndependentSets = m_flags.test(DxvkContextFlag::GpIndependentSets); - // Set up vertex buffer strides for active bindings - for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) { - const uint32_t binding = m_state.gp.state.ilBindings[i].binding(); - m_state.gp.state.ilBindings[i].setStride(m_state.vi.vertexStrides[binding]); - } - // Check which dynamic states need to be active. States that // are not dynamic will be invalidated in the command buffer. m_flags.clr(DxvkContextFlag::GpDynamicBlendConstants, @@ -5074,7 +5073,11 @@ namespace dxvk { std::array buffers; std::array offsets; std::array lengths; + std::array strides; + bool oldDynamicStrides = m_flags.test(DxvkContextFlag::GpDynamicVertexStrides); + bool newDynamicStrides = true; + // Set buffer handles and offsets for active bindings for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) { uint32_t binding = m_state.gp.state.ilBindings[i].binding(); @@ -5085,20 +5088,48 @@ namespace dxvk { buffers[i] = vbo.buffer.buffer; offsets[i] = vbo.buffer.offset; lengths[i] = vbo.buffer.range; - + strides[i] = m_state.vi.vertexStrides[binding]; + + if (strides[i]) { + // Dynamic strides are only allowed if the stride is not smaller + // than highest attribute offset + format size for given binding + newDynamicStrides &= strides[i] >= m_state.vi.vertexExtents[binding]; + } + if (m_vbTracked.set(binding)) m_cmd->trackResource(m_state.vi.vertexBuffers[binding].buffer()); } else { buffers[i] = VK_NULL_HANDLE; offsets[i] = 0; lengths[i] = 0; + strides[i] = 0; } } - + + // If vertex strides are static or if we are switching between static or + // dynamic strides, we'll have to apply them to the pipeline state and + // also sort out our state flags + if (unlikely(!oldDynamicStrides) || unlikely(!newDynamicStrides)) { + m_flags.clr(DxvkContextFlag::GpDynamicVertexStrides); + + for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) { + uint32_t stride = newDynamicStrides ? 0 : strides[i]; + + if (m_state.gp.state.ilBindings[i].stride() != stride) { + m_state.gp.state.ilBindings[i].setStride(stride); + m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + } + } + + if (newDynamicStrides) + m_flags.set(DxvkContextFlag::GpDynamicVertexStrides); + } + // Vertex bindigs get remapped when compiling the // pipeline, so this actually does the right thing m_cmd->cmdBindVertexBuffers(0, m_state.gp.state.il.bindingCount(), - buffers.data(), offsets.data(), lengths.data(), nullptr); + buffers.data(), offsets.data(), lengths.data(), + newDynamicStrides ? strides.data() : nullptr); } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 5f4528124..439170267 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -252,12 +252,8 @@ namespace dxvk { m_vbTracked.clr(binding); m_state.vi.vertexBuffers[binding] = buffer; + m_state.vi.vertexStrides[binding] = stride; m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers); - - if (unlikely(m_state.vi.vertexStrides[binding] != stride)) { - m_state.vi.vertexStrides[binding] = stride; - m_flags.set(DxvkContextFlag::GpDirtyPipelineState); - } } /** diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 8fffb5545..c80f93817 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -41,6 +41,7 @@ namespace dxvk { GpDynamicDepthBounds, ///< Depth bounds are dynamic GpDynamicStencilRef, ///< Stencil reference is dynamic GpDynamicRasterizerState, ///< Cull mode and front face are dynamic + GpDynamicVertexStrides, ///< Vertex buffer strides are dynamic GpIndependentSets, ///< Graphics pipeline layout was created with independent sets CpDirtyPipeline, ///< Compute pipeline binding are out of date @@ -89,6 +90,7 @@ namespace dxvk { std::array vertexBuffers = { }; std::array vertexStrides = { }; + std::array vertexExtents = { }; }; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 34ceaea09..16fcf34a9 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -67,6 +67,21 @@ namespace dxvk { } + bool DxvkGraphicsPipelineVertexInputState::useDynamicVertexStrides() const { + if (!viInfo.vertexBindingDescriptionCount) + return false; + + // The backend will set all strides to 0 if dynamic strides are + // allowed, since the restrictions only apply to non-zero strides + bool dynamicStride = true; + + for (uint32_t i = 0; i < viInfo.vertexBindingDescriptionCount && dynamicStride; i++) + dynamicStride = !viBindings[i].stride; + + return dynamicStride; + } + + bool DxvkGraphicsPipelineVertexInputState::eq(const DxvkGraphicsPipelineVertexInputState& other) const { bool eq = iaInfo.topology == other.iaInfo.topology && iaInfo.primitiveRestartEnable == other.iaInfo.primitiveRestartEnable @@ -141,6 +156,14 @@ namespace dxvk { : m_device(device) { auto vk = m_device->vkd(); + VkDynamicState dynamicState = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE; + VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + + if (state.useDynamicVertexStrides()) { + dyInfo.dynamicStateCount = 1; + dyInfo.pDynamicStates = &dynamicState; + } + VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT }; libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT; @@ -148,6 +171,7 @@ namespace dxvk { info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; info.pVertexInputState = &state.viInfo; info.pInputAssemblyState = &state.iaInfo; + info.pDynamicState = &dyInfo; info.basePipelineIndex = -1; VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), @@ -766,12 +790,15 @@ namespace dxvk { auto vk = m_device->vkd(); // Set up dynamic states as needed - std::array dynamicStates; + std::array dynamicStates; uint32_t dynamicStateCount = 0; dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT; dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT; + if (state.useDynamicVertexStrides()) + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE; + if (state.useDynamicDepthBias()) dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 21631d3f4..446c90f38 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -43,6 +43,8 @@ namespace dxvk { std::array viDivisors = { }; std::array viAttributes = { }; + bool useDynamicVertexStrides() const; + bool eq(const DxvkGraphicsPipelineVertexInputState& other) const; size_t hash() const; diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 25fd921a2..1906848ec 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -731,6 +731,18 @@ namespace dxvk { return ds.enableDepthBoundsTest(); } + bool useDynamicVertexStrides() const { + if (!il.bindingCount()) + return false; + + bool result = true; + + for (uint32_t i = 0; i < il.bindingCount() && result; i++) + result = !ilBindings[i].stride(); + + return result; + } + bool useDynamicBlendConstants() const { bool result = false; From 2fee9595155cdacf54506d5b2bafc7535eb2ab94 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 12:22:22 +0200 Subject: [PATCH 0248/1348] [dxvk] Bump state cache format to v15 --- src/dxvk/dxvk_state_cache.cpp | 10 +++++++++- src/dxvk/dxvk_state_cache_types.h | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 63a982c3e..31800cb27 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -105,7 +105,15 @@ namespace dxvk { return true; } - return read(data); + if (!read(data)) + return false; + + // Format hasn't changed, but we introduced + // dynamic vertex strides in the meantime + if (version < 15) + data.setStride(0); + + return true; } diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index aa5d6848f..e12ca5d07 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -52,7 +52,7 @@ namespace dxvk { */ struct DxvkStateCacheHeader { char magic[4] = { 'D', 'X', 'V', 'K' }; - uint32_t version = 14; + uint32_t version = 15; uint32_t entrySize = 0; /* no longer meaningful */ }; From 46a596dd846c2675c8779e6c580da97bce65cf31 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 13:22:03 +0200 Subject: [PATCH 0249/1348] [dxvk] Normalize vertex input state using vertex shader input mask Filters out unused bindings and attributes when creating Vulkan pipelines. --- src/dxvk/dxvk_graphics.cpp | 95 ++++++++++++++++++++++---------------- src/dxvk/dxvk_graphics.h | 5 +- 2 files changed, 57 insertions(+), 43 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 16fcf34a9..292df4cc9 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -17,68 +17,79 @@ namespace dxvk { DxvkGraphicsPipelineVertexInputState::DxvkGraphicsPipelineVertexInputState( const DxvkDevice* device, - const DxvkGraphicsPipelineStateInfo& state) { + const DxvkGraphicsPipelineStateInfo& state, + const DxvkShader* vs) { std::array viBindingMap = { }; iaInfo.topology = state.ia.primitiveTopology(); iaInfo.primitiveRestartEnable = state.ia.primitiveRestart(); - viInfo.vertexBindingDescriptionCount = state.il.bindingCount(); - viInfo.vertexAttributeDescriptionCount = state.il.attributeCount(); + uint32_t attrMask = vs->info().inputMask; + uint32_t bindingMask = 0; + + // Find out which bindings are used based on the attribute mask + for (uint32_t i = 0; i < state.il.attributeCount(); i++) { + if (attrMask & (1u << state.ilAttributes[i].location())) + bindingMask |= 1u << state.ilAttributes[i].binding(); + } // Process vertex bindings. We will compact binding numbers on // the fly so that vertex buffers can be updated more easily. + uint32_t bindingCount = 0; + for (uint32_t i = 0; i < state.il.bindingCount(); i++) { - viBindingMap[state.ilBindings[i].binding()] = i; + uint32_t bindingIndex = state.ilBindings[i].binding(); - viBindings[i].binding = i; - viBindings[i].stride = state.ilBindings[i].stride(); - viBindings[i].inputRate = state.ilBindings[i].inputRate(); + if (bindingMask & (1u << bindingIndex)) { + viBindingMap[bindingIndex] = i; - if (state.ilBindings[i].inputRate() == VK_VERTEX_INPUT_RATE_INSTANCE - && state.ilBindings[i].divisor() != 1) { - uint32_t index = viDivisorInfo.vertexBindingDivisorCount++; + VkVertexInputBindingDescription& binding = viBindings[bindingCount++]; + binding.binding = i; + binding.stride = state.ilBindings[i].stride(); + binding.inputRate = state.ilBindings[i].inputRate(); - viDivisors[index].binding = i; - viDivisors[index].divisor = state.ilBindings[i].divisor(); + if (state.ilBindings[i].inputRate() == VK_VERTEX_INPUT_RATE_INSTANCE + && state.ilBindings[i].divisor() != 1) { + VkVertexInputBindingDivisorDescriptionEXT& divisor = viDivisors[viDivisorInfo.vertexBindingDivisorCount++]; + divisor.binding = i; + divisor.divisor = state.ilBindings[i].divisor(); + } } } - if (viInfo.vertexBindingDescriptionCount) + if (bindingCount) { + bool supportsDivisor = device->features().extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor; + + viInfo.vertexBindingDescriptionCount = bindingCount; viInfo.pVertexBindingDescriptions = viBindings.data(); - if (viDivisorInfo.vertexBindingDivisorCount) { - viDivisorInfo.pVertexBindingDivisors = viDivisors.data(); - - if (device->features().extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor) + if (viDivisorInfo.vertexBindingDivisorCount && supportsDivisor) { + viDivisorInfo.pVertexBindingDivisors = viDivisors.data(); viInfo.pNext = &viDivisorInfo; + } } - // Process vertex attributes, using binding map generated above + // Process vertex attributes, filtering out unused ones + uint32_t attrCount = 0; + for (uint32_t i = 0; i < state.il.attributeCount(); i++) { - viAttributes[i].location = state.ilAttributes[i].location(); - viAttributes[i].binding = viBindingMap[state.ilAttributes[i].binding()]; - viAttributes[i].format = state.ilAttributes[i].format(); - viAttributes[i].offset = state.ilAttributes[i].offset(); + if (attrMask & (1u << state.ilAttributes[i].location())) { + VkVertexInputAttributeDescription& attr = viAttributes[attrCount++]; + attr.location = state.ilAttributes[i].location(); + attr.binding = viBindingMap[state.ilAttributes[i].binding()]; + attr.format = state.ilAttributes[i].format(); + attr.offset = state.ilAttributes[i].offset(); + } } - if (viInfo.vertexAttributeDescriptionCount) + if (attrCount) { + viInfo.vertexAttributeDescriptionCount = attrCount; viInfo.pVertexAttributeDescriptions = viAttributes.data(); - } + } - - bool DxvkGraphicsPipelineVertexInputState::useDynamicVertexStrides() const { - if (!viInfo.vertexBindingDescriptionCount) - return false; - - // The backend will set all strides to 0 if dynamic strides are - // allowed, since the restrictions only apply to non-zero strides - bool dynamicStride = true; - - for (uint32_t i = 0; i < viInfo.vertexBindingDescriptionCount && dynamicStride; i++) - dynamicStride = !viBindings[i].stride; - - return dynamicStride; + // We need to be consistent with the pipeline state vector since + // the normalized state may otherwise change beavhiour here. + viUseDynamicVertexStrides = state.useDynamicVertexStrides(); } @@ -87,7 +98,8 @@ namespace dxvk { && iaInfo.primitiveRestartEnable == other.iaInfo.primitiveRestartEnable && viInfo.vertexBindingDescriptionCount == other.viInfo.vertexBindingDescriptionCount && viInfo.vertexAttributeDescriptionCount == other.viInfo.vertexAttributeDescriptionCount - && viDivisorInfo.vertexBindingDivisorCount == other.viDivisorInfo.vertexBindingDivisorCount; + && viDivisorInfo.vertexBindingDivisorCount == other.viDivisorInfo.vertexBindingDivisorCount + && viUseDynamicVertexStrides == other.viUseDynamicVertexStrides; for (uint32_t i = 0; i < viInfo.vertexBindingDescriptionCount && eq; i++) { const auto& a = viBindings[i]; @@ -127,6 +139,7 @@ namespace dxvk { hash.add(uint32_t(viInfo.vertexBindingDescriptionCount)); hash.add(uint32_t(viInfo.vertexAttributeDescriptionCount)); hash.add(uint32_t(viDivisorInfo.vertexBindingDivisorCount)); + hash.add(uint32_t(viUseDynamicVertexStrides)); for (uint32_t i = 0; i < viInfo.vertexBindingDescriptionCount; i++) { hash.add(uint32_t(viBindings[i].binding)); @@ -159,7 +172,7 @@ namespace dxvk { VkDynamicState dynamicState = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE; VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; - if (state.useDynamicVertexStrides()) { + if (state.viUseDynamicVertexStrides) { dyInfo.dynamicStateCount = 1; dyInfo.pDynamicStates = &dynamicState; } @@ -652,7 +665,7 @@ namespace dxvk { if (!fastHandle) { // If that didn't succeed, link a pipeline using the // pre-compiled fragment and vertex shader libraries. - DxvkGraphicsPipelineVertexInputState viState(m_device, state); + DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr()); DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); DxvkGraphicsPipelineBaseInstanceKey key; @@ -853,7 +866,7 @@ namespace dxvk { stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, state), &specInfo); } - DxvkGraphicsPipelineVertexInputState viState(m_device, state); + DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr()); DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr()); DxvkGraphicsPipelineFragmentShaderState fsState(m_device, state); DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 446c90f38..2c85abdc4 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -33,7 +33,8 @@ namespace dxvk { DxvkGraphicsPipelineVertexInputState( const DxvkDevice* device, - const DxvkGraphicsPipelineStateInfo& state); + const DxvkGraphicsPipelineStateInfo& state, + const DxvkShader* vs); VkPipelineInputAssemblyStateCreateInfo iaInfo = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; VkPipelineVertexInputStateCreateInfo viInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; @@ -43,7 +44,7 @@ namespace dxvk { std::array viDivisors = { }; std::array viAttributes = { }; - bool useDynamicVertexStrides() const; + VkBool32 viUseDynamicVertexStrides = VK_FALSE; bool eq(const DxvkGraphicsPipelineVertexInputState& other) const; From 661a8cd258b8598dddc9491ba2a2ec3c87549119 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 16:47:08 +0200 Subject: [PATCH 0250/1348] [dxvk] Be consistent about enabling dynamic blend constants --- src/dxvk/dxvk_graphics.cpp | 23 +++++++---------------- src/dxvk/dxvk_graphics.h | 6 +++--- src/dxvk/dxvk_graphics_state.h | 2 +- 3 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 292df4cc9..b29d52bda 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -285,21 +285,10 @@ namespace dxvk { msSampleMask = state.ms.sampleMask() & ((1u << msInfo.rasterizationSamples) - 1); msInfo.pSampleMask = &msSampleMask; msInfo.alphaToCoverageEnable = state.ms.enableAlphaToCoverage(); - } - - bool DxvkGraphicsPipelineFragmentOutputState::useDynamicBlendConstants() const { - bool result = false; - - for (uint32_t i = 0; i < MaxNumRenderTargets && !result; i++) { - result = cbAttachments[i].blendEnable - && (util::isBlendConstantBlendFactor(cbAttachments[i].srcColorBlendFactor) - || util::isBlendConstantBlendFactor(cbAttachments[i].dstColorBlendFactor) - || util::isBlendConstantBlendFactor(cbAttachments[i].srcAlphaBlendFactor) - || util::isBlendConstantBlendFactor(cbAttachments[i].dstAlphaBlendFactor)); - } - - return result; + // We need to be fully consistent with the pipeline state here, and + // while we could consistently infer it, just don't take any chances + cbUseDynamicBlendConstants = state.useDynamicBlendConstants(); } @@ -315,7 +304,8 @@ namespace dxvk { && msInfo.minSampleShading == other.msInfo.minSampleShading && msInfo.alphaToCoverageEnable == other.msInfo.alphaToCoverageEnable && msInfo.alphaToOneEnable == other.msInfo.alphaToOneEnable - && msSampleMask == other.msSampleMask; + && msSampleMask == other.msSampleMask + && cbUseDynamicBlendConstants == other.cbUseDynamicBlendConstants; for (uint32_t i = 0; i < rtInfo.colorAttachmentCount && eq; i++) eq = rtColorFormats[i] == other.rtColorFormats[i]; @@ -353,6 +343,7 @@ namespace dxvk { hash.add(uint32_t(msInfo.alphaToCoverageEnable)); hash.add(uint32_t(msInfo.alphaToOneEnable)); hash.add(uint32_t(msSampleMask)); + hash.add(uint32_t(cbUseDynamicBlendConstants)); for (uint32_t i = 0; i < rtInfo.colorAttachmentCount; i++) hash.add(uint32_t(rtColorFormats[i])); @@ -384,7 +375,7 @@ namespace dxvk { VkDynamicState dynamicState = VK_DYNAMIC_STATE_BLEND_CONSTANTS; VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; - if (state.useDynamicBlendConstants()) { + if (state.cbUseDynamicBlendConstants) { dyInfo.dynamicStateCount = 1; dyInfo.pDynamicStates = &dynamicState; } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 2c85abdc4..991ba1c97 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -99,12 +99,12 @@ namespace dxvk { VkPipelineColorBlendStateCreateInfo cbInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; VkPipelineMultisampleStateCreateInfo msInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; - uint32_t msSampleMask = 0u; + uint32_t msSampleMask = 0u; + VkBool32 cbUseDynamicBlendConstants = VK_FALSE; + std::array cbAttachments = { }; std::array rtColorFormats = { }; - bool useDynamicBlendConstants() const; - bool eq(const DxvkGraphicsPipelineFragmentOutputState& other) const; size_t hash() const; diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 1906848ec..7e10c0d07 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -747,7 +747,7 @@ namespace dxvk { bool result = false; for (uint32_t i = 0; i < MaxNumRenderTargets && !result; i++) { - result |= omBlend[i].blendEnable() + result |= rt.getColorFormat(i) && omBlend[i].blendEnable() && (util::isBlendConstantBlendFactor(omBlend[i].srcColorBlendFactor()) || util::isBlendConstantBlendFactor(omBlend[i].dstColorBlendFactor()) || util::isBlendConstantBlendFactor(omBlend[i].srcAlphaBlendFactor()) From 9e7b93b55b714b73085805cab0ceef0ea082231c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 19:32:03 +0200 Subject: [PATCH 0251/1348] [dxvk] Fix infinite recursion caused by rebase derp --- src/dxvk/dxvk_format.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_format.h b/src/dxvk/dxvk_format.h index 383df60c6..5697ee9a3 100644 --- a/src/dxvk/dxvk_format.h +++ b/src/dxvk/dxvk_format.h @@ -78,7 +78,7 @@ namespace dxvk { if (likely(format <= VK_FORMAT_BC7_SRGB_BLOCK)) return &g_formatInfos[uint32_t(format)]; else - return lookupFormatInfo(format); + return lookupFormatInfoSlow(format); } } \ No newline at end of file From e2340d722434619214c6651e95a7ab987db50896 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 23:51:04 +0200 Subject: [PATCH 0252/1348] [dxvk] Fix dual-source blending with multiple bound render targets We can't write to more than one render target, so zero out the write mask. Also, normalize blend state for disabled render targets for good measure. --- src/dxvk/dxvk_graphics.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index b29d52bda..5a57b1ba5 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -215,6 +215,10 @@ namespace dxvk { // mask for any attachment that the fragment shader does not write to. uint32_t fsOutputMask = fs ? fs->info().outputMask : 0u; + // Dual-source blending can only write to one render target + if (state.useDualSourceBlending()) + fsOutputMask &= 0x1; + const VkColorComponentFlags rgbaWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; @@ -229,20 +233,23 @@ namespace dxvk { rtInfo.colorAttachmentCount = i + 1; auto formatInfo = lookupFormatInfo(rtColorFormats[i]); - cbAttachments[i] = state.omBlend[i].state(); - if (!(fsOutputMask & (1 << i)) || !formatInfo) { - cbAttachments[i].colorWriteMask = 0; - } else { - if (cbAttachments[i].colorWriteMask != rgbaWriteMask) { - cbAttachments[i].colorWriteMask = util::remapComponentMask( + if ((fsOutputMask & (1 << i)) && formatInfo) { + VkColorComponentFlags writeMask = state.omBlend[i].colorWriteMask(); + + if (writeMask != rgbaWriteMask) { + writeMask = util::remapComponentMask( state.omBlend[i].colorWriteMask(), state.omSwizzle[i].mapping()); } - cbAttachments[i].colorWriteMask &= formatInfo->componentMask; + writeMask &= formatInfo->componentMask; - if (cbAttachments[i].colorWriteMask == formatInfo->componentMask) { - cbAttachments[i].colorWriteMask = rgbaWriteMask; + if (writeMask == formatInfo->componentMask) + writeMask = rgbaWriteMask; + + if (writeMask) { + cbAttachments[i] = state.omBlend[i].state(); + cbAttachments[i].colorWriteMask = writeMask; } } } From 2fabc90f4603f406610b205dd65041f756767b1b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 16 Jul 2022 13:21:44 +0200 Subject: [PATCH 0253/1348] [dxvk] Add fast path for rasterizer state comparison --- src/dxvk/dxvk_context.cpp | 19 ++++++++----------- src/dxvk/dxvk_graphics_state.h | 4 ++++ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 19efd460b..81ec35e2c 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2428,19 +2428,16 @@ namespace dxvk { m_flags.set(DxvkContextFlag::GpDirtyRasterizerState); } - if (m_state.gp.state.rs.depthClipEnable() != rs.depthClipEnable - || m_state.gp.state.rs.depthBiasEnable() != rs.depthBiasEnable - || m_state.gp.state.rs.polygonMode() != rs.polygonMode - || m_state.gp.state.rs.sampleCount() != rs.sampleCount - || m_state.gp.state.rs.conservativeMode() != rs.conservativeMode) { - m_state.gp.state.rs = DxvkRsInfo( - rs.depthClipEnable, - rs.depthBiasEnable, - rs.polygonMode, - rs.sampleCount, - rs.conservativeMode); + DxvkRsInfo rsInfo( + rs.depthClipEnable, + rs.depthBiasEnable, + rs.polygonMode, + rs.sampleCount, + rs.conservativeMode); + if (!m_state.gp.state.rs.eq(rsInfo)) { m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + m_state.gp.state.rs = rsInfo; } } diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 7e10c0d07..918f558b5 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -250,6 +250,10 @@ namespace dxvk { return VkConservativeRasterizationModeEXT(m_conservativeMode); } + bool eq(const DxvkRsInfo& other) const { + return !std::memcmp(this, &other, sizeof(*this)); + } + private: uint16_t m_depthClipEnable : 1; From dadc1bc8ffe58dde7cdf66b37b3b248cbe5b8b23 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 16 Jul 2022 13:25:19 +0200 Subject: [PATCH 0254/1348] [dxvk] Add dirty tracking for dynamic depth-stencil state Significantly reduces the number of API calls and potentially context rolls when switching between different base pipelines. --- src/dxvk/dxvk_context.cpp | 118 +++++++++++++++++++-------------- src/dxvk/dxvk_context_state.h | 2 + src/dxvk/dxvk_graphics.cpp | 23 +++---- src/dxvk/dxvk_graphics_state.h | 4 +- 4 files changed, 84 insertions(+), 63 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 81ec35e2c..047cb80cd 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -100,6 +100,7 @@ namespace dxvk { DxvkContextFlag::GpDirtyViewport, DxvkContextFlag::GpDirtyDepthBias, DxvkContextFlag::GpDirtyDepthBounds, + DxvkContextFlag::GpDirtyDepthStencilState, DxvkContextFlag::CpDirtyPipeline, DxvkContextFlag::CpDirtyPipelineState, DxvkContextFlag::DirtyDrawBuffer); @@ -2437,6 +2438,12 @@ namespace dxvk { if (!m_state.gp.state.rs.eq(rsInfo)) { m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + + // Since depth bias enable is only dynamic for base pipelines, + // it is applied as part of the dynamic depth-stencil state + if (m_state.gp.state.rs.depthBiasEnable() != rs.depthBiasEnable) + m_flags.set(DxvkContextFlag::GpDirtyDepthStencilState); + m_state.gp.state.rs = rsInfo; } } @@ -2463,7 +2470,9 @@ namespace dxvk { m_state.gp.state.dsFront = DxvkDsStencilOp(ds.stencilOpFront); m_state.gp.state.dsBack = DxvkDsStencilOp(ds.stencilOpBack); - m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + m_flags.set( + DxvkContextFlag::GpDirtyPipelineState, + DxvkContextFlag::GpDirtyDepthStencilState); } @@ -4015,6 +4024,7 @@ namespace dxvk { DxvkContextFlag::GpDirtyViewport, DxvkContextFlag::GpDirtyDepthBias, DxvkContextFlag::GpDirtyDepthBounds, + DxvkContextFlag::GpDirtyDepthStencilState, DxvkContextFlag::DirtyPushConstants); m_flags.clr( @@ -4440,7 +4450,8 @@ namespace dxvk { DxvkContextFlag::GpDirtyRasterizerState, DxvkContextFlag::GpDirtyViewport, DxvkContextFlag::GpDirtyDepthBias, - DxvkContextFlag::GpDirtyDepthBounds); + DxvkContextFlag::GpDirtyDepthBounds, + DxvkContextFlag::GpDirtyDepthStencilState); m_state.gp.pipeline = nullptr; } @@ -4489,6 +4500,7 @@ namespace dxvk { // Check which dynamic states need to be active. States that // are not dynamic will be invalidated in the command buffer. m_flags.clr(DxvkContextFlag::GpDynamicBlendConstants, + DxvkContextFlag::GpDynamicDepthStencilState, DxvkContextFlag::GpDynamicDepthBias, DxvkContextFlag::GpDynamicDepthBounds, DxvkContextFlag::GpDynamicStencilRef, @@ -4499,18 +4511,6 @@ namespace dxvk { ? DxvkContextFlag::GpDynamicBlendConstants : DxvkContextFlag::GpDirtyBlendConstants); - m_flags.set(m_state.gp.state.useDynamicDepthBias() - ? DxvkContextFlag::GpDynamicDepthBias - : DxvkContextFlag::GpDirtyDepthBias); - - m_flags.set(m_state.gp.state.useDynamicDepthBounds() - ? DxvkContextFlag::GpDynamicDepthBounds - : DxvkContextFlag::GpDirtyDepthBounds); - - m_flags.set(m_state.gp.state.useDynamicStencilRef() - ? DxvkContextFlag::GpDynamicStencilRef - : DxvkContextFlag::GpDirtyStencilRef); - m_flags.set((!m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasRasterizerDiscard)) ? DxvkContextFlag::GpDynamicRasterizerState : DxvkContextFlag::GpDirtyRasterizerState); @@ -4525,43 +4525,31 @@ namespace dxvk { VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineInfo.first); - // For pipelines created from graphics pipeline libraries, we need - // to apply a bunch of dynamic state that is otherwise static + // For pipelines created from graphics pipeline libraries, we need to + // apply a bunch of dynamic state that is otherwise static or unused if (pipelineInfo.second == DxvkGraphicsPipelineType::BasePipeline) { - VkImageAspectFlags dsReadOnlyAspects = m_state.gp.state.rt.getDepthStencilReadOnlyAspects(); - - m_cmd->cmdSetDepthState( - m_state.gp.state.ds.enableDepthTest(), - m_state.gp.state.ds.enableDepthWrite() && - !(dsReadOnlyAspects & VK_IMAGE_ASPECT_DEPTH_BIT), - m_state.gp.state.ds.depthCompareOp()); - - if (m_device->features().core.features.depthBounds) { - m_cmd->cmdSetDepthBoundsState( - m_state.gp.state.ds.enableDepthBoundsTest()); - - m_flags.set(DxvkContextFlag::GpDynamicDepthBounds); - } - - VkStencilOpState dsFront = m_state.gp.state.dsFront.state(); - VkStencilOpState dsBack = m_state.gp.state.dsBack.state(); - - if (dsReadOnlyAspects & VK_IMAGE_ASPECT_STENCIL_BIT) { - dsFront.writeMask = 0; - dsBack.writeMask = 0; - } - - m_cmd->cmdSetStencilState( - m_state.gp.state.ds.enableStencilTest(), - dsFront, dsBack); - - m_cmd->cmdSetDepthBiasState( - m_state.gp.state.rs.depthBiasEnable()); - m_flags.set( + DxvkContextFlag::GpDynamicDepthStencilState, DxvkContextFlag::GpDynamicDepthBias, DxvkContextFlag::GpDynamicStencilRef, DxvkContextFlag::GpIndependentSets); + + if (m_device->features().core.features.depthBounds) + m_flags.set(DxvkContextFlag::GpDynamicDepthBounds); + } else { + m_flags.set(m_state.gp.state.useDynamicDepthBias() + ? DxvkContextFlag::GpDynamicDepthBias + : DxvkContextFlag::GpDirtyDepthBias); + + m_flags.set(m_state.gp.state.useDynamicDepthBounds() + ? DxvkContextFlag::GpDynamicDepthBounds + : DxvkContextFlag::GpDirtyDepthBounds); + + m_flags.set(m_state.gp.state.useDynamicStencilRef() + ? DxvkContextFlag::GpDynamicStencilRef + : DxvkContextFlag::GpDirtyStencilRef); + + m_flags.set(DxvkContextFlag::GpDirtyDepthStencilState); } // If necessary, dirty descriptor sets due to layout incompatibilities @@ -5181,6 +5169,39 @@ namespace dxvk { m_cmd->cmdSetScissor(m_state.vp.viewportCount, m_state.vp.scissorRects.data()); } + if (m_flags.all(DxvkContextFlag::GpDirtyDepthStencilState, + DxvkContextFlag::GpDynamicDepthStencilState)) { + m_flags.clr(DxvkContextFlag::GpDirtyDepthStencilState); + + // Make sure to not enable writes to aspects that cannot be + // written in the current depth-stencil attachment layout. + // This mirrors what we do for monolithic pipelines. + VkImageAspectFlags dsReadOnlyAspects = m_state.gp.state.rt.getDepthStencilReadOnlyAspects(); + + bool enableDepthWrites = !(dsReadOnlyAspects & VK_IMAGE_ASPECT_DEPTH_BIT); + bool enableStencilWrites = !(dsReadOnlyAspects & VK_IMAGE_ASPECT_STENCIL_BIT); + + m_cmd->cmdSetDepthState( + m_state.gp.state.ds.enableDepthTest(), + m_state.gp.state.ds.enableDepthWrite() && enableDepthWrites, + m_state.gp.state.ds.depthCompareOp()); + + if (m_device->features().core.features.depthBounds) { + m_cmd->cmdSetDepthBoundsState( + m_state.gp.state.ds.enableDepthBoundsTest()); + + m_flags.set(DxvkContextFlag::GpDynamicDepthBounds); + } + + m_cmd->cmdSetStencilState( + m_state.gp.state.ds.enableStencilTest(), + m_state.gp.state.dsFront.state(enableStencilWrites), + m_state.gp.state.dsBack.state(enableStencilWrites)); + + m_cmd->cmdSetDepthBiasState( + m_state.gp.state.rs.depthBiasEnable()); + } + if (m_flags.all(DxvkContextFlag::GpDirtyRasterizerState, DxvkContextFlag::GpDynamicRasterizerState)) { m_flags.clr(DxvkContextFlag::GpDirtyRasterizerState); @@ -5333,10 +5354,11 @@ namespace dxvk { if (m_flags.any( DxvkContextFlag::GpDirtyViewport, DxvkContextFlag::GpDirtyBlendConstants, - DxvkContextFlag::GpDirtyStencilRef, DxvkContextFlag::GpDirtyDepthBias, DxvkContextFlag::GpDirtyDepthBounds, - DxvkContextFlag::GpDirtyRasterizerState)) + DxvkContextFlag::GpDirtyDepthStencilState, + DxvkContextFlag::GpDirtyRasterizerState, + DxvkContextFlag::GpDirtyStencilRef)) this->updateDynamicState(); if (m_flags.test(DxvkContextFlag::DirtyPushConstants)) diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index c80f93817..11dab5518 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -31,12 +31,14 @@ namespace dxvk { GpDirtyIndexBuffer, ///< Index buffer binding are out of date GpDirtyXfbBuffers, ///< Transform feedback buffer bindings are out of date GpDirtyBlendConstants, ///< Blend constants have changed + GpDirtyDepthStencilState, ///< Depth-stencil state has changed GpDirtyDepthBias, ///< Depth bias has changed GpDirtyDepthBounds, ///< Depth bounds have changed GpDirtyStencilRef, ///< Stencil reference has changed GpDirtyRasterizerState, ///< Cull mode and front face have changed GpDirtyViewport, ///< Viewport state has changed GpDynamicBlendConstants, ///< Blend constants are dynamic + GpDynamicDepthStencilState, ///< Depth-stencil state is dynamic GpDynamicDepthBias, ///< Depth bias is dynamic GpDynamicDepthBounds, ///< Depth bounds are dynamic GpDynamicStencilRef, ///< Stencil reference is dynamic diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 5a57b1ba5..229627d73 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -470,21 +470,18 @@ namespace dxvk { DxvkGraphicsPipelineFragmentShaderState::DxvkGraphicsPipelineFragmentShaderState( const DxvkDevice* device, const DxvkGraphicsPipelineStateInfo& state) { + VkImageAspectFlags dsReadOnlyAspects = state.rt.getDepthStencilReadOnlyAspects(); + + bool enableDepthWrites = !(dsReadOnlyAspects & VK_IMAGE_ASPECT_DEPTH_BIT); + bool enableStencilWrites = !(dsReadOnlyAspects & VK_IMAGE_ASPECT_STENCIL_BIT); + dsInfo.depthTestEnable = state.ds.enableDepthTest(); - dsInfo.depthWriteEnable = state.ds.enableDepthWrite(); + dsInfo.depthWriteEnable = state.ds.enableDepthWrite() && enableDepthWrites; dsInfo.depthCompareOp = state.ds.depthCompareOp(); dsInfo.depthBoundsTestEnable = state.ds.enableDepthBoundsTest(); dsInfo.stencilTestEnable = state.ds.enableStencilTest(); - dsInfo.front = state.dsFront.state(); - dsInfo.back = state.dsBack.state(); - - if ((state.rt.getDepthStencilReadOnlyAspects() & VK_IMAGE_ASPECT_DEPTH_BIT)) - dsInfo.depthWriteEnable = VK_FALSE; - - if ((state.rt.getDepthStencilReadOnlyAspects() & VK_IMAGE_ASPECT_STENCIL_BIT)) { - dsInfo.front.writeMask = 0; - dsInfo.back.writeMask = 0; - } + dsInfo.front = state.dsFront.state(enableStencilWrites); + dsInfo.back = state.dsBack.state(enableStencilWrites); } @@ -1162,8 +1159,8 @@ namespace dxvk { if (state.ds.enableStencilTest()) { std::array states = {{ - state.dsFront.state(), - state.dsBack.state(), + state.dsFront.state(true), + state.dsBack.state(true), }}; for (size_t i = 0; i < states.size(); i++) { diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 918f558b5..133e0d68a 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -395,14 +395,14 @@ namespace dxvk { m_compareMask (uint32_t(state.compareMask)), m_writeMask (uint32_t(state.writeMask)) { } - VkStencilOpState state() const { + VkStencilOpState state(bool write) const { VkStencilOpState result; result.failOp = VkStencilOp(m_failOp); result.passOp = VkStencilOp(m_passOp); result.depthFailOp = VkStencilOp(m_depthFailOp); result.compareOp = VkCompareOp(m_compareOp); result.compareMask = m_compareMask; - result.writeMask = m_writeMask; + result.writeMask = write ? m_writeMask : 0; result.reference = 0; return result; } From 39dd25e972c28564571a82089a36bc7b84c79071 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 16 Jul 2022 14:47:54 +0200 Subject: [PATCH 0255/1348] [dxvk] Unconditionally call updateDynamicState And optimize that instead. The previous check would always succeed anyway since we'd set unused dynamic states to dirty, which is necessary for us to update that state once it's actually used by a pipeline. --- src/dxvk/dxvk_context.cpp | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 047cb80cd..e5a520fc6 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5162,15 +5162,15 @@ namespace dxvk { void DxvkContext::updateDynamicState() { - if (m_flags.test(DxvkContextFlag::GpDirtyViewport)) { + if (unlikely(m_flags.test(DxvkContextFlag::GpDirtyViewport))) { m_flags.clr(DxvkContextFlag::GpDirtyViewport); m_cmd->cmdSetViewport(m_state.vp.viewportCount, m_state.vp.viewports.data()); m_cmd->cmdSetScissor(m_state.vp.viewportCount, m_state.vp.scissorRects.data()); } - if (m_flags.all(DxvkContextFlag::GpDirtyDepthStencilState, - DxvkContextFlag::GpDynamicDepthStencilState)) { + if (unlikely(m_flags.all(DxvkContextFlag::GpDirtyDepthStencilState, + DxvkContextFlag::GpDynamicDepthStencilState))) { m_flags.clr(DxvkContextFlag::GpDirtyDepthStencilState); // Make sure to not enable writes to aspects that cannot be @@ -5202,6 +5202,12 @@ namespace dxvk { m_state.gp.state.rs.depthBiasEnable()); } + if (unlikely(m_flags.all(DxvkContextFlag::GpDirtyBlendConstants, + DxvkContextFlag::GpDynamicBlendConstants))) { + m_flags.clr(DxvkContextFlag::GpDirtyBlendConstants); + m_cmd->cmdSetBlendConstants(&m_state.dyn.blendConstants.r); + } + if (m_flags.all(DxvkContextFlag::GpDirtyRasterizerState, DxvkContextFlag::GpDynamicRasterizerState)) { m_flags.clr(DxvkContextFlag::GpDirtyRasterizerState); @@ -5211,12 +5217,6 @@ namespace dxvk { m_state.dyn.frontFace); } - if (m_flags.all(DxvkContextFlag::GpDirtyBlendConstants, - DxvkContextFlag::GpDynamicBlendConstants)) { - m_flags.clr(DxvkContextFlag::GpDirtyBlendConstants); - m_cmd->cmdSetBlendConstants(&m_state.dyn.blendConstants.r); - } - if (m_flags.all(DxvkContextFlag::GpDirtyStencilRef, DxvkContextFlag::GpDynamicStencilRef)) { m_flags.clr(DxvkContextFlag::GpDirtyStencilRef); @@ -5351,15 +5351,7 @@ namespace dxvk { if (m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasTransformFeedback)) this->updateTransformFeedbackState(); - if (m_flags.any( - DxvkContextFlag::GpDirtyViewport, - DxvkContextFlag::GpDirtyBlendConstants, - DxvkContextFlag::GpDirtyDepthBias, - DxvkContextFlag::GpDirtyDepthBounds, - DxvkContextFlag::GpDirtyDepthStencilState, - DxvkContextFlag::GpDirtyRasterizerState, - DxvkContextFlag::GpDirtyStencilRef)) - this->updateDynamicState(); + this->updateDynamicState(); if (m_flags.test(DxvkContextFlag::DirtyPushConstants)) this->updatePushConstants(); From 6e8598846d8ac4f95ada43686e22f6b9bc70cff8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 16 Jul 2022 20:19:46 +0200 Subject: [PATCH 0256/1348] [dxvk] Allow mutable commands to be recorded into CS chunks --- src/dxvk/dxvk_cs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_cs.h b/src/dxvk/dxvk_cs.h index ab2733c14..72691c34c 100644 --- a/src/dxvk/dxvk_cs.h +++ b/src/dxvk/dxvk_cs.h @@ -47,7 +47,7 @@ namespace dxvk { * \brief Executes embedded commands * \param [in] ctx The target context */ - virtual void exec(DxvkContext* ctx) const = 0; + virtual void exec(DxvkContext* ctx) = 0; private: @@ -73,7 +73,7 @@ namespace dxvk { DxvkCsTypedCmd (DxvkCsTypedCmd&&) = delete; DxvkCsTypedCmd& operator = (DxvkCsTypedCmd&&) = delete; - void exec(DxvkContext* ctx) const { + void exec(DxvkContext* ctx) { m_command(ctx); } @@ -104,7 +104,7 @@ namespace dxvk { DxvkCsDataCmd (DxvkCsDataCmd&&) = delete; DxvkCsDataCmd& operator = (DxvkCsDataCmd&&) = delete; - void exec(DxvkContext* ctx) const { + void exec(DxvkContext* ctx) { m_command(ctx, &m_data); } From 8747c0f105e9f7b342016af6cc6cfb71815bc984 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 16 Jul 2022 23:17:06 +0200 Subject: [PATCH 0257/1348] [dxvk] Remove unused method from graphics pipeline code --- src/dxvk/dxvk_graphics.cpp | 14 -------------- src/dxvk/dxvk_graphics.h | 11 ----------- 2 files changed, 25 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 229627d73..dc8293f59 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -534,20 +534,6 @@ namespace dxvk { } - Rc DxvkGraphicsPipeline::getShader( - VkShaderStageFlagBits stage) const { - switch (stage) { - case VK_SHADER_STAGE_VERTEX_BIT: return m_shaders.vs; - case VK_SHADER_STAGE_GEOMETRY_BIT: return m_shaders.gs; - case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return m_shaders.tcs; - case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return m_shaders.tes; - case VK_SHADER_STAGE_FRAGMENT_BIT: return m_shaders.fs; - default: - return nullptr; - } - } - - DxvkGlobalPipelineBarrier DxvkGraphicsPipeline::getGlobalBarrier( const DxvkGraphicsPipelineStateInfo& state) const { DxvkGlobalPipelineBarrier barrier = m_barrier; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 991ba1c97..70dbcc1c0 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -343,17 +343,6 @@ namespace dxvk { return m_bindings; } - /** - * \brief Queries shader for a given stage - * - * In case no shader is specified for the - * given stage, \c nullptr will be returned. - * \param [in] stage The shader stage - * \returns Shader of the given stage - */ - Rc getShader( - VkShaderStageFlagBits stage) const; - /** * \brief Queries global resource barrier * From a1c3df7750854c633d540a5f508dcfedffcf76f4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 16 Jul 2022 23:41:08 +0200 Subject: [PATCH 0258/1348] [dxvk] Always pre-compile compute shaders We didn't initially do this because the pipeline library code unconditionally used pNext chains to pass shader code. However, shader module creation has since been refactored, and now there is no good reason not to compile compute shaders immediately. Also fix the stat counter while we're at it. --- src/dxvk/dxvk_compute.cpp | 20 +++++++++++--------- src/dxvk/dxvk_pipemanager.cpp | 16 ++++++++++++++-- src/dxvk/dxvk_pipemanager.h | 3 +++ src/dxvk/dxvk_shader.cpp | 14 +++++++++++--- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 5e83fbe6e..c8eb4a999 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -35,18 +35,20 @@ namespace dxvk { VkPipeline DxvkComputePipeline::getPipelineHandle( const DxvkComputePipelineStateInfo& state) { - if (m_library) { - // For compute pipelines that can be precompiled, we can use that - // pipeline variant unconditionally since there is no state for us - // to worry about other than specialization constants - if (unlikely(!m_libraryHandle)) { - m_libraryHandle = m_library->getPipelineHandle( - DxvkShaderPipelineLibraryCompileArgs()); - m_stats->numComputePipelines += 1; - } + if (m_libraryHandle) { + // Compute pipelines without spec constants are always + // pre-compiled, so we'll almost always hit this path + return m_libraryHandle; + } else if (m_library) { + // Retrieve actual pipeline handle on first use. This + // may wait for an ongoing compile job to finish, or + // compile the pipeline immediately on the calling thread. + m_libraryHandle = m_library->getPipelineHandle( + DxvkShaderPipelineLibraryCompileArgs()); return m_libraryHandle; } else { + // Slow path for compute shaders that do use spec constants DxvkComputePipelineInstance* instance = this->findInstance(state); if (unlikely(!instance)) { diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index d14469d51..589f095f6 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -280,7 +280,7 @@ namespace dxvk { void DxvkPipelineManager::registerShader( const Rc& shader) { - if (m_device->canUseGraphicsPipelineLibrary() && shader->canUsePipelineLibrary()) { + if (canPrecompileShader(shader)) { auto library = createPipelineLibrary(shader); m_workers.compilePipelineLibrary(library); } @@ -380,5 +380,17 @@ namespace dxvk { return &pair->second; } - + + + bool DxvkPipelineManager::canPrecompileShader( + const Rc& shader) const { + if (!shader->canUsePipelineLibrary()) + return false; + + if (shader->info().stage == VK_SHADER_STAGE_COMPUTE_BIT) + return true; + + return m_device->canUseGraphicsPipelineLibrary(); + } + } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 6a0bccd5f..9e6ed35e4 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -276,6 +276,9 @@ namespace dxvk { DxvkShaderPipelineLibrary* findPipelineLibrary( const Rc& shader); + bool canPrecompileShader( + const Rc& shader) const; + }; } \ No newline at end of file diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index e3e99d71d..07acc49bd 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -502,17 +502,28 @@ namespace dxvk { if (pipeline) return pipeline; + bool usesDefaultArgs = (args == DxvkShaderPipelineLibraryCompileArgs()); + switch (stage) { case VK_SHADER_STAGE_VERTEX_BIT: pipeline = compileVertexShaderPipeline(args); + + if (usesDefaultArgs) + m_stats->numGraphicsLibraries += 1; break; case VK_SHADER_STAGE_FRAGMENT_BIT: pipeline = compileFragmentShaderPipeline(); + + if (usesDefaultArgs) + m_stats->numGraphicsLibraries += 1; break; case VK_SHADER_STAGE_COMPUTE_BIT: pipeline = compileComputeShaderPipeline(); + + if (usesDefaultArgs) + m_stats->numComputePipelines += 1; break; default: @@ -520,9 +531,6 @@ namespace dxvk { return VK_NULL_HANDLE; } - if (args == DxvkShaderPipelineLibraryCompileArgs()) - m_stats->numGraphicsLibraries += 1; - return pipeline; } From ff39819086b616d175a8de179c4e292014975116 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 17 Jul 2022 00:09:30 +0200 Subject: [PATCH 0259/1348] [dxvk] Merge methods to bind a compute pipeline There is no workload in practice where the same shader will be used multiple times with different spec constants, so there is no good reason to have two dirty flags or to split lookup and binding. --- src/dxvk/dxvk_context.cpp | 38 ++++++++++++----------------------- src/dxvk/dxvk_context.h | 1 - src/dxvk/dxvk_context_state.h | 3 +-- 3 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index e5a520fc6..74c3fbafb 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -101,7 +101,6 @@ namespace dxvk { DxvkContextFlag::GpDirtyDepthBias, DxvkContextFlag::GpDirtyDepthBounds, DxvkContextFlag::GpDirtyDepthStencilState, - DxvkContextFlag::CpDirtyPipeline, DxvkContextFlag::CpDirtyPipelineState, DxvkContextFlag::DirtyDrawBuffer); @@ -183,7 +182,6 @@ namespace dxvk { if (stage == VK_SHADER_STAGE_COMPUTE_BIT) { m_flags.set( - DxvkContextFlag::CpDirtyPipeline, DxvkContextFlag::CpDirtyPipelineState); } else { m_flags.set( @@ -4395,43 +4393,38 @@ namespace dxvk { void DxvkContext::unbindComputePipeline() { - m_flags.set( - DxvkContextFlag::CpDirtyPipeline, - DxvkContextFlag::CpDirtyPipelineState); + m_flags.set(DxvkContextFlag::CpDirtyPipelineState); m_state.cp.pipeline = nullptr; } - bool DxvkContext::updateComputePipeline() { + bool DxvkContext::updateComputePipelineState() { if (unlikely(m_state.gp.pipeline != nullptr)) this->unbindGraphicsPipeline(); + // Look up pipeline object based on the bound compute shader auto newPipeline = lookupComputePipeline(m_state.cp.shaders); m_state.cp.pipeline = newPipeline; if (unlikely(!newPipeline)) return false; - m_descriptorState.dirtyStages(VK_SHADER_STAGE_COMPUTE_BIT); - - if (m_state.cp.pipeline->getBindings()->layout().getPushConstantRange().size) - m_flags.set(DxvkContextFlag::DirtyPushConstants); - - m_flags.clr(DxvkContextFlag::CpDirtyPipeline); - return true; - } - - - bool DxvkContext::updateComputePipelineState() { - VkPipeline pipeline = m_state.cp.pipeline->getPipelineHandle(m_state.cp.state); + // Look up Vulkan pipeline handle for the given compute state + auto pipelineHandle = newPipeline->getPipelineHandle(m_state.cp.state); - if (unlikely(!pipeline)) + if (unlikely(!pipelineHandle)) return false; m_cmd->cmdBindPipeline( VK_PIPELINE_BIND_POINT_COMPUTE, - pipeline); + pipelineHandle); + + // Mark compute resources and push constants as dirty + m_descriptorState.dirtyStages(VK_SHADER_STAGE_COMPUTE_BIT); + + if (newPipeline->getBindings()->layout().getPushConstantRange().size) + m_flags.set(DxvkContextFlag::DirtyPushConstants); m_flags.clr(DxvkContextFlag::CpDirtyPipelineState); return true; @@ -5274,11 +5267,6 @@ namespace dxvk { bool DxvkContext::commitComputeState() { this->spillRenderPass(false); - if (m_flags.test(DxvkContextFlag::CpDirtyPipeline)) { - if (unlikely(!this->updateComputePipeline())) - return false; - } - if (m_flags.test(DxvkContextFlag::CpDirtyPipelineState)) { if (unlikely(!this->updateComputePipelineState())) return false; diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 439170267..2ebe37f7c 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1323,7 +1323,6 @@ namespace dxvk { void pauseTransformFeedback(); void unbindComputePipeline(); - bool updateComputePipeline(); bool updateComputePipelineState(); void unbindGraphicsPipeline(); diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 11dab5518..859f29ca2 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -46,8 +46,7 @@ namespace dxvk { GpDynamicVertexStrides, ///< Vertex buffer strides are dynamic GpIndependentSets, ///< Graphics pipeline layout was created with independent sets - CpDirtyPipeline, ///< Compute pipeline binding are out of date - CpDirtyPipelineState, ///< Compute pipeline needs to be recompiled + CpDirtyPipelineState, ///< Compute pipeline is out of date DirtyDrawBuffer, ///< Indirect argument buffer is dirty DirtyPushConstants, ///< Push constant data has changed From d898eff3bed74aff619c40d6639d14c6e7c55bde Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 17 Jul 2022 03:53:40 +0200 Subject: [PATCH 0260/1348] [dxvk] Don't remove private inpurs from interface list in SPIR-V 1.4+ And if we have to, exit after one iteration since otherwise our iterator gets invalidated. --- src/dxvk/dxvk_shader.cpp | 31 ++++++++++++++++++++----------- src/dxvk/dxvk_shader.h | 1 + 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 07acc49bd..c05130f5a 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -171,6 +171,8 @@ namespace dxvk { spv::StorageClass storageClass = spv::StorageClassMax; }; + uint32_t spirvVersion = code.data()[1]; + std::unordered_map types; std::unordered_map constants; std::unordered_set candidates; @@ -214,6 +216,9 @@ namespace dxvk { break; } } + + if (ins.opCode() == spv::OpFunction) + break; } if (!inputVarId) @@ -292,21 +297,25 @@ namespace dxvk { code.endInsertion(); // Remove variable from interface list - for (auto ins : code) { - if (ins.opCode() == spv::OpEntryPoint) { - uint32_t argIdx = 2 + code.strLen(ins.chr(2)); + if (spirvVersion < spvVersion(1, 4)) { + for (auto ins : code) { + if (ins.opCode() == spv::OpEntryPoint) { + uint32_t argIdx = 2 + code.strLen(ins.chr(2)); - while (argIdx < ins.length()) { - if (ins.arg(argIdx) == inputVarId) { - ins.setArg(0, spv::OpEntryPoint | ((ins.length() - 1) << spv::WordCountShift)); + while (argIdx < ins.length()) { + if (ins.arg(argIdx) == inputVarId) { + ins.setArg(0, spv::OpEntryPoint | ((ins.length() - 1) << spv::WordCountShift)); - code.beginInsertion(ins.offset() + argIdx); - code.erase(1); - code.endInsertion(); - break; + code.beginInsertion(ins.offset() + argIdx); + code.erase(1); + code.endInsertion(); + break; + } + + argIdx += 1; } - argIdx += 1; + break; } } } diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index cae24b640..6ed5c632e 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -9,6 +9,7 @@ #include "../spirv/spirv_code_buffer.h" #include "../spirv/spirv_compression.h" +#include "../spirv/spirv_module.h" namespace dxvk { From 48ac9b27e4fab29588f44cf1b9f2ac8bcb1e3164 Mon Sep 17 00:00:00 2001 From: Leopard1907 Date: Sun, 17 Jul 2022 05:50:33 +0300 Subject: [PATCH 0261/1348] eveonline-dx12_workaround Launcher probes feature level 12_1, if it fails to probe it DX12 option in launcher stays greyed out, doesn't let user enable DX12. --- src/util/config/config.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index b448cf75c..7051dbbf7 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -30,6 +30,12 @@ namespace dxvk { /* The Vanishing of Ethan Carter Redux */ { R"(\\EthanCarter-Win64-Shipping\.exe$)", {{ { "dxgi.customVendorId", "10de" }, + }} }, + /* EVE Online: Needs this to expose D3D12 * + * otherwise D3D12 option on launcher is * + * greyed out */ + { R"(\\evelauncher\.exe$)", {{ + { "d3d11.maxFeatureLevel", "12_1" }, }} }, /* The Evil Within: Submits command lists * * multiple times */ From c40116716197b58aef4982b13315d2c12f0c3b13 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 17 Jul 2022 13:49:24 +0200 Subject: [PATCH 0262/1348] [dxvk] Introduce SPIR-V pass to inject render target swizzles --- src/dxvk/dxvk_shader.cpp | 262 +++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_shader.h | 11 +- 2 files changed, 272 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index c05130f5a..f53dc7ebd 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -379,6 +379,268 @@ namespace dxvk { } + void DxvkShader::emitOutputSwizzles( + SpirvCodeBuffer& code, + uint32_t outputMask, + const VkComponentMapping* swizzles) { + // Skip this step entirely if all relevant + // outputs use the identity swizzle + bool requiresEpilogue = false; + + for (auto index : bit::BitMask(outputMask)) + requiresEpilogue |= !util::isIdentityMapping(swizzles[index]); + + if (!requiresEpilogue) + return; + + // Gather some information. We need to scan pointer types with + // the output storage class to find the base vector type, and + // we need to scan vector types to find the component count. + uint32_t entryPointId = 0; + uint32_t functionId = 0; + + size_t epilogueOffset = 0; + size_t variableOffset = 0; + + struct VarInfo { + uint32_t varId; + uint32_t typeId; + uint32_t location; + uint32_t componentCount; + uint32_t componentTypeId; + }; + + struct VarIdInfo { + uint32_t location; + }; + + struct TypeIdInfo { + uint32_t componentCount; + uint32_t baseTypeId; + }; + + union IdInfo { + VarIdInfo var; + TypeIdInfo type; + }; + + // Stores type information depending on type category: + // OpTypePointer: type id -> base type id + // OpTypeVector: type id -> component count + // OpTypeFloat/Int: type id -> 1 + std::unordered_map idInfo; + std::vector varInfos; + + SpirvInstruction prev; + + for (auto ins : code) { + switch (ins.opCode()) { + case spv::OpEntryPoint: { + entryPointId = ins.arg(2); + } break; + + case spv::OpDecorate: { + if (ins.arg(2) == spv::DecorationLocation) { + IdInfo info; + info.var.location = ins.arg(3); + idInfo.insert({ ins.arg(1), info }); + } + } break; + + case spv::OpTypeVector: { + IdInfo info; + info.type.componentCount = ins.arg(3); + info.type.baseTypeId = ins.arg(2); + idInfo.insert({ ins.arg(1), info }); + } break; + + case spv::OpTypeInt: + case spv::OpTypeFloat: { + IdInfo info; + info.type.componentCount = 1; + info.type.baseTypeId = 0; + idInfo.insert({ ins.arg(1), info }); + } break; + + case spv::OpTypePointer: { + if (ins.arg(2) == spv::StorageClassOutput) { + IdInfo info; + info.type.componentCount = 0; + info.type.baseTypeId = ins.arg(3); + idInfo.insert({ ins.arg(1), info }); + } + } break; + + case spv::OpVariable: { + if (!variableOffset) + variableOffset = ins.offset(); + + if (ins.arg(3) == spv::StorageClassOutput) { + uint32_t ptrId = ins.arg(1); + uint32_t varId = ins.arg(2); + + auto ptrEntry = idInfo.find(ptrId); + auto varEntry = idInfo.find(varId); + + if (ptrEntry != idInfo.end() + && varEntry != idInfo.end()) { + uint32_t typeId = ptrEntry->second.type.baseTypeId; + + auto typeEntry = idInfo.find(typeId); + if (typeEntry != idInfo.end()) { + VarInfo info; + info.varId = varId; + info.typeId = typeId; + info.location = varEntry->second.var.location; + info.componentCount = typeEntry->second.type.componentCount; + info.componentTypeId = (info.componentCount == 1) + ? typeId : typeEntry->second.type.baseTypeId; + + varInfos.push_back(info); + } + } + } + } break; + + case spv::OpFunction: { + functionId = ins.arg(2); + } break; + + case spv::OpFunctionEnd: { + if (entryPointId == functionId) + epilogueOffset = prev.offset(); + } break; + + default: + prev = ins; + } + + if (epilogueOffset) + break; + } + + // Oops, this shouldn't happen + if (!epilogueOffset) + return; + + code.beginInsertion(epilogueOffset); + + struct ConstInfo { + uint32_t constId; + uint32_t typeId; + uint32_t value; + }; + + std::vector consts; + + for (const auto& var : varInfos) { + uint32_t storeId = 0; + + if (var.componentCount == 1) { + if (util::getComponentIndex(swizzles[var.location].r, 0) != 0) { + storeId = code.allocId(); + + ConstInfo constInfo; + constInfo.constId = storeId; + constInfo.typeId = var.componentTypeId; + constInfo.value = 0; + consts.push_back(constInfo); + } + } else { + uint32_t constId = 0; + + std::array indices = {{ + util::getComponentIndex(swizzles[var.location].r, 0), + util::getComponentIndex(swizzles[var.location].g, 1), + util::getComponentIndex(swizzles[var.location].b, 2), + util::getComponentIndex(swizzles[var.location].a, 3), + }}; + + bool needsSwizzle = false; + + for (uint32_t i = 0; i < var.componentCount && !constId; i++) { + needsSwizzle |= indices[i] != i; + + if (indices[i] >= var.componentCount) + constId = code.allocId(); + } + + if (needsSwizzle) { + uint32_t loadId = code.allocId(); + code.putIns(spv::OpLoad, 4); + code.putWord(var.typeId); + code.putWord(loadId); + code.putWord(var.varId); + + if (!constId) { + storeId = code.allocId(); + code.putIns(spv::OpVectorShuffle, 5 + var.componentCount); + code.putWord(var.typeId); + code.putWord(storeId); + code.putWord(loadId); + code.putWord(loadId); + + for (uint32_t i = 0; i < var.componentCount; i++) + code.putWord(indices[i]); + } else { + std::array ids = { }; + + ConstInfo constInfo; + constInfo.constId = constId; + constInfo.typeId = var.componentTypeId; + constInfo.value = 0; + consts.push_back(constInfo); + + for (uint32_t i = 0; i < var.componentCount; i++) { + if (indices[i] < var.componentCount) { + ids[i] = code.allocId(); + + code.putIns(spv::OpCompositeExtract, 5); + code.putWord(var.componentTypeId); + code.putWord(ids[i]); + code.putWord(loadId); + code.putWord(indices[i]); + } else { + ids[i] = constId; + } + } + + storeId = code.allocId(); + code.putIns(spv::OpCompositeConstruct, 3 + var.componentCount); + code.putWord(var.typeId); + code.putWord(storeId); + + for (uint32_t i = 0; i < var.componentCount; i++) + code.putWord(ids[i]); + } + } + } + + if (storeId) { + code.putIns(spv::OpStore, 3); + code.putWord(var.varId); + code.putWord(storeId); + } + } + + code.endInsertion(); + + // If necessary, insert constants + if (!consts.empty()) { + code.beginInsertion(variableOffset); + + for (const auto& c : consts) { + code.putIns(spv::OpConstant, 4); + code.putWord(c.typeId); + code.putWord(c.constId); + code.putWord(c.value); + } + + code.endInsertion(); + } + } + + DxvkShaderStageInfo::DxvkShaderStageInfo(const DxvkDevice* device) : m_device(device) { diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 6ed5c632e..905c8ed91 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -80,6 +80,8 @@ namespace dxvk { struct DxvkShaderModuleCreateInfo { bool fsDualSrcBlend = false; uint32_t undefinedInputs = 0; + + std::array rtSwizzles = { }; }; @@ -227,7 +229,14 @@ namespace dxvk { DxvkBindingLayout m_bindings; - static void eliminateInput(SpirvCodeBuffer& code, uint32_t location); + static void eliminateInput( + SpirvCodeBuffer& code, + uint32_t location); + + static void emitOutputSwizzles( + SpirvCodeBuffer& code, + uint32_t outputMask, + const VkComponentMapping* swizzles); }; From 568aae8667f2704233f763f5e7faeff30c907fe0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 17 Jul 2022 14:00:37 +0200 Subject: [PATCH 0263/1348] [dxvk] Use SPIR-V pass to swizzle FS outputs instead of spec constants --- src/dxvk/dxvk_graphics.cpp | 44 ++++++++++++++++++++------------------ src/dxvk/dxvk_graphics.h | 4 ++++ src/dxvk/dxvk_shader.cpp | 4 ++++ 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index dc8293f59..0d00184f7 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -732,17 +732,8 @@ namespace dxvk { // Remapping fragment shader outputs would require spec constants for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - VkFormat rtFormat = state.rt.getColorFormat(i); - - if (rtFormat && (m_fsOut & (1u << i)) && state.omBlend[i].colorWriteMask()) { - auto mapping = state.omSwizzle[i].mapping(); - - if (mapping.r != VK_COMPONENT_SWIZZLE_R - || mapping.g != VK_COMPONENT_SWIZZLE_G - || mapping.b != VK_COMPONENT_SWIZZLE_B - || mapping.a != VK_COMPONENT_SWIZZLE_A) - return false; - } + if (writesRenderTarget(state, i) && !util::isIdentityMapping(state.omSwizzle[i].mapping())) + return false; } return true; @@ -813,14 +804,6 @@ namespace dxvk { // Set up some specialization constants DxvkSpecConstants specData; - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if ((m_fsOut & (1 << i)) != 0) { - specData.set(uint32_t(DxvkSpecConstantId::ColorComponentMappings) + i, - state.omSwizzle[i].rIndex() << 0 | state.omSwizzle[i].gIndex() << 4 | - state.omSwizzle[i].bIndex() << 8 | state.omSwizzle[i].aIndex() << 12, 0x3210u); - } - } - for (uint32_t i = 0; i < MaxNumSpecConstants; i++) specData.set(getSpecId(i), state.sc.specConstants[i], 0u); @@ -907,9 +890,15 @@ namespace dxvk { DxvkShaderModuleCreateInfo info; // Fix up fragment shader outputs for dual-source blending - if (shaderInfo.stage == VK_SHADER_STAGE_FRAGMENT_BIT) + if (shaderInfo.stage == VK_SHADER_STAGE_FRAGMENT_BIT) { info.fsDualSrcBlend = state.useDualSourceBlending(); + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + if (writesRenderTarget(state, i)) + info.rtSwizzles[i] = state.omSwizzle[i].mapping(); + } + } + // Deal with undefined shader inputs uint32_t consumedInputs = shaderInfo.inputMask; uint32_t providedInputs = 0; @@ -927,7 +916,6 @@ namespace dxvk { } info.undefinedInputs = (providedInputs & consumedInputs) ^ consumedInputs; - return shader->getCode(m_bindings, info); } @@ -957,6 +945,20 @@ namespace dxvk { } + bool DxvkGraphicsPipeline::writesRenderTarget( + const DxvkGraphicsPipelineStateInfo& state, + uint32_t target) const { + if (!(m_fsOut & (1u << target))) + return false; + + if (!state.omBlend[target].colorWriteMask()) + return false; + + VkFormat rtFormat = state.rt.getColorFormat(target); + return rtFormat != VK_FORMAT_UNDEFINED; + } + + bool DxvkGraphicsPipeline::validatePipelineState( const DxvkGraphicsPipelineStateInfo& state, bool trusted) const { diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 70dbcc1c0..8ab88b746 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -432,6 +432,10 @@ namespace dxvk { Rc getPrevStageShader( VkShaderStageFlagBits stage) const; + bool writesRenderTarget( + const DxvkGraphicsPipelineStateInfo& state, + uint32_t target) const; + bool validatePipelineState( const DxvkGraphicsPipelineStateInfo& state, bool trusted) const; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index f53dc7ebd..61b57bfd4 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -140,6 +140,10 @@ namespace dxvk { for (uint32_t u : bit::BitMask(state.undefinedInputs)) eliminateInput(spirvCode, u); + // Emit fragment shader swizzles as necessary + if (m_info.stage == VK_SHADER_STAGE_FRAGMENT_BIT) + emitOutputSwizzles(spirvCode, m_info.outputMask, state.rtSwizzles.data()); + return spirvCode; } From 0f16a8f70d5f5cad9d9e990067ca01c388ac592c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 17 Jul 2022 14:04:59 +0200 Subject: [PATCH 0264/1348] [dxbc] Remove output mapping code --- src/dxbc/dxbc_compiler.cpp | 60 -------------------------------------- src/dxbc/dxbc_compiler.h | 9 ------ 2 files changed, 69 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 8ea7c9a7a..16ec63b2c 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -5691,20 +5691,6 @@ namespace dxvk { } - uint32_t DxbcCompiler::emitNewSpecConstant( - DxvkSpecConstantId specId, - DxbcScalarType type, - uint32_t value, - const char* name) { - uint32_t id = m_module.specConst32( - getScalarTypeId(type), value); - - m_module.decorateSpecId(id, uint32_t(specId)); - m_module.setDebugName(id, name); - return id; - } - - void DxbcCompiler::emitInputSetup() { m_module.setLateConst(m_vArrayLengthId, &m_vArrayLength); @@ -5847,51 +5833,6 @@ namespace dxvk { } - void DxbcCompiler::emitOutputMapping() { - // For pixel shaders, we need to swizzle the - // output vectors using some spec constants. - for (uint32_t i = 0; i < m_oRegs.size(); i++) { - if (m_oRegs[i].id == 0 || m_oRegs[i].type.ccount < 2) - continue; - - DxbcRegisterValue vector = emitValueLoad(m_oRegs[i]); - - uint32_t specTypeId = getScalarTypeId(DxbcScalarType::Uint32); - uint32_t compTypeId = getScalarTypeId(vector.type.ctype); - - uint32_t specId = m_module.specConst32(specTypeId, 0x3210); - m_module.decorateSpecId(specId, uint32_t(DxvkSpecConstantId::ColorComponentMappings) + i); - m_module.setDebugName(specId, str::format("omap", i).c_str()); - - std::array scalars; - for (uint32_t c = 0; c < vector.type.ccount; c++) { - scalars[c] = m_module.opVectorExtractDynamic(compTypeId, vector.id, - m_module.opBitFieldUExtract(specTypeId, specId, - m_module.constu32(4 * c), m_module.constu32(4))); - } - - uint32_t typeId = getVectorTypeId(vector.type); - vector.id = m_module.opCompositeConstruct(typeId, vector.type.ccount, scalars.data()); - - // Replace NaN by zero if requested - if (m_moduleInfo.options.enableRtOutputNanFixup && vector.type.ctype == DxbcScalarType::Float32) { - uint32_t boolType = m_module.defBoolType(); - - if (vector.type.ccount > 1) - boolType = m_module.defVectorType(boolType, vector.type.ccount); - - uint32_t zero = emitBuildConstVecf32(0.0f, 0.0f, 0.0f, 0.0f, - DxbcRegMask((1u << vector.type.ccount) - 1)).id; - uint32_t isNan = m_module.opIsNan(boolType, vector.id); - vector.id = m_module.opSelect(typeId, isNan, zero, vector.id); - } - - emitValueStore(m_oRegs[i], vector, - DxbcRegMask::firstN(vector.type.ccount)); - } - } - - void DxbcCompiler::emitOutputDepthClamp() { // HACK: Some drivers do not clamp FragDepth to [minDepth..maxDepth] // before writing to the depth attachment, but we do not have acccess @@ -6937,7 +6878,6 @@ namespace dxvk { } this->emitOutputSetup(); - this->emitOutputMapping(); if (m_moduleInfo.options.useDepthClipWorkaround) this->emitOutputDepthClamp(); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index a3ac717a9..dea5007bb 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -999,21 +999,12 @@ namespace dxvk { const DxbcRegister& reg, DxbcRegisterValue value); - //////////////////////////////////////// - // Spec constant declaration and access - uint32_t emitNewSpecConstant( - DxvkSpecConstantId specId, - DxbcScalarType type, - uint32_t value, - const char* name); - //////////////////////////// // Input/output preparation void emitInputSetup(); void emitInputSetup(uint32_t vertexCount); void emitOutputSetup(); - void emitOutputMapping(); void emitOutputDepthClamp(); void emitInitWorkgroupMemory(); From f15466a2c51f8cada604bed9df59716b0b8020cf Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 17 Jul 2022 14:08:47 +0200 Subject: [PATCH 0265/1348] [dxvk] Remove remaining built-in specialization constants --- src/d3d9/d3d9_fixed_function.cpp | 12 ++++++------ src/dxso/dxso_compiler.cpp | 16 ++++++++-------- src/dxvk/dxvk_compute.cpp | 2 +- src/dxvk/dxvk_context.h | 5 ++--- src/dxvk/dxvk_graphics.cpp | 2 +- src/dxvk/dxvk_shader.h | 15 --------------- src/dxvk/dxvk_spec_const.h | 13 ------------- 7 files changed, 18 insertions(+), 47 deletions(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 69198eace..8c7aeb2a1 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -45,16 +45,16 @@ namespace dxvk { if (!fogCtx.IsPixel) { spvModule.setDebugName(fogMode, "vertex_fog_mode"); - spvModule.decorateSpecId(fogMode, getSpecId(D3D9SpecConstantId::VertexFogMode)); + spvModule.decorateSpecId(fogMode, D3D9SpecConstantId::VertexFogMode); } else { spvModule.setDebugName(fogMode, "pixel_fog_mode"); - spvModule.decorateSpecId(fogMode, getSpecId(D3D9SpecConstantId::PixelFogMode)); + spvModule.decorateSpecId(fogMode, D3D9SpecConstantId::PixelFogMode); } uint32_t fogEnabled = spvModule.specConstBool(false); spvModule.setDebugName(fogEnabled, "fog_enabled"); - spvModule.decorateSpecId(fogEnabled, getSpecId(D3D9SpecConstantId::FogEnabled)); + spvModule.decorateSpecId(fogEnabled, D3D9SpecConstantId::FogEnabled); uint32_t doFog = spvModule.allocateId(); uint32_t skipFog = spvModule.allocateId(); @@ -272,7 +272,7 @@ namespace dxvk { if (isFixedFunction) { uint32_t pointMode = spvModule.specConst32(uint32Type, 0); spvModule.setDebugName(pointMode, "point_mode"); - spvModule.decorateSpecId(pointMode, getSpecId(D3D9SpecConstantId::PointMode)); + spvModule.decorateSpecId(pointMode, D3D9SpecConstantId::PointMode); uint32_t scaleBit = spvModule.opBitFieldUExtract(uint32Type, pointMode, spvModule.consti32(0), spvModule.consti32(1)); uint32_t isScale = spvModule.opIEqual(boolType, scaleBit, spvModule.constu32(1)); @@ -325,7 +325,7 @@ namespace dxvk { uint32_t pointMode = spvModule.specConst32(uint32Type, 0); spvModule.setDebugName(pointMode, "point_mode"); - spvModule.decorateSpecId(pointMode, getSpecId(D3D9SpecConstantId::PointMode)); + spvModule.decorateSpecId(pointMode, D3D9SpecConstantId::PointMode); uint32_t spriteBit = spvModule.opBitFieldUExtract(uint32Type, pointMode, spvModule.consti32(1), spvModule.consti32(1)); uint32_t isSprite = spvModule.opIEqual(boolType, spriteBit, spvModule.constu32(1)); @@ -2190,7 +2190,7 @@ namespace dxvk { // Declare spec constants for render states uint32_t alphaFuncId = m_module.specConst32(m_module.defIntType(32, 0), 0); m_module.setDebugName(alphaFuncId, "alpha_func"); - m_module.decorateSpecId(alphaFuncId, getSpecId(D3D9SpecConstantId::AlphaCompareOp)); + m_module.decorateSpecId(alphaFuncId, D3D9SpecConstantId::AlphaCompareOp); // Implement alpha test auto oC0 = m_ps.out.COLOR; diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index b17c4c556..289ef90ed 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -270,11 +270,11 @@ namespace dxvk { } m_nullSpecConstant = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_nullSpecConstant, getSpecId(D3D9SpecConstantId::SamplerNull)); + m_module.decorateSpecId(m_nullSpecConstant, D3D9SpecConstantId::SamplerNull); m_module.setDebugName(m_nullSpecConstant, "nullSamplers"); m_depthSpecConstant = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_depthSpecConstant, getSpecId(D3D9SpecConstantId::SamplerDepthMode)); + m_module.decorateSpecId(m_depthSpecConstant, D3D9SpecConstantId::SamplerDepthMode); m_module.setDebugName(m_depthSpecConstant, "depthSamplers"); this->emitDclInputArray(); @@ -339,10 +339,10 @@ namespace dxvk { m_bindings.push_back(binding); m_boolSpecConstant = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_boolSpecConstant, getSpecId( + m_module.decorateSpecId(m_boolSpecConstant, m_programInfo.type() == DxsoProgramType::VertexShader ? D3D9SpecConstantId::VertexShaderBools - : D3D9SpecConstantId::PixelShaderBools)); + : D3D9SpecConstantId::PixelShaderBools); m_module.setDebugName(m_boolSpecConstant, "boolConstants"); } @@ -534,18 +534,18 @@ namespace dxvk { if (m_programInfo.majorVersion() < 2 || m_moduleInfo.options.forceSamplerTypeSpecConstants) { m_ps.samplerTypeSpec = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_ps.samplerTypeSpec, getSpecId(D3D9SpecConstantId::SamplerType)); + m_module.decorateSpecId(m_ps.samplerTypeSpec, D3D9SpecConstantId::SamplerType); m_module.setDebugName(m_ps.samplerTypeSpec, "s_sampler_types"); if (m_programInfo.majorVersion() < 2) { m_ps.projectionSpec = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_ps.projectionSpec, getSpecId(D3D9SpecConstantId::ProjectionType)); + m_module.decorateSpecId(m_ps.projectionSpec, D3D9SpecConstantId::ProjectionType); m_module.setDebugName(m_ps.projectionSpec, "s_projections"); } } m_ps.fetch4Spec = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_ps.fetch4Spec, getSpecId(D3D9SpecConstantId::Fetch4)); + m_module.decorateSpecId(m_ps.fetch4Spec, D3D9SpecConstantId::Fetch4); m_module.setDebugName(m_ps.fetch4Spec, "s_fetch4"); this->setupRenderStateInfo(); @@ -3759,7 +3759,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t alphaFuncId = m_module.specConst32(m_module.defIntType(32, 0), 0); m_module.setDebugName (alphaFuncId, "alpha_func"); - m_module.decorateSpecId (alphaFuncId, getSpecId(D3D9SpecConstantId::AlphaCompareOp)); + m_module.decorateSpecId (alphaFuncId, D3D9SpecConstantId::AlphaCompareOp); // Implement alpha test and fog DxsoRegister color0; diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index c8eb4a999..bbf8a27f2 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -109,7 +109,7 @@ namespace dxvk { DxvkSpecConstants specData; for (uint32_t i = 0; i < MaxNumSpecConstants; i++) - specData.set(getSpecId(i), state.sc.specConstants[i], 0u); + specData.set(i, state.sc.specConstants[i], 0u); VkSpecializationInfo specInfo = specData.getSpecInfo(); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 2ebe37f7c..c783544d1 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1024,9 +1024,8 @@ namespace dxvk { /** * \brief Sets specialization constants * - * Replaces current specialization constants with - * the given list of constant entries. The specId - * in the shader can be computed with \c getSpecId. + * Replaces current specialization constants + * with the given list of constant entries. * \param [in] pipeline Graphics or Compute pipeline * \param [in] index Constant index * \param [in] value Constant value diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 0d00184f7..948cee55d 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -805,7 +805,7 @@ namespace dxvk { DxvkSpecConstants specData; for (uint32_t i = 0; i < MaxNumSpecConstants; i++) - specData.set(getSpecId(i), state.sc.specConstants[i], 0u); + specData.set(i, state.sc.specConstants[i], 0u); VkSpecializationInfo specInfo = specData.getSpecInfo(); diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 905c8ed91..4ff2ffb45 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -18,21 +18,6 @@ namespace dxvk { class DxvkPipelineManager; struct DxvkPipelineStats; - /** - * \brief Built-in specialization constants - * - * These specialization constants allow the SPIR-V - * shaders to access some pipeline state like D3D - * shaders do. They need to be filled in by the - * implementation at pipeline compilation time. - */ - enum class DxvkSpecConstantId : uint32_t { - FirstPipelineConstant = 0, - /// Special constant ranges that do not count - /// towards the spec constant min/max values - ColorComponentMappings = DxvkLimits::MaxNumSpecConstants, - }; - /** * \brief Shader flags * diff --git a/src/dxvk/dxvk_spec_const.h b/src/dxvk/dxvk_spec_const.h index df4f041cb..3e5ec4abe 100644 --- a/src/dxvk/dxvk_spec_const.h +++ b/src/dxvk/dxvk_spec_const.h @@ -74,18 +74,5 @@ namespace dxvk { void setAsUint32(uint32_t specId, uint32_t value); }; - - - /** - * \brief Computes specialization constant ID - * - * Computest the specId to use within shaders - * for a given pipeline specialization constant. - * \param [in] index Spec constant index - * \returns Specialization constant ID - */ - inline uint32_t getSpecId(uint32_t index) { - return uint32_t(DxvkSpecConstantId::FirstPipelineConstant) + index; - } } \ No newline at end of file From 8d1b9eca5d4db5684976002a555974813a1b288e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 17 Jul 2022 16:44:03 +0200 Subject: [PATCH 0266/1348] [dxvk] Fix blending with A8 render targets --- src/dxvk/dxvk_graphics.cpp | 10 +++++++++ src/dxvk/dxvk_util.cpp | 42 ++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_util.h | 12 ++++++++++- 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 948cee55d..bffb9bcef 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -250,6 +250,16 @@ namespace dxvk { if (writeMask) { cbAttachments[i] = state.omBlend[i].state(); cbAttachments[i].colorWriteMask = writeMask; + + // If we're rendering to an emulated alpha-only render target, fix up blending + if (cbAttachments[i].blendEnable && formatInfo->componentMask == VK_COLOR_COMPONENT_R_BIT && state.omSwizzle[i].rIndex() == 3) { + cbAttachments[i].srcColorBlendFactor = util::remapAlphaToColorBlendFactor( + std::exchange(cbAttachments[i].srcAlphaBlendFactor, VK_BLEND_FACTOR_ONE)); + cbAttachments[i].dstColorBlendFactor = util::remapAlphaToColorBlendFactor( + std::exchange(cbAttachments[i].dstAlphaBlendFactor, VK_BLEND_FACTOR_ZERO)); + cbAttachments[i].colorBlendOp = + std::exchange(cbAttachments[i].alphaBlendOp, VK_BLEND_OP_ADD); + } } } } diff --git a/src/dxvk/dxvk_util.cpp b/src/dxvk/dxvk_util.cpp index ba689c5ca..1c2296984 100644 --- a/src/dxvk/dxvk_util.cpp +++ b/src/dxvk/dxvk_util.cpp @@ -272,6 +272,48 @@ namespace dxvk::util { } + VkBlendFactor remapAlphaToColorBlendFactor(VkBlendFactor factor) { + switch (factor) { + // Make sure we use the red component from the + // fragment shader since alpha may be undefined + case VK_BLEND_FACTOR_SRC_ALPHA: + return VK_BLEND_FACTOR_SRC_COLOR; + + case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: + return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; + + case VK_BLEND_FACTOR_SRC1_ALPHA: + return VK_BLEND_FACTOR_SRC1_COLOR; + + case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: + return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR; + + // This is defined to always be 1 for alpha + case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE: + return VK_BLEND_FACTOR_ONE; + + // Make sure we use the red component from the + // attachment since there is no alpha component + case VK_BLEND_FACTOR_DST_ALPHA: + return VK_BLEND_FACTOR_DST_COLOR; + + case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: + return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; + + // For blend constants we actually need to do the + // opposite and make sure we always use alpha + case VK_BLEND_FACTOR_CONSTANT_COLOR: + return VK_BLEND_FACTOR_CONSTANT_ALPHA; + + case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: + return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA; + + default: + return factor; + } + } + + bool isIdentityMapping( VkComponentMapping mapping) { return (mapping.r == VK_COMPONENT_SWIZZLE_R || mapping.r == VK_COMPONENT_SWIZZLE_IDENTITY) diff --git a/src/dxvk/dxvk_util.h b/src/dxvk/dxvk_util.h index cf26e9c5b..a9a4b7ee4 100644 --- a/src/dxvk/dxvk_util.h +++ b/src/dxvk/dxvk_util.h @@ -339,7 +339,17 @@ namespace dxvk::util { VkComponentMapping resolveSrcComponentMapping( VkComponentMapping dstMapping, VkComponentMapping srcMapping); - + + /** + * \brief Remaps alpha blend factor to a color one + * + * Needed when rendering to alpha-only render targets + * which we only support through single-channel formats. + * \param [in] factor Alpha blend factor + * \returns Corresponding color blend factor + */ + VkBlendFactor remapAlphaToColorBlendFactor(VkBlendFactor factor); + bool isIdentityMapping( VkComponentMapping mapping); From 0b11995dea5861e5cef87e18ea227b85814aad72 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 14:19:06 +0200 Subject: [PATCH 0267/1348] [dxvk] Clean up image and image view creation code Someone was dunk while setting pNext to VK_NULL_HANDLE instead of nullptr. --- src/dxvk/dxvk_image.cpp | 77 +++++++++-------------------------------- 1 file changed, 17 insertions(+), 60 deletions(-) diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index c8dd3f53d..d1b330f4b 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -22,15 +22,11 @@ namespace dxvk { // If defined, we should provide a format list, which // allows some drivers to enable image compression - VkImageFormatListCreateInfo formatList; - formatList.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO; - formatList.pNext = nullptr; + VkImageFormatListCreateInfo formatList = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO }; formatList.viewFormatCount = createInfo.viewFormatCount; formatList.pViewFormats = createInfo.viewFormats; - VkImageCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - info.pNext = &formatList; + VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, &formatList }; info.flags = createInfo.flags; info.imageType = createInfo.type; info.format = createInfo.format; @@ -41,8 +37,6 @@ namespace dxvk { info.tiling = createInfo.tiling; info.usage = createInfo.usage; info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - info.queueFamilyIndexCount = 0; - info.pQueueFamilyIndices = nullptr; info.initialLayout = createInfo.initialLayout; m_shared = canShareImage(info, createInfo.sharing); @@ -76,46 +70,27 @@ namespace dxvk { // alignment on non-linear images in order not to violate the // bufferImageGranularity limit, which may be greater than the // required resource memory alignment on some GPUs. - VkMemoryDedicatedRequirements dedicatedRequirements; - dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS; - dedicatedRequirements.pNext = VK_NULL_HANDLE; - dedicatedRequirements.prefersDedicatedAllocation = VK_FALSE; - dedicatedRequirements.requiresDedicatedAllocation = VK_FALSE; + VkMemoryDedicatedRequirements dedicatedRequirements = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS }; + VkMemoryRequirements2 memReq = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &dedicatedRequirements }; - VkMemoryRequirements2 memReq; - memReq.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; - memReq.pNext = &dedicatedRequirements; - - VkImageMemoryRequirementsInfo2 memReqInfo; - memReqInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2; + VkImageMemoryRequirementsInfo2 memReqInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 }; memReqInfo.image = m_image.image; - memReqInfo.pNext = VK_NULL_HANDLE; - VkMemoryDedicatedAllocateInfo dedMemoryAllocInfo; - dedMemoryAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; - dedMemoryAllocInfo.pNext = VK_NULL_HANDLE; - dedMemoryAllocInfo.buffer = VK_NULL_HANDLE; + VkMemoryDedicatedAllocateInfo dedMemoryAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO }; dedMemoryAllocInfo.image = m_image.image; - VkExportMemoryAllocateInfo exportInfo; + VkExportMemoryAllocateInfo exportInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO }; if (m_shared && createInfo.sharing.mode == DxvkSharedHandleMode::Export) { - exportInfo.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO; - exportInfo.pNext = nullptr; + exportInfo.pNext = std::exchange(dedMemoryAllocInfo.pNext, &exportInfo); exportInfo.handleTypes = createInfo.sharing.type; - - dedMemoryAllocInfo.pNext = &exportInfo; } #ifdef _WIN32 - VkImportMemoryWin32HandleInfoKHR importInfo; + VkImportMemoryWin32HandleInfoKHR importInfo = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR }; if (m_shared && createInfo.sharing.mode == DxvkSharedHandleMode::Import) { - importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR; - importInfo.pNext = nullptr; + importInfo.pNext = std::exchange(dedMemoryAllocInfo.pNext, &importInfo); importInfo.handleType = createInfo.sharing.type; importInfo.handle = createInfo.sharing.handle; - importInfo.name = nullptr; - - dedMemoryAllocInfo.pNext = &importInfo; } #endif @@ -186,29 +161,18 @@ namespace dxvk { return false; } - VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo; - externalImageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO; - externalImageFormatInfo.pNext = VK_NULL_HANDLE; + VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO }; externalImageFormatInfo.handleType = sharingInfo.type; - VkPhysicalDeviceImageFormatInfo2 imageFormatInfo; - imageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2; - imageFormatInfo.pNext = &externalImageFormatInfo; + VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, &externalImageFormatInfo }; imageFormatInfo.format = createInfo.format; imageFormatInfo.type = createInfo.imageType; imageFormatInfo.tiling = createInfo.tiling; imageFormatInfo.usage = createInfo.usage; imageFormatInfo.flags = createInfo.flags; - VkExternalImageFormatProperties externalImageFormatProperties; - externalImageFormatProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES; - externalImageFormatProperties.pNext = nullptr; - externalImageFormatProperties.externalMemoryProperties = {}; - - VkImageFormatProperties2 imageFormatProperties; - imageFormatProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2; - imageFormatProperties.pNext = &externalImageFormatProperties; - imageFormatProperties.imageFormatProperties = {}; + VkExternalImageFormatProperties externalImageFormatProperties = { VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES }; + VkImageFormatProperties2 imageFormatProperties = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, &externalImageFormatProperties }; VkResult vr = m_device->adapter()->vki()->vkGetPhysicalDeviceImageFormatProperties2( m_device->adapter()->handle(), &imageFormatInfo, &imageFormatProperties); @@ -243,9 +207,7 @@ namespace dxvk { return INVALID_HANDLE_VALUE; #ifdef _WIN32 - VkMemoryGetWin32HandleInfoKHR handleInfo; - handleInfo.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR; - handleInfo.pNext = nullptr; + VkMemoryGetWin32HandleInfoKHR handleInfo = { VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR }; handleInfo.handleType = m_info.sharing.type; handleInfo.memory = m_image.memory.memory(); if (m_vkd->vkGetMemoryWin32HandleKHR(m_vkd->device(), &handleInfo, &handle) != VK_SUCCESS) @@ -319,15 +281,10 @@ namespace dxvk { subresourceRange.baseArrayLayer = m_info.minLayer; subresourceRange.layerCount = numLayers; - VkImageViewUsageCreateInfo viewUsage; - viewUsage.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO; - viewUsage.pNext = nullptr; + VkImageViewUsageCreateInfo viewUsage = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; viewUsage.usage = m_info.usage; - VkImageViewCreateInfo viewInfo; - viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewInfo.pNext = &viewUsage; - viewInfo.flags = 0; + VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &viewUsage }; viewInfo.image = m_image->handle(); viewInfo.viewType = type; viewInfo.format = m_info.format; From d29d403c67870b5da77ea89db518ced563315b4a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 14:21:23 +0200 Subject: [PATCH 0268/1348] [dxvk] Clean up buffer and buffer view creation code --- src/dxvk/dxvk_buffer.cpp | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 2419c4bea..78a5946cd 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -58,15 +58,10 @@ namespace dxvk { DxvkBufferHandle DxvkBuffer::allocBuffer(VkDeviceSize sliceCount, bool clear) const { auto vkd = m_device->vkd(); - VkBufferCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; info.size = m_physSliceStride * sliceCount; info.usage = m_info.usage; info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - info.queueFamilyIndexCount = 0; - info.pQueueFamilyIndices = nullptr; DxvkBufferHandle handle; @@ -78,26 +73,14 @@ namespace dxvk { "\n usage: ", info.usage)); } - VkMemoryDedicatedRequirements dedicatedRequirements; - dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS; - dedicatedRequirements.pNext = VK_NULL_HANDLE; - dedicatedRequirements.prefersDedicatedAllocation = VK_FALSE; - dedicatedRequirements.requiresDedicatedAllocation = VK_FALSE; + VkMemoryDedicatedRequirements dedicatedRequirements = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS }; + VkMemoryRequirements2 memReq = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &dedicatedRequirements }; - VkMemoryRequirements2 memReq; - memReq.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; - memReq.pNext = &dedicatedRequirements; - - VkBufferMemoryRequirementsInfo2 memReqInfo; - memReqInfo.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2; + VkBufferMemoryRequirementsInfo2 memReqInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 }; memReqInfo.buffer = handle.buffer; - memReqInfo.pNext = VK_NULL_HANDLE; - VkMemoryDedicatedAllocateInfo dedMemoryAllocInfo; - dedMemoryAllocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO; - dedMemoryAllocInfo.pNext = VK_NULL_HANDLE; + VkMemoryDedicatedAllocateInfo dedMemoryAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO }; dedMemoryAllocInfo.buffer = handle.buffer; - dedMemoryAllocInfo.image = VK_NULL_HANDLE; vkd->vkGetBufferMemoryRequirements2( vkd->device(), &memReqInfo, &memReq); @@ -199,10 +182,7 @@ namespace dxvk { VkBufferView DxvkBufferView::createBufferView( const DxvkBufferSliceHandle& slice) { - VkBufferViewCreateInfo viewInfo; - viewInfo.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; - viewInfo.pNext = nullptr; - viewInfo.flags = 0; + VkBufferViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO }; viewInfo.buffer = slice.handle; viewInfo.format = m_info.format; viewInfo.offset = slice.offset; From 6276d5503c101fac5348e63cec28db2f5a4a00d3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 14:31:09 +0200 Subject: [PATCH 0269/1348] =?UTF-8?q?[=C3=B0xvk]=20Clean=20up=20some=20dev?= =?UTF-8?q?ice=20creation=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/dxvk/dxvk_adapter.cpp | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index f35790596..3a49b651c 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -28,12 +28,8 @@ namespace dxvk { DxvkAdapterMemoryInfo DxvkAdapter::getMemoryHeapInfo() const { - VkPhysicalDeviceMemoryBudgetPropertiesEXT memBudget = { }; - memBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; - memBudget.pNext = nullptr; - - VkPhysicalDeviceMemoryProperties2 memProps = { }; - memProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; + VkPhysicalDeviceMemoryBudgetPropertiesEXT memBudget = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT }; + VkPhysicalDeviceMemoryProperties2 memProps = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 }; memProps.pNext = m_hasMemoryBudget ? &memBudget : nullptr; m_vki->vkGetPhysicalDeviceMemoryProperties2(m_handle, &memProps); @@ -428,9 +424,7 @@ namespace dxvk { } // Report the desired overallocation behaviour to the driver - VkDeviceMemoryOverallocationCreateInfoAMD overallocInfo; - overallocInfo.sType = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD; - overallocInfo.pNext = nullptr; + VkDeviceMemoryOverallocationCreateInfoAMD overallocInfo = { VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD }; overallocInfo.overallocationBehavior = VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD; // Create the requested queues @@ -445,24 +439,16 @@ namespace dxvk { this->logQueueFamilies(queueFamilies); for (uint32_t family : queueFamiliySet) { - VkDeviceQueueCreateInfo graphicsQueue; - graphicsQueue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - graphicsQueue.pNext = nullptr; - graphicsQueue.flags = 0; + VkDeviceQueueCreateInfo graphicsQueue = { VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO }; graphicsQueue.queueFamilyIndex = family; graphicsQueue.queueCount = 1; graphicsQueue.pQueuePriorities = &queuePriority; queueInfos.push_back(graphicsQueue); } - VkDeviceCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - info.pNext = enabledFeatures.core.pNext; - info.flags = 0; + VkDeviceCreateInfo info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, &enabledFeatures.core.pNext }; info.queueCreateInfoCount = queueInfos.size(); info.pQueueCreateInfos = queueInfos.data(); - info.enabledLayerCount = 0; - info.ppEnabledLayerNames = nullptr; info.enabledExtensionCount = extensionNameList.count(); info.ppEnabledExtensionNames = extensionNameList.names(); info.pEnabledFeatures = &enabledFeatures.core.features; From 04f43f0d2c599dc0b653c2320df40de5265192dc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 14:36:08 +0200 Subject: [PATCH 0270/1348] [dxvk] Clean up sampler creation code --- src/dxvk/dxvk_sampler.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/dxvk/dxvk_sampler.cpp b/src/dxvk/dxvk_sampler.cpp index c10e82d02..00d926555 100644 --- a/src/dxvk/dxvk_sampler.cpp +++ b/src/dxvk/dxvk_sampler.cpp @@ -7,15 +7,10 @@ namespace dxvk { DxvkDevice* device, const DxvkSamplerCreateInfo& info) : m_vkd(device->vkd()) { - VkSamplerCustomBorderColorCreateInfoEXT borderColorInfo; - borderColorInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT; - borderColorInfo.pNext = nullptr; + VkSamplerCustomBorderColorCreateInfoEXT borderColorInfo = { VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT }; borderColorInfo.customBorderColor = info.borderColor; - borderColorInfo.format = VK_FORMAT_UNDEFINED; - VkSamplerCreateInfo samplerInfo; - samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerInfo.pNext = nullptr; + VkSamplerCreateInfo samplerInfo = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; samplerInfo.flags = info.nonSeamless ? VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT : 0; samplerInfo.magFilter = info.magFilter; samplerInfo.minFilter = info.minFilter; @@ -42,7 +37,7 @@ namespace dxvk { samplerInfo.borderColor = getBorderColor(device, info); if (samplerInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) - samplerInfo.pNext = &borderColorInfo; + borderColorInfo.pNext = std::exchange(samplerInfo.pNext, &borderColorInfo); if (m_vkd->vkCreateSampler(m_vkd->device(), &samplerInfo, nullptr, &m_sampler) != VK_SUCCESS) From fc461d0e27b75865f309b4d87fe0e9b6d834bb73 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 14:49:28 +0200 Subject: [PATCH 0271/1348] [dxvk] Clean up some swapchain creation code --- src/vulkan/vulkan_presenter.cpp | 47 +++++++-------------------------- 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index 17e1067a3..f83ed22e0 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -64,15 +64,12 @@ namespace dxvk::vk { VkResult Presenter::presentImage() { PresenterSync sync = m_semaphores.at(m_frameIndex); - VkPresentInfoKHR info; - info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - info.pNext = nullptr; + VkPresentInfoKHR info = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR }; info.waitSemaphoreCount = 1; info.pWaitSemaphores = &sync.present; info.swapchainCount = 1; info.pSwapchains = &m_swapchain; info.pImageIndices = &m_imageIndex; - info.pResults = nullptr; VkResult status = m_vkd->vkQueuePresentKHR(m_device.queue, &info); @@ -144,15 +141,10 @@ namespace dxvk::vk { return VK_SUCCESS; } - VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo; - fullScreenInfo.sType = VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT; - fullScreenInfo.pNext = nullptr; + VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; fullScreenInfo.fullScreenExclusive = desc.fullScreenExclusive; - VkSwapchainCreateInfoKHR swapInfo; - swapInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - swapInfo.pNext = nullptr; - swapInfo.flags = 0; + VkSwapchainCreateInfoKHR swapInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR }; swapInfo.surface = m_surface; swapInfo.minImageCount = m_info.imageCount; swapInfo.imageFormat = m_info.format.format; @@ -162,8 +154,6 @@ namespace dxvk::vk { swapInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; swapInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - swapInfo.queueFamilyIndexCount = 0; - swapInfo.pQueueFamilyIndices = nullptr; swapInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; swapInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; swapInfo.presentMode = m_info.presentMode; @@ -198,10 +188,7 @@ namespace dxvk::vk { for (uint32_t i = 0; i < m_info.imageCount; i++) { m_images[i].image = images[i]; - VkImageViewCreateInfo viewInfo; - viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewInfo.pNext = nullptr; - viewInfo.flags = 0; + VkImageViewCreateInfo viewInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; viewInfo.image = images[i]; viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; viewInfo.format = m_info.format.format; @@ -221,10 +208,7 @@ namespace dxvk::vk { m_semaphores.resize(m_info.imageCount); for (uint32_t i = 0; i < m_semaphores.size(); i++) { - VkSemaphoreCreateInfo semInfo; - semInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - semInfo.pNext = nullptr; - semInfo.flags = 0; + VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(), &semInfo, nullptr, &m_semaphores[i].acquire)) != VK_SUCCESS) @@ -256,14 +240,10 @@ namespace dxvk::vk { VkResult Presenter::getSupportedFormats(std::vector& formats, const PresenterDesc& desc) { uint32_t numFormats = 0; - VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo; - fullScreenInfo.sType = VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT; - fullScreenInfo.pNext = nullptr; + VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; fullScreenInfo.fullScreenExclusive = desc.fullScreenExclusive; - VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo; - surfaceInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR; - surfaceInfo.pNext = &fullScreenInfo; + VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, &fullScreenInfo }; surfaceInfo.surface = m_surface; VkResult status; @@ -302,14 +282,10 @@ namespace dxvk::vk { VkResult Presenter::getSupportedPresentModes(std::vector& modes, const PresenterDesc& desc) { uint32_t numModes = 0; - VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo; - fullScreenInfo.sType = VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT; - fullScreenInfo.pNext = nullptr; + VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; fullScreenInfo.fullScreenExclusive = desc.fullScreenExclusive; - VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo; - surfaceInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR; - surfaceInfo.pNext = &fullScreenInfo; + VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, &fullScreenInfo }; surfaceInfo.surface = m_surface; VkResult status; @@ -448,10 +424,7 @@ namespace dxvk::vk { HINSTANCE instance = reinterpret_cast( GetWindowLongPtr(m_window, GWLP_HINSTANCE)); - VkWin32SurfaceCreateInfoKHR info; - info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; - info.pNext = nullptr; - info.flags = 0; + VkWin32SurfaceCreateInfoKHR info = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR }; info.hinstance = instance; info.hwnd = m_window; From 37f31ae1e76943652a79b401d9eab3b53c5cbb66 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 14:50:29 +0200 Subject: [PATCH 0272/1348] [dxvk] Clean up more code around object creation in meta passes --- src/dxvk/dxvk_meta_blit.cpp | 36 ++++---------------- src/dxvk/dxvk_meta_clear.cpp | 42 +++++------------------ src/dxvk/dxvk_meta_copy.cpp | 5 +-- src/dxvk/dxvk_meta_pack.cpp | 62 ++++++---------------------------- src/dxvk/dxvk_meta_pack.h | 2 +- src/dxvk/dxvk_meta_resolve.cpp | 18 ++-------- 6 files changed, 30 insertions(+), 135 deletions(-) diff --git a/src/dxvk/dxvk_meta_blit.cpp b/src/dxvk/dxvk_meta_blit.cpp index e36debc7f..e99238b93 100644 --- a/src/dxvk/dxvk_meta_blit.cpp +++ b/src/dxvk/dxvk_meta_blit.cpp @@ -74,15 +74,10 @@ namespace dxvk { VK_IMAGE_VIEW_TYPE_2D_ARRAY, }}; - VkImageViewUsageCreateInfo usageInfo; - usageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO; - usageInfo.pNext = nullptr; + VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; usageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - VkImageViewCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - info.pNext = &usageInfo; - info.flags = 0; + VkImageViewCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo }; info.image = m_dstImage->handle(); info.viewType = viewTypes.at(uint32_t(m_dstImage->info().type)); info.format = m_dstImage->info().format; @@ -102,15 +97,10 @@ namespace dxvk { VkImageView DxvkMetaBlitRenderPass::createSrcView(const VkComponentMapping& mapping) { - VkImageViewUsageCreateInfo usageInfo; - usageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO; - usageInfo.pNext = nullptr; + VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO }; usageInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; - VkImageViewCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - info.pNext = &usageInfo; - info.flags = 0; + VkImageViewCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo }; info.image = m_srcImage->handle(); info.viewType = this->viewType(); info.format = m_srcImage->info().format; @@ -189,25 +179,14 @@ namespace dxvk { VkSampler DxvkMetaBlitObjects::createSampler(VkFilter filter) const { - VkSamplerCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkSamplerCreateInfo info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; info.magFilter = filter; info.minFilter = filter; info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.mipLodBias = 0.0f; - info.anisotropyEnable = VK_FALSE; - info.maxAnisotropy = 1.0f; - info.compareEnable = VK_FALSE; - info.compareOp = VK_COMPARE_OP_ALWAYS; - info.minLod = 0.0f; - info.maxLod = 0.0f; info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; - info.unnormalizedCoordinates = VK_FALSE; VkSampler result = VK_NULL_HANDLE; if (m_vkd->vkCreateSampler(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) @@ -217,10 +196,7 @@ namespace dxvk { VkShaderModule DxvkMetaBlitObjects::createShaderModule(const SpirvCodeBuffer& code) const { - VkShaderModuleCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkShaderModuleCreateInfo info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; info.codeSize = code.size(); info.pCode = code.data(); diff --git a/src/dxvk/dxvk_meta_clear.cpp b/src/dxvk/dxvk_meta_clear.cpp index d5b3381d2..e6b2fc363 100644 --- a/src/dxvk/dxvk_meta_clear.cpp +++ b/src/dxvk/dxvk_meta_clear.cpp @@ -116,17 +116,9 @@ namespace dxvk { VkDescriptorSetLayout DxvkMetaClearObjects::createDescriptorSetLayout( VkDescriptorType descriptorType) { - VkDescriptorSetLayoutBinding bindInfo; - bindInfo.binding = 0; - bindInfo.descriptorType = descriptorType; - bindInfo.descriptorCount = 1; - bindInfo.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; - bindInfo.pImmutableSamplers = nullptr; + VkDescriptorSetLayoutBinding bindInfo = { 0, descriptorType, 1, VK_SHADER_STAGE_COMPUTE_BIT }; - VkDescriptorSetLayoutCreateInfo dsetInfo; - dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - dsetInfo.pNext = nullptr; - dsetInfo.flags = 0; + VkDescriptorSetLayoutCreateInfo dsetInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; dsetInfo.bindingCount = 1; dsetInfo.pBindings = &bindInfo; @@ -140,17 +132,11 @@ namespace dxvk { VkPipelineLayout DxvkMetaClearObjects::createPipelineLayout( VkDescriptorSetLayout dsetLayout) { - VkPushConstantRange pushInfo; - pushInfo.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; - pushInfo.offset = 0; - pushInfo.size = sizeof(DxvkMetaClearArgs); + VkPushConstantRange pushInfo = { VK_SHADER_STAGE_COMPUTE_BIT, 0, uint32_t(sizeof(DxvkMetaClearArgs)) }; - VkPipelineLayoutCreateInfo pipeInfo; - pipeInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeInfo.pNext = nullptr; - pipeInfo.flags = 0; - pipeInfo.setLayoutCount = 1; - pipeInfo.pSetLayouts = &dsetLayout; + VkPipelineLayoutCreateInfo pipeInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; + pipeInfo.setLayoutCount = 1; + pipeInfo.pSetLayouts = &dsetLayout; pipeInfo.pushConstantRangeCount = 1; pipeInfo.pPushConstantRanges = &pushInfo; @@ -165,10 +151,7 @@ namespace dxvk { VkPipeline DxvkMetaClearObjects::createPipeline( const SpirvCodeBuffer& spirvCode, VkPipelineLayout pipeLayout) { - VkShaderModuleCreateInfo shaderInfo; - shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - shaderInfo.pNext = nullptr; - shaderInfo.flags = 0; + VkShaderModuleCreateInfo shaderInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; shaderInfo.codeSize = spirvCode.size(); shaderInfo.pCode = spirvCode.data(); @@ -177,22 +160,15 @@ namespace dxvk { &shaderInfo, nullptr, &shaderModule) != VK_SUCCESS) throw DxvkError("Dxvk: Failed to create meta clear shader module"); - VkPipelineShaderStageCreateInfo stageInfo; - stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - stageInfo.pNext = nullptr; - stageInfo.flags = 0; + VkPipelineShaderStageCreateInfo stageInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO }; stageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; stageInfo.module = shaderModule; stageInfo.pName = "main"; stageInfo.pSpecializationInfo = nullptr; - VkComputePipelineCreateInfo pipeInfo; - pipeInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - pipeInfo.pNext = nullptr; - pipeInfo.flags = 0; + VkComputePipelineCreateInfo pipeInfo = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; pipeInfo.stage = stageInfo; pipeInfo.layout = pipeLayout; - pipeInfo.basePipelineHandle = VK_NULL_HANDLE; pipeInfo.basePipelineIndex = -1; VkPipeline result = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index 7f7e11a29..4368f13da 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -192,10 +192,7 @@ namespace dxvk { VkShaderModule DxvkMetaCopyObjects::createShaderModule( const SpirvCodeBuffer& code) const { - VkShaderModuleCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkShaderModuleCreateInfo info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; info.codeSize = code.size(); info.pCode = code.data(); diff --git a/src/dxvk/dxvk_meta_pack.cpp b/src/dxvk/dxvk_meta_pack.cpp index dbf4999b3..f18bb7cc2 100644 --- a/src/dxvk/dxvk_meta_pack.cpp +++ b/src/dxvk/dxvk_meta_pack.cpp @@ -92,23 +92,13 @@ namespace dxvk { VkSampler DxvkMetaPackObjects::createSampler() { - VkSamplerCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkSamplerCreateInfo info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; info.magFilter = VK_FILTER_NEAREST; info.minFilter = VK_FILTER_NEAREST; info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.mipLodBias = 0.0f; - info.anisotropyEnable = VK_FALSE; - info.maxAnisotropy = 1.0f; - info.compareEnable = VK_FALSE; - info.compareOp = VK_COMPARE_OP_ALWAYS; - info.minLod = 0.0f; - info.maxLod = 0.0f; info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; info.unnormalizedCoordinates = VK_FALSE; @@ -126,10 +116,7 @@ namespace dxvk { { 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, &m_sampler }, }}; - VkDescriptorSetLayoutCreateInfo dsetInfo; - dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - dsetInfo.pNext = nullptr; - dsetInfo.flags = 0; + VkDescriptorSetLayoutCreateInfo dsetInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; dsetInfo.bindingCount = bindings.size(); dsetInfo.pBindings = bindings.data(); @@ -147,10 +134,7 @@ namespace dxvk { { 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, }}; - VkDescriptorSetLayoutCreateInfo dsetInfo; - dsetInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - dsetInfo.pNext = nullptr; - dsetInfo.flags = 0; + VkDescriptorSetLayoutCreateInfo dsetInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; dsetInfo.bindingCount = bindings.size(); dsetInfo.pBindings = bindings.data(); @@ -163,16 +147,10 @@ namespace dxvk { VkPipelineLayout DxvkMetaPackObjects::createPipelineLayout( VkDescriptorSetLayout dsetLayout, - size_t pushLayout) { - VkPushConstantRange push; - push.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; - push.offset = 0; - push.size = pushLayout; + uint32_t pushLayout) { + VkPushConstantRange push = { VK_SHADER_STAGE_COMPUTE_BIT, 0, pushLayout }; - VkPipelineLayoutCreateInfo layoutInfo; - layoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - layoutInfo.pNext = nullptr; - layoutInfo.flags = 0; + VkPipelineLayoutCreateInfo layoutInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; layoutInfo.setLayoutCount = 1; layoutInfo.pSetLayouts = &dsetLayout; layoutInfo.pushConstantRangeCount = 1; @@ -192,17 +170,13 @@ namespace dxvk { { 2, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, offsetof(DxvkMetaPackDescriptors, srcStencil), 0 }, }}; - VkDescriptorUpdateTemplateCreateInfo templateInfo; - templateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO; - templateInfo.pNext = nullptr; - templateInfo.flags = 0; + VkDescriptorUpdateTemplateCreateInfo templateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO }; templateInfo.descriptorUpdateEntryCount = bindings.size(); templateInfo.pDescriptorUpdateEntries = bindings.data(); templateInfo.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET; templateInfo.descriptorSetLayout = m_dsetLayoutPack; templateInfo.pipelineBindPoint = VK_PIPELINE_BIND_POINT_COMPUTE; templateInfo.pipelineLayout = m_pipeLayoutPack; - templateInfo.set = 0; VkDescriptorUpdateTemplate result = VK_NULL_HANDLE; if (m_vkd->vkCreateDescriptorUpdateTemplate(m_vkd->device(), @@ -219,10 +193,7 @@ namespace dxvk { { 2, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, offsetof(DxvkMetaUnpackDescriptors, srcBuffer), 0 }, }}; - VkDescriptorUpdateTemplateCreateInfo templateInfo; - templateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO; - templateInfo.pNext = nullptr; - templateInfo.flags = 0; + VkDescriptorUpdateTemplateCreateInfo templateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO }; templateInfo.descriptorUpdateEntryCount = bindings.size(); templateInfo.pDescriptorUpdateEntries = bindings.data(); templateInfo.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET; @@ -242,10 +213,7 @@ namespace dxvk { VkPipeline DxvkMetaPackObjects::createPipeline( VkPipelineLayout pipeLayout, const SpirvCodeBuffer& code) { - VkShaderModuleCreateInfo shaderInfo; - shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - shaderInfo.pNext = nullptr; - shaderInfo.flags = 0; + VkShaderModuleCreateInfo shaderInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; shaderInfo.codeSize = code.size(); shaderInfo.pCode = code.data(); @@ -254,22 +222,14 @@ namespace dxvk { if (m_vkd->vkCreateShaderModule(m_vkd->device(), &shaderInfo, nullptr, &module) != VK_SUCCESS) throw DxvkError("DxvkMetaPackObjects: Failed to create shader module"); - VkPipelineShaderStageCreateInfo stageInfo; - stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - stageInfo.pNext = nullptr; - stageInfo.flags = 0; + VkPipelineShaderStageCreateInfo stageInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO }; stageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; stageInfo.module = module; stageInfo.pName = "main"; - stageInfo.pSpecializationInfo = nullptr; - VkComputePipelineCreateInfo pipeInfo; - pipeInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - pipeInfo.pNext = nullptr; - pipeInfo.flags = 0; + VkComputePipelineCreateInfo pipeInfo = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; pipeInfo.stage = stageInfo; pipeInfo.layout = pipeLayout; - pipeInfo.basePipelineHandle = VK_NULL_HANDLE; pipeInfo.basePipelineIndex = -1; VkPipeline result = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_meta_pack.h b/src/dxvk/dxvk_meta_pack.h index 7c69d8c36..133ce24b2 100644 --- a/src/dxvk/dxvk_meta_pack.h +++ b/src/dxvk/dxvk_meta_pack.h @@ -118,7 +118,7 @@ namespace dxvk { VkPipelineLayout createPipelineLayout( VkDescriptorSetLayout dsetLayout, - size_t pushLayout); + uint32_t pushLayout); VkDescriptorUpdateTemplateKHR createPackDescriptorUpdateTemplate(); diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index b71b686bc..26cde48e5 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -116,25 +116,14 @@ namespace dxvk { VkSampler DxvkMetaResolveObjects::createSampler() const { - VkSamplerCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkSamplerCreateInfo info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; info.magFilter = VK_FILTER_NEAREST; info.minFilter = VK_FILTER_NEAREST; info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.mipLodBias = 0.0f; - info.anisotropyEnable = VK_FALSE; - info.maxAnisotropy = 1.0f; - info.compareEnable = VK_FALSE; - info.compareOp = VK_COMPARE_OP_ALWAYS; - info.minLod = 0.0f; - info.maxLod = 0.0f; info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; - info.unnormalizedCoordinates = VK_FALSE; VkSampler result = VK_NULL_HANDLE; if (m_vkd->vkCreateSampler(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) @@ -145,10 +134,7 @@ namespace dxvk { VkShaderModule DxvkMetaResolveObjects::createShaderModule( const SpirvCodeBuffer& code) const { - VkShaderModuleCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkShaderModuleCreateInfo info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; info.codeSize = code.size(); info.pCode = code.data(); From a1ace8ef21a9810e0995354f99fe3e4bbddcde25 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 14:51:26 +0200 Subject: [PATCH 0273/1348] [dxvk] Clean up misc. code --- src/dxvk/dxvk_barrier.cpp | 12 +++--------- src/dxvk/dxvk_context.cpp | 22 ++++------------------ src/dxvk/dxvk_image.cpp | 10 ++++------ 3 files changed, 11 insertions(+), 33 deletions(-) diff --git a/src/dxvk/dxvk_barrier.cpp b/src/dxvk/dxvk_barrier.cpp index 65acedc98..c5b000f85 100644 --- a/src/dxvk/dxvk_barrier.cpp +++ b/src/dxvk/dxvk_barrier.cpp @@ -104,9 +104,7 @@ namespace dxvk { if (access.test(DxvkAccess::Write)) m_dstAccess |= dstAccess; } else { - VkImageMemoryBarrier barrier; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.pNext = nullptr; + VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; barrier.srcAccessMask = srcAccess & AccessWriteMask; barrier.dstAccessMask = dstAccess; barrier.oldLayout = srcLayout; @@ -138,9 +136,7 @@ namespace dxvk { release.m_srcStages |= srcStages; acquire.m_dstStages |= dstStages; - VkBufferMemoryBarrier barrier; - barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; - barrier.pNext = nullptr; + VkBufferMemoryBarrier barrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER }; barrier.srcAccessMask = srcAccess & AccessWriteMask; barrier.dstAccessMask = 0; barrier.srcQueueFamilyIndex = srcQueue; @@ -248,9 +244,7 @@ namespace dxvk { if (!srcFlags) srcFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; if (!dstFlags) dstFlags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - VkMemoryBarrier memBarrier; - memBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; - memBarrier.pNext = nullptr; + VkMemoryBarrier memBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER }; memBarrier.srcAccessMask = m_srcAccess; memBarrier.dstAccessMask = m_dstAccess; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 74c3fbafb..f100dd9ad 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -23,11 +23,7 @@ namespace dxvk { m_state.om.framebufferInfo = makeFramebufferInfo(m_state.om.renderTargets); for (uint32_t i = 0; i < MaxNumActiveBindings; i++) { - m_descriptorWrites[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - m_descriptorWrites[i].pNext = nullptr; - m_descriptorWrites[i].dstSet = VK_NULL_HANDLE; - m_descriptorWrites[i].dstBinding = 0; - m_descriptorWrites[i].dstArrayElement = 0; + m_descriptorWrites[i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; m_descriptorWrites[i].descriptorCount = 1; m_descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_MAX_ENUM; m_descriptorWrites[i].pImageInfo = &m_descriptors[i].image; @@ -326,16 +322,12 @@ namespace dxvk { VkDescriptorSet descriptorSet = m_descriptorPool->alloc(pipeInfo.dsetLayout); - VkWriteDescriptorSet descriptorWrite; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.pNext = nullptr; + VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; descriptorWrite.dstSet = descriptorSet; descriptorWrite.dstBinding = 0; descriptorWrite.dstArrayElement = 0; descriptorWrite.descriptorCount = 1; descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; - descriptorWrite.pImageInfo = nullptr; - descriptorWrite.pBufferInfo = nullptr; descriptorWrite.pTexelBufferView = &viewObject; m_cmd->updateDescriptorSets(1, &descriptorWrite); @@ -3163,17 +3155,13 @@ namespace dxvk { viewInfo.imageView = imageView->handle(); viewInfo.imageLayout = imageView->imageInfo().layout; - VkWriteDescriptorSet descriptorWrite; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.pNext = nullptr; + VkWriteDescriptorSet descriptorWrite = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; descriptorWrite.dstSet = descriptorSet; descriptorWrite.dstBinding = 0; descriptorWrite.dstArrayElement = 0; descriptorWrite.descriptorCount = 1; descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; descriptorWrite.pImageInfo = &viewInfo; - descriptorWrite.pBufferInfo = nullptr; - descriptorWrite.pTexelBufferView = nullptr; m_cmd->updateDescriptorSets(1, &descriptorWrite); // Prepare shader arguments @@ -5681,9 +5669,7 @@ namespace dxvk { VkAccessFlags srcAccess, VkPipelineStageFlags dstStages, VkAccessFlags dstAccess) { - VkMemoryBarrier barrier; - barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; - barrier.pNext = nullptr; + VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER }; barrier.srcAccessMask = srcAccess; barrier.dstAccessMask = dstAccess; diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index d1b330f4b..f08ce410c 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -41,13 +41,11 @@ namespace dxvk { m_shared = canShareImage(info, createInfo.sharing); - VkExternalMemoryImageCreateInfo externalInfo; - if (m_shared) { - externalInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO; - externalInfo.pNext = nullptr; - externalInfo.handleTypes = createInfo.sharing.type; + VkExternalMemoryImageCreateInfo externalInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO }; - formatList.pNext = &externalInfo; + if (m_shared) { + externalInfo.pNext = std::exchange(info.pNext, &externalInfo); + externalInfo.handleTypes = createInfo.sharing.type; } if (m_vkd->vkCreateImage(m_vkd->device(), From 9ebeb8e502f5ce33c7fc642b8826ec17f0b0accc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 14:51:40 +0200 Subject: [PATCH 0274/1348] [dxvk] Clean up instance creation code a bit --- src/dxvk/dxvk_instance.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index e6fabd8c2..8c6c3deb1 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -122,22 +122,14 @@ namespace dxvk { std::string appName = env::getExeName(); - VkApplicationInfo appInfo; - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pNext = nullptr; + VkApplicationInfo appInfo = { VK_STRUCTURE_TYPE_APPLICATION_INFO }; appInfo.pApplicationName = appName.c_str(); - appInfo.applicationVersion = 0; appInfo.pEngineName = "DXVK"; appInfo.engineVersion = VK_MAKE_VERSION(1, 10, 1); appInfo.apiVersion = VK_MAKE_VERSION(1, 3, 0); - VkInstanceCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; info.pApplicationInfo = &appInfo; - info.enabledLayerCount = 0; - info.ppEnabledLayerNames = nullptr; info.enabledExtensionCount = extensionNameList.count(); info.ppEnabledExtensionNames = extensionNameList.names(); From a76b5693f3245cf705c54412e9f2939413f49772 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 14:52:12 +0200 Subject: [PATCH 0275/1348] [dxvk] Clean up remaining object creation code --- src/dxvk/dxvk_descriptor.cpp | 5 +---- src/dxvk/dxvk_gpu_event.cpp | 5 +---- src/dxvk/dxvk_gpu_query.cpp | 6 +----- src/dxvk/dxvk_memory.cpp | 11 +++++------ 4 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index 112011cb1..bb09d5178 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -305,10 +305,7 @@ namespace dxvk { { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, maxSets / 64 }, { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, maxSets * 1 } }}; - VkDescriptorPoolCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkDescriptorPoolCreateInfo info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; info.maxSets = maxSets; info.poolSizeCount = pools.size(); info.pPoolSizes = pools.data(); diff --git a/src/dxvk/dxvk_gpu_event.cpp b/src/dxvk/dxvk_gpu_event.cpp index b54303f7d..6166ca09a 100644 --- a/src/dxvk/dxvk_gpu_event.cpp +++ b/src/dxvk/dxvk_gpu_event.cpp @@ -58,10 +58,7 @@ namespace dxvk { } if (!event) { - VkEventCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkEventCreateInfo info = { VK_STRUCTURE_TYPE_EVENT_CREATE_INFO }; VkResult status = m_vkd->vkCreateEvent( m_vkd->device(), &info, nullptr, &event); diff --git a/src/dxvk/dxvk_gpu_query.cpp b/src/dxvk/dxvk_gpu_query.cpp index 40d3a0910..426b58f6e 100644 --- a/src/dxvk/dxvk_gpu_query.cpp +++ b/src/dxvk/dxvk_gpu_query.cpp @@ -183,13 +183,9 @@ namespace dxvk { void DxvkGpuQueryAllocator::createQueryPool() { - VkQueryPoolCreateInfo info; - info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; - info.pNext = nullptr; - info.flags = 0; + VkQueryPoolCreateInfo info = { VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO }; info.queryType = m_queryType; info.queryCount = m_queryPoolSize; - info.pipelineStatistics = 0; if (m_queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS) { info.pipelineStatistics diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 279700d85..308bee3e1 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -407,17 +407,16 @@ namespace dxvk { result.memFlags = flags; result.priority = priority; - VkMemoryPriorityAllocateInfoEXT prio; - prio.sType = VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT; - prio.pNext = dedAllocInfo; + VkMemoryPriorityAllocateInfoEXT prio = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT }; prio.priority = priority; - VkMemoryAllocateInfo info; - info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - info.pNext = useMemoryPriority ? &prio : prio.pNext; + VkMemoryAllocateInfo info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, dedAllocInfo }; info.allocationSize = size; info.memoryTypeIndex = type->memTypeId; + if (useMemoryPriority) + prio.pNext = std::exchange(info.pNext, &prio); + if (m_vkd->vkAllocateMemory(m_vkd->device(), &info, nullptr, &result.memHandle) != VK_SUCCESS) return DxvkDeviceMemory(); From e6df48fa3e7de35f8b0419b6a73f4db1698585ba Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 14:53:29 +0200 Subject: [PATCH 0276/1348] [dxvk] Fix a derp --- src/dxvk/dxvk_adapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 3a49b651c..9ad973463 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -446,7 +446,7 @@ namespace dxvk { queueInfos.push_back(graphicsQueue); } - VkDeviceCreateInfo info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, &enabledFeatures.core.pNext }; + VkDeviceCreateInfo info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, enabledFeatures.core.pNext }; info.queueCreateInfoCount = queueInfos.size(); info.pQueueCreateInfos = queueInfos.data(); info.enabledExtensionCount = extensionNameList.count(); From e28b268351ba9ff86fb39804ae12c770b6e08547 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Mon, 18 Jul 2022 19:02:47 +0200 Subject: [PATCH 0277/1348] [util] Enable disableMsaa option for Mary Skelter 2 --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 7051dbbf7..b4bb740c7 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -232,6 +232,10 @@ namespace dxvk { * use of 4x MSAA throughout the renderer */ { R"(\\WOFF\.exe$)", {{ { "d3d11.disableMsaa", "True" }, + }} }, + /* Mary Skelter 2 - Broken MSAA */ + { R"(\\MarySkelter2\.exe$)", {{ + { "d3d11.disableMsaa", "True" }, }} }, /* Final Fantasy XIV - Stuttering on NV */ { R"(\\ffxiv_dx11\.exe$)", {{ From 17205f53532b9768f72f473f0decd701f9220bc0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 16:09:10 +0200 Subject: [PATCH 0278/1348] [dxvk] Fix formatting in barrier function --- src/dxvk/dxvk_context.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index f100dd9ad..e8e6bc7fa 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5393,11 +5393,11 @@ namespace dxvk { // Skip write-after-write barriers if explicitly requested VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT - | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; + | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) - && (!(m_execBarriers.getSrcStages() & ~stageMask)) - && ((srcAccess | dstAccess) == DxvkAccess::Write)) + && (!(m_execBarriers.getSrcStages() & ~stageMask)) + && ((srcAccess | dstAccess) == DxvkAccess::Write)) continue; requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); From 0d65142136aa24861b8040c8feb5ecfba1907773 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 15:29:26 +0200 Subject: [PATCH 0279/1348] [dxvk] Add entry points for new synchronization API --- src/vulkan/vulkan_loader.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index e0e221b3e..0cf6851d7 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -165,6 +165,7 @@ namespace dxvk::vk { VULKAN_FN(vkDestroyDevice); VULKAN_FN(vkGetDeviceQueue); VULKAN_FN(vkQueueSubmit); + VULKAN_FN(vkQueueSubmit2); VULKAN_FN(vkQueueWaitIdle); VULKAN_FN(vkDeviceWaitIdle); VULKAN_FN(vkAllocateMemory); @@ -295,13 +296,18 @@ namespace dxvk::vk { VULKAN_FN(vkCmdClearAttachments); VULKAN_FN(vkCmdResolveImage); VULKAN_FN(vkCmdSetEvent); + VULKAN_FN(vkCmdSetEvent2); VULKAN_FN(vkCmdResetEvent); + VULKAN_FN(vkCmdResetEvent2); VULKAN_FN(vkCmdWaitEvents); + VULKAN_FN(vkCmdWaitEvents2); VULKAN_FN(vkCmdPipelineBarrier); + VULKAN_FN(vkCmdPipelineBarrier2); VULKAN_FN(vkCmdBeginQuery); VULKAN_FN(vkCmdEndQuery); VULKAN_FN(vkCmdResetQueryPool); VULKAN_FN(vkCmdWriteTimestamp); + VULKAN_FN(vkCmdWriteTimestamp2); VULKAN_FN(vkCmdCopyQueryPoolResults); VULKAN_FN(vkCmdPushConstants); VULKAN_FN(vkCmdBeginRenderPass); From adb906b18cb23f441cfb5850bca4eabbaf4c250a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 15:43:19 +0200 Subject: [PATCH 0280/1348] [dxvk] Use synchronization2 functions for barriers We don't really use the new stage/access flags yet, and I'm not sure whether we will move to them since the benefits seem rather limited. However, using the functions means we can bypass a lot of internal translation inside some Vulkan drivers. --- src/dxvk/dxvk_barrier.cpp | 113 +++++++++++++++++++------------------- src/dxvk/dxvk_barrier.h | 15 ++--- src/dxvk/dxvk_cmdlist.h | 16 +----- src/dxvk/dxvk_context.cpp | 40 ++++++++------ src/dxvk/dxvk_context.h | 1 - 5 files changed, 87 insertions(+), 98 deletions(-) diff --git a/src/dxvk/dxvk_barrier.cpp b/src/dxvk/dxvk_barrier.cpp index c5b000f85..546e871ee 100644 --- a/src/dxvk/dxvk_barrier.cpp +++ b/src/dxvk/dxvk_barrier.cpp @@ -44,13 +44,13 @@ namespace dxvk { VkAccessFlags dstAccess) { DxvkAccessFlags access = this->getAccessTypes(srcAccess); - m_srcStages |= srcStages; - m_dstStages |= dstStages; - - m_srcAccess |= srcAccess & AccessWriteMask; + m_allBarrierSrcStages |= srcStages; + m_memBarrier.srcStageMask |= srcStages; + m_memBarrier.srcAccessMask |= srcAccess & AccessWriteMask; + m_memBarrier.dstStageMask |= dstStages; if (access.test(DxvkAccess::Write)) - m_dstAccess |= dstAccess; + m_memBarrier.dstAccessMask |= dstAccess; } @@ -62,17 +62,13 @@ namespace dxvk { VkAccessFlags dstAccess) { DxvkAccessFlags access = this->getAccessTypes(srcAccess); - if (srcStages == VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT - || dstStages == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT) - access.set(DxvkAccess::Write); + m_allBarrierSrcStages |= srcStages; + m_memBarrier.srcStageMask |= srcStages; + m_memBarrier.srcAccessMask |= srcAccess & AccessWriteMask; + m_memBarrier.dstStageMask |= dstStages; - m_srcStages |= srcStages; - m_dstStages |= dstStages; - - m_srcAccess |= srcAccess & AccessWriteMask; - if (access.test(DxvkAccess::Write)) - m_dstAccess |= dstAccess; + m_memBarrier.dstAccessMask |= dstAccess; m_bufSlices.insert(bufSlice.handle, DxvkBarrierBufferSlice(bufSlice.offset, bufSlice.length, access)); @@ -90,22 +86,20 @@ namespace dxvk { VkAccessFlags dstAccess) { DxvkAccessFlags access = this->getAccessTypes(srcAccess); - if (srcStages == VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT - || dstStages == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT - || srcLayout != dstLayout) - access.set(DxvkAccess::Write); - - m_srcStages |= srcStages; - m_dstStages |= dstStages; - + m_allBarrierSrcStages |= srcStages; + if (srcLayout == dstLayout) { - m_srcAccess |= srcAccess & AccessWriteMask; + m_memBarrier.srcStageMask |= srcStages; + m_memBarrier.srcAccessMask |= srcAccess & AccessWriteMask; + m_memBarrier.dstStageMask |= dstStages; if (access.test(DxvkAccess::Write)) - m_dstAccess |= dstAccess; + m_memBarrier.dstAccessMask |= dstAccess; } else { - VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; + VkImageMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; + barrier.srcStageMask = srcStages; barrier.srcAccessMask = srcAccess & AccessWriteMask; + barrier.dstStageMask = dstStages; barrier.dstAccessMask = dstAccess; barrier.oldLayout = srcLayout; barrier.newLayout = dstLayout; @@ -115,6 +109,8 @@ namespace dxvk { barrier.subresourceRange = subresources; barrier.subresourceRange.aspectMask = image->formatInfo()->aspectMask; m_imgBarriers.push_back(barrier); + + access.set(DxvkAccess::Write); } m_imgSlices.insert(image->handle(), @@ -133,11 +129,12 @@ namespace dxvk { VkAccessFlags dstAccess) { auto& release = *this; - release.m_srcStages |= srcStages; - acquire.m_dstStages |= dstStages; + m_allBarrierSrcStages |= srcStages; - VkBufferMemoryBarrier barrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER }; + VkBufferMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 }; + barrier.srcStageMask = srcStages; barrier.srcAccessMask = srcAccess & AccessWriteMask; + barrier.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; barrier.dstAccessMask = 0; barrier.srcQueueFamilyIndex = srcQueue; barrier.dstQueueFamilyIndex = dstQueue; @@ -146,7 +143,9 @@ namespace dxvk { barrier.size = bufSlice.length; release.m_bufBarriers.push_back(barrier); + barrier.srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; barrier.srcAccessMask = 0; + barrier.dstStageMask = dstStages; barrier.dstAccessMask = dstAccess; acquire.m_bufBarriers.push_back(barrier); @@ -172,13 +171,12 @@ namespace dxvk { VkAccessFlags dstAccess) { auto& release = *this; - release.m_srcStages |= srcStages; - acquire.m_dstStages |= dstStages; + m_allBarrierSrcStages |= srcStages; - VkImageMemoryBarrier barrier; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.pNext = nullptr; + VkImageMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; + barrier.srcStageMask = srcStages; barrier.srcAccessMask = srcAccess & AccessWriteMask; + barrier.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; barrier.dstAccessMask = 0; barrier.oldLayout = srcLayout; barrier.newLayout = dstLayout; @@ -192,7 +190,9 @@ namespace dxvk { if (srcQueue == dstQueue) barrier.oldLayout = dstLayout; + barrier.srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; barrier.srcAccessMask = 0; + barrier.dstStageMask = dstStages; barrier.dstAccessMask = dstAccess; acquire.m_imgBarriers.push_back(barrier); @@ -237,29 +237,25 @@ namespace dxvk { void DxvkBarrierSet::recordCommands(const Rc& commandList) { - if (m_srcStages | m_dstStages) { - VkPipelineStageFlags srcFlags = m_srcStages; - VkPipelineStageFlags dstFlags = m_dstStages; - - if (!srcFlags) srcFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - if (!dstFlags) dstFlags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + VkDependencyInfo depInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; - VkMemoryBarrier memBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER }; - memBarrier.srcAccessMask = m_srcAccess; - memBarrier.dstAccessMask = m_dstAccess; + if (m_memBarrier.srcStageMask | m_memBarrier.dstStageMask) { + depInfo.memoryBarrierCount = 1; + depInfo.pMemoryBarriers = &m_memBarrier; + } - VkMemoryBarrier* pMemBarrier = nullptr; - if (m_srcAccess | m_dstAccess) - pMemBarrier = &memBarrier; - - commandList->cmdPipelineBarrier( - m_cmdBuffer, srcFlags, dstFlags, 0, - pMemBarrier ? 1 : 0, pMemBarrier, - m_bufBarriers.size(), - m_bufBarriers.data(), - m_imgBarriers.size(), - m_imgBarriers.data()); - + if (!m_bufBarriers.empty()) { + depInfo.bufferMemoryBarrierCount = m_bufBarriers.size(); + depInfo.pBufferMemoryBarriers = m_bufBarriers.data(); + } + + if (!m_imgBarriers.empty()) { + depInfo.imageMemoryBarrierCount = m_imgBarriers.size(); + depInfo.pImageMemoryBarriers = m_imgBarriers.data(); + } + + if (depInfo.memoryBarrierCount + depInfo.bufferMemoryBarrierCount + depInfo.imageMemoryBarrierCount) { + commandList->cmdPipelineBarrier(m_cmdBuffer, &depInfo); commandList->addStatCtr(DxvkStatCounter::CmdBarrierCount, 1); this->reset(); @@ -268,11 +264,12 @@ namespace dxvk { void DxvkBarrierSet::reset() { - m_srcStages = 0; - m_dstStages = 0; + m_allBarrierSrcStages = 0; - m_srcAccess = 0; - m_dstAccess = 0; + m_memBarrier.srcStageMask = 0; + m_memBarrier.srcAccessMask = 0; + m_memBarrier.dstStageMask = 0; + m_memBarrier.dstAccessMask = 0; m_bufBarriers.resize(0); m_imgBarriers.resize(0); diff --git a/src/dxvk/dxvk_barrier.h b/src/dxvk/dxvk_barrier.h index 18308d1bf..ebe7080ba 100644 --- a/src/dxvk/dxvk_barrier.h +++ b/src/dxvk/dxvk_barrier.h @@ -538,7 +538,7 @@ namespace dxvk { const VkImageSubresourceRange& imgSubres); VkPipelineStageFlags getSrcStages() { - return m_srcStages; + return m_allBarrierSrcStages; } void recordCommands( @@ -567,15 +567,12 @@ namespace dxvk { }; DxvkCmdBuffer m_cmdBuffer; - - VkPipelineStageFlags m_srcStages = 0; - VkPipelineStageFlags m_dstStages = 0; - VkAccessFlags m_srcAccess = 0; - VkAccessFlags m_dstAccess = 0; - - std::vector m_bufBarriers; - std::vector m_imgBarriers; + VkPipelineStageFlags2 m_allBarrierSrcStages = 0; + + VkMemoryBarrier2 m_memBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 }; + std::vector m_bufBarriers; + std::vector m_imgBarriers; DxvkBarrierSubresourceSet m_bufSlices; DxvkBarrierSubresourceSet m_imgSlices; diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 36374b147..023db49f7 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -607,22 +607,10 @@ namespace dxvk { void cmdPipelineBarrier( DxvkCmdBuffer cmdBuffer, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - VkDependencyFlags dependencyFlags, - uint32_t memoryBarrierCount, - const VkMemoryBarrier* pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier* pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier* pImageMemoryBarriers) { + const VkDependencyInfo* dependencyInfo) { m_cmdBuffersUsed.set(cmdBuffer); - m_vkd->vkCmdPipelineBarrier(getCmdBuffer(cmdBuffer), - srcStageMask, dstStageMask, dependencyFlags, - memoryBarrierCount, pMemoryBarriers, - bufferMemoryBarrierCount, pBufferMemoryBarriers, - imageMemoryBarrierCount, pImageMemoryBarriers); + m_vkd->vkCmdPipelineBarrier2(getCmdBuffer(cmdBuffer), dependencyInfo); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index e8e6bc7fa..7b8c4a222 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -950,7 +950,7 @@ namespace dxvk { srcBufferSlice.handle, tmpBufferSlice.handle, 1, ©Region); - emitMemoryBarrier(0, + emitMemoryBarrier( VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, @@ -1456,7 +1456,8 @@ namespace dxvk { VkImageLayout initialLayout) { if (initialLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) { m_initBarriers.accessImage(image, subresources, - initialLayout, 0, 0, + initialLayout, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, image->info().layout, image->info().stages, image->info().access); @@ -1466,7 +1467,9 @@ namespace dxvk { VkImageLayout clearLayout = image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); m_execAcquires.accessImage(image, subresources, - initialLayout, 0, 0, clearLayout, + initialLayout, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, + clearLayout, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT); m_execAcquires.recordCommands(m_cmd); @@ -2261,7 +2264,8 @@ namespace dxvk { // Discard previous subresource contents barriers->accessImage(image, vk::makeSubresourceRange(subresources), - VK_IMAGE_LAYOUT_UNDEFINED, 0, 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT); @@ -4545,14 +4549,16 @@ namespace dxvk { srcBarrier.stages |= pipelineBarrier.stages; srcBarrier.access |= pipelineBarrier.access; - DxvkAccessFlags access = DxvkBarrierSet::getAccessTypes(srcBarrier.access); - DxvkGlobalPipelineBarrier dstBarrier = access.test(DxvkAccess::Write) - ? m_globalRwGraphicsBarrier - : m_globalRoGraphicsBarrier; + if (srcBarrier.stages) { + DxvkAccessFlags access = DxvkBarrierSet::getAccessTypes(srcBarrier.access); + DxvkGlobalPipelineBarrier dstBarrier = access.test(DxvkAccess::Write) + ? m_globalRwGraphicsBarrier + : m_globalRoGraphicsBarrier; - m_execBarriers.accessMemory( - srcBarrier.stages, srcBarrier.access, - dstBarrier.stages, dstBarrier.access); + m_execBarriers.accessMemory( + srcBarrier.stages, srcBarrier.access, + dstBarrier.stages, dstBarrier.access); + } m_flags.clr(DxvkContextFlag::GpDirtyPipelineState); return true; @@ -5664,19 +5670,21 @@ namespace dxvk { void DxvkContext::emitMemoryBarrier( - VkDependencyFlags flags, VkPipelineStageFlags srcStages, VkAccessFlags srcAccess, VkPipelineStageFlags dstStages, VkAccessFlags dstAccess) { - VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER }; + VkMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 }; + barrier.srcStageMask = srcStages; barrier.srcAccessMask = srcAccess; + barrier.dstStageMask = dstStages; barrier.dstAccessMask = dstAccess; - m_cmd->cmdPipelineBarrier( - DxvkCmdBuffer::ExecBuffer, srcStages, dstStages, - flags, 1, &barrier, 0, nullptr, 0, nullptr); + VkDependencyInfo depInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + depInfo.memoryBarrierCount = 1; + depInfo.pMemoryBarriers = &barrier; + m_cmd->cmdPipelineBarrier(DxvkCmdBuffer::ExecBuffer, &depInfo); m_cmd->addStatCtr(DxvkStatCounter::CmdBarrierCount, 1); } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index c783544d1..37385d794 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1404,7 +1404,6 @@ namespace dxvk { VkAccessFlags access); void emitMemoryBarrier( - VkDependencyFlags flags, VkPipelineStageFlags srcStages, VkAccessFlags srcAccess, VkPipelineStageFlags dstStages, From 0c79882e8488fc108185a499766d6d5d23bdbe2d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 17:59:37 +0200 Subject: [PATCH 0281/1348] [dxvk] Use synchronization2 functions for events --- src/dxvk/dxvk_cmdlist.h | 4 ++-- src/dxvk/dxvk_context.cpp | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 023db49f7..e8fdb632a 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -707,8 +707,8 @@ namespace dxvk { void cmdSetEvent( VkEvent event, - VkPipelineStageFlags stages) { - m_vkd->vkCmdSetEvent(m_execBuffer, event, stages); + const VkDependencyInfo* dependencyInfo) { + m_vkd->vkCmdSetEvent2(m_execBuffer, event, dependencyInfo); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 7b8c4a222..64b71d72a 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2524,8 +2524,17 @@ namespace dxvk { DxvkGpuEventHandle handle = m_common->eventPool().allocEvent(); - m_cmd->cmdSetEvent(handle.event, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); + // Supported client APIs can't access device memory in a defined manner + // without triggering a queue submission first, so we really only need + // to wait for prior commands, especially queries, to complete. + VkMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 }; + barrier.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + + VkDependencyInfo depInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + depInfo.memoryBarrierCount = 1; + depInfo.pMemoryBarriers = &barrier; + + m_cmd->cmdSetEvent(handle.event, &depInfo); m_cmd->trackGpuEvent(event->reset(handle)); m_cmd->trackResource(event); From 330ff8fa48950961f5ac24e28785d7a71e26c73d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 18 Jul 2022 19:35:12 +0200 Subject: [PATCH 0282/1348] [dxvk] Use synchronization2 functions for queue submissions --- src/dxvk/dxvk_cmdlist.cpp | 71 ++++++++++++++++++++++++--------------- src/dxvk/dxvk_cmdlist.h | 13 ++++--- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 90d3408e9..496dbdaff 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -87,35 +87,55 @@ namespace dxvk { DxvkQueueSubmission info = DxvkQueueSubmission(); if (m_cmdBuffersUsed.test(DxvkCmdBuffer::SdmaBuffer)) { - info.cmdBuffers[info.cmdBufferCount++] = m_sdmaBuffer; + auto& cmdInfo = info.cmdBuffers[info.cmdBufferCount++]; + cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; + cmdInfo.commandBuffer = m_sdmaBuffer; if (m_device->hasDedicatedTransferQueue()) { - info.wakeSync[info.wakeCount++] = m_sdmaSemaphore; + auto& signalInfo = info.wakeSync[info.wakeCount++]; + signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + signalInfo.semaphore = m_sdmaSemaphore; + signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; + VkResult status = submitToQueue(transfer.queueHandle, VK_NULL_HANDLE, info); if (status != VK_SUCCESS) return status; info = DxvkQueueSubmission(); - info.waitSync[info.waitCount] = m_sdmaSemaphore; - info.waitMask[info.waitCount] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - info.waitCount += 1; + + auto& waitInfo = info.waitSync[info.waitCount++]; + waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + waitInfo.semaphore = m_sdmaSemaphore; + waitInfo.stageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; } } - if (m_cmdBuffersUsed.test(DxvkCmdBuffer::InitBuffer)) - info.cmdBuffers[info.cmdBufferCount++] = m_initBuffer; - if (m_cmdBuffersUsed.test(DxvkCmdBuffer::ExecBuffer)) - info.cmdBuffers[info.cmdBufferCount++] = m_execBuffer; - - if (waitSemaphore) { - info.waitSync[info.waitCount] = waitSemaphore; - info.waitMask[info.waitCount] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - info.waitCount += 1; + if (m_cmdBuffersUsed.test(DxvkCmdBuffer::InitBuffer)) { + auto& cmdInfo = info.cmdBuffers[info.cmdBufferCount++]; + cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; + cmdInfo.commandBuffer = m_initBuffer; } - if (wakeSemaphore) - info.wakeSync[info.wakeCount++] = wakeSemaphore; + if (m_cmdBuffersUsed.test(DxvkCmdBuffer::ExecBuffer)) { + auto& cmdInfo = info.cmdBuffers[info.cmdBufferCount++]; + cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; + cmdInfo.commandBuffer = m_execBuffer; + } + + if (waitSemaphore) { + auto& waitInfo = info.waitSync[info.waitCount++]; + waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + waitInfo.semaphore = waitSemaphore; + waitInfo.stageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + } + + if (wakeSemaphore) { + auto& signalInfo = info.wakeSync[info.wakeCount++]; + signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + signalInfo.semaphore = wakeSemaphore; + signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; + } return submitToQueue(graphics.queueHandle, m_fence, info); } @@ -194,18 +214,15 @@ namespace dxvk { VkQueue queue, VkFence fence, const DxvkQueueSubmission& info) { - VkSubmitInfo submitInfo; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.pNext = nullptr; - submitInfo.waitSemaphoreCount = info.waitCount; - submitInfo.pWaitSemaphores = info.waitSync; - submitInfo.pWaitDstStageMask = info.waitMask; - submitInfo.commandBufferCount = info.cmdBufferCount; - submitInfo.pCommandBuffers = info.cmdBuffers; - submitInfo.signalSemaphoreCount = info.wakeCount; - submitInfo.pSignalSemaphores = info.wakeSync; + VkSubmitInfo2 submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO_2 }; + submitInfo.waitSemaphoreInfoCount = info.waitCount; + submitInfo.pWaitSemaphoreInfos = info.waitSync; + submitInfo.commandBufferInfoCount = info.cmdBufferCount; + submitInfo.pCommandBufferInfos = info.cmdBuffers; + submitInfo.signalSemaphoreInfoCount = info.wakeCount; + submitInfo.pSignalSemaphoreInfos = info.wakeSync; - return m_vkd->vkQueueSubmit(queue, 1, &submitInfo, fence); + return m_vkd->vkQueueSubmit2(queue, 1, &submitInfo, fence); } void DxvkCommandList::cmdBeginDebugUtilsLabel(VkDebugUtilsLabelEXT *pLabelInfo) { diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index e8fdb632a..f0b92a5ea 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -38,13 +38,12 @@ namespace dxvk { * only, array sizes are based on need. */ struct DxvkQueueSubmission { - uint32_t waitCount; - VkSemaphore waitSync[2]; - VkPipelineStageFlags waitMask[2]; - uint32_t wakeCount; - VkSemaphore wakeSync[2]; - uint32_t cmdBufferCount; - VkCommandBuffer cmdBuffers[4]; + uint32_t waitCount; + VkSemaphoreSubmitInfo waitSync[2]; + uint32_t wakeCount; + VkSemaphoreSubmitInfo wakeSync[2]; + uint32_t cmdBufferCount; + VkCommandBufferSubmitInfo cmdBuffers[4]; }; /** From 563b1d7801a2824bc4d5663e0aa8c049e6fcf6f2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Jul 2022 13:49:01 +0200 Subject: [PATCH 0283/1348] [dxvk] Add entry points for copy_commands2 --- src/vulkan/vulkan_loader.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 0cf6851d7..aea15c47b 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -285,16 +285,22 @@ namespace dxvk::vk { VULKAN_FN(vkCmdDispatch); VULKAN_FN(vkCmdDispatchIndirect); VULKAN_FN(vkCmdCopyBuffer); + VULKAN_FN(vkCmdCopyBuffer2); VULKAN_FN(vkCmdCopyImage); + VULKAN_FN(vkCmdCopyImage2); VULKAN_FN(vkCmdBlitImage); + VULKAN_FN(vkCmdBlitImage2); VULKAN_FN(vkCmdCopyBufferToImage); + VULKAN_FN(vkCmdCopyBufferToImage2); VULKAN_FN(vkCmdCopyImageToBuffer); + VULKAN_FN(vkCmdCopyImageToBuffer2); VULKAN_FN(vkCmdUpdateBuffer); VULKAN_FN(vkCmdFillBuffer); VULKAN_FN(vkCmdClearColorImage); VULKAN_FN(vkCmdClearDepthStencilImage); VULKAN_FN(vkCmdClearAttachments); VULKAN_FN(vkCmdResolveImage); + VULKAN_FN(vkCmdResolveImage2); VULKAN_FN(vkCmdSetEvent); VULKAN_FN(vkCmdSetEvent2); VULKAN_FN(vkCmdResetEvent); From ff813232288b4e772a92c4510d1acab022742df2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Jul 2022 13:53:28 +0200 Subject: [PATCH 0284/1348] [dxvk] Use copy_commands2 functions for image blits Don't expose VkImageBlit2 to client APIs since we can't easily support pNext chains, so just convert the struct internally. --- src/dxvk/dxvk_cmdlist.h | 13 ++----------- src/dxvk/dxvk_context.cpp | 23 +++++++++++++++++++---- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index f0b92a5ea..b41aef179 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -339,17 +339,8 @@ namespace dxvk { } void cmdBlitImage( - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageBlit* pRegions, - VkFilter filter) { - m_vkd->vkCmdBlitImage(m_execBuffer, - srcImage, srcImageLayout, - dstImage, dstImageLayout, - regionCount, pRegions, filter); + const VkBlitImageInfo2* pBlitInfo) { + m_vkd->vkCmdBlitImage2(m_execBuffer, pBlitInfo); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 64b71d72a..68c29298e 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2861,10 +2861,25 @@ namespace dxvk { m_execAcquires.recordCommands(m_cmd); // Perform the blit operation - m_cmd->cmdBlitImage( - srcImage->handle(), srcLayout, - dstImage->handle(), dstLayout, - 1, ®ion, filter); + VkImageBlit2 blitRegion = { VK_STRUCTURE_TYPE_IMAGE_BLIT_2 }; + blitRegion.srcSubresource = region.srcSubresource; + blitRegion.dstSubresource = region.dstSubresource; + + for (uint32_t i = 0; i < 2; i++) { + blitRegion.srcOffsets[i] = region.srcOffsets[i]; + blitRegion.dstOffsets[i] = region.dstOffsets[i]; + } + + VkBlitImageInfo2 blitInfo = { VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 }; + blitInfo.srcImage = srcImage->handle(); + blitInfo.srcImageLayout = srcLayout; + blitInfo.dstImage = dstImage->handle(); + blitInfo.dstImageLayout = dstLayout; + blitInfo.regionCount = 1; + blitInfo.pRegions = &blitRegion; + blitInfo.filter = filter; + + m_cmd->cmdBlitImage(&blitInfo); m_execBarriers.accessImage( dstImage, dstSubresourceRange, dstLayout, From f39d49772dec90e98728b793cbb83d9b53d812d9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Jul 2022 14:10:47 +0200 Subject: [PATCH 0285/1348] [dxvk] Use copy_commands2 functions for image resolves Same idea as with blits, don't expose VkImageResolve2. --- src/dxvk/dxvk_cmdlist.h | 12 ++---------- src/dxvk/dxvk_context.cpp | 22 +++++++++++++++++----- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index b41aef179..954071e79 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -616,16 +616,8 @@ namespace dxvk { void cmdResolveImage( - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageResolve* pRegions) { - m_vkd->vkCmdResolveImage(m_execBuffer, - srcImage, srcImageLayout, - dstImage, dstImageLayout, - regionCount, pRegions); + const VkResolveImageInfo2* resolveInfo) { + m_vkd->vkCmdResolveImage2(m_execBuffer, resolveInfo); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 68c29298e..cef4bdd93 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -3705,11 +3705,23 @@ namespace dxvk { } m_execAcquires.recordCommands(m_cmd); - - m_cmd->cmdResolveImage( - srcImage->handle(), srcLayout, - dstImage->handle(), dstLayout, - 1, ®ion); + + VkImageResolve2 resolveRegion = { VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2 }; + resolveRegion.srcSubresource = region.srcSubresource; + resolveRegion.srcOffset = region.srcOffset; + resolveRegion.dstSubresource = region.dstSubresource; + resolveRegion.dstOffset = region.dstOffset; + resolveRegion.extent = region.extent; + + VkResolveImageInfo2 resolveInfo = { VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2 }; + resolveInfo.srcImage = srcImage->handle(); + resolveInfo.srcImageLayout = srcLayout; + resolveInfo.dstImage = dstImage->handle(); + resolveInfo.dstImageLayout = dstLayout; + resolveInfo.regionCount = 1; + resolveInfo.pRegions = &resolveRegion; + + m_cmd->cmdResolveImage(&resolveInfo); m_execBarriers.accessImage( dstImage, dstSubresourceRange, dstLayout, From dc1d82deffe98d80b8c09c1d438c448bde754395 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Jul 2022 14:19:41 +0200 Subject: [PATCH 0286/1348] [dxvk] Use copy_commands2 functions for buffer copies --- src/dxvk/dxvk_cmdlist.h | 9 ++------ src/dxvk/dxvk_context.cpp | 46 +++++++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 954071e79..a07ba5e24 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -381,15 +381,10 @@ namespace dxvk { void cmdCopyBuffer( DxvkCmdBuffer cmdBuffer, - VkBuffer srcBuffer, - VkBuffer dstBuffer, - uint32_t regionCount, - const VkBufferCopy* pRegions) { + const VkCopyBufferInfo2* copyInfo) { m_cmdBuffersUsed.set(cmdBuffer); - m_vkd->vkCmdCopyBuffer(getCmdBuffer(cmdBuffer), - srcBuffer, dstBuffer, - regionCount, pRegions); + m_vkd->vkCmdCopyBuffer2(getCmdBuffer(cmdBuffer), copyInfo); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index cef4bdd93..abbb6f32a 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -468,13 +468,18 @@ namespace dxvk { ? DxvkCmdBuffer::InitBuffer : DxvkCmdBuffer::ExecBuffer; - VkBufferCopy bufferRegion; - bufferRegion.srcOffset = srcSlice.offset; - bufferRegion.dstOffset = dstSlice.offset; - bufferRegion.size = dstSlice.length; + VkBufferCopy2 copyRegion = { VK_STRUCTURE_TYPE_BUFFER_COPY_2 }; + copyRegion.srcOffset = srcSlice.offset; + copyRegion.dstOffset = dstSlice.offset; + copyRegion.size = dstSlice.length; - m_cmd->cmdCopyBuffer(cmdBuffer, - srcSlice.handle, dstSlice.handle, 1, &bufferRegion); + VkCopyBufferInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 }; + copyInfo.srcBuffer = srcSlice.handle; + copyInfo.dstBuffer = dstSlice.handle; + copyInfo.regionCount = 1; + copyInfo.pRegions = ©Region; + + m_cmd->cmdCopyBuffer(cmdBuffer, ©Info); auto& barriers = replaceBuffer ? m_initBarriers @@ -941,14 +946,18 @@ namespace dxvk { auto tmpBufferSlice = tmpBuffer->getSliceHandle(); - VkBufferCopy copyRegion; + VkBufferCopy2 copyRegion = { VK_STRUCTURE_TYPE_BUFFER_COPY_2 }; copyRegion.srcOffset = srcBufferSlice.offset; copyRegion.dstOffset = tmpBufferSlice.offset; copyRegion.size = tmpBufferSlice.length; - m_cmd->cmdCopyBuffer(DxvkCmdBuffer::ExecBuffer, - srcBufferSlice.handle, tmpBufferSlice.handle, - 1, ©Region); + VkCopyBufferInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 }; + copyInfo.srcBuffer = srcBufferSlice.handle; + copyInfo.dstBuffer = tmpBufferSlice.handle; + copyInfo.regionCount = 1; + copyInfo.pRegions = ©Region; + + m_cmd->cmdCopyBuffer(DxvkCmdBuffer::ExecBuffer, ©Info); emitMemoryBarrier( VK_PIPELINE_STAGE_TRANSFER_BIT, @@ -2222,13 +2231,18 @@ namespace dxvk { auto stagingHandle = stagingSlice.getSliceHandle(); std::memcpy(stagingHandle.mapPtr, data, bufferSlice.length); - VkBufferCopy region; - region.srcOffset = stagingHandle.offset; - region.dstOffset = bufferSlice.offset; - region.size = bufferSlice.length; + VkBufferCopy2 copyRegion = { VK_STRUCTURE_TYPE_BUFFER_COPY_2 }; + copyRegion.srcOffset = stagingHandle.offset; + copyRegion.dstOffset = bufferSlice.offset; + copyRegion.size = bufferSlice.length; - m_cmd->cmdCopyBuffer(DxvkCmdBuffer::SdmaBuffer, - stagingHandle.handle, bufferSlice.handle, 1, ®ion); + VkCopyBufferInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 }; + copyInfo.srcBuffer = stagingHandle.handle; + copyInfo.dstBuffer = bufferSlice.handle; + copyInfo.regionCount = 1; + copyInfo.pRegions = ©Region; + + m_cmd->cmdCopyBuffer(DxvkCmdBuffer::SdmaBuffer, ©Info); m_sdmaBarriers.releaseBuffer( m_initBarriers, bufferSlice, From 23846ad577c9c0b2a37ba467bf48adb323710428 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Jul 2022 14:23:51 +0200 Subject: [PATCH 0287/1348] [dxvk] Use copy_commands2 functions for image copies --- src/dxvk/dxvk_cmdlist.h | 12 ++---------- src/dxvk/dxvk_context.cpp | 41 ++++++++++++++++++++++----------------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index a07ba5e24..ef2aa7dca 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -405,18 +405,10 @@ namespace dxvk { void cmdCopyImage( DxvkCmdBuffer cmdBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageCopy* pRegions) { + const VkCopyImageInfo2* copyInfo) { m_cmdBuffersUsed.set(cmdBuffer); - m_vkd->vkCmdCopyImage(getCmdBuffer(cmdBuffer), - srcImage, srcImageLayout, - dstImage, dstImageLayout, - regionCount, pRegions); + m_vkd->vkCmdCopyImage2(getCmdBuffer(cmdBuffer), copyInfo); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index abbb6f32a..48e3c378b 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -3301,29 +3301,34 @@ namespace dxvk { for (auto aspects = dstSubresource.aspectMask; aspects; ) { auto aspect = vk::getNextAspect(aspects); - VkImageCopy imageRegion; - imageRegion.srcSubresource = srcSubresource; - imageRegion.srcSubresource.aspectMask = aspect; - imageRegion.srcOffset = srcOffset; - imageRegion.dstSubresource = dstSubresource; - imageRegion.dstSubresource.aspectMask = aspect; - imageRegion.dstOffset = dstOffset; - imageRegion.extent = extent; + VkImageCopy2 copyRegion = { VK_STRUCTURE_TYPE_IMAGE_COPY_2 }; + copyRegion.srcSubresource = srcSubresource; + copyRegion.srcSubresource.aspectMask = aspect; + copyRegion.srcOffset = srcOffset; + copyRegion.dstSubresource = dstSubresource; + copyRegion.dstSubresource.aspectMask = aspect; + copyRegion.dstOffset = dstOffset; + copyRegion.extent = extent; if (dstFormatInfo->flags.test(DxvkFormatFlag::MultiPlane)) { auto plane = &dstFormatInfo->planes[vk::getPlaneIndex(aspect)]; - imageRegion.srcOffset.x /= plane->blockSize.width; - imageRegion.srcOffset.y /= plane->blockSize.height; - imageRegion.dstOffset.x /= plane->blockSize.width; - imageRegion.dstOffset.y /= plane->blockSize.height; - imageRegion.extent.width /= plane->blockSize.width; - imageRegion.extent.height /= plane->blockSize.height; + copyRegion.srcOffset.x /= plane->blockSize.width; + copyRegion.srcOffset.y /= plane->blockSize.height; + copyRegion.dstOffset.x /= plane->blockSize.width; + copyRegion.dstOffset.y /= plane->blockSize.height; + copyRegion.extent.width /= plane->blockSize.width; + copyRegion.extent.height /= plane->blockSize.height; } - m_cmd->cmdCopyImage(DxvkCmdBuffer::ExecBuffer, - srcImage->handle(), srcImageLayout, - dstImage->handle(), dstImageLayout, - 1, &imageRegion); + VkCopyImageInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2 }; + copyInfo.srcImage = srcImage->handle(); + copyInfo.srcImageLayout = srcImageLayout; + copyInfo.dstImage = dstImage->handle(); + copyInfo.dstImageLayout = dstImageLayout; + copyInfo.regionCount = 1; + copyInfo.pRegions = ©Region; + + m_cmd->cmdCopyImage(DxvkCmdBuffer::ExecBuffer, ©Info); } m_execBarriers.accessImage( From 0ba741b7d2cebdea2a4417bb50e1cb9e1cec7580 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Jul 2022 14:38:39 +0200 Subject: [PATCH 0288/1348] [dxvk] Use copy_commands2 functions for buffer <-> image copies --- src/dxvk/dxvk_cmdlist.h | 20 +++-------- src/dxvk/dxvk_context.cpp | 76 ++++++++++++++++++++++++++------------- 2 files changed, 55 insertions(+), 41 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index ef2aa7dca..286a58557 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -390,16 +390,10 @@ namespace dxvk { void cmdCopyBufferToImage( DxvkCmdBuffer cmdBuffer, - VkBuffer srcBuffer, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkBufferImageCopy* pRegions) { + const VkCopyBufferToImageInfo2* copyInfo) { m_cmdBuffersUsed.set(cmdBuffer); - m_vkd->vkCmdCopyBufferToImage(getCmdBuffer(cmdBuffer), - srcBuffer, dstImage, dstImageLayout, - regionCount, pRegions); + m_vkd->vkCmdCopyBufferToImage2(getCmdBuffer(cmdBuffer), copyInfo); } @@ -414,16 +408,10 @@ namespace dxvk { void cmdCopyImageToBuffer( DxvkCmdBuffer cmdBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkBuffer dstBuffer, - uint32_t regionCount, - const VkBufferImageCopy* pRegions) { + const VkCopyImageToBufferInfo2* copyInfo) { m_cmdBuffersUsed.set(cmdBuffer); - m_vkd->vkCmdCopyImageToBuffer(getCmdBuffer(cmdBuffer), - srcImage, srcImageLayout, dstBuffer, - regionCount, pRegions); + m_vkd->vkCmdCopyImageToBuffer2(getCmdBuffer(cmdBuffer), copyInfo); } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 48e3c378b..dc2490fff 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1202,17 +1202,27 @@ namespace dxvk { VkImageSubresourceLayers dstSubresourceS = dstSubresource; dstSubresourceS.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT; - std::array copyRegions = {{ - { tmpBufferViewD->info().rangeOffset, 0, 0, dstSubresourceD, dstOffset3D, dstExtent3D }, - { tmpBufferViewS->info().rangeOffset, 0, 0, dstSubresourceS, dstOffset3D, dstExtent3D }, - }}; + std::array copyRegions; + copyRegions[0] = { VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 }; + copyRegions[0].bufferOffset = tmpBufferViewD->info().rangeOffset; + copyRegions[0].imageSubresource = dstSubresourceD; + copyRegions[0].imageOffset = dstOffset3D; + copyRegions[0].imageExtent = dstExtent3D; - m_cmd->cmdCopyBufferToImage(DxvkCmdBuffer::ExecBuffer, - tmpBuffer->getSliceHandle().handle, - dstImage->handle(), - dstImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL), - copyRegions.size(), - copyRegions.data()); + copyRegions[1] = { VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 }; + copyRegions[1].bufferOffset = tmpBufferViewS->info().rangeOffset; + copyRegions[1].imageSubresource = dstSubresourceS; + copyRegions[1].imageOffset = dstOffset3D; + copyRegions[1].imageExtent = dstExtent3D; + + VkCopyBufferToImageInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 }; + copyInfo.srcBuffer = tmpBuffer->getSliceHandle().handle; + copyInfo.dstImage = dstImage->handle(); + copyInfo.dstImageLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + copyInfo.regionCount = copyRegions.size(); + copyInfo.pRegions = copyRegions.data(); + + m_cmd->cmdCopyBufferToImage(DxvkCmdBuffer::ExecBuffer, ©Info); m_execBarriers.accessImage( dstImage, vk::makeSubresourceRange(dstSubresource), @@ -1517,18 +1527,22 @@ namespace dxvk { } for (uint32_t layer = 0; layer < subresources.layerCount; layer++) { - VkBufferImageCopy region; - region.bufferOffset = zeroHandle.offset; - region.bufferRowLength = 0; - region.bufferImageHeight = 0; - region.imageSubresource = vk::makeSubresourceLayers( + VkBufferImageCopy2 copyRegion = { VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 }; + copyRegion.bufferOffset = zeroHandle.offset; + copyRegion.imageSubresource = vk::makeSubresourceLayers( vk::pickSubresource(subresources, level, layer)); - region.imageSubresource.aspectMask = aspect; - region.imageOffset = offset; - region.imageExtent = extent; + copyRegion.imageSubresource.aspectMask = aspect; + copyRegion.imageOffset = offset; + copyRegion.imageExtent = extent; - m_cmd->cmdCopyBufferToImage(DxvkCmdBuffer::ExecBuffer, - zeroHandle.handle, image->handle(), clearLayout, 1, ®ion); + VkCopyBufferToImageInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 }; + copyInfo.srcBuffer = zeroHandle.handle; + copyInfo.dstImage = image->handle(); + copyInfo.dstImageLayout = clearLayout; + copyInfo.regionCount = 1; + copyInfo.pRegions = ©Region; + + m_cmd->cmdCopyBufferToImage(DxvkCmdBuffer::ExecBuffer, ©Info); } } @@ -2943,7 +2957,7 @@ namespace dxvk { auto aspect = vk::getNextAspect(aspects); auto elementSize = formatInfo->elementSize; - VkBufferImageCopy copyRegion = { }; + VkBufferImageCopy2 copyRegion = { VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 }; copyRegion.imageSubresource.aspectMask = aspect; copyRegion.imageSubresource.baseArrayLayer = imageSubresource.baseArrayLayer + i; copyRegion.imageSubresource.layerCount = layers; @@ -2979,11 +2993,23 @@ namespace dxvk { // Perform the actual copy if constexpr (ToImage) { - m_cmd->cmdCopyBufferToImage(cmd, bufferSlice.handle, - image->handle(), imageLayout, 1, ©Region); + VkCopyBufferToImageInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 }; + copyInfo.srcBuffer = bufferSlice.handle; + copyInfo.dstImage = image->handle(); + copyInfo.dstImageLayout = imageLayout; + copyInfo.regionCount = 1; + copyInfo.pRegions = ©Region; + + m_cmd->cmdCopyBufferToImage(cmd, ©Info); } else { - m_cmd->cmdCopyImageToBuffer(cmd, image->handle(), imageLayout, - bufferSlice.handle, 1, ©Region); + VkCopyImageToBufferInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2 }; + copyInfo.srcImage = image->handle(); + copyInfo.srcImageLayout = imageLayout; + copyInfo.dstBuffer = bufferSlice.handle; + copyInfo.regionCount = 1; + copyInfo.pRegions = ©Region; + + m_cmd->cmdCopyImageToBuffer(cmd, ©Info); } aspectOffset += blockCount.depth * slicePitch; From fc796abede0a560109b63abd66ada98f3d83946e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Jul 2022 15:27:18 +0200 Subject: [PATCH 0289/1348] [dxvk] Bump engine version reported to the Vulkan driver Might help with Fossilize stuff. --- src/dxvk/dxvk_instance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index 8c6c3deb1..3b7487f7a 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -125,7 +125,7 @@ namespace dxvk { VkApplicationInfo appInfo = { VK_STRUCTURE_TYPE_APPLICATION_INFO }; appInfo.pApplicationName = appName.c_str(); appInfo.pEngineName = "DXVK"; - appInfo.engineVersion = VK_MAKE_VERSION(1, 10, 1); + appInfo.engineVersion = VK_MAKE_VERSION(2, 0, 0); appInfo.apiVersion = VK_MAKE_VERSION(1, 3, 0); VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; From 2d93760002c38ebe6a040557a115aafe368d1cbf Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Jul 2022 19:08:58 +0200 Subject: [PATCH 0290/1348] [dxvk] Clarify feature enablement And fall back to robustImageAccess if robustImageAccess2 is not supported. Not what we want, but better than nothing. --- src/dxvk/dxvk_adapter.cpp | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 9ad973463..b30924584 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -333,24 +333,48 @@ namespace dxvk { extensionsEnabled.merge(m_extraExtensions); DxvkNameList extensionNameList = extensionsEnabled.toNameList(); - // Enable additional device features if supported - enabledFeatures.vk12.drawIndirectCount = m_deviceFeatures.vk12.drawIndirectCount; - enabledFeatures.vk12.hostQueryReset = VK_TRUE; - enabledFeatures.vk12.shaderOutputViewportIndex = m_deviceFeatures.vk12.shaderOutputViewportIndex; - enabledFeatures.vk12.shaderOutputLayer = m_deviceFeatures.vk12.shaderOutputLayer; + // Optionally used by some client API extensions + enabledFeatures.vk12.drawIndirectCount = + m_deviceFeatures.vk12.drawIndirectCount; - enabledFeatures.vk13.pipelineCreationCacheControl = m_deviceFeatures.vk13.pipelineCreationCacheControl; + // Required since we no longer have a fallback for GPU queries + enabledFeatures.vk12.hostQueryReset = VK_TRUE; + + // Used by some internal shaders, and can be used by applications + enabledFeatures.vk12.shaderOutputViewportIndex = + m_deviceFeatures.vk12.shaderOutputViewportIndex; + enabledFeatures.vk12.shaderOutputLayer = + m_deviceFeatures.vk12.shaderOutputLayer; + + // Only enable the base image robustness feature if robustness 2 isn't + // supported, since this is only a subset of what we actually want. + enabledFeatures.vk13.robustImageAccess = + m_deviceFeatures.vk13.robustImageAccess && + !m_deviceFeatures.extRobustness2.robustImageAccess2; + + // Only used in combination with pipeline libraries + // right now, but enabling it won't hurt anyway + enabledFeatures.vk13.pipelineCreationCacheControl = + m_deviceFeatures.vk13.pipelineCreationCacheControl; + + // Core features that we're relying on in various places enabledFeatures.vk13.synchronization2 = VK_TRUE; enabledFeatures.vk13.dynamicRendering = VK_TRUE; enabledFeatures.vk13.maintenance4 = VK_TRUE; + // Used for both pNext shader module info, and fast-linking pipelines provided + // that graphicsPipelineLibraryIndependentInterpolationDecoration is supported enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary; + // Require robustBufferAccess2 since we use the robustness alignment + // info in a number of places, and require null descriptor support + // since we no longer have a fallback for those in the backend enabledFeatures.extRobustness2.robustBufferAccess2 = VK_TRUE; enabledFeatures.extRobustness2.robustImageAccess2 = m_deviceFeatures.extRobustness2.robustImageAccess2; enabledFeatures.extRobustness2.nullDescriptor = VK_TRUE; + // We use this to avoid decompressing SPIR-V shaders in some situations enabledFeatures.extShaderModuleIdentifier.shaderModuleIdentifier = m_deviceFeatures.extShaderModuleIdentifier.shaderModuleIdentifier; @@ -775,6 +799,7 @@ namespace dxvk { "\n shaderOutputViewportIndex : ", features.vk12.shaderOutputViewportIndex, "\n shaderOutputLayer : ", features.vk12.shaderOutputLayer, "\nVulkan 1.3", + "\n robustImageAccess : ", features.vk13.robustImageAccess, "\n pipelineCreationCacheControl : ", features.vk13.pipelineCreationCacheControl, "\n shaderDemoteToHelperInvocation : ", features.vk13.shaderDemoteToHelperInvocation, "\n shaderZeroInitializeWorkgroupMemory : ", features.vk13.shaderZeroInitializeWorkgroupMemory, From 75d0b1af9683a63aa4c0af39246bba93610c7d50 Mon Sep 17 00:00:00 2001 From: Kassin Dornelles Date: Wed, 20 Jul 2022 04:50:52 -0300 Subject: [PATCH 0291/1348] [util] Remove Resident Evil 6 workaround It's actually making things worse, so better use the default path --- src/util/config/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index b4bb740c7..254c6f71c 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -512,7 +512,7 @@ namespace dxvk { { "d3d9.floatEmulation", "Strict" }, }} }, /* Resident Evil games */ - { R"(\\(rerev|rerev2|re0hd|bhd|re5dx9|BH6)\.exe$)", {{ + { R"(\\(rerev|rerev2|re0hd|bhd|re5dx9)\.exe$)", {{ { "d3d9.allowDirectBufferMapping", "False" }, }} }, /* Limbo */ From 16eae7addec8e0dbe2d1afa78fa077546642e6c5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 20 Jul 2022 13:57:52 +0200 Subject: [PATCH 0292/1348] [dxvk] Allow resetting the state cache using the DXVK_STATE_CACHE env var --- README.md | 4 +++- src/dxvk/dxvk_state_cache.cpp | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4db6c29a5..db344e378 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,9 @@ Some applications do not provide a method to select a different GPU. In that cas DXVK caches pipeline state by default, so that shaders can be recompiled ahead of time on subsequent runs of an application, even if the driver's own shader cache got invalidated in the meantime. This cache is enabled by default, and generally reduces stuttering. The following environment variables can be used to control the cache: -- `DXVK_STATE_CACHE=0` Disables the state cache. +- `DXVK_STATE_CACHE`: Controls the state cache. The following values are supported: + - `disable`: Disables the cache entirely. + - `reset`: Clears the cache file. - `DXVK_STATE_CACHE_PATH=/some/directory` Specifies a directory where to put the cache files. Defaults to the current working directory of the application. ### Debugging diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 31800cb27..770fedc5a 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -238,12 +238,13 @@ namespace dxvk { m_pipeManager (pipeManager), m_pipeWorkers (pipeWorkers) { std::string useStateCache = env::getEnvVar("DXVK_STATE_CACHE"); - m_enable = useStateCache != "0" && device->config().enableStateCache; + m_enable = useStateCache != "0" && useStateCache != "disable" && + device->config().enableStateCache; if (!m_enable) return; - bool newFile = !readCacheFile(); + bool newFile = (useStateCache == "reset") || (!readCacheFile()); if (newFile) { Logger::warn("DXVK: Creating new state cache file"); From a178c57aea7b775ff73b4beba7c1e9c94f6d77d7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 20 Jul 2022 16:57:27 +0200 Subject: [PATCH 0293/1348] [dxvk] Remove barrier argument from render target transition functions We're always using the same barrier set anyway. --- src/dxvk/dxvk_context.cpp | 56 ++++++++++++++++++--------------------- src/dxvk/dxvk_context.h | 4 --- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index dc2490fff..9064a98ae 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -195,8 +195,8 @@ namespace dxvk { const VkImageBlit& region, VkFilter filter) { this->spillRenderPass(true); - this->prepareImage(m_execBarriers, dstImage, vk::makeSubresourceRange(region.dstSubresource)); - this->prepareImage(m_execBarriers, srcImage, vk::makeSubresourceRange(region.srcSubresource)); + this->prepareImage(dstImage, vk::makeSubresourceRange(region.dstSubresource)); + this->prepareImage(srcImage, vk::makeSubresourceRange(region.srcSubresource)); auto mapping = util::resolveSrcComponentMapping(dstMapping, srcMapping); @@ -230,7 +230,7 @@ namespace dxvk { VkImageSubresourceRange subresources = image->getAvailableSubresources(); - this->prepareImage(m_execBarriers, image, subresources); + this->prepareImage(image, subresources); if (m_execBarriers.isImageDirty(image, subresources, DxvkAccess::Write)) m_execBarriers.recordCommands(m_cmd); @@ -393,7 +393,7 @@ namespace dxvk { // will indirectly emit barriers for the given render target. // If there is overlap, we need to explicitly transition affected attachments. this->spillRenderPass(true); - this->prepareImage(m_execBarriers, imageView->image(), imageView->subresources(), false); + this->prepareImage(imageView->image(), imageView->subresources(), false); } else if (!m_state.om.framebufferInfo.isWritable(attachmentIndex, clearAspects)) { // We cannot inline clears if the clear aspects are not writable this->spillRenderPass(true); @@ -542,7 +542,7 @@ namespace dxvk { VkDeviceSize rowAlignment, VkDeviceSize sliceAlignment) { this->spillRenderPass(true); - this->prepareImage(m_execBarriers, dstImage, vk::makeSubresourceRange(dstSubresource)); + this->prepareImage(dstImage, vk::makeSubresourceRange(dstSubresource)); auto srcSlice = srcBuffer->getSliceHandle(srcOffset, 0); @@ -612,8 +612,8 @@ namespace dxvk { if (this->copyImageClear(dstImage, dstSubresource, dstOffset, extent, srcImage, srcSubresource)) return; - this->prepareImage(m_execBarriers, dstImage, vk::makeSubresourceRange(dstSubresource)); - this->prepareImage(m_execBarriers, srcImage, vk::makeSubresourceRange(srcSubresource)); + this->prepareImage(dstImage, vk::makeSubresourceRange(dstSubresource)); + this->prepareImage(srcImage, vk::makeSubresourceRange(srcSubresource)); bool useFb = dstSubresource.aspectMask != srcSubresource.aspectMask; @@ -713,7 +713,7 @@ namespace dxvk { VkOffset3D srcOffset, VkExtent3D srcExtent) { this->spillRenderPass(true); - this->prepareImage(m_execBarriers, srcImage, vk::makeSubresourceRange(srcSubresource)); + this->prepareImage(srcImage, vk::makeSubresourceRange(srcSubresource)); auto dstSlice = dstBuffer->getSliceHandle(dstOffset, 0); @@ -775,7 +775,7 @@ namespace dxvk { VkExtent2D srcExtent, VkFormat format) { this->spillRenderPass(true); - this->prepareImage(m_execBarriers, srcImage, vk::makeSubresourceRange(srcSubresource)); + this->prepareImage(srcImage, vk::makeSubresourceRange(srcSubresource)); this->invalidateState(); @@ -1063,7 +1063,7 @@ namespace dxvk { this->spillRenderPass(true); this->invalidateState(); - this->prepareImage(m_execBarriers, dstImage, vk::makeSubresourceRange(dstSubresource)); + this->prepareImage(dstImage, vk::makeSubresourceRange(dstSubresource)); if (m_execBarriers.isBufferDirty(srcBuffer->getSliceHandle(), DxvkAccess::Read) || m_execBarriers.isImageDirty(dstImage, vk::makeSubresourceRange(dstSubresource), DxvkAccess::Write)) @@ -1806,8 +1806,8 @@ namespace dxvk { const VkImageResolve& region, VkFormat format) { this->spillRenderPass(true); - this->prepareImage(m_execBarriers, dstImage, vk::makeSubresourceRange(region.dstSubresource)); - this->prepareImage(m_execBarriers, srcImage, vk::makeSubresourceRange(region.srcSubresource)); + this->prepareImage(dstImage, vk::makeSubresourceRange(region.dstSubresource)); + this->prepareImage(srcImage, vk::makeSubresourceRange(region.srcSubresource)); if (format == VK_FORMAT_UNDEFINED) format = srcImage->info().format; @@ -1839,8 +1839,8 @@ namespace dxvk { VkResolveModeFlagBits depthMode, VkResolveModeFlagBits stencilMode) { this->spillRenderPass(true); - this->prepareImage(m_execBarriers, dstImage, vk::makeSubresourceRange(region.dstSubresource)); - this->prepareImage(m_execBarriers, srcImage, vk::makeSubresourceRange(region.srcSubresource)); + this->prepareImage(dstImage, vk::makeSubresourceRange(region.dstSubresource)); + this->prepareImage(srcImage, vk::makeSubresourceRange(region.srcSubresource)); // Technically legal, but no-op if (!depthMode && !stencilMode) @@ -2154,7 +2154,7 @@ namespace dxvk { } } - this->transitionRenderTargetLayouts(m_execBarriers, true); + this->transitionRenderTargetLayouts(true); } @@ -2590,7 +2590,7 @@ namespace dxvk { srcStages |= r.first->info().stages; srcAccess |= r.first->info().access; - this->prepareImage(m_execBarriers, r.first, r.first->getAvailableSubresources()); + this->prepareImage(r.first, r.first->getAvailableSubresources()); } m_execBarriers.accessMemory(srcStages, srcAccess, @@ -4136,14 +4136,14 @@ namespace dxvk { if (suspend) m_flags.set(DxvkContextFlag::GpRenderPassSuspended); else - this->transitionRenderTargetLayouts(m_execBarriers, false); + this->transitionRenderTargetLayouts(false); m_execBarriers.recordCommands(m_cmd); } else if (!suspend) { // We may end a previously suspended render pass if (m_flags.test(DxvkContextFlag::GpRenderPassSuspended)) { m_flags.clr(DxvkContextFlag::GpRenderPassSuspended); - this->transitionRenderTargetLayouts(m_execBarriers, false); + this->transitionRenderTargetLayouts(false); m_execBarriers.recordCommands(m_cmd); } @@ -4936,13 +4936,12 @@ namespace dxvk { void DxvkContext::transitionRenderTargetLayouts( - DxvkBarrierSet& barriers, bool sharedOnly) { for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { const DxvkAttachment& color = m_state.om.framebufferInfo.getColorTarget(i); if (color.view != nullptr && (!sharedOnly || color.view->imageInfo().shared)) { - this->transitionColorAttachment(barriers, color, m_rtLayouts.color[i]); + this->transitionColorAttachment(color, m_rtLayouts.color[i]); m_rtLayouts.color[i] = color.view->imageInfo().layout; } } @@ -4950,18 +4949,17 @@ namespace dxvk { const DxvkAttachment& depth = m_state.om.framebufferInfo.getDepthTarget(); if (depth.view != nullptr && (!sharedOnly || depth.view->imageInfo().shared)) { - this->transitionDepthAttachment(barriers, depth, m_rtLayouts.depth); + this->transitionDepthAttachment(depth, m_rtLayouts.depth); m_rtLayouts.depth = depth.view->imageInfo().layout; } } void DxvkContext::transitionColorAttachment( - DxvkBarrierSet& barriers, const DxvkAttachment& attachment, VkImageLayout oldLayout) { if (oldLayout != attachment.view->imageInfo().layout) { - barriers.accessImage( + m_execBarriers.accessImage( attachment.view->image(), attachment.view->imageSubresources(), oldLayout, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, @@ -4976,11 +4974,10 @@ namespace dxvk { void DxvkContext::transitionDepthAttachment( - DxvkBarrierSet& barriers, const DxvkAttachment& attachment, VkImageLayout oldLayout) { if (oldLayout != attachment.view->imageInfo().layout) { - barriers.accessImage( + m_execBarriers.accessImage( attachment.view->image(), attachment.view->imageSubresources(), oldLayout, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | @@ -5030,7 +5027,7 @@ namespace dxvk { } if (!found && m_flags.test(DxvkContextFlag::GpRenderPassSuspended)) - this->transitionColorAttachment(m_execBarriers, oldAttachment, m_rtLayouts.color[i]); + this->transitionColorAttachment(oldAttachment, m_rtLayouts.color[i]); } } @@ -5046,7 +5043,7 @@ namespace dxvk { if (found) layouts.depth = m_rtLayouts.depth; else if (m_flags.test(DxvkContextFlag::GpRenderPassSuspended)) - this->transitionDepthAttachment(m_execBarriers, oldAttachment, m_rtLayouts.depth); + this->transitionDepthAttachment(oldAttachment, m_rtLayouts.depth); } m_rtLayouts = layouts; @@ -5054,7 +5051,6 @@ namespace dxvk { void DxvkContext::prepareImage( - DxvkBarrierSet& barriers, const Rc& image, const VkImageSubresourceRange& subresources, bool flushClears) { @@ -5082,7 +5078,7 @@ namespace dxvk { if (attachment.view != nullptr && attachment.view->image() == image && (is3D || vk::checkSubresourceRangeOverlap(attachment.view->subresources(), subresources))) { - this->transitionColorAttachment(barriers, attachment, m_rtLayouts.color[i]); + this->transitionColorAttachment(attachment, m_rtLayouts.color[i]); m_rtLayouts.color[i] = image->info().layout; } } @@ -5091,7 +5087,7 @@ namespace dxvk { if (attachment.view != nullptr && attachment.view->image() == image && (is3D || vk::checkSubresourceRangeOverlap(attachment.view->subresources(), subresources))) { - this->transitionDepthAttachment(barriers, attachment, m_rtLayouts.depth); + this->transitionDepthAttachment(attachment, m_rtLayouts.depth); m_rtLayouts.depth = image->info().layout; } } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 37385d794..1f1c1fd54 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1346,16 +1346,13 @@ namespace dxvk { void applyRenderTargetStoreLayouts(); void transitionRenderTargetLayouts( - DxvkBarrierSet& barriers, bool sharedOnly); void transitionColorAttachment( - DxvkBarrierSet& barriers, const DxvkAttachment& attachment, VkImageLayout oldLayout); void transitionDepthAttachment( - DxvkBarrierSet& barriers, const DxvkAttachment& attachment, VkImageLayout oldLayout); @@ -1364,7 +1361,6 @@ namespace dxvk { const DxvkFramebufferInfo& oldFb); void prepareImage( - DxvkBarrierSet& barriers, const Rc& image, const VkImageSubresourceRange& subresources, bool flushClears = true); From 779f8b39cdef136bd1dc177c5f93034b5a7c9f6d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 20 Jul 2022 22:38:03 +0200 Subject: [PATCH 0294/1348] [spirv] Track currently active block ID --- src/spirv/spirv_module.cpp | 10 ++++++++++ src/spirv/spirv_module.h | 7 ++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index c253c6a3d..7e9efe71f 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -2986,6 +2986,8 @@ namespace dxvk { void SpirvModule::opLabel(uint32_t labelId) { m_code.putIns (spv::OpLabel, 2); m_code.putWord(labelId); + + m_blockId = labelId; } @@ -3533,6 +3535,8 @@ namespace dxvk { uint32_t label) { m_code.putIns (spv::OpBranch, 2); m_code.putWord(label); + + m_blockId = 0; } @@ -3544,6 +3548,8 @@ namespace dxvk { m_code.putWord(condition); m_code.putWord(trueLabel); m_code.putWord(falseLabel); + + m_blockId = 0; } @@ -3560,6 +3566,8 @@ namespace dxvk { m_code.putWord(caseLabels[i].literal); m_code.putWord(caseLabels[i].labelId); } + + m_blockId = 0; } @@ -3584,11 +3592,13 @@ namespace dxvk { void SpirvModule::opReturn() { m_code.putIns (spv::OpReturn, 1); + m_blockId = 0; } void SpirvModule::opKill() { m_code.putIns (spv::OpKill, 1); + m_blockId = 0; } diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index e9be24d6f..f1ef6947e 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -50,7 +50,7 @@ namespace dxvk { ~SpirvModule(); SpirvCodeBuffer compile() const; - + size_t getInsertionPtr() { return m_code.getInsertionPtr(); } @@ -63,6 +63,10 @@ namespace dxvk { m_code.endInsertion(); } + uint32_t getBlockId() const { + return m_blockId; + } + uint32_t allocateId(); bool hasCapability( @@ -1239,6 +1243,7 @@ namespace dxvk { uint32_t m_version; uint32_t m_id = 1; uint32_t m_instExtGlsl450 = 0; + uint32_t m_blockId = 0; SpirvCodeBuffer m_capabilities; SpirvCodeBuffer m_extensions; From ec813e036ce425b03ba2d3289dcd9d636c322b01 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 20 Jul 2022 22:54:09 +0200 Subject: [PATCH 0295/1348] [dxbc] Fix UAV write test We broke this during the null descriptor refactor. Also make it so that we don't generate conditionals when there's nothing to test. --- src/dxbc/dxbc_compiler.cpp | 132 +++++++++++++------------------------ src/dxbc/dxbc_compiler.h | 5 +- 2 files changed, 47 insertions(+), 90 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 16ec63b2c..ad393d554 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -2273,21 +2273,8 @@ namespace dxvk { && bufferInfo.type != DxbcResourceType::Typed && isUav; - // Perform atomic operations on UAVs only if the UAV - // is bound and if there is nothing else stopping us. - DxbcConditional cond; - - if (isUav) { - uint32_t writeTest = emitUavWriteTest(bufferInfo); - - cond.labelIf = m_module.allocateId(); - cond.labelEnd = m_module.allocateId(); - - m_module.opSelectionMerge(cond.labelEnd, spv::SelectionControlMaskNone); - m_module.opBranchConditional(writeTest, cond.labelIf, cond.labelEnd); - - m_module.opLabel(cond.labelIf); - } + // Perform atomic operations on UAVs only if the invocation is alive + DxbcConditional cond = emitBeginPsKillTest(); // Retrieve destination pointer for the atomic operation> const DxbcRegisterPointer pointer = emitGetAtomicPointer( @@ -2413,11 +2400,7 @@ namespace dxvk { if (isImm) emitRegisterStore(ins.dst[0], value); - // End conditional block - if (isUav) { - m_module.opBranch(cond.labelEnd); - m_module.opLabel (cond.labelEnd); - } + emitEndPsKillTest(cond); } @@ -2425,30 +2408,22 @@ namespace dxvk { // imm_atomic_alloc and imm_atomic_consume have the following operands: // (dst0) The register that will hold the old counter value // (dst1) The UAV whose counter is going to be modified - const DxbcBufferInfo bufferInfo = getBufferInfo(ins.dst[1]); - const uint32_t registerId = ins.dst[1].idx[0].offset; if (m_uavs.at(registerId).ctrId == 0) m_uavs.at(registerId).ctrId = emitDclUavCounter(registerId); - // Only perform the operation if the UAV is bound - uint32_t writeTest = emitUavWriteTest(bufferInfo); - - DxbcConditional cond; - cond.labelIf = m_module.allocateId(); - cond.labelEnd = m_module.allocateId(); - - m_module.opSelectionMerge(cond.labelEnd, spv::SelectionControlMaskNone); - m_module.opBranchConditional(writeTest, cond.labelIf, cond.labelEnd); - - m_module.opLabel(cond.labelIf); + // Only perform the operation if the invocation is alive + DxbcConditional cond = emitBeginPsKillTest(); // Only use subgroup ops on compute to avoid having to // deal with helper invocations or hardware limitations bool useSubgroupOps = m_moduleInfo.options.useSubgroupOpsForAtomicCounters && m_programInfo.type() == DxbcProgramType::ComputeShader; + // Current block ID used in a phi later on + uint32_t baseBlockId = m_module.getBlockId(); + // In case we have subgroup ops enabled, we need to // count the number of active lanes, the lane index, // and we need to perform the atomic op conditionally @@ -2550,7 +2525,7 @@ namespace dxvk { std::array phiLabels = {{ { value.id, elect.labelIf }, - { undef, cond.labelIf }, + { undef, baseBlockId }, }}; value.id = m_module.opPhi(typeId, @@ -2562,10 +2537,7 @@ namespace dxvk { // Store the result emitRegisterStore(ins.dst[0], value); - - // End conditional block - m_module.opBranch(cond.labelEnd); - m_module.opLabel (cond.labelEnd); + emitEndPsKillTest(cond); } @@ -3677,17 +3649,8 @@ namespace dxvk { // (src1) The value to store const DxbcBufferInfo uavInfo = getBufferInfo(ins.dst[0]); - // Execute write op only if the UAV is bound - uint32_t writeTest = emitUavWriteTest(uavInfo); - - DxbcConditional cond; - cond.labelIf = m_module.allocateId(); - cond.labelEnd = m_module.allocateId(); - - m_module.opSelectionMerge (cond.labelEnd, spv::SelectionControlMaskNone); - m_module.opBranchConditional(writeTest, cond.labelIf, cond.labelEnd); - - m_module.opLabel(cond.labelIf); + // Execute write op only if the invocation is active + DxbcConditional cond = emitBeginPsKillTest(); // Load texture coordinates DxbcRegisterValue texCoord = emitLoadTexCoord(ins.src[0], uavInfo.image); @@ -3702,10 +3665,8 @@ namespace dxvk { m_module.opImageWrite( m_module.opLoad(uavInfo.typeId, uavInfo.varId), texCoord.id, texValue.id, SpirvImageOperands()); - - // End conditional block - m_module.opBranch(cond.labelEnd); - m_module.opLabel (cond.labelEnd); + + emitEndPsKillTest(cond); } @@ -5152,21 +5113,8 @@ namespace dxvk { bool isSsbo = m_moduleInfo.options.minSsboAlignment <= bufferInfo.align && !isTgsm; - // Perform UAV writes only if the UAV is bound and if there - // is nothing else preventing us from writing to it. - DxbcConditional cond; - - if (!isTgsm) { - uint32_t writeTest = emitUavWriteTest(bufferInfo); - - cond.labelIf = m_module.allocateId(); - cond.labelEnd = m_module.allocateId(); - - m_module.opSelectionMerge(cond.labelEnd, spv::SelectionControlMaskNone); - m_module.opBranchConditional(writeTest, cond.labelIf, cond.labelEnd); - - m_module.opLabel(cond.labelIf); - } + // Perform UAV writes only if the invocation is active + DxbcConditional cond = emitBeginPsKillTest(); // Perform the actual write operation uint32_t bufferId = isTgsm || isSsbo ? 0 : m_module.opLoad(bufferInfo.typeId, bufferInfo.varId); @@ -5228,12 +5176,8 @@ namespace dxvk { m_module.constu32(spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsAcquireReleaseMask)); } - - // End conditional block - if (!isTgsm) { - m_module.opBranch(cond.labelEnd); - m_module.opLabel (cond.labelEnd); - } + + emitEndPsKillTest(cond); } @@ -6483,23 +6427,35 @@ namespace dxvk { } - uint32_t DxbcCompiler::emitUavWriteTest(const DxbcBufferInfo& uav) { - uint32_t typeId = m_module.defBoolType(); - uint32_t testId = 0; + DxbcConditional DxbcCompiler::emitBeginPsKillTest() { + if (!m_ps.killState) + return DxbcConditional(); + + uint32_t boolId = m_module.defBoolType(); + uint32_t killState = m_module.opLoad(boolId, m_ps.killState); + uint32_t testId = m_module.opLogicalNot(boolId, killState); + + DxbcConditional cond; + cond.labelIf = m_module.allocateId(); + cond.labelEnd = m_module.allocateId(); - if (m_ps.killState != 0) { - uint32_t killState = m_module.opLoad(typeId, m_ps.killState); - - testId = m_module.opLogicalAnd(typeId, testId, - m_module.opLogicalNot(typeId, killState)); - } else { - testId = m_module.constBool(true); - } + m_module.opSelectionMerge(cond.labelEnd, spv::SelectionControlMaskNone); + m_module.opBranchConditional(testId, cond.labelIf, cond.labelEnd); - return testId; + m_module.opLabel(cond.labelIf); + return cond; } - - + + + void DxbcCompiler::emitEndPsKillTest(const DxbcConditional& cond) { + if (!m_ps.killState) + return; + + m_module.opBranch(cond.labelEnd); + m_module.opLabel(cond.labelEnd); + } + + void DxbcCompiler::emitInit() { // Set up common capabilities for all shaders m_module.enableCapability(spv::CapabilityShader); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index dea5007bb..29d410c70 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -1063,8 +1063,9 @@ namespace dxvk { /////////////////////////////// // Some state checking methods - uint32_t emitUavWriteTest( - const DxbcBufferInfo& uav); + DxbcConditional emitBeginPsKillTest(); + + void emitEndPsKillTest(const DxbcConditional& cond); ////////////////////////////////////// // Common function definition methods From a40724aaf85f2e3a774e31e62d9e16f2cfe506ee Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Oct 2021 16:08:00 +0200 Subject: [PATCH 0296/1348] [dxvk] Add timeline semaphore entry points Co-authored-by: Derek Lesho --- src/dxvk/dxvk_adapter.cpp | 1 + src/vulkan/vulkan_loader.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index b30924584..b3bb96421 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -798,6 +798,7 @@ namespace dxvk { "\n bufferDeviceAddress : ", features.vk12.bufferDeviceAddress, "\n shaderOutputViewportIndex : ", features.vk12.shaderOutputViewportIndex, "\n shaderOutputLayer : ", features.vk12.shaderOutputLayer, + "\n timelineSemaphore : ", features.vk12.timelineSemaphore, "\nVulkan 1.3", "\n robustImageAccess : ", features.vk13.robustImageAccess, "\n pipelineCreationCacheControl : ", features.vk13.pipelineCreationCacheControl, diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index aea15c47b..094f19cc2 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -248,6 +248,9 @@ namespace dxvk::vk { VULKAN_FN(vkUpdateDescriptorSetWithTemplate); VULKAN_FN(vkResetQueryPool); VULKAN_FN(vkGetBufferDeviceAddress); + VULKAN_FN(vkGetSemaphoreCounterValue); + VULKAN_FN(vkSignalSemaphore); + VULKAN_FN(vkWaitSemaphores); VULKAN_FN(vkCmdBindPipeline); VULKAN_FN(vkCmdSetViewport); VULKAN_FN(vkCmdSetScissor); From 446ec07f3be493746362461c6d03be456ed13bf8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 22 Oct 2021 01:04:53 +0200 Subject: [PATCH 0297/1348] [dxvk] Add DxvkFence Co-authored-by: Derek Lesho --- src/dxvk/dxvk_device.cpp | 10 ++++- src/dxvk/dxvk_device.h | 12 ++++- src/dxvk/dxvk_fence.cpp | 95 +++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_fence.h | 97 ++++++++++++++++++++++++++++++++++++++++ src/dxvk/meson.build | 1 + 5 files changed, 212 insertions(+), 3 deletions(-) create mode 100644 src/dxvk/dxvk_fence.cpp create mode 100644 src/dxvk/dxvk_fence.h diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 5255be402..482e1d898 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -127,8 +127,14 @@ namespace dxvk { uint32_t index) { return new DxvkGpuQuery(m_vkd, type, flags, index); } - - + + + Rc DxvkDevice::createFence( + const DxvkFenceCreateInfo& fenceInfo) { + return new DxvkFence(this, fenceInfo); + } + + Rc DxvkDevice::createBuffer( const DxvkBufferCreateInfo& createInfo, VkMemoryPropertyFlags memoryType) { diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 89de0e6f5..d2096cdf2 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -6,6 +6,7 @@ #include "dxvk_constant_state.h" #include "dxvk_context.h" #include "dxvk_extensions.h" +#include "dxvk_fence.h" #include "dxvk_framebuffer.h" #include "dxvk_image.h" #include "dxvk_instance.h" @@ -269,6 +270,15 @@ namespace dxvk { VkQueryControlFlags flags, uint32_t index); + /** + * \brief Creates new fence + * + * \param [in] info Fence create info + * \returns The fence + */ + Rc createFence( + const DxvkFenceCreateInfo& fenceInfo); + /** * \brief Creates a buffer object * @@ -495,4 +505,4 @@ namespace dxvk { }; -} \ No newline at end of file +} diff --git a/src/dxvk/dxvk_fence.cpp b/src/dxvk/dxvk_fence.cpp new file mode 100644 index 000000000..2e5a362eb --- /dev/null +++ b/src/dxvk/dxvk_fence.cpp @@ -0,0 +1,95 @@ +#include "dxvk_device.h" +#include "dxvk_fence.h" + +namespace dxvk { + + DxvkFence::DxvkFence( + DxvkDevice* device, + const DxvkFenceCreateInfo& info) + : m_vkd(device->vkd()), m_info(info) { + VkSemaphoreTypeCreateInfo typeInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO }; + typeInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; + typeInfo.initialValue = info.initialValue; + + VkSemaphoreCreateInfo semaphoreInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &typeInfo }; + + VkResult vr = m_vkd->vkCreateSemaphore(m_vkd->device(), + &semaphoreInfo, nullptr, &m_semaphore); + + if (vr != VK_SUCCESS) + throw DxvkError("Failed to create timeline semaphore"); + + m_thread = dxvk::thread([this] { run(); }); + } + + + DxvkFence::~DxvkFence() { + m_stop.store(true); + m_thread.join(); + + m_vkd->vkDestroySemaphore(m_vkd->device(), m_semaphore, nullptr); + } + + + void DxvkFence::enqueueWait(uint64_t value, DxvkFenceEvent&& event) { + std::unique_lock lock(m_mutex); + + if (value > m_lastValue.load()) + m_queue.emplace(value, std::move(event)); + else + event(); + } + + + void DxvkFence::run() { + uint64_t value = 0ull; + + VkSemaphoreWaitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO }; + waitInfo.semaphoreCount = 1; + waitInfo.pSemaphores = &m_semaphore; + waitInfo.pValues = &value; + + while (!m_stop.load()) { + std::unique_lock lock(m_mutex); + + // Query actual semaphore value and start from there, so that + // we can skip over large increments in the semaphore value + VkResult vr = m_vkd->vkGetSemaphoreCounterValue(m_vkd->device(), m_semaphore, &value); + + if (vr != VK_SUCCESS) { + Logger::err(str::format("Failed to query semaphore value: ", vr)); + return; + } + + m_lastValue.store(value); + + // Signal all enqueued events whose value is not greater than + // the current semaphore value + while (!m_queue.empty() && m_queue.top().value <= value) { + m_queue.top().event(); + m_queue.pop(); + } + + if (m_stop) + return; + + lock.unlock(); + + // Wait for the semaphore to be singaled again and update state. + // The timeout is unfortunate, but we can't always know when a + // signal operation has been recorded, and the alternative would + // be to create a teardown semaphore and use WAIT_ANY, which may + // be fall back to a busy-wait loop on some drivers. + value += 1; + + vr = m_vkd->vkWaitSemaphores( + m_vkd->device(), &waitInfo, 10'000'000ull); + + if (vr != VK_SUCCESS && vr != VK_TIMEOUT) { + Logger::err(str::format("Failed to wait for semaphore: ", vr)); + return; + } + } + } + +} diff --git a/src/dxvk/dxvk_fence.h b/src/dxvk/dxvk_fence.h new file mode 100644 index 000000000..a533d22ba --- /dev/null +++ b/src/dxvk/dxvk_fence.h @@ -0,0 +1,97 @@ +#pragma once + +#include +#include + +#include "dxvk_resource.h" + +#include "../util/thread.h" + +namespace dxvk { + + class DxvkDevice; + + using DxvkFenceEvent = std::function; + + /** + * \brief Fence create info + */ + struct DxvkFenceCreateInfo { + uint64_t initialValue; + }; + + /** + * \brief Fence + * + * Wrapper around Vulkan timeline semaphores that + * can signal an event when the value changes. + */ + class DxvkFence : public RcObject { + + public: + + DxvkFence( + DxvkDevice* device, + const DxvkFenceCreateInfo& info); + + ~DxvkFence(); + + /** + * \brief Semaphore handle + */ + VkSemaphore handle() const { + return m_semaphore; + } + + /** + * \brief Retrieves current semaphore value + * \returns Current semaphore value + */ + uint64_t getValue() { + return m_lastValue.load(); + } + + /** + * \brief Enqueues semaphore wait + * + * Signals the given event when the + * semaphore reaches the given value. + * \param [in] value Enqueue value + * \param [in] event Callback + */ + void enqueueWait(uint64_t value, DxvkFenceEvent&& event); + + private: + + struct QueueItem { + QueueItem() { } + QueueItem(uint32_t v, DxvkFenceEvent&& e) + : value(v), event(std::move(e)) { } + + uint64_t value; + DxvkFenceEvent event; + + bool operator == (const QueueItem& item) const { return value == item.value; } + bool operator != (const QueueItem& item) const { return value != item.value; } + bool operator < (const QueueItem& item) const { return value < item.value; } + bool operator <= (const QueueItem& item) const { return value <= item.value; } + bool operator > (const QueueItem& item) const { return value > item.value; } + bool operator >= (const QueueItem& item) const { return value >= item.value; } + }; + + Rc m_vkd; + DxvkFenceCreateInfo m_info; + VkSemaphore m_semaphore; + + std::priority_queue m_queue; + std::atomic m_lastValue = { 0ull }; + std::atomic m_stop = { false }; + + dxvk::mutex m_mutex; + dxvk::thread m_thread; + + void run(); + + }; + +} \ No newline at end of file diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index b82be6aac..99100b32d 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -73,6 +73,7 @@ dxvk_src = files([ 'dxvk_device.cpp', 'dxvk_device_filter.cpp', 'dxvk_extensions.cpp', + 'dxvk_fence.cpp', 'dxvk_format.cpp', 'dxvk_framebuffer.cpp', 'dxvk_gpu_event.cpp', From 4167e1b887a155ee4588fc28f2de3e870eeec624 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 22 Oct 2021 16:25:53 +0200 Subject: [PATCH 0298/1348] [dxvk] Refactor queue submission info Co-authored-by: Derek Lesho --- src/dxvk/dxvk_cmdlist.cpp | 48 +++++++++++++++++++-------------------- src/dxvk/dxvk_cmdlist.h | 16 ++++++++----- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 496dbdaff..255725b32 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -84,60 +84,60 @@ namespace dxvk { const auto& graphics = m_device->queues().graphics; const auto& transfer = m_device->queues().transfer; - DxvkQueueSubmission info = DxvkQueueSubmission(); + m_submission.reset(); if (m_cmdBuffersUsed.test(DxvkCmdBuffer::SdmaBuffer)) { - auto& cmdInfo = info.cmdBuffers[info.cmdBufferCount++]; - cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; + VkCommandBufferSubmitInfo cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; cmdInfo.commandBuffer = m_sdmaBuffer; + m_submission.cmdBuffers.push_back(cmdInfo); if (m_device->hasDedicatedTransferQueue()) { - auto& signalInfo = info.wakeSync[info.wakeCount++]; - signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; signalInfo.semaphore = m_sdmaSemaphore; signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; + m_submission.wakeSync.push_back(signalInfo); - VkResult status = submitToQueue(transfer.queueHandle, VK_NULL_HANDLE, info); + VkResult status = submitToQueue(transfer.queueHandle, VK_NULL_HANDLE, m_submission); if (status != VK_SUCCESS) return status; - info = DxvkQueueSubmission(); + m_submission.reset(); - auto& waitInfo = info.waitSync[info.waitCount++]; - waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; waitInfo.semaphore = m_sdmaSemaphore; waitInfo.stageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + m_submission.waitSync.push_back(waitInfo); } } if (m_cmdBuffersUsed.test(DxvkCmdBuffer::InitBuffer)) { - auto& cmdInfo = info.cmdBuffers[info.cmdBufferCount++]; - cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; + VkCommandBufferSubmitInfo cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; cmdInfo.commandBuffer = m_initBuffer; + m_submission.cmdBuffers.push_back(cmdInfo); } if (m_cmdBuffersUsed.test(DxvkCmdBuffer::ExecBuffer)) { - auto& cmdInfo = info.cmdBuffers[info.cmdBufferCount++]; - cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; + VkCommandBufferSubmitInfo cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; cmdInfo.commandBuffer = m_execBuffer; + m_submission.cmdBuffers.push_back(cmdInfo); } if (waitSemaphore) { - auto& waitInfo = info.waitSync[info.waitCount++]; - waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; waitInfo.semaphore = waitSemaphore; waitInfo.stageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + m_submission.waitSync.push_back(waitInfo); } if (wakeSemaphore) { - auto& signalInfo = info.wakeSync[info.wakeCount++]; - signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; signalInfo.semaphore = wakeSemaphore; signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; + m_submission.wakeSync.push_back(signalInfo); } - return submitToQueue(graphics.queueHandle, m_fence, info); + return submitToQueue(graphics.queueHandle, m_fence, m_submission); } @@ -215,12 +215,12 @@ namespace dxvk { VkFence fence, const DxvkQueueSubmission& info) { VkSubmitInfo2 submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO_2 }; - submitInfo.waitSemaphoreInfoCount = info.waitCount; - submitInfo.pWaitSemaphoreInfos = info.waitSync; - submitInfo.commandBufferInfoCount = info.cmdBufferCount; - submitInfo.pCommandBufferInfos = info.cmdBuffers; - submitInfo.signalSemaphoreInfoCount = info.wakeCount; - submitInfo.pSignalSemaphoreInfos = info.wakeSync; + submitInfo.waitSemaphoreInfoCount = info.waitSync.size(); + submitInfo.pWaitSemaphoreInfos = info.waitSync.data(); + submitInfo.commandBufferInfoCount = info.cmdBuffers.size(); + submitInfo.pCommandBufferInfos = info.cmdBuffers.data(); + submitInfo.signalSemaphoreInfoCount = info.wakeSync.size(); + submitInfo.pSignalSemaphoreInfos = info.wakeSync.data(); return m_vkd->vkQueueSubmit2(queue, 1, &submitInfo, fence); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 286a58557..4139f020d 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -38,12 +38,15 @@ namespace dxvk { * only, array sizes are based on need. */ struct DxvkQueueSubmission { - uint32_t waitCount; - VkSemaphoreSubmitInfo waitSync[2]; - uint32_t wakeCount; - VkSemaphoreSubmitInfo wakeSync[2]; - uint32_t cmdBufferCount; - VkCommandBufferSubmitInfo cmdBuffers[4]; + std::vector waitSync; + std::vector wakeSync; + std::vector cmdBuffers; + + void reset() { + waitSync.clear(); + wakeSync.clear(); + cmdBuffers.clear(); + } }; /** @@ -789,6 +792,7 @@ namespace dxvk { DxvkGpuQueryTracker m_gpuQueryTracker; DxvkBufferTracker m_bufferTracker; DxvkStatCounters m_statCounters; + DxvkQueueSubmission m_submission; std::vector, From 05a827703bffb87737a22604a2932030f4505da7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 22 Oct 2021 16:49:22 +0200 Subject: [PATCH 0299/1348] [dxvk] Add fence support to command list Co-authored-by: Derek Lesho --- src/dxvk/dxvk_cmdlist.cpp | 23 +++++++++++++++++++++-- src/dxvk/dxvk_cmdlist.h | 26 +++++++++++++++++++++++++- src/dxvk/dxvk_context.cpp | 10 ++++++++++ src/dxvk/dxvk_context.h | 22 +++++++++++++++++++++- src/dxvk/dxvk_fence.h | 17 +++++++++++++++++ 5 files changed, 94 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 255725b32..107850753 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -106,7 +106,7 @@ namespace dxvk { VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; waitInfo.semaphore = m_sdmaSemaphore; - waitInfo.stageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; m_submission.waitSync.push_back(waitInfo); } } @@ -126,7 +126,7 @@ namespace dxvk { if (waitSemaphore) { VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; waitInfo.semaphore = waitSemaphore; - waitInfo.stageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; m_submission.waitSync.push_back(waitInfo); } @@ -137,6 +137,22 @@ namespace dxvk { m_submission.wakeSync.push_back(signalInfo); } + for (const auto& entry : m_waitSemaphores) { + VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + waitInfo.semaphore = entry.fence->handle(); + waitInfo.value = entry.value; + waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; + m_submission.waitSync.push_back(waitInfo); + } + + for (const auto& entry : m_signalSemaphores) { + VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + signalInfo.semaphore = entry.fence->handle(); + signalInfo.value = entry.value; + signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; + m_submission.wakeSync.push_back(signalInfo); + } + return submitToQueue(graphics.queueHandle, m_fence, m_submission); } @@ -207,6 +223,9 @@ namespace dxvk { descriptorPools.second->recycleDescriptorPool(descriptorPools.first); m_descriptorPools.clear(); + + m_waitSemaphores.clear(); + m_signalSemaphores.clear(); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 4139f020d..f58f725d2 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -5,6 +5,7 @@ #include "dxvk_bind_mask.h" #include "dxvk_buffer.h" #include "dxvk_descriptor.h" +#include "dxvk_fence.h" #include "dxvk_gpu_event.h" #include "dxvk_gpu_query.h" #include "dxvk_lifetime.h" @@ -195,6 +196,26 @@ namespace dxvk { m_signalTracker.notify(); } + /** + * \brief Waits for fence + * + * \param [in] fence Fence to wait on + * \param [in] value Value to wait for + */ + void waitFence(Rc fence, uint64_t value) { + m_waitSemaphores.emplace_back(std::move(fence), value); + } + + /** + * \brief Signals fence + * + * \param [in] fence Fence to signal + * \param [in] value Value to signal to + */ + void signalFence(Rc fence, uint64_t value) { + m_signalSemaphores.emplace_back(std::move(fence), value); + } + /** * \brief Resets the command list * @@ -784,7 +805,7 @@ namespace dxvk { VkCommandBuffer m_sdmaBuffer = VK_NULL_HANDLE; VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE; - + DxvkCmdBufferFlags m_cmdBuffersUsed; DxvkLifetimeTracker m_resources; DxvkSignalTracker m_signalTracker; @@ -794,6 +815,9 @@ namespace dxvk { DxvkStatCounters m_statCounters; DxvkQueueSubmission m_submission; + std::vector m_waitSemaphores; + std::vector m_signalSemaphores; + std::vector, Rc>> m_descriptorPools; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 9064a98ae..b1716c326 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2646,6 +2646,16 @@ namespace dxvk { } + void DxvkContext::waitFence(const Rc& fence, uint64_t value) { + m_cmd->waitFence(fence, value); + } + + + void DxvkContext::signalFence(const Rc& fence, uint64_t value) { + m_cmd->signalFence(fence, value); + } + + void DxvkContext::beginDebugLabel(VkDebugUtilsLabelEXT *label) { if (!m_device->instance()->extensions().extDebugUtils) return; diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 1f1c1fd54..3e9eff4e3 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1088,7 +1088,27 @@ namespace dxvk { void signal( const Rc& signal, uint64_t value); - + + /** + * \brief Waits for fence + * + * Stalls current command list execution until + * the fence reaches the given value or higher. + * \param [in] fence Fence to wait on + * \param [in] value Value to wait on + */ + void waitFence(const Rc& fence, uint64_t value); + + /** + * \brief Signals fence + * + * Signals fence to the given value once the current + * command list execution completes on the GPU. + * \param [in] fence Fence to signal + * \param [in] value Value to signal + */ + void signalFence(const Rc& fence, uint64_t value); + /** * \brief Begins a debug label region * \param [in] label The debug label diff --git a/src/dxvk/dxvk_fence.h b/src/dxvk/dxvk_fence.h index a533d22ba..c9fc243b1 100644 --- a/src/dxvk/dxvk_fence.h +++ b/src/dxvk/dxvk_fence.h @@ -2,6 +2,8 @@ #include #include +#include +#include #include "dxvk_resource.h" @@ -10,6 +12,7 @@ namespace dxvk { class DxvkDevice; + class DxvkFence; using DxvkFenceEvent = std::function; @@ -20,6 +23,20 @@ namespace dxvk { uint64_t initialValue; }; + /** + * \brief Fence-value pair + */ + struct DxvkFenceValuePair { + DxvkFenceValuePair() { } + DxvkFenceValuePair(Rc&& fence_, uint64_t value_) + : fence(std::move(fence_)), value(value_) { } + DxvkFenceValuePair(const Rc& fence_, uint64_t value_) + : fence(fence_), value(value_) { } + + Rc fence; + uint64_t value; + }; + /** * \brief Fence * From dcd2c4847b95cd5732f17087f515e64a886800a8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 22 Oct 2021 17:22:41 +0200 Subject: [PATCH 0300/1348] [d3d11] Implement ID3D11Fence No interop support just yet. Co-authored-by: Derek Lesho --- src/d3d11/d3d11_context_imm.cpp | 34 ++++++++++++++-- src/d3d11/d3d11_device.cpp | 17 ++++---- src/d3d11/d3d11_device.h | 2 +- src/d3d11/d3d11_fence.cpp | 72 +++++++++++++++++++++++++++++++++ src/d3d11/d3d11_fence.h | 47 +++++++++++++++++++++ src/d3d11/meson.build | 1 + 6 files changed, 161 insertions(+), 12 deletions(-) create mode 100644 src/d3d11/d3d11_fence.cpp create mode 100644 src/d3d11/d3d11_fence.h diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 0c4ea85e3..cbbc2d1eb 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -1,6 +1,7 @@ #include "d3d11_cmdlist.h" #include "d3d11_context_imm.h" #include "d3d11_device.h" +#include "d3d11_fence.h" #include "d3d11_texture.h" constexpr static uint32_t MinFlushIntervalUs = 750; @@ -190,16 +191,41 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::Signal( ID3D11Fence* pFence, UINT64 Value) { - Logger::err("D3D11ImmediateContext::Signal: Not implemented"); - return E_NOTIMPL; + auto fence = static_cast(pFence); + + if (!fence) + return E_INVALIDARG; + + EmitCs([ + cFence = fence->GetFence(), + cValue = Value + ] (DxvkContext* ctx) { + ctx->signalFence(cFence, cValue); + }); + + Flush(); + return S_OK; } HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::Wait( ID3D11Fence* pFence, UINT64 Value) { - Logger::err("D3D11ImmediateContext::Wait: Not implemented"); - return E_NOTIMPL; + auto fence = static_cast(pFence); + + if (!fence) + return E_INVALIDARG; + + Flush(); + + EmitCs([ + cFence = fence->GetFence(), + cValue = Value + ] (DxvkContext* ctx) { + ctx->waitFence(cFence, cValue); + }); + + return S_OK; } diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index f71aa1561..337c3127a 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -12,6 +12,7 @@ #include "d3d11_context_def.h" #include "d3d11_context_imm.h" #include "d3d11_device.h" +#include "d3d11_fence.h" #include "d3d11_input_layout.h" #include "d3d11_interop.h" #include "d3d11_query.h" @@ -1347,16 +1348,17 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Device::CreateFence( UINT64 InitialValue, D3D11_FENCE_FLAG Flags, - REFIID ReturnedInterface, + REFIID riid, void** ppFence) { InitReturnPtr(ppFence); - static bool s_errorShown = false; - - if (!std::exchange(s_errorShown, true)) - Logger::err("D3D11Device::CreateFence: Not implemented"); - - return E_NOTIMPL; + try { + Com fence = new D3D11Fence(this, InitialValue, Flags); + return fence->QueryInterface(riid, ppFence); + } catch (const DxvkError& e) { + Logger::err(e.message()); + return E_FAIL; + } } @@ -1930,6 +1932,7 @@ namespace dxvk { enabled.vk11.shaderDrawParameters = VK_TRUE; enabled.vk12.samplerMirrorClampToEdge = VK_TRUE; + enabled.vk12.timelineSemaphore = VK_TRUE; enabled.vk13.shaderDemoteToHelperInvocation = supported.vk13.shaderDemoteToHelperInvocation; diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 7643f8f4b..5a99bd62a 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -260,7 +260,7 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE CreateFence( UINT64 InitialValue, D3D11_FENCE_FLAG Flags, - REFIID ReturnedInterface, + REFIID riid, void** ppFence); void STDMETHODCALLTYPE ReadFromSubresource( diff --git a/src/d3d11/d3d11_fence.cpp b/src/d3d11/d3d11_fence.cpp new file mode 100644 index 000000000..3c802f898 --- /dev/null +++ b/src/d3d11/d3d11_fence.cpp @@ -0,0 +1,72 @@ +#include "d3d11_fence.h" +#include "d3d11_device.h" + +namespace dxvk { + + D3D11Fence::D3D11Fence( + D3D11Device* pDevice, + UINT64 InitialValue, + D3D11_FENCE_FLAG Flags) + : D3D11DeviceChild(pDevice) { + DxvkFenceCreateInfo fenceInfo; + fenceInfo.initialValue = InitialValue; + + if (Flags) + Logger::err(str::format("Fence flags 0x", std::hex, Flags, " not supported")); + + m_fence = pDevice->GetDXVKDevice()->createFence(fenceInfo); + } + + + D3D11Fence::~D3D11Fence() { + + } + + + HRESULT STDMETHODCALLTYPE D3D11Fence::QueryInterface( + REFIID riid, + void** ppvObject) { + if (ppvObject == nullptr) + return E_POINTER; + + *ppvObject = nullptr; + + if (riid == __uuidof(IUnknown) + || riid == __uuidof(ID3D11DeviceChild) + || riid == __uuidof(ID3D11Fence)) { + *ppvObject = ref(this); + return S_OK; + } + + Logger::warn("D3D11Fence: Unknown interface query"); + Logger::warn(str::format(riid)); + return E_NOINTERFACE; + } + + + HRESULT STDMETHODCALLTYPE D3D11Fence::CreateSharedHandle( + const SECURITY_ATTRIBUTES* pAttributes, + DWORD dwAccess, + LPCWSTR lpName, + HANDLE* pHandle) { + Logger::err("D3D11Fence::CreateSharedHandle: Not implemented"); + return E_NOTIMPL; + } + + + HRESULT STDMETHODCALLTYPE D3D11Fence::SetEventOnCompletion( + UINT64 Value, + HANDLE hEvent) { + m_fence->enqueueWait(Value, [hEvent] { + SetEvent(hEvent); + }); + + return S_OK; + } + + + UINT64 STDMETHODCALLTYPE D3D11Fence::GetCompletedValue() { + return m_fence->getValue(); + } + +} diff --git a/src/d3d11/d3d11_fence.h b/src/d3d11/d3d11_fence.h new file mode 100644 index 000000000..b29c0c999 --- /dev/null +++ b/src/d3d11/d3d11_fence.h @@ -0,0 +1,47 @@ +#pragma once + +#include "../dxvk/dxvk_fence.h" +#include "../dxvk/dxvk_gpu_query.h" + +#include "d3d11_device_child.h" + +namespace dxvk { + + class D3D11Fence : public D3D11DeviceChild { + + public: + + D3D11Fence( + D3D11Device* pDevice, + UINT64 InitialValue, + D3D11_FENCE_FLAG Flags); + + ~D3D11Fence(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + HRESULT STDMETHODCALLTYPE CreateSharedHandle( + const SECURITY_ATTRIBUTES* pAttributes, + DWORD dwAccess, + LPCWSTR lpName, + HANDLE* pHandle); + + HRESULT STDMETHODCALLTYPE SetEventOnCompletion( + UINT64 Value, + HANDLE hEvent); + + UINT64 STDMETHODCALLTYPE GetCompletedValue(); + + Rc GetFence() const { + return m_fence; + } + + private: + + Rc m_fence; + + }; + +} diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index ad35acd8e..85fe78074 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -37,6 +37,7 @@ d3d11_src = [ 'd3d11_depth_stencil.cpp', 'd3d11_device.cpp', 'd3d11_enums.cpp', + 'd3d11_fence.cpp', 'd3d11_gdi.cpp', 'd3d11_initializer.cpp', 'd3d11_input_layout.cpp', From a8e573b9b8f76c2570ca199e00dcbb5e4a850bab Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 19 Jul 2022 22:26:12 -0400 Subject: [PATCH 0301/1348] [dxvk] Enable VK_KHR_external_semaphore_win32 if available --- src/dxvk/dxvk_adapter.cpp | 3 ++- src/dxvk/dxvk_extensions.h | 1 + src/vulkan/vulkan_loader.h | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index b3bb96421..ea1423fa8 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -283,7 +283,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.extConservativeRasterization, @@ -300,6 +300,7 @@ namespace dxvk { &devExtensions.extTransformFeedback, &devExtensions.extVertexAttributeDivisor, &devExtensions.khrExternalMemoryWin32, + &devExtensions.khrExternalSemaphoreWin32, &devExtensions.khrPipelineLibrary, &devExtensions.khrSwapchain, &devExtensions.nvxBinaryImport, diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index cbf4ba09d..ffc7c3730 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -292,6 +292,7 @@ namespace dxvk { DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt khrExternalSemaphoreWin32 = { VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrPipelineLibrary = { VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrSwapchain = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt nvxBinaryImport = { VK_NVX_BINARY_IMPORT_EXTENSION_NAME, DxvkExtMode::Disabled }; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 094f19cc2..47c26eed8 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -379,6 +379,11 @@ namespace dxvk::vk { VULKAN_FN(vkGetMemoryWin32HandleKHR); VULKAN_FN(vkGetMemoryWin32HandlePropertiesKHR); #endif + + #ifdef VK_KHR_external_semaphore_win32 + VULKAN_FN(vkGetSemaphoreWin32HandleKHR); + VULKAN_FN(vkImportSemaphoreWin32HandleKHR); + #endif }; } From a3548f8043412f89acfb9d8edb6324db00710b10 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 19 Jul 2022 22:27:54 -0400 Subject: [PATCH 0302/1348] [dxvk] Add shared handle access to DxvkFence --- src/dxvk/dxvk_fence.cpp | 33 +++++++++++++++++++++++++++++++++ src/dxvk/dxvk_fence.h | 17 ++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_fence.cpp b/src/dxvk/dxvk_fence.cpp index 2e5a362eb..3f3a7746d 100644 --- a/src/dxvk/dxvk_fence.cpp +++ b/src/dxvk/dxvk_fence.cpp @@ -11,6 +11,12 @@ namespace dxvk { typeInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; typeInfo.initialValue = info.initialValue; + VkExportSemaphoreCreateInfo exportInfo = { VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO }; + exportInfo.handleTypes = info.sharedType; + + if (info.sharedType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM) + typeInfo.pNext = &exportInfo; + VkSemaphoreCreateInfo semaphoreInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &typeInfo }; VkResult vr = m_vkd->vkCreateSemaphore(m_vkd->device(), @@ -19,6 +25,17 @@ namespace dxvk { if (vr != VK_SUCCESS) throw DxvkError("Failed to create timeline semaphore"); + if (info.sharedHandle != INVALID_HANDLE_VALUE) { + VkImportSemaphoreWin32HandleInfoKHR importInfo = { VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR }; + importInfo.semaphore = m_semaphore; + importInfo.handleType = info.sharedType; + importInfo.handle = info.sharedHandle; + + vr = m_vkd->vkImportSemaphoreWin32HandleKHR(m_vkd->device(), &importInfo); + if (vr != VK_SUCCESS) + throw DxvkError("Failed to import timeline semaphore"); + } + m_thread = dxvk::thread([this] { run(); }); } @@ -92,4 +109,20 @@ namespace dxvk { } } + HANDLE DxvkFence::sharedHandle() const { + if (m_info.sharedType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM) + return INVALID_HANDLE_VALUE; + + VkSemaphoreGetWin32HandleInfoKHR win32HandleInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR }; + win32HandleInfo.semaphore = m_semaphore; + win32HandleInfo.handleType = m_info.sharedType; + + HANDLE sharedHandle = INVALID_HANDLE_VALUE; + VkResult vr = m_vkd->vkGetSemaphoreWin32HandleKHR(m_vkd->device(), &win32HandleInfo, &sharedHandle); + + if (vr != VK_SUCCESS) + Logger::err(str::format("Failed to get semaphore handle: ", vr)); + + return sharedHandle; + } } diff --git a/src/dxvk/dxvk_fence.h b/src/dxvk/dxvk_fence.h index c9fc243b1..797452860 100644 --- a/src/dxvk/dxvk_fence.h +++ b/src/dxvk/dxvk_fence.h @@ -21,6 +21,15 @@ namespace dxvk { */ struct DxvkFenceCreateInfo { uint64_t initialValue; + VkExternalSemaphoreHandleTypeFlagBits sharedType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM; + union { +#ifdef _WIN32 + HANDLE sharedHandle = INVALID_HANDLE_VALUE; +#else + // Placeholder for other handle types, such as FD + void *dummy; +#endif + }; }; /** @@ -78,6 +87,12 @@ namespace dxvk { */ void enqueueWait(uint64_t value, DxvkFenceEvent&& event); + /** + * \brief Create a new shared handle to timeline semaphore backing the fence + * \returns The shared handle with the type given by DxvkFenceCreateInfo::sharedType + */ + HANDLE sharedHandle() const; + private: struct QueueItem { @@ -111,4 +126,4 @@ namespace dxvk { }; -} \ No newline at end of file +} From 8fefb099d7f8d665655a30bdcd7f065e711bd66c Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Tue, 19 Jul 2022 22:28:26 -0400 Subject: [PATCH 0303/1348] [d3d11] Add support for shared ID3D11Fence resources --- src/d3d11/d3d11_device.cpp | 14 +++++++++++--- src/d3d11/d3d11_fence.cpp | 37 +++++++++++++++++++++++++++++++++---- src/d3d11/d3d11_fence.h | 4 +++- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 337c3127a..0984f73e0 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1353,7 +1353,7 @@ namespace dxvk { InitReturnPtr(ppFence); try { - Com fence = new D3D11Fence(this, InitialValue, Flags); + Com fence = new D3D11Fence(this, InitialValue, Flags, INVALID_HANDLE_VALUE); return fence->QueryInterface(riid, ppFence); } catch (const DxvkError& e) { Logger::err(e.message()); @@ -1424,8 +1424,16 @@ namespace dxvk { void** ppFence) { InitReturnPtr(ppFence); - Logger::err("D3D11Device::OpenSharedFence: Not implemented"); - return E_NOTIMPL; + if (ppFence == nullptr) + return S_FALSE; + + try { + Com fence = new D3D11Fence(this, 0, D3D11_FENCE_FLAG_SHARED, hFence); + return fence->QueryInterface(ReturnedInterface, ppFence); + } catch (const DxvkError& e) { + Logger::err(e.message()); + return E_FAIL; + } } diff --git a/src/d3d11/d3d11_fence.cpp b/src/d3d11/d3d11_fence.cpp index 3c802f898..e3c7688b2 100644 --- a/src/d3d11/d3d11_fence.cpp +++ b/src/d3d11/d3d11_fence.cpp @@ -6,12 +6,21 @@ namespace dxvk { D3D11Fence::D3D11Fence( D3D11Device* pDevice, UINT64 InitialValue, - D3D11_FENCE_FLAG Flags) + D3D11_FENCE_FLAG Flags, + HANDLE hFence) : D3D11DeviceChild(pDevice) { DxvkFenceCreateInfo fenceInfo; fenceInfo.initialValue = InitialValue; + m_flags = Flags; - if (Flags) + if (Flags & D3D11_FENCE_FLAG_SHARED) { + fenceInfo.sharedType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE_BIT; + if (hFence == nullptr) + hFence = INVALID_HANDLE_VALUE; + fenceInfo.sharedHandle = hFence; + } + + if (Flags & ~D3D11_FENCE_FLAG_SHARED) Logger::err(str::format("Fence flags 0x", std::hex, Flags, " not supported")); m_fence = pDevice->GetDXVKDevice()->createFence(fenceInfo); @@ -49,14 +58,31 @@ namespace dxvk { DWORD dwAccess, LPCWSTR lpName, HANDLE* pHandle) { - Logger::err("D3D11Fence::CreateSharedHandle: Not implemented"); - return E_NOTIMPL; + if (!(m_flags & D3D11_FENCE_FLAG_SHARED)) + return E_INVALIDARG; + + if (pAttributes) + Logger::warn(str::format("CreateSharedHandle: attributes ", pAttributes, " not handled")); + if (dwAccess) + Logger::warn(str::format("CreateSharedHandle: access ", dwAccess, " not handled")); + if (lpName) + Logger::warn(str::format("CreateSharedHandle: name ", dxvk::str::fromws(lpName), " not handled")); + + HANDLE sharedHandle = m_fence->sharedHandle(); + if (sharedHandle == INVALID_HANDLE_VALUE) + return E_INVALIDARG; + + *pHandle = sharedHandle; + return S_OK; } HRESULT STDMETHODCALLTYPE D3D11Fence::SetEventOnCompletion( UINT64 Value, HANDLE hEvent) { + // TODO in case of rewinds, the stored value may be higher. + // For shared fences, calling vkWaitSemaphores here could alleviate the issue. + m_fence->enqueueWait(Value, [hEvent] { SetEvent(hEvent); }); @@ -66,6 +92,9 @@ namespace dxvk { UINT64 STDMETHODCALLTYPE D3D11Fence::GetCompletedValue() { + // TODO in the case of rewinds, the stored value may be higher. + // For shared fences, calling vkGetSemaphoreCounterValue here could alleviate the issue. + return m_fence->getValue(); } diff --git a/src/d3d11/d3d11_fence.h b/src/d3d11/d3d11_fence.h index b29c0c999..99d42a943 100644 --- a/src/d3d11/d3d11_fence.h +++ b/src/d3d11/d3d11_fence.h @@ -14,7 +14,8 @@ namespace dxvk { D3D11Fence( D3D11Device* pDevice, UINT64 InitialValue, - D3D11_FENCE_FLAG Flags); + D3D11_FENCE_FLAG Flags, + HANDLE hFence); ~D3D11Fence(); @@ -41,6 +42,7 @@ namespace dxvk { private: Rc m_fence; + D3D11_FENCE_FLAG m_flags; }; From f2d4455cdfccd8b961ba08ef1e204662466ef3b6 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Fri, 22 Jul 2022 17:25:16 +0200 Subject: [PATCH 0304/1348] [util] enable dialog mode for NFS 3 modern patch --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 254c6f71c..9c02a7d80 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -579,6 +579,10 @@ namespace dxvk { { R"(\\PortRoyale3\.exe$)", {{ { "d3d9.allowDoNotWait", "False" }, }} }, + /* Need For Speed 3 modern patch */ + { R"(\\nfs3\.exe$)", {{ + { "d3d9.enableDialogMode", "True" }, + }} }, }}; From cb291f29a1e2ec547b85142a861d4836e9bb12e6 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sat, 23 Jul 2022 00:08:28 +0200 Subject: [PATCH 0305/1348] [util] enable alphaTestWiggleRoom for Ninja Blade --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 9c02a7d80..02d013bd4 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -583,6 +583,11 @@ namespace dxvk { { R"(\\nfs3\.exe$)", {{ { "d3d9.enableDialogMode", "True" }, }} }, + /* Ninja Blade * + * Transparent main character on Nvidia */ + { R"(\\NinjaBlade\.exe$)", {{ + { "d3d9.alphaTestWiggleRoom", "True" }, + }} }, }}; From 9d8484f2e9ce2a1ce6d605088ea0f3ffb1b89881 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 23 Jul 2022 15:31:43 +0200 Subject: [PATCH 0306/1348] [dxvk] Use synchronization2 functions for timestamp queries Again not really making use of the new stage flags, but might as well call the function. Oversight from earlier changes. --- src/dxvk/dxvk_cmdlist.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index f58f725d2..1e8625396 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -762,10 +762,10 @@ namespace dxvk { void cmdWriteTimestamp( - VkPipelineStageFlagBits pipelineStage, + VkPipelineStageFlagBits2 pipelineStage, VkQueryPool queryPool, uint32_t query) { - m_vkd->vkCmdWriteTimestamp(m_execBuffer, + m_vkd->vkCmdWriteTimestamp2(m_execBuffer, pipelineStage, queryPool, query); } From 9cd04735442be8ff28ad97c4c77789bdbefc43ea Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 23 Jul 2022 21:21:22 +0200 Subject: [PATCH 0307/1348] [util] Set ignoreGraphicsBarriers option for Stray --- src/util/config/config.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 02d013bd4..39ae0ada0 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -283,6 +283,12 @@ namespace dxvk { { R"(\\DayZ_x64\.exe$)", {{ { "d3d11.cachedDynamicResources", "cr" }, }} }, + /* Stray - writes to the same UAV every draw, * + * presumably for culling, which doesn't play * + * nicely with D3D11 without vendor libraries */ + { R"(\\Stray-Win64-Shipping\.exe$)", {{ + { "d3d11.ignoreGraphicsBarriers", "True" }, + }} }, /**********************************************/ /* D3D9 GAMES */ From 41ec5d2c523f380bf8fa9b9e18c371ab32941258 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 24 Jul 2022 15:20:03 +0200 Subject: [PATCH 0308/1348] [dxvk] Avoid bsf instruction It's very slow compared to tzcnt on some CPUs, and we have a working fallback. --- src/util/util_bit.h | 48 ++++++++++++++++----------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index 4ee917d83..e52f945be 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -56,11 +56,17 @@ namespace dxvk::bit { #elif defined(__BMI__) return __tzcnt_u32(n); #elif defined(__GNUC__) || defined(__clang__) + // tzcnt is encoded as rep bsf, so we can use it on all + // processors, but the behaviour of zero inputs differs: + // - bsf: zf = 1, cf = ?, result = ? + // - tzcnt: zf = 0, cf = 1, result = 32 + // We'll have to handle this case manually. uint32_t res; uint32_t tmp; asm ( + "tzcnt %2, %0;" "mov $32, %1;" - "bsf %2, %0;" + "test %2, %2;" "cmovz %1, %0;" : "=&r" (res), "=&r" (tmp) : "r" (n)); @@ -86,41 +92,21 @@ namespace dxvk::bit { uint64_t res; uint64_t tmp; asm ( + "tzcnt %2, %0;" "mov $64, %1;" - "bsf %2, %0;" + "test %2, %2;" "cmovz %1, %0;" : "=&r" (res), "=&r" (tmp) : "r" (n)); return res; #else - uint32_t r = 63; - n &= -n; - r -= (n & 0x00000000FFFFFFFFull) ? 32 : 0; - r -= (n & 0x0000FFFF0000FFFFull) ? 16 : 0; - r -= (n & 0x00FF00FF00FF00FFull) ? 8 : 0; - r -= (n & 0x0F0F0F0F0F0F0F0Full) ? 4 : 0; - r -= (n & 0x3333333333333333ull) ? 2 : 0; - r -= (n & 0x5555555555555555ull) ? 1 : 0; - return n != 0 ? r : 64; - #endif - } - - inline uint32_t bsf(uint32_t n) { - #if defined(_MSC_VER) && !defined(__clang__) - unsigned long index; - _BitScanForward(&index, n); - return uint32_t(index); - #elif defined(__GNUC__) || defined(__clang__) - return __builtin_ctz(n); - #else - uint32_t r = 31; - n &= -n; - r -= (n & 0x0000FFFF) ? 16 : 0; - r -= (n & 0x00FF00FF) ? 8 : 0; - r -= (n & 0x0F0F0F0F) ? 4 : 0; - r -= (n & 0x33333333) ? 2 : 0; - r -= (n & 0x55555555) ? 1 : 0; - return r; + uint32_t lo = uint32_t(n); + if (lo) { + return tzcnt(lo); + } else { + uint32_t hi = uint32_t(n >> 32); + return tzcnt(hi) + 32; + } #endif } @@ -348,7 +334,7 @@ namespace dxvk::bit { } uint32_t operator * () const { - return bsf(m_mask); + return tzcnt(m_mask); } bool operator == (iterator other) const { return m_mask == other.m_mask; } From b67d5c8c1d83084587ed66acde0ddbb5db822881 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 24 Jul 2022 17:30:54 +0200 Subject: [PATCH 0309/1348] [util] Correctly mark flag register as clobbered --- src/util/util_bit.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index e52f945be..ee7470a70 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -69,7 +69,8 @@ namespace dxvk::bit { "test %2, %2;" "cmovz %1, %0;" : "=&r" (res), "=&r" (tmp) - : "r" (n)); + : "r" (n) + : "cc"); return res; #else uint32_t r = 31; @@ -97,7 +98,8 @@ namespace dxvk::bit { "test %2, %2;" "cmovz %1, %0;" : "=&r" (res), "=&r" (tmp) - : "r" (n)); + : "r" (n) + : "cc"); return res; #else uint32_t lo = uint32_t(n); From abf5ed154fbdb0e76e275e41b6ae2db16e836dbf Mon Sep 17 00:00:00 2001 From: Krzysztof Dobrowolski Date: Fri, 22 Jul 2022 19:55:51 +0200 Subject: [PATCH 0310/1348] [dxvk] Add Direct3D9ForceHybridEnumeration empty export function. --- src/d3d9/d3d9.def | 2 ++ src/d3d9/d3d9_main.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/d3d9/d3d9.def b/src/d3d9/d3d9.def index 50e2eb08a..4e3f9ae51 100644 --- a/src/d3d9/d3d9.def +++ b/src/d3d9/d3d9.def @@ -23,3 +23,5 @@ EXPORTS DXVK_RegisterAnnotation @ 28257 NONAME DXVK_UnRegisterAnnotation @ 28258 NONAME + + Direct3D9ForceHybridEnumeration @16 NONAME PRIVATE diff --git a/src/d3d9/d3d9_main.cpp b/src/d3d9/d3d9_main.cpp index 367dac9c3..e182b5fa3 100644 --- a/src/d3d9/d3d9_main.cpp +++ b/src/d3d9/d3d9_main.cpp @@ -98,4 +98,7 @@ extern "C" { dxvk::D3D9GlobalAnnotationList::Instance().UnregisterAnnotator(annotation); } + DLLEXPORT void __stdcall Direct3D9ForceHybridEnumeration(UINT uHybrid) { + } + } From 08da6d8ca4a93efc95c984fa78f0001a9d3bf4b6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 25 Jul 2022 15:58:03 +0200 Subject: [PATCH 0311/1348] [dxbc] Bound-check mip level for resinfo instruction --- src/dxbc/dxbc_compiler.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index ad393d554..70aaa2e3f 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -3077,7 +3077,14 @@ namespace dxvk { // result into a four-component vector later. DxbcRegisterValue imageSize = emitQueryTextureSize(ins.src[1], mipLod); DxbcRegisterValue imageLevels = emitQueryTextureLods(ins.src[1]); - + + // If the mip level is out of bounds, D3D requires us to return + // zero before applying modifiers, whereas SPIR-V is undefined, + // so we need to fix it up manually here. + imageSize.id = m_module.opSelect(getVectorTypeId(imageSize.type), + m_module.opULessThan(m_module.defBoolType(), mipLod.id, imageLevels.id), + imageSize.id, emitBuildZeroVector(imageSize.type).id); + // Convert intermediates to the requested type if (returnType == DxbcScalarType::Float32) { imageSize.type.ctype = DxbcScalarType::Float32; From b06140af470117e8aa27fc539aa291f5c3f8691c Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Mon, 25 Jul 2022 15:33:42 +0200 Subject: [PATCH 0312/1348] [util] set maxFrameLatency to 1 for YS Origin --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 39ae0ada0..be4689aa3 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -594,6 +594,11 @@ namespace dxvk { { R"(\\NinjaBlade\.exe$)", {{ { "d3d9.alphaTestWiggleRoom", "True" }, }} }, + /* YS Origin * + * Helps very bad frametimes in some areas */ + { R"(\\yso_win\.exe$)", {{ + { "d3d9.maxFrameLatency", "1" }, + }} }, }}; From 5fe04eb6ac97b34efcff39da74c9811ee2b01425 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 26 Jul 2022 02:40:08 +0200 Subject: [PATCH 0313/1348] [dxvk] Fix weird indentation how did this happen --- src/dxvk/dxvk_swapchain_blitter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index ade44e218..33ae54bf9 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -54,10 +54,10 @@ namespace dxvk { this->draw(ctx, m_fsResolve, dstView, dstRect, srcView, srcRect); } else { - if (m_resolveImage == nullptr - || m_resolveImage->info().extent != srcView->imageInfo().extent - || m_resolveImage->info().format != srcView->imageInfo().format) - this->createResolveImage(srcView->imageInfo()); + if (m_resolveImage == nullptr + || m_resolveImage->info().extent != srcView->imageInfo().extent + || m_resolveImage->info().format != srcView->imageInfo().format) + this->createResolveImage(srcView->imageInfo()); this->resolve(ctx, m_resolveView, srcView); this->draw(ctx, m_fsBlit, dstView, dstRect, m_resolveView, srcRect); From 6425d2368bf6b3f22bbb39ee1d79aa74d6fe295f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 26 Jul 2022 18:49:22 +0100 Subject: [PATCH 0314/1348] [build] Use arch-mingw-github-action v8 Fixes generated version info. --- .github/workflows/artifacts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/artifacts.yml b/.github/workflows/artifacts.yml index 94162e1c0..b843d1aaf 100644 --- a/.github/workflows/artifacts.yml +++ b/.github/workflows/artifacts.yml @@ -19,7 +19,7 @@ jobs: - name: Build release id: build-release - uses: Joshua-Ashton/arch-mingw-github-action@v7 + uses: Joshua-Ashton/arch-mingw-github-action@v8 with: command: | export VERSION_NAME="${GITHUB_REF##*/}-${GITHUB_SHA##*/}" From 6c5f73ac26205fe9cdb98a450e12206c6caf2510 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 26 Jul 2022 22:34:23 +0200 Subject: [PATCH 0315/1348] [dxvk] Reintroduce VkPhysicalDeviceIDProperties We need this to get the device LUID. Wine does not fill in the LUID properties in VkPhysicalDeviceVulkan11Properties right now. Fixes DLSS not working, as well as other potential issues. --- src/d3d9/d3d9_adapter.cpp | 6 +++--- src/dxgi/dxgi_adapter.cpp | 6 +++--- src/dxvk/dxvk_adapter.cpp | 3 +++ src/dxvk/dxvk_device_info.h | 1 + src/dxvk/dxvk_instance.cpp | 4 ++-- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/d3d9/d3d9_adapter.cpp b/src/d3d9/d3d9_adapter.cpp index 7ca05fffe..6a5762d4c 100644 --- a/src/d3d9/d3d9_adapter.cpp +++ b/src/d3d9/d3d9_adapter.cpp @@ -702,10 +702,10 @@ namespace dxvk { if (pLUID == nullptr) return D3DERR_INVALIDCALL; - auto& vk11 = m_adapter->devicePropertiesExt().vk11; + auto& deviceId = m_adapter->devicePropertiesExt().coreDeviceId; - if (vk11.deviceLUIDValid) - *pLUID = bit::cast(vk11.deviceLUID); + if (deviceId.deviceLUIDValid) + *pLUID = bit::cast(deviceId.deviceLUID); else *pLUID = dxvk::GetAdapterLUID(m_ordinal); diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index 81c471746..3e8f6307e 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -244,7 +244,7 @@ namespace dxvk { auto deviceProp = m_adapter->deviceProperties(); auto memoryProp = m_adapter->memoryProperties(); - auto vk11 = m_adapter->devicePropertiesExt().vk11; + auto deviceId = m_adapter->devicePropertiesExt().coreDeviceId; // Custom Vendor / Device ID if (options->customVendorId >= 0) @@ -322,8 +322,8 @@ namespace dxvk { pDesc->GraphicsPreemptionGranularity = DXGI_GRAPHICS_PREEMPTION_DMA_BUFFER_BOUNDARY; pDesc->ComputePreemptionGranularity = DXGI_COMPUTE_PREEMPTION_DMA_BUFFER_BOUNDARY; - if (vk11.deviceLUIDValid) - std::memcpy(&pDesc->AdapterLuid, vk11.deviceLUID, VK_LUID_SIZE); + if (deviceId.deviceLUIDValid) + std::memcpy(&pDesc->AdapterLuid, deviceId.deviceLUID, VK_LUID_SIZE); else pDesc->AdapterLuid = GetAdapterLUID(m_index); diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index ea1423fa8..42514ebdc 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -611,6 +611,9 @@ namespace dxvk { m_deviceInfo.vk13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES; m_deviceInfo.vk13.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.vk13); + m_deviceInfo.coreDeviceId.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; + m_deviceInfo.coreDeviceId.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.coreDeviceId); + if (m_deviceExtensions.supports(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) { m_deviceInfo.extConservativeRasterization.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT; m_deviceInfo.extConservativeRasterization.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extConservativeRasterization); diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 545c88cdc..d8bc9ffdb 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -14,6 +14,7 @@ namespace dxvk { */ struct DxvkDeviceInfo { VkPhysicalDeviceProperties2 core; + VkPhysicalDeviceIDProperties coreDeviceId; VkPhysicalDeviceVulkan11Properties vk11; VkPhysicalDeviceVulkan12Properties vk12; VkPhysicalDeviceVulkan13Properties vk13; diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index 3b7487f7a..189418c72 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -61,9 +61,9 @@ namespace dxvk { Rc DxvkInstance::findAdapterByLuid(const void* luid) const { for (const auto& adapter : m_adapters) { - const auto& props = adapter->devicePropertiesExt().vk11; + const auto& deviceId = adapter->devicePropertiesExt().coreDeviceId; - if (props.deviceLUIDValid && !std::memcmp(luid, props.deviceLUID, VK_LUID_SIZE)) + if (deviceId.deviceLUIDValid && !std::memcmp(luid, deviceId.deviceLUID, VK_LUID_SIZE)) return adapter; } From 116feca6af9d868c3c694a4064c7c3f75a52b9de Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sun, 10 Jul 2022 20:14:37 +0200 Subject: [PATCH 0316/1348] [d3d9] Handle unbound textures in fixed function shaders --- src/d3d9/d3d9_device.cpp | 2 ++ src/d3d9/d3d9_fixed_function.cpp | 10 ++++++++-- src/d3d9/d3d9_fixed_function.h | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 86cc93904..83bbf3a7b 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -6661,6 +6661,8 @@ namespace dxvk { break; } + stage.TextureBound = m_state.textures[idx] != nullptr ? 1 : 0; + stage.ColorOp = data[DXVK_TSS_COLOROP]; stage.AlphaOp = data[DXVK_TSS_ALPHAOP]; diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 8c7aeb2a1..6ac190b3b 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -1545,9 +1545,11 @@ namespace dxvk { uint32_t current = diffuse; // Temp starts off as equal to vec4(0) uint32_t temp = m_module.constvec4f32(0.0f, 0.0f, 0.0f, 0.0f); - + uint32_t texture = m_module.constvec4f32(0.0f, 0.0f, 0.0f, 1.0f); + uint32_t unboundTextureConstId = m_module.constvec4f32(0.0f, 0.0f, 0.0f, 1.0f); + for (uint32_t i = 0; i < caps::TextureStageCount; i++) { const auto& stage = m_fsKey.Stages[i].Contents; @@ -1706,7 +1708,11 @@ namespace dxvk { reg = temp; break; case D3DTA_TEXTURE: - reg = GetTexture(); + if (stage.TextureBound != 0) { + reg = GetTexture(); + } else { + reg = unboundTextureConstId; + } break; case D3DTA_TFACTOR: reg = m_ps.constants.textureFactor; diff --git a/src/d3d9/d3d9_fixed_function.h b/src/d3d9/d3d9_fixed_function.h index 3c0158c75..e91de84a5 100644 --- a/src/d3d9/d3d9_fixed_function.h +++ b/src/d3d9/d3d9_fixed_function.h @@ -150,6 +150,8 @@ namespace dxvk { uint32_t ProjectedCount : 3; + uint32_t TextureBound : 1; + // Included in here, read from Stage 0 for packing reasons // Affects all stages. uint32_t GlobalSpecularEnable : 1; From 45c1d7911ee8b592388819f9f7c367c9a33ad9d9 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Tue, 15 Mar 2022 22:07:37 +0100 Subject: [PATCH 0317/1348] [d3d9] Remove evictManagedOnUnlock This is annoying to maintain and hopefully won't be necessary anymore. --- dxvk.conf | 11 ----------- src/d3d9/d3d9_device.cpp | 9 ++++----- src/d3d9/d3d9_options.cpp | 1 - src/d3d9/d3d9_options.h | 3 --- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index fedc28148..45f5998b1 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -298,17 +298,6 @@ # d3d9.shaderModel = 3 -# Evict Managed on Unlock -# -# Decides whether we should evict managed resources from -# system memory when they are unlocked entirely. -# -# Supported values: -# - True, False: Always enable / disable - -# d3d9.evictManagedOnUnlock = False - - # DPI Awareness # # Decides whether we should call SetProcessDPIAware on device diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 83bbf3a7b..e88b4ee9d 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4309,8 +4309,7 @@ namespace dxvk { pResource->SetLocked(Subresource, true); const bool noDirtyUpdate = Flags & D3DLOCK_NO_DIRTY_UPDATE; - if (likely((pResource->IsManaged() && m_d3d9Options.evictManagedOnUnlock) - || ((desc.Pool == D3DPOOL_DEFAULT || !noDirtyUpdate) && !readOnly))) { + if ((desc.Pool == D3DPOOL_DEFAULT || !noDirtyUpdate) && !readOnly) { if (pBox && MipLevel != 0) { D3DBOX scaledBox = *pBox; scaledBox.Left <<= MipLevel; @@ -4325,7 +4324,7 @@ namespace dxvk { } } - if (managed && !m_d3d9Options.evictManagedOnUnlock && !readOnly) { + if (managed && !readOnly) { pResource->SetNeedsUpload(Subresource, true); for (uint32_t i : bit::BitMask(m_activeTextures)) { @@ -4373,7 +4372,7 @@ namespace dxvk { const D3DBOX& box = pResource->GetDirtyBox(Face); bool shouldFlush = pResource->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED; shouldFlush &= box.Left < box.Right && box.Top < box.Bottom && box.Front < box.Back; - shouldFlush &= !pResource->IsManaged() || m_d3d9Options.evictManagedOnUnlock; + shouldFlush &= !pResource->IsManaged(); if (shouldFlush) { this->FlushImage(pResource, Subresource); @@ -4385,7 +4384,7 @@ namespace dxvk { // and we aren't managed (for sysmem copy.) bool shouldToss = pResource->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED; shouldToss &= !pResource->IsDynamic(); - shouldToss &= !pResource->IsManaged() || m_d3d9Options.evictManagedOnUnlock; + shouldToss &= !pResource->IsManaged(); if (shouldToss) { pResource->DestroyBufferSubresource(Subresource); diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index a3944d892..b7e802605 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -43,7 +43,6 @@ namespace dxvk { this->maxFrameRate = config.getOption ("d3d9.maxFrameRate", 0); this->presentInterval = config.getOption ("d3d9.presentInterval", -1); this->shaderModel = config.getOption ("d3d9.shaderModel", 3); - this->evictManagedOnUnlock = config.getOption ("d3d9.evictManagedOnUnlock", false); this->dpiAware = config.getOption ("d3d9.dpiAware", true); this->strictConstantCopies = config.getOption ("d3d9.strictConstantCopies", false); this->strictPow = config.getOption ("d3d9.strictPow", true); diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index 17ffb41d7..33e3ebe5b 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -36,9 +36,6 @@ namespace dxvk { /// Set the max shader model the device can support in the caps. int32_t shaderModel; - /// Whether or not managed resources should stay in memory until unlock, or until manually evicted. - bool evictManagedOnUnlock; - /// Whether or not to set the process as DPI aware in Windows when the API interface is created. bool dpiAware; From ba4d95c5fcf38a8712fddede40523fbca56a9fbb Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sat, 11 Jun 2022 19:38:05 +0200 Subject: [PATCH 0318/1348] [d3d9] Remove direct upload path And remove some tracking that will no longer be necessary. --- src/d3d9/d3d9_common_buffer.h | 15 ------ src/d3d9/d3d9_common_texture.h | 5 -- src/d3d9/d3d9_device.cpp | 97 +++++++++------------------------- 3 files changed, 26 insertions(+), 91 deletions(-) diff --git a/src/d3d9/d3d9_common_buffer.h b/src/d3d9/d3d9_common_buffer.h index c3bc413c1..d2f7f7458 100644 --- a/src/d3d9/d3d9_common_buffer.h +++ b/src/d3d9/d3d9_common_buffer.h @@ -155,11 +155,6 @@ namespace dxvk { */ inline D3D9Range& DirtyRange() { return m_dirtyRange; } - /** - * \brief The range of the buffer that might currently be read by the GPU - */ - inline D3D9Range& GPUReadingRange() { return m_gpuReadingRange; } - /** * \brief Whether or not the buffer was written to by the GPU (in IDirect3DDevice9::ProcessVertices) */ @@ -184,15 +179,6 @@ namespace dxvk { */ inline bool NeedsUpload() { return m_desc.Pool != D3DPOOL_DEFAULT && !m_dirtyRange.IsDegenerate(); } - inline bool DoesStagingBufferUploads() const { return m_uploadUsingStaging; } - - inline void EnableStagingBufferUploads() { - if (GetMapMode() != D3D9_COMMON_BUFFER_MAP_MODE_BUFFER) - return; - - m_uploadUsingStaging = true; - } - void PreLoad(); bool HasSequenceNumber() const { @@ -252,7 +238,6 @@ namespace dxvk { DxvkBufferSliceHandle m_sliceHandle; D3D9Range m_dirtyRange; - D3D9Range m_gpuReadingRange; uint32_t m_lockCount = 0; diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index e52ead2f1..a3c74eb4e 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -378,11 +378,6 @@ namespace dxvk { bool NeedsUpload(UINT Subresource) const { return m_needsUpload.get(Subresource); } bool NeedsAnyUpload() { return m_needsUpload.any(); } void ClearNeedsUpload() { return m_needsUpload.clearAll(); } - bool DoesStagingBufferUploads(UINT Subresource) const { return m_uploadUsingStaging.get(Subresource); } - - void EnableStagingBufferUploads(UINT Subresource) { - m_uploadUsingStaging.set(Subresource, true); - } void SetNeedsMipGen(bool value) { m_needsMipGen = value; } bool NeedsMipGen() const { return m_needsMipGen; } diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index e88b4ee9d..6f7a3ddee 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4142,10 +4142,6 @@ namespace dxvk { VkExtent3D levelExtent = pResource->GetExtentMip(MipLevel); VkExtent3D blockCount = util::computeBlockCount(levelExtent, formatInfo->blockSize); - const bool systemmem = desc.Pool == D3DPOOL_SYSTEMMEM; - const bool managed = IsPoolManaged(desc.Pool); - const bool scratch = desc.Pool == D3DPOOL_SCRATCH; - bool fullResource = pBox == nullptr; if (unlikely(!fullResource)) { VkOffset3D lockOffset; @@ -4187,7 +4183,7 @@ namespace dxvk { DxvkBufferSliceHandle physSlice; - if (Flags & D3DLOCK_DISCARD) { + if ((Flags & D3DLOCK_DISCARD) && needsReadback) { // We do not have to preserve the contents of the // buffer if the entire image gets discarded. physSlice = pResource->DiscardMapSlice(Subresource); @@ -4201,18 +4197,8 @@ namespace dxvk { } else { physSlice = pResource->GetMappedSlice(Subresource); - // We do not need to wait for the resource in the event the - // calling app promises not to overwrite data that is in use - // or is reading. Remember! This will only trigger for MANAGED resources - // that cannot get affected by GPU, therefore readonly is A-OK for NOT waiting. - const bool usesStagingBuffer = pResource->DoesStagingBufferUploads(Subresource); - const bool skipWait = (scratch || managed || systemmem) && !needsReadback - && (usesStagingBuffer || readOnly); - - if (alloced && !needsReadback) { - std::memset(physSlice.mapPtr, 0, physSlice.length); - } - else if (!skipWait) { + if (needsReadback) { + const Rc mappedBuffer = pResource->GetBuffer(Subresource); if (unlikely(needsReadback) && pResource->GetImage() != nullptr) { Rc resourceImage = pResource->GetImage(); @@ -4283,12 +4269,12 @@ namespace dxvk { } }); TrackTextureMappingBufferSequenceNumber(pResource, Subresource); - } else if (!(Flags & D3DLOCK_DONOTWAIT) && !WaitForResource(mappedBuffer, pResource->GetMappingBufferSequenceNumber(Subresource), D3DLOCK_DONOTWAIT)) { - pResource->EnableStagingBufferUploads(Subresource); } if (!WaitForResource(mappedBuffer, pResource->GetMappingBufferSequenceNumber(Subresource), Flags)) return D3DERR_WASSTILLDRAWING; + } else if (alloced) { + std::memset(physSlice.mapPtr, 0, physSlice.length); } } @@ -4324,7 +4310,7 @@ namespace dxvk { } } - if (managed && !readOnly) { + if (IsPoolManaged(desc.Pool) && !readOnly) { pResource->SetNeedsUpload(Subresource, true); for (uint32_t i : bit::BitMask(m_activeTextures)) { @@ -4475,38 +4461,25 @@ namespace dxvk { + srcOffsetBlockCount.y * pitch + srcOffsetBlockCount.x * formatInfo->elementSize; - VkDeviceSize sliceAlignment = 1; - VkDeviceSize rowAlignment = 1; - DxvkBufferSlice copySrcSlice; - if (pSrcTexture->DoesStagingBufferUploads(SrcSubresource)) { - VkDeviceSize dirtySize = extentBlockCount.width * extentBlockCount.height * extentBlockCount.depth * formatInfo->elementSize; - D3D9BufferSlice slice = AllocStagingBuffer(dirtySize); - copySrcSlice = slice.slice; - void* srcData = reinterpret_cast(srcSlice.mapPtr) + copySrcOffset; - util::packImageData( - slice.mapPtr, srcData, extentBlockCount, formatInfo->elementSize, - pitch, pitch * srcTexLevelExtentBlockCount.height); - } else { - copySrcSlice = DxvkBufferSlice(pSrcTexture->GetBuffer(SrcSubresource), copySrcOffset, srcSlice.length); - // row/slice alignment can act as the pitch parameter - rowAlignment = pitch; - sliceAlignment = srcTexLevelExtentBlockCount.height * pitch; - } + VkDeviceSize dirtySize = extentBlockCount.width * extentBlockCount.height * extentBlockCount.depth * formatInfo->elementSize; + D3D9BufferSlice slice = AllocStagingBuffer(dirtySize); + const void* srcData = reinterpret_cast(srcSlice.mapPtr) + copySrcOffset; + util::packImageData( + slice.mapPtr, srcData, extentBlockCount, formatInfo->elementSize, + pitch, pitch * srcTexLevelExtentBlockCount.height); EmitCs([ - cSrcSlice = std::move(copySrcSlice), + cSrcSlice = slice.slice, cDstImage = image, cDstLayers = dstLayers, cDstLevelExtent = alignedExtent, - cOffset = alignedDestOffset, - cRowAlignment = rowAlignment, - cSliceAlignment = sliceAlignment + cOffset = alignedDestOffset ] (DxvkContext* ctx) { ctx->copyBufferToImage( cDstImage, cDstLayers, cOffset, cDstLevelExtent, cSrcSlice.buffer(), cSrcSlice.offset(), - cRowAlignment, cSliceAlignment); + 1, 1); }); TrackTextureMappingBufferSequenceNumber(pSrcTexture, SrcSubresource); @@ -4607,11 +4580,14 @@ namespace dxvk { if ((desc.Pool == D3DPOOL_DEFAULT || !(Flags & D3DLOCK_NO_DIRTY_UPDATE)) && !(Flags & D3DLOCK_READONLY)) pResource->DirtyRange().Conjoin(lockRange); + const bool directMapping = pResource->GetMapMode() == D3D9_COMMON_BUFFER_MAP_MODE_DIRECT; + const bool needsReadback = pResource->NeedsReadback(); + Rc mappingBuffer = pResource->GetBuffer(); DxvkBufferSliceHandle physSlice; - if (Flags & D3DLOCK_DISCARD) { + if ((Flags & D3DLOCK_DISCARD) && (directMapping || needsReadback)) { // Allocate a new backing slice for the buffer and set // it as the 'new' mapped slice. This assumes that the // only way to invalidate a buffer is by mapping it. @@ -4625,7 +4601,6 @@ namespace dxvk { }); pResource->SetNeedsReadback(false); - pResource->GPUReadingRange().Clear(); } else { // Use map pointer from previous map operation. This @@ -4633,31 +4608,18 @@ namespace dxvk { // if the map mode is D3DLOCK_NOOVERWRITE. physSlice = pResource->GetMappedSlice(); - // NOOVERWRITE promises that they will not write in a currently used area. - // Therefore we can skip waiting for these two cases. - // We can also skip waiting if there is not dirty range overlap, if we are one of those resources. - - // If we are respecting the bounds ie. (MANAGED) we can test overlap - // of our bounds, otherwise we just ignore this and go for it all the time. const bool needsReadback = pResource->NeedsReadback(); const bool readOnly = Flags & D3DLOCK_READONLY; - const bool noOverlap = !pResource->GPUReadingRange().Overlaps(lockRange); + // NOOVERWRITE promises that they will not write in a currently used area. const bool noOverwrite = Flags & D3DLOCK_NOOVERWRITE; - const bool usesStagingBuffer = pResource->DoesStagingBufferUploads(); const bool directMapping = pResource->GetMapMode() == D3D9_COMMON_BUFFER_MAP_MODE_DIRECT; - const bool skipWait = (!needsReadback && (usesStagingBuffer || readOnly || (noOverlap && !directMapping))) || noOverwrite; + const bool skipWait = (!needsReadback && (readOnly || !directMapping)) || noOverwrite; if (!skipWait) { - if (unlikely(needsReadback)) { - Logger::warn("Buffer readback is unimplemented."); - // Remember to update the sequence number when implementing buffer readback. - } else if (!(Flags & D3DLOCK_DONOTWAIT) && !WaitForResource(mappingBuffer, pResource->GetMappingBufferSequenceNumber(), D3DLOCK_DONOTWAIT)) - pResource->EnableStagingBufferUploads(); - + const Rc mappingBuffer = pResource->GetBuffer(); if (!WaitForResource(mappingBuffer, pResource->GetMappingBufferSequenceNumber(), Flags)) return D3DERR_WASSTILLDRAWING; pResource->SetNeedsReadback(false); - pResource->GPUReadingRange().Clear(); } } @@ -4688,19 +4650,13 @@ namespace dxvk { D3D9Range& range = pResource->DirtyRange(); - DxvkBufferSlice copySrcSlice; - if (pResource->DoesStagingBufferUploads()) { - D3D9BufferSlice slice = AllocStagingBuffer(range.max - range.min); - copySrcSlice = slice.slice; - void* srcData = reinterpret_cast(srcSlice.mapPtr) + range.min; - memcpy(slice.mapPtr, srcData, range.max - range.min); - } else { - copySrcSlice = DxvkBufferSlice(pResource->GetBuffer(), range.min, range.max - range.min); - } + D3D9BufferSlice slice = AllocStagingBuffer(range.max - range.min); + void* srcData = reinterpret_cast(srcSlice.mapPtr) + range.min; + memcpy(slice.mapPtr, srcData, range.max - range.min); EmitCs([ cDstSlice = dstBuffer, - cSrcSlice = copySrcSlice, + cSrcSlice = slice.slice, cDstOffset = range.min, cLength = range.max - range.min ] (DxvkContext* ctx) { @@ -4712,7 +4668,6 @@ namespace dxvk { cLength); }); - pResource->GPUReadingRange().Conjoin(pResource->DirtyRange()); pResource->DirtyRange().Clear(); TrackBufferMappingBufferSequenceNumber(pResource); From 08ad6583ea223b70aa02498fbb7c9e44bbbab572 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Thu, 28 Jul 2022 15:40:36 +0200 Subject: [PATCH 0319/1348] [d3d9] Only set upload bit for managed textures Otherwise D3DPOOL_DEFAULT can hit the draw time late upload path. --- src/d3d9/d3d9_texture.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/d3d9/d3d9_texture.cpp b/src/d3d9/d3d9_texture.cpp index 4b2371eaf..811a6cd3a 100644 --- a/src/d3d9/d3d9_texture.cpp +++ b/src/d3d9/d3d9_texture.cpp @@ -87,7 +87,9 @@ namespace dxvk { // Some games keep using the pointer returned in LockRect() after calling Unlock() // and purely rely on AddDirtyRect to notify D3D9 that contents have changed. // We have no way of knowing which mip levels were actually changed. - m_texture.SetAllNeedUpload(); + if (m_texture.IsManaged()) + m_texture.SetAllNeedUpload(); + return D3D_OK; } @@ -169,7 +171,9 @@ namespace dxvk { // Some games keep using the pointer returned in LockBox() after calling Unlock() // and purely rely on AddDirtyBox to notify D3D9 that contents have changed. // We have no way of knowing which mip levels were actually changed. - m_texture.SetAllNeedUpload(); + if (m_texture.IsManaged()) + m_texture.SetAllNeedUpload(); + return D3D_OK; } @@ -257,9 +261,12 @@ namespace dxvk { // Some games keep using the pointer returned in LockRect() after calling Unlock() // and purely rely on AddDirtyRect to notify D3D9 that contents have changed. // We have no way of knowing which mip levels were actually changed. - for (uint32_t m = 0; m < m_texture.Desc()->MipLevels; m++) { - m_texture.SetNeedsUpload(m_texture.CalcSubresource(Face, m), true); + if (m_texture.IsManaged()) { + for (uint32_t m = 0; m < m_texture.Desc()->MipLevels; m++) { + m_texture.SetNeedsUpload(m_texture.CalcSubresource(Face, m), true); + } } + return D3D_OK; } From c3dbb6429f0fef00695c175cee0080bdd99352ab Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Thu, 2 Jun 2022 03:22:22 +0200 Subject: [PATCH 0320/1348] [d3d9] Implement memory allocator for memory mapped files --- src/d3d9/d3d9_device.cpp | 27 ++-- src/d3d9/d3d9_device.h | 7 + src/d3d9/d3d9_mem.cpp | 292 +++++++++++++++++++++++++++++++++++++++ src/d3d9/d3d9_mem.h | 160 +++++++++++++++++++++ src/d3d9/meson.build | 3 +- 5 files changed, 475 insertions(+), 14 deletions(-) create mode 100644 src/d3d9/d3d9_mem.cpp create mode 100644 src/d3d9/d3d9_mem.h diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 6f7a3ddee..4b9954181 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -39,19 +39,20 @@ namespace dxvk { HWND hFocusWindow, DWORD BehaviorFlags, Rc dxvkDevice) - : m_parent ( pParent ) - , m_deviceType ( DeviceType ) - , m_window ( hFocusWindow ) - , m_behaviorFlags ( BehaviorFlags ) - , m_adapter ( pAdapter ) - , m_dxvkDevice ( dxvkDevice ) - , m_shaderModules ( new D3D9ShaderModuleSet ) - , m_stagingBuffer ( dxvkDevice, StagingBufferSize ) - , m_d3d9Options ( dxvkDevice, pParent->GetInstance()->config() ) - , m_multithread ( BehaviorFlags & D3DCREATE_MULTITHREADED ) - , m_isSWVP ( (BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) ? true : false ) - , m_csThread ( dxvkDevice, dxvkDevice->createContext(DxvkContextType::Primary) ) - , m_csChunk ( AllocCsChunk() ) { + : m_parent ( pParent ) + , m_deviceType ( DeviceType ) + , m_window ( hFocusWindow ) + , m_behaviorFlags ( BehaviorFlags ) + , m_adapter ( pAdapter ) + , m_dxvkDevice ( dxvkDevice ) + , m_memoryAllocator ( ) + , m_shaderModules ( new D3D9ShaderModuleSet ) + , m_stagingBuffer ( dxvkDevice, StagingBufferSize ) + , m_d3d9Options ( dxvkDevice, pParent->GetInstance()->config() ) + , m_multithread ( BehaviorFlags & D3DCREATE_MULTITHREADED ) + , m_isSWVP ( (BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) ? true : false ) + , m_csThread ( dxvkDevice, dxvkDevice->createContext(DxvkContextType::Primary) ) + , m_csChunk ( AllocCsChunk() ) { // If we can SWVP, then we use an extended constant set // as SWVP has many more slots available than HWVP. bool canSWVP = CanSWVP(); diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 8090f1b55..2d1e3dcc8 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -11,6 +11,7 @@ #include "d3d9_adapter.h" #include "d3d9_constant_buffer.h" #include "d3d9_constant_set.h" +#include "d3d9_mem.h" #include "d3d9_state.h" @@ -929,6 +930,10 @@ namespace dxvk { return m_samplerCount.load(); } + D3D9MemoryAllocator* GetAllocator() { + return &m_memoryAllocator; + } + private: DxvkCsChunkRef AllocCsChunk() { @@ -1148,6 +1153,8 @@ namespace dxvk { D3D9Adapter* m_adapter; Rc m_dxvkDevice; + D3D9MemoryAllocator m_memoryAllocator; + uint32_t m_frameLatency = DefaultFrameLatency; D3D9Initializer* m_initializer = nullptr; diff --git a/src/d3d9/d3d9_mem.cpp b/src/d3d9/d3d9_mem.cpp new file mode 100644 index 000000000..c288fd3ac --- /dev/null +++ b/src/d3d9/d3d9_mem.cpp @@ -0,0 +1,292 @@ +#include "d3d9_mem.h" +#include "../util/util_string.h" +#include "../util/util_math.h" +#include "../util/log/log.h" +#include "../util/util_likely.h" +#include + +#ifdef D3D9_ALLOW_UNMAPPING +#include +#endif + +namespace dxvk { + +#ifdef D3D9_ALLOW_UNMAPPING + D3D9MemoryAllocator::D3D9MemoryAllocator() { + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + m_allocationGranularity = sysInfo.dwAllocationGranularity; + } + + D3D9Memory D3D9MemoryAllocator::Alloc(uint32_t Size) { + std::lock_guard lock(m_mutex); + + uint32_t alignedSize = align(Size, CACHE_LINE_SIZE); + for (auto& chunk : m_chunks) { + D3D9Memory memory = chunk->Alloc(alignedSize); + if (memory) { + m_usedMemory += memory.GetSize(); + return memory; + } + } + + uint32_t chunkSize = std::max(D3D9ChunkSize, alignedSize); + m_allocatedMemory += chunkSize; + + D3D9MemoryChunk* chunk = new D3D9MemoryChunk(this, chunkSize); + std::unique_ptr uniqueChunk(chunk); + D3D9Memory memory = uniqueChunk->Alloc(alignedSize); + m_usedMemory += memory.GetSize(); + + m_chunks.push_back(std::move(uniqueChunk)); + return memory; + } + + void D3D9MemoryAllocator::FreeChunk(D3D9MemoryChunk *Chunk) { + std::lock_guard lock(m_mutex); + + m_allocatedMemory -= Chunk->Size(); + + m_chunks.erase(std::remove_if(m_chunks.begin(), m_chunks.end(), [&](auto& item) { + return item.get() == Chunk; + }), m_chunks.end()); + } + + void D3D9MemoryAllocator::NotifyMapped(uint32_t Size) { + m_mappedMemory += Size; + } + + void D3D9MemoryAllocator::NotifyUnmapped(uint32_t Size) { + m_mappedMemory -= Size; + } + + void D3D9MemoryAllocator::NotifyFreed(uint32_t Size) { + m_usedMemory -= Size; + } + + uint32_t D3D9MemoryAllocator::MappedMemory() { + return m_mappedMemory.load(); + } + + uint32_t D3D9MemoryAllocator::UsedMemory() { + return m_usedMemory.load(); + } + + uint32_t D3D9MemoryAllocator::AllocatedMemory() { + return m_allocatedMemory.load(); + } + + D3D9MemoryChunk::D3D9MemoryChunk(D3D9MemoryAllocator* Allocator, uint32_t Size) + : m_allocator(Allocator), m_size(Size), m_mappingGranularity(m_allocator->MemoryGranularity() * 16) { + m_mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE | SEC_COMMIT, 0, Size, nullptr); + m_freeRanges.push_back({ 0, Size }); + m_mappingRanges.resize(((Size + m_mappingGranularity - 1) / m_mappingGranularity)); + } + + D3D9MemoryChunk::~D3D9MemoryChunk() { + std::lock_guard lock(m_mutex); + + CloseHandle(m_mapping); + } + + void* D3D9MemoryChunk::Map(D3D9Memory* memory) { + std::lock_guard lock(m_mutex); + + uint32_t alignedOffset = alignDown(memory->GetOffset(), m_mappingGranularity); + uint32_t alignmentDelta = memory->GetOffset() - alignedOffset; + uint32_t alignedSize = memory->GetSize() + alignmentDelta; + if (alignedSize > m_mappingGranularity) { + // The allocation crosses the boundary of the internal mapping page it's a part of + // so we map it on it's own. + alignedOffset = alignDown(memory->GetOffset(), m_allocator->MemoryGranularity()); + alignmentDelta = memory->GetOffset() - alignedOffset; + alignedSize = memory->GetSize() + alignmentDelta; + + m_allocator->NotifyMapped(alignedSize); + uint8_t* basePtr = static_cast(MapViewOfFile(m_mapping, FILE_MAP_ALL_ACCESS, 0, alignedOffset, alignedSize)); + if (unlikely(basePtr == nullptr)) { + DWORD error = GetLastError(); + Logger::err(str::format("Mapping non-persisted file failed: ", error, ", Mapped memory: ", m_allocator->MappedMemory())); + return nullptr; + } + return basePtr + alignmentDelta; + } + + // For small allocations we map the entire mapping page to minimize the overhead from having the align the offset to 65k bytes. + // This should hopefully also reduce the amount of MapViewOfFile calls we do for tiny allocations. + auto& mappingRange = m_mappingRanges[memory->GetOffset() / m_mappingGranularity]; + if (unlikely(mappingRange.refCount == 0)) { + m_allocator->NotifyMapped(m_mappingGranularity); + mappingRange.ptr = static_cast(MapViewOfFile(m_mapping, FILE_MAP_ALL_ACCESS, 0, alignedOffset, m_mappingGranularity)); + if (unlikely(mappingRange.ptr == nullptr)) { + DWORD error = GetLastError(); + LPTSTR buffer = nullptr; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), (LPTSTR)&buffer, 0, nullptr); + Logger::err(str::format("Mapping non-persisted file failed: ", error, ", Mapped memory: ", m_allocator->MappedMemory(), ", Msg: ", buffer)); + if (buffer) { + LocalFree(buffer); + } + } + } + mappingRange.refCount++; + uint8_t* basePtr = static_cast(mappingRange.ptr); + return basePtr + alignmentDelta; + } + + void D3D9MemoryChunk::Unmap(D3D9Memory* memory) { + std::lock_guard lock(m_mutex); + + uint32_t alignedOffset = alignDown(memory->GetOffset(), m_mappingGranularity); + uint32_t alignmentDelta = memory->GetOffset() - alignedOffset; + uint32_t alignedSize = memory->GetSize() + alignmentDelta; + if (alignedSize > m_mappingGranularity) { + // Single use mapping + alignedOffset = alignDown(memory->GetOffset(), m_allocator->MemoryGranularity()); + alignmentDelta = memory->GetOffset() - alignedOffset; + alignedSize = memory->GetSize() + alignmentDelta; + + uint8_t* basePtr = static_cast(memory->Ptr()) - alignmentDelta; + UnmapViewOfFile(basePtr); + m_allocator->NotifyUnmapped(alignedSize); + return; + } + auto& mappingRange = m_mappingRanges[memory->GetOffset() / m_mappingGranularity]; + mappingRange.refCount--; + if (unlikely(mappingRange.refCount == 0)) { + UnmapViewOfFile(mappingRange.ptr); + mappingRange.ptr = nullptr; + m_allocator->NotifyUnmapped(m_mappingGranularity); + } + } + + D3D9Memory D3D9MemoryChunk::Alloc(uint32_t Size) { + std::lock_guard lock(m_mutex); + + uint32_t offset = 0; + uint32_t size = 0; + + for (auto range = m_freeRanges.begin(); range != m_freeRanges.end(); range++) { + if (range->length >= Size) { + offset = range->offset; + size = Size; + range->offset += Size; + range->length -= Size; + if (range->length < (4 << 10)) { + size += range->length; + m_freeRanges.erase(range); + } + break; + } + } + + if (size != 0) + return D3D9Memory(this, offset, Size); + + return {}; + } + + void D3D9MemoryChunk::Free(D3D9Memory *Memory) { + std::lock_guard lock(m_mutex); + + uint32_t offset = Memory->GetOffset(); + uint32_t size = Memory->GetSize(); + + auto curr = m_freeRanges.begin(); + + // shamelessly stolen from dxvk_memory.cpp + while (curr != m_freeRanges.end()) { + if (curr->offset == offset + size) { + size += curr->length; + curr = m_freeRanges.erase(curr); + } else if (curr->offset + curr->length == offset) { + offset -= curr->length; + size += curr->length; + curr = m_freeRanges.erase(curr); + } else { + curr++; + } + } + + m_freeRanges.push_back({ offset, size }); + m_allocator->NotifyFreed(Memory->GetSize()); + } + + bool D3D9MemoryChunk::IsEmpty() { + std::lock_guard lock(m_mutex); + + return m_freeRanges.size() == 1 + && m_freeRanges[0].length == m_size; + } + + D3D9MemoryAllocator* D3D9MemoryChunk::Allocator() const { + return m_allocator; + } + + HANDLE D3D9MemoryChunk::FileHandle() const { + return m_mapping; + } + + + D3D9Memory::D3D9Memory(D3D9MemoryChunk* Chunk, size_t Offset, size_t Size) + : m_chunk(Chunk), m_offset(Offset), m_size(Size) {} + + D3D9Memory::D3D9Memory(D3D9Memory&& other) + : m_chunk(std::exchange(other.m_chunk, nullptr)), + m_ptr(std::exchange(other.m_ptr, nullptr)), + m_offset(std::exchange(other.m_offset, 0)), + m_size(std::exchange(other.m_size, 0)) {} + + D3D9Memory::~D3D9Memory() { + this->Free(); + } + + D3D9Memory& D3D9Memory::operator = (D3D9Memory&& other) { + this->Free(); + + m_chunk = std::exchange(other.m_chunk, nullptr); + m_ptr = std::exchange(other.m_ptr, nullptr); + m_offset = std::exchange(other.m_offset, 0); + m_size = std::exchange(other.m_size, 0); + return *this; + } + + void D3D9Memory::Free() { + if (unlikely(m_chunk == nullptr)) + return; + + if (m_ptr != nullptr) + Unmap(); + + m_chunk->Free(this); + if (m_chunk->IsEmpty()) { + D3D9MemoryAllocator* allocator = m_chunk->Allocator(); + allocator->FreeChunk(m_chunk); + } + m_chunk = nullptr; + } + + void D3D9Memory::Map() { + if (unlikely(m_ptr != nullptr)) + return; + + if (unlikely(m_chunk == nullptr)) + return; + + m_ptr = m_chunk->Map(this); + } + + void D3D9Memory::Unmap() { + if (unlikely(m_ptr == nullptr)) + return; + + m_chunk->Unmap(this); + m_ptr = nullptr; + } + + void* D3D9Memory::Ptr() { + return m_ptr; + } + +#endif + +} diff --git a/src/d3d9/d3d9_mem.h b/src/d3d9/d3d9_mem.h new file mode 100644 index 000000000..f2ffde0a6 --- /dev/null +++ b/src/d3d9/d3d9_mem.h @@ -0,0 +1,160 @@ + +#pragma once + +#include "../util/thread.h" + +#if defined(_WIN32) && !defined(_WIN64) + #define D3D9_ALLOW_UNMAPPING +#endif + +#ifdef D3D9_ALLOW_UNMAPPING + #define WIN32_LEAN_AND_MEAN + #include +#endif + +namespace dxvk { + + class D3D9MemoryAllocator; + class D3D9Memory; + +#ifdef D3D9_ALLOW_UNMAPPING + + class D3D9MemoryChunk; + + constexpr uint32_t D3D9ChunkSize = 64 << 20; + + struct D3D9MemoryRange { + uint32_t offset; + uint32_t length; + }; + + struct D3D9MappingRange { + uint32_t refCount = 0; + void* ptr = nullptr; + }; + + class D3D9MemoryChunk { + friend D3D9MemoryAllocator; + + public: + ~D3D9MemoryChunk(); + + D3D9MemoryChunk (const D3D9MemoryChunk&) = delete; + D3D9MemoryChunk& operator = (const D3D9MemoryChunk&) = delete; + + D3D9MemoryChunk (D3D9MemoryChunk&& other) = delete; + D3D9MemoryChunk& operator = (D3D9MemoryChunk&& other) = delete; + +#ifdef D3D9_MEM_MAP_CHUNKS + void IncMapCounter(); + void DecMapCounter(); + void* Ptr() const { return m_ptr; } +#endif + D3D9Memory Alloc(uint32_t Size); + void Free(D3D9Memory* Memory); + bool IsEmpty(); + uint32_t Size() const { return m_size; } + D3D9MemoryAllocator* Allocator() const; + HANDLE FileHandle() const; + void* Map(D3D9Memory* memory); + void Unmap(D3D9Memory* memory); + + private: + D3D9MemoryChunk(D3D9MemoryAllocator* Allocator, uint32_t Size); + + dxvk::mutex m_mutex; + D3D9MemoryAllocator* m_allocator; + HANDLE m_mapping; + uint32_t m_size; + uint32_t m_mappingGranularity; + std::vector m_freeRanges; + std::vector m_mappingRanges; + +#ifdef D3D9_MEM_MAP_CHUNKS + uint32_t m_mapCounter = 0; + void* m_ptr; +#endif + }; + + class D3D9Memory { + friend D3D9MemoryChunk; + + public: + D3D9Memory() {} + ~D3D9Memory(); + + D3D9Memory (const D3D9Memory&) = delete; + D3D9Memory& operator = (const D3D9Memory&) = delete; + + D3D9Memory (D3D9Memory&& other); + D3D9Memory& operator = (D3D9Memory&& other); + + operator bool() const { return m_chunk != nullptr; } + + void Map(); + void Unmap(); + void* Ptr(); + D3D9MemoryChunk* GetChunk() const { return m_chunk; } + size_t GetOffset() const { return m_offset; } + size_t GetSize() const { return m_size; } + + private: + D3D9Memory(D3D9MemoryChunk* Chunk, size_t Offset, size_t Size); + void Free(); + + D3D9MemoryChunk* m_chunk = nullptr; + void* m_ptr = nullptr; + size_t m_offset = 0; + size_t m_size = 0; + }; + + class D3D9MemoryAllocator { + friend D3D9MemoryChunk; + + public: + D3D9MemoryAllocator(); + ~D3D9MemoryAllocator() = default; + D3D9Memory Alloc(uint32_t Size); + void FreeChunk(D3D9MemoryChunk* Chunk); + void NotifyMapped(uint32_t Size); + void NotifyUnmapped(uint32_t Size); + void NotifyFreed(uint32_t Size); + uint32_t MappedMemory(); + uint32_t UsedMemory(); + uint32_t AllocatedMemory(); + uint32_t MemoryGranularity() { return m_allocationGranularity; } + + private: + dxvk::mutex m_mutex; + std::vector> m_chunks; + std::atomic m_mappedMemory = 0; + std::atomic m_allocatedMemory = 0; + std::atomic m_usedMemory = 0; + uint32_t m_allocationGranularity; + }; + +#else + class D3D9Memory { + public: + operator bool() const { return false; } + + void Map() {} + void Unmap() {} + void* Ptr() { return nullptr; } + + private: + void Free(); + }; + + class D3D9MemoryAllocator { + + public: + D3D9Memory Alloc(uint32_t Size) { return { }; } + uint32_t MappedMemory() { return 0; } + uint32_t UsedMemory() { return 0; } + uint32_t AllocatedMemory() { return 0; } + }; + +#endif + +} diff --git a/src/d3d9/meson.build b/src/d3d9/meson.build index 476525cc4..2641f58ee 100644 --- a/src/d3d9/meson.build +++ b/src/d3d9/meson.build @@ -40,7 +40,8 @@ d3d9_src = [ 'd3d9_swvp_emu.cpp', 'd3d9_format_helpers.cpp', 'd3d9_hud.cpp', - 'd3d9_annotation.cpp' + 'd3d9_annotation.cpp', + 'd3d9_mem.cpp' ] d3d9_dll = shared_library('d3d9'+dll_ext, d3d9_src, glsl_generator.process(d3d9_shaders), d3d9_res, From d598fd3156623226f68f314e5e7c04d8fd330d8e Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Fri, 11 Mar 2022 14:10:27 +0100 Subject: [PATCH 0321/1348] [d3d9] Add HUD item for unmappable memory --- src/d3d9/d3d9_hud.cpp | 59 +++++++++++++++++++++++++++++++++++++ src/d3d9/d3d9_hud.h | 34 ++++++++++++++++++++- src/d3d9/d3d9_swapchain.cpp | 4 +++ 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_hud.cpp b/src/d3d9/d3d9_hud.cpp index e37a5a0e3..b9ab5f433 100644 --- a/src/d3d9/d3d9_hud.cpp +++ b/src/d3d9/d3d9_hud.cpp @@ -33,4 +33,63 @@ namespace dxvk::hud { return position; } + HudTextureMemory::HudTextureMemory(D3D9DeviceEx* device) + : m_device (device) + , m_allocatedString ("") + , m_mappedString ("") {} + + + void HudTextureMemory::update(dxvk::high_resolution_clock::time_point time) { + D3D9MemoryAllocator* allocator = m_device->GetAllocator(); + + m_maxAllocated = std::max(m_maxAllocated, allocator->AllocatedMemory()); + m_maxUsed = std::max(m_maxUsed, allocator->UsedMemory()); + m_maxMapped = std::max(m_maxMapped, allocator->MappedMemory()); + + auto elapsed = std::chrono::duration_cast(time - m_lastUpdate); + + if (elapsed.count() < UpdateInterval) + return; + + m_allocatedString = str::format(m_maxAllocated >> 20, " MB (Used: ", m_maxUsed >> 20, " MB)"); + m_mappedString = str::format(m_maxMapped >> 20, " MB"); + m_maxAllocated = 0; + m_maxUsed = 0; + m_maxMapped = 0; + m_lastUpdate = time; + } + + + HudPos HudTextureMemory::render( + HudRenderer& renderer, + HudPos position) { + position.y += 16.0f; + + renderer.drawText(16.0f, + { position.x, position.y }, + { 0.0f, 1.0f, 0.75f, 1.0f }, + "Mappable:"); + + renderer.drawText(16.0f, + { position.x + 120.0f, position.y }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + m_allocatedString); + + position.y += 24.0f; + + renderer.drawText(16.0f, + { position.x, position.y }, + { 0.0f, 1.0f, 0.75f, 1.0f }, + "Mapped:"); + + renderer.drawText(16.0f, + { position.x + 120.0f, position.y }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + m_mappedString); + + position.y += 8.0f; + + return position; + } + } \ No newline at end of file diff --git a/src/d3d9/d3d9_hud.h b/src/d3d9/d3d9_hud.h index b500e48b6..b0060ef36 100644 --- a/src/d3d9/d3d9_hud.h +++ b/src/d3d9/d3d9_hud.h @@ -6,7 +6,7 @@ namespace dxvk::hud { /** - * \brief HUD item to display DXVK version + * \brief HUD item to display sampler count */ class HudSamplerCount : public HudItem { @@ -28,4 +28,36 @@ namespace dxvk::hud { }; + /** + * \brief HUD item to display unmappable memory + */ + class HudTextureMemory : public HudItem { + constexpr static int64_t UpdateInterval = 500'000; + + public: + + HudTextureMemory(D3D9DeviceEx* device); + + void update(dxvk::high_resolution_clock::time_point time); + + HudPos render( + HudRenderer& renderer, + HudPos position); + + private: + + D3D9DeviceEx* m_device; + + uint32_t m_maxAllocated = 0; + uint32_t m_maxUsed = 0; + uint32_t m_maxMapped = 0; + + dxvk::high_resolution_clock::time_point m_lastUpdate + = dxvk::high_resolution_clock::now(); + + std::string m_allocatedString; + std::string m_mappedString; + + }; + } \ No newline at end of file diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 41a373ef2..fd063c22f 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -1081,6 +1081,10 @@ namespace dxvk { if (m_hud != nullptr) { m_hud->addItem("api", 1, GetApiName()); m_hud->addItem("samplers", -1, m_parent); + +#ifdef D3D9_ALLOW_UNMAPPING + m_hud->addItem("memory", -1, m_parent); +#endif } } From 6ca6554452543cca14daf017437c5b7b3e848909 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Wed, 16 Mar 2022 02:28:22 +0100 Subject: [PATCH 0322/1348] [d3d9] Use memory mapped files for textures --- src/d3d9/d3d9_common_texture.cpp | 59 ++++++++++++++++++--- src/d3d9/d3d9_common_texture.h | 88 +++++++++++++++++++------------- src/d3d9/d3d9_device.cpp | 45 ++++++++-------- src/d3d9/d3d9_initializer.cpp | 21 +++++--- src/d3d9/d3d9_swapchain.cpp | 5 +- 5 files changed, 146 insertions(+), 72 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index ef93e9473..b14ff99ff 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -40,7 +40,8 @@ namespace dxvk { m_shadow = DetermineShadowState(); m_supportsFetch4 = DetermineFetch4Compatibility(); - if (m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED) { + const bool createImage = m_desc.Pool != D3DPOOL_SYSTEMMEM && m_desc.Pool != D3DPOOL_SCRATCH && m_desc.Format != D3D9Format::NULL_FORMAT; + if (createImage) { bool plainSurface = m_type == D3DRTYPE_SURFACE && !(m_desc.Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)); @@ -73,7 +74,9 @@ namespace dxvk { } } - if (m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM) + if (m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE) + AllocData(); + else if (m_mapMode != D3D9_COMMON_TEXTURE_MAP_MODE_NONE && m_desc.Pool != D3DPOOL_DEFAULT) CreateBuffers(); m_exposedMipLevels = m_desc.MipLevels; @@ -165,11 +168,16 @@ namespace dxvk { return D3D_OK; } + void* D3D9CommonTexture::GetData(UINT Subresource) { + if (unlikely(m_mappedSlices[Subresource].mapPtr != nullptr || m_mapMode != D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE)) + return m_mappedSlices[Subresource].mapPtr; - bool D3D9CommonTexture::CreateBufferSubresource(UINT Subresource) { - if (m_buffers[Subresource] != nullptr) - return false; + D3D9Memory& memory = m_data[Subresource]; + memory.Map(); + return memory.Ptr(); + } + void D3D9CommonTexture::CreateBufferSubresource(UINT Subresource) { DxvkBufferCreateInfo info; info.size = GetMipSize(Subresource); info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT @@ -190,8 +198,6 @@ namespace dxvk { m_buffers[Subresource] = m_device->GetDXVKDevice()->createBuffer(info, memType); m_mappedSlices[Subresource] = m_buffers[Subresource]->getSliceHandle(); - - return true; } @@ -477,6 +483,20 @@ namespace dxvk { return VK_IMAGE_LAYOUT_GENERAL; } + D3D9_COMMON_TEXTURE_MAP_MODE D3D9CommonTexture::DetermineMapMode() const { + if (m_desc.Format == D3D9Format::NULL_FORMAT) + return D3D9_COMMON_TEXTURE_MAP_MODE_NONE; + +#ifdef D3D9_ALLOW_UNMAPPING + if (m_desc.Pool != D3DPOOL_DEFAULT) + return D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE; +#endif + + if (m_desc.Pool == D3DPOOL_SYSTEMMEM || m_desc.Pool == D3DPOOL_SCRATCH) + return D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM; + + return D3D9_COMMON_TEXTURE_MAP_MODE_BACKED; + } void D3D9CommonTexture::ExportImageInfo() { /* From MSDN: @@ -606,5 +626,30 @@ namespace dxvk { m_sampleView.Srgb = CreateView(AllLayers, Lod, VK_IMAGE_USAGE_SAMPLED_BIT, true); } + void D3D9CommonTexture::AllocData() { + // D3D9Initializer will handle clearing the data + const uint32_t count = CountSubresources(); + for (uint32_t i = 0; i < count; i++) { + m_data[i] = m_device->GetAllocator()->Alloc(GetMipSize(i)); + } + } + + const Rc& D3D9CommonTexture::GetBuffer(UINT Subresource, bool Initialize) { + if (unlikely(m_buffers[Subresource] == nullptr)) { + CreateBufferSubresource(Subresource); + + if (Initialize) { + if (m_data[Subresource]) { + m_data[Subresource].Map(); + memcpy(m_mappedSlices[Subresource].mapPtr, m_data[Subresource].Ptr(), GetMipSize(Subresource)); + } else { + memset(m_mappedSlices[Subresource].mapPtr, 0, GetMipSize(Subresource)); + } + } + m_data[Subresource] = {}; + } + + return m_buffers[Subresource]; + } } diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index a3c74eb4e..c29a9243c 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -3,6 +3,7 @@ #include "d3d9_format.h" #include "d3d9_util.h" #include "d3d9_caps.h" +#include "d3d9_mem.h" #include "../dxvk/dxvk_device.h" @@ -22,6 +23,7 @@ namespace dxvk { D3D9_COMMON_TEXTURE_MAP_MODE_NONE, ///< No mapping available D3D9_COMMON_TEXTURE_MAP_MODE_BACKED, ///< Mapped image through buffer D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM, ///< Only a buffer - no image + D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE, ///< Non-Vulkan memory that can be unmapped }; /** @@ -141,9 +143,17 @@ namespace dxvk { return m_resolveImage; } - const Rc& GetBuffer(UINT Subresource) { - return m_buffers[Subresource]; - } + /** + * \brief Returns a pointer to the internal data used for LockRect/LockBox + * + * This works regardless of the map mode used by this texture + * and will map the memory if necessary. + * \param [in] Subresource Subresource index + * @return Pointer to locking data + */ + void* GetData(UINT Subresource); + + const Rc& GetBuffer(UINT Subresource, bool Initialize); DxvkBufferSliceHandle GetMappedSlice(UINT Subresource) { @@ -215,24 +225,16 @@ namespace dxvk { return Face * m_desc.MipLevels + MipLevel; } - /** - * \brief Creates buffers - * Creates mapping and staging buffers for all subresources - * allocates new buffers if necessary - */ - void CreateBuffers() { - const uint32_t count = CountSubresources(); - for (uint32_t i = 0; i < count; i++) - CreateBufferSubresource(i); + void UnmapData(UINT Subresource) { + m_data[Subresource].Unmap(); } - /** - * \brief Creates a buffer - * Creates mapping and staging buffers for a given subresource - * allocates new buffers if necessary - * \returns Whether an allocation happened - */ - bool CreateBufferSubresource(UINT Subresource); + void UnmapData() { + const uint32_t subresources = CountSubresources(); + for (uint32_t i = 0; i < subresources; i++) { + m_data[i].Unmap(); + } + } /** * \brief Destroys a buffer @@ -456,6 +458,12 @@ namespace dxvk { : 0ull; } + /** + * \brief Mip level + * \returns Size of packed mip level in bytes + */ + VkDeviceSize GetMipSize(UINT Subresource) const; + private: D3D9DeviceEx* m_device; @@ -468,7 +476,9 @@ namespace dxvk { D3D9SubresourceArray< Rc> m_buffers; D3D9SubresourceArray< - DxvkBufferSliceHandle> m_mappedSlices; + DxvkBufferSliceHandle> m_mappedSlices = { }; + D3D9SubresourceArray< + D3D9Memory> m_data = { }; D3D9SubresourceArray< uint64_t> m_seqs = { }; @@ -503,12 +513,6 @@ namespace dxvk { std::array m_dirtyBoxes; - /** - * \brief Mip level - * \returns Size of packed mip level in bytes - */ - VkDeviceSize GetMipSize(UINT Subresource) const; - Rc CreatePrimaryImage(D3DRESOURCETYPE ResourceType, bool TryOffscreenRT, HANDLE* pSharedHandle) const; Rc CreateResolveImage() const; @@ -525,15 +529,7 @@ namespace dxvk { VkFormat Format, VkImageTiling Tiling) const; - D3D9_COMMON_TEXTURE_MAP_MODE DetermineMapMode() const { - if (m_desc.Format == D3D9Format::NULL_FORMAT) - return D3D9_COMMON_TEXTURE_MAP_MODE_NONE; - - if (m_desc.Pool == D3DPOOL_SYSTEMMEM || m_desc.Pool == D3DPOOL_SCRATCH) - return D3D9_COMMON_TEXTURE_MAP_MODE_SYSTEMMEM; - - return D3D9_COMMON_TEXTURE_MAP_MODE_BACKED; - } + D3D9_COMMON_TEXTURE_MAP_MODE DetermineMapMode() const; VkImageLayout OptimizeLayout( VkImageUsageFlags Usage) const; @@ -544,6 +540,28 @@ namespace dxvk { D3DRESOURCETYPE Dimension, UINT Layer); + /** + * \brief Creates a buffer + * Creates mapping and staging buffers for a given subresource + * allocates new buffers if necessary + * \returns Whether an allocation happened + */ + void CreateBufferSubresource(UINT Subresource); + + /** + * \brief Creates buffers + * Creates mapping and staging buffers for all subresources + * allocates new buffers if necessary + */ + void CreateBuffers() { + // D3D9Initializer will handle clearing the buffers + const uint32_t count = CountSubresources(); + for (uint32_t i = 0; i < count; i++) + CreateBufferSubresource(i); + } + + void AllocData(); + static constexpr UINT AllLayers = UINT32_MAX; }; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 4b9954181..fbc4c64b2 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -876,7 +876,10 @@ namespace dxvk { if (dstTexInfo->Desc()->Pool == D3DPOOL_DEFAULT) return this->StretchRect(pRenderTarget, nullptr, pDestSurface, nullptr, D3DTEXF_NONE); - Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource()); + VkExtent3D dstTexExtent = dstTexInfo->GetExtentMip(dst->GetMipLevel()); + VkExtent3D srcTexExtent = srcTexInfo->GetExtentMip(src->GetMipLevel()); + + Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height); Rc srcImage = srcTexInfo->GetImage(); const DxvkFormatInfo* srcFormatInfo = lookupFormatInfo(srcImage->info().format); @@ -887,9 +890,8 @@ namespace dxvk { srcSubresource.mipLevel, srcSubresource.arrayLayer, 1 }; - VkExtent3D srcExtent = srcTexInfo->GetExtentMip(src->GetMipLevel()); - VkExtent3D texLevelExtentBlockCount = util::computeBlockCount(srcExtent, srcFormatInfo->blockSize); + VkExtent3D texLevelExtentBlockCount = util::computeBlockCount(srcTexExtent, srcFormatInfo->blockSize); VkDeviceSize pitch = align(texLevelExtentBlockCount.width * uint32_t(srcFormatInfo->elementSize), 4); uint32_t pitchBlocks = uint32_t(pitch / srcFormatInfo->elementSize); VkExtent2D dstExtent = VkExtent2D{ pitchBlocks, @@ -899,7 +901,7 @@ namespace dxvk { cBuffer = dstBuffer, cImage = srcImage, cSubresources = srcSubresourceLayers, - cLevelExtent = srcExtent, + cLevelExtent = srcTexExtent, cDstExtent = dstExtent ] (DxvkContext* ctx) { ctx->copyImageToBuffer(cBuffer, 0, 4, 0, @@ -4128,10 +4130,6 @@ namespace dxvk { auto& desc = *(pResource->Desc()); - bool alloced = pResource->CreateBufferSubresource(Subresource); - - const Rc mappedBuffer = pResource->GetBuffer(Subresource); - auto& formatMapping = pResource->GetFormatMapping(); const DxvkFormatInfo* formatInfo = formatMapping.IsValid() @@ -4182,12 +4180,14 @@ namespace dxvk { bool needsReadback = pResource->NeedsReachback(Subresource) || renderable; pResource->SetNeedsReadback(Subresource, false); - DxvkBufferSliceHandle physSlice; + void* mapPtr; if ((Flags & D3DLOCK_DISCARD) && needsReadback) { // We do not have to preserve the contents of the // buffer if the entire image gets discarded. - physSlice = pResource->DiscardMapSlice(Subresource); + const Rc mappedBuffer = pResource->GetBuffer(Subresource, false); + DxvkBufferSliceHandle physSlice = pResource->DiscardMapSlice(Subresource); + mapPtr = physSlice.mapPtr; EmitCs([ cImageBuffer = std::move(mappedBuffer), @@ -4196,10 +4196,15 @@ namespace dxvk { ctx->invalidateBuffer(cImageBuffer, cBufferSlice); }); } else { - physSlice = pResource->GetMappedSlice(Subresource); + if (unlikely(pResource->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED)) { + // Create mapping buffer if it doesn't exist yet. (POOL_DEFAULT) + pResource->GetBuffer(Subresource, !needsReadback); + } + + mapPtr = pResource->GetData(Subresource); if (needsReadback) { - const Rc mappedBuffer = pResource->GetBuffer(Subresource); + const Rc mappedBuffer = pResource->GetBuffer(Subresource, false); if (unlikely(needsReadback) && pResource->GetImage() != nullptr) { Rc resourceImage = pResource->GetImage(); @@ -4274,8 +4279,6 @@ namespace dxvk { if (!WaitForResource(mappedBuffer, pResource->GetMappingBufferSequenceNumber(Subresource), Flags)) return D3DERR_WASSTILLDRAWING; - } else if (alloced) { - std::memset(physSlice.mapPtr, 0, physSlice.length); } } @@ -4332,8 +4335,7 @@ namespace dxvk { (!atiHack) ? formatInfo : nullptr, pBox); - - uint8_t* data = reinterpret_cast(physSlice.mapPtr); + uint8_t* data = reinterpret_cast(mapPtr); data += offset; pLockedBox->pBits = data; return D3D_OK; @@ -4419,7 +4421,6 @@ namespace dxvk { // Now that data has been written into the buffer, // we need to copy its contents into the image - const DxvkBufferSliceHandle srcSlice = pSrcTexture->GetMappedSlice(SrcSubresource); auto formatInfo = lookupFormatInfo(image->info().format); auto srcSubresource = pSrcTexture->GetSubresourceFromIndex( @@ -4462,9 +4463,10 @@ namespace dxvk { + srcOffsetBlockCount.y * pitch + srcOffsetBlockCount.x * formatInfo->elementSize; + const void* mapPtr = pSrcTexture->GetData(SrcSubresource); VkDeviceSize dirtySize = extentBlockCount.width * extentBlockCount.height * extentBlockCount.depth * formatInfo->elementSize; D3D9BufferSlice slice = AllocStagingBuffer(dirtySize); - const void* srcData = reinterpret_cast(srcSlice.mapPtr) + copySrcOffset; + const void* srcData = reinterpret_cast(mapPtr) + copySrcOffset; util::packImageData( slice.mapPtr, srcData, extentBlockCount, formatInfo->elementSize, pitch, pitch * srcTexLevelExtentBlockCount.height); @@ -4487,6 +4489,7 @@ namespace dxvk { } else { const DxvkFormatInfo* formatInfo = lookupFormatInfo(pDestTexture->GetFormatMapping().FormatColor); + const void* mapPtr = pSrcTexture->GetData(SrcSubresource); // Add more blocks for the other planes that we might have. // TODO: PLEASE CLEAN ME @@ -4504,11 +4507,11 @@ namespace dxvk { } // the converter can not handle the 4 aligned pitch so we always repack into a staging buffer - D3D9BufferSlice slice = AllocStagingBuffer(srcSlice.length); + D3D9BufferSlice slice = AllocStagingBuffer(pSrcTexture->GetMipSize(SrcSubresource)); VkDeviceSize pitch = align(srcTexLevelExtentBlockCount.width * formatInfo->elementSize, 4); util::packImageData( - slice.mapPtr, srcSlice.mapPtr, srcTexLevelExtentBlockCount, formatInfo->elementSize, + slice.mapPtr, mapPtr, srcTexLevelExtentBlockCount, formatInfo->elementSize, pitch, std::min(convertFormat.PlaneCount, 2u) * pitch * srcTexLevelExtentBlockCount.height); Flush(); @@ -5214,7 +5217,7 @@ namespace dxvk { void D3D9DeviceEx::UploadManagedTexture(D3D9CommonTexture* pResource) { for (uint32_t subresource = 0; subresource < pResource->CountSubresources(); subresource++) { - if (!pResource->NeedsUpload(subresource) || pResource->GetBuffer(subresource) == nullptr) + if (!pResource->NeedsUpload(subresource)) continue; this->FlushImage(pResource, subresource); diff --git a/src/d3d9/d3d9_initializer.cpp b/src/d3d9/d3d9_initializer.cpp index 2695bdaf5..d9a2eceac 100644 --- a/src/d3d9/d3d9_initializer.cpp +++ b/src/d3d9/d3d9_initializer.cpp @@ -40,13 +40,15 @@ namespace dxvk { void D3D9Initializer::InitTexture( D3D9CommonTexture* pTexture, - void* pInitialData) { + void* pInitialData) { if (pTexture->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_NONE) return; - (pTexture->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED) - ? InitDeviceLocalTexture(pTexture) - : InitHostVisibleTexture(pTexture, pInitialData); + if (pTexture->GetImage() != nullptr) + InitDeviceLocalTexture(pTexture); + + if (pTexture->Desc()->Pool != D3DPOOL_DEFAULT) + InitHostVisibleTexture(pTexture, pInitialData); } @@ -115,7 +117,8 @@ namespace dxvk { for (uint32_t a = 0; a < desc->ArraySize; a++) { for (uint32_t m = 0; m < desc->MipLevels; m++) { uint32_t subresource = pTexture->CalcSubresource(a, m); - DxvkBufferSliceHandle mapSlice = pTexture->GetBuffer(subresource)->getSliceHandle(); + void* mapPtr = pTexture->GetData(subresource); + uint32_t length = pTexture->GetMipSize(subresource); if (pInitialData != nullptr) { VkExtent3D mipExtent = pTexture->GetExtentMip(m); @@ -125,7 +128,7 @@ namespace dxvk { uint32_t alignedPitch = align(pitch, 4); util::packImageData( - mapSlice.mapPtr, + mapPtr, pInitialData, pitch, pitch * blockCount.height, @@ -138,11 +141,13 @@ namespace dxvk { VK_IMAGE_ASPECT_COLOR_BIT); } else { std::memset( - mapSlice.mapPtr, 0, - mapSlice.length); + mapPtr, 0, + length); } } } + if (pTexture->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE) + pTexture->UnmapData(); } diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index fd063c22f..0caa562d8 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -341,7 +341,10 @@ namespace dxvk { if (unlikely(dstTexInfo->Desc()->Pool != D3DPOOL_SYSTEMMEM && dstTexInfo->Desc()->Pool != D3DPOOL_SCRATCH)) return D3DERR_INVALIDCALL; - Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource()); + VkExtent3D dstTexExtent = dstTexInfo->GetExtentMip(dst->GetMipLevel()); + VkExtent3D srcTexExtent = srcTexInfo->GetExtentMip(0); + + Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height); Rc srcImage = srcTexInfo->GetImage(); if (srcImage->info().sampleCount != VK_SAMPLE_COUNT_1_BIT) { From b4f432f1de2b75647a30911792f727da619a88f8 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Wed, 6 Jul 2022 18:10:09 +0200 Subject: [PATCH 0323/1348] [util] Implement LRU list --- src/util/util_lru.h | 69 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/util/util_lru.h diff --git a/src/util/util_lru.h b/src/util/util_lru.h new file mode 100644 index 000000000..96076cc4a --- /dev/null +++ b/src/util/util_lru.h @@ -0,0 +1,69 @@ +#include +#include +#include + +namespace dxvk { + + template + class lru_list { + + public: + typedef typename std::list::const_iterator const_iterator; + + void insert(T value) { + auto cacheIter = m_cache.find(value); + if (cacheIter != m_cache.end()) + m_list.erase(cacheIter->second); + + m_list.push_back(value); + auto iter = m_list.cend(); + iter--; + m_cache[value] = iter; + } + + void remove(const T& value) { + auto cacheIter = m_cache.find(value); + if (cacheIter == m_cache.end()) + return; + + m_list.erase(cacheIter->second); + m_cache.erase(cacheIter); + } + + const_iterator remove(const_iterator iter) { + auto cacheIter = m_cache.find(*iter); + m_cache.erase(cacheIter); + return m_list.erase(iter); + } + + void touch(const T& value) { + auto cacheIter = m_cache.find(value); + if (cacheIter == m_cache.end()) + return; + + m_list.erase(cacheIter->second); + m_list.push_back(value); + auto iter = m_list.cend(); + --iter; + m_cache[value] = iter; + } + + const_iterator leastRecentlyUsedIter() const { + return m_list.cbegin(); + } + + const_iterator leastRecentlyUsedEndIter() const { + return m_list.cend(); + } + + uint32_t size() const noexcept { + return m_list.size(); + } + + private: + std::list m_list; + std::unordered_map m_cache; + + }; + +} From ea76bfd0194c7131bd7ba6121a15ed6e36992b40 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 14 Feb 2022 00:08:01 +0100 Subject: [PATCH 0324/1348] [d3d9] Unmap unused resources --- dxvk.conf | 9 ++++ src/d3d9/d3d9_common_texture.cpp | 4 +- src/d3d9/d3d9_device.cpp | 72 ++++++++++++++++++++++++++++++-- src/d3d9/d3d9_device.h | 12 ++++++ src/d3d9/d3d9_options.cpp | 1 + src/d3d9/d3d9_options.h | 3 ++ src/d3d9/d3d9_texture.cpp | 3 ++ 7 files changed, 100 insertions(+), 4 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index 45f5998b1..ba924e8ad 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -560,3 +560,12 @@ # - True/False # dxvk.enableDebugUtils = False + +# Memory limit for locked D3D9 textures +# +# How much virtual memory will be used for textures (in MB). +# 0 to disable the limit. +# THIS DOES NOT IMPACT ACTUAL MEMORY CONSUMPTION OR TEXTURE QUALITY. +# DO NOT CHANGE THIS UNLESS YOU HAVE A VERY GOOD REASON. + +# d3d9.textureMemory = 100 diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index b14ff99ff..74100dfc8 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -89,6 +89,8 @@ namespace dxvk { D3D9CommonTexture::~D3D9CommonTexture() { if (m_size != 0) m_device->ChangeReportedMemory(m_size); + + m_device->RemoveMappedTexture(this); } @@ -488,7 +490,7 @@ namespace dxvk { return D3D9_COMMON_TEXTURE_MAP_MODE_NONE; #ifdef D3D9_ALLOW_UNMAPPING - if (m_desc.Pool != D3DPOOL_DEFAULT) + if (m_device->GetOptions()->textureMemory != 0 && m_desc.Pool != D3DPOOL_DEFAULT) return D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE; #endif diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index fbc4c64b2..57f22d6e5 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -1,6 +1,7 @@ #include "d3d9_device.h" #include "d3d9_annotation.h" +#include "d3d9_common_texture.h" #include "d3d9_interface.h" #include "d3d9_swapchain.h" #include "d3d9_caps.h" @@ -4201,6 +4202,7 @@ namespace dxvk { pResource->GetBuffer(Subresource, !needsReadback); } + // Don't use MapTexture here to keep the mapped list small while the resource is still locked. mapPtr = pResource->GetData(Subresource); if (needsReadback) { @@ -4298,6 +4300,8 @@ namespace dxvk { pResource->SetLocked(Subresource, true); + UnmapTextures(); + const bool noDirtyUpdate = Flags & D3DLOCK_NO_DIRTY_UPDATE; if ((desc.Pool == D3DPOOL_DEFAULT || !noDirtyUpdate) && !readOnly) { if (pBox && MipLevel != 0) { @@ -4354,6 +4358,7 @@ namespace dxvk { if (unlikely(!pResource->GetLocked(Subresource))) return D3D_OK; + MapTexture(pResource, Subresource); // Add it to the list of mapped resources pResource->SetLocked(Subresource, false); // Flush image contents from staging if we aren't read only @@ -4380,6 +4385,7 @@ namespace dxvk { pResource->SetNeedsReadback(Subresource, true); } + UnmapTextures(); return D3D_OK; } @@ -4463,7 +4469,7 @@ namespace dxvk { + srcOffsetBlockCount.y * pitch + srcOffsetBlockCount.x * formatInfo->elementSize; - const void* mapPtr = pSrcTexture->GetData(SrcSubresource); + const void* mapPtr = MapTexture(pSrcTexture, SrcSubresource); VkDeviceSize dirtySize = extentBlockCount.width * extentBlockCount.height * extentBlockCount.depth * formatInfo->elementSize; D3D9BufferSlice slice = AllocStagingBuffer(dirtySize); const void* srcData = reinterpret_cast(mapPtr) + copySrcOffset; @@ -4489,7 +4495,7 @@ namespace dxvk { } else { const DxvkFormatInfo* formatInfo = lookupFormatInfo(pDestTexture->GetFormatMapping().FormatColor); - const void* mapPtr = pSrcTexture->GetData(SrcSubresource); + const void* mapPtr = MapTexture(pSrcTexture, SrcSubresource); // Add more blocks for the other planes that we might have. // TODO: PLEASE CLEAN ME @@ -4522,6 +4528,7 @@ namespace dxvk { image, dstLayers, slice.slice); } + UnmapTextures(); } void D3D9DeviceEx::EmitGenerateMips( @@ -4643,6 +4650,7 @@ namespace dxvk { pResource->SetMapFlags(Flags | oldFlags); pResource->IncrementLockCount(); + UnmapTextures(); return D3D_OK; } @@ -4675,7 +4683,8 @@ namespace dxvk { pResource->DirtyRange().Clear(); TrackBufferMappingBufferSequenceNumber(pResource); - return D3D_OK; + UnmapTextures(); + return D3D_OK; } @@ -7223,4 +7232,61 @@ namespace dxvk { return m_csChunk->empty() ? m_csSeqNum : m_csSeqNum + 1; } + + void* D3D9DeviceEx::MapTexture(D3D9CommonTexture* pTexture, UINT Subresource) { + // Will only be called inside the device lock + void *ptr = pTexture->GetData(Subresource); + +#ifdef D3D9_ALLOW_UNMAPPING + if (likely(pTexture->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE)) { + m_mappedTextures.insert(pTexture); + } +#endif + + return ptr; + } + + void D3D9DeviceEx::TouchMappedTexture(D3D9CommonTexture* pTexture) { +#ifdef D3D9_ALLOW_UNMAPPING + if (pTexture->GetMapMode() != D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE) + return; + + D3D9DeviceLock lock = LockDevice(); + m_mappedTextures.touch(pTexture); +#endif + } + + void D3D9DeviceEx::RemoveMappedTexture(D3D9CommonTexture* pTexture) { +#ifdef D3D9_ALLOW_UNMAPPING + if (pTexture->GetMapMode() != D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE) + return; + + D3D9DeviceLock lock = LockDevice(); + m_mappedTextures.remove(pTexture); +#endif + } + + void D3D9DeviceEx::UnmapTextures() { + // Will only be called inside the device lock + +#ifdef D3D9_ALLOW_UNMAPPING + uint32_t mappedMemory = m_memoryAllocator.MappedMemory(); + if (likely(mappedMemory < uint32_t(m_d3d9Options.textureMemory))) + return; + + uint32_t threshold = (m_d3d9Options.textureMemory / 4) * 3; + + auto iter = m_mappedTextures.leastRecentlyUsedIter(); + while (m_memoryAllocator.MappedMemory() >= threshold && iter != m_mappedTextures.leastRecentlyUsedEndIter()) { + if (unlikely((*iter)->IsAnySubresourceLocked() != 0)) { + iter++; + continue; + } + (*iter)->UnmapData(); + + iter = m_mappedTextures.remove(iter); + } +#endif + } + } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 2d1e3dcc8..6b1d26412 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -28,10 +28,13 @@ #include "d3d9_shader_permutations.h" +#include #include #include #include +#include "../util/util_lru.h" + namespace dxvk { class D3D9InterfaceEx; @@ -934,6 +937,10 @@ namespace dxvk { return &m_memoryAllocator; } + void* MapTexture(D3D9CommonTexture* pTexture, UINT Subresource); + void TouchMappedTexture(D3D9CommonTexture* pTexture); + void RemoveMappedTexture(D3D9CommonTexture* pTexture); + private: DxvkCsChunkRef AllocCsChunk() { @@ -1142,6 +1149,8 @@ namespace dxvk { D3D9CommonTexture* pResource, UINT Subresource); + void UnmapTextures(); + uint64_t GetCurrentSequenceNumber(); Com m_parent; @@ -1282,6 +1291,9 @@ namespace dxvk { Direct3DState9 m_state; +#ifdef D3D9_ALLOW_UNMAPPING + lru_list m_mappedTextures; +#endif }; } diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index b7e802605..ec44bf245 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -73,6 +73,7 @@ namespace dxvk { this->deviceLocalConstantBuffers = config.getOption ("d3d9.deviceLocalConstantBuffers", false); this->allowDirectBufferMapping = config.getOption ("d3d9.allowDirectBufferMapping", true); this->seamlessCubes = config.getOption ("d3d9.seamlessCubes", false); + this->textureMemory = config.getOption ("d3d9.textureMemory", 100) << 20; // If we are not Nvidia, enable general hazards. this->generalHazards = adapter != nullptr diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index 33e3ebe5b..34d3ae1f1 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -157,6 +157,9 @@ namespace dxvk { /// Don't use non seamless cube maps bool seamlessCubes; + + /// How much virtual memory will be used for textures (in MB). + int32_t textureMemory; }; } diff --git a/src/d3d9/d3d9_texture.cpp b/src/d3d9/d3d9_texture.cpp index 811a6cd3a..2f1d3ce6e 100644 --- a/src/d3d9/d3d9_texture.cpp +++ b/src/d3d9/d3d9_texture.cpp @@ -90,6 +90,7 @@ namespace dxvk { if (m_texture.IsManaged()) m_texture.SetAllNeedUpload(); + m_parent->TouchMappedTexture(&m_texture); return D3D_OK; } @@ -174,6 +175,7 @@ namespace dxvk { if (m_texture.IsManaged()) m_texture.SetAllNeedUpload(); + m_parent->TouchMappedTexture(&m_texture); return D3D_OK; } @@ -267,6 +269,7 @@ namespace dxvk { } } + m_parent->TouchMappedTexture(&m_texture); return D3D_OK; } From 1d1f0c7e7eb41dbbfa44a208bec84c81f5d0b1ea Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 30 Jul 2022 12:30:33 +0000 Subject: [PATCH 0325/1348] [d3d9] Document D3D9SpecConstantId --- src/d3d9/d3d9_spec_constants.h | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/d3d9/d3d9_spec_constants.h b/src/d3d9/d3d9_spec_constants.h index 2f7cdaf39..2e6ccf99e 100644 --- a/src/d3d9/d3d9_spec_constants.h +++ b/src/d3d9/d3d9_spec_constants.h @@ -5,21 +5,26 @@ namespace dxvk { enum D3D9SpecConstantId : uint32_t { - AlphaCompareOp = 0, - SamplerType = 1, - FogEnabled = 2, - VertexFogMode = 3, - PixelFogMode = 4, + AlphaCompareOp = 0, // Range: 0 -> 7 | Bits: 3 + SamplerType = 1, // 2 bits for 16 samplers | Bits: 32 + // ^ not used for vertex shaders + FogEnabled = 2, // Range: 0 -> 1 | Bits: 1 + VertexFogMode = 3, // Range: 0 -> 3 | Bits: 2 + PixelFogMode = 4, // Range: 0 -> 3 | Bits: 2 - PointMode = 5, - ProjectionType = 6, + PointMode = 5, // Range: 0 -> 3 | Bits: 3 + ProjectionType = 6, // 1 bit for 16 samplers | Bits: 16 + // ^ not supported for vertex shaders - VertexShaderBools = 7, - PixelShaderBools = 8, - Fetch4 = 9, + VertexShaderBools = 7, // 16 bools | Bits: 16 + PixelShaderBools = 8, // 16 bools | Bits: 16 + Fetch4 = 9, // 1 bit for 16 samplers | Bits: 16 + // ^ not supported for vertex shaders - SamplerDepthMode = 10, - SamplerNull = 11, + SamplerDepthMode = 10, // 1 bit for 20 samplers | Bits: 20 + // ^ vs + ps + SamplerNull = 11, // 1 bit for 20 samplers | Bits: 20 + // ^ vs + ps }; } \ No newline at end of file From 753aede1fce18aedeea84f52753ff4d8888d6d9b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 30 Jul 2022 12:34:18 +0000 Subject: [PATCH 0326/1348] [d3d9] Correct comment about ProjectionType --- src/d3d9/d3d9_spec_constants.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_spec_constants.h b/src/d3d9/d3d9_spec_constants.h index 2e6ccf99e..2c4fcc162 100644 --- a/src/d3d9/d3d9_spec_constants.h +++ b/src/d3d9/d3d9_spec_constants.h @@ -13,8 +13,9 @@ namespace dxvk { PixelFogMode = 4, // Range: 0 -> 3 | Bits: 2 PointMode = 5, // Range: 0 -> 3 | Bits: 3 - ProjectionType = 6, // 1 bit for 16 samplers | Bits: 16 + ProjectionType = 6, // 1 bit for 6 samplers | Bits: 6 // ^ not supported for vertex shaders + // PS 1.x only supports up to 6 samplers VertexShaderBools = 7, // 16 bools | Bits: 16 PixelShaderBools = 8, // 16 bools | Bits: 16 From 80a58f000a428e262283930917842af4f23a0034 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 15:39:22 +0200 Subject: [PATCH 0327/1348] [dxvk] Generate bit mask of used spec constants in DxvkShader This way we can more accurately track which constants are used, and not pass any unnecessary data at compile time. We can extend this in the future to also skip unused constants for pipeline lookups. Also, any spec constant with the ID of MaxNumSpecConstants will be treated as a spec constant selector. If the shader uses this constant, it is assumed that it does not access any other spec constants if the value of this constant is 0. This will allow shaders with spec constants to be used with pipeline libraries. --- src/dxvk/dxvk_shader.cpp | 9 ++++++--- src/dxvk/dxvk_shader.h | 11 ++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 61b57bfd4..c9e120aba 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -64,8 +64,10 @@ namespace dxvk { bindingOffsets[varId].setOffset = ins.offset() + 3; } - if (ins.arg(2) == spv::DecorationSpecId && ins.arg(3) < MaxNumSpecConstants) - m_flags.set(DxvkShaderFlag::HasSpecConstants); + if (ins.arg(2) == spv::DecorationSpecId) { + if (ins.arg(3) <= MaxNumSpecConstants) + m_specConstantMask |= 1u << ins.arg(3); + } if (ins.arg(2) == spv::DecorationLocation && ins.arg(3) == 1) { m_o1LocOffset = ins.offset() + 3; @@ -158,7 +160,8 @@ namespace dxvk { return false; // Ignore shaders that have user-defined spec constants - return !m_flags.test(DxvkShaderFlag::HasSpecConstants); + // and no selector to read their contents from elsewhere + return !m_specConstantMask || (m_specConstantMask & (1u << MaxNumSpecConstants)); } diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 4ff2ffb45..2def7936b 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -27,7 +27,6 @@ namespace dxvk { enum DxvkShaderFlag : uint64_t { HasSampleRateShading, HasTransformFeedback, - HasSpecConstants, ExportsStencilRef, ExportsViewportIndexLayerFromVertexStage, }; @@ -112,6 +111,14 @@ namespace dxvk { return m_bindings; } + /** + * \brief Retrieves spec constant mask + * \returns Bit mask of used spec constants + */ + uint32_t getSpecConstantMask() const { + return m_specConstantMask; + } + /** * \brief Patches code using given info * @@ -209,6 +216,8 @@ namespace dxvk { size_t m_o1IdxOffset = 0; size_t m_o1LocOffset = 0; + uint32_t m_specConstantMask = 0; + std::vector m_uniformData; std::vector m_bindingOffsets; From b90f8819c63d0cd6799db4bed151b7814ffb713d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 15:54:38 +0200 Subject: [PATCH 0328/1348] [dxvk] Only pass required spec constants when compiling graphics pipelines --- src/dxvk/dxvk_graphics.cpp | 26 ++++++++++++++++++++++++-- src/dxvk/dxvk_graphics.h | 6 +++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index bffb9bcef..9af8b08e1 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -514,6 +514,7 @@ namespace dxvk { m_fsLibrary (fsLibrary) { m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->info().inputMask : 0; m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->info().outputMask : 0; + m_specConstantMask = this->computeSpecConstantMask(); if (m_shaders.gs != nullptr) { if (m_shaders.gs->flags().test(DxvkShaderFlag::HasTransformFeedback)) { @@ -814,8 +815,13 @@ namespace dxvk { // Set up some specialization constants DxvkSpecConstants specData; - for (uint32_t i = 0; i < MaxNumSpecConstants; i++) - specData.set(i, state.sc.specConstants[i], 0u); + for (uint32_t i = 0; i < MaxNumSpecConstants; i++) { + if (m_specConstantMask & (1u << i)) + specData.set(i, state.sc.specConstants[i], 0u); + } + + if (m_specConstantMask & (1u << MaxNumSpecConstants)) + specData.set(MaxNumSpecConstants, 1u, 0u); VkSpecializationInfo specInfo = specData.getSpecInfo(); @@ -969,6 +975,22 @@ namespace dxvk { } + uint32_t DxvkGraphicsPipeline::computeSpecConstantMask() const { + uint32_t mask = m_shaders.vs->getSpecConstantMask(); + + if (m_shaders.tcs != nullptr) + mask |= m_shaders.tcs->getSpecConstantMask(); + if (m_shaders.tes != nullptr) + mask |= m_shaders.tes->getSpecConstantMask(); + if (m_shaders.gs != nullptr) + mask |= m_shaders.gs->getSpecConstantMask(); + if (m_shaders.fs != nullptr) + mask |= m_shaders.fs->getSpecConstantMask(); + + return mask; + } + + bool DxvkGraphicsPipeline::validatePipelineState( const DxvkGraphicsPipelineStateInfo& state, bool trusted) const { diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 8ab88b746..71e05642e 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -395,7 +395,9 @@ namespace dxvk { uint32_t m_vsIn = 0; uint32_t m_fsOut = 0; - + + uint32_t m_specConstantMask = 0; + // List of pipeline instances, shared between threads alignas(CACHE_LINE_SIZE) dxvk::mutex m_mutex; @@ -436,6 +438,8 @@ namespace dxvk { const DxvkGraphicsPipelineStateInfo& state, uint32_t target) const; + uint32_t computeSpecConstantMask() const; + bool validatePipelineState( const DxvkGraphicsPipelineStateInfo& state, bool trusted) const; From 47794b661e38703e25562d588091089b74548749 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 16:00:28 +0200 Subject: [PATCH 0329/1348] [dxvk] Only pass requried spec constants when compiling compute pipelines --- src/dxvk/dxvk_compute.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index bbf8a27f2..02249771e 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -106,10 +106,16 @@ namespace dxvk { Logger::debug(str::format(" cs : ", m_shaders.cs->debugName())); } + uint32_t specConstantMask = m_shaders.cs->getSpecConstantMask(); DxvkSpecConstants specData; - - for (uint32_t i = 0; i < MaxNumSpecConstants; i++) - specData.set(i, state.sc.specConstants[i], 0u); + + for (uint32_t i = 0; i < MaxNumSpecConstants; i++) { + if (specConstantMask & (1u << i)) + specData.set(i, state.sc.specConstants[i], 0u); + } + + if (specConstantMask & (1u << MaxNumSpecConstants)) + specData.set(MaxNumSpecConstants, 1u, 0u); VkSpecializationInfo specInfo = specData.getSpecInfo(); From 94ca65d5873dd120d3dc4fb6ff08d6bd59ed4776 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 17:42:46 +0200 Subject: [PATCH 0330/1348] [dxvk] Ignore spec constants that are not used by the current pipeline May reduce the number of pipeline permutations. --- src/dxvk/dxvk_compute.h | 11 +++++ src/dxvk/dxvk_context.cpp | 77 ++++++++++++++++++++++++++--------- src/dxvk/dxvk_context.h | 24 ++++++++++- src/dxvk/dxvk_context_state.h | 10 +++++ src/dxvk/dxvk_graphics.h | 11 +++++ 5 files changed, 112 insertions(+), 21 deletions(-) diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index a921e7d63..560e59ab5 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -90,6 +90,17 @@ namespace dxvk { DxvkBindingLayoutObjects* getBindings() const { return m_bindings; } + + /** + * \brief Queries spec constant mask + * + * This only includes user spec constants. + * \returns Bit mask of used spec constants + */ + uint32_t getSpecConstantMask() const { + constexpr uint32_t globalMask = (1u << MaxNumSpecConstants) - 1; + return m_shaders.cs->getSpecConstantMask() & globalMask; + } /** * \brief Retrieves pipeline handle diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b1716c326..f568987e5 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2524,24 +2524,6 @@ namespace dxvk { } - void DxvkContext::setSpecConstant( - VkPipelineBindPoint pipeline, - uint32_t index, - uint32_t value) { - auto& specConst = pipeline == VK_PIPELINE_BIND_POINT_GRAPHICS - ? m_state.gp.state.sc.specConstants[index] - : m_state.cp.state.sc.specConstants[index]; - - if (specConst != value) { - specConst = value; - - m_flags.set(pipeline == VK_PIPELINE_BIND_POINT_GRAPHICS - ? DxvkContextFlag::GpDirtyPipelineState - : DxvkContextFlag::CpDirtyPipelineState); - } - } - - void DxvkContext::setBarrierControl(DxvkBarrierControlFlags control) { m_barrierControl = control; } @@ -4493,6 +4475,12 @@ namespace dxvk { if (unlikely(!newPipeline)) return false; + if (unlikely(newPipeline->getSpecConstantMask() != m_state.cp.constants.mask)) + this->resetSpecConstants(newPipeline->getSpecConstantMask()); + + if (m_flags.test(DxvkContextFlag::CpDirtySpecConstants)) + this->updateSpecConstants(); + // Look up Vulkan pipeline handle for the given compute state auto pipelineHandle = newPipeline->getPipelineHandle(m_state.cp.state); @@ -4545,6 +4533,9 @@ namespace dxvk { return false; } + if (unlikely(newPipeline->getSpecConstantMask() != m_state.gp.constants.mask)) + this->resetSpecConstants(newPipeline->getSpecConstantMask()); + if (m_state.gp.flags != newPipeline->flags()) { m_state.gp.flags = newPipeline->flags(); @@ -4656,6 +4647,49 @@ namespace dxvk { } + template + void DxvkContext::resetSpecConstants( + uint32_t newMask) { + auto& scInfo = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ? m_state.gp.state.sc : m_state.cp.state.sc; + auto& scState = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ? m_state.gp.constants : m_state.cp.constants; + + // Set all constants to 0 that were used by the previous pipeline + // but are not used by the old one. Any stale data could otherwise + // lead to unnecessary pipeline variants being created. + for (auto i : bit::BitMask(scState.mask & ~newMask)) + scInfo.specConstants[i] = 0; + + scState.mask = newMask; + + auto flag = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS + ? DxvkContextFlag::GpDirtySpecConstants + : DxvkContextFlag::CpDirtySpecConstants; + + if (newMask) + m_flags.set(flag); + else + m_flags.clr(flag); + } + + + template + void DxvkContext::updateSpecConstants() { + auto& scInfo = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ? m_state.gp.state.sc : m_state.cp.state.sc; + auto& scState = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ? m_state.gp.constants : m_state.cp.constants; + + for (auto i : bit::BitMask(scState.mask)) + scInfo.specConstants[i] = scState.data[i]; + + if (BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS) { + m_flags.clr(DxvkContextFlag::GpDirtySpecConstants); + m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + } else { + m_flags.clr(DxvkContextFlag::CpDirtySpecConstants); + m_flags.set(DxvkContextFlag::CpDirtyPipelineState); + } + } + + void DxvkContext::invalidateState() { this->unbindComputePipeline(); this->unbindGraphicsPipeline(); @@ -5348,7 +5382,9 @@ namespace dxvk { bool DxvkContext::commitComputeState() { this->spillRenderPass(false); - if (m_flags.test(DxvkContextFlag::CpDirtyPipelineState)) { + if (m_flags.any( + DxvkContextFlag::CpDirtyPipelineState, + DxvkContextFlag::CpDirtySpecConstants)) { if (unlikely(!this->updateComputePipelineState())) return false; } @@ -5397,6 +5433,9 @@ namespace dxvk { if (m_flags.test(DxvkContextFlag::GpDirtyVertexBuffers)) this->updateVertexBufferBindings(); + if (m_flags.test(DxvkContextFlag::GpDirtySpecConstants)) + this->updateSpecConstants(); + if (m_flags.test(DxvkContextFlag::GpDirtyPipelineState)) { DxvkGlobalPipelineBarrier barrier = { }; diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 3e9eff4e3..46b0dd9ba 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1033,7 +1033,20 @@ namespace dxvk { void setSpecConstant( VkPipelineBindPoint pipeline, uint32_t index, - uint32_t value); + uint32_t value) { + auto& scState = pipeline == VK_PIPELINE_BIND_POINT_GRAPHICS + ? m_state.gp.constants : m_state.cp.constants; + + if (scState.data[index] != value) { + scState.data[index] = value; + + if (scState.mask & (1u << index)) { + m_flags.set(pipeline == VK_PIPELINE_BIND_POINT_GRAPHICS + ? DxvkContextFlag::GpDirtySpecConstants + : DxvkContextFlag::CpDirtySpecConstants); + } + } + } /** * \brief Sets barrier control flags @@ -1347,7 +1360,14 @@ namespace dxvk { void unbindGraphicsPipeline(); bool updateGraphicsPipeline(); bool updateGraphicsPipelineState(DxvkGlobalPipelineBarrier srcBarrier); - + + template + void resetSpecConstants( + uint32_t newMask); + + template + void updateSpecConstants(); + void invalidateState(); template diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 859f29ca2..d0b4d5630 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -37,6 +37,7 @@ namespace dxvk { GpDirtyStencilRef, ///< Stencil reference has changed GpDirtyRasterizerState, ///< Cull mode and front face have changed GpDirtyViewport, ///< Viewport state has changed + GpDirtySpecConstants, ///< Graphics spec constants are out of date GpDynamicBlendConstants, ///< Blend constants are dynamic GpDynamicDepthStencilState, ///< Depth-stencil state is dynamic GpDynamicDepthBias, ///< Depth bias is dynamic @@ -47,6 +48,7 @@ namespace dxvk { GpIndependentSets, ///< Graphics pipeline layout was created with independent sets CpDirtyPipelineState, ///< Compute pipeline is out of date + CpDirtySpecConstants, ///< Compute spec constants are out of date DirtyDrawBuffer, ///< Indirect argument buffer is dirty DirtyPushConstants, ///< Push constant data has changed @@ -120,11 +122,18 @@ namespace dxvk { }; + struct DxvkSpecConstantState { + uint32_t mask = 0; + std::array data = { }; + }; + + struct DxvkGraphicsPipelineState { DxvkGraphicsPipelineShaders shaders; DxvkGraphicsPipelineStateInfo state; DxvkGraphicsPipelineFlags flags; DxvkGraphicsPipeline* pipeline = nullptr; + DxvkSpecConstantState constants; }; @@ -132,6 +141,7 @@ namespace dxvk { DxvkComputePipelineShaders shaders; DxvkComputePipelineStateInfo state; DxvkComputePipeline* pipeline = nullptr; + DxvkSpecConstantState constants; }; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 71e05642e..d3593b41a 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -343,6 +343,17 @@ namespace dxvk { return m_bindings; } + /** + * \brief Queries spec constant mask + * + * This only includes user spec constants. + * \returns Bit mask of used spec constants + */ + uint32_t getSpecConstantMask() const { + constexpr uint32_t globalMask = (1u << MaxNumSpecConstants) - 1; + return m_specConstantMask & globalMask; + } + /** * \brief Queries global resource barrier * From 2782afaf8acef100af766a6a14455dd132124ed7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 17:52:55 +0200 Subject: [PATCH 0331/1348] [dxvk] Inline pushConstants method No reason not to. --- src/dxvk/dxvk_context.cpp | 10 ---------- src/dxvk/dxvk_context.h | 8 ++++++-- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index f568987e5..b2c3bb837 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1790,16 +1790,6 @@ namespace dxvk { } - void DxvkContext::pushConstants( - uint32_t offset, - uint32_t size, - const void* data) { - std::memcpy(&m_state.pc.data[offset], data, size); - - m_flags.set(DxvkContextFlag::DirtyPushConstants); - } - - void DxvkContext::resolveImage( const Rc& dstImage, const Rc& srcImage, diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 46b0dd9ba..c738dd5ec 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -793,8 +793,12 @@ namespace dxvk { void pushConstants( uint32_t offset, uint32_t size, - const void* data); - + const void* data) { + std::memcpy(&m_state.pc.data[offset], data, size); + + m_flags.set(DxvkContextFlag::DirtyPushConstants); + } + /** * \brief Resolves a multisampled image resource * From bad7d4690bfd3c35cff79595d25ead1ed5dc39a4 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sat, 30 Jul 2022 00:11:43 +0200 Subject: [PATCH 0332/1348] [d3d9] Handle very large Up draws --- src/d3d9/d3d9_device.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 57f22d6e5..78a02707d 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3976,22 +3976,32 @@ namespace dxvk { D3D9BufferSlice D3D9DeviceEx::AllocUPBuffer(VkDeviceSize size) { constexpr VkDeviceSize UPBufferSize = 1 << 20; - if (unlikely(m_upBuffer == nullptr)) { + if (unlikely(m_upBuffer == nullptr || size > UPBufferSize)) { VkMemoryPropertyFlags memoryFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; DxvkBufferCreateInfo info; - info.size = UPBufferSize; + info.size = std::max(UPBufferSize, size); info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT; info.access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_INDEX_READ_BIT; info.stages = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; - m_upBuffer = m_dxvkDevice->createBuffer(info, memoryFlags); - m_upBufferMapPtr = m_upBuffer->mapPtr(0); + Rc buffer = m_dxvkDevice->createBuffer(info, memoryFlags); + + if (size <= UPBufferSize) { + m_upBuffer = std::move(buffer); + m_upBufferMapPtr = m_upBuffer->mapPtr(0); + } else { + // Temporary buffer + D3D9BufferSlice result; + result.slice = DxvkBufferSlice(std::move(buffer), 0, size); + result.mapPtr = buffer->mapPtr(0); + return result; + } } VkDeviceSize alignedSize = align(size, CACHE_LINE_SIZE); From 200df73ba7c8a3a7689abfb9ccbf8c5d2bd67736 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 28 Jul 2022 18:40:46 +0200 Subject: [PATCH 0333/1348] [util] Implement utility functions for string conversion --- src/util/util_string.cpp | 201 +++++++++++++++++++++++++++++++++++++++ src/util/util_string.h | 154 +++++++++++++++++++++++++++++- 2 files changed, 354 insertions(+), 1 deletion(-) diff --git a/src/util/util_string.cpp b/src/util/util_string.cpp index 2151c1e40..084d89d1c 100644 --- a/src/util/util_string.cpp +++ b/src/util/util_string.cpp @@ -1,6 +1,207 @@ #include "util_string.h" namespace dxvk::str { + + const uint8_t* decodeTypedChar( + const uint8_t* begin, + const uint8_t* end, + uint32_t& ch) { + uint32_t first = begin[0]; + + if (likely(first < 0x80)) { + // Basic ASCII character + ch = uint32_t(first); + return begin + 1; + } else if (unlikely(first < 0xC0)) { + // Character starts with a continuation byte, + // just skip until we find the next valid prefix + while ((begin < end) && (((*begin) & 0xC0) == 0x80)) + begin += 1; + + ch = uint32_t('?'); + return begin; + } else { + // The number of leading 1 bits in the first byte + // determines the length of this character + size_t length = bit::lzcnt((~first) << 24); + + if (unlikely(begin + length > end)) { + ch = uint32_t('?'); + return end; + } + + if (first < 0xE0) { + ch = ((uint32_t(begin[0]) & 0x1F) << 6) + | ((uint32_t(begin[1]) & 0x3F)); + } else if (first < 0xF0) { + ch = ((uint32_t(begin[0]) & 0x0F) << 12) + | ((uint32_t(begin[1]) & 0x3F) << 6) + | ((uint32_t(begin[2]) & 0x3F)); + } else if (first < 0xF8) { + ch = ((uint32_t(begin[0]) & 0x07) << 18) + | ((uint32_t(begin[1]) & 0x3F) << 12) + | ((uint32_t(begin[2]) & 0x3F) << 6) + | ((uint32_t(begin[3]) & 0x3F)); + } else { + // Invalid prefix + ch = uint32_t('?'); + } + + return begin + length; + } + } + + const uint16_t* decodeTypedChar( + const uint16_t* begin, + const uint16_t* end, + uint32_t& ch) { + uint32_t first = begin[0]; + + if (likely(first < 0xD800)) { + ch = first; + return begin + 1; + } else if (first < 0xDC00) { + if (unlikely(begin + 2 > end)) { + ch = uint32_t('?'); + return end; + } + + ch = 0x10000 + + ((uint32_t(begin[0]) & 0x3FF) << 10) + + ((uint32_t(begin[1]) & 0x3FF)); + return begin + 2; + } else if (unlikely(first < 0xE000)) { + // Stray low surrogate + ch = uint32_t('?'); + return begin + 1; + } else { + ch = first; + return begin + 1; + } + } + + + const uint32_t* decodeTypedChar( + const uint32_t* begin, + const uint32_t* end, + uint32_t& ch) { + ch = begin[0]; + return begin + 1; + } + + + size_t encodeTypedChar( + uint8_t* begin, + uint8_t* end, + uint32_t ch) { + if (likely(ch < 0x80)) { + if (begin) { + if (unlikely(begin + 1 > end)) + return 0; + + begin[0] = uint8_t(ch); + } + + return 1; + } else if (ch < 0x800) { + if (begin) { + if (unlikely(begin + 2 > end)) + return 0; + + begin[0] = uint8_t(0xC0 | (ch >> 6)); + begin[1] = uint8_t(0x80 | (ch & 0x3F)); + } + + return 2; + } else if (ch < 0x10000) { + if (begin) { + if (unlikely(begin + 3 > end)) + return 0; + + begin[0] = uint8_t(0xE0 | ((ch >> 12))); + begin[1] = uint8_t(0x80 | ((ch >> 6) & 0x3F)); + begin[2] = uint8_t(0x80 | ((ch >> 0) & 0x3F)); + } + + return 3; + } else if (ch < 0x200000) { + if (begin) { + if (unlikely(begin + 4 < end)) + return 0; + + begin[0] = uint8_t(0xF0 | ((ch >> 18))); + begin[1] = uint8_t(0x80 | ((ch >> 12) & 0x3F)); + begin[2] = uint8_t(0x80 | ((ch >> 6) & 0x3F)); + begin[3] = uint8_t(0x80 | ((ch >> 0) & 0x3F)); + } + + return 4; + } else { + // Invalid code point for UTF-8 + return 0; + } + } + + + size_t encodeTypedChar( + uint16_t* begin, + uint16_t* end, + uint32_t ch) { + if (likely(ch < 0xD800)) { + if (begin) { + if (unlikely(begin + 1 > end)) + return 0; + + begin[0] = ch; + } + + return 1; + } else if (ch < 0xE000) { + // Private use code points, + // we can't encode these + return 0; + } else if (ch < 0x10000) { + if (begin) { + if (unlikely(begin + 1 > end)) + return 0; + + begin[0] = ch; + } + + return 1; + } else if (ch < 0x110000) { + if (begin) { + if (unlikely(begin + 2 > end)) + return 0; + + ch -= 0x10000; + begin[0] = uint16_t(0xD800 + (ch >> 10)); + begin[1] = uint16_t(0xDC00 + (ch & 0x3FF)); + } + + return 2; + } else { + // Invalid code point + return 0; + } + } + + + size_t encodeTypedChar( + uint32_t* begin, + uint32_t* end, + uint32_t ch) { + if (begin) { + if (unlikely(begin + 1 > end)) + return 0; + + begin[0] = ch; + } + + return 1; + } + + std::string fromws(const WCHAR *ws) { size_t len = ::WideCharToMultiByte(CP_UTF8, 0, ws, -1, nullptr, 0, nullptr, nullptr); diff --git a/src/util/util_string.h b/src/util/util_string.h index ae6740343..93595fdaf 100644 --- a/src/util/util_string.h +++ b/src/util/util_string.h @@ -7,8 +7,160 @@ #include "./com/com_include.h" +#include "util_bit.h" +#include "util_likely.h" + namespace dxvk::str { - + + template struct UnicodeChar { }; + template<> struct UnicodeChar<1> { using type = uint8_t; }; + template<> struct UnicodeChar<2> { using type = uint16_t; }; + template<> struct UnicodeChar<4> { using type = uint32_t; }; + + template + using UnicodeCharType = typename UnicodeChar::type; + + const uint8_t* decodeTypedChar( + const uint8_t* begin, + const uint8_t* end, + uint32_t& ch); + + const uint16_t* decodeTypedChar( + const uint16_t* begin, + const uint16_t* end, + uint32_t& ch); + + const uint32_t* decodeTypedChar( + const uint32_t* begin, + const uint32_t* end, + uint32_t& ch); + + size_t encodeTypedChar( + uint8_t* begin, + uint8_t* end, + uint32_t ch); + + size_t encodeTypedChar( + uint16_t* begin, + uint16_t* end, + uint32_t ch); + + size_t encodeTypedChar( + uint32_t* begin, + uint32_t* end, + uint32_t ch); + + /** + * \brief Decodes a single character + * + * Note that \c begin and \c end must not be equal. + * \param [in] begin Pointer to current position within the input string + * \param [in] end Pointer to the end of the input string + * \param [out] ch Pointer to the decoded character code + * \returns Pointer to next character in the input string + */ + template + const T* decodeChar( + const T* begin, + const T* end, + uint32_t& ch) { + using CharType = UnicodeCharType; + + const CharType* result = decodeTypedChar( + reinterpret_cast(begin), + reinterpret_cast(end), + ch); + + return reinterpret_cast(result); + } + + /** + * \brief Encodes a character + * + * Note that \c begin and \c end may be both be \c nullptr or equal, in + * which case only the length of the encoded character will be returned. + * \param [in] begin Pointer to current position within the output string + * \param [in] end Pointer to the end of the output string + * \param [in] ch Character to encode + * \returns If begin is \c nullptr , the number of units required to encode + * the character. Otherwise, the number of units written to the output. + * This may return \c 0 for characters that cannot be written or encoded. + */ + template + size_t encodeChar( + T* begin, + T* end, + uint32_t ch) { + using CharType = UnicodeCharType; + + return encodeTypedChar( + reinterpret_cast(begin), + reinterpret_cast(end), + ch); + } + + /** + * \brief Computes length of a null-terminated string + * + * \param [in] begin Start of input string + * \returns Number of characters in input string, + * excluding the terminating null character + */ + template + size_t length(const S* string) { + size_t result = 0; + + while (string[result]) + result += 1; + + return result; + } + + /** + * \brief Converts string from one encoding to another + * + * The output string arguments may be \c nullptr. In that case, the + * total length of the transcoded string will be returned, in units + * of the output character type. The output string will only be + * null-terminated if the input string is also null-terminated. + * \tparam D Output character type + * \tparam S Input character type + * \param [in] dstBegin Start of output string + * \param [in] dstLength Length of output string + * \param [in] srcBegin Start of input string + * \param [in] srcLength Length of input string + * \returns If \c dstBegin is \c nullptr , the total number of output + * characters required to store the output string. Otherwise, the + * total number of characters written to the output string. + */ + template + size_t transcodeString( + D* dstBegin, + size_t dstLength, + const S* srcBegin, + size_t srcLength) { + size_t totalLength = 0; + + auto dstEnd = dstBegin + dstLength; + auto srcEnd = srcBegin + srcLength; + + while (srcBegin < srcEnd) { + uint32_t ch; + + srcBegin = decodeChar(srcBegin, srcEnd, ch); + + if (dstBegin) + totalLength += encodeChar(dstBegin + totalLength, dstEnd, ch); + else + totalLength += encodeChar(nullptr, nullptr, ch); + + if (!ch) + break; + } + + return totalLength; + } + std::string fromws(const WCHAR *ws); void tows(const char* mbs, WCHAR* wcs, size_t wcsLen); From bb3c0b9707ccfe0584092ccbfeabe495b69b93d0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 29 Jul 2022 16:43:39 +0200 Subject: [PATCH 0334/1348] [dxgi] Use transcodeString to convert adapter name --- src/dxgi/dxgi_adapter.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index 3e8f6307e..2beb97728 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -268,7 +268,10 @@ namespace dxvk { // Convert device name std::memset(pDesc->Description, 0, sizeof(pDesc->Description)); - str::tows(description, pDesc->Description); + + str::transcodeString(pDesc->Description, + sizeof(pDesc->Description) / sizeof(pDesc->Description[0]) - 1, + description.c_str(), description.size()); // Get amount of video memory // based on the Vulkan heaps From 65070bd765ef01b1b3b376157391716b9afd7f40 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 28 Jul 2022 19:38:18 +0200 Subject: [PATCH 0335/1348] [util] Use transcodeString in setThreadName function --- src/util/util_env.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/util/util_env.cpp b/src/util/util_env.cpp index 61f6326e1..a759ae349 100644 --- a/src/util/util_env.cpp +++ b/src/util/util_env.cpp @@ -93,13 +93,17 @@ namespace dxvk::env { #ifdef _WIN32 using SetThreadDescriptionProc = HRESULT (WINAPI *) (HANDLE, PCWSTR); - static auto proc = reinterpret_cast( + static auto SetThreadDescription = reinterpret_cast( ::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "SetThreadDescription")); - if (proc != nullptr) { - auto wideName = std::vector(name.length() + 1); - str::tows(name.c_str(), wideName.data(), wideName.size()); - (*proc)(::GetCurrentThread(), wideName.data()); + if (SetThreadDescription) { + std::array wideName = { }; + + str::transcodeString( + wideName.data(), wideName.size() - 1, + name.data(), name.size()); + + SetThreadDescription(::GetCurrentThread(), wideName.data()); } #else std::array posixName = {}; From 1c08725acd1cd750903a1a6a97b8372dbbdf191f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 28 Jul 2022 19:41:05 +0200 Subject: [PATCH 0336/1348] [util] Use transcodeString in createDirectory function --- src/util/util_env.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/util/util_env.cpp b/src/util/util_env.cpp index a759ae349..1b0901f66 100644 --- a/src/util/util_env.cpp +++ b/src/util/util_env.cpp @@ -115,9 +115,14 @@ namespace dxvk::env { bool createDirectory(const std::string& path) { #ifdef _WIN32 - WCHAR widePath[MAX_PATH]; - str::tows(path.c_str(), widePath); - return !!CreateDirectoryW(widePath, nullptr); + std::array widePath; + + size_t length = str::transcodeString( + widePath.data(), widePath.size() - 1, + path.data(), path.size()); + + widePath[length] = L'\0'; + return !!CreateDirectoryW(widePath.data(), nullptr); #else return std::filesystem::create_directories(path); #endif From ec7de66419bbc833809293a1780a7d0f01a32305 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 28 Jul 2022 19:50:16 +0200 Subject: [PATCH 0337/1348] [util] Use transcodeString in tows and fromws helpers --- src/dxgi/dxgi_adapter.cpp | 9 ++++---- src/util/util_string.cpp | 44 +++++++++++++++------------------------ src/util/util_string.h | 21 ++++++++++++------- 3 files changed, 34 insertions(+), 40 deletions(-) diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index 2beb97728..84a43bc73 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -252,11 +252,10 @@ namespace dxvk { if (options->customDeviceId >= 0) deviceProp.deviceID = options->customDeviceId; - - const char* description = deviceProp.deviceName; - // Custom device description - if (!options->customDeviceDesc.empty()) - description = options->customDeviceDesc.c_str(); + + std::string description = options->customDeviceDesc.empty() + ? std::string(deviceProp.deviceName) + : options->customDeviceDesc; // XXX nvapi workaround for a lot of Unreal Engine 4 games if (options->customVendorId < 0 && options->customDeviceId < 0 diff --git a/src/util/util_string.cpp b/src/util/util_string.cpp index 084d89d1c..8a7a22488 100644 --- a/src/util/util_string.cpp +++ b/src/util/util_string.cpp @@ -202,42 +202,32 @@ namespace dxvk::str { } - std::string fromws(const WCHAR *ws) { - size_t len = ::WideCharToMultiByte(CP_UTF8, - 0, ws, -1, nullptr, 0, nullptr, nullptr); - - if (len <= 1) - return ""; - - len -= 1; + std::string fromws(const WCHAR* ws) { + size_t srcLen = length(ws); + size_t dstLen = transcodeString( + nullptr, 0, ws, srcLen); std::string result; - result.resize(len); - ::WideCharToMultiByte(CP_UTF8, 0, ws, -1, - &result.at(0), len, nullptr, nullptr); + result.resize(dstLen); + + transcodeString(result.data(), + dstLen, ws, srcLen); + return result; } - void tows(const char* mbs, WCHAR* wcs, size_t wcsLen) { - ::MultiByteToWideChar( - CP_UTF8, 0, mbs, -1, - wcs, wcsLen); - } - std::wstring tows(const char* mbs) { - size_t len = ::MultiByteToWideChar(CP_UTF8, - 0, mbs, -1, nullptr, 0); - - if (len <= 1) - return L""; - - len -= 1; + size_t srcLen = length(mbs); + size_t dstLen = transcodeString( + nullptr, 0, mbs, srcLen); std::wstring result; - result.resize(len); - ::MultiByteToWideChar(CP_UTF8, 0, mbs, -1, - &result.at(0), len); + result.resize(dstLen); + + transcodeString(result.data(), + dstLen, mbs, srcLen); + return result; } diff --git a/src/util/util_string.h b/src/util/util_string.h index 93595fdaf..95addf2b6 100644 --- a/src/util/util_string.h +++ b/src/util/util_string.h @@ -161,15 +161,20 @@ namespace dxvk::str { return totalLength; } - std::string fromws(const WCHAR *ws); - - void tows(const char* mbs, WCHAR* wcs, size_t wcsLen); - - template - void tows(const char* mbs, WCHAR (&wcs)[N]) { - return tows(mbs, wcs, N); - } + /** + * \brief Creates string object from wide char array + * + * \param [in] ws Null-terminated wide string + * \returns Regular string object + */ + std::string fromws(const WCHAR* ws); + /** + * \brief Creates wide string object from char array + * + * \param [in] mbs Null-terminated string + * \returns Wide string object + */ std::wstring tows(const char* mbs); inline void format1(std::stringstream&) { } From 10e6d0ef8a3f3b697e638463b91deb8108a4b12c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 20:38:04 +0200 Subject: [PATCH 0338/1348] [dxvk] Don't redundantly reset spec constant values No longer needed. --- src/d3d9/d3d9_format_helpers.cpp | 4 ---- src/dxvk/dxvk_swapchain_blitter.cpp | 2 -- src/dxvk/hud/dxvk_hud.cpp | 6 ------ src/dxvk/hud/dxvk_hud.h | 3 --- 4 files changed, 15 deletions(-) diff --git a/src/d3d9/d3d9_format_helpers.cpp b/src/d3d9/d3d9_format_helpers.cpp index d8d73d70a..69132767a 100644 --- a/src/d3d9/d3d9_format_helpers.cpp +++ b/src/d3d9/d3d9_format_helpers.cpp @@ -105,10 +105,6 @@ namespace dxvk { (imageExtent.height / 8) + (imageExtent.height % 8), 1); - // Reset the spec constants used... - if (specConstantValue) - m_context->setSpecConstant(VK_PIPELINE_BIND_POINT_COMPUTE, 0, 0); - m_transferCommands += 1; } diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index 33ae54bf9..61e0c3202 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -213,8 +213,6 @@ namespace dxvk { ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, srcView->imageInfo().sampleCount); ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 1, m_gammaView != nullptr); ctx->draw(3, 1, 0, 0); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 1, 0); } void DxvkSwapchainBlitter::resolve( diff --git a/src/dxvk/hud/dxvk_hud.cpp b/src/dxvk/hud/dxvk_hud.cpp index 892d5d431..935760c06 100644 --- a/src/dxvk/hud/dxvk_hud.cpp +++ b/src/dxvk/hud/dxvk_hud.cpp @@ -66,7 +66,6 @@ namespace dxvk::hud { VkExtent2D surfaceSize) { this->setupRendererState(ctx, surfaceFormat, surfaceSize); this->renderHudElements(ctx); - this->resetRendererState(ctx); } @@ -102,11 +101,6 @@ namespace dxvk::hud { } - void Hud::resetRendererState(const Rc& ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0); - } - - void Hud::renderHudElements(const Rc& ctx) { m_hudItems.render(m_renderer); } diff --git a/src/dxvk/hud/dxvk_hud.h b/src/dxvk/hud/dxvk_hud.h index d6217b8c0..8efc8774b 100644 --- a/src/dxvk/hud/dxvk_hud.h +++ b/src/dxvk/hud/dxvk_hud.h @@ -90,9 +90,6 @@ namespace dxvk::hud { VkSurfaceFormatKHR surfaceFormat, VkExtent2D surfaceSize); - void resetRendererState( - const Rc& ctx); - void renderHudElements( const Rc& ctx); From 4d8b75c8fbd2ec38c2aa6213d5163d811ba06606 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 20:38:58 +0200 Subject: [PATCH 0339/1348] [d3d9] Fix spec constant derp --- src/d3d9/d3d9_format_helpers.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/d3d9/d3d9_format_helpers.cpp b/src/d3d9/d3d9_format_helpers.cpp index 69132767a..2c369d21b 100644 --- a/src/d3d9/d3d9_format_helpers.cpp +++ b/src/d3d9/d3d9_format_helpers.cpp @@ -93,9 +93,7 @@ namespace dxvk { bufferViewInfo.rangeLength = srcSlice.length(); auto tmpBufferView = m_device->createBufferView(srcSlice.buffer(), bufferViewInfo); - if (specConstantValue) - m_context->setSpecConstant(VK_PIPELINE_BIND_POINT_COMPUTE, 0, specConstantValue); - + m_context->setSpecConstant(VK_PIPELINE_BIND_POINT_COMPUTE, 0, specConstantValue); m_context->bindResourceView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Image, tmpImageView, nullptr); m_context->bindResourceView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Buffer, nullptr, tmpBufferView); m_context->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, m_shaders[videoFormat.FormatType]); From 54f9eaf13cd393c26262cef70114807f72c9e8d1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 21:17:21 +0200 Subject: [PATCH 0340/1348] [dxvk] Don't spam log messages when pipeline state validation fails --- src/dxvk/dxvk_graphics.cpp | 36 +++++++++--------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 9af8b08e1..7f59613c7 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -1018,10 +1018,8 @@ namespace dxvk { return true; // Validate shaders - if (!m_shaders.validate()) { - Logger::err("Invalid pipeline: Shader types do not match stage"); + if (!m_shaders.validate()) return false; - } // Validate vertex input layout uint32_t ilLocationMask = 0; @@ -1033,45 +1031,33 @@ namespace dxvk { for (uint32_t i = 0; i < state.il.attributeCount(); i++) { const DxvkIlAttribute& attribute = state.ilAttributes[i]; - if (ilLocationMask & (1u << attribute.location())) { - Logger::err(str::format("Invalid pipeline: Vertex location ", attribute.location(), " defined twice")); + if (ilLocationMask & (1u << attribute.location())) return false; - } - if (!(ilBindingMask & (1u << attribute.binding()))) { - Logger::err(str::format("Invalid pipeline: Vertex binding ", attribute.binding(), " not defined")); + if (!(ilBindingMask & (1u << attribute.binding()))) return false; - } VkFormatProperties formatInfo = m_device->adapter()->formatProperties(attribute.format()); - if (!(formatInfo.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) { - Logger::err(str::format("Invalid pipeline: Format ", attribute.format(), " not supported for vertex buffers")); + if (!(formatInfo.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) return false; - } ilLocationMask |= 1u << attribute.location(); } // Validate rasterization state if (state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT) { - if (!m_device->extensions().extConservativeRasterization) { - Logger::err("Conservative rasterization not supported by device"); + if (!m_device->extensions().extConservativeRasterization) return false; - } if (state.rs.conservativeMode() == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT - && !m_device->properties().extConservativeRasterization.primitiveUnderestimation) { - Logger::err("Primitive underestimation not supported by device"); + && !m_device->properties().extConservativeRasterization.primitiveUnderestimation) return false; - } } // Validate depth-stencil state - if (state.ds.enableDepthBoundsTest() && !m_device->features().core.features.depthBounds) { - Logger::err("Depth bounds not supported by device"); + if (state.ds.enableDepthBoundsTest() && !m_device->features().core.features.depthBounds) return false; - } // Validate render target format support VkFormat depthFormat = state.rt.getDepthStencilFormat(); @@ -1079,10 +1065,8 @@ namespace dxvk { if (depthFormat) { VkFormatProperties formatInfo = m_device->adapter()->formatProperties(depthFormat); - if (!(formatInfo.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) { - Logger::err(str::format(depthFormat, " not supported as depth-stencil attachment")); + if (!(formatInfo.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) return false; - } } for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { @@ -1091,10 +1075,8 @@ namespace dxvk { if (colorFormat) { VkFormatProperties formatInfo = m_device->adapter()->formatProperties(colorFormat); - if (!(formatInfo.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) { - Logger::err(str::format(depthFormat, " not supported as color attachment")); + if (!(formatInfo.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) return false; - } } } From 8d72b8e820c1daac552aafd7b6ad3aee5c78f4e1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 21:24:15 +0200 Subject: [PATCH 0341/1348] [dxvk] Reject pipelines that set unused spec constants --- src/dxvk/dxvk_graphics.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 7f59613c7..b29f6e632 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -1080,6 +1080,12 @@ namespace dxvk { } } + // Validate spec constant state + for (uint32_t i = 0; i < MaxNumSpecConstants; i++) { + if (state.sc.specConstants[i] && !(m_specConstantMask & (1u << i))) + return false; + } + return true; } From 297759be4e5ffa7907b3ecc23d160a78c2a835cc Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 19 Apr 2022 18:41:57 +0100 Subject: [PATCH 0342/1348] [build] Initial reworkings for non-Windows platform support in Meson --- meson.build | 140 ++++++++++++++++++++++++------------------- src/dxvk/meson.build | 2 +- 2 files changed, 80 insertions(+), 62 deletions(-) diff --git a/meson.build b/meson.build index b61342331..992085a09 100644 --- a/meson.build +++ b/meson.build @@ -1,14 +1,13 @@ project('dxvk', ['c', 'cpp'], version : 'v1.10.1', meson_version : '>= 0.49', default_options : [ 'cpp_std=c++17' ]) cpu_family = target_machine.cpu_family() +platform = target_machine.system() cpp = meson.get_compiler('cpp') cc = meson.get_compiler('c') dxvk_is_msvc = cpp.get_id() == 'msvc' compiler_args = [ - '-DNOMINMAX', - '-D_WIN32_WINNT=0xa00', '-msse', '-msse2', '-msse3', @@ -19,22 +18,7 @@ compiler_args = [ '-Wno-microsoft-exception-spec', ] -link_args = [ - '-static', - '-static-libgcc', - '-static-libstdc++', - # We need to set the section alignment for debug symbols to - # work properly as well as avoiding a memcpy from the Wine loader. - '-Wl,--file-alignment=4096', -] - -# Wine's built-in back traces only work with dwarf2 symbols -if get_option('debug') and target_machine.system() == 'windows' - compiler_args += [ - '-gstrict-dwarf', - '-gdwarf-2', - ] -endif +link_args = [] if get_option('build_id') link_args += [ @@ -42,11 +26,80 @@ if get_option('build_id') ] endif -if cpu_family == 'x86' - link_args += [ - '-Wl,--enable-stdcall-fixup', - '-Wl,--add-stdcall-alias', +if platform == 'windows' + compiler_args += [ + '-DNOMINMAX', + '-D_WIN32_WINNT=0xa00', ] + + link_args += [ + '-static', + '-static-libgcc', + '-static-libstdc++', + # We need to set the section alignment for debug symbols to + # work properly as well as avoiding a memcpy from the Wine loader. + '-Wl,--file-alignment=4096', + ] + + # Wine's built-in back traces only work with dwarf2 symbols + if get_option('debug') + compiler_args += [ + '-gstrict-dwarf', + '-gdwarf-2', + ] + endif + + # Enable stdcall fixup on 32-bit + if cpu_family == 'x86' + link_args += [ + '-Wl,--enable-stdcall-fixup', + '-Wl,--add-stdcall-alias', + ] + endif + + if (cpu_family == 'x86_64') + dxvk_library_path = meson.source_root() + '/lib' + else + dxvk_library_path = meson.source_root() + '/lib32' + endif + + lib_vulkan = cpp.find_library('vulkan-1', dirs : dxvk_library_path) + lib_d3d9 = cpp.find_library('d3d9') + lib_d3d11 = cpp.find_library('d3d11') + lib_dxgi = cpp.find_library('dxgi') + lib_d3dcompiler_43 = cpp.find_library('d3dcompiler_43', dirs : dxvk_library_path) + + if dxvk_is_msvc + lib_d3dcompiler_47 = cpp.find_library('d3dcompiler') + else + lib_d3dcompiler_47 = cpp.find_library('d3dcompiler_47') + endif + + if dxvk_is_msvc + res_ext = '.res' + wrc = find_program('rc') + wrc_generator = generator(wrc, + output : [ '@BASENAME@' + res_ext ], + arguments : [ '/fo', '@OUTPUT@', '@INPUT@' ], + ) + else + res_ext = '.o' + wrc = find_program('windres') + wrc_generator = generator(wrc, + output : [ '@BASENAME@' + res_ext ], + arguments : [ '-i', '@INPUT@', '-o', '@OUTPUT@' ], + ) + endif + + dxvk_include_path = include_directories('./include') +else + lib_vulkan = cpp.find_library('vulkan') + lib_sdl2 = cpp.find_library('SDL2') + + wrc = find_program('touch') + wrc_generator = generator(wrc, output : [ '@BASENAME@_ignored.h' ], arguments : [ '@OUTPUT@' ] ) + + dxvk_include_path = include_directories('./include', './include/native', './include/native/windows', './include/native/directx') endif add_project_arguments(cpp.get_supported_arguments(compiler_args), language: 'cpp') @@ -54,31 +107,8 @@ add_project_arguments(cc.get_supported_arguments(compiler_args), language: 'c') add_project_link_arguments(cpp.get_supported_link_arguments(link_args), language: 'cpp') add_project_link_arguments(cc.get_supported_link_arguments(link_args), language: 'c') -dxvk_include_path = include_directories('./include') - -if (cpu_family == 'x86_64') - dxvk_library_path = meson.source_root() + '/lib' -else - dxvk_library_path = meson.source_root() + '/lib32' -endif - -dxvk_extradep = [ ] - -lib_vulkan = cpp.find_library('vulkan-1', dirs : dxvk_library_path) -lib_d3d9 = cpp.find_library('d3d9') -lib_d3d11 = cpp.find_library('d3d11') -lib_dxgi = cpp.find_library('dxgi') -lib_d3dcompiler_43 = cpp.find_library('d3dcompiler_43', dirs : dxvk_library_path) - -if dxvk_is_msvc - lib_d3dcompiler_47 = cpp.find_library('d3dcompiler') -else - lib_d3dcompiler_47 = cpp.find_library('d3dcompiler_47') -endif - exe_ext = '' dll_ext = '' - def_spec_ext = '.def' glsl_compiler = find_program('glslangValidator') @@ -91,28 +121,16 @@ glsl_generator = generator(glsl_compiler, arguments : glsl_args, ) -if dxvk_is_msvc - res_ext = '.res' - wrc = find_program('rc') - wrc_generator = generator(wrc, - output : [ '@BASENAME@' + res_ext ], - arguments : [ '/fo', '@OUTPUT@', '@INPUT@' ], - ) -else - res_ext = '.o' - wrc = find_program('windres') - wrc_generator = generator(wrc, - output : [ '@BASENAME@' + res_ext ], - arguments : [ '-i', '@INPUT@', '-o', '@OUTPUT@' ], - ) -endif - dxvk_version = vcs_tag( command: ['git', 'describe', '--dirty=+'], input: 'version.h.in', output: 'version.h', ) +if platform != 'windows' + error('Non-Windows platforms not supported... yet.') +endif + subdir('src') enable_tests = get_option('enable_tests') diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 99100b32d..93ebb1d3c 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -120,7 +120,7 @@ thread_dep = dependency('threads') dxvk_lib = static_library('dxvk', dxvk_src, glsl_generator.process(dxvk_shaders), dxvk_version, link_with : [ util_lib, spirv_lib ], - dependencies : [ thread_dep, vkcommon_dep ] + dxvk_extradep, + dependencies : [ thread_dep, vkcommon_dep ], include_directories : [ dxvk_include_path ], ) From 76ddd2a35a7f7fae8fd77adcf30c5fe14c2ffad2 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 20 Apr 2022 14:57:14 +0100 Subject: [PATCH 0343/1348] [build] Use current_source_dir instead of source_root source_root is deprecated and doesn't work if we are used in a subproject --- meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 992085a09..f044c8f4f 100644 --- a/meson.build +++ b/meson.build @@ -58,9 +58,9 @@ if platform == 'windows' endif if (cpu_family == 'x86_64') - dxvk_library_path = meson.source_root() + '/lib' + dxvk_library_path = meson.current_source_dir() + '/lib' else - dxvk_library_path = meson.source_root() + '/lib32' + dxvk_library_path = meson.current_source_dir() + '/lib32' endif lib_vulkan = cpp.find_library('vulkan-1', dirs : dxvk_library_path) From 0eaad2eb5b26ea5f512d02d724bdc22d458ca06b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 22:14:26 +0200 Subject: [PATCH 0344/1348] [dxso] Don't create shader object for redundant PS permutations --- src/d3d9/d3d9_shader.cpp | 2 +- src/dxso/dxso_compiler.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_shader.cpp b/src/d3d9/d3d9_shader.cpp index 8b5bb8bd6..664ebbdbc 100644 --- a/src/d3d9/d3d9_shader.cpp +++ b/src/d3d9/d3d9_shader.cpp @@ -90,7 +90,7 @@ namespace dxvk { pDevice->GetDXVKDevice()->registerShader(m_shaders[0]); - if (m_shaders[1] != nullptr) + if (m_shaders[1] != nullptr && m_shaders[1] != m_shaders[0]) pDevice->GetDXVKDevice()->registerShader(m_shaders[1]); } diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 289ef90ed..69f77e5b0 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -236,7 +236,10 @@ namespace dxvk { if (m_ps.specularColorIn) m_module.decorate(m_ps.specularColorIn, spv::DecorationFlat); - permutations[D3D9ShaderPermutations::FlatShade] = compileShader(); + if (m_ps.diffuseColorIn || m_ps.specularColorIn) + permutations[D3D9ShaderPermutations::FlatShade] = compileShader(); + else + permutations[D3D9ShaderPermutations::FlatShade] = permutations[D3D9ShaderPermutations::None]; } return permutations; From 0a151467462765d271bb4a49c6e0b2fda6a8ce5d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 22:50:10 +0200 Subject: [PATCH 0345/1348] [dxvk] Use unordered map to look up base pipelines No reason to use a linear list here. The object is always locked when we access this list, so we don't need the lock-free one here. --- src/dxvk/dxvk_graphics.cpp | 53 ++++++++++++++++++-------------------- src/dxvk/dxvk_graphics.h | 42 +++++++++++++++--------------- src/dxvk/dxvk_shader.h | 4 +++ 3 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index b29f6e632..4d6dc1df2 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -541,7 +541,7 @@ namespace dxvk { this->destroyPipeline(instance.fastHandle.load()); for (const auto& instance : m_basePipelines) - this->destroyPipeline(instance.handle); + this->destroyPipeline(instance.second); } @@ -654,19 +654,10 @@ namespace dxvk { VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT); } - if (!fastHandle) { - // If that didn't succeed, link a pipeline using the - // pre-compiled fragment and vertex shader libraries. - DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr()); - DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); - - DxvkGraphicsPipelineBaseInstanceKey key; - key.viLibrary = m_manager->createVertexInputLibrary(viState); - key.foLibrary = m_manager->createFragmentOutputLibrary(foState); - key.args.depthClipEnable = state.rs.depthClipEnable(); - - baseHandle = this->createBaseInstance(key)->handle; - } + // If that didn't succeed, link a pipeline using the + // pre-compiled fragment and vertex shader libraries. + if (!fastHandle) + baseHandle = this->getBasePipeline(state); } else { // Create optimized variant right away, no choice fastHandle = this->createOptimizedPipeline(state, 0); @@ -692,20 +683,6 @@ namespace dxvk { } - DxvkGraphicsPipelineBaseInstance* DxvkGraphicsPipeline::createBaseInstance( - const DxvkGraphicsPipelineBaseInstanceKey& key) { - for (auto& instance : m_basePipelines) { - if (instance.key.viLibrary == key.viLibrary - && instance.key.foLibrary == key.foLibrary - && instance.key.args == key.args) - return &instance; - } - - VkPipeline handle = createBasePipeline(key); - return &(*m_basePipelines.emplace(key, handle)); - } - - bool DxvkGraphicsPipeline::canCreateBasePipeline( const DxvkGraphicsPipelineStateInfo& state) const { if (!m_vsLibrary || !m_fsLibrary) @@ -751,6 +728,26 @@ namespace dxvk { } + VkPipeline DxvkGraphicsPipeline::getBasePipeline( + const DxvkGraphicsPipelineStateInfo& state) { + DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr()); + DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); + + DxvkGraphicsPipelineBaseInstanceKey key; + key.viLibrary = m_manager->createVertexInputLibrary(viState); + key.foLibrary = m_manager->createFragmentOutputLibrary(foState); + key.args.depthClipEnable = state.rs.depthClipEnable(); + + auto entry = m_basePipelines.find(key); + if (entry != m_basePipelines.end()) + return entry->second; + + VkPipeline handle = createBasePipeline(key); + m_basePipelines.insert({ key, handle }); + return handle; + } + + VkPipeline DxvkGraphicsPipeline::createBasePipeline( const DxvkGraphicsPipelineBaseInstanceKey& key) const { auto vk = m_device->vkd(); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index d3593b41a..5238d96f5 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -274,26 +274,23 @@ namespace dxvk { const DxvkGraphicsPipelineVertexInputLibrary* viLibrary = nullptr; const DxvkGraphicsPipelineFragmentOutputLibrary* foLibrary = nullptr; DxvkShaderPipelineLibraryCompileArgs args; + + bool eq(const DxvkGraphicsPipelineBaseInstanceKey& other) const { + return viLibrary == other.viLibrary + && foLibrary == other.foLibrary + && args == other.args; + } + + size_t hash() const { + DxvkHashState hash; + hash.add(size_t(viLibrary)); + hash.add(size_t(foLibrary)); + hash.add(args.hash()); + return hash; + } }; - /** - * \brief Base pipeline instance - * - * Stores the key and handle of a base pipeline. - */ - struct DxvkGraphicsPipelineBaseInstance { - DxvkGraphicsPipelineBaseInstance() { } - DxvkGraphicsPipelineBaseInstance( - const DxvkGraphicsPipelineBaseInstanceKey& key_, - VkPipeline handle_) - : key(key_), handle(handle_) { } - - DxvkGraphicsPipelineBaseInstanceKey key; - VkPipeline handle = VK_NULL_HANDLE; - }; - - /** * \brief Graphics pipeline * @@ -413,7 +410,10 @@ namespace dxvk { alignas(CACHE_LINE_SIZE) dxvk::mutex m_mutex; sync::List m_pipelines; - sync::List m_basePipelines; + + std::unordered_map< + DxvkGraphicsPipelineBaseInstanceKey, + VkPipeline, DxvkHash, DxvkEq> m_basePipelines; DxvkGraphicsPipelineInstance* createInstance( const DxvkGraphicsPipelineStateInfo& state, @@ -422,12 +422,12 @@ namespace dxvk { DxvkGraphicsPipelineInstance* findInstance( const DxvkGraphicsPipelineStateInfo& state); - DxvkGraphicsPipelineBaseInstance* createBaseInstance( - const DxvkGraphicsPipelineBaseInstanceKey& key); - bool canCreateBasePipeline( const DxvkGraphicsPipelineStateInfo& state) const; + VkPipeline getBasePipeline( + const DxvkGraphicsPipelineStateInfo& state); + VkPipeline createBasePipeline( const DxvkGraphicsPipelineBaseInstanceKey& key) const; diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 2def7936b..5a8f327a5 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -329,6 +329,10 @@ namespace dxvk { bool operator != (const DxvkShaderPipelineLibraryCompileArgs& other) const { return !this->operator == (other); } + + size_t hash() const { + return size_t(depthClipEnable); + } }; From 97ab6a313b01e802994710f6973fd9f0dc5a5462 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 23:04:46 +0200 Subject: [PATCH 0346/1348] [dxvk] Make pre-rasterization state usable with lookup tables --- src/dxvk/dxvk_graphics.cpp | 47 ++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_graphics.h | 4 ++++ 2 files changed, 51 insertions(+) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 4d6dc1df2..08f1b5e7b 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -472,6 +472,53 @@ namespace dxvk { } + + bool DxvkGraphicsPipelinePreRasterizationState::eq(const DxvkGraphicsPipelinePreRasterizationState& other) const { + bool eq = tsInfo.patchControlPoints == other.tsInfo.patchControlPoints; + + if (eq) { + eq = rsInfo.depthClampEnable == other.rsInfo.depthClampEnable + && rsInfo.rasterizerDiscardEnable == other.rsInfo.rasterizerDiscardEnable + && rsInfo.polygonMode == other.rsInfo.polygonMode + && rsInfo.depthBiasEnable == other.rsInfo.depthBiasEnable + && rsInfo.lineWidth == other.rsInfo.lineWidth; + } + + if (eq) + eq = rsXfbStreamInfo.rasterizationStream == other.rsXfbStreamInfo.rasterizationStream; + + if (eq) + eq = rsDepthClipInfo.depthClipEnable == other.rsDepthClipInfo.depthClipEnable; + + if (eq) { + eq = rsConservativeInfo.conservativeRasterizationMode == other.rsConservativeInfo.conservativeRasterizationMode + && rsConservativeInfo.extraPrimitiveOverestimationSize == other.rsConservativeInfo.extraPrimitiveOverestimationSize; + } + + return eq; + } + + + size_t DxvkGraphicsPipelinePreRasterizationState::hash() const { + DxvkHashState hash; + hash.add(tsInfo.patchControlPoints); + + hash.add(rsInfo.depthClampEnable); + hash.add(rsInfo.rasterizerDiscardEnable); + hash.add(rsInfo.polygonMode); + hash.add(rsInfo.depthBiasEnable); + hash.add(bit::cast(rsInfo.lineWidth)); + + hash.add(rsXfbStreamInfo.rasterizationStream); + + hash.add(rsDepthClipInfo.depthClipEnable); + + hash.add(rsConservativeInfo.conservativeRasterizationMode); + hash.add(bit::cast(rsConservativeInfo.extraPrimitiveOverestimationSize)); + return hash; + } + + DxvkGraphicsPipelineFragmentShaderState::DxvkGraphicsPipelineFragmentShaderState() { } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 5238d96f5..013fc91c3 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -159,6 +159,10 @@ namespace dxvk { VkPipelineRasterizationDepthClipStateCreateInfoEXT rsDepthClipInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT }; VkPipelineRasterizationStateStreamCreateInfoEXT rsXfbStreamInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT }; VkPipelineRasterizationConservativeStateCreateInfoEXT rsConservativeInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT }; + + bool eq(const DxvkGraphicsPipelinePreRasterizationState& other) const; + + size_t hash() const; }; From 9cb0d6d6103746dccedadfa874154e3193c5f8f3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 23:14:31 +0200 Subject: [PATCH 0347/1348] [dxvk] Make fragment shader state usable with lookup tables --- src/dxvk/dxvk_graphics.cpp | 59 ++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_graphics.h | 4 +++ 2 files changed, 63 insertions(+) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 08f1b5e7b..c79bee70e 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -542,6 +542,65 @@ namespace dxvk { } + bool DxvkGraphicsPipelineFragmentShaderState::eq(const DxvkGraphicsPipelineFragmentShaderState& other) const { + bool eq = dsInfo.depthTestEnable == other.dsInfo.depthTestEnable + && dsInfo.depthBoundsTestEnable == other.dsInfo.depthBoundsTestEnable + && dsInfo.stencilTestEnable == other.dsInfo.stencilTestEnable; + + if (eq && dsInfo.depthTestEnable) { + eq = dsInfo.depthWriteEnable == other.dsInfo.depthWriteEnable + && dsInfo.depthCompareOp == other.dsInfo.depthCompareOp; + } + + if (eq && dsInfo.stencilTestEnable) { + eq = dsInfo.front.failOp == other.dsInfo.front.failOp + && dsInfo.front.passOp == other.dsInfo.front.passOp + && dsInfo.front.depthFailOp == other.dsInfo.front.depthFailOp + && dsInfo.front.compareOp == other.dsInfo.front.compareOp + && dsInfo.front.compareMask == other.dsInfo.front.compareMask + && dsInfo.front.writeMask == other.dsInfo.front.writeMask + && dsInfo.back.failOp == other.dsInfo.back.failOp + && dsInfo.back.passOp == other.dsInfo.back.passOp + && dsInfo.back.depthFailOp == other.dsInfo.back.depthFailOp + && dsInfo.back.compareOp == other.dsInfo.back.compareOp + && dsInfo.back.compareMask == other.dsInfo.back.compareMask + && dsInfo.back.writeMask == other.dsInfo.back.writeMask; + } + + return eq; + } + + + size_t DxvkGraphicsPipelineFragmentShaderState::hash() const { + DxvkHashState hash; + hash.add(dsInfo.depthTestEnable); + hash.add(dsInfo.depthBoundsTestEnable); + hash.add(dsInfo.stencilTestEnable); + + if (dsInfo.depthTestEnable) { + hash.add(dsInfo.depthWriteEnable); + hash.add(dsInfo.depthCompareOp); + } + + if (dsInfo.stencilTestEnable) { + hash.add(dsInfo.front.failOp); + hash.add(dsInfo.front.passOp); + hash.add(dsInfo.front.depthFailOp); + hash.add(dsInfo.front.compareOp); + hash.add(dsInfo.front.compareMask); + hash.add(dsInfo.front.writeMask); + hash.add(dsInfo.back.failOp); + hash.add(dsInfo.back.passOp); + hash.add(dsInfo.back.depthFailOp); + hash.add(dsInfo.back.compareOp); + hash.add(dsInfo.back.compareMask); + hash.add(dsInfo.back.writeMask); + } + + return hash; + } + + DxvkGraphicsPipeline::DxvkGraphicsPipeline( DxvkDevice* device, DxvkPipelineManager* pipeMgr, diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 013fc91c3..58489c016 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -180,6 +180,10 @@ namespace dxvk { const DxvkGraphicsPipelineStateInfo& state); VkPipelineDepthStencilStateCreateInfo dsInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; + + bool eq(const DxvkGraphicsPipelineFragmentShaderState& other) const; + + size_t hash() const; }; From 32c2d91961f74fc119338b0645600460ceb9f262 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 31 Jul 2022 00:01:12 +0200 Subject: [PATCH 0348/1348] [dxvk] Make DxvkShaderModuleCreateInfo usable with lookup tables --- src/dxvk/dxvk_shader.cpp | 31 +++++++++++++++++++++++++++++++ src/dxvk/dxvk_shader.h | 4 ++++ 2 files changed, 35 insertions(+) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index c9e120aba..dc25c61b5 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -10,6 +10,37 @@ namespace dxvk { + bool DxvkShaderModuleCreateInfo::eq(const DxvkShaderModuleCreateInfo& other) const { + bool eq = fsDualSrcBlend == other.fsDualSrcBlend + && undefinedInputs == other.undefinedInputs; + + for (uint32_t i = 0; i < rtSwizzles.size() && eq; i++) { + eq = rtSwizzles[i].r == other.rtSwizzles[i].r + && rtSwizzles[i].g == other.rtSwizzles[i].g + && rtSwizzles[i].b == other.rtSwizzles[i].b + && rtSwizzles[i].a == other.rtSwizzles[i].a; + } + + return eq; + } + + + size_t DxvkShaderModuleCreateInfo::hash() const { + DxvkHashState hash; + hash.add(uint32_t(fsDualSrcBlend)); + hash.add(undefinedInputs); + + for (uint32_t i = 0; i < rtSwizzles.size(); i++) { + hash.add(rtSwizzles[i].r); + hash.add(rtSwizzles[i].g); + hash.add(rtSwizzles[i].b); + hash.add(rtSwizzles[i].a); + } + + return hash; + } + + DxvkShader::DxvkShader( const DxvkShaderCreateInfo& info, SpirvCodeBuffer&& spirv) diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 5a8f327a5..e0eec2e0f 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -66,6 +66,10 @@ namespace dxvk { uint32_t undefinedInputs = 0; std::array rtSwizzles = { }; + + bool eq(const DxvkShaderModuleCreateInfo& other) const; + + size_t hash() const; }; From 30fa9df868bb90808bbd5b6708f0822f82f66891 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 23:38:22 +0200 Subject: [PATCH 0349/1348] [dxvk] Introduce DxvkGraphicsPipelineSpecConstantState --- src/dxvk/dxvk_compute.cpp | 16 ++---- src/dxvk/dxvk_graphics.cpp | 99 +++++++++++++++++++++++++++++--------- src/dxvk/dxvk_graphics.h | 29 ++++++++++- 3 files changed, 106 insertions(+), 38 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 02249771e..d475ace8a 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -4,6 +4,7 @@ #include "dxvk_compute.h" #include "dxvk_device.h" +#include "dxvk_graphics.h" #include "dxvk_pipemanager.h" #include "dxvk_spec_const.h" #include "dxvk_state_cache.h" @@ -106,23 +107,12 @@ namespace dxvk { Logger::debug(str::format(" cs : ", m_shaders.cs->debugName())); } - uint32_t specConstantMask = m_shaders.cs->getSpecConstantMask(); - DxvkSpecConstants specData; - - for (uint32_t i = 0; i < MaxNumSpecConstants; i++) { - if (specConstantMask & (1u << i)) - specData.set(i, state.sc.specConstants[i], 0u); - } - - if (specConstantMask & (1u << MaxNumSpecConstants)) - specData.set(MaxNumSpecConstants, 1u, 0u); - - VkSpecializationInfo specInfo = specData.getSpecInfo(); + DxvkPipelineSpecConstantState scState(m_shaders.cs->getSpecConstantMask(), state.sc); DxvkShaderStageInfo stageInfo(m_device); stageInfo.addStage(VK_SHADER_STAGE_COMPUTE_BIT, m_shaders.cs->getCode(m_bindings, DxvkShaderModuleCreateInfo()), - &specInfo); + &scState.scInfo); VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; info.stage = *stageInfo.getStageInfos(); diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index c79bee70e..6ab86914f 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -601,6 +601,68 @@ namespace dxvk { } + DxvkPipelineSpecConstantState::DxvkPipelineSpecConstantState() { + + } + + + DxvkPipelineSpecConstantState::DxvkPipelineSpecConstantState( + uint32_t mask, + const DxvkScInfo& state) { + for (uint32_t i = 0; i < MaxNumSpecConstants; i++) { + if (mask & (1u << i)) + addConstant(i, state.specConstants[i]); + } + + if (mask & (1u << MaxNumSpecConstants)) + addConstant(MaxNumSpecConstants, VK_TRUE); + + if (scInfo.mapEntryCount) { + scInfo.pMapEntries = scConstantMap.data(); + scInfo.dataSize = scInfo.mapEntryCount * sizeof(uint32_t); + scInfo.pData = scConstantData.data(); + } + } + + + bool DxvkPipelineSpecConstantState::eq(const DxvkPipelineSpecConstantState& other) const { + bool eq = scInfo.mapEntryCount == other.scInfo.mapEntryCount; + + for (uint32_t i = 0; i < scInfo.mapEntryCount && eq; i++) { + eq = scConstantMap[i].constantID == other.scConstantMap[i].constantID + && scConstantData[i] == other.scConstantData[i]; + } + + return eq; + } + + + size_t DxvkPipelineSpecConstantState::hash() const { + DxvkHashState hash; + hash.add(scInfo.mapEntryCount); + + for (uint32_t i = 0; i < scInfo.mapEntryCount; i++) { + hash.add(scConstantMap[i].constantID); + hash.add(scConstantData[i]); + } + + return hash; + } + + + void DxvkPipelineSpecConstantState::addConstant(uint32_t id, uint32_t value) { + if (value) { + uint32_t index = scInfo.mapEntryCount++; + + scConstantMap[index].constantID = id; + scConstantMap[index].offset = sizeof(uint32_t) * index; + scConstantMap[index].size = sizeof(uint32_t); + + scConstantData[index] = value; + } + } + + DxvkGraphicsPipeline::DxvkGraphicsPipeline( DxvkDevice* device, DxvkPipelineManager* pipeMgr, @@ -915,45 +977,34 @@ namespace dxvk { dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_FRONT_FACE; } - // Set up some specialization constants - DxvkSpecConstants specData; - - for (uint32_t i = 0; i < MaxNumSpecConstants; i++) { - if (m_specConstantMask & (1u << i)) - specData.set(i, state.sc.specConstants[i], 0u); - } - - if (m_specConstantMask & (1u << MaxNumSpecConstants)) - specData.set(MaxNumSpecConstants, 1u, 0u); - - VkSpecializationInfo specInfo = specData.getSpecInfo(); + // Set up pipeline state + DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr()); + DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr()); + DxvkGraphicsPipelineFragmentShaderState fsState(m_device, state); + DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); + DxvkPipelineSpecConstantState scState(m_specConstantMask, state.sc); // Build stage infos for all provided shaders DxvkShaderStageInfo stageInfo(m_device); if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) { - stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, m_vsLibrary->getModuleIdentifier(), &specInfo); + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, m_vsLibrary->getModuleIdentifier(), &scState.scInfo); if (m_shaders.fs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, m_fsLibrary->getModuleIdentifier(), &specInfo); + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, m_fsLibrary->getModuleIdentifier(), &scState.scInfo); } else { - stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, state), &specInfo); + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, state), &scState.scInfo); if (m_shaders.tcs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, state), &specInfo); + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, state), &scState.scInfo); if (m_shaders.tes != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, state), &specInfo); + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, state), &scState.scInfo); if (m_shaders.gs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, state), &specInfo); + stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, state), &scState.scInfo); if (m_shaders.fs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, state), &specInfo); + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, state), &scState.scInfo); } - DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr()); - DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr()); - DxvkGraphicsPipelineFragmentShaderState fsState(m_device, state); - DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); - VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; dyInfo.dynamicStateCount = dynamicStateCount; dyInfo.pDynamicStates = dynamicStates.data(); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 58489c016..614633c81 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -186,7 +186,34 @@ namespace dxvk { size_t hash() const; }; - + + /** + * \brief Specialization constant state for pipelines + * + * Can only be used when all pipeline state is known. + */ + struct DxvkPipelineSpecConstantState { + DxvkPipelineSpecConstantState(); + + DxvkPipelineSpecConstantState( + uint32_t mask, + const DxvkScInfo& state); + + VkSpecializationInfo scInfo = { }; + std::array scConstantMap = { }; + std::array scConstantData = { }; + + bool eq(const DxvkPipelineSpecConstantState& other) const; + + size_t hash() const; + + private: + + void addConstant(uint32_t id, uint32_t value); + + }; + + /** * \brief Flags that describe pipeline properties */ From 63420c0cd7f2533f204b6f6b0632f2dac7ef6c8d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 31 Jul 2022 00:24:16 +0200 Subject: [PATCH 0350/1348] [dxvk] Introduce DxvkGraphicsPipelineShaderState And factor out a bunch of related code. --- src/dxvk/dxvk_graphics.cpp | 193 ++++++++++++++++++++------------- src/dxvk/dxvk_graphics.h | 47 ++++++-- src/dxvk/dxvk_graphics_state.h | 10 ++ 3 files changed, 164 insertions(+), 86 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 6ab86914f..9fb31ab7f 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -601,6 +601,112 @@ namespace dxvk { } + DxvkGraphicsPipelineShaderState::DxvkGraphicsPipelineShaderState() { + + } + + + DxvkGraphicsPipelineShaderState::DxvkGraphicsPipelineShaderState( + const DxvkGraphicsPipelineShaders& shaders, + const DxvkGraphicsPipelineStateInfo& state) + : vsInfo (getCreateInfo(shaders, shaders.vs, state)), + tcsInfo (getCreateInfo(shaders, shaders.tcs, state)), + tesInfo (getCreateInfo(shaders, shaders.tes, state)), + gsInfo (getCreateInfo(shaders, shaders.gs, state)), + fsInfo (getCreateInfo(shaders, shaders.fs, state)) { + + } + + + bool DxvkGraphicsPipelineShaderState::eq(const DxvkGraphicsPipelineShaderState& other) const { + return vsInfo.eq(other.vsInfo) + && tcsInfo.eq(other.tcsInfo) + && tesInfo.eq(other.tesInfo) + && gsInfo.eq(other.gsInfo) + && fsInfo.eq(other.fsInfo); + } + + + size_t DxvkGraphicsPipelineShaderState::hash() const { + DxvkHashState hash; + hash.add(vsInfo.hash()); + hash.add(tcsInfo.hash()); + hash.add(tesInfo.hash()); + hash.add(gsInfo.hash()); + hash.add(fsInfo.hash()); + return hash; + } + + + DxvkShaderModuleCreateInfo DxvkGraphicsPipelineShaderState::getCreateInfo( + const DxvkGraphicsPipelineShaders& shaders, + const Rc& shader, + const DxvkGraphicsPipelineStateInfo& state) { + DxvkShaderModuleCreateInfo info; + + if (shader == nullptr) + return info; + + // Fix up fragment shader outputs for dual-source blending + const DxvkShaderCreateInfo& shaderInfo = shader->info(); + + if (shaderInfo.stage == VK_SHADER_STAGE_FRAGMENT_BIT) { + info.fsDualSrcBlend = state.useDualSourceBlending(); + + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + if ((shaderInfo.outputMask & (1u << i)) && state.writesRenderTarget(i)) + info.rtSwizzles[i] = state.omSwizzle[i].mapping(); + } + } + + // Deal with undefined shader inputs + uint32_t consumedInputs = shaderInfo.inputMask; + uint32_t providedInputs = 0; + + if (shaderInfo.stage == VK_SHADER_STAGE_VERTEX_BIT) { + for (uint32_t i = 0; i < state.il.attributeCount(); i++) + providedInputs |= 1u << state.ilAttributes[i].location(); + } else if (shaderInfo.stage != VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) { + auto prevStage = getPrevStageShader(shaders, shaderInfo.stage); + providedInputs = prevStage->info().outputMask; + } else { + // Technically not correct, but this + // would need a lot of extra care + providedInputs = consumedInputs; + } + + info.undefinedInputs = (providedInputs & consumedInputs) ^ consumedInputs; + return info; + } + + + Rc DxvkGraphicsPipelineShaderState::getPrevStageShader( + const DxvkGraphicsPipelineShaders& shaders, + const VkShaderStageFlagBits stage) { + if (stage == VK_SHADER_STAGE_VERTEX_BIT) + return nullptr; + + if (stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) + return shaders.tcs; + + Rc result = shaders.vs; + + if (stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) + return result; + + if (shaders.tes != nullptr) + result = shaders.tes; + + if (stage == VK_SHADER_STAGE_GEOMETRY_BIT) + return result; + + if (shaders.gs != nullptr) + result = shaders.gs; + + return result; + } + + DxvkPipelineSpecConstantState::DxvkPipelineSpecConstantState() { } @@ -888,7 +994,8 @@ namespace dxvk { // Remapping fragment shader outputs would require spec constants for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (writesRenderTarget(state, i) && !util::isIdentityMapping(state.omSwizzle[i].mapping())) + if ((m_fsOut & (1u << i)) && state.writesRenderTarget(i) + && !util::isIdentityMapping(state.omSwizzle[i].mapping())) return false; } @@ -978,6 +1085,7 @@ namespace dxvk { } // Set up pipeline state + DxvkGraphicsPipelineShaderState shState(m_shaders, state); DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr()); DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr()); DxvkGraphicsPipelineFragmentShaderState fsState(m_device, state); @@ -993,16 +1101,16 @@ namespace dxvk { if (m_shaders.fs != nullptr) stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, m_fsLibrary->getModuleIdentifier(), &scState.scInfo); } else { - stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, state), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, shState.vsInfo), &scState.scInfo); if (m_shaders.tcs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, state), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, shState.tcsInfo), &scState.scInfo); if (m_shaders.tes != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, state), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, shState.tesInfo), &scState.scInfo); if (m_shaders.gs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, state), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, shState.gsInfo), &scState.scInfo); if (m_shaders.fs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, state), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, shState.fsInfo), &scState.scInfo); } VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; @@ -1053,82 +1161,11 @@ namespace dxvk { SpirvCodeBuffer DxvkGraphicsPipeline::getShaderCode( const Rc& shader, - const DxvkGraphicsPipelineStateInfo& state) const { - auto vk = m_device->vkd(); - - const DxvkShaderCreateInfo& shaderInfo = shader->info(); - DxvkShaderModuleCreateInfo info; - - // Fix up fragment shader outputs for dual-source blending - if (shaderInfo.stage == VK_SHADER_STAGE_FRAGMENT_BIT) { - info.fsDualSrcBlend = state.useDualSourceBlending(); - - for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { - if (writesRenderTarget(state, i)) - info.rtSwizzles[i] = state.omSwizzle[i].mapping(); - } - } - - // Deal with undefined shader inputs - uint32_t consumedInputs = shaderInfo.inputMask; - uint32_t providedInputs = 0; - - if (shaderInfo.stage == VK_SHADER_STAGE_VERTEX_BIT) { - for (uint32_t i = 0; i < state.il.attributeCount(); i++) - providedInputs |= 1u << state.ilAttributes[i].location(); - } else if (shaderInfo.stage != VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) { - auto prevStage = getPrevStageShader(shaderInfo.stage); - providedInputs = prevStage->info().outputMask; - } else { - // Technically not correct, but this - // would need a lot of extra care - providedInputs = consumedInputs; - } - - info.undefinedInputs = (providedInputs & consumedInputs) ^ consumedInputs; + const DxvkShaderModuleCreateInfo& info) const { return shader->getCode(m_bindings, info); } - Rc DxvkGraphicsPipeline::getPrevStageShader(VkShaderStageFlagBits stage) const { - if (stage == VK_SHADER_STAGE_VERTEX_BIT) - return nullptr; - - if (stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) - return m_shaders.tcs; - - Rc result = m_shaders.vs; - - if (stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) - return result; - - if (m_shaders.tes != nullptr) - result = m_shaders.tes; - - if (stage == VK_SHADER_STAGE_GEOMETRY_BIT) - return result; - - if (m_shaders.gs != nullptr) - result = m_shaders.gs; - - return result; - } - - - bool DxvkGraphicsPipeline::writesRenderTarget( - const DxvkGraphicsPipelineStateInfo& state, - uint32_t target) const { - if (!(m_fsOut & (1u << target))) - return false; - - if (!state.omBlend[target].colorWriteMask()) - return false; - - VkFormat rtFormat = state.rt.getColorFormat(target); - return rtFormat != VK_FORMAT_UNDEFINED; - } - - uint32_t DxvkGraphicsPipeline::computeSpecConstantMask() const { uint32_t mask = m_shaders.vs->getSpecConstantMask(); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 614633c81..11f033b30 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -19,6 +19,8 @@ namespace dxvk { class DxvkStateCache; class DxvkPipelineManager; class DxvkPipelineWorkers; + + struct DxvkGraphicsPipelineShaders; struct DxvkPipelineStats; /** @@ -187,6 +189,42 @@ namespace dxvk { }; + /** + * \brief Shader create info state for graphics pipelines + * + * Can only be used when all pipeline state is known. + */ + struct DxvkGraphicsPipelineShaderState { + DxvkGraphicsPipelineShaderState(); + + DxvkGraphicsPipelineShaderState( + const DxvkGraphicsPipelineShaders& shaders, + const DxvkGraphicsPipelineStateInfo& state); + + DxvkShaderModuleCreateInfo vsInfo; + DxvkShaderModuleCreateInfo tcsInfo; + DxvkShaderModuleCreateInfo tesInfo; + DxvkShaderModuleCreateInfo gsInfo; + DxvkShaderModuleCreateInfo fsInfo; + + bool eq(const DxvkGraphicsPipelineShaderState& other) const; + + size_t hash() const; + + private: + + DxvkShaderModuleCreateInfo getCreateInfo( + const DxvkGraphicsPipelineShaders& shaders, + const Rc& shader, + const DxvkGraphicsPipelineStateInfo& state); + + Rc getPrevStageShader( + const DxvkGraphicsPipelineShaders& shaders, + const VkShaderStageFlagBits stage); + + }; + + /** * \brief Specialization constant state for pipelines * @@ -475,15 +513,8 @@ namespace dxvk { SpirvCodeBuffer getShaderCode( const Rc& shader, - const DxvkGraphicsPipelineStateInfo& state) const; + const DxvkShaderModuleCreateInfo& info) const; - Rc getPrevStageShader( - VkShaderStageFlagBits stage) const; - - bool writesRenderTarget( - const DxvkGraphicsPipelineStateInfo& state, - uint32_t target) const; - uint32_t computeSpecConstantMask() const; bool validatePipelineState( diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 133e0d68a..49f081a35 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -769,6 +769,16 @@ namespace dxvk { util::isDualSourceBlendFactor(omBlend[0].dstAlphaBlendFactor())); } + bool writesRenderTarget( + uint32_t target) const { + if (!omBlend[target].colorWriteMask()) + return false; + + VkFormat rtFormat = rt.getColorFormat(target); + return rtFormat != VK_FORMAT_UNDEFINED; + } + + DxvkIaInfo ia; DxvkIlInfo il; DxvkRsInfo rs; From b2969f628f7b42f29555da7eb30cd7a31c5c9b1f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 31 Jul 2022 00:33:29 +0200 Subject: [PATCH 0351/1348] [dxvk] Introduce DxvkGraphicsPipelineDynamicState --- src/dxvk/dxvk_graphics.cpp | 92 +++++++++++++++++++++++++------------- src/dxvk/dxvk_graphics.h | 45 ++++++++++++++----- 2 files changed, 93 insertions(+), 44 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 9fb31ab7f..cd7e8e101 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -601,6 +601,64 @@ namespace dxvk { } + DxvkGraphicsPipelineDynamicState::DxvkGraphicsPipelineDynamicState() { + + } + + + DxvkGraphicsPipelineDynamicState::DxvkGraphicsPipelineDynamicState( + const DxvkDevice* device, + const DxvkGraphicsPipelineStateInfo& state, + DxvkGraphicsPipelineFlags flags) { + dyStates[dyInfo.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT; + dyStates[dyInfo.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT; + + if (state.useDynamicVertexStrides()) + dyStates[dyInfo.dynamicStateCount++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE; + + if (state.useDynamicDepthBias()) + dyStates[dyInfo.dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS; + + if (state.useDynamicDepthBounds()) + dyStates[dyInfo.dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS; + + if (state.useDynamicBlendConstants()) + dyStates[dyInfo.dynamicStateCount++] = VK_DYNAMIC_STATE_BLEND_CONSTANTS; + + if (state.useDynamicStencilRef()) + dyStates[dyInfo.dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; + + if (!flags.test(DxvkGraphicsPipelineFlag::HasRasterizerDiscard)) { + dyStates[dyInfo.dynamicStateCount++] = VK_DYNAMIC_STATE_CULL_MODE; + dyStates[dyInfo.dynamicStateCount++] = VK_DYNAMIC_STATE_FRONT_FACE; + } + + if (dyInfo.dynamicStateCount) + dyInfo.pDynamicStates = dyStates.data(); + } + + + bool DxvkGraphicsPipelineDynamicState::eq(const DxvkGraphicsPipelineDynamicState& other) const { + bool eq = dyInfo.dynamicStateCount == other.dyInfo.dynamicStateCount; + + for (uint32_t i = 0; i < dyInfo.dynamicStateCount && eq; i++) + eq = dyStates[i] == other.dyStates[i]; + + return eq; + } + + + size_t DxvkGraphicsPipelineDynamicState::hash() const { + DxvkHashState hash; + hash.add(dyInfo.dynamicStateCount); + + for (uint32_t i = 0; i < dyInfo.dynamicStateCount; i++) + hash.add(dyStates[i]); + + return hash; + } + + DxvkGraphicsPipelineShaderState::DxvkGraphicsPipelineShaderState() { } @@ -1057,35 +1115,9 @@ namespace dxvk { VkPipelineCreateFlags flags) const { auto vk = m_device->vkd(); - // Set up dynamic states as needed - std::array dynamicStates; - uint32_t dynamicStateCount = 0; - - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT; - - if (state.useDynamicVertexStrides()) - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE; - - if (state.useDynamicDepthBias()) - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS; - - if (state.useDynamicDepthBounds()) - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS; - - if (state.useDynamicBlendConstants()) - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_BLEND_CONSTANTS; - - if (state.useDynamicStencilRef()) - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_STENCIL_REFERENCE; - - if (!m_flags.test(DxvkGraphicsPipelineFlag::HasRasterizerDiscard)) { - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_CULL_MODE; - dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_FRONT_FACE; - } - // Set up pipeline state DxvkGraphicsPipelineShaderState shState(m_shaders, state); + DxvkGraphicsPipelineDynamicState dyState(m_device, state, m_flags); DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr()); DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr()); DxvkGraphicsPipelineFragmentShaderState fsState(m_device, state); @@ -1113,10 +1145,6 @@ namespace dxvk { stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, shState.fsInfo), &scState.scInfo); } - VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; - dyInfo.dynamicStateCount = dynamicStateCount; - dyInfo.pDynamicStates = dynamicStates.data(); - VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &foState.rtInfo }; info.flags = flags; info.stageCount = stageInfo.getStageCount(); @@ -1129,7 +1157,7 @@ namespace dxvk { info.pMultisampleState = &foState.msInfo; info.pDepthStencilState = &fsState.dsInfo; info.pColorBlendState = &foState.cbInfo; - info.pDynamicState = &dyInfo; + info.pDynamicState = &dyState.dyInfo; info.layout = m_bindings->getPipelineLayout(false); info.basePipelineIndex = -1; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 11f033b30..31a130495 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -23,6 +23,18 @@ namespace dxvk { struct DxvkGraphicsPipelineShaders; struct DxvkPipelineStats; + /** + * \brief Flags that describe pipeline properties + */ + enum class DxvkGraphicsPipelineFlag { + HasRasterizerDiscard, + HasTransformFeedback, + HasStorageDescriptors, + }; + + using DxvkGraphicsPipelineFlags = Flags; + + /** * \brief Vertex input info for graphics pipelines * @@ -189,6 +201,27 @@ namespace dxvk { }; + /** + * \brief Dynamic state for graphics pipelines + * + */ + struct DxvkGraphicsPipelineDynamicState { + DxvkGraphicsPipelineDynamicState(); + + DxvkGraphicsPipelineDynamicState( + const DxvkDevice* device, + const DxvkGraphicsPipelineStateInfo& state, + DxvkGraphicsPipelineFlags flags); + + VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + std::array dyStates = { }; + + bool eq(const DxvkGraphicsPipelineDynamicState& other) const; + + size_t hash() const; + }; + + /** * \brief Shader create info state for graphics pipelines * @@ -252,18 +285,6 @@ namespace dxvk { }; - /** - * \brief Flags that describe pipeline properties - */ - enum class DxvkGraphicsPipelineFlag { - HasRasterizerDiscard, - HasTransformFeedback, - HasStorageDescriptors, - }; - - using DxvkGraphicsPipelineFlags = Flags; - - /** * \brief Shaders used in graphics pipelines */ From db786cda6c3dd5cb49f4432365c6ac47ff0465c5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 30 Jul 2022 23:45:24 +0200 Subject: [PATCH 0352/1348] [dxvk] Remove old code to process specialization constants We barely use spec constants anymore, so a much simpler solution will do. --- src/d3d9/d3d9_fixed_function.cpp | 1 - src/dxso/dxso_compiler.cpp | 2 - src/dxvk/dxvk_compute.cpp | 1 - src/dxvk/dxvk_graphics.cpp | 1 - src/dxvk/dxvk_spec_const.cpp | 36 --------------- src/dxvk/dxvk_spec_const.h | 78 -------------------------------- src/dxvk/meson.build | 1 - 7 files changed, 120 deletions(-) delete mode 100644 src/dxvk/dxvk_spec_const.cpp delete mode 100644 src/dxvk/dxvk_spec_const.h diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 6ac190b3b..0fc845f75 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -5,7 +5,6 @@ #include "d3d9_spec_constants.h" #include "../dxvk/dxvk_hash.h" -#include "../dxvk/dxvk_spec_const.h" #include "../spirv/spirv_module.h" diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 69f77e5b0..357eccf74 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -9,8 +9,6 @@ #include "../d3d9/d3d9_fixed_function.h" #include "dxso_util.h" -#include "../dxvk/dxvk_spec_const.h" - #include namespace dxvk { diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index d475ace8a..448408dcb 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -6,7 +6,6 @@ #include "dxvk_device.h" #include "dxvk_graphics.h" #include "dxvk_pipemanager.h" -#include "dxvk_spec_const.h" #include "dxvk_state_cache.h" namespace dxvk { diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index cd7e8e101..fe653264b 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -5,7 +5,6 @@ #include "dxvk_device.h" #include "dxvk_graphics.h" #include "dxvk_pipemanager.h" -#include "dxvk_spec_const.h" #include "dxvk_state_cache.h" namespace dxvk { diff --git a/src/dxvk/dxvk_spec_const.cpp b/src/dxvk/dxvk_spec_const.cpp deleted file mode 100644 index eec6d8ae5..000000000 --- a/src/dxvk/dxvk_spec_const.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "dxvk_spec_const.h" - -namespace dxvk { - - DxvkSpecConstants::DxvkSpecConstants() { - - } - - - DxvkSpecConstants::~DxvkSpecConstants() { - - } - - - VkSpecializationInfo DxvkSpecConstants::getSpecInfo() const { - VkSpecializationInfo specInfo; - specInfo.mapEntryCount = m_map.size(); - specInfo.pMapEntries = m_map.data(); - specInfo.dataSize = m_data.size() * sizeof(uint32_t); - specInfo.pData = m_data.data(); - return specInfo; - } - - - void DxvkSpecConstants::setAsUint32(uint32_t specId, uint32_t value) { - uint32_t index = m_data.size(); - m_data.push_back(value); - - VkSpecializationMapEntry mapEntry; - mapEntry.constantID = specId; - mapEntry.offset = sizeof(uint32_t) * index; - mapEntry.size = sizeof(uint32_t); - m_map.push_back(mapEntry); - } - -} \ No newline at end of file diff --git a/src/dxvk/dxvk_spec_const.h b/src/dxvk/dxvk_spec_const.h deleted file mode 100644 index 3e5ec4abe..000000000 --- a/src/dxvk/dxvk_spec_const.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include "dxvk_limits.h" -#include "dxvk_shader.h" - -namespace dxvk { - - /** - * \briefS Specialization constant entry - * - * Used to pass a list of user-defined - * specialization constants to shaders. - */ - struct DxvkSpecConstant { - uint32_t specId; - uint32_t value; - }; - - - /** - * \brief Specialization constant info - * - * Accumulates specialization constant data for - * constants that use non-default values. - */ - class DxvkSpecConstants { - - public: - - DxvkSpecConstants(); - - ~DxvkSpecConstants(); - - /** - * \brief Sets specialization constant value - * - * If the given value is different from the constant's - * default value, this will store the new value and add - * a map entry so that it gets applied properly. Each - * constant may only be set once. - * \param [in] specId Specialization constant ID - * \param [in] value Specialization constant value - * \param [in] defaultValue Default value - */ - template - void set(uint32_t specId, T value, T defaultValue) { - if (value != defaultValue) - setAsUint32(specId, uint32_t(value)); - } - - /** - * \brief Sets specialization constant value - * - * Always passes the constant value to the driver. - * \param [in] specId Specialization constant ID - * \param [in] value Specialization constant value - */ - template - void set(uint32_t specId, T value) { - setAsUint32(specId, uint32_t(value)); - } - - /** - * \brief Generates specialization info structure - * \returns Specialization info for shader module - */ - VkSpecializationInfo getSpecInfo() const; - - private: - - std::vector m_data = { }; - std::vector m_map = { }; - - void setAsUint32(uint32_t specId, uint32_t value); - - }; - -} \ No newline at end of file diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 93ebb1d3c..b0463108c 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -100,7 +100,6 @@ dxvk_src = files([ 'dxvk_shader.cpp', 'dxvk_shader_key.cpp', 'dxvk_signal.cpp', - 'dxvk_spec_const.cpp', 'dxvk_staging.cpp', 'dxvk_state_cache.cpp', 'dxvk_stats.cpp', From 00eaec1619ca734ad76a802339d89df187f8a487 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 31 Jul 2022 00:59:08 +0200 Subject: [PATCH 0353/1348] [dxvk] Use normalized state to look up optimized graphics pipelines We can't normalize all state at the time it is bound, e.g. disabling unused blend state before render targets are known. By looking up pipelines using normalized state we ensure that our VkPipelines are actually unique. Based on my testing this only affects a small number of pipelines in most games (anywhere from 0 to a couple dozen), with some outliers like The Witcher 1, where a third of the pipelines are redundant due to stale render state. --- src/dxvk/dxvk_graphics.cpp | 83 ++++++++++++++++++++++---------------- src/dxvk/dxvk_graphics.h | 70 ++++++++++++++++++++++++++++++-- 2 files changed, 116 insertions(+), 37 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index fe653264b..86633ba1a 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -868,8 +868,8 @@ namespace dxvk { DxvkGraphicsPipeline::~DxvkGraphicsPipeline() { - for (const auto& instance : m_pipelines) - this->destroyPipeline(instance.fastHandle.load()); + for (const auto& instance : m_fastPipelines) + this->destroyPipeline(instance.second); for (const auto& instance : m_basePipelines) this->destroyPipeline(instance.second); @@ -962,7 +962,7 @@ namespace dxvk { || instance->isCompiling.exchange(VK_TRUE, std::memory_order_acquire)) return; - VkPipeline pipeline = this->createOptimizedPipeline(state, 0); + VkPipeline pipeline = this->getOptimizedPipeline(state, 0); instance->fastHandle.store(pipeline, std::memory_order_release); // Log pipeline state on error @@ -981,7 +981,7 @@ namespace dxvk { // Try to create an optimized pipeline from the cache // first, since this is expected to be the fastest path. if (m_device->canUsePipelineCacheControl()) { - fastHandle = this->createOptimizedPipeline(state, + fastHandle = this->getOptimizedPipeline(state, VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT); } @@ -991,7 +991,7 @@ namespace dxvk { baseHandle = this->getBasePipeline(state); } else { // Create optimized variant right away, no choice - fastHandle = this->createOptimizedPipeline(state, 0); + fastHandle = this->getOptimizedPipeline(state, 0); } // Log pipeline state if requested, or on failure @@ -1108,59 +1108,74 @@ namespace dxvk { return pipeline; } - - VkPipeline DxvkGraphicsPipeline::createOptimizedPipeline( + + VkPipeline DxvkGraphicsPipeline::getOptimizedPipeline( const DxvkGraphicsPipelineStateInfo& state, + VkPipelineCreateFlags flags) { + DxvkGraphicsPipelineFastInstanceKey key(m_device, + m_shaders, state, m_flags, m_specConstantMask); + + std::lock_guard lock(m_fastMutex); + + auto entry = m_fastPipelines.find(key); + if (entry != m_fastPipelines.end()) + return entry->second; + + // Keep pipeline locked to prevent multiple threads from compiling + // identical Vulkan pipelines. This should be rare, but has been + // buggy on some drivers in the past, so just don't allow it. + VkPipeline handle = createOptimizedPipeline(key, flags); + + if (handle) + m_fastPipelines.insert({ key, handle }); + + return handle; + } + + + VkPipeline DxvkGraphicsPipeline::createOptimizedPipeline( + const DxvkGraphicsPipelineFastInstanceKey& key, VkPipelineCreateFlags flags) const { auto vk = m_device->vkd(); - // Set up pipeline state - DxvkGraphicsPipelineShaderState shState(m_shaders, state); - DxvkGraphicsPipelineDynamicState dyState(m_device, state, m_flags); - DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr()); - DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr()); - DxvkGraphicsPipelineFragmentShaderState fsState(m_device, state); - DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr()); - DxvkPipelineSpecConstantState scState(m_specConstantMask, state.sc); - // Build stage infos for all provided shaders DxvkShaderStageInfo stageInfo(m_device); if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) { - stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, m_vsLibrary->getModuleIdentifier(), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, m_vsLibrary->getModuleIdentifier(), &key.scState.scInfo); if (m_shaders.fs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, m_fsLibrary->getModuleIdentifier(), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, m_fsLibrary->getModuleIdentifier(), &key.scState.scInfo); } else { - stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, shState.vsInfo), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, key.shState.vsInfo), &key.scState.scInfo); if (m_shaders.tcs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, shState.tcsInfo), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, key.shState.tcsInfo), &key.scState.scInfo); if (m_shaders.tes != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, shState.tesInfo), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, key.shState.tesInfo), &key.scState.scInfo); if (m_shaders.gs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, shState.gsInfo), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, key.shState.gsInfo), &key.scState.scInfo); if (m_shaders.fs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, shState.fsInfo), &scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, key.shState.fsInfo), &key.scState.scInfo); } - VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &foState.rtInfo }; + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &key.foState.rtInfo }; info.flags = flags; info.stageCount = stageInfo.getStageCount(); info.pStages = stageInfo.getStageInfos(); - info.pVertexInputState = &viState.viInfo; - info.pInputAssemblyState = &viState.iaInfo; - info.pTessellationState = &prState.tsInfo; - info.pViewportState = &prState.vpInfo; - info.pRasterizationState = &prState.rsInfo; - info.pMultisampleState = &foState.msInfo; - info.pDepthStencilState = &fsState.dsInfo; - info.pColorBlendState = &foState.cbInfo; - info.pDynamicState = &dyState.dyInfo; + info.pVertexInputState = &key.viState.viInfo; + info.pInputAssemblyState = &key.viState.iaInfo; + info.pTessellationState = &key.prState.tsInfo; + info.pViewportState = &key.prState.vpInfo; + info.pRasterizationState = &key.prState.rsInfo; + info.pMultisampleState = &key.foState.msInfo; + info.pDepthStencilState = &key.fsState.dsInfo; + info.pColorBlendState = &key.foState.cbInfo; + info.pDynamicState = &key.dyState.dyInfo; info.layout = m_bindings->getPipelineLayout(false); info.basePipelineIndex = -1; - if (!prState.tsInfo.patchControlPoints) + if (!key.prState.tsInfo.patchControlPoints) info.pTessellationState = nullptr; VkPipeline pipeline = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 31a130495..a0c0bfbaa 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -385,6 +385,61 @@ namespace dxvk { }; + /** + * \brief Fast instance key + * + * Stores pipeline state used to compile an + * optimized pipeline. + */ + struct DxvkGraphicsPipelineFastInstanceKey { + DxvkGraphicsPipelineFastInstanceKey() { } + + DxvkGraphicsPipelineFastInstanceKey( + DxvkDevice* device, + const DxvkGraphicsPipelineShaders& shaders, + const DxvkGraphicsPipelineStateInfo& state, + DxvkGraphicsPipelineFlags flags, + uint32_t specConstantMask) + : shState(shaders, state), + dyState(device, state, flags), + viState(device, state, shaders.vs.ptr()), + prState(device, state, shaders.gs.ptr()), + fsState(device, state), + foState(device, state, shaders.fs.ptr()), + scState(specConstantMask, state.sc) { } + + DxvkGraphicsPipelineShaderState shState; + DxvkGraphicsPipelineDynamicState dyState; + DxvkGraphicsPipelineVertexInputState viState; + DxvkGraphicsPipelinePreRasterizationState prState; + DxvkGraphicsPipelineFragmentShaderState fsState; + DxvkGraphicsPipelineFragmentOutputState foState; + DxvkPipelineSpecConstantState scState; + + bool eq(const DxvkGraphicsPipelineFastInstanceKey& other) const { + return shState.eq(other.shState) + && dyState.eq(other.dyState) + && viState.eq(other.viState) + && prState.eq(other.prState) + && fsState.eq(other.fsState) + && foState.eq(other.foState) + && scState.eq(other.scState); + } + + size_t hash() const { + DxvkHashState hash; + hash.add(shState.hash()); + hash.add(dyState.hash()); + hash.add(viState.hash()); + hash.add(prState.hash()); + hash.add(fsState.hash()); + hash.add(foState.hash()); + hash.add(scState.hash()); + return hash; + } + }; + + /** * \brief Graphics pipeline * @@ -500,7 +555,6 @@ namespace dxvk { uint32_t m_specConstantMask = 0; - // List of pipeline instances, shared between threads alignas(CACHE_LINE_SIZE) dxvk::mutex m_mutex; sync::List m_pipelines; @@ -509,6 +563,12 @@ namespace dxvk { DxvkGraphicsPipelineBaseInstanceKey, VkPipeline, DxvkHash, DxvkEq> m_basePipelines; + alignas(CACHE_LINE_SIZE) + dxvk::mutex m_fastMutex; + std::unordered_map< + DxvkGraphicsPipelineFastInstanceKey, + VkPipeline, DxvkHash, DxvkEq> m_fastPipelines; + DxvkGraphicsPipelineInstance* createInstance( const DxvkGraphicsPipelineStateInfo& state, bool doCreateBasePipeline); @@ -525,10 +585,14 @@ namespace dxvk { VkPipeline createBasePipeline( const DxvkGraphicsPipelineBaseInstanceKey& key) const; - VkPipeline createOptimizedPipeline( + VkPipeline getOptimizedPipeline( const DxvkGraphicsPipelineStateInfo& state, + VkPipelineCreateFlags flags); + + VkPipeline createOptimizedPipeline( + const DxvkGraphicsPipelineFastInstanceKey& key, VkPipelineCreateFlags flags) const; - + void destroyPipeline( VkPipeline pipeline) const; From a2ef99b95c530ebde9cec337cb8b6f654fbcd04f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 31 Jul 2022 02:39:20 +0200 Subject: [PATCH 0354/1348] [d3d9] Generalize D3D9ConstantBuffer constructor --- src/d3d9/d3d9_constant_buffer.cpp | 16 ++++++++++++++-- src/d3d9/d3d9_constant_buffer.h | 6 ++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_constant_buffer.cpp b/src/d3d9/d3d9_constant_buffer.cpp index f717d95ec..a20502bb7 100644 --- a/src/d3d9/d3d9_constant_buffer.cpp +++ b/src/d3d9/d3d9_constant_buffer.cpp @@ -13,9 +13,21 @@ namespace dxvk { DxsoProgramType ShaderStage, DxsoConstantBuffers BufferType, VkDeviceSize Size) + : D3D9ConstantBuffer(pDevice, GetShaderStage(ShaderStage), + computeResourceSlotId(ShaderStage, DxsoBindingType::ConstantBuffer, BufferType), + Size) { + + } + + + D3D9ConstantBuffer::D3D9ConstantBuffer( + D3D9DeviceEx* pDevice, + VkShaderStageFlags Stages, + uint32_t ResourceSlot, + VkDeviceSize Size) : m_device (pDevice) - , m_binding (computeResourceSlotId(ShaderStage, DxsoBindingType::ConstantBuffer, BufferType)) - , m_stages (GetShaderStage(ShaderStage)) + , m_binding (ResourceSlot) + , m_stages (Stages) , m_size (Size) , m_align (getAlignment(pDevice->GetDXVKDevice())) { diff --git a/src/d3d9/d3d9_constant_buffer.h b/src/d3d9/d3d9_constant_buffer.h index 1dff07a96..980a7b1bf 100644 --- a/src/d3d9/d3d9_constant_buffer.h +++ b/src/d3d9/d3d9_constant_buffer.h @@ -27,6 +27,12 @@ namespace dxvk { DxsoConstantBuffers BufferType, VkDeviceSize Size); + D3D9ConstantBuffer( + D3D9DeviceEx* pDevice, + VkShaderStageFlags Stages, + uint32_t ResourceSlot, + VkDeviceSize Size); + ~D3D9ConstantBuffer(); /** From 54f989b2e64e556cab691a0e5464b7c2e825ea2a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 31 Jul 2022 02:39:38 +0200 Subject: [PATCH 0355/1348] [dxso] Introduce getSpecConstantBufferSlot --- src/dxso/dxso_util.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dxso/dxso_util.h b/src/dxso/dxso_util.h index 3a94acfb1..d027d6fc7 100644 --- a/src/dxso/dxso_util.h +++ b/src/dxso/dxso_util.h @@ -53,6 +53,10 @@ namespace dxvk { return DxsoConstantBuffers::VSCount + caps::MaxTexturesVS + DxsoConstantBuffers::PSCount + caps::MaxTexturesPS + 1; // From last pixel shader slot, above. } + constexpr uint32_t getSpecConstantBufferSlot() { + return getSWVPBufferSlot() + 1; + } + uint32_t RegisterLinkerSlot(DxsoSemantic semantic); } \ No newline at end of file From 8db2eb51fa2ec08b6f8198bf4941504ecd3218db Mon Sep 17 00:00:00 2001 From: pchome Date: Sun, 31 Jul 2022 15:47:21 +0300 Subject: [PATCH 0356/1348] [d3d9] fix ordinal values in the DEF file --- src/d3d9/d3d9.def | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d3d9/d3d9.def b/src/d3d9/d3d9.def index 4e3f9ae51..3042268e2 100644 --- a/src/d3d9/d3d9.def +++ b/src/d3d9/d3d9.def @@ -18,10 +18,10 @@ EXPORTS Direct3D9EnableMaximizedWindowedModeShim @36 - Direct3DCreate9 @ 37 - Direct3DCreate9Ex @ 38 + Direct3DCreate9 @37 + Direct3DCreate9Ex @38 - DXVK_RegisterAnnotation @ 28257 NONAME - DXVK_UnRegisterAnnotation @ 28258 NONAME + DXVK_RegisterAnnotation @28257 NONAME + DXVK_UnRegisterAnnotation @28258 NONAME Direct3D9ForceHybridEnumeration @16 NONAME PRIVATE From 96710555381e5125ee4ee9117023464e7b524cde Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 1 Aug 2022 12:05:43 +0200 Subject: [PATCH 0357/1348] [util] Support parsing floating point arguments --- src/util/config/config.cpp | 60 ++++++++++++++++++++++++++++++++++++++ src/util/config/config.h | 4 +++ 2 files changed, 64 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index be4689aa3..801365015 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -755,6 +755,66 @@ namespace dxvk { } + bool Config::parseOptionValue( + const std::string& value, + float& result) { + if (value.size() == 0) + return false; + + // Parse sign + size_t pos = 0; + bool negate = false; + + if (value[0] == '-') { + negate = true; + pos += 1; + } + + // Parse integer part + uint64_t intPart = 0; + + if (value[pos] == '.') + return false; + + while (pos < value.size()) { + if (value[pos] == '.') { + if (++pos == value.size()) + return false; + break; + } + + if (value[pos] < '0' || value[pos] > '9') + return false; + + intPart *= 10; + intPart += value[pos] - '0'; + pos += 1; + } + + // Parse fractional part + uint64_t fractPart = 0; + uint64_t fractDivisor = 1; + + while (pos < value.size()) { + if (value[pos] < '0' || value[pos] > '9') + return false; + + fractDivisor *= 10; + fractPart *= 10; + fractPart += value[pos] - '0'; + pos += 1; + } + + // Compute final number, not super accurate but this should do + result = float((double(fractPart) / double(fractDivisor)) + double(intPart)); + + if (negate) + result = -result; + + return true; + } + + bool Config::parseOptionValue( const std::string& value, Tristate& result) { diff --git a/src/util/config/config.h b/src/util/config/config.h index f947272ca..eb8492544 100644 --- a/src/util/config/config.h +++ b/src/util/config/config.h @@ -123,6 +123,10 @@ namespace dxvk { const std::string& value, int32_t& result); + static bool parseOptionValue( + const std::string& value, + float& result); + static bool parseOptionValue( const std::string& value, Tristate& result); From 727fd7ac33ca8ba09f166bce04c0cbb77601fe98 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 1 Aug 2022 12:08:11 +0200 Subject: [PATCH 0358/1348] [d3d11] Add option to control sampler LOD bias --- dxvk.conf | 10 ++++++++++ src/d3d11/d3d11_options.cpp | 6 +++++- src/d3d11/d3d11_options.h | 7 ++++++- src/d3d11/d3d11_sampler.cpp | 6 +++++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index ba924e8ad..1cce94d8b 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -169,6 +169,16 @@ # d3d9.samplerAnisotropy = -1 +# Changes the mipmap LOD bias for all samplers. The given number will be +# added to the LOD bias provided by the application, rather than replacing +# it entirely. Positive values will reduce texture detail, while negative +# values may increase sharpness at the cost of shimmer. +# +# Supported values: Any number between -2.0 and 1.0 + +# d3d11.samplerLodBias = 0.0 + + # Declares vertex positions as invariant in order to solve # potential Z-fighting issues at a small performance cost. # diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index 5744a0bfb..84d052bf3 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -1,4 +1,4 @@ -#include +#include "../util/util_math.h" #include "d3d11_options.h" @@ -13,6 +13,7 @@ namespace dxvk { this->ignoreGraphicsBarriers = config.getOption("d3d11.ignoreGraphicsBarriers", false); this->maxTessFactor = config.getOption("d3d11.maxTessFactor", 0); this->samplerAnisotropy = config.getOption("d3d11.samplerAnisotropy", -1); + this->samplerLodBias = config.getOption("d3d11.samplerLodBias", 0.0f); this->invariantPosition = config.getOption("d3d11.invariantPosition", true); this->floatControls = config.getOption("d3d11.floatControls", true); this->disableMsaa = config.getOption("d3d11.disableMsaa", false); @@ -23,6 +24,9 @@ namespace dxvk { this->syncInterval = config.getOption("dxgi.syncInterval", -1); this->tearFree = config.getOption("dxgi.tearFree", Tristate::Auto); + // Clamp LOD bias so that people don't abuse this in unintended ways + this->samplerLodBias = dxvk::fclamp(this->samplerLodBias, -2.0f, 1.0f); + int32_t maxImplicitDiscardSize = config.getOption("d3d11.maxImplicitDiscardSize", 256); this->maxImplicitDiscardSize = maxImplicitDiscardSize >= 0 ? VkDeviceSize(maxImplicitDiscardSize) << 10 diff --git a/src/d3d11/d3d11_options.h b/src/d3d11/d3d11_options.h index 3c3a26169..dcbef7c3c 100644 --- a/src/d3d11/d3d11_options.h +++ b/src/d3d11/d3d11_options.h @@ -61,7 +61,12 @@ namespace dxvk { /// Enforces anisotropic filtering with the /// given anisotropy value for all samplers. int32_t samplerAnisotropy; - + + /// Mipmap LOD bias + /// + /// Enforces the given LOD bias for all samplers. + float samplerLodBias; + /// Declare vertex positions in shaders as invariant bool invariantPosition; diff --git a/src/d3d11/d3d11_sampler.cpp b/src/d3d11/d3d11_sampler.cpp index e3e54cf39..8150c29c3 100644 --- a/src/d3d11/d3d11_sampler.cpp +++ b/src/d3d11/d3d11_sampler.cpp @@ -44,6 +44,10 @@ namespace dxvk { if (desc.MaxAnisotropy < 1) info.maxAnisotropy = 1.0f; if (desc.MaxAnisotropy > 16) info.maxAnisotropy = 16.0f; + // Enforce LOD bias specified in the device options + if (info.minFilter == VK_FILTER_LINEAR && info.magFilter == VK_FILTER_LINEAR) + info.mipmapLodBias += device->GetOptions()->samplerLodBias; + // Enforce anisotropy specified in the device options int32_t samplerAnisotropyOption = device->GetOptions()->samplerAnisotropy; @@ -51,7 +55,7 @@ namespace dxvk { info.useAnisotropy = samplerAnisotropyOption > 0; info.maxAnisotropy = float(samplerAnisotropyOption); } - + m_sampler = device->GetDXVKDevice()->createSampler(info); } From 5256d5e2f681b8f6d4db1880d5e31e4891a32e1f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 1 Aug 2022 20:24:31 +0200 Subject: [PATCH 0359/1348] [dxvk] Fix minor edge cases when parsing floats in config file --- src/util/config/config.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 801365015..5f7f6bbba 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -767,7 +767,9 @@ namespace dxvk { if (value[0] == '-') { negate = true; - pos += 1; + + if (++pos == value.size()) + return false; } // Parse integer part @@ -811,7 +813,7 @@ namespace dxvk { if (negate) result = -result; - return true; + return std::isfinite(result); } From 715493cd759a13e1ded86dced1c098493dafe0f3 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 2 Aug 2022 02:15:27 +0000 Subject: [PATCH 0360/1348] [d3d10] Mark D3D10ShaderReflection classes as final Fixes warnings about calling delete on non-final inherited objects. --- src/d3d10/d3d10_reflection.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d3d10/d3d10_reflection.h b/src/d3d10/d3d10_reflection.h index b25a92ceb..482b4f0f9 100644 --- a/src/d3d10/d3d10_reflection.h +++ b/src/d3d10/d3d10_reflection.h @@ -10,7 +10,7 @@ namespace dxvk { - class D3D10ShaderReflectionType : public ID3D10ShaderReflectionType { + class D3D10ShaderReflectionType final : public ID3D10ShaderReflectionType { public: @@ -49,7 +49,7 @@ namespace dxvk { }; - class D3D10ShaderReflectionVariable : public ID3D10ShaderReflectionVariable { + class D3D10ShaderReflectionVariable final : public ID3D10ShaderReflectionVariable { public: @@ -75,7 +75,7 @@ namespace dxvk { }; - class D3D10ShaderReflectionConstantBuffer : public ID3D10ShaderReflectionConstantBuffer { + class D3D10ShaderReflectionConstantBuffer final : public ID3D10ShaderReflectionConstantBuffer { public: From 08424ccb2eedb2200ea3bbbebb88a79453e92f1d Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Tue, 2 Aug 2022 04:10:12 -0700 Subject: [PATCH 0361/1348] [d3d9] Add missing vector header Fixes compilation under MSYS2's clang backend. --- src/d3d9/d3d9_mem.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/d3d9/d3d9_mem.h b/src/d3d9/d3d9_mem.h index f2ffde0a6..20ac138cc 100644 --- a/src/d3d9/d3d9_mem.h +++ b/src/d3d9/d3d9_mem.h @@ -12,6 +12,8 @@ #include #endif +#include + namespace dxvk { class D3D9MemoryAllocator; From c1cb4d9d1826ccc3eccb33093746ced5bd165782 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 2 Aug 2022 14:33:41 +0200 Subject: [PATCH 0362/1348] [dxvk] Add feature check for external semaphores --- src/dxvk/dxvk_fence.cpp | 39 +++++++++++++++++++++++++++++--------- src/vulkan/vulkan_loader.h | 1 + 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/dxvk/dxvk_fence.cpp b/src/dxvk/dxvk_fence.cpp index 3f3a7746d..f9c3dc536 100644 --- a/src/dxvk/dxvk_fence.cpp +++ b/src/dxvk/dxvk_fence.cpp @@ -14,8 +14,25 @@ namespace dxvk { VkExportSemaphoreCreateInfo exportInfo = { VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO }; exportInfo.handleTypes = info.sharedType; - if (info.sharedType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM) - typeInfo.pNext = &exportInfo; + VkExternalSemaphoreFeatureFlags externalFeatures = 0; + + if (info.sharedType != VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM) { + auto vki = device->adapter()->vki(); + + VkPhysicalDeviceExternalSemaphoreInfo externalInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, &typeInfo }; + externalInfo.handleType = info.sharedType; + + VkExternalSemaphoreProperties externalProperties = { }; + vki->vkGetPhysicalDeviceExternalSemaphoreProperties( + device->adapter()->handle(), &externalInfo, &externalProperties); + + externalFeatures = externalProperties.externalSemaphoreFeatures; + + if (externalFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) + typeInfo.pNext = &exportInfo; + else + Logger::warn(str::format("Exporting semaphores of type ", info.sharedType, " not supported by device")); + } VkSemaphoreCreateInfo semaphoreInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &typeInfo }; @@ -26,14 +43,18 @@ namespace dxvk { throw DxvkError("Failed to create timeline semaphore"); if (info.sharedHandle != INVALID_HANDLE_VALUE) { - VkImportSemaphoreWin32HandleInfoKHR importInfo = { VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR }; - importInfo.semaphore = m_semaphore; - importInfo.handleType = info.sharedType; - importInfo.handle = info.sharedHandle; + if (externalFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT) { + VkImportSemaphoreWin32HandleInfoKHR importInfo = { VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR }; + importInfo.semaphore = m_semaphore; + importInfo.handleType = info.sharedType; + importInfo.handle = info.sharedHandle; - vr = m_vkd->vkImportSemaphoreWin32HandleKHR(m_vkd->device(), &importInfo); - if (vr != VK_SUCCESS) - throw DxvkError("Failed to import timeline semaphore"); + vr = m_vkd->vkImportSemaphoreWin32HandleKHR(m_vkd->device(), &importInfo); + if (vr != VK_SUCCESS) + throw DxvkError("Failed to import timeline semaphore"); + } else { + Logger::warn(str::format("Importing semaphores of type ", info.sharedType, " not supported by device")); + } } m_thread = dxvk::thread([this] { run(); }); diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 47c26eed8..6f469c650 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -85,6 +85,7 @@ namespace dxvk::vk { VULKAN_FN(vkDestroyInstance); VULKAN_FN(vkEnumerateDeviceExtensionProperties); VULKAN_FN(vkEnumeratePhysicalDevices); + VULKAN_FN(vkGetPhysicalDeviceExternalSemaphoreProperties); VULKAN_FN(vkGetPhysicalDeviceFeatures); VULKAN_FN(vkGetPhysicalDeviceFeatures2); VULKAN_FN(vkGetPhysicalDeviceFormatProperties); From ac2d3e952dea89a966ed2825702381bea60eac76 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 2 Aug 2022 22:21:26 +0100 Subject: [PATCH 0363/1348] [util] Set m_size in small_vector::resize Turns out this has been broken since it was added, meaning isViewCompatible has always returned false putting us down slow paths for UAV clears + copies for the past two years. --- src/util/util_small_vector.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/util_small_vector.h b/src/util/util_small_vector.h index c313ca4b1..daf5bedb9 100644 --- a/src/util/util_small_vector.h +++ b/src/util/util_small_vector.h @@ -57,6 +57,8 @@ namespace dxvk { for (size_t i = m_size; i < n; i++) new (ptr(i)) T(); + + m_size = n; } void push_back(const T& object) { From fc7e934854567b242361f744f19c61b567746786 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 15:14:07 +0200 Subject: [PATCH 0364/1348] [util] Always inline Rc::decRef and Rc::incRef GCC feels the need to generate functions with two instructions for some reason. Doesn't meaningfully change performance, but makes profiling a lot easier in some instances. --- src/util/rc/util_rc.h | 6 ++++-- src/util/rc/util_rc_ptr.h | 4 ++-- src/util/util_likely.h | 2 ++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/util/rc/util_rc.h b/src/util/rc/util_rc.h index c33d0c614..f8e8c2304 100644 --- a/src/util/rc/util_rc.h +++ b/src/util/rc/util_rc.h @@ -2,6 +2,8 @@ #include +#include "../util_likely.h" + namespace dxvk { /** @@ -15,7 +17,7 @@ namespace dxvk { * \brief Increments reference count * \returns New reference count */ - uint32_t incRef() { + always_inline uint32_t incRef() { return ++m_refCount; } @@ -23,7 +25,7 @@ namespace dxvk { * \brief Decrements reference count * \returns New reference count */ - uint32_t decRef() { + always_inline uint32_t decRef() { return --m_refCount; } diff --git a/src/util/rc/util_rc_ptr.h b/src/util/rc/util_rc_ptr.h index 23c5c43d5..55540f603 100644 --- a/src/util/rc/util_rc_ptr.h +++ b/src/util/rc/util_rc_ptr.h @@ -102,12 +102,12 @@ namespace dxvk { T* m_object = nullptr; - void incRef() const { + always_inline void incRef() const { if (m_object != nullptr) m_object->incRef(); } - void decRef() const { + always_inline void decRef() const { if (m_object != nullptr) { if (m_object->decRef() == 0) delete m_object; diff --git a/src/util/util_likely.h b/src/util/util_likely.h index 7eba9818c..cf6a970d4 100644 --- a/src/util/util_likely.h +++ b/src/util/util_likely.h @@ -3,7 +3,9 @@ #ifdef __GNUC__ #define likely(x) __builtin_expect((x),1) #define unlikely(x) __builtin_expect((x),0) +#define always_inline inline __attribute__((always_inline)) #else #define likely(x) (x) #define unlikely(x) (x) +#define always_inline inline #endif From 8e37949a719861baf080bbb79e832b0593d2bad2 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Wed, 3 Aug 2022 19:40:34 +0200 Subject: [PATCH 0365/1348] [util] Use raw tzcnt for BitMask iterator Dereferencing an end iterator is UB, so we don't have to care about the 0 case. --- src/util/util_bit.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index ee7470a70..4acd9c23a 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -336,7 +336,16 @@ namespace dxvk::bit { } uint32_t operator * () const { +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__BMI__) + uint32_t res; + asm ("tzcnt %1,%0" + : "=r" (res) + : "r" (m_mask) + : "cc"); + return res; +#else return tzcnt(m_mask); +#endif } bool operator == (iterator other) const { return m_mask == other.m_mask; } From f10be7bc8534032850fe7d36bf6072a25bbd4399 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 14:15:10 +0200 Subject: [PATCH 0366/1348] [dxvk] Add binding methods that take rvalue references The goal here is to replace the old methods entirely. --- src/dxvk/dxvk_context.cpp | 28 ------- src/dxvk/dxvk_context.h | 169 +++++++++++++++++++++++++++++++++++++- 2 files changed, 168 insertions(+), 29 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b2c3bb837..743c0a6d1 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -159,34 +159,6 @@ namespace dxvk { } - void DxvkContext::bindShader( - VkShaderStageFlagBits stage, - const Rc& shader) { - Rc* shaderStage; - - switch (stage) { - case VK_SHADER_STAGE_VERTEX_BIT: shaderStage = &m_state.gp.shaders.vs; break; - case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: shaderStage = &m_state.gp.shaders.tcs; break; - case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: shaderStage = &m_state.gp.shaders.tes; break; - case VK_SHADER_STAGE_GEOMETRY_BIT: shaderStage = &m_state.gp.shaders.gs; break; - case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.shaders.fs; break; - case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.shaders.cs; break; - default: return; - } - - *shaderStage = shader; - - if (stage == VK_SHADER_STAGE_COMPUTE_BIT) { - m_flags.set( - DxvkContextFlag::CpDirtyPipelineState); - } else { - m_flags.set( - DxvkContextFlag::GpDirtyPipeline, - DxvkContextFlag::GpDirtyPipelineState); - } - } - - void DxvkContext::blitImage( const Rc& dstImage, const VkComponentMapping& dstMapping, diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index c738dd5ec..db91271b0 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -106,6 +106,26 @@ namespace dxvk { } } + void bindRenderTargets( + DxvkRenderTargets&& targets) { + // Set up default render pass ops + m_state.om.renderTargets = std::move(targets); + + this->resetRenderPassOps( + m_state.om.renderTargets, + m_state.om.renderPassOps); + + if (!m_state.om.framebufferInfo.hasTargets(m_state.om.renderTargets)) { + // Create a new framebuffer object next + // time we start rendering something + m_flags.set(DxvkContextFlag::GpDirtyFramebuffer); + } else { + // Don't redundantly spill the render pass if + // the same render targets are bound again + m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer); + } + } + /** * \brief Binds indirect argument buffer * @@ -123,6 +143,15 @@ namespace dxvk { m_flags.set(DxvkContextFlag::DirtyDrawBuffer); } + void bindDrawBuffers( + DxvkBufferSlice&& argBuffer, + DxvkBufferSlice&& cntBuffer) { + m_state.id.argBuffer = std::move(argBuffer); + m_state.id.cntBuffer = std::move(cntBuffer); + + m_flags.set(DxvkContextFlag::DirtyDrawBuffer); + } + /** * \brief Binds index buffer * @@ -143,6 +172,18 @@ namespace dxvk { m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer); } + void bindIndexBuffer( + DxvkBufferSlice&& buffer, + VkIndexType indexType) { + if (!m_state.vi.indexBuffer.matchesBuffer(buffer)) + m_vbTracked.clr(MaxNumVertexBindings); + + m_state.vi.indexBuffer = std::move(buffer); + m_state.vi.indexType = indexType; + + m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer); + } + /** * \brief Binds buffer as a shader resource * @@ -165,6 +206,20 @@ namespace dxvk { m_descriptorState.dirtyBuffers(stages); } + void bindResourceBuffer( + VkShaderStageFlags stages, + uint32_t slot, + DxvkBufferSlice&& buffer) { + bool needsUpdate = !m_rc[slot].bufferSlice.matchesBuffer(buffer); + + if (likely(needsUpdate)) + m_rcTracked.clr(slot); + + m_rc[slot].bufferSlice = std::move(buffer); + + m_descriptorState.dirtyBuffers(stages); + } + /** * \brief Changes bound range of a resource buffer * @@ -207,6 +262,21 @@ namespace dxvk { m_descriptorState.dirtyViews(stages); } + void bindResourceView( + VkShaderStageFlags stages, + uint32_t slot, + Rc&& imageView, + Rc&& bufferView) { + m_rc[slot].bufferSlice = bufferView != nullptr + ? bufferView->slice() + : DxvkBufferSlice(); + m_rc[slot].bufferView = std::move(bufferView); + m_rc[slot].imageView = std::move(imageView); + m_rcTracked.clr(slot); + + m_descriptorState.dirtyViews(stages); + } + /** * \brief Binds image sampler * @@ -226,6 +296,16 @@ namespace dxvk { m_descriptorState.dirtyViews(stages); } + void bindResourceSampler( + VkShaderStageFlags stages, + uint32_t slot, + Rc&& sampler) { + m_rc[slot].sampler = std::move(sampler); + m_rcTracked.clr(slot); + + m_descriptorState.dirtyViews(stages); + } + /** * \brief Binds a shader to a given state * @@ -234,7 +314,72 @@ namespace dxvk { */ void bindShader( VkShaderStageFlagBits stage, - const Rc& shader); + const Rc& shader) { + Rc* shaderStage; + + switch (stage) { + case VK_SHADER_STAGE_VERTEX_BIT: shaderStage = &m_state.gp.shaders.vs; break; + case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: shaderStage = &m_state.gp.shaders.tcs; break; + case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: shaderStage = &m_state.gp.shaders.tes; break; + case VK_SHADER_STAGE_GEOMETRY_BIT: shaderStage = &m_state.gp.shaders.gs; break; + case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.shaders.fs; break; + case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.shaders.cs; break; + default: return; + } + + *shaderStage = shader; + + if (stage == VK_SHADER_STAGE_COMPUTE_BIT) { + m_flags.set( + DxvkContextFlag::CpDirtyPipelineState); + } else { + m_flags.set( + DxvkContextFlag::GpDirtyPipeline, + DxvkContextFlag::GpDirtyPipelineState); + } + } + + void bindShader( + VkShaderStageFlagBits stage, + Rc&& shader) { + switch (stage) { + case VK_SHADER_STAGE_VERTEX_BIT: + m_state.gp.shaders.vs = std::move(shader); + break; + + case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: + m_state.gp.shaders.tcs = std::move(shader); + break; + + case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: + m_state.gp.shaders.tes = std::move(shader); + break; + + case VK_SHADER_STAGE_GEOMETRY_BIT: + m_state.gp.shaders.gs = std::move(shader); + break; + + case VK_SHADER_STAGE_FRAGMENT_BIT: + m_state.gp.shaders.fs = std::move(shader); + break; + + case VK_SHADER_STAGE_COMPUTE_BIT: + m_state.cp.shaders.cs = std::move(shader); + break; + + default: + return; + } + + if (stage == VK_SHADER_STAGE_COMPUTE_BIT) { + m_flags.set( + DxvkContextFlag::CpDirtyPipelineState); + } else { + m_flags.set( + DxvkContextFlag::GpDirtyPipeline, + DxvkContextFlag::GpDirtyPipelineState); + } + } /** * \brief Binds vertex buffer @@ -256,6 +401,18 @@ namespace dxvk { m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers); } + void bindVertexBuffer( + uint32_t binding, + DxvkBufferSlice&& buffer, + uint32_t stride) { + if (!m_state.vi.vertexBuffers[binding].matchesBuffer(buffer)) + m_vbTracked.clr(binding); + + m_state.vi.vertexBuffers[binding] = std::move(buffer); + m_state.vi.vertexStrides[binding] = stride; + m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers); + } + /** * \brief Binds transform feedback buffer * @@ -276,6 +433,16 @@ namespace dxvk { } } + void bindXfbBuffer( + uint32_t binding, + DxvkBufferSlice&& buffer, + DxvkBufferSlice&& counter) { + m_state.xfb.buffers [binding] = std::move(buffer); + m_state.xfb.counters[binding] = std::move(counter); + + m_flags.set(DxvkContextFlag::GpDirtyXfbBuffers); + } + /** * \brief Blits an image * From 0315997fcd31f1d6de68514d6c7a5bb0a07b35bd Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 16:14:57 +0200 Subject: [PATCH 0367/1348] [d3d9] Use mutable lambdas to avoid some redundant ref counting --- src/d3d9/d3d9_constant_buffer.cpp | 4 ++-- src/d3d9/d3d9_device.cpp | 33 ++++++++++++++++--------------- src/d3d9/d3d9_format_helpers.cpp | 6 +++--- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/d3d9/d3d9_constant_buffer.cpp b/src/d3d9/d3d9_constant_buffer.cpp index a20502bb7..a88935b01 100644 --- a/src/d3d9/d3d9_constant_buffer.cpp +++ b/src/d3d9/d3d9_constant_buffer.cpp @@ -117,8 +117,8 @@ namespace dxvk { cStages = m_stages, cBinding = m_binding, cSlice = DxvkBufferSlice(m_buffer) - ] (DxvkContext* ctx) { - ctx->bindResourceBuffer(cStages, cBinding, cSlice); + ] (DxvkContext* ctx) mutable { + ctx->bindResourceBuffer(cStages, cBinding, std::move(cSlice)); }); } diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 78a02707d..716100c39 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2503,12 +2503,12 @@ namespace dxvk { cPrimCount = PrimitiveCount, cInstanceCount = GetInstanceCount(), cStride = VertexStreamZeroStride - ](DxvkContext* ctx) { + ](DxvkContext* ctx) mutable { auto drawInfo = GenerateDrawInfo(cPrimType, cPrimCount, cInstanceCount); ApplyPrimitiveType(ctx, cPrimType); - ctx->bindVertexBuffer(0, cBufferSlice, cStride); + ctx->bindVertexBuffer(0, std::move(cBufferSlice), cStride); ctx->draw( drawInfo.vertexCount, drawInfo.instanceCount, 0, 0); @@ -2645,7 +2645,7 @@ namespace dxvk { cInstanceCount = GetInstanceCount(), cBufferSlice = slice, cIndexed = m_state.indices != nullptr - ](DxvkContext* ctx) { + ](DxvkContext* ctx) mutable { Rc shader = m_swvpEmulator.GetShaderModule(this, cDecl); auto drawInfo = GenerateDrawInfo(D3DPT_POINTLIST, cVertexCount, cInstanceCount); @@ -2662,8 +2662,8 @@ namespace dxvk { // to avoid val errors / UB. ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, nullptr); - ctx->bindShader(VK_SHADER_STAGE_GEOMETRY_BIT, shader); - ctx->bindResourceBuffer(VK_SHADER_STAGE_GEOMETRY_BIT, getSWVPBufferSlot(), cBufferSlice); + ctx->bindShader(VK_SHADER_STAGE_GEOMETRY_BIT, std::move(shader)); + ctx->bindResourceBuffer(VK_SHADER_STAGE_GEOMETRY_BIT, getSWVPBufferSlot(), std::move(cBufferSlice)); ctx->draw( drawInfo.vertexCount, drawInfo.instanceCount, cStartIndex, 0); @@ -5476,8 +5476,8 @@ namespace dxvk { // Create and bind the framebuffer object to the context EmitCs([ cAttachments = std::move(attachments) - ] (DxvkContext* ctx) { - ctx->bindRenderTargets(cAttachments); + ] (DxvkContext* ctx) mutable { + ctx->bindRenderTargets(std::move(cAttachments)); }); } @@ -5813,7 +5813,8 @@ namespace dxvk { auto pair = m_samplers.find(cKey); if (pair != m_samplers.end()) { - ctx->bindResourceSampler(stage, cSlot, pair->second); + ctx->bindResourceSampler(stage, cSlot, + Rc(pair->second)); return; } @@ -5880,9 +5881,9 @@ namespace dxvk { EmitCs([ cSlot = slot, cImageView = commonTex->GetSampleView(srgb) - ](DxvkContext* ctx) { + ](DxvkContext* ctx) mutable { VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; - ctx->bindResourceView(stage, cSlot, cImageView, nullptr); + ctx->bindResourceView(stage, cSlot, std::move(cImageView), nullptr); }); } @@ -6129,8 +6130,8 @@ namespace dxvk { D3D9ShaderPermutation Permutation) { EmitCs([ cShader = pShaderModule->GetShader(Permutation) - ] (DxvkContext* ctx) { - ctx->bindShader(GetShaderStage(ShaderStage), cShader); + ] (DxvkContext* ctx) mutable { + ctx->bindShader(GetShaderStage(ShaderStage), std::move(cShader)); }); } @@ -6259,8 +6260,8 @@ namespace dxvk { pBuffer->GetCommonBuffer()->GetBufferSlice(Offset) : DxvkBufferSlice(), cStride = pBuffer != nullptr ? Stride : 0 - ] (DxvkContext* ctx) { - ctx->bindVertexBuffer(cSlotId, cBufferSlice, cStride); + ] (DxvkContext* ctx) mutable { + ctx->bindVertexBuffer(cSlotId, std::move(cBufferSlice), cStride); }); } @@ -6276,8 +6277,8 @@ namespace dxvk { EmitCs([ cBufferSlice = buffer != nullptr ? buffer->GetBufferSlice() : DxvkBufferSlice(), cIndexType = indexType - ](DxvkContext* ctx) { - ctx->bindIndexBuffer(cBufferSlice, cIndexType); + ](DxvkContext* ctx) mutable { + ctx->bindIndexBuffer(std::move(cBufferSlice), cIndexType); }); } diff --git a/src/d3d9/d3d9_format_helpers.cpp b/src/d3d9/d3d9_format_helpers.cpp index 2c369d21b..59dc3868f 100644 --- a/src/d3d9/d3d9_format_helpers.cpp +++ b/src/d3d9/d3d9_format_helpers.cpp @@ -94,9 +94,9 @@ namespace dxvk { auto tmpBufferView = m_device->createBufferView(srcSlice.buffer(), bufferViewInfo); m_context->setSpecConstant(VK_PIPELINE_BIND_POINT_COMPUTE, 0, specConstantValue); - m_context->bindResourceView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Image, tmpImageView, nullptr); - m_context->bindResourceView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Buffer, nullptr, tmpBufferView); - m_context->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, m_shaders[videoFormat.FormatType]); + m_context->bindResourceView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Image, std::move(tmpImageView), nullptr); + m_context->bindResourceView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Buffer, nullptr, std::move(tmpBufferView)); + m_context->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, Rc(m_shaders[videoFormat.FormatType])); m_context->pushConstants(0, sizeof(VkExtent2D), &imageExtent); m_context->dispatch( (imageExtent.width / 8) + (imageExtent.width % 8), From e4204f76e68825585c75d2acf3a5213ba613de9d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 16:33:54 +0200 Subject: [PATCH 0368/1348] [d3d11] Introduce D3D11CommonContext --- src/d3d11/d3d11_context_common.cpp | 26 +++++++++++ src/d3d11/d3d11_context_common.h | 71 ++++++++++++++++++++++++++++++ src/d3d11/d3d11_context_def.cpp | 2 +- src/d3d11/d3d11_context_def.h | 9 ++-- src/d3d11/d3d11_context_imm.cpp | 2 +- src/d3d11/d3d11_context_imm.h | 7 +-- src/d3d11/meson.build | 1 + 7 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 src/d3d11/d3d11_context_common.cpp create mode 100644 src/d3d11/d3d11_context_common.h diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp new file mode 100644 index 000000000..8b93c36f9 --- /dev/null +++ b/src/d3d11/d3d11_context_common.cpp @@ -0,0 +1,26 @@ +#include "d3d11_context_common.h" +#include "d3d11_context_def.h" +#include "d3d11_context_imm.h" + +namespace dxvk { + + template + D3D11CommonContext::D3D11CommonContext( + D3D11Device* pParent, + const Rc& Device, + DxvkCsChunkFlags CsFlags) + : D3D11DeviceContext(pParent, Device, CsFlags) { + + } + + + template + D3D11CommonContext::~D3D11CommonContext() { + + } + + // Explicitly instantiate here + template class D3D11CommonContext; + template class D3D11CommonContext; + +} diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h new file mode 100644 index 000000000..bb4b295f0 --- /dev/null +++ b/src/d3d11/d3d11_context_common.h @@ -0,0 +1,71 @@ +#pragma once + +#include +#include + +#include "d3d11_buffer.h" +#include "d3d11_context.h" +#include "d3d11_texture.h" + +namespace dxvk { + + class D3D11DeferredContext; + class D3D11ImmediateContext; + + template + struct D3D11ContextObjectForwarder; + + /** + * \brief Object forwarder for immediate contexts + * + * Binding methods can use this to efficiently bind objects + * to the DXVK context without redundant reference counting. + */ + template<> + struct D3D11ContextObjectForwarder { + template + static T&& move(T& object) { + return std::move(object); + } + }; + + /** + * \brief Object forwarder for deferred contexts + * + * This forwarder will create a copy of the object passed + * into it, so that CS chunks can be reused if necessary. + */ + template<> + struct D3D11ContextObjectForwarder { + template + static T move(const T& object) { + return object; + } + }; + + /** + * \brief Common D3D11 device context implementation + * + * Implements all common device context methods, but since this is + * templates with the actual context type (deferred or immediate), + * all methods can call back into context-specific methods without + * having to use virtual methods. + */ + template + class D3D11CommonContext : public D3D11DeviceContext { + constexpr static bool IsDeferred = std::is_same_v; + using Forwarder = D3D11ContextObjectForwarder; + public: + + D3D11CommonContext( + D3D11Device* pParent, + const Rc& Device, + DxvkCsChunkFlags CsFlags); + + ~D3D11CommonContext(); + + + + }; + +} diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 57695bf25..1304236e1 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -7,7 +7,7 @@ namespace dxvk { D3D11Device* pParent, const Rc& Device, UINT ContextFlags) - : D3D11DeviceContext(pParent, Device, GetCsChunkFlags(pParent)), + : D3D11CommonContext(pParent, Device, GetCsChunkFlags(pParent)), m_contextFlags(ContextFlags), m_commandList (CreateCommandList()) { ClearState(); diff --git a/src/d3d11/d3d11_context_def.h b/src/d3d11/d3d11_context_def.h index c5fe49c9d..bda8725ca 100644 --- a/src/d3d11/d3d11_context_def.h +++ b/src/d3d11/d3d11_context_def.h @@ -1,9 +1,7 @@ #pragma once -#include "d3d11_buffer.h" #include "d3d11_cmdlist.h" -#include "d3d11_context.h" -#include "d3d11_texture.h" +#include "d3d11_context_common.h" #include @@ -23,8 +21,9 @@ namespace dxvk { D3D11_MAPPED_SUBRESOURCE MapInfo; }; - class D3D11DeferredContext : public D3D11DeviceContext { - friend class D3D11DeviceContext; + class D3D11DeferredContext : public D3D11CommonContext { + template + friend class D3D11CommonContext; public: D3D11DeferredContext( diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index cbbc2d1eb..de04b9ef9 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -13,7 +13,7 @@ namespace dxvk { D3D11ImmediateContext::D3D11ImmediateContext( D3D11Device* pParent, const Rc& Device) - : D3D11DeviceContext(pParent, Device, DxvkCsChunkFlag::SingleUse), + : D3D11CommonContext(pParent, Device, DxvkCsChunkFlag::SingleUse), m_csThread(Device, Device->createContext(DxvkContextType::Primary)), m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize), m_videoContext(this, Device) { diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 6bc1e6da0..2356fd505 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -4,7 +4,7 @@ #include "../util/sync/sync_signal.h" -#include "d3d11_context.h" +#include "d3d11_context_common.h" #include "d3d11_state_object.h" #include "d3d11_video.h" @@ -13,10 +13,11 @@ namespace dxvk { class D3D11Buffer; class D3D11CommonTexture; - class D3D11ImmediateContext : public D3D11DeviceContext { + class D3D11ImmediateContext : public D3D11CommonContext { + template + friend class D3D11CommonContext; friend class D3D11SwapChain; friend class D3D11VideoContext; - friend class D3D11DeviceContext; public: D3D11ImmediateContext( diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 85fe78074..4600a5a5e 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -30,6 +30,7 @@ d3d11_src = [ 'd3d11_class_linkage.cpp', 'd3d11_cmdlist.cpp', 'd3d11_context.cpp', + 'd3d11_context_common.cpp', 'd3d11_context_def.cpp', 'd3d11_context_ext.cpp', 'd3d11_context_imm.cpp', From 3ead348b82aa013ac16de2d23fa2a980eba96267 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 16:41:50 +0200 Subject: [PATCH 0369/1348] [d3d11] Move UpdateSubresource code to D3D11CommonContext --- src/d3d11/d3d11_context.h | 62 -------------------- src/d3d11/d3d11_context_common.cpp | 91 ++++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 26 +++++++++ src/d3d11/d3d11_context_def.cpp | 25 -------- src/d3d11/d3d11_context_def.h | 17 ------ src/d3d11/d3d11_context_imm.cpp | 25 -------- src/d3d11/d3d11_context_imm.h | 17 ------ 7 files changed, 117 insertions(+), 146 deletions(-) diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index b9eba9c19..361e0fd6d 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -806,68 +806,6 @@ namespace dxvk { ID3D11Resource* pResource, UINT Subresource); - template - static void UpdateResource( - ContextType* pContext, - ID3D11Resource* pDstResource, - UINT DstSubresource, - const D3D11_BOX* pDstBox, - const void* pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch, - UINT CopyFlags) { - D3D10DeviceLock lock = pContext->LockContext(); - - if (!pDstResource) - return; - - // We need a different code path for buffers - D3D11_RESOURCE_DIMENSION resourceType; - pDstResource->GetType(&resourceType); - - if (likely(resourceType == D3D11_RESOURCE_DIMENSION_BUFFER)) { - const auto bufferResource = static_cast(pDstResource); - uint64_t bufferSize = bufferResource->Desc()->ByteWidth; - - // Provide a fast path for mapped buffer updates since some - // games use UpdateSubresource to update constant buffers. - if (likely(bufferResource->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_DIRECT) && likely(!pDstBox)) { - pContext->UpdateMappedBuffer(bufferResource, 0, bufferSize, pSrcData, 0); - return; - } - - // Validate buffer range to update - uint64_t offset = 0; - uint64_t length = bufferSize; - - if (pDstBox) { - offset = pDstBox->left; - length = pDstBox->right - offset; - } - - if (unlikely(offset + length > bufferSize)) - return; - - // Still try to be fast if a box is provided but we update the full buffer - if (likely(bufferResource->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_DIRECT)) { - CopyFlags &= D3D11_COPY_DISCARD | D3D11_COPY_NO_OVERWRITE; - - if (likely(length == bufferSize) || unlikely(CopyFlags != 0)) { - pContext->UpdateMappedBuffer(bufferResource, offset, length, pSrcData, CopyFlags); - return; - } - } - - // Otherwise we can't really do anything fancy, so just do a GPU copy - pContext->UpdateBuffer(bufferResource, offset, length, pSrcData); - } else { - D3D11CommonTexture* textureResource = GetCommonTexture(pDstResource); - - pContext->UpdateTexture(textureResource, - DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch); - } - } - void UpdateBuffer( D3D11Buffer* pDstBuffer, UINT Offset, diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 8b93c36f9..4e4adfdde 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -19,6 +19,97 @@ namespace dxvk { } + + template + void STDMETHODCALLTYPE D3D11CommonContext::UpdateSubresource( + ID3D11Resource* pDstResource, + UINT DstSubresource, + const D3D11_BOX* pDstBox, + const void* pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch) { + UpdateResource(pDstResource, DstSubresource, pDstBox, + pSrcData, SrcRowPitch, SrcDepthPitch, 0); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::UpdateSubresource1( + ID3D11Resource* pDstResource, + UINT DstSubresource, + const D3D11_BOX* pDstBox, + const void* pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch, + UINT CopyFlags) { + UpdateResource(pDstResource, DstSubresource, pDstBox, + pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags); + } + + + template + void D3D11CommonContext::UpdateResource( + ID3D11Resource* pDstResource, + UINT DstSubresource, + const D3D11_BOX* pDstBox, + const void* pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch, + UINT CopyFlags) { + auto context = static_cast(this); + D3D10DeviceLock lock = context->LockContext(); + + if (!pDstResource) + return; + + // We need a different code path for buffers + D3D11_RESOURCE_DIMENSION resourceType; + pDstResource->GetType(&resourceType); + + if (likely(resourceType == D3D11_RESOURCE_DIMENSION_BUFFER)) { + const auto bufferResource = static_cast(pDstResource); + uint64_t bufferSize = bufferResource->Desc()->ByteWidth; + + // Provide a fast path for mapped buffer updates since some + // games use UpdateSubresource to update constant buffers. + if (likely(bufferResource->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_DIRECT) && likely(!pDstBox)) { + context->UpdateMappedBuffer(bufferResource, 0, bufferSize, pSrcData, 0); + return; + } + + // Validate buffer range to update + uint64_t offset = 0; + uint64_t length = bufferSize; + + if (pDstBox) { + offset = pDstBox->left; + length = pDstBox->right - offset; + } + + if (unlikely(offset + length > bufferSize)) + return; + + // Still try to be fast if a box is provided but we update the full buffer + if (likely(bufferResource->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_DIRECT)) { + CopyFlags &= D3D11_COPY_DISCARD | D3D11_COPY_NO_OVERWRITE; + + if (likely(length == bufferSize) || unlikely(CopyFlags != 0)) { + context->UpdateMappedBuffer(bufferResource, offset, length, pSrcData, CopyFlags); + return; + } + } + + // Otherwise we can't really do anything fancy, so just do a GPU copy + context->UpdateBuffer(bufferResource, offset, length, pSrcData); + } else { + D3D11CommonTexture* textureResource = GetCommonTexture(pDstResource); + + context->UpdateTexture(textureResource, + DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch); + } + } + + // Explicitly instantiate here template class D3D11CommonContext; template class D3D11CommonContext; diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index bb4b295f0..9dedc793a 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -64,7 +64,33 @@ namespace dxvk { ~D3D11CommonContext(); + void STDMETHODCALLTYPE UpdateSubresource( + ID3D11Resource* pDstResource, + UINT DstSubresource, + const D3D11_BOX* pDstBox, + const void* pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch); + void STDMETHODCALLTYPE UpdateSubresource1( + ID3D11Resource* pDstResource, + UINT DstSubresource, + const D3D11_BOX* pDstBox, + const void* pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch, + UINT CopyFlags); + + protected: + + void UpdateResource( + ID3D11Resource* pDstResource, + UINT DstSubresource, + const D3D11_BOX* pDstBox, + const void* pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch, + UINT CopyFlags); }; diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 1304236e1..9400f0e63 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -236,31 +236,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeferredContext::UpdateSubresource( - ID3D11Resource* pDstResource, - UINT DstSubresource, - const D3D11_BOX* pDstBox, - const void* pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch) { - UpdateResource(this, pDstResource, - DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, 0); - } - - - void STDMETHODCALLTYPE D3D11DeferredContext::UpdateSubresource1( - ID3D11Resource* pDstResource, - UINT DstSubresource, - const D3D11_BOX* pDstBox, - const void* pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch, - UINT CopyFlags) { - UpdateResource(this, pDstResource, - DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags); - } - - void STDMETHODCALLTYPE D3D11DeferredContext::SwapDeviceContextState( ID3DDeviceContextState* pState, ID3DDeviceContextState** ppPreviousState) { diff --git a/src/d3d11/d3d11_context_def.h b/src/d3d11/d3d11_context_def.h index bda8725ca..d88204745 100644 --- a/src/d3d11/d3d11_context_def.h +++ b/src/d3d11/d3d11_context_def.h @@ -80,23 +80,6 @@ namespace dxvk { ID3D11Resource* pResource, UINT Subresource); - void STDMETHODCALLTYPE UpdateSubresource( - ID3D11Resource* pDstResource, - UINT DstSubresource, - const D3D11_BOX* pDstBox, - const void* pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch); - - void STDMETHODCALLTYPE UpdateSubresource1( - ID3D11Resource* pDstResource, - UINT DstSubresource, - const D3D11_BOX* pDstBox, - const void* pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch, - UINT CopyFlags); - void STDMETHODCALLTYPE SwapDeviceContextState( ID3DDeviceContextState* pState, ID3DDeviceContextState** ppPreviousState); diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index de04b9ef9..2ce43e256 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -321,31 +321,6 @@ namespace dxvk { } } - void STDMETHODCALLTYPE D3D11ImmediateContext::UpdateSubresource( - ID3D11Resource* pDstResource, - UINT DstSubresource, - const D3D11_BOX* pDstBox, - const void* pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch) { - UpdateResource(this, pDstResource, - DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, 0); - } - - - void STDMETHODCALLTYPE D3D11ImmediateContext::UpdateSubresource1( - ID3D11Resource* pDstResource, - UINT DstSubresource, - const D3D11_BOX* pDstBox, - const void* pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch, - UINT CopyFlags) { - UpdateResource(this, pDstResource, - DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags); - } - - void STDMETHODCALLTYPE D3D11ImmediateContext::OMSetRenderTargets( UINT NumViews, ID3D11RenderTargetView* const* ppRenderTargetViews, diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 2356fd505..1a0d3b762 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -78,23 +78,6 @@ namespace dxvk { ID3D11Resource* pResource, UINT Subresource); - void STDMETHODCALLTYPE UpdateSubresource( - ID3D11Resource* pDstResource, - UINT DstSubresource, - const D3D11_BOX* pDstBox, - const void* pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch); - - void STDMETHODCALLTYPE UpdateSubresource1( - ID3D11Resource* pDstResource, - UINT DstSubresource, - const D3D11_BOX* pDstBox, - const void* pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch, - UINT CopyFlags); - void STDMETHODCALLTYPE OMSetRenderTargets( UINT NumViews, ID3D11RenderTargetView* const* ppRenderTargetViews, From 4af974768a45c6520b0bed39f50f0ee20fb81010 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 17:04:33 +0200 Subject: [PATCH 0370/1348] [d3d11] Refactor D3D11UserDefinedAnnotation --- src/d3d11/d3d11_annotation.cpp | 25 +++++++++++-------------- src/d3d11/d3d11_annotation.h | 18 ++++++++++++------ src/d3d11/d3d11_context.cpp | 4 ++-- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/d3d11/d3d11_annotation.cpp b/src/d3d11/d3d11_annotation.cpp index 7c74b7ad3..2eb79d7aa 100644 --- a/src/d3d11/d3d11_annotation.cpp +++ b/src/d3d11/d3d11_annotation.cpp @@ -30,21 +30,18 @@ namespace dxvk { registrationFunction(annotation); } - D3D11UserDefinedAnnotation::D3D11UserDefinedAnnotation(D3D11DeviceContext* ctx) - : m_container(ctx), - m_eventDepth(0) { - if (m_container->IsAnnotationEnabled()) + D3D11UserDefinedAnnotation::D3D11UserDefinedAnnotation( + D3D11DeviceContext* container, + const Rc& dxvkDevice) + : m_container(container), m_eventDepth(0), + m_annotationsEnabled(dxvkDevice->instance()->extensions().extDebugUtils) { + if (m_annotationsEnabled) RegisterUserDefinedAnnotation(this); } - D3D11UserDefinedAnnotation::D3D11UserDefinedAnnotation(const D3D11UserDefinedAnnotation&) - { - if (m_container->IsAnnotationEnabled()) - RegisterUserDefinedAnnotation(this); - } D3D11UserDefinedAnnotation::~D3D11UserDefinedAnnotation() { - if (m_container->IsAnnotationEnabled()) + if (m_annotationsEnabled) RegisterUserDefinedAnnotation(this); } @@ -69,7 +66,7 @@ namespace dxvk { INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::BeginEvent( D3DCOLOR Color, LPCWSTR Name) { - if (!m_container->IsAnnotationEnabled()) + if (!m_annotationsEnabled) return -1; D3D10DeviceLock lock = m_container->LockContext(); @@ -89,7 +86,7 @@ namespace dxvk { INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::EndEvent() { - if (!m_container->IsAnnotationEnabled()) + if (!m_annotationsEnabled) return -1; D3D10DeviceLock lock = m_container->LockContext(); @@ -105,7 +102,7 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11UserDefinedAnnotation::SetMarker( D3DCOLOR Color, LPCWSTR Name) { - if (!m_container->IsAnnotationEnabled()) + if (!m_annotationsEnabled) return; D3D10DeviceLock lock = m_container->LockContext(); @@ -123,7 +120,7 @@ namespace dxvk { BOOL STDMETHODCALLTYPE D3D11UserDefinedAnnotation::GetStatus() { - return m_container->IsAnnotationEnabled(); + return m_annotationsEnabled; } } diff --git a/src/d3d11/d3d11_annotation.h b/src/d3d11/d3d11_annotation.h index 06d80af61..8419b92cc 100644 --- a/src/d3d11/d3d11_annotation.h +++ b/src/d3d11/d3d11_annotation.h @@ -1,7 +1,9 @@ #pragma once #include "d3d11_include.h" + #include "../dxvk/dxvk_annotation.h" +#include "../dxvk/dxvk_device.h" namespace dxvk { @@ -11,10 +13,15 @@ namespace dxvk { public: - D3D11UserDefinedAnnotation(D3D11DeviceContext* ctx); - D3D11UserDefinedAnnotation(const D3D11UserDefinedAnnotation&); + D3D11UserDefinedAnnotation( + D3D11DeviceContext* container, + const Rc& dxvkDevice); + ~D3D11UserDefinedAnnotation(); + D3D11UserDefinedAnnotation (const D3D11UserDefinedAnnotation&) = delete; + D3D11UserDefinedAnnotation& operator = (const D3D11UserDefinedAnnotation&) = delete; + ULONG STDMETHODCALLTYPE AddRef(); ULONG STDMETHODCALLTYPE Release(); @@ -37,10 +44,9 @@ namespace dxvk { private: - D3D11DeviceContext* m_container; - - // Stack depth for non-finalized BeginEvent calls - int32_t m_eventDepth; + D3D11DeviceContext* m_container; + int32_t m_eventDepth; + bool m_annotationsEnabled; }; } diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 8aff2312e..9920150cc 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -19,7 +19,7 @@ namespace dxvk { m_multithread(this, false), m_device (Device), m_staging (Device, StagingBufferSize), - m_annotation(this), + m_annotation(this, Device), m_csFlags (CsFlags), m_csChunk (AllocCsChunk()), m_cmdData (nullptr) { @@ -2821,7 +2821,7 @@ namespace dxvk { BOOL STDMETHODCALLTYPE D3D11DeviceContext::IsAnnotationEnabled() { - return m_device->instance()->extensions().extDebugUtils; + return m_annotation.GetStatus(); } From 10345d006361c0b394af83d58e9911e7a6509555 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 17:09:30 +0200 Subject: [PATCH 0371/1348] [d3d11] Move QueryInterface to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 40 ----------------------------- src/d3d11/d3d11_context.h | 4 --- src/d3d11/d3d11_context_common.cpp | 41 ++++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 4 +++ src/d3d11/d3d11_context_imm.cpp | 2 +- 5 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 9920150cc..6ca5ca272 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -32,46 +32,6 @@ namespace dxvk { } - HRESULT STDMETHODCALLTYPE D3D11DeviceContext::QueryInterface(REFIID riid, void** ppvObject) { - if (ppvObject == nullptr) - return E_POINTER; - - *ppvObject = nullptr; - - if (riid == __uuidof(IUnknown) - || riid == __uuidof(ID3D11DeviceChild) - || riid == __uuidof(ID3D11DeviceContext) - || riid == __uuidof(ID3D11DeviceContext1) - || riid == __uuidof(ID3D11DeviceContext2) - || riid == __uuidof(ID3D11DeviceContext3) - || riid == __uuidof(ID3D11DeviceContext4)) { - *ppvObject = ref(this); - return S_OK; - } - - if (riid == __uuidof(ID3D11VkExtContext) - || riid == __uuidof(ID3D11VkExtContext1)) { - *ppvObject = ref(&m_contextExt); - return S_OK; - } - - if (riid == __uuidof(ID3DUserDefinedAnnotation) - || riid == __uuidof(IDXVKUserDefinedAnnotation)) { - *ppvObject = ref(&m_annotation); - return S_OK; - } - - if (riid == __uuidof(ID3D10Multithread)) { - *ppvObject = ref(&m_multithread); - return S_OK; - } - - Logger::warn("D3D11DeviceContext::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); - return E_NOINTERFACE; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::DiscardResource(ID3D11Resource* pResource) { D3D10DeviceLock lock = LockContext(); diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 361e0fd6d..9fb3724a7 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -32,10 +32,6 @@ namespace dxvk { DxvkCsChunkFlags CsFlags); ~D3D11DeviceContext(); - HRESULT STDMETHODCALLTYPE QueryInterface( - REFIID riid, - void** ppvObject); - void STDMETHODCALLTYPE DiscardResource(ID3D11Resource *pResource); void STDMETHODCALLTYPE DiscardView(ID3D11View* pResourceView); diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 4e4adfdde..ffe4ac16f 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -20,6 +20,47 @@ namespace dxvk { } + template + HRESULT STDMETHODCALLTYPE D3D11CommonContext::QueryInterface(REFIID riid, void** ppvObject) { + if (ppvObject == nullptr) + return E_POINTER; + + *ppvObject = nullptr; + + if (riid == __uuidof(IUnknown) + || riid == __uuidof(ID3D11DeviceChild) + || riid == __uuidof(ID3D11DeviceContext) + || riid == __uuidof(ID3D11DeviceContext1) + || riid == __uuidof(ID3D11DeviceContext2) + || riid == __uuidof(ID3D11DeviceContext3) + || riid == __uuidof(ID3D11DeviceContext4)) { + *ppvObject = ref(this); + return S_OK; + } + + if (riid == __uuidof(ID3D11VkExtContext) + || riid == __uuidof(ID3D11VkExtContext1)) { + *ppvObject = ref(&m_contextExt); + return S_OK; + } + + if (riid == __uuidof(ID3DUserDefinedAnnotation) + || riid == __uuidof(IDXVKUserDefinedAnnotation)) { + *ppvObject = ref(&m_annotation); + return S_OK; + } + + if (riid == __uuidof(ID3D10Multithread)) { + *ppvObject = ref(&m_multithread); + return S_OK; + } + + Logger::warn("D3D11DeviceContext::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + return E_NOINTERFACE; + } + + template void STDMETHODCALLTYPE D3D11CommonContext::UpdateSubresource( ID3D11Resource* pDstResource, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 9dedc793a..cc04fe5aa 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -64,6 +64,10 @@ namespace dxvk { ~D3D11CommonContext(); + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + void STDMETHODCALLTYPE UpdateSubresource( ID3D11Resource* pDstResource, UINT DstSubresource, diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 2ce43e256..c26b4ad3e 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -57,7 +57,7 @@ namespace dxvk { return S_OK; } - return D3D11DeviceContext::QueryInterface(riid, ppvObject); + return D3D11CommonContext::QueryInterface(riid, ppvObject); } From 3f5f731c42e8be12699f52629139386ab07581b0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 17:13:32 +0200 Subject: [PATCH 0372/1348] [d3d11] Move D3D11UserDefinedAnnotation member to D3D11CommonContext This needs to be temlpated because we'll be moving EmitCs to the common implementation as well, and make EmitCsChunk non-virtual. --- src/d3d11/d3d11_annotation.cpp | 41 ++++++++++++++++++++---------- src/d3d11/d3d11_annotation.h | 16 +++++++----- src/d3d11/d3d11_context.cpp | 6 ----- src/d3d11/d3d11_context.h | 6 +---- src/d3d11/d3d11_context_common.cpp | 9 ++++++- src/d3d11/d3d11_context_common.h | 4 +++ 6 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/d3d11/d3d11_annotation.cpp b/src/d3d11/d3d11_annotation.cpp index 2eb79d7aa..b46dfe41e 100644 --- a/src/d3d11/d3d11_annotation.cpp +++ b/src/d3d11/d3d11_annotation.cpp @@ -1,5 +1,6 @@ #include "d3d11_annotation.h" -#include "d3d11_context.h" +#include "d3d11_context_def.h" +#include "d3d11_context_imm.h" #include "d3d11_device.h" #include "../util/util_misc.h" @@ -30,40 +31,47 @@ namespace dxvk { registrationFunction(annotation); } - D3D11UserDefinedAnnotation::D3D11UserDefinedAnnotation( - D3D11DeviceContext* container, + + template + D3D11UserDefinedAnnotation::D3D11UserDefinedAnnotation( + ContextType* container, const Rc& dxvkDevice) : m_container(container), m_eventDepth(0), m_annotationsEnabled(dxvkDevice->instance()->extensions().extDebugUtils) { - if (m_annotationsEnabled) + if (!IsDeferred && m_annotationsEnabled) RegisterUserDefinedAnnotation(this); } - D3D11UserDefinedAnnotation::~D3D11UserDefinedAnnotation() { - if (m_annotationsEnabled) + template + D3D11UserDefinedAnnotation::~D3D11UserDefinedAnnotation() { + if (!IsDeferred && m_annotationsEnabled) RegisterUserDefinedAnnotation(this); } - ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation::AddRef() { + template + ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation::AddRef() { return m_container->AddRef(); } - ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation::Release() { + template + ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation::Release() { return m_container->Release(); } - HRESULT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::QueryInterface( + template + HRESULT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::QueryInterface( REFIID riid, void** ppvObject) { return m_container->QueryInterface(riid, ppvObject); } - INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::BeginEvent( + template + INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::BeginEvent( D3DCOLOR Color, LPCWSTR Name) { if (!m_annotationsEnabled) @@ -85,7 +93,8 @@ namespace dxvk { } - INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::EndEvent() { + template + INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::EndEvent() { if (!m_annotationsEnabled) return -1; @@ -99,7 +108,8 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11UserDefinedAnnotation::SetMarker( + template + void STDMETHODCALLTYPE D3D11UserDefinedAnnotation::SetMarker( D3DCOLOR Color, LPCWSTR Name) { if (!m_annotationsEnabled) @@ -119,8 +129,13 @@ namespace dxvk { } - BOOL STDMETHODCALLTYPE D3D11UserDefinedAnnotation::GetStatus() { + template + BOOL STDMETHODCALLTYPE D3D11UserDefinedAnnotation::GetStatus() { return m_annotationsEnabled; } + + template class D3D11UserDefinedAnnotation; + template class D3D11UserDefinedAnnotation; + } diff --git a/src/d3d11/d3d11_annotation.h b/src/d3d11/d3d11_annotation.h index 8419b92cc..ec569a9a0 100644 --- a/src/d3d11/d3d11_annotation.h +++ b/src/d3d11/d3d11_annotation.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "d3d11_include.h" #include "../dxvk/dxvk_annotation.h" @@ -7,14 +9,16 @@ namespace dxvk { - class D3D11DeviceContext; + class D3D11DeferredContext; + class D3D11ImmediateContext; + template class D3D11UserDefinedAnnotation final : public IDXVKUserDefinedAnnotation { - + constexpr static bool IsDeferred = std::is_same_v; public: D3D11UserDefinedAnnotation( - D3D11DeviceContext* container, + ContextType* container, const Rc& dxvkDevice); ~D3D11UserDefinedAnnotation(); @@ -44,9 +48,9 @@ namespace dxvk { private: - D3D11DeviceContext* m_container; - int32_t m_eventDepth; - bool m_annotationsEnabled; + ContextType* m_container; + int32_t m_eventDepth; + bool m_annotationsEnabled; }; } diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 6ca5ca272..f9251f447 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -19,7 +19,6 @@ namespace dxvk { m_multithread(this, false), m_device (Device), m_staging (Device, StagingBufferSize), - m_annotation(this, Device), m_csFlags (CsFlags), m_csChunk (AllocCsChunk()), m_cmdData (nullptr) { @@ -2780,11 +2779,6 @@ namespace dxvk { } - BOOL STDMETHODCALLTYPE D3D11DeviceContext::IsAnnotationEnabled() { - return m_annotation.GetStatus(); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::SetMarkerInt( LPCWSTR pLabel, INT Data) { diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 9fb3724a7..93e85e879 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -21,6 +21,7 @@ namespace dxvk { class D3D11DeviceContext : public D3D11DeviceChild { friend class D3D11DeviceContextExt; // Needed in order to call EmitCs for pushing markers + template friend class D3D11UserDefinedAnnotation; constexpr static VkDeviceSize StagingBufferSize = 4ull << 20; @@ -658,8 +659,6 @@ namespace dxvk { ID3D11Buffer** ppSOTargets, UINT* pOffsets); - BOOL STDMETHODCALLTYPE IsAnnotationEnabled(); - void STDMETHODCALLTYPE SetMarkerInt( LPCWSTR pLabel, INT Data); @@ -695,9 +694,6 @@ namespace dxvk { Rc m_updateBuffer; DxvkStagingBuffer m_staging; - - //has to be declared after m_device, as compiler initialize in order of declaration in the class - D3D11UserDefinedAnnotation m_annotation; DxvkCsChunkFlags m_csFlags; DxvkCsChunkRef m_csChunk; diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index ffe4ac16f..786e9840c 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -9,7 +9,8 @@ namespace dxvk { D3D11Device* pParent, const Rc& Device, DxvkCsChunkFlags CsFlags) - : D3D11DeviceContext(pParent, Device, CsFlags) { + : D3D11DeviceContext(pParent, Device, CsFlags), + m_annotation(static_cast(this), Device) { } @@ -88,6 +89,12 @@ namespace dxvk { } + template + BOOL STDMETHODCALLTYPE D3D11CommonContext::IsAnnotationEnabled() { + return m_annotation.GetStatus(); + } + + template void D3D11CommonContext::UpdateResource( ID3D11Resource* pDstResource, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index cc04fe5aa..8161142bf 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -85,8 +85,12 @@ namespace dxvk { UINT SrcDepthPitch, UINT CopyFlags); + BOOL STDMETHODCALLTYPE IsAnnotationEnabled(); + protected: + D3D11UserDefinedAnnotation m_annotation; + void UpdateResource( ID3D11Resource* pDstResource, UINT DstSubresource, From a7c25a01f2ad3c3eb316b2b8e7584c84f6d1ffc3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 17:24:34 +0200 Subject: [PATCH 0373/1348] [d3d11] Move D3D11DeviceContextExt to D3D11CommonContext Will be needed for both EmitCs and TrackSequenceNumber functions. --- src/d3d11/d3d11_context.cpp | 1 - src/d3d11/d3d11_context.h | 2 +- src/d3d11/d3d11_context_common.cpp | 1 + src/d3d11/d3d11_context_common.h | 1 + src/d3d11/d3d11_context_ext.cpp | 43 +++++++++++++++++++++--------- src/d3d11/d3d11_context_ext.h | 8 +++--- 6 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index f9251f447..17656170d 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -15,7 +15,6 @@ namespace dxvk { const Rc& Device, DxvkCsChunkFlags CsFlags) : D3D11DeviceChild(pParent), - m_contextExt(this), m_multithread(this, false), m_device (Device), m_staging (Device, StagingBufferSize), diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 93e85e879..4e153f254 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -19,6 +19,7 @@ namespace dxvk { class D3D11Device; class D3D11DeviceContext : public D3D11DeviceChild { + template friend class D3D11DeviceContextExt; // Needed in order to call EmitCs for pushing markers template @@ -687,7 +688,6 @@ namespace dxvk { protected: - D3D11DeviceContextExt m_contextExt; D3D10Multithread m_multithread; Rc m_device; diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 786e9840c..188d9b344 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -10,6 +10,7 @@ namespace dxvk { const Rc& Device, DxvkCsChunkFlags CsFlags) : D3D11DeviceContext(pParent, Device, CsFlags), + m_contextExt(static_cast(this)), m_annotation(static_cast(this), Device) { } diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 8161142bf..544e8b0c9 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -89,6 +89,7 @@ namespace dxvk { protected: + D3D11DeviceContextExt m_contextExt; D3D11UserDefinedAnnotation m_annotation; void UpdateResource( diff --git a/src/d3d11/d3d11_context_ext.cpp b/src/d3d11/d3d11_context_ext.cpp index ecd41e832..c89e0bc06 100644 --- a/src/d3d11/d3d11_context_ext.cpp +++ b/src/d3d11/d3d11_context_ext.cpp @@ -3,38 +3,44 @@ #include #include "d3d11_device.h" -#include "d3d11_context.h" +#include "d3d11_context_imm.h" +#include "d3d11_context_def.h" #include "d3d11_cuda.h" #include "../util/log/log.h" namespace dxvk { - D3D11DeviceContextExt::D3D11DeviceContextExt( - D3D11DeviceContext* pContext) + template + D3D11DeviceContextExt::D3D11DeviceContextExt( + ContextType* pContext) : m_ctx(pContext) { } - ULONG STDMETHODCALLTYPE D3D11DeviceContextExt::AddRef() { + template + ULONG STDMETHODCALLTYPE D3D11DeviceContextExt::AddRef() { return m_ctx->AddRef(); } - ULONG STDMETHODCALLTYPE D3D11DeviceContextExt::Release() { + template + ULONG STDMETHODCALLTYPE D3D11DeviceContextExt::Release() { return m_ctx->Release(); } - HRESULT STDMETHODCALLTYPE D3D11DeviceContextExt::QueryInterface( + template + HRESULT STDMETHODCALLTYPE D3D11DeviceContextExt::QueryInterface( REFIID riid, void** ppvObject) { return m_ctx->QueryInterface(riid, ppvObject); } - void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndirect( + template + void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndirect( UINT DrawCount, ID3D11Buffer* pBufferForArgs, UINT ByteOffsetForArgs, @@ -52,7 +58,8 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndexedIndirect( + template + void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndexedIndirect( UINT DrawCount, ID3D11Buffer* pBufferForArgs, UINT ByteOffsetForArgs, @@ -70,7 +77,8 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndirectCount( + template + void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndirectCount( UINT MaxDrawCount, ID3D11Buffer* pBufferForCount, UINT ByteOffsetForCount, @@ -91,7 +99,8 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndexedIndirectCount( + template + void STDMETHODCALLTYPE D3D11DeviceContextExt::MultiDrawIndexedIndirectCount( UINT MaxDrawCount, ID3D11Buffer* pBufferForCount, UINT ByteOffsetForCount, @@ -112,7 +121,8 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContextExt::SetDepthBoundsTest( + template + void STDMETHODCALLTYPE D3D11DeviceContextExt::SetDepthBoundsTest( BOOL Enable, FLOAT MinDepthBounds, FLOAT MaxDepthBounds) { @@ -129,7 +139,8 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContextExt::SetBarrierControl( + template + void STDMETHODCALLTYPE D3D11DeviceContextExt::SetBarrierControl( UINT ControlFlags) { D3D10DeviceLock lock = m_ctx->LockContext(); DxvkBarrierControlFlags flags; @@ -146,7 +157,8 @@ namespace dxvk { } - bool STDMETHODCALLTYPE D3D11DeviceContextExt::LaunchCubinShaderNVX(IUnknown* hShader, uint32_t GridX, uint32_t GridY, uint32_t GridZ, + template + bool STDMETHODCALLTYPE D3D11DeviceContextExt::LaunchCubinShaderNVX(IUnknown* hShader, uint32_t GridX, uint32_t GridY, uint32_t GridZ, const void* pParams, uint32_t ParamSize, void* const* pReadResources, uint32_t NumReadResources, void* const* pWriteResources, uint32_t NumWriteResources) { D3D10DeviceLock lock = m_ctx->LockContext(); @@ -202,4 +214,9 @@ namespace dxvk { return true; } + + + template class D3D11DeviceContextExt; + template class D3D11DeviceContextExt; + } diff --git a/src/d3d11/d3d11_context_ext.h b/src/d3d11/d3d11_context_ext.h index 2109a0dea..6b95dcf95 100644 --- a/src/d3d11/d3d11_context_ext.h +++ b/src/d3d11/d3d11_context_ext.h @@ -4,14 +4,16 @@ namespace dxvk { - class D3D11DeviceContext; + class D3D11DeferredContext; + class D3D11ImmediateContext; + template class D3D11DeviceContextExt : public ID3D11VkExtContext1 { public: D3D11DeviceContextExt( - D3D11DeviceContext* pContext); + ContextType* pContext); ULONG STDMETHODCALLTYPE AddRef(); @@ -71,7 +73,7 @@ namespace dxvk { private: - D3D11DeviceContext* m_ctx; + ContextType* m_ctx; }; From 43661abbfc1cb8d3669c810fa48a1df0f93e8f79 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 17:55:39 +0200 Subject: [PATCH 0374/1348] [d3d11] Add binding methods to D3D11CommonContext Uses mutable lambdas to avoid redundant ref counting on immediate contexts. --- src/d3d11/d3d11_context_common.cpp | 266 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 56 ++++++ 2 files changed, 322 insertions(+) diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 188d9b344..e694fadf6 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -96,6 +96,272 @@ namespace dxvk { } + template + template + void D3D11CommonContext::BindShader( + const D3D11CommonShader* pShaderModule) { + // Bind the shader and the ICB at once + EmitCs([ + cSlice = pShaderModule != nullptr + && pShaderModule->GetIcb() != nullptr + ? DxvkBufferSlice(pShaderModule->GetIcb()) + : DxvkBufferSlice(), + cShader = pShaderModule != nullptr + ? pShaderModule->GetShader() + : nullptr + ] (DxvkContext* ctx) mutable { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + + uint32_t slotId = computeConstantBufferBinding(ShaderStage, + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); + + ctx->bindShader(stage, + Forwarder::move(cShader)); + ctx->bindResourceBuffer(stage, slotId, + Forwarder::move(cSlice)); + }); + } + + + template + void D3D11CommonContext::BindFramebuffer() { + DxvkRenderTargets attachments; + uint32_t sampleCount = 0; + + // D3D11 doesn't have the concept of a framebuffer object, + // so we'll just create a new one every time the render + // target bindings are updated. Set up the attachments. + for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) { + if (m_state.om.renderTargetViews[i] != nullptr) { + attachments.color[i] = { + m_state.om.renderTargetViews[i]->GetImageView(), + m_state.om.renderTargetViews[i]->GetRenderLayout() }; + sampleCount = m_state.om.renderTargetViews[i]->GetSampleCount(); + } + } + + if (m_state.om.depthStencilView != nullptr) { + attachments.depth = { + m_state.om.depthStencilView->GetImageView(), + m_state.om.depthStencilView->GetRenderLayout() }; + sampleCount = m_state.om.depthStencilView->GetSampleCount(); + } + + // Create and bind the framebuffer object to the context + EmitCs([ + cAttachments = std::move(attachments) + ] (DxvkContext* ctx) mutable { + ctx->bindRenderTargets(Forwarder::move(cAttachments)); + }); + + // If necessary, update push constant for the sample count + if (m_state.om.sampleCount != sampleCount) { + m_state.om.sampleCount = sampleCount; + ApplyRasterizerSampleCount(); + } + } + + + template + void D3D11CommonContext::BindDrawBuffers( + D3D11Buffer* pBufferForArgs, + D3D11Buffer* pBufferForCount) { + EmitCs([ + cArgBuffer = pBufferForArgs ? pBufferForArgs->GetBufferSlice() : DxvkBufferSlice(), + cCntBuffer = pBufferForCount ? pBufferForCount->GetBufferSlice() : DxvkBufferSlice() + ] (DxvkContext* ctx) mutable { + ctx->bindDrawBuffers( + Forwarder::move(cArgBuffer), + Forwarder::move(cCntBuffer)); + }); + } + + + template + void D3D11CommonContext::BindVertexBuffer( + UINT Slot, + D3D11Buffer* pBuffer, + UINT Offset, + UINT Stride) { + if (likely(pBuffer != nullptr)) { + EmitCs([ + cSlotId = Slot, + cBufferSlice = pBuffer->GetBufferSlice(Offset), + cStride = Stride + ] (DxvkContext* ctx) mutable { + ctx->bindVertexBuffer(cSlotId, + Forwarder::move(cBufferSlice), + cStride); + }); + } else { + EmitCs([ + cSlotId = Slot + ] (DxvkContext* ctx) { + ctx->bindVertexBuffer(cSlotId, DxvkBufferSlice(), 0); + }); + } + } + + + template + void D3D11CommonContext::BindIndexBuffer( + D3D11Buffer* pBuffer, + UINT Offset, + DXGI_FORMAT Format) { + VkIndexType indexType = Format == DXGI_FORMAT_R16_UINT + ? VK_INDEX_TYPE_UINT16 + : VK_INDEX_TYPE_UINT32; + + EmitCs([ + cBufferSlice = pBuffer != nullptr ? pBuffer->GetBufferSlice(Offset) : DxvkBufferSlice(), + cIndexType = indexType + ] (DxvkContext* ctx) mutable { + ctx->bindIndexBuffer( + Forwarder::move(cBufferSlice), + cIndexType); + }); + } + + + template + void D3D11CommonContext::BindXfbBuffer( + UINT Slot, + D3D11Buffer* pBuffer, + UINT Offset) { + DxvkBufferSlice bufferSlice; + DxvkBufferSlice counterSlice; + + if (pBuffer != nullptr) { + bufferSlice = pBuffer->GetBufferSlice(); + counterSlice = pBuffer->GetSOCounter(); + } + + EmitCs([ + cSlotId = Slot, + cOffset = Offset, + cBufferSlice = bufferSlice, + cCounterSlice = counterSlice + ] (DxvkContext* ctx) mutable { + if (cCounterSlice.defined() && cOffset != ~0u) { + ctx->updateBuffer( + cCounterSlice.buffer(), + cCounterSlice.offset(), + sizeof(cOffset), + &cOffset); + } + + ctx->bindXfbBuffer(cSlotId, + Forwarder::move(cBufferSlice), + Forwarder::move(cCounterSlice)); + }); + } + + + template + template + void D3D11CommonContext::BindConstantBuffer( + UINT Slot, + D3D11Buffer* pBuffer, + UINT Offset, + UINT Length) { + EmitCs([ + cSlotId = Slot, + cBufferSlice = pBuffer ? pBuffer->GetBufferSlice(16 * Offset, 16 * Length) : DxvkBufferSlice() + ] (DxvkContext* ctx) mutable { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceBuffer(stage, cSlotId, + Forwarder::move(cBufferSlice)); + }); + } + + + template + template + void D3D11CommonContext::BindConstantBufferRange( + UINT Slot, + UINT Offset, + UINT Length) { + EmitCs([ + cSlotId = Slot, + cOffset = 16 * Offset, + cLength = 16 * Length + ] (DxvkContext* ctx) { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceBufferRange(stage, cSlotId, cOffset, cLength); + }); + } + + + template + template + void D3D11CommonContext::BindSampler( + UINT Slot, + D3D11SamplerState* pSampler) { + EmitCs([ + cSlotId = Slot, + cSampler = pSampler != nullptr ? pSampler->GetDXVKSampler() : nullptr + ] (DxvkContext* ctx) mutable { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceSampler(stage, cSlotId, + Forwarder::move(cSampler)); + }); + } + + + template + template + void D3D11CommonContext::BindShaderResource( + UINT Slot, + D3D11ShaderResourceView* pResource) { + EmitCs([ + cSlotId = Slot, + cImageView = pResource != nullptr ? pResource->GetImageView() : nullptr, + cBufferView = pResource != nullptr ? pResource->GetBufferView() : nullptr + ] (DxvkContext* ctx) mutable { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceView(stage, cSlotId, + Forwarder::move(cImageView), + Forwarder::move(cBufferView)); + }); + } + + + template + template + void D3D11CommonContext::BindUnorderedAccessView( + UINT UavSlot, + D3D11UnorderedAccessView* pUav, + UINT CtrSlot, + UINT Counter) { + EmitCs([ + cUavSlotId = UavSlot, + cCtrSlotId = CtrSlot, + cImageView = pUav != nullptr ? pUav->GetImageView() : nullptr, + cBufferView = pUav != nullptr ? pUav->GetBufferView() : nullptr, + cCounterSlice = pUav != nullptr ? pUav->GetCounterSlice() : DxvkBufferSlice(), + cCounterValue = Counter + ] (DxvkContext* ctx) mutable { + VkShaderStageFlags stages = ShaderStage == DxbcProgramType::PixelShader + ? VK_SHADER_STAGE_ALL_GRAPHICS + : VK_SHADER_STAGE_COMPUTE_BIT; + + if (cCounterSlice.defined() && cCounterValue != ~0u) { + ctx->updateBuffer( + cCounterSlice.buffer(), + cCounterSlice.offset(), + sizeof(uint32_t), + &cCounterValue); + } + + ctx->bindResourceView(stages, cUavSlotId, + Forwarder::move(cImageView), + Forwarder::move(cBufferView)); + ctx->bindResourceBuffer(stages, cCtrSlotId, + Forwarder::move(cCounterSlice)); + }); + } + + template void D3D11CommonContext::UpdateResource( ID3D11Resource* pDstResource, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 544e8b0c9..49b2870ef 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -92,6 +92,62 @@ namespace dxvk { D3D11DeviceContextExt m_contextExt; D3D11UserDefinedAnnotation m_annotation; + template + void BindShader( + const D3D11CommonShader* pShaderModule); + + void BindFramebuffer(); + + void BindDrawBuffers( + D3D11Buffer* pBufferForArgs, + D3D11Buffer* pBufferForCount); + + void BindVertexBuffer( + UINT Slot, + D3D11Buffer* pBuffer, + UINT Offset, + UINT Stride); + + void BindIndexBuffer( + D3D11Buffer* pBuffer, + UINT Offset, + DXGI_FORMAT Format); + + void BindXfbBuffer( + UINT Slot, + D3D11Buffer* pBuffer, + UINT Offset); + + template + void BindConstantBuffer( + UINT Slot, + D3D11Buffer* pBuffer, + UINT Offset, + UINT Length); + + template + void BindConstantBufferRange( + UINT Slot, + UINT Offset, + UINT Length); + + template + void BindSampler( + UINT Slot, + D3D11SamplerState* pSampler); + + template + void BindShaderResource( + UINT Slot, + D3D11ShaderResourceView* pResource); + + template + void BindUnorderedAccessView( + UINT UavSlot, + D3D11UnorderedAccessView* pUav, + UINT CtrSlot, + UINT Counter); + void UpdateResource( ID3D11Resource* pDstResource, UINT DstSubresource, From 5a45677a39c58b58cd583ce8ba21a70b32118ee4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 17:58:42 +0200 Subject: [PATCH 0375/1348] [d3d11] Add hazard tracking methods to D3D11CommonContext --- src/d3d11/d3d11_context_common.cpp | 168 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 38 +++++++ 2 files changed, 206 insertions(+) diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index e694fadf6..ebbdc3ed8 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -362,6 +362,174 @@ namespace dxvk { } + template + template + void D3D11CommonContext::ResolveSrvHazards( + T* pView, + D3D11ShaderResourceBindings& Bindings) { + uint32_t slotId = computeSrvBinding(ShaderStage, 0); + int32_t srvId = Bindings.hazardous.findNext(0); + + while (srvId >= 0) { + auto srv = Bindings.views[srvId].ptr(); + + if (likely(srv && srv->TestHazards())) { + bool hazard = CheckViewOverlap(pView, srv); + + if (unlikely(hazard)) { + Bindings.views[srvId] = nullptr; + Bindings.hazardous.clr(srvId); + + BindShaderResource(slotId + srvId, nullptr); + } + } else { + // Avoid further redundant iterations + Bindings.hazardous.clr(srvId); + } + + srvId = Bindings.hazardous.findNext(srvId + 1); + } + } + + + template + template + void D3D11CommonContext::ResolveCsSrvHazards( + T* pView) { + if (!pView) return; + ResolveSrvHazards (pView, m_state.cs.shaderResources); + } + + + template + template + void D3D11CommonContext::ResolveOmSrvHazards( + T* pView) { + if (!pView) return; + ResolveSrvHazards (pView, m_state.vs.shaderResources); + ResolveSrvHazards (pView, m_state.hs.shaderResources); + ResolveSrvHazards (pView, m_state.ds.shaderResources); + ResolveSrvHazards (pView, m_state.gs.shaderResources); + ResolveSrvHazards (pView, m_state.ps.shaderResources); + } + + + template + bool D3D11CommonContext::ResolveOmRtvHazards( + D3D11UnorderedAccessView* pView) { + if (!pView || !pView->HasBindFlag(D3D11_BIND_RENDER_TARGET)) + return false; + + bool hazard = false; + + if (CheckViewOverlap(pView, m_state.om.depthStencilView.ptr())) { + m_state.om.depthStencilView = nullptr; + hazard = true; + } + + for (uint32_t i = 0; i < m_state.om.maxRtv; i++) { + if (CheckViewOverlap(pView, m_state.om.renderTargetViews[i].ptr())) { + m_state.om.renderTargetViews[i] = nullptr; + hazard = true; + } + } + + return hazard; + } + + + template + void D3D11CommonContext::ResolveOmUavHazards( + D3D11RenderTargetView* pView) { + if (!pView || !pView->HasBindFlag(D3D11_BIND_UNORDERED_ACCESS)) + return; + + uint32_t uavSlotId = computeUavBinding (DxbcProgramType::PixelShader, 0); + uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0); + + for (uint32_t i = 0; i < m_state.om.maxUav; i++) { + if (CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr())) { + m_state.ps.unorderedAccessViews[i] = nullptr; + + BindUnorderedAccessView( + uavSlotId + i, nullptr, + ctrSlotId + i, ~0u); + } + } + } + + + template + bool D3D11CommonContext::TestRtvUavHazards( + UINT NumRTVs, + ID3D11RenderTargetView* const* ppRTVs, + UINT NumUAVs, + ID3D11UnorderedAccessView* const* ppUAVs) { + if (NumRTVs == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) NumRTVs = 0; + if (NumUAVs == D3D11_KEEP_UNORDERED_ACCESS_VIEWS) NumUAVs = 0; + + for (uint32_t i = 0; i < NumRTVs; i++) { + auto rtv = static_cast(ppRTVs[i]); + + if (!rtv) + continue; + + for (uint32_t j = 0; j < i; j++) { + if (CheckViewOverlap(rtv, static_cast(ppRTVs[j]))) + return true; + } + + if (rtv->HasBindFlag(D3D11_BIND_UNORDERED_ACCESS)) { + for (uint32_t j = 0; j < NumUAVs; j++) { + if (CheckViewOverlap(rtv, static_cast(ppUAVs[j]))) + return true; + } + } + } + + for (uint32_t i = 0; i < NumUAVs; i++) { + auto uav = static_cast(ppUAVs[i]); + + if (!uav) + continue; + + for (uint32_t j = 0; j < i; j++) { + if (CheckViewOverlap(uav, static_cast(ppUAVs[j]))) + return true; + } + } + + return false; + } + + + template + template + bool D3D11CommonContext::TestSrvHazards( + D3D11ShaderResourceView* pView) { + bool hazard = false; + + if (ShaderStage == DxbcProgramType::ComputeShader) { + int32_t uav = m_state.cs.uavMask.findNext(0); + + while (uav >= 0 && !hazard) { + hazard = CheckViewOverlap(pView, m_state.cs.unorderedAccessViews[uav].ptr()); + uav = m_state.cs.uavMask.findNext(uav + 1); + } + } else { + hazard = CheckViewOverlap(pView, m_state.om.depthStencilView.ptr()); + + for (uint32_t i = 0; !hazard && i < m_state.om.maxRtv; i++) + hazard = CheckViewOverlap(pView, m_state.om.renderTargetViews[i].ptr()); + + for (uint32_t i = 0; !hazard && i < m_state.om.maxUav; i++) + hazard = CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr()); + } + + return hazard; + } + + template void D3D11CommonContext::UpdateResource( ID3D11Resource* pDstResource, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 49b2870ef..f5e3ac1eb 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -148,6 +148,44 @@ namespace dxvk { UINT CtrSlot, UINT Counter); + template + void ResolveSrvHazards( + T* pView, + D3D11ShaderResourceBindings& Bindings); + + template + void ResolveCsSrvHazards( + T* pView); + + template + void ResolveOmSrvHazards( + T* pView); + + bool ResolveOmRtvHazards( + D3D11UnorderedAccessView* pView); + + void ResolveOmUavHazards( + D3D11RenderTargetView* pView); + + void SetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView, + UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, + const UINT* pUAVInitialCounts); + + bool TestRtvUavHazards( + UINT NumRTVs, + ID3D11RenderTargetView* const* ppRTVs, + UINT NumUAVs, + ID3D11UnorderedAccessView* const* ppUAVs); + + template + bool TestSrvHazards( + D3D11ShaderResourceView* pView); + void UpdateResource( ID3D11Resource* pDstResource, UINT DstSubresource, From 77c032da5c0299bb426d740e463ab4c8171e15a6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 18:07:03 +0200 Subject: [PATCH 0376/1348] [d3d11] Move OM* functions to D3D11CommonContext We can get rid of the immediate context overload as well since we can just directly call FlushImplicit here. --- src/d3d11/d3d11_context.cpp | 325 ----------------------------- src/d3d11/d3d11_context.h | 60 ------ src/d3d11/d3d11_context_common.cpp | 306 ++++++++++++++++++++++++++- src/d3d11/d3d11_context_common.h | 56 +++++ src/d3d11/d3d11_context_imm.cpp | 27 --- src/d3d11/d3d11_context_imm.h | 14 -- 6 files changed, 360 insertions(+), 428 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 17656170d..0d4b27f55 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2353,215 +2353,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::OMSetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView) { - OMSetRenderTargetsAndUnorderedAccessViews( - NumViews, ppRenderTargetViews, pDepthStencilView, - NumViews, 0, nullptr, nullptr); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - const UINT* pUAVInitialCounts) { - D3D10DeviceLock lock = LockContext(); - - if (TestRtvUavHazards(NumRTVs, ppRenderTargetViews, NumUAVs, ppUnorderedAccessViews)) - return; - - bool needsUpdate = false; - - if (likely(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL)) { - // Native D3D11 does not change the render targets if - // the parameters passed to this method are invalid. - if (!ValidateRenderTargets(NumRTVs, ppRenderTargetViews, pDepthStencilView)) - return; - - for (uint32_t i = 0; i < m_state.om.renderTargetViews.size(); i++) { - auto rtv = i < NumRTVs - ? static_cast(ppRenderTargetViews[i]) - : nullptr; - - if (m_state.om.renderTargetViews[i] != rtv) { - m_state.om.renderTargetViews[i] = rtv; - needsUpdate = true; - ResolveOmSrvHazards(rtv); - - if (NumUAVs == D3D11_KEEP_UNORDERED_ACCESS_VIEWS) - ResolveOmUavHazards(rtv); - } - } - - auto dsv = static_cast(pDepthStencilView); - - if (m_state.om.depthStencilView != dsv) { - m_state.om.depthStencilView = dsv; - needsUpdate = true; - ResolveOmSrvHazards(dsv); - } - - m_state.om.maxRtv = NumRTVs; - } - - if (unlikely(NumUAVs || m_state.om.maxUav)) { - uint32_t uavSlotId = computeUavBinding (DxbcProgramType::PixelShader, 0); - uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0); - - if (likely(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS)) { - uint32_t newMaxUav = NumUAVs ? UAVStartSlot + NumUAVs : 0; - uint32_t oldMaxUav = std::exchange(m_state.om.maxUav, newMaxUav); - - for (uint32_t i = 0; i < std::max(oldMaxUav, newMaxUav); i++) { - D3D11UnorderedAccessView* uav = nullptr; - uint32_t ctr = ~0u; - - if (i >= UAVStartSlot && i < UAVStartSlot + NumUAVs) { - uav = static_cast(ppUnorderedAccessViews[i - UAVStartSlot]); - ctr = pUAVInitialCounts ? pUAVInitialCounts[i - UAVStartSlot] : ~0u; - } - - if (m_state.ps.unorderedAccessViews[i] != uav || ctr != ~0u) { - m_state.ps.unorderedAccessViews[i] = uav; - - BindUnorderedAccessView( - uavSlotId + i, uav, - ctrSlotId + i, ctr); - - ResolveOmSrvHazards(uav); - - if (NumRTVs == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - needsUpdate |= ResolveOmRtvHazards(uav); - } - } - } - } - - if (needsUpdate) - BindFramebuffer(); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMSetBlendState( - ID3D11BlendState* pBlendState, - const FLOAT BlendFactor[4], - UINT SampleMask) { - D3D10DeviceLock lock = LockContext(); - - auto blendState = static_cast(pBlendState); - - if (m_state.om.cbState != blendState - || m_state.om.sampleMask != SampleMask) { - m_state.om.cbState = blendState; - m_state.om.sampleMask = SampleMask; - - ApplyBlendState(); - } - - if (BlendFactor != nullptr) { - for (uint32_t i = 0; i < 4; i++) - m_state.om.blendFactor[i] = BlendFactor[i]; - - ApplyBlendFactor(); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMSetDepthStencilState( - ID3D11DepthStencilState* pDepthStencilState, - UINT StencilRef) { - D3D10DeviceLock lock = LockContext(); - - auto depthStencilState = static_cast(pDepthStencilState); - - if (m_state.om.dsState != depthStencilState) { - m_state.om.dsState = depthStencilState; - ApplyDepthStencilState(); - } - - if (m_state.om.stencilRef != StencilRef) { - m_state.om.stencilRef = StencilRef; - ApplyStencilRef(); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMGetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView** ppRenderTargetViews, - ID3D11DepthStencilView** ppDepthStencilView) { - D3D10DeviceLock lock = LockContext(); - - if (ppRenderTargetViews != nullptr) { - for (UINT i = 0; i < NumViews; i++) { - ppRenderTargetViews[i] = i < m_state.om.renderTargetViews.size() - ? m_state.om.renderTargetViews[i].ref() - : nullptr; - } - } - - if (ppDepthStencilView != nullptr) - *ppDepthStencilView = m_state.om.depthStencilView.ref(); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMGetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView** ppRenderTargetViews, - ID3D11DepthStencilView** ppDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView** ppUnorderedAccessViews) { - OMGetRenderTargets(NumRTVs, ppRenderTargetViews, ppDepthStencilView); - - D3D10DeviceLock lock = LockContext(); - - if (ppUnorderedAccessViews != nullptr) { - for (UINT i = 0; i < NumUAVs; i++) { - ppUnorderedAccessViews[i] = UAVStartSlot + i < m_state.ps.unorderedAccessViews.size() - ? m_state.ps.unorderedAccessViews[UAVStartSlot + i].ref() - : nullptr; - } - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMGetBlendState( - ID3D11BlendState** ppBlendState, - FLOAT BlendFactor[4], - UINT* pSampleMask) { - D3D10DeviceLock lock = LockContext(); - - if (ppBlendState != nullptr) - *ppBlendState = ref(m_state.om.cbState); - - if (BlendFactor != nullptr) - std::memcpy(BlendFactor, m_state.om.blendFactor, sizeof(FLOAT) * 4); - - if (pSampleMask != nullptr) - *pSampleMask = m_state.om.sampleMask; - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::OMGetDepthStencilState( - ID3D11DepthStencilState** ppDepthStencilState, - UINT* pStencilRef) { - D3D10DeviceLock lock = LockContext(); - - if (ppDepthStencilState != nullptr) - *ppDepthStencilState = ref(m_state.om.dsState); - - if (pStencilRef != nullptr) - *pStencilRef = m_state.om.stencilRef; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::RSSetState(ID3D11RasterizerState* pRasterizerState) { D3D10DeviceLock lock = LockContext(); @@ -4385,122 +4176,6 @@ namespace dxvk { } - template - void D3D11DeviceContext::ResolveOmSrvHazards( - T* pView) { - if (!pView) return; - ResolveSrvHazards (pView, m_state.vs.shaderResources); - ResolveSrvHazards (pView, m_state.hs.shaderResources); - ResolveSrvHazards (pView, m_state.ds.shaderResources); - ResolveSrvHazards (pView, m_state.gs.shaderResources); - ResolveSrvHazards (pView, m_state.ps.shaderResources); - } - - - bool D3D11DeviceContext::ResolveOmRtvHazards( - D3D11UnorderedAccessView* pView) { - if (!pView || !pView->HasBindFlag(D3D11_BIND_RENDER_TARGET)) - return false; - - bool hazard = false; - - if (CheckViewOverlap(pView, m_state.om.depthStencilView.ptr())) { - m_state.om.depthStencilView = nullptr; - hazard = true; - } - - for (uint32_t i = 0; i < m_state.om.maxRtv; i++) { - if (CheckViewOverlap(pView, m_state.om.renderTargetViews[i].ptr())) { - m_state.om.renderTargetViews[i] = nullptr; - hazard = true; - } - } - - return hazard; - } - - - void D3D11DeviceContext::ResolveOmUavHazards( - D3D11RenderTargetView* pView) { - if (!pView || !pView->HasBindFlag(D3D11_BIND_UNORDERED_ACCESS)) - return; - - uint32_t uavSlotId = computeUavBinding (DxbcProgramType::PixelShader, 0); - uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0); - - for (uint32_t i = 0; i < m_state.om.maxUav; i++) { - if (CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr())) { - m_state.ps.unorderedAccessViews[i] = nullptr; - - BindUnorderedAccessView( - uavSlotId + i, nullptr, - ctrSlotId + i, ~0u); - } - } - } - - - bool D3D11DeviceContext::ValidateRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView) { - Rc refView; - - VkExtent3D dsvExtent = { 0u, 0u, 0u }; - VkExtent3D rtvExtent = { 0u, 0u, 0u }; - - if (pDepthStencilView != nullptr) { - refView = static_cast( - pDepthStencilView)->GetImageView(); - dsvExtent = refView->mipLevelExtent(0); - } - - for (uint32_t i = 0; i < NumViews; i++) { - if (ppRenderTargetViews[i] != nullptr) { - auto curView = static_cast( - ppRenderTargetViews[i])->GetImageView(); - - if (!rtvExtent.width) - rtvExtent = curView->mipLevelExtent(0); - - if (refView != nullptr) { - // Render target views must all have the same sample count, - // layer count, and type. The size can mismatch under certain - // conditions, the D3D11 documentation is wrong here. - if (curView->info().type != refView->info().type - || curView->info().numLayers != refView->info().numLayers) - return false; - - if (curView->imageInfo().sampleCount - != refView->imageInfo().sampleCount) - return false; - - // Color targets must all be the same size - VkExtent3D curExtent = curView->mipLevelExtent(0); - - if (curExtent.width != rtvExtent.width - || curExtent.height != rtvExtent.height) - return false; - } else { - // Set reference view. All remaining views - // must be compatible to the reference view. - refView = curView; - } - } - } - - // Based on testing, the depth-stencil target is allowed - // to be larger than all color targets, but not smaller - if (rtvExtent.width && dsvExtent.width) { - if (rtvExtent.width > dsvExtent.width - || rtvExtent.height > dsvExtent.height) - return false; - } - - return true; - } - - VkClearValue D3D11DeviceContext::ConvertColorValue( const FLOAT Color[4], const DxvkFormatInfo* pFormatInfo) { diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 4e153f254..21e5d4c03 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -579,51 +579,6 @@ namespace dxvk { UINT NumUAVs, ID3D11UnorderedAccessView** ppUnorderedAccessViews); - void STDMETHODCALLTYPE OMSetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView); - - void STDMETHODCALLTYPE OMSetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - const UINT* pUAVInitialCounts); - - void STDMETHODCALLTYPE OMSetBlendState( - ID3D11BlendState* pBlendState, - const FLOAT BlendFactor[4], - UINT SampleMask); - - void STDMETHODCALLTYPE OMSetDepthStencilState( - ID3D11DepthStencilState* pDepthStencilState, - UINT StencilRef); - - void STDMETHODCALLTYPE OMGetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView** ppRenderTargetViews, - ID3D11DepthStencilView** ppDepthStencilView); - - void STDMETHODCALLTYPE OMGetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView** ppRenderTargetViews, - ID3D11DepthStencilView** ppDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView** ppUnorderedAccessViews); - - void STDMETHODCALLTYPE OMGetBlendState( - ID3D11BlendState** ppBlendState, - FLOAT BlendFactor[4], - UINT* pSampleMask); - - void STDMETHODCALLTYPE OMGetDepthStencilState( - ID3D11DepthStencilState** ppDepthStencilState, - UINT* pStencilRef); - void STDMETHODCALLTYPE RSSetState( ID3D11RasterizerState* pRasterizerState); @@ -912,21 +867,6 @@ namespace dxvk { void ResolveCsSrvHazards( T* pView); - template - void ResolveOmSrvHazards( - T* pView); - - bool ResolveOmRtvHazards( - D3D11UnorderedAccessView* pView); - - void ResolveOmUavHazards( - D3D11RenderTargetView* pView); - - bool ValidateRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView); - VkClearValue ConvertColorValue( const FLOAT Color[4], const DxvkFormatInfo* pFormatInfo); diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index ebbdc3ed8..3e7430598 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -10,8 +10,8 @@ namespace dxvk { const Rc& Device, DxvkCsChunkFlags CsFlags) : D3D11DeviceContext(pParent, Device, CsFlags), - m_contextExt(static_cast(this)), - m_annotation(static_cast(this), Device) { + m_contextExt(GetTypedContext()), + m_annotation(GetTypedContext(), Device) { } @@ -90,6 +90,162 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::OMSetRenderTargets( + UINT NumViews, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView) { + D3D10DeviceLock lock = LockContext(); + + if constexpr (!IsDeferred) + GetTypedContext()->FlushImplicit(true); + + SetRenderTargetsAndUnorderedAccessViews( + NumViews, ppRenderTargetViews, pDepthStencilView, + NumViews, 0, nullptr, nullptr); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMSetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView, + UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, + const UINT* pUAVInitialCounts) { + D3D10DeviceLock lock = LockContext(); + + if constexpr (!IsDeferred) + GetTypedContext()->FlushImplicit(true); + + SetRenderTargetsAndUnorderedAccessViews( + NumRTVs, ppRenderTargetViews, pDepthStencilView, + UAVStartSlot, NumUAVs, ppUnorderedAccessViews, pUAVInitialCounts); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMSetBlendState( + ID3D11BlendState* pBlendState, + const FLOAT BlendFactor[4], + UINT SampleMask) { + D3D10DeviceLock lock = LockContext(); + + auto blendState = static_cast(pBlendState); + + if (m_state.om.cbState != blendState + || m_state.om.sampleMask != SampleMask) { + m_state.om.cbState = blendState; + m_state.om.sampleMask = SampleMask; + + ApplyBlendState(); + } + + if (BlendFactor != nullptr) { + for (uint32_t i = 0; i < 4; i++) + m_state.om.blendFactor[i] = BlendFactor[i]; + + ApplyBlendFactor(); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMSetDepthStencilState( + ID3D11DepthStencilState* pDepthStencilState, + UINT StencilRef) { + D3D10DeviceLock lock = LockContext(); + + auto depthStencilState = static_cast(pDepthStencilState); + + if (m_state.om.dsState != depthStencilState) { + m_state.om.dsState = depthStencilState; + ApplyDepthStencilState(); + } + + if (m_state.om.stencilRef != StencilRef) { + m_state.om.stencilRef = StencilRef; + ApplyStencilRef(); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMGetRenderTargets( + UINT NumViews, + ID3D11RenderTargetView** ppRenderTargetViews, + ID3D11DepthStencilView** ppDepthStencilView) { + OMGetRenderTargetsAndUnorderedAccessViews( + NumViews, ppRenderTargetViews, ppDepthStencilView, + NumViews, 0, nullptr); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMGetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, + ID3D11RenderTargetView** ppRenderTargetViews, + ID3D11DepthStencilView** ppDepthStencilView, + UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView** ppUnorderedAccessViews) { + D3D10DeviceLock lock = LockContext(); + + if (ppRenderTargetViews) { + for (UINT i = 0; i < NumRTVs; i++) { + ppRenderTargetViews[i] = i < m_state.om.renderTargetViews.size() + ? m_state.om.renderTargetViews[i].ref() + : nullptr; + } + } + + if (ppDepthStencilView) + *ppDepthStencilView = m_state.om.depthStencilView.ref(); + + if (ppUnorderedAccessViews) { + for (UINT i = 0; i < NumUAVs; i++) { + ppUnorderedAccessViews[i] = UAVStartSlot + i < m_state.ps.unorderedAccessViews.size() + ? m_state.ps.unorderedAccessViews[UAVStartSlot + i].ref() + : nullptr; + } + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMGetBlendState( + ID3D11BlendState** ppBlendState, + FLOAT BlendFactor[4], + UINT* pSampleMask) { + D3D10DeviceLock lock = LockContext(); + + if (ppBlendState) + *ppBlendState = ref(m_state.om.cbState); + + if (BlendFactor) + std::memcpy(BlendFactor, m_state.om.blendFactor, sizeof(FLOAT) * 4); + + if (pSampleMask) + *pSampleMask = m_state.om.sampleMask; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::OMGetDepthStencilState( + ID3D11DepthStencilState** ppDepthStencilState, + UINT* pStencilRef) { + D3D10DeviceLock lock = LockContext(); + + if (ppDepthStencilState) + *ppDepthStencilState = ref(m_state.om.dsState); + + if (pStencilRef) + *pStencilRef = m_state.om.stencilRef; + } + + template BOOL STDMETHODCALLTYPE D3D11CommonContext::IsAnnotationEnabled() { return m_annotation.GetStatus(); @@ -459,6 +615,90 @@ namespace dxvk { } + template + void D3D11CommonContext::SetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView, + UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, + const UINT* pUAVInitialCounts) { + if (TestRtvUavHazards(NumRTVs, ppRenderTargetViews, NumUAVs, ppUnorderedAccessViews)) + return; + + bool needsUpdate = false; + + if (likely(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL)) { + // Native D3D11 does not change the render targets if + // the parameters passed to this method are invalid. + if (!ValidateRenderTargets(NumRTVs, ppRenderTargetViews, pDepthStencilView)) + return; + + for (uint32_t i = 0; i < m_state.om.renderTargetViews.size(); i++) { + auto rtv = i < NumRTVs + ? static_cast(ppRenderTargetViews[i]) + : nullptr; + + if (m_state.om.renderTargetViews[i] != rtv) { + m_state.om.renderTargetViews[i] = rtv; + needsUpdate = true; + ResolveOmSrvHazards(rtv); + + if (NumUAVs == D3D11_KEEP_UNORDERED_ACCESS_VIEWS) + ResolveOmUavHazards(rtv); + } + } + + auto dsv = static_cast(pDepthStencilView); + + if (m_state.om.depthStencilView != dsv) { + m_state.om.depthStencilView = dsv; + needsUpdate = true; + ResolveOmSrvHazards(dsv); + } + + m_state.om.maxRtv = NumRTVs; + } + + if (unlikely(NumUAVs || m_state.om.maxUav)) { + uint32_t uavSlotId = computeUavBinding (DxbcProgramType::PixelShader, 0); + uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0); + + if (likely(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS)) { + uint32_t newMaxUav = NumUAVs ? UAVStartSlot + NumUAVs : 0; + uint32_t oldMaxUav = std::exchange(m_state.om.maxUav, newMaxUav); + + for (uint32_t i = 0; i < std::max(oldMaxUav, newMaxUav); i++) { + D3D11UnorderedAccessView* uav = nullptr; + uint32_t ctr = ~0u; + + if (i >= UAVStartSlot && i < UAVStartSlot + NumUAVs) { + uav = static_cast(ppUnorderedAccessViews[i - UAVStartSlot]); + ctr = pUAVInitialCounts ? pUAVInitialCounts[i - UAVStartSlot] : ~0u; + } + + if (m_state.ps.unorderedAccessViews[i] != uav || ctr != ~0u) { + m_state.ps.unorderedAccessViews[i] = uav; + + BindUnorderedAccessView( + uavSlotId + i, uav, + ctrSlotId + i, ctr); + + ResolveOmSrvHazards(uav); + + if (NumRTVs == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + needsUpdate |= ResolveOmRtvHazards(uav); + } + } + } + } + + if (needsUpdate) + BindFramebuffer(); + } + + template bool D3D11CommonContext::TestRtvUavHazards( UINT NumRTVs, @@ -593,6 +833,68 @@ namespace dxvk { } + template + bool D3D11CommonContext::ValidateRenderTargets( + UINT NumViews, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView) { + Rc refView; + + VkExtent3D dsvExtent = { 0u, 0u, 0u }; + VkExtent3D rtvExtent = { 0u, 0u, 0u }; + + if (pDepthStencilView != nullptr) { + refView = static_cast( + pDepthStencilView)->GetImageView(); + dsvExtent = refView->mipLevelExtent(0); + } + + for (uint32_t i = 0; i < NumViews; i++) { + if (ppRenderTargetViews[i] != nullptr) { + auto curView = static_cast( + ppRenderTargetViews[i])->GetImageView(); + + if (!rtvExtent.width) + rtvExtent = curView->mipLevelExtent(0); + + if (refView != nullptr) { + // Render target views must all have the same sample count, + // layer count, and type. The size can mismatch under certain + // conditions, the D3D11 documentation is wrong here. + if (curView->info().type != refView->info().type + || curView->info().numLayers != refView->info().numLayers) + return false; + + if (curView->imageInfo().sampleCount + != refView->imageInfo().sampleCount) + return false; + + // Color targets must all be the same size + VkExtent3D curExtent = curView->mipLevelExtent(0); + + if (curExtent.width != rtvExtent.width + || curExtent.height != rtvExtent.height) + return false; + } else { + // Set reference view. All remaining views + // must be compatible to the reference view. + refView = curView; + } + } + } + + // Based on testing, the depth-stencil target is allowed + // to be larger than all color targets, but not smaller + if (rtvExtent.width && dsvExtent.width) { + if (rtvExtent.width > dsvExtent.width + || rtvExtent.height > dsvExtent.height) + return false; + } + + return true; + } + + // Explicitly instantiate here template class D3D11CommonContext; template class D3D11CommonContext; diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index f5e3ac1eb..6827063e8 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -85,6 +85,51 @@ namespace dxvk { UINT SrcDepthPitch, UINT CopyFlags); + void STDMETHODCALLTYPE OMSetRenderTargets( + UINT NumViews, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView); + + void STDMETHODCALLTYPE OMSetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView, + UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, + const UINT* pUAVInitialCounts); + + void STDMETHODCALLTYPE OMSetBlendState( + ID3D11BlendState* pBlendState, + const FLOAT BlendFactor[4], + UINT SampleMask); + + void STDMETHODCALLTYPE OMSetDepthStencilState( + ID3D11DepthStencilState* pDepthStencilState, + UINT StencilRef); + + void STDMETHODCALLTYPE OMGetRenderTargets( + UINT NumViews, + ID3D11RenderTargetView** ppRenderTargetViews, + ID3D11DepthStencilView** ppDepthStencilView); + + void STDMETHODCALLTYPE OMGetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, + ID3D11RenderTargetView** ppRenderTargetViews, + ID3D11DepthStencilView** ppDepthStencilView, + UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView** ppUnorderedAccessViews); + + void STDMETHODCALLTYPE OMGetBlendState( + ID3D11BlendState** ppBlendState, + FLOAT BlendFactor[4], + UINT* pSampleMask); + + void STDMETHODCALLTYPE OMGetDepthStencilState( + ID3D11DepthStencilState** ppDepthStencilState, + UINT* pStencilRef); + BOOL STDMETHODCALLTYPE IsAnnotationEnabled(); protected: @@ -195,6 +240,17 @@ namespace dxvk { UINT SrcDepthPitch, UINT CopyFlags); + bool ValidateRenderTargets( + UINT NumViews, + ID3D11RenderTargetView* const* ppRenderTargetViews, + ID3D11DepthStencilView* pDepthStencilView); + + private: + + ContextType* GetTypedContext() { + return static_cast(this); + } + }; } diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index c26b4ad3e..a32a1c775 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -321,34 +321,7 @@ namespace dxvk { } } - void STDMETHODCALLTYPE D3D11ImmediateContext::OMSetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView) { - FlushImplicit(TRUE); - - D3D11DeviceContext::OMSetRenderTargets( - NumViews, ppRenderTargetViews, pDepthStencilView); - } - - - void STDMETHODCALLTYPE D3D11ImmediateContext::OMSetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - const UINT* pUAVInitialCounts) { - FlushImplicit(TRUE); - D3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( - NumRTVs, ppRenderTargetViews, pDepthStencilView, - UAVStartSlot, NumUAVs, ppUnorderedAccessViews, - pUAVInitialCounts); - } - - HRESULT D3D11ImmediateContext::MapBuffer( D3D11Buffer* pResource, D3D11_MAP MapType, diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 1a0d3b762..ddc6304c2 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -78,20 +78,6 @@ namespace dxvk { ID3D11Resource* pResource, UINT Subresource); - void STDMETHODCALLTYPE OMSetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView); - - void STDMETHODCALLTYPE OMSetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView* const* ppRenderTargetViews, - ID3D11DepthStencilView* pDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - const UINT* pUAVInitialCounts); - void STDMETHODCALLTYPE SwapDeviceContextState( ID3DDeviceContextState* pState, ID3DDeviceContextState** ppPreviousState); From e0ee06a279e050237f2be0e3ba94883078daffc4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 18:15:32 +0200 Subject: [PATCH 0377/1348] [d3d11] Move IA* functions to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 147 --------------------------- src/d3d11/d3d11_context.h | 36 ------- src/d3d11/d3d11_context_common.cpp | 155 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 36 +++++++ 4 files changed, 191 insertions(+), 183 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 0d4b27f55..92c356629 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1284,153 +1284,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::IASetInputLayout(ID3D11InputLayout* pInputLayout) { - D3D10DeviceLock lock = LockContext(); - - auto inputLayout = static_cast(pInputLayout); - - if (m_state.ia.inputLayout != inputLayout) { - bool equal = false; - - // Some games (e.g. Grim Dawn) create lots and lots of - // identical input layouts, so we'll only apply the state - // if the input layouts has actually changed between calls. - if (m_state.ia.inputLayout != nullptr && inputLayout != nullptr) - equal = m_state.ia.inputLayout->Compare(inputLayout); - - m_state.ia.inputLayout = inputLayout; - - if (!equal) - ApplyInputLayout(); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology) { - D3D10DeviceLock lock = LockContext(); - - if (m_state.ia.primitiveTopology != Topology) { - m_state.ia.primitiveTopology = Topology; - ApplyPrimitiveTopology(); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::IASetVertexBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppVertexBuffers, - const UINT* pStrides, - const UINT* pOffsets) { - D3D10DeviceLock lock = LockContext(); - - for (uint32_t i = 0; i < NumBuffers; i++) { - auto newBuffer = static_cast(ppVertexBuffers[i]); - bool needsUpdate = m_state.ia.vertexBuffers[StartSlot + i].buffer != newBuffer; - - if (needsUpdate) - m_state.ia.vertexBuffers[StartSlot + i].buffer = newBuffer; - - needsUpdate |= m_state.ia.vertexBuffers[StartSlot + i].offset != pOffsets[i] - || m_state.ia.vertexBuffers[StartSlot + i].stride != pStrides[i]; - - if (needsUpdate) { - m_state.ia.vertexBuffers[StartSlot + i].offset = pOffsets[i]; - m_state.ia.vertexBuffers[StartSlot + i].stride = pStrides[i]; - - BindVertexBuffer(StartSlot + i, newBuffer, pOffsets[i], pStrides[i]); - } - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::IASetIndexBuffer( - ID3D11Buffer* pIndexBuffer, - DXGI_FORMAT Format, - UINT Offset) { - D3D10DeviceLock lock = LockContext(); - - auto newBuffer = static_cast(pIndexBuffer); - bool needsUpdate = m_state.ia.indexBuffer.buffer != newBuffer; - - if (needsUpdate) - m_state.ia.indexBuffer.buffer = newBuffer; - - needsUpdate |= m_state.ia.indexBuffer.offset != Offset - || m_state.ia.indexBuffer.format != Format; - - if (needsUpdate) { - m_state.ia.indexBuffer.offset = Offset; - m_state.ia.indexBuffer.format = Format; - - BindIndexBuffer(newBuffer, Offset, Format); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::IAGetInputLayout(ID3D11InputLayout** ppInputLayout) { - D3D10DeviceLock lock = LockContext(); - - *ppInputLayout = m_state.ia.inputLayout.ref(); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::IAGetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY* pTopology) { - D3D10DeviceLock lock = LockContext(); - - *pTopology = m_state.ia.primitiveTopology; - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::IAGetVertexBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppVertexBuffers, - UINT* pStrides, - UINT* pOffsets) { - D3D10DeviceLock lock = LockContext(); - - for (uint32_t i = 0; i < NumBuffers; i++) { - const bool inRange = StartSlot + i < m_state.ia.vertexBuffers.size(); - - if (ppVertexBuffers != nullptr) { - ppVertexBuffers[i] = inRange - ? m_state.ia.vertexBuffers[StartSlot + i].buffer.ref() - : nullptr; - } - - if (pStrides != nullptr) { - pStrides[i] = inRange - ? m_state.ia.vertexBuffers[StartSlot + i].stride - : 0u; - } - - if (pOffsets != nullptr) { - pOffsets[i] = inRange - ? m_state.ia.vertexBuffers[StartSlot + i].offset - : 0u; - } - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::IAGetIndexBuffer( - ID3D11Buffer** ppIndexBuffer, - DXGI_FORMAT* pFormat, - UINT* pOffset) { - D3D10DeviceLock lock = LockContext(); - - if (ppIndexBuffer != nullptr) - *ppIndexBuffer = m_state.ia.indexBuffer.buffer.ref(); - - if (pFormat != nullptr) - *pFormat = m_state.ia.indexBuffer.format; - - if (pOffset != nullptr) - *pOffset = m_state.ia.indexBuffer.offset; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::VSSetShader( ID3D11VertexShader* pVertexShader, ID3D11ClassInstance* const* ppClassInstances, diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 21e5d4c03..e538a1cc6 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -208,42 +208,6 @@ namespace dxvk { ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs); - void STDMETHODCALLTYPE IASetInputLayout( - ID3D11InputLayout* pInputLayout); - - void STDMETHODCALLTYPE IASetPrimitiveTopology( - D3D11_PRIMITIVE_TOPOLOGY Topology); - - void STDMETHODCALLTYPE IASetVertexBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppVertexBuffers, - const UINT* pStrides, - const UINT* pOffsets); - - void STDMETHODCALLTYPE IASetIndexBuffer( - ID3D11Buffer* pIndexBuffer, - DXGI_FORMAT Format, - UINT Offset); - - void STDMETHODCALLTYPE IAGetInputLayout( - ID3D11InputLayout** ppInputLayout); - - void STDMETHODCALLTYPE IAGetPrimitiveTopology( - D3D11_PRIMITIVE_TOPOLOGY* pTopology); - - void STDMETHODCALLTYPE IAGetVertexBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppVertexBuffers, - UINT* pStrides, - UINT* pOffsets); - - void STDMETHODCALLTYPE IAGetIndexBuffer( - ID3D11Buffer** ppIndexBuffer, - DXGI_FORMAT* pFormat, - UINT* pOffset); - void STDMETHODCALLTYPE VSSetShader( ID3D11VertexShader* pVertexShader, ID3D11ClassInstance* const* ppClassInstances, diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 3e7430598..62410db1c 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -90,6 +90,161 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::IASetInputLayout(ID3D11InputLayout* pInputLayout) { + D3D10DeviceLock lock = LockContext(); + + auto inputLayout = static_cast(pInputLayout); + + if (m_state.ia.inputLayout != inputLayout) { + bool equal = false; + + // Some games (e.g. Grim Dawn) create lots and lots of + // identical input layouts, so we'll only apply the state + // if the input layouts has actually changed between calls. + if (m_state.ia.inputLayout != nullptr && inputLayout != nullptr) + equal = m_state.ia.inputLayout->Compare(inputLayout); + + m_state.ia.inputLayout = inputLayout; + + if (!equal) + ApplyInputLayout(); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology) { + D3D10DeviceLock lock = LockContext(); + + if (m_state.ia.primitiveTopology != Topology) { + m_state.ia.primitiveTopology = Topology; + ApplyPrimitiveTopology(); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::IASetVertexBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppVertexBuffers, + const UINT* pStrides, + const UINT* pOffsets) { + D3D10DeviceLock lock = LockContext(); + + for (uint32_t i = 0; i < NumBuffers; i++) { + auto newBuffer = static_cast(ppVertexBuffers[i]); + bool needsUpdate = m_state.ia.vertexBuffers[StartSlot + i].buffer != newBuffer; + + if (needsUpdate) + m_state.ia.vertexBuffers[StartSlot + i].buffer = newBuffer; + + needsUpdate |= m_state.ia.vertexBuffers[StartSlot + i].offset != pOffsets[i] + || m_state.ia.vertexBuffers[StartSlot + i].stride != pStrides[i]; + + if (needsUpdate) { + m_state.ia.vertexBuffers[StartSlot + i].offset = pOffsets[i]; + m_state.ia.vertexBuffers[StartSlot + i].stride = pStrides[i]; + + BindVertexBuffer(StartSlot + i, newBuffer, pOffsets[i], pStrides[i]); + } + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::IASetIndexBuffer( + ID3D11Buffer* pIndexBuffer, + DXGI_FORMAT Format, + UINT Offset) { + D3D10DeviceLock lock = LockContext(); + + auto newBuffer = static_cast(pIndexBuffer); + bool needsUpdate = m_state.ia.indexBuffer.buffer != newBuffer; + + if (needsUpdate) + m_state.ia.indexBuffer.buffer = newBuffer; + + needsUpdate |= m_state.ia.indexBuffer.offset != Offset + || m_state.ia.indexBuffer.format != Format; + + if (needsUpdate) { + m_state.ia.indexBuffer.offset = Offset; + m_state.ia.indexBuffer.format = Format; + + BindIndexBuffer(newBuffer, Offset, Format); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::IAGetInputLayout(ID3D11InputLayout** ppInputLayout) { + D3D10DeviceLock lock = LockContext(); + + *ppInputLayout = m_state.ia.inputLayout.ref(); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::IAGetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY* pTopology) { + D3D10DeviceLock lock = LockContext(); + + *pTopology = m_state.ia.primitiveTopology; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::IAGetVertexBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppVertexBuffers, + UINT* pStrides, + UINT* pOffsets) { + D3D10DeviceLock lock = LockContext(); + + for (uint32_t i = 0; i < NumBuffers; i++) { + const bool inRange = StartSlot + i < m_state.ia.vertexBuffers.size(); + + if (ppVertexBuffers) { + ppVertexBuffers[i] = inRange + ? m_state.ia.vertexBuffers[StartSlot + i].buffer.ref() + : nullptr; + } + + if (pStrides) { + pStrides[i] = inRange + ? m_state.ia.vertexBuffers[StartSlot + i].stride + : 0u; + } + + if (pOffsets) { + pOffsets[i] = inRange + ? m_state.ia.vertexBuffers[StartSlot + i].offset + : 0u; + } + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::IAGetIndexBuffer( + ID3D11Buffer** ppIndexBuffer, + DXGI_FORMAT* pFormat, + UINT* pOffset) { + D3D10DeviceLock lock = LockContext(); + + if (ppIndexBuffer) + *ppIndexBuffer = m_state.ia.indexBuffer.buffer.ref(); + + if (pFormat) + *pFormat = m_state.ia.indexBuffer.format; + + if (pOffset) + *pOffset = m_state.ia.indexBuffer.offset; + } + + template void STDMETHODCALLTYPE D3D11CommonContext::OMSetRenderTargets( UINT NumViews, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 6827063e8..a1c249301 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -85,6 +85,42 @@ namespace dxvk { UINT SrcDepthPitch, UINT CopyFlags); + void STDMETHODCALLTYPE IASetInputLayout( + ID3D11InputLayout* pInputLayout); + + void STDMETHODCALLTYPE IASetPrimitiveTopology( + D3D11_PRIMITIVE_TOPOLOGY Topology); + + void STDMETHODCALLTYPE IASetVertexBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppVertexBuffers, + const UINT* pStrides, + const UINT* pOffsets); + + void STDMETHODCALLTYPE IASetIndexBuffer( + ID3D11Buffer* pIndexBuffer, + DXGI_FORMAT Format, + UINT Offset); + + void STDMETHODCALLTYPE IAGetInputLayout( + ID3D11InputLayout** ppInputLayout); + + void STDMETHODCALLTYPE IAGetPrimitiveTopology( + D3D11_PRIMITIVE_TOPOLOGY* pTopology); + + void STDMETHODCALLTYPE IAGetVertexBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppVertexBuffers, + UINT* pStrides, + UINT* pOffsets); + + void STDMETHODCALLTYPE IAGetIndexBuffer( + ID3D11Buffer** ppIndexBuffer, + DXGI_FORMAT* pFormat, + UINT* pOffset); + void STDMETHODCALLTYPE OMSetRenderTargets( UINT NumViews, ID3D11RenderTargetView* const* ppRenderTargetViews, From 26ac57f688bfed022a272284d923b6fc6a1e3978 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 19:13:41 +0200 Subject: [PATCH 0378/1348] [d3d11] Move *SetShader methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 198 --------------------------- src/d3d11/d3d11_context.h | 60 --------- src/d3d11/d3d11_context_common.cpp | 210 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 60 +++++++++ 4 files changed, 270 insertions(+), 258 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 92c356629..313dda77e 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1284,25 +1284,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::VSSetShader( - ID3D11VertexShader* pVertexShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - auto shader = static_cast(pVertexShader); - - if (NumClassInstances != 0) - Logger::err("D3D11: Class instances not supported"); - - if (m_state.vs.shader != shader) { - m_state.vs.shader = shader; - - BindShader(GetCommonShader(shader)); - } - } - - void STDMETHODCALLTYPE D3D11DeviceContext::VSSetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -1359,20 +1340,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::VSGetShader( - ID3D11VertexShader** ppVertexShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - if (ppVertexShader != nullptr) - *ppVertexShader = m_state.vs.shader.ref(); - - if (pNumClassInstances != nullptr) - *pNumClassInstances = 0; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::VSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -1426,25 +1393,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::HSSetShader( - ID3D11HullShader* pHullShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - auto shader = static_cast(pHullShader); - - if (NumClassInstances != 0) - Logger::err("D3D11: Class instances not supported"); - - if (m_state.hs.shader != shader) { - m_state.hs.shader = shader; - - BindShader(GetCommonShader(shader)); - } - } - - void STDMETHODCALLTYPE D3D11DeviceContext::HSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -1501,20 +1449,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::HSGetShader( - ID3D11HullShader** ppHullShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - if (ppHullShader != nullptr) - *ppHullShader = m_state.hs.shader.ref(); - - if (pNumClassInstances != nullptr) - *pNumClassInstances = 0; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::HSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -1568,25 +1502,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::DSSetShader( - ID3D11DomainShader* pDomainShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - auto shader = static_cast(pDomainShader); - - if (NumClassInstances != 0) - Logger::err("D3D11: Class instances not supported"); - - if (m_state.ds.shader != shader) { - m_state.ds.shader = shader; - - BindShader(GetCommonShader(shader)); - } - } - - void STDMETHODCALLTYPE D3D11DeviceContext::DSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -1643,20 +1558,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::DSGetShader( - ID3D11DomainShader** ppDomainShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - if (ppDomainShader != nullptr) - *ppDomainShader = m_state.ds.shader.ref(); - - if (pNumClassInstances != nullptr) - *pNumClassInstances = 0; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::DSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -1710,25 +1611,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::GSSetShader( - ID3D11GeometryShader* pShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - auto shader = static_cast(pShader); - - if (NumClassInstances != 0) - Logger::err("D3D11: Class instances not supported"); - - if (m_state.gs.shader != shader) { - m_state.gs.shader = shader; - - BindShader(GetCommonShader(shader)); - } - } - - void STDMETHODCALLTYPE D3D11DeviceContext::GSSetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -1785,20 +1667,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::GSGetShader( - ID3D11GeometryShader** ppGeometryShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - if (ppGeometryShader != nullptr) - *ppGeometryShader = m_state.gs.shader.ref(); - - if (pNumClassInstances != nullptr) - *pNumClassInstances = 0; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::GSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -1852,25 +1720,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::PSSetShader( - ID3D11PixelShader* pPixelShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - auto shader = static_cast(pPixelShader); - - if (NumClassInstances != 0) - Logger::err("D3D11: Class instances not supported"); - - if (m_state.ps.shader != shader) { - m_state.ps.shader = shader; - - BindShader(GetCommonShader(shader)); - } - } - - void STDMETHODCALLTYPE D3D11DeviceContext::PSSetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -1927,20 +1776,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::PSGetShader( - ID3D11PixelShader** ppPixelShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - if (ppPixelShader != nullptr) - *ppPixelShader = m_state.ps.shader.ref(); - - if (pNumClassInstances != nullptr) - *pNumClassInstances = 0; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::PSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -1994,25 +1829,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::CSSetShader( - ID3D11ComputeShader* pComputeShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - auto shader = static_cast(pComputeShader); - - if (NumClassInstances != 0) - Logger::err("D3D11: Class instances not supported"); - - if (m_state.cs.shader != shader) { - m_state.cs.shader = shader; - - BindShader(GetCommonShader(shader)); - } - } - - void STDMETHODCALLTYPE D3D11DeviceContext::CSSetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -2125,20 +1941,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::CSGetShader( - ID3D11ComputeShader** ppComputeShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances) { - D3D10DeviceLock lock = LockContext(); - - if (ppComputeShader != nullptr) - *ppComputeShader = m_state.cs.shader.ref(); - - if (pNumClassInstances != nullptr) - *pNumClassInstances = 0; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::CSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index e538a1cc6..b15d375a7 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -208,11 +208,6 @@ namespace dxvk { ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs); - void STDMETHODCALLTYPE VSSetShader( - ID3D11VertexShader* pVertexShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances); - void STDMETHODCALLTYPE VSSetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -235,11 +230,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE VSGetShader( - ID3D11VertexShader** ppVertexShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances); - void STDMETHODCALLTYPE VSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -262,11 +252,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE HSSetShader( - ID3D11HullShader* pHullShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances); - void STDMETHODCALLTYPE HSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -289,11 +274,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE HSGetShader( - ID3D11HullShader** ppHullShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances); - void STDMETHODCALLTYPE HSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -316,11 +296,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE DSSetShader( - ID3D11DomainShader* pDomainShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances); - void STDMETHODCALLTYPE DSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -343,11 +318,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE DSGetShader( - ID3D11DomainShader** ppDomainShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances); - void STDMETHODCALLTYPE DSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -370,11 +340,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE GSSetShader( - ID3D11GeometryShader* pShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances); - void STDMETHODCALLTYPE GSSetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -397,11 +362,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE GSGetShader( - ID3D11GeometryShader** ppGeometryShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances); - void STDMETHODCALLTYPE GSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -424,11 +384,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE PSSetShader( - ID3D11PixelShader* pPixelShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances); - void STDMETHODCALLTYPE PSSetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -451,11 +406,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE PSGetShader( - ID3D11PixelShader** ppPixelShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances); - void STDMETHODCALLTYPE PSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -478,11 +428,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE CSSetShader( - ID3D11ComputeShader* pComputeShader, - ID3D11ClassInstance* const* ppClassInstances, - UINT NumClassInstances); - void STDMETHODCALLTYPE CSSetConstantBuffers( UINT StartSlot, UINT NumBuffers, @@ -511,11 +456,6 @@ namespace dxvk { ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts); - void STDMETHODCALLTYPE CSGetShader( - ID3D11ComputeShader** ppComputeShader, - ID3D11ClassInstance** ppClassInstances, - UINT* pNumClassInstances); - void STDMETHODCALLTYPE CSGetConstantBuffers( UINT StartSlot, UINT NumBuffers, diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 62410db1c..9d67e040d 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -245,6 +245,216 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::VSSetShader( + ID3D11VertexShader* pVertexShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + auto shader = static_cast(pVertexShader); + + if (NumClassInstances) + Logger::err("D3D11: Class instances not supported"); + + if (m_state.vs.shader != shader) { + m_state.vs.shader = shader; + + BindShader(GetCommonShader(shader)); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::VSGetShader( + ID3D11VertexShader** ppVertexShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + if (ppVertexShader) + *ppVertexShader = m_state.vs.shader.ref(); + + if (pNumClassInstances) + *pNumClassInstances = 0; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::HSSetShader( + ID3D11HullShader* pHullShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + auto shader = static_cast(pHullShader); + + if (NumClassInstances) + Logger::err("D3D11: Class instances not supported"); + + if (m_state.hs.shader != shader) { + m_state.hs.shader = shader; + + BindShader(GetCommonShader(shader)); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::HSGetShader( + ID3D11HullShader** ppHullShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + if (ppHullShader) + *ppHullShader = m_state.hs.shader.ref(); + + if (pNumClassInstances) + *pNumClassInstances = 0; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DSSetShader( + ID3D11DomainShader* pDomainShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + auto shader = static_cast(pDomainShader); + + if (NumClassInstances) + Logger::err("D3D11: Class instances not supported"); + + if (m_state.ds.shader != shader) { + m_state.ds.shader = shader; + + BindShader(GetCommonShader(shader)); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DSGetShader( + ID3D11DomainShader** ppDomainShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + if (ppDomainShader) + *ppDomainShader = m_state.ds.shader.ref(); + + if (pNumClassInstances) + *pNumClassInstances = 0; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::GSSetShader( + ID3D11GeometryShader* pShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + auto shader = static_cast(pShader); + + if (NumClassInstances) + Logger::err("D3D11: Class instances not supported"); + + if (m_state.gs.shader != shader) { + m_state.gs.shader = shader; + + BindShader(GetCommonShader(shader)); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::GSGetShader( + ID3D11GeometryShader** ppGeometryShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + if (ppGeometryShader) + *ppGeometryShader = m_state.gs.shader.ref(); + + if (pNumClassInstances) + *pNumClassInstances = 0; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::PSSetShader( + ID3D11PixelShader* pPixelShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + auto shader = static_cast(pPixelShader); + + if (NumClassInstances) + Logger::err("D3D11: Class instances not supported"); + + if (m_state.ps.shader != shader) { + m_state.ps.shader = shader; + + BindShader(GetCommonShader(shader)); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::PSGetShader( + ID3D11PixelShader** ppPixelShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + if (ppPixelShader) + *ppPixelShader = m_state.ps.shader.ref(); + + if (pNumClassInstances) + *pNumClassInstances = 0; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::CSSetShader( + ID3D11ComputeShader* pComputeShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + auto shader = static_cast(pComputeShader); + + if (NumClassInstances) + Logger::err("D3D11: Class instances not supported"); + + if (m_state.cs.shader != shader) { + m_state.cs.shader = shader; + + BindShader(GetCommonShader(shader)); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::CSGetShader( + ID3D11ComputeShader** ppComputeShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + + if (ppComputeShader) + *ppComputeShader = m_state.cs.shader.ref(); + + if (pNumClassInstances) + *pNumClassInstances = 0; + } + + template void STDMETHODCALLTYPE D3D11CommonContext::OMSetRenderTargets( UINT NumViews, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index a1c249301..f628d6fa7 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -121,6 +121,66 @@ namespace dxvk { DXGI_FORMAT* pFormat, UINT* pOffset); + void STDMETHODCALLTYPE VSSetShader( + ID3D11VertexShader* pVertexShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances); + + void STDMETHODCALLTYPE VSGetShader( + ID3D11VertexShader** ppVertexShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances); + + void STDMETHODCALLTYPE HSSetShader( + ID3D11HullShader* pHullShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances); + + void STDMETHODCALLTYPE HSGetShader( + ID3D11HullShader** ppHullShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances); + + void STDMETHODCALLTYPE DSSetShader( + ID3D11DomainShader* pDomainShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances); + + void STDMETHODCALLTYPE DSGetShader( + ID3D11DomainShader** ppDomainShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances); + + void STDMETHODCALLTYPE GSSetShader( + ID3D11GeometryShader* pShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances); + + void STDMETHODCALLTYPE GSGetShader( + ID3D11GeometryShader** ppGeometryShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances); + + void STDMETHODCALLTYPE PSSetShader( + ID3D11PixelShader* pPixelShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances); + + void STDMETHODCALLTYPE PSGetShader( + ID3D11PixelShader** ppPixelShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances); + + void STDMETHODCALLTYPE CSSetShader( + ID3D11ComputeShader* pComputeShader, + ID3D11ClassInstance* const* ppClassInstances, + UINT NumClassInstances); + + void STDMETHODCALLTYPE CSGetShader( + ID3D11ComputeShader** ppComputeShader, + ID3D11ClassInstance** ppClassInstances, + UINT* pNumClassInstances); + void STDMETHODCALLTYPE OMSetRenderTargets( UINT NumViews, ID3D11RenderTargetView* const* ppRenderTargetViews, From bfaa21dccca803fce0952b91114330ad81ee570e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 19:49:15 +0200 Subject: [PATCH 0379/1348] [d3d11] Move *SetConstantBuffers methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 496 --------------------------- src/d3d11/d3d11_context.h | 168 --------- src/d3d11/d3d11_context_common.cpp | 523 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 168 +++++++++ 4 files changed, 691 insertions(+), 664 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 313dda77e..b1c8864f8 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1284,36 +1284,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::VSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers( - m_state.vs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::VSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers1( - m_state.vs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::VSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -1340,37 +1310,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::VSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.vs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::VSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.vs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::VSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -1406,36 +1345,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::HSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers( - m_state.hs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::HSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers1( - m_state.hs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::HSSetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1449,37 +1358,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::HSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.hs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::HSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.hs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::HSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -1515,36 +1393,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::DSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers( - m_state.ds.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers1( - m_state.ds.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::DSSetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1558,37 +1406,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::DSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.ds.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.ds.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::DSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -1611,36 +1428,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::GSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers( - m_state.gs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::GSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers1( - m_state.gs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::GSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -1667,37 +1454,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::GSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.gs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::GSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.gs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::GSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -1720,36 +1476,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::PSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers( - m_state.ps.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::PSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers1( - m_state.ps.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::PSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -1776,37 +1502,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::PSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.ps.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::PSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.ps.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::PSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -1829,36 +1524,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::CSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers( - m_state.cs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::CSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - SetConstantBuffers1( - m_state.cs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::CSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -1941,37 +1606,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::CSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.cs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - nullptr, nullptr); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::CSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants) { - D3D10DeviceLock lock = LockContext(); - - GetConstantBuffers( - m_state.cs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::CSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -3304,105 +2938,6 @@ namespace dxvk { } - template - void D3D11DeviceContext::SetConstantBuffers( - D3D11ConstantBufferBindings& Bindings, - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers) { - uint32_t slotId = computeConstantBufferBinding(ShaderStage, StartSlot); - - for (uint32_t i = 0; i < NumBuffers; i++) { - auto newBuffer = static_cast(ppConstantBuffers[i]); - - UINT constantCount = 0; - - if (likely(newBuffer != nullptr)) - constantCount = std::min(newBuffer->Desc()->ByteWidth / 16, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)); - - if (Bindings[StartSlot + i].buffer != newBuffer - || Bindings[StartSlot + i].constantBound != constantCount) { - Bindings[StartSlot + i].buffer = newBuffer; - Bindings[StartSlot + i].constantOffset = 0; - Bindings[StartSlot + i].constantCount = constantCount; - Bindings[StartSlot + i].constantBound = constantCount; - - BindConstantBuffer(slotId + i, newBuffer, 0, constantCount); - } - } - } - - - template - void D3D11DeviceContext::SetConstantBuffers1( - D3D11ConstantBufferBindings& Bindings, - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants) { - uint32_t slotId = computeConstantBufferBinding(ShaderStage, StartSlot); - - for (uint32_t i = 0; i < NumBuffers; i++) { - auto newBuffer = static_cast(ppConstantBuffers[i]); - - UINT constantOffset; - UINT constantCount; - UINT constantBound; - - if (likely(newBuffer != nullptr)) { - UINT bufferConstantsCount = newBuffer->Desc()->ByteWidth / 16; - constantBound = std::min(bufferConstantsCount, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)); - - if (likely(pFirstConstant && pNumConstants)) { - constantOffset = pFirstConstant[i]; - constantCount = pNumConstants [i]; - - if (unlikely(constantCount > D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)) - continue; - - constantBound = (constantOffset + constantCount > bufferConstantsCount) - ? bufferConstantsCount - std::min(constantOffset, bufferConstantsCount) - : constantCount; - } else { - constantOffset = 0; - constantCount = constantBound; - } - } else { - constantOffset = 0; - constantCount = 0; - constantBound = 0; - } - - // Do a full rebind if either the buffer changes, or if either the current or - // the previous number of bound constants were zero, since we're binding a null - // buffer to the backend in that case. - bool needsUpdate = Bindings[StartSlot + i].buffer != newBuffer; - - if (!needsUpdate) { - needsUpdate |= !constantBound; - needsUpdate |= !Bindings[StartSlot + i].constantBound; - } - - if (needsUpdate) { - Bindings[StartSlot + i].buffer = newBuffer; - Bindings[StartSlot + i].constantOffset = constantOffset; - Bindings[StartSlot + i].constantCount = constantCount; - Bindings[StartSlot + i].constantBound = constantBound; - - BindConstantBuffer(slotId + i, newBuffer, constantOffset, constantBound); - } else if (Bindings[StartSlot + i].constantOffset != constantOffset - || Bindings[StartSlot + i].constantCount != constantCount) { - Bindings[StartSlot + i].constantOffset = constantOffset; - Bindings[StartSlot + i].constantCount = constantCount; - Bindings[StartSlot + i].constantBound = constantBound; - - BindConstantBufferRange(slotId + i, constantOffset, constantBound); - } - } - } - - template void D3D11DeviceContext::SetSamplers( D3D11SamplerBindings& Bindings, @@ -3451,37 +2986,6 @@ namespace dxvk { } - void D3D11DeviceContext::GetConstantBuffers( - const D3D11ConstantBufferBindings& Bindings, - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants) { - for (uint32_t i = 0; i < NumBuffers; i++) { - const bool inRange = StartSlot + i < Bindings.size(); - - if (ppConstantBuffers != nullptr) { - ppConstantBuffers[i] = inRange - ? Bindings[StartSlot + i].buffer.ref() - : nullptr; - } - - if (pFirstConstant != nullptr) { - pFirstConstant[i] = inRange - ? Bindings[StartSlot + i].constantOffset - : 0u; - } - - if (pNumConstants != nullptr) { - pNumConstants[i] = inRange - ? Bindings[StartSlot + i].constantCount - : 0u; - } - } - } - - void D3D11DeviceContext::GetShaderResources( const D3D11ShaderResourceBindings& Bindings, UINT StartSlot, diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index b15d375a7..442c449e8 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -208,18 +208,6 @@ namespace dxvk { ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs); - void STDMETHODCALLTYPE VSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers); - - void STDMETHODCALLTYPE VSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants); - void STDMETHODCALLTYPE VSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -230,18 +218,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE VSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers); - - void STDMETHODCALLTYPE VSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants); - void STDMETHODCALLTYPE VSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -257,35 +233,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews); - void STDMETHODCALLTYPE HSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers); - - void STDMETHODCALLTYPE HSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants); - void STDMETHODCALLTYPE HSSetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE HSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers); - - void STDMETHODCALLTYPE HSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants); - void STDMETHODCALLTYPE HSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -301,35 +253,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews); - void STDMETHODCALLTYPE DSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers); - - void STDMETHODCALLTYPE DSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants); - void STDMETHODCALLTYPE DSSetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE DSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers); - - void STDMETHODCALLTYPE DSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants); - void STDMETHODCALLTYPE DSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -340,18 +268,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE GSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers); - - void STDMETHODCALLTYPE GSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants); - void STDMETHODCALLTYPE GSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -362,18 +278,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE GSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers); - - void STDMETHODCALLTYPE GSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants); - void STDMETHODCALLTYPE GSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -384,18 +288,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE PSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers); - - void STDMETHODCALLTYPE PSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants); - void STDMETHODCALLTYPE PSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -406,18 +298,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE PSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers); - - void STDMETHODCALLTYPE PSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants); - void STDMETHODCALLTYPE PSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -428,18 +308,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE CSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers); - - void STDMETHODCALLTYPE CSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants); - void STDMETHODCALLTYPE CSSetShaderResources( UINT StartSlot, UINT NumViews, @@ -456,18 +324,6 @@ namespace dxvk { ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts); - void STDMETHODCALLTYPE CSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers); - - void STDMETHODCALLTYPE CSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants); - void STDMETHODCALLTYPE CSGetShaderResources( UINT StartSlot, UINT NumViews, @@ -682,22 +538,6 @@ namespace dxvk { ID3D11Buffer* pBufferForArgs, ID3D11Buffer* pBufferForCount); - template - void SetConstantBuffers( - D3D11ConstantBufferBindings& Bindings, - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers); - - template - void SetConstantBuffers1( - D3D11ConstantBufferBindings& Bindings, - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer* const* ppConstantBuffers, - const UINT* pFirstConstant, - const UINT* pNumConstants); - template void SetSamplers( D3D11SamplerBindings& Bindings, @@ -712,14 +552,6 @@ namespace dxvk { UINT NumResources, ID3D11ShaderResourceView* const* ppResources); - void GetConstantBuffers( - const D3D11ConstantBufferBindings& Bindings, - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer** ppConstantBuffers, - UINT* pFirstConstant, - UINT* pNumConstants); - void GetShaderResources( const D3D11ShaderResourceBindings& Bindings, UINT StartSlot, diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 9d67e040d..e6ed67066 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -265,6 +265,38 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::VSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers( + m_state.vs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::VSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers1( + m_state.vs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::VSGetShader( ID3D11VertexShader** ppVertexShader, @@ -280,6 +312,39 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::VSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.vs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + nullptr, nullptr); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::VSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.vs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::HSSetShader( ID3D11HullShader* pHullShader, @@ -300,6 +365,38 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::HSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers( + m_state.hs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::HSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers1( + m_state.hs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::HSGetShader( ID3D11HullShader** ppHullShader, @@ -315,6 +412,39 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::HSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.hs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + nullptr, nullptr); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::HSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.hs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::DSSetShader( ID3D11DomainShader* pDomainShader, @@ -335,6 +465,38 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::DSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers( + m_state.ds.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers1( + m_state.ds.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::DSGetShader( ID3D11DomainShader** ppDomainShader, @@ -350,6 +512,39 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::DSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.ds.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + nullptr, nullptr); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.ds.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::GSSetShader( ID3D11GeometryShader* pShader, @@ -370,6 +565,38 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::GSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers( + m_state.gs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::GSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers1( + m_state.gs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::GSGetShader( ID3D11GeometryShader** ppGeometryShader, @@ -385,6 +612,39 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::GSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.gs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + nullptr, nullptr); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::GSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.gs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::PSSetShader( ID3D11PixelShader* pPixelShader, @@ -405,6 +665,38 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::PSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers( + m_state.ps.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::PSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers1( + m_state.ps.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::PSGetShader( ID3D11PixelShader** ppPixelShader, @@ -420,6 +712,39 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::PSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.ps.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + nullptr, nullptr); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::PSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.ps.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::CSSetShader( ID3D11ComputeShader* pComputeShader, @@ -440,6 +765,38 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::CSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers( + m_state.cs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::CSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + SetConstantBuffers1( + m_state.cs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::CSGetShader( ID3D11ComputeShader** ppComputeShader, @@ -455,6 +812,39 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::CSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.cs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + nullptr, nullptr); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::CSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + + GetConstantBuffers( + m_state.cs.constantBuffers, + StartSlot, NumBuffers, + ppConstantBuffers, + pFirstConstant, + pNumConstants); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::OMSetRenderTargets( UINT NumViews, @@ -883,6 +1273,38 @@ namespace dxvk { } + template + void D3D11CommonContext::GetConstantBuffers( + const D3D11ConstantBufferBindings& Bindings, + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants) { + for (uint32_t i = 0; i < NumBuffers; i++) { + const bool inRange = StartSlot + i < Bindings.size(); + + if (ppConstantBuffers) { + ppConstantBuffers[i] = inRange + ? Bindings[StartSlot + i].buffer.ref() + : nullptr; + } + + if (pFirstConstant) { + pFirstConstant[i] = inRange + ? Bindings[StartSlot + i].constantOffset + : 0u; + } + + if (pNumConstants) { + pNumConstants[i] = inRange + ? Bindings[StartSlot + i].constantCount + : 0u; + } + } + } + + template template void D3D11CommonContext::ResolveSrvHazards( @@ -980,6 +1402,107 @@ namespace dxvk { } + template + template + void D3D11CommonContext::SetConstantBuffers( + D3D11ConstantBufferBindings& Bindings, + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers) { + uint32_t slotId = computeConstantBufferBinding(ShaderStage, StartSlot); + + for (uint32_t i = 0; i < NumBuffers; i++) { + auto newBuffer = static_cast(ppConstantBuffers[i]); + + UINT constantCount = 0; + + if (likely(newBuffer != nullptr)) + constantCount = std::min(newBuffer->Desc()->ByteWidth / 16, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)); + + if (Bindings[StartSlot + i].buffer != newBuffer + || Bindings[StartSlot + i].constantBound != constantCount) { + Bindings[StartSlot + i].buffer = newBuffer; + Bindings[StartSlot + i].constantOffset = 0; + Bindings[StartSlot + i].constantCount = constantCount; + Bindings[StartSlot + i].constantBound = constantCount; + + BindConstantBuffer(slotId + i, newBuffer, 0, constantCount); + } + } + } + + + template + template + void D3D11CommonContext::SetConstantBuffers1( + D3D11ConstantBufferBindings& Bindings, + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants) { + uint32_t slotId = computeConstantBufferBinding(ShaderStage, StartSlot); + + for (uint32_t i = 0; i < NumBuffers; i++) { + auto newBuffer = static_cast(ppConstantBuffers[i]); + + UINT constantOffset; + UINT constantCount; + UINT constantBound; + + if (likely(newBuffer != nullptr)) { + UINT bufferConstantsCount = newBuffer->Desc()->ByteWidth / 16; + constantBound = std::min(bufferConstantsCount, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)); + + if (likely(pFirstConstant && pNumConstants)) { + constantOffset = pFirstConstant[i]; + constantCount = pNumConstants [i]; + + if (unlikely(constantCount > D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)) + continue; + + constantBound = (constantOffset + constantCount > bufferConstantsCount) + ? bufferConstantsCount - std::min(constantOffset, bufferConstantsCount) + : constantCount; + } else { + constantOffset = 0; + constantCount = constantBound; + } + } else { + constantOffset = 0; + constantCount = 0; + constantBound = 0; + } + + // Do a full rebind if either the buffer changes, or if either the current or + // the previous number of bound constants were zero, since we're binding a null + // buffer to the backend in that case. + bool needsUpdate = Bindings[StartSlot + i].buffer != newBuffer; + + if (!needsUpdate) { + needsUpdate |= !constantBound; + needsUpdate |= !Bindings[StartSlot + i].constantBound; + } + + if (needsUpdate) { + Bindings[StartSlot + i].buffer = newBuffer; + Bindings[StartSlot + i].constantOffset = constantOffset; + Bindings[StartSlot + i].constantCount = constantCount; + Bindings[StartSlot + i].constantBound = constantBound; + + BindConstantBuffer(slotId + i, newBuffer, constantOffset, constantBound); + } else if (Bindings[StartSlot + i].constantOffset != constantOffset + || Bindings[StartSlot + i].constantCount != constantCount) { + Bindings[StartSlot + i].constantOffset = constantOffset; + Bindings[StartSlot + i].constantCount = constantCount; + Bindings[StartSlot + i].constantBound = constantBound; + + BindConstantBufferRange(slotId + i, constantOffset, constantBound); + } + } + } + + template void D3D11CommonContext::SetRenderTargetsAndUnorderedAccessViews( UINT NumRTVs, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index f628d6fa7..66bd47f12 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -126,61 +126,205 @@ namespace dxvk { ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances); + void STDMETHODCALLTYPE VSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers); + + void STDMETHODCALLTYPE VSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants); + void STDMETHODCALLTYPE VSGetShader( ID3D11VertexShader** ppVertexShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances); + void STDMETHODCALLTYPE VSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers); + + void STDMETHODCALLTYPE VSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants); + void STDMETHODCALLTYPE HSSetShader( ID3D11HullShader* pHullShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances); + void STDMETHODCALLTYPE HSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers); + + void STDMETHODCALLTYPE HSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants); + void STDMETHODCALLTYPE HSGetShader( ID3D11HullShader** ppHullShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances); + void STDMETHODCALLTYPE HSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers); + + void STDMETHODCALLTYPE HSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants); + void STDMETHODCALLTYPE DSSetShader( ID3D11DomainShader* pDomainShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances); + void STDMETHODCALLTYPE DSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers); + + void STDMETHODCALLTYPE DSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants); + void STDMETHODCALLTYPE DSGetShader( ID3D11DomainShader** ppDomainShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances); + void STDMETHODCALLTYPE DSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers); + + void STDMETHODCALLTYPE DSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants); + void STDMETHODCALLTYPE GSSetShader( ID3D11GeometryShader* pShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances); + void STDMETHODCALLTYPE GSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers); + + void STDMETHODCALLTYPE GSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants); + void STDMETHODCALLTYPE GSGetShader( ID3D11GeometryShader** ppGeometryShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances); + void STDMETHODCALLTYPE GSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers); + + void STDMETHODCALLTYPE GSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants); + void STDMETHODCALLTYPE PSSetShader( ID3D11PixelShader* pPixelShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances); + void STDMETHODCALLTYPE PSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers); + + void STDMETHODCALLTYPE PSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants); + void STDMETHODCALLTYPE PSGetShader( ID3D11PixelShader** ppPixelShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances); + void STDMETHODCALLTYPE PSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers); + + void STDMETHODCALLTYPE PSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants); + void STDMETHODCALLTYPE CSSetShader( ID3D11ComputeShader* pComputeShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances); + void STDMETHODCALLTYPE CSSetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers); + + void STDMETHODCALLTYPE CSSetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants); + void STDMETHODCALLTYPE CSGetShader( ID3D11ComputeShader** ppComputeShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances); + void STDMETHODCALLTYPE CSGetConstantBuffers( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers); + + void STDMETHODCALLTYPE CSGetConstantBuffers1( + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants); + void STDMETHODCALLTYPE OMSetRenderTargets( UINT NumViews, ID3D11RenderTargetView* const* ppRenderTargetViews, @@ -289,6 +433,14 @@ namespace dxvk { UINT CtrSlot, UINT Counter); + void GetConstantBuffers( + const D3D11ConstantBufferBindings& Bindings, + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer** ppConstantBuffers, + UINT* pFirstConstant, + UINT* pNumConstants); + template void ResolveSrvHazards( T* pView, @@ -308,6 +460,22 @@ namespace dxvk { void ResolveOmUavHazards( D3D11RenderTargetView* pView); + template + void SetConstantBuffers( + D3D11ConstantBufferBindings& Bindings, + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers); + + template + void SetConstantBuffers1( + D3D11ConstantBufferBindings& Bindings, + UINT StartSlot, + UINT NumBuffers, + ID3D11Buffer* const* ppConstantBuffers, + const UINT* pFirstConstant, + const UINT* pNumConstants); + void SetRenderTargetsAndUnorderedAccessViews( UINT NumRTVs, ID3D11RenderTargetView* const* ppRenderTargetViews, From 3af5b3ba7ba122a8c767be7473f63d128e7f5b97 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 19:58:55 +0200 Subject: [PATCH 0380/1348] [d3d11] Move *SetShaderResources methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 186 --------------------------- src/d3d11/d3d11_context.h | 73 ----------- src/d3d11/d3d11_context_common.cpp | 200 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 73 +++++++++++ 4 files changed, 273 insertions(+), 259 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index b1c8864f8..9e521762d 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1284,19 +1284,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::VSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - SetShaderResources( - m_state.vs.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::VSSetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1310,17 +1297,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::VSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - GetShaderResources(m_state.vs.shaderResources, - StartSlot, NumViews, ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::VSGetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1332,19 +1308,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::HSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - SetShaderResources( - m_state.hs.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::HSSetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1358,17 +1321,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::HSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - GetShaderResources(m_state.hs.shaderResources, - StartSlot, NumViews, ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::HSGetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1380,19 +1332,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::DSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - SetShaderResources( - m_state.ds.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::DSSetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1406,17 +1345,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::DSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - GetShaderResources(m_state.ds.shaderResources, - StartSlot, NumViews, ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::DSGetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1428,19 +1356,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::GSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - SetShaderResources( - m_state.gs.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::GSSetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1454,17 +1369,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::GSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - GetShaderResources(m_state.gs.shaderResources, - StartSlot, NumViews, ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::GSGetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1476,19 +1380,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::PSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - SetShaderResources( - m_state.ps.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::PSSetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1502,17 +1393,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::PSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - GetShaderResources(m_state.ps.shaderResources, - StartSlot, NumViews, ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::PSGetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1524,19 +1404,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::CSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - SetShaderResources( - m_state.cs.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::CSSetSamplers( UINT StartSlot, UINT NumSamplers, @@ -1606,17 +1473,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::CSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews) { - D3D10DeviceLock lock = LockContext(); - - GetShaderResources(m_state.cs.shaderResources, - StartSlot, NumViews, ppShaderResourceViews); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::CSGetSamplers( UINT StartSlot, UINT NumSamplers, @@ -2957,48 +2813,6 @@ namespace dxvk { } - template - void D3D11DeviceContext::SetShaderResources( - D3D11ShaderResourceBindings& Bindings, - UINT StartSlot, - UINT NumResources, - ID3D11ShaderResourceView* const* ppResources) { - uint32_t slotId = computeSrvBinding(ShaderStage, StartSlot); - - for (uint32_t i = 0; i < NumResources; i++) { - auto resView = static_cast(ppResources[i]); - - if (Bindings.views[StartSlot + i] != resView) { - if (unlikely(resView && resView->TestHazards())) { - if (TestSrvHazards(resView)) - resView = nullptr; - - // Only set if necessary, but don't reset it on every - // bind as this would be more expensive than a few - // redundant checks in OMSetRenderTargets and friends. - Bindings.hazardous.set(StartSlot + i, resView); - } - - Bindings.views[StartSlot + i] = resView; - BindShaderResource(slotId + i, resView); - } - } - } - - - void D3D11DeviceContext::GetShaderResources( - const D3D11ShaderResourceBindings& Bindings, - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews) { - for (uint32_t i = 0; i < NumViews; i++) { - ppShaderResourceViews[i] = StartSlot + i < Bindings.views.size() - ? Bindings.views[StartSlot + i].ref() - : nullptr; - } - } - - void D3D11DeviceContext::GetSamplers( const D3D11SamplerBindings& Bindings, UINT StartSlot, diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 442c449e8..d975da86a 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -208,111 +208,56 @@ namespace dxvk { ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs); - void STDMETHODCALLTYPE VSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews); - void STDMETHODCALLTYPE VSSetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE VSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews); - void STDMETHODCALLTYPE VSGetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE HSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews); - void STDMETHODCALLTYPE HSSetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE HSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews); - void STDMETHODCALLTYPE HSGetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE DSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews); - void STDMETHODCALLTYPE DSSetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE DSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews); - void STDMETHODCALLTYPE DSGetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE GSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews); - void STDMETHODCALLTYPE GSSetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE GSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews); - void STDMETHODCALLTYPE GSGetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE PSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews); - void STDMETHODCALLTYPE PSSetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE PSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews); - void STDMETHODCALLTYPE PSGetSamplers( UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE CSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView* const* ppShaderResourceViews); - void STDMETHODCALLTYPE CSSetSamplers( UINT StartSlot, UINT NumSamplers, @@ -324,11 +269,6 @@ namespace dxvk { ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts); - void STDMETHODCALLTYPE CSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews); - void STDMETHODCALLTYPE CSGetSamplers( UINT StartSlot, UINT NumSamplers, @@ -545,19 +485,6 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); - template - void SetShaderResources( - D3D11ShaderResourceBindings& Bindings, - UINT StartSlot, - UINT NumResources, - ID3D11ShaderResourceView* const* ppResources); - - void GetShaderResources( - const D3D11ShaderResourceBindings& Bindings, - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView** ppShaderResourceViews); - void GetSamplers( const D3D11SamplerBindings& Bindings, UINT StartSlot, diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index e6ed67066..27adbdbc1 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -297,6 +297,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::VSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + SetShaderResources( + m_state.vs.shaderResources, + StartSlot, NumViews, + ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::VSGetShader( ID3D11VertexShader** ppVertexShader, @@ -345,6 +359,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::VSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + GetShaderResources(m_state.vs.shaderResources, + StartSlot, NumViews, ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::HSSetShader( ID3D11HullShader* pHullShader, @@ -397,6 +423,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::HSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + SetShaderResources( + m_state.hs.shaderResources, + StartSlot, NumViews, + ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::HSGetShader( ID3D11HullShader** ppHullShader, @@ -445,6 +485,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::HSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + GetShaderResources(m_state.hs.shaderResources, + StartSlot, NumViews, ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::DSSetShader( ID3D11DomainShader* pDomainShader, @@ -497,6 +549,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::DSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + SetShaderResources( + m_state.ds.shaderResources, + StartSlot, NumViews, + ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::DSGetShader( ID3D11DomainShader** ppDomainShader, @@ -545,6 +611,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::DSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + GetShaderResources(m_state.ds.shaderResources, + StartSlot, NumViews, ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::GSSetShader( ID3D11GeometryShader* pShader, @@ -597,6 +675,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::GSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + SetShaderResources( + m_state.gs.shaderResources, + StartSlot, NumViews, + ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::GSGetShader( ID3D11GeometryShader** ppGeometryShader, @@ -645,6 +737,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::GSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + GetShaderResources(m_state.gs.shaderResources, + StartSlot, NumViews, ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::PSSetShader( ID3D11PixelShader* pPixelShader, @@ -697,6 +801,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::PSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + SetShaderResources( + m_state.ps.shaderResources, + StartSlot, NumViews, + ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::PSGetShader( ID3D11PixelShader** ppPixelShader, @@ -745,6 +863,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::PSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + GetShaderResources(m_state.ps.shaderResources, + StartSlot, NumViews, ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::CSSetShader( ID3D11ComputeShader* pComputeShader, @@ -797,6 +927,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::CSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + SetShaderResources( + m_state.cs.shaderResources, + StartSlot, NumViews, + ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::CSGetShader( ID3D11ComputeShader** ppComputeShader, @@ -845,6 +989,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::CSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + + GetShaderResources(m_state.cs.shaderResources, + StartSlot, NumViews, ppShaderResourceViews); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::OMSetRenderTargets( UINT NumViews, @@ -1305,6 +1461,20 @@ namespace dxvk { } + template + void D3D11CommonContext::GetShaderResources( + const D3D11ShaderResourceBindings& Bindings, + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews) { + for (uint32_t i = 0; i < NumViews; i++) { + ppShaderResourceViews[i] = StartSlot + i < Bindings.views.size() + ? Bindings.views[StartSlot + i].ref() + : nullptr; + } + } + + template template void D3D11CommonContext::ResolveSrvHazards( @@ -1503,6 +1673,36 @@ namespace dxvk { } + template + template + void D3D11CommonContext::SetShaderResources( + D3D11ShaderResourceBindings& Bindings, + UINT StartSlot, + UINT NumResources, + ID3D11ShaderResourceView* const* ppResources) { + uint32_t slotId = computeSrvBinding(ShaderStage, StartSlot); + + for (uint32_t i = 0; i < NumResources; i++) { + auto resView = static_cast(ppResources[i]); + + if (Bindings.views[StartSlot + i] != resView) { + if (unlikely(resView && resView->TestHazards())) { + if (TestSrvHazards(resView)) + resView = nullptr; + + // Only set if necessary, but don't reset it on every + // bind as this would be more expensive than a few + // redundant checks in OMSetRenderTargets and friends. + Bindings.hazardous.set(StartSlot + i, resView); + } + + Bindings.views[StartSlot + i] = resView; + BindShaderResource(slotId + i, resView); + } + } + } + + template void D3D11CommonContext::SetRenderTargetsAndUnorderedAccessViews( UINT NumRTVs, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 66bd47f12..28ae115c9 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -138,6 +138,11 @@ namespace dxvk { const UINT* pFirstConstant, const UINT* pNumConstants); + void STDMETHODCALLTYPE VSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE VSGetShader( ID3D11VertexShader** ppVertexShader, ID3D11ClassInstance** ppClassInstances, @@ -155,6 +160,11 @@ namespace dxvk { UINT* pFirstConstant, UINT* pNumConstants); + void STDMETHODCALLTYPE VSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE HSSetShader( ID3D11HullShader* pHullShader, ID3D11ClassInstance* const* ppClassInstances, @@ -172,6 +182,11 @@ namespace dxvk { const UINT* pFirstConstant, const UINT* pNumConstants); + void STDMETHODCALLTYPE HSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE HSGetShader( ID3D11HullShader** ppHullShader, ID3D11ClassInstance** ppClassInstances, @@ -189,6 +204,11 @@ namespace dxvk { UINT* pFirstConstant, UINT* pNumConstants); + void STDMETHODCALLTYPE HSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE DSSetShader( ID3D11DomainShader* pDomainShader, ID3D11ClassInstance* const* ppClassInstances, @@ -206,6 +226,11 @@ namespace dxvk { const UINT* pFirstConstant, const UINT* pNumConstants); + void STDMETHODCALLTYPE DSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE DSGetShader( ID3D11DomainShader** ppDomainShader, ID3D11ClassInstance** ppClassInstances, @@ -223,6 +248,11 @@ namespace dxvk { UINT* pFirstConstant, UINT* pNumConstants); + void STDMETHODCALLTYPE DSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE GSSetShader( ID3D11GeometryShader* pShader, ID3D11ClassInstance* const* ppClassInstances, @@ -240,6 +270,11 @@ namespace dxvk { const UINT* pFirstConstant, const UINT* pNumConstants); + void STDMETHODCALLTYPE GSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE GSGetShader( ID3D11GeometryShader** ppGeometryShader, ID3D11ClassInstance** ppClassInstances, @@ -257,6 +292,11 @@ namespace dxvk { UINT* pFirstConstant, UINT* pNumConstants); + void STDMETHODCALLTYPE GSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE PSSetShader( ID3D11PixelShader* pPixelShader, ID3D11ClassInstance* const* ppClassInstances, @@ -274,6 +314,11 @@ namespace dxvk { const UINT* pFirstConstant, const UINT* pNumConstants); + void STDMETHODCALLTYPE PSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE PSGetShader( ID3D11PixelShader** ppPixelShader, ID3D11ClassInstance** ppClassInstances, @@ -291,6 +336,11 @@ namespace dxvk { UINT* pFirstConstant, UINT* pNumConstants); + void STDMETHODCALLTYPE PSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE CSSetShader( ID3D11ComputeShader* pComputeShader, ID3D11ClassInstance* const* ppClassInstances, @@ -308,6 +358,11 @@ namespace dxvk { const UINT* pFirstConstant, const UINT* pNumConstants); + void STDMETHODCALLTYPE CSSetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE CSGetShader( ID3D11ComputeShader** ppComputeShader, ID3D11ClassInstance** ppClassInstances, @@ -325,6 +380,11 @@ namespace dxvk { UINT* pFirstConstant, UINT* pNumConstants); + void STDMETHODCALLTYPE CSGetShaderResources( + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE OMSetRenderTargets( UINT NumViews, ID3D11RenderTargetView* const* ppRenderTargetViews, @@ -441,6 +501,12 @@ namespace dxvk { UINT* pFirstConstant, UINT* pNumConstants); + void GetShaderResources( + const D3D11ShaderResourceBindings& Bindings, + UINT StartSlot, + UINT NumViews, + ID3D11ShaderResourceView** ppShaderResourceViews); + template void ResolveSrvHazards( T* pView, @@ -476,6 +542,13 @@ namespace dxvk { const UINT* pFirstConstant, const UINT* pNumConstants); + template + void SetShaderResources( + D3D11ShaderResourceBindings& Bindings, + UINT StartSlot, + UINT NumResources, + ID3D11ShaderResourceView* const* ppResources); + void SetRenderTargetsAndUnorderedAccessViews( UINT NumRTVs, ID3D11RenderTargetView* const* ppRenderTargetViews, From 159eed825faf242cd08a40d7c4128efe870c4d99 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:02:23 +0200 Subject: [PATCH 0381/1348] [d3d11] Move *SetSamplers methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 176 -------------------------- src/d3d11/d3d11_context.h | 73 ----------- src/d3d11/d3d11_context_common.cpp | 190 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 73 +++++++++++ 4 files changed, 263 insertions(+), 249 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 9e521762d..48f36906c 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1284,139 +1284,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::VSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - SetSamplers( - m_state.vs.samplers, - StartSlot, NumSamplers, - ppSamplers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::VSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - GetSamplers(m_state.vs.samplers, - StartSlot, NumSamplers, ppSamplers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::HSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - SetSamplers( - m_state.hs.samplers, - StartSlot, NumSamplers, - ppSamplers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::HSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - GetSamplers(m_state.hs.samplers, - StartSlot, NumSamplers, ppSamplers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - SetSamplers( - m_state.ds.samplers, - StartSlot, NumSamplers, - ppSamplers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - GetSamplers(m_state.ds.samplers, - StartSlot, NumSamplers, ppSamplers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::GSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - SetSamplers( - m_state.gs.samplers, - StartSlot, NumSamplers, - ppSamplers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::GSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - GetSamplers(m_state.gs.samplers, - StartSlot, NumSamplers, ppSamplers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::PSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - SetSamplers( - m_state.ps.samplers, - StartSlot, NumSamplers, - ppSamplers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::PSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - GetSamplers(m_state.ps.samplers, - StartSlot, NumSamplers, ppSamplers); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::CSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - SetSamplers( - m_state.cs.samplers, - StartSlot, NumSamplers, - ppSamplers); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::CSSetUnorderedAccessViews( UINT StartSlot, UINT NumUAVs, @@ -1473,17 +1340,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::CSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers) { - D3D10DeviceLock lock = LockContext(); - - GetSamplers(m_state.cs.samplers, - StartSlot, NumSamplers, ppSamplers); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::CSGetUnorderedAccessViews( UINT StartSlot, UINT NumUAVs, @@ -2794,38 +2650,6 @@ namespace dxvk { } - template - void D3D11DeviceContext::SetSamplers( - D3D11SamplerBindings& Bindings, - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers) { - uint32_t slotId = computeSamplerBinding(ShaderStage, StartSlot); - - for (uint32_t i = 0; i < NumSamplers; i++) { - auto sampler = static_cast(ppSamplers[i]); - - if (Bindings[StartSlot + i] != sampler) { - Bindings[StartSlot + i] = sampler; - BindSampler(slotId + i, sampler); - } - } - } - - - void D3D11DeviceContext::GetSamplers( - const D3D11SamplerBindings& Bindings, - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers) { - for (uint32_t i = 0; i < NumSamplers; i++) { - ppSamplers[i] = StartSlot + i < Bindings.size() - ? ref(Bindings[StartSlot + i]) - : nullptr; - } - } - - void D3D11DeviceContext::ResetState() { EmitCs([] (DxvkContext* ctx) { // Reset render targets diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index d975da86a..bf093c0b0 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -208,72 +208,12 @@ namespace dxvk { ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs); - void STDMETHODCALLTYPE VSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers); - - void STDMETHODCALLTYPE VSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers); - - void STDMETHODCALLTYPE HSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers); - - void STDMETHODCALLTYPE HSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers); - - void STDMETHODCALLTYPE DSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers); - - void STDMETHODCALLTYPE DSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers); - - void STDMETHODCALLTYPE GSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers); - - void STDMETHODCALLTYPE GSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers); - - void STDMETHODCALLTYPE PSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers); - - void STDMETHODCALLTYPE PSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers); - - void STDMETHODCALLTYPE CSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers); - void STDMETHODCALLTYPE CSSetUnorderedAccessViews( UINT StartSlot, UINT NumUAVs, ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts); - void STDMETHODCALLTYPE CSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers); - void STDMETHODCALLTYPE CSGetUnorderedAccessViews( UINT StartSlot, UINT NumUAVs, @@ -478,19 +418,6 @@ namespace dxvk { ID3D11Buffer* pBufferForArgs, ID3D11Buffer* pBufferForCount); - template - void SetSamplers( - D3D11SamplerBindings& Bindings, - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState* const* ppSamplers); - - void GetSamplers( - const D3D11SamplerBindings& Bindings, - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState** ppSamplers); - void ResetState(); void RestoreState(); diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 27adbdbc1..832c806c7 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -311,6 +311,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::VSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + SetSamplers( + m_state.vs.samplers, + StartSlot, NumSamplers, + ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::VSGetShader( ID3D11VertexShader** ppVertexShader, @@ -371,6 +385,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::VSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + GetSamplers(m_state.vs.samplers, + StartSlot, NumSamplers, ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::HSSetShader( ID3D11HullShader* pHullShader, @@ -437,6 +463,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::HSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + SetSamplers( + m_state.hs.samplers, + StartSlot, NumSamplers, + ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::HSGetShader( ID3D11HullShader** ppHullShader, @@ -497,6 +537,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::HSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + GetSamplers(m_state.hs.samplers, + StartSlot, NumSamplers, ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::DSSetShader( ID3D11DomainShader* pDomainShader, @@ -563,6 +615,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::DSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + SetSamplers( + m_state.ds.samplers, + StartSlot, NumSamplers, + ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::DSGetShader( ID3D11DomainShader** ppDomainShader, @@ -623,6 +689,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::DSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + GetSamplers(m_state.ds.samplers, + StartSlot, NumSamplers, ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::GSSetShader( ID3D11GeometryShader* pShader, @@ -689,6 +767,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::GSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + SetSamplers( + m_state.gs.samplers, + StartSlot, NumSamplers, + ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::GSGetShader( ID3D11GeometryShader** ppGeometryShader, @@ -749,6 +841,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::GSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + GetSamplers(m_state.gs.samplers, + StartSlot, NumSamplers, ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::PSSetShader( ID3D11PixelShader* pPixelShader, @@ -815,6 +919,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::PSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + SetSamplers( + m_state.ps.samplers, + StartSlot, NumSamplers, + ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::PSGetShader( ID3D11PixelShader** ppPixelShader, @@ -875,6 +993,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::PSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + GetSamplers(m_state.ps.samplers, + StartSlot, NumSamplers, ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::CSSetShader( ID3D11ComputeShader* pComputeShader, @@ -941,6 +1071,20 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::CSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + SetSamplers( + m_state.cs.samplers, + StartSlot, NumSamplers, + ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::CSGetShader( ID3D11ComputeShader** ppComputeShader, @@ -1001,6 +1145,18 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::CSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + + GetSamplers(m_state.cs.samplers, + StartSlot, NumSamplers, ppSamplers); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::OMSetRenderTargets( UINT NumViews, @@ -1475,6 +1631,20 @@ namespace dxvk { } + template + void D3D11CommonContext::GetSamplers( + const D3D11SamplerBindings& Bindings, + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers) { + for (uint32_t i = 0; i < NumSamplers; i++) { + ppSamplers[i] = StartSlot + i < Bindings.size() + ? ref(Bindings[StartSlot + i]) + : nullptr; + } + } + + template template void D3D11CommonContext::ResolveSrvHazards( @@ -1703,6 +1873,26 @@ namespace dxvk { } + template + template + void D3D11CommonContext::SetSamplers( + D3D11SamplerBindings& Bindings, + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers) { + uint32_t slotId = computeSamplerBinding(ShaderStage, StartSlot); + + for (uint32_t i = 0; i < NumSamplers; i++) { + auto sampler = static_cast(ppSamplers[i]); + + if (Bindings[StartSlot + i] != sampler) { + Bindings[StartSlot + i] = sampler; + BindSampler(slotId + i, sampler); + } + } + } + + template void D3D11CommonContext::SetRenderTargetsAndUnorderedAccessViews( UINT NumRTVs, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 28ae115c9..450218cad 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -143,6 +143,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE VSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers); + void STDMETHODCALLTYPE VSGetShader( ID3D11VertexShader** ppVertexShader, ID3D11ClassInstance** ppClassInstances, @@ -165,6 +170,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE VSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers); + void STDMETHODCALLTYPE HSSetShader( ID3D11HullShader* pHullShader, ID3D11ClassInstance* const* ppClassInstances, @@ -187,6 +197,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE HSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers); + void STDMETHODCALLTYPE HSGetShader( ID3D11HullShader** ppHullShader, ID3D11ClassInstance** ppClassInstances, @@ -209,6 +224,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE HSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers); + void STDMETHODCALLTYPE DSSetShader( ID3D11DomainShader* pDomainShader, ID3D11ClassInstance* const* ppClassInstances, @@ -231,6 +251,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE DSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers); + void STDMETHODCALLTYPE DSGetShader( ID3D11DomainShader** ppDomainShader, ID3D11ClassInstance** ppClassInstances, @@ -253,6 +278,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE DSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers); + void STDMETHODCALLTYPE GSSetShader( ID3D11GeometryShader* pShader, ID3D11ClassInstance* const* ppClassInstances, @@ -275,6 +305,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE GSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers); + void STDMETHODCALLTYPE GSGetShader( ID3D11GeometryShader** ppGeometryShader, ID3D11ClassInstance** ppClassInstances, @@ -297,6 +332,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE GSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers); + void STDMETHODCALLTYPE PSSetShader( ID3D11PixelShader* pPixelShader, ID3D11ClassInstance* const* ppClassInstances, @@ -319,6 +359,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE PSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers); + void STDMETHODCALLTYPE PSGetShader( ID3D11PixelShader** ppPixelShader, ID3D11ClassInstance** ppClassInstances, @@ -341,6 +386,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE PSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers); + void STDMETHODCALLTYPE CSSetShader( ID3D11ComputeShader* pComputeShader, ID3D11ClassInstance* const* ppClassInstances, @@ -363,6 +413,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews); + void STDMETHODCALLTYPE CSSetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers); + void STDMETHODCALLTYPE CSGetShader( ID3D11ComputeShader** ppComputeShader, ID3D11ClassInstance** ppClassInstances, @@ -385,6 +440,11 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews); + void STDMETHODCALLTYPE CSGetSamplers( + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers); + void STDMETHODCALLTYPE OMSetRenderTargets( UINT NumViews, ID3D11RenderTargetView* const* ppRenderTargetViews, @@ -507,6 +567,12 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews); + void GetSamplers( + const D3D11SamplerBindings& Bindings, + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState** ppSamplers); + template void ResolveSrvHazards( T* pView, @@ -549,6 +615,13 @@ namespace dxvk { UINT NumResources, ID3D11ShaderResourceView* const* ppResources); + template + void SetSamplers( + D3D11SamplerBindings& Bindings, + UINT StartSlot, + UINT NumSamplers, + ID3D11SamplerState* const* ppSamplers); + void SetRenderTargetsAndUnorderedAccessViews( UINT NumRTVs, ID3D11RenderTargetView* const* ppRenderTargetViews, From f664e877492e03d5f7296c77034b54334634d7d4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:21:02 +0200 Subject: [PATCH 0382/1348] [d3d11] Move CSSetUnorderedAccessViews to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 70 ----------------------------- src/d3d11/d3d11_context.h | 11 ----- src/d3d11/d3d11_context_common.cpp | 72 ++++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 11 +++++ 4 files changed, 83 insertions(+), 81 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 48f36906c..39f2b1974 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1284,76 +1284,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::CSSetUnorderedAccessViews( - UINT StartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - const UINT* pUAVInitialCounts) { - D3D10DeviceLock lock = LockContext(); - - if (TestRtvUavHazards(0, nullptr, NumUAVs, ppUnorderedAccessViews)) - return; - - // Unbind previously bound conflicting UAVs - uint32_t uavSlotId = computeUavBinding (DxbcProgramType::ComputeShader, 0); - uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::ComputeShader, 0); - - int32_t uavId = m_state.cs.uavMask.findNext(0); - - while (uavId >= 0) { - if (uint32_t(uavId) < StartSlot || uint32_t(uavId) >= StartSlot + NumUAVs) { - for (uint32_t i = 0; i < NumUAVs; i++) { - auto uav = static_cast(ppUnorderedAccessViews[i]); - - if (CheckViewOverlap(uav, m_state.cs.unorderedAccessViews[uavId].ptr())) { - m_state.cs.unorderedAccessViews[uavId] = nullptr; - m_state.cs.uavMask.clr(uavId); - - BindUnorderedAccessView( - uavSlotId + uavId, nullptr, - ctrSlotId + uavId, ~0u); - } - } - - uavId = m_state.cs.uavMask.findNext(uavId + 1); - } else { - uavId = m_state.cs.uavMask.findNext(StartSlot + NumUAVs); - } - } - - // Actually bind the given UAVs - for (uint32_t i = 0; i < NumUAVs; i++) { - auto uav = static_cast(ppUnorderedAccessViews[i]); - auto ctr = pUAVInitialCounts ? pUAVInitialCounts[i] : ~0u; - - if (m_state.cs.unorderedAccessViews[StartSlot + i] != uav || ctr != ~0u) { - m_state.cs.unorderedAccessViews[StartSlot + i] = uav; - m_state.cs.uavMask.set(StartSlot + i, uav != nullptr); - - BindUnorderedAccessView( - uavSlotId + StartSlot + i, uav, - ctrSlotId + StartSlot + i, ctr); - - ResolveCsSrvHazards(uav); - } - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::CSGetUnorderedAccessViews( - UINT StartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView** ppUnorderedAccessViews) { - D3D10DeviceLock lock = LockContext(); - - for (uint32_t i = 0; i < NumUAVs; i++) { - ppUnorderedAccessViews[i] = StartSlot + i < m_state.cs.unorderedAccessViews.size() - ? m_state.cs.unorderedAccessViews[StartSlot + i].ref() - : nullptr; - } - } - - void STDMETHODCALLTYPE D3D11DeviceContext::RSSetState(ID3D11RasterizerState* pRasterizerState) { D3D10DeviceLock lock = LockContext(); diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index bf093c0b0..4cb0ebcb5 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -208,17 +208,6 @@ namespace dxvk { ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs); - void STDMETHODCALLTYPE CSSetUnorderedAccessViews( - UINT StartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, - const UINT* pUAVInitialCounts); - - void STDMETHODCALLTYPE CSGetUnorderedAccessViews( - UINT StartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView** ppUnorderedAccessViews); - void STDMETHODCALLTYPE RSSetState( ID3D11RasterizerState* pRasterizerState); diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 832c806c7..996ad3f7f 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -1085,6 +1085,63 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::CSSetUnorderedAccessViews( + UINT StartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, + const UINT* pUAVInitialCounts) { + D3D10DeviceLock lock = LockContext(); + + if (TestRtvUavHazards(0, nullptr, NumUAVs, ppUnorderedAccessViews)) + return; + + // Unbind previously bound conflicting UAVs + uint32_t uavSlotId = computeUavBinding (DxbcProgramType::ComputeShader, 0); + uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::ComputeShader, 0); + + int32_t uavId = m_state.cs.uavMask.findNext(0); + + while (uavId >= 0) { + if (uint32_t(uavId) < StartSlot || uint32_t(uavId) >= StartSlot + NumUAVs) { + for (uint32_t i = 0; i < NumUAVs; i++) { + auto uav = static_cast(ppUnorderedAccessViews[i]); + + if (CheckViewOverlap(uav, m_state.cs.unorderedAccessViews[uavId].ptr())) { + m_state.cs.unorderedAccessViews[uavId] = nullptr; + m_state.cs.uavMask.clr(uavId); + + BindUnorderedAccessView( + uavSlotId + uavId, nullptr, + ctrSlotId + uavId, ~0u); + } + } + + uavId = m_state.cs.uavMask.findNext(uavId + 1); + } else { + uavId = m_state.cs.uavMask.findNext(StartSlot + NumUAVs); + } + } + + // Actually bind the given UAVs + for (uint32_t i = 0; i < NumUAVs; i++) { + auto uav = static_cast(ppUnorderedAccessViews[i]); + auto ctr = pUAVInitialCounts ? pUAVInitialCounts[i] : ~0u; + + if (m_state.cs.unorderedAccessViews[StartSlot + i] != uav || ctr != ~0u) { + m_state.cs.unorderedAccessViews[StartSlot + i] = uav; + m_state.cs.uavMask.set(StartSlot + i, uav != nullptr); + + BindUnorderedAccessView( + uavSlotId + StartSlot + i, uav, + ctrSlotId + StartSlot + i, ctr); + + ResolveCsSrvHazards(uav); + } + } + } + + template void STDMETHODCALLTYPE D3D11CommonContext::CSGetShader( ID3D11ComputeShader** ppComputeShader, @@ -1157,6 +1214,21 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::CSGetUnorderedAccessViews( + UINT StartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView** ppUnorderedAccessViews) { + D3D10DeviceLock lock = LockContext(); + + for (uint32_t i = 0; i < NumUAVs; i++) { + ppUnorderedAccessViews[i] = StartSlot + i < m_state.cs.unorderedAccessViews.size() + ? m_state.cs.unorderedAccessViews[StartSlot + i].ref() + : nullptr; + } + } + + template void STDMETHODCALLTYPE D3D11CommonContext::OMSetRenderTargets( UINT NumViews, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 450218cad..ca7d8de57 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -418,6 +418,12 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); + void STDMETHODCALLTYPE CSSetUnorderedAccessViews( + UINT StartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, + const UINT* pUAVInitialCounts); + void STDMETHODCALLTYPE CSGetShader( ID3D11ComputeShader** ppComputeShader, ID3D11ClassInstance** ppClassInstances, @@ -445,6 +451,11 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); + void STDMETHODCALLTYPE CSGetUnorderedAccessViews( + UINT StartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView** ppUnorderedAccessViews); + void STDMETHODCALLTYPE OMSetRenderTargets( UINT NumViews, ID3D11RenderTargetView* const* ppRenderTargetViews, From 1ef9d5389bf547e4e47e38082e5e88aec9d858e0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:27:33 +0200 Subject: [PATCH 0383/1348] [d3d11] Move ClearState and RestoreState to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 333 ---------------------------- src/d3d11/d3d11_context.h | 22 -- src/d3d11/d3d11_context_common.cpp | 340 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 22 ++ 4 files changed, 362 insertions(+), 355 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 39f2b1974..b79506c11 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -104,122 +104,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::ClearState() { - D3D10DeviceLock lock = LockContext(); - - // Default shaders - m_state.vs.shader = nullptr; - m_state.hs.shader = nullptr; - m_state.ds.shader = nullptr; - m_state.gs.shader = nullptr; - m_state.ps.shader = nullptr; - m_state.cs.shader = nullptr; - - // Default constant buffers - for (uint32_t i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) { - m_state.vs.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.hs.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.ds.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.gs.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.ps.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.cs.constantBuffers[i] = { nullptr, 0, 0 }; - } - - // Default samplers - for (uint32_t i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) { - m_state.vs.samplers[i] = nullptr; - m_state.hs.samplers[i] = nullptr; - m_state.ds.samplers[i] = nullptr; - m_state.gs.samplers[i] = nullptr; - m_state.ps.samplers[i] = nullptr; - m_state.cs.samplers[i] = nullptr; - } - - // Default shader resources - for (uint32_t i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) { - m_state.vs.shaderResources.views[i] = nullptr; - m_state.hs.shaderResources.views[i] = nullptr; - m_state.ds.shaderResources.views[i] = nullptr; - m_state.gs.shaderResources.views[i] = nullptr; - m_state.ps.shaderResources.views[i] = nullptr; - m_state.cs.shaderResources.views[i] = nullptr; - } - - m_state.vs.shaderResources.hazardous.clear(); - m_state.hs.shaderResources.hazardous.clear(); - m_state.ds.shaderResources.hazardous.clear(); - m_state.gs.shaderResources.hazardous.clear(); - m_state.ps.shaderResources.hazardous.clear(); - m_state.cs.shaderResources.hazardous.clear(); - - // Default UAVs - for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) { - m_state.ps.unorderedAccessViews[i] = nullptr; - m_state.cs.unorderedAccessViews[i] = nullptr; - } - - m_state.cs.uavMask.clear(); - - // Default ID state - m_state.id.argBuffer = nullptr; - - // Default IA state - m_state.ia.inputLayout = nullptr; - m_state.ia.primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; - - for (uint32_t i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) { - m_state.ia.vertexBuffers[i].buffer = nullptr; - m_state.ia.vertexBuffers[i].offset = 0; - m_state.ia.vertexBuffers[i].stride = 0; - } - - m_state.ia.indexBuffer.buffer = nullptr; - m_state.ia.indexBuffer.offset = 0; - m_state.ia.indexBuffer.format = DXGI_FORMAT_UNKNOWN; - - // Default OM State - for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - m_state.om.renderTargetViews[i] = nullptr; - m_state.om.depthStencilView = nullptr; - - m_state.om.cbState = nullptr; - m_state.om.dsState = nullptr; - - for (uint32_t i = 0; i < 4; i++) - m_state.om.blendFactor[i] = 1.0f; - - m_state.om.sampleCount = 0; - m_state.om.sampleMask = D3D11_DEFAULT_SAMPLE_MASK; - m_state.om.stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE; - - m_state.om.maxRtv = 0; - m_state.om.maxUav = 0; - - // Default RS state - m_state.rs.state = nullptr; - m_state.rs.numViewports = 0; - m_state.rs.numScissors = 0; - - for (uint32_t i = 0; i < D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++) { - m_state.rs.viewports[i] = D3D11_VIEWPORT { }; - m_state.rs.scissors [i] = D3D11_RECT { }; - } - - // Default SO state - for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) { - m_state.so.targets[i].buffer = nullptr; - m_state.so.targets[i].offset = 0; - } - - // Default predication - m_state.pr.predicateObject = nullptr; - m_state.pr.predicateValue = FALSE; - - // Make sure to apply all state - ResetState(); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::SetPredication( ID3D11Predicate* pPredicate, BOOL PredicateValue) { @@ -2580,223 +2464,6 @@ namespace dxvk { } - void D3D11DeviceContext::ResetState() { - EmitCs([] (DxvkContext* ctx) { - // Reset render targets - ctx->bindRenderTargets(DxvkRenderTargets()); - - // Reset vertex input state - ctx->setInputLayout(0, nullptr, 0, nullptr); - - // Reset render states - DxvkInputAssemblyState iaState; - InitDefaultPrimitiveTopology(&iaState); - - DxvkDepthStencilState dsState; - InitDefaultDepthStencilState(&dsState); - - DxvkRasterizerState rsState; - InitDefaultRasterizerState(&rsState); - - DxvkBlendMode cbState; - DxvkLogicOpState loState; - DxvkMultisampleState msState; - InitDefaultBlendState(&cbState, &loState, &msState, D3D11_DEFAULT_SAMPLE_MASK); - - ctx->setInputAssemblyState(iaState); - ctx->setDepthStencilState(dsState); - ctx->setRasterizerState(rsState); - ctx->setLogicOpState(loState); - ctx->setMultisampleState(msState); - - for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - ctx->setBlendMode(i, cbState); - - // Reset dynamic states - ctx->setBlendConstants(DxvkBlendConstants { 1.0f, 1.0f, 1.0f, 1.0f }); - ctx->setStencilReference(D3D11_DEFAULT_STENCIL_REFERENCE); - - // Reset viewports - auto viewport = VkViewport(); - auto scissor = VkRect2D(); - - ctx->setViewports(1, &viewport, &scissor); - - // Unbind indirect draw buffer - ctx->bindDrawBuffers(DxvkBufferSlice(), DxvkBufferSlice()); - - // Unbind index and vertex buffers - ctx->bindIndexBuffer(DxvkBufferSlice(), VK_INDEX_TYPE_UINT32); - - for (uint32_t i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) - ctx->bindVertexBuffer(i, DxvkBufferSlice(), 0); - - // Unbind transform feedback buffers - for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) - ctx->bindXfbBuffer(i, DxvkBufferSlice(), DxvkBufferSlice()); - - // Unbind per-shader stage resources - for (uint32_t i = 0; i < 6; i++) { - auto programType = DxbcProgramType(i); - auto stage = GetShaderStage(programType); - - ctx->bindShader(stage, nullptr); - - // Unbind constant buffers, including the shader's ICB - auto cbSlotId = computeConstantBufferBinding(programType, 0); - - for (uint32_t j = 0; j <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; j++) - ctx->bindResourceBuffer(stage, cbSlotId + j, DxvkBufferSlice()); - - // Unbind shader resource views - auto srvSlotId = computeSrvBinding(programType, 0); - - for (uint32_t j = 0; j < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; j++) - ctx->bindResourceView(stage, srvSlotId + j, nullptr, nullptr); - - // Unbind texture samplers - auto samplerSlotId = computeSamplerBinding(programType, 0); - - for (uint32_t j = 0; j < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; j++) - ctx->bindResourceSampler(stage, samplerSlotId + j, nullptr); - - // Unbind UAVs for supported stages - if (programType == DxbcProgramType::PixelShader - || programType == DxbcProgramType::ComputeShader) { - VkShaderStageFlags stages = programType == DxbcProgramType::PixelShader - ? VK_SHADER_STAGE_ALL_GRAPHICS - : VK_SHADER_STAGE_COMPUTE_BIT; - - auto uavSlotId = computeUavBinding(programType, 0); - auto ctrSlotId = computeUavCounterBinding(programType, 0); - - for (uint32_t j = 0; j < D3D11_1_UAV_SLOT_COUNT; j++) { - ctx->bindResourceView (stages, uavSlotId, nullptr, nullptr); - ctx->bindResourceBuffer (stages, ctrSlotId, DxvkBufferSlice()); - } - } - } - - // Initialize push constants - DxbcPushConstants pc; - pc.rasterizerSampleCount = 1; - ctx->pushConstants(0, sizeof(pc), &pc); - }); - } - - - void D3D11DeviceContext::RestoreState() { - BindFramebuffer(); - - BindShader (GetCommonShader(m_state.vs.shader.ptr())); - BindShader (GetCommonShader(m_state.hs.shader.ptr())); - BindShader (GetCommonShader(m_state.ds.shader.ptr())); - BindShader (GetCommonShader(m_state.gs.shader.ptr())); - BindShader (GetCommonShader(m_state.ps.shader.ptr())); - BindShader (GetCommonShader(m_state.cs.shader.ptr())); - - ApplyInputLayout(); - ApplyPrimitiveTopology(); - ApplyBlendState(); - ApplyBlendFactor(); - ApplyDepthStencilState(); - ApplyStencilRef(); - ApplyRasterizerState(); - ApplyRasterizerSampleCount(); - ApplyViewportState(); - - BindDrawBuffers( - m_state.id.argBuffer.ptr(), - m_state.id.cntBuffer.ptr()); - - BindIndexBuffer( - m_state.ia.indexBuffer.buffer.ptr(), - m_state.ia.indexBuffer.offset, - m_state.ia.indexBuffer.format); - - for (uint32_t i = 0; i < m_state.ia.vertexBuffers.size(); i++) { - BindVertexBuffer(i, - m_state.ia.vertexBuffers[i].buffer.ptr(), - m_state.ia.vertexBuffers[i].offset, - m_state.ia.vertexBuffers[i].stride); - } - - for (uint32_t i = 0; i < m_state.so.targets.size(); i++) - BindXfbBuffer(i, m_state.so.targets[i].buffer.ptr(), ~0u); - - RestoreConstantBuffers (m_state.vs.constantBuffers); - RestoreConstantBuffers (m_state.hs.constantBuffers); - RestoreConstantBuffers (m_state.ds.constantBuffers); - RestoreConstantBuffers (m_state.gs.constantBuffers); - RestoreConstantBuffers (m_state.ps.constantBuffers); - RestoreConstantBuffers (m_state.cs.constantBuffers); - - RestoreSamplers (m_state.vs.samplers); - RestoreSamplers (m_state.hs.samplers); - RestoreSamplers (m_state.ds.samplers); - RestoreSamplers(m_state.gs.samplers); - RestoreSamplers (m_state.ps.samplers); - RestoreSamplers (m_state.cs.samplers); - - RestoreShaderResources (m_state.vs.shaderResources); - RestoreShaderResources (m_state.hs.shaderResources); - RestoreShaderResources (m_state.ds.shaderResources); - RestoreShaderResources (m_state.gs.shaderResources); - RestoreShaderResources (m_state.ps.shaderResources); - RestoreShaderResources (m_state.cs.shaderResources); - - RestoreUnorderedAccessViews (m_state.ps.unorderedAccessViews); - RestoreUnorderedAccessViews (m_state.cs.unorderedAccessViews); - } - - - template - void D3D11DeviceContext::RestoreConstantBuffers( - D3D11ConstantBufferBindings& Bindings) { - uint32_t slotId = computeConstantBufferBinding(Stage, 0); - - for (uint32_t i = 0; i < Bindings.size(); i++) { - BindConstantBuffer(slotId + i, Bindings[i].buffer.ptr(), - Bindings[i].constantOffset, Bindings[i].constantBound); - } - } - - - template - void D3D11DeviceContext::RestoreSamplers( - D3D11SamplerBindings& Bindings) { - uint32_t slotId = computeSamplerBinding(Stage, 0); - - for (uint32_t i = 0; i < Bindings.size(); i++) - BindSampler(slotId + i, Bindings[i]); - } - - - template - void D3D11DeviceContext::RestoreShaderResources( - D3D11ShaderResourceBindings& Bindings) { - uint32_t slotId = computeSrvBinding(Stage, 0); - - for (uint32_t i = 0; i < Bindings.views.size(); i++) - BindShaderResource(slotId + i, Bindings.views[i].ptr()); - } - - - template - void D3D11DeviceContext::RestoreUnorderedAccessViews( - D3D11UnorderedAccessBindings& Bindings) { - uint32_t uavSlotId = computeUavBinding (Stage, 0); - uint32_t ctrSlotId = computeUavCounterBinding(Stage, 0); - - for (uint32_t i = 0; i < Bindings.size(); i++) { - BindUnorderedAccessView( - uavSlotId + i, - Bindings[i].ptr(), - ctrSlotId + i, ~0u); - } - } - - bool D3D11DeviceContext::TestRtvUavHazards( UINT NumRTVs, ID3D11RenderTargetView* const* ppRTVs, diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 4cb0ebcb5..e82faee49 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -43,8 +43,6 @@ namespace dxvk { const D3D11_RECT* pRects, UINT NumRects); - void STDMETHODCALLTYPE ClearState(); - void STDMETHODCALLTYPE SetPredication( ID3D11Predicate* pPredicate, BOOL PredicateValue); @@ -407,26 +405,6 @@ namespace dxvk { ID3D11Buffer* pBufferForArgs, ID3D11Buffer* pBufferForCount); - void ResetState(); - - void RestoreState(); - - template - void RestoreConstantBuffers( - D3D11ConstantBufferBindings& Bindings); - - template - void RestoreSamplers( - D3D11SamplerBindings& Bindings); - - template - void RestoreShaderResources( - D3D11ShaderResourceBindings& Bindings); - - template - void RestoreUnorderedAccessViews( - D3D11UnorderedAccessBindings& Bindings); - bool TestRtvUavHazards( UINT NumRTVs, ID3D11RenderTargetView* const* ppRTVs, diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 996ad3f7f..c8ea5cf0b 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -63,6 +63,123 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::ClearState() { + D3D10DeviceLock lock = LockContext(); + + // Default shaders + m_state.vs.shader = nullptr; + m_state.hs.shader = nullptr; + m_state.ds.shader = nullptr; + m_state.gs.shader = nullptr; + m_state.ps.shader = nullptr; + m_state.cs.shader = nullptr; + + // Default constant buffers + for (uint32_t i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) { + m_state.vs.constantBuffers[i] = { nullptr, 0, 0 }; + m_state.hs.constantBuffers[i] = { nullptr, 0, 0 }; + m_state.ds.constantBuffers[i] = { nullptr, 0, 0 }; + m_state.gs.constantBuffers[i] = { nullptr, 0, 0 }; + m_state.ps.constantBuffers[i] = { nullptr, 0, 0 }; + m_state.cs.constantBuffers[i] = { nullptr, 0, 0 }; + } + + // Default samplers + for (uint32_t i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) { + m_state.vs.samplers[i] = nullptr; + m_state.hs.samplers[i] = nullptr; + m_state.ds.samplers[i] = nullptr; + m_state.gs.samplers[i] = nullptr; + m_state.ps.samplers[i] = nullptr; + m_state.cs.samplers[i] = nullptr; + } + + // Default shader resources + for (uint32_t i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) { + m_state.vs.shaderResources.views[i] = nullptr; + m_state.hs.shaderResources.views[i] = nullptr; + m_state.ds.shaderResources.views[i] = nullptr; + m_state.gs.shaderResources.views[i] = nullptr; + m_state.ps.shaderResources.views[i] = nullptr; + m_state.cs.shaderResources.views[i] = nullptr; + } + + m_state.vs.shaderResources.hazardous.clear(); + m_state.hs.shaderResources.hazardous.clear(); + m_state.ds.shaderResources.hazardous.clear(); + m_state.gs.shaderResources.hazardous.clear(); + m_state.ps.shaderResources.hazardous.clear(); + m_state.cs.shaderResources.hazardous.clear(); + + // Default UAVs + for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) { + m_state.ps.unorderedAccessViews[i] = nullptr; + m_state.cs.unorderedAccessViews[i] = nullptr; + } + + m_state.cs.uavMask.clear(); + + // Default ID state + m_state.id.argBuffer = nullptr; + + // Default IA state + m_state.ia.inputLayout = nullptr; + m_state.ia.primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + + for (uint32_t i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) { + m_state.ia.vertexBuffers[i].buffer = nullptr; + m_state.ia.vertexBuffers[i].offset = 0; + m_state.ia.vertexBuffers[i].stride = 0; + } + + m_state.ia.indexBuffer.buffer = nullptr; + m_state.ia.indexBuffer.offset = 0; + m_state.ia.indexBuffer.format = DXGI_FORMAT_UNKNOWN; + + // Default OM State + for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + m_state.om.renderTargetViews[i] = nullptr; + m_state.om.depthStencilView = nullptr; + + m_state.om.cbState = nullptr; + m_state.om.dsState = nullptr; + + for (uint32_t i = 0; i < 4; i++) + m_state.om.blendFactor[i] = 1.0f; + + m_state.om.sampleCount = 0; + m_state.om.sampleMask = D3D11_DEFAULT_SAMPLE_MASK; + m_state.om.stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE; + + m_state.om.maxRtv = 0; + m_state.om.maxUav = 0; + + // Default RS state + m_state.rs.state = nullptr; + m_state.rs.numViewports = 0; + m_state.rs.numScissors = 0; + + for (uint32_t i = 0; i < D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++) { + m_state.rs.viewports[i] = D3D11_VIEWPORT { }; + m_state.rs.scissors [i] = D3D11_RECT { }; + } + + // Default SO state + for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) { + m_state.so.targets[i].buffer = nullptr; + m_state.so.targets[i].offset = 0; + } + + // Default predication + m_state.pr.predicateObject = nullptr; + m_state.pr.predicateValue = FALSE; + + // Make sure to apply all state + ResetState(); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::UpdateSubresource( ID3D11Resource* pDstResource, @@ -1717,6 +1834,112 @@ namespace dxvk { } + template + void D3D11CommonContext::ResetState() { + EmitCs([] (DxvkContext* ctx) { + // Reset render targets + ctx->bindRenderTargets(DxvkRenderTargets()); + + // Reset vertex input state + ctx->setInputLayout(0, nullptr, 0, nullptr); + + // Reset render states + DxvkInputAssemblyState iaState; + InitDefaultPrimitiveTopology(&iaState); + + DxvkDepthStencilState dsState; + InitDefaultDepthStencilState(&dsState); + + DxvkRasterizerState rsState; + InitDefaultRasterizerState(&rsState); + + DxvkBlendMode cbState; + DxvkLogicOpState loState; + DxvkMultisampleState msState; + InitDefaultBlendState(&cbState, &loState, &msState, D3D11_DEFAULT_SAMPLE_MASK); + + ctx->setInputAssemblyState(iaState); + ctx->setDepthStencilState(dsState); + ctx->setRasterizerState(rsState); + ctx->setLogicOpState(loState); + ctx->setMultisampleState(msState); + + for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + ctx->setBlendMode(i, cbState); + + // Reset dynamic states + ctx->setBlendConstants(DxvkBlendConstants { 1.0f, 1.0f, 1.0f, 1.0f }); + ctx->setStencilReference(D3D11_DEFAULT_STENCIL_REFERENCE); + + // Reset viewports + auto viewport = VkViewport(); + auto scissor = VkRect2D(); + + ctx->setViewports(1, &viewport, &scissor); + + // Unbind indirect draw buffer + ctx->bindDrawBuffers(DxvkBufferSlice(), DxvkBufferSlice()); + + // Unbind index and vertex buffers + ctx->bindIndexBuffer(DxvkBufferSlice(), VK_INDEX_TYPE_UINT32); + + for (uint32_t i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + ctx->bindVertexBuffer(i, DxvkBufferSlice(), 0); + + // Unbind transform feedback buffers + for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) + ctx->bindXfbBuffer(i, DxvkBufferSlice(), DxvkBufferSlice()); + + // Unbind per-shader stage resources + for (uint32_t i = 0; i < 6; i++) { + auto programType = DxbcProgramType(i); + auto stage = GetShaderStage(programType); + + ctx->bindShader(stage, nullptr); + + // Unbind constant buffers, including the shader's ICB + auto cbSlotId = computeConstantBufferBinding(programType, 0); + + for (uint32_t j = 0; j <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; j++) + ctx->bindResourceBuffer(stage, cbSlotId + j, DxvkBufferSlice()); + + // Unbind shader resource views + auto srvSlotId = computeSrvBinding(programType, 0); + + for (uint32_t j = 0; j < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; j++) + ctx->bindResourceView(stage, srvSlotId + j, nullptr, nullptr); + + // Unbind texture samplers + auto samplerSlotId = computeSamplerBinding(programType, 0); + + for (uint32_t j = 0; j < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; j++) + ctx->bindResourceSampler(stage, samplerSlotId + j, nullptr); + + // Unbind UAVs for supported stages + if (programType == DxbcProgramType::PixelShader + || programType == DxbcProgramType::ComputeShader) { + VkShaderStageFlags stages = programType == DxbcProgramType::PixelShader + ? VK_SHADER_STAGE_ALL_GRAPHICS + : VK_SHADER_STAGE_COMPUTE_BIT; + + auto uavSlotId = computeUavBinding(programType, 0); + auto ctrSlotId = computeUavCounterBinding(programType, 0); + + for (uint32_t j = 0; j < D3D11_1_UAV_SLOT_COUNT; j++) { + ctx->bindResourceView (stages, uavSlotId, nullptr, nullptr); + ctx->bindResourceBuffer (stages, ctrSlotId, DxvkBufferSlice()); + } + } + } + + // Initialize push constants + DxbcPushConstants pc; + pc.rasterizerSampleCount = 1; + ctx->pushConstants(0, sizeof(pc), &pc); + }); + } + + template template void D3D11CommonContext::ResolveSrvHazards( @@ -2049,6 +2272,123 @@ namespace dxvk { } + template + void D3D11CommonContext::RestoreState() { + BindFramebuffer(); + + BindShader (GetCommonShader(m_state.vs.shader.ptr())); + BindShader (GetCommonShader(m_state.hs.shader.ptr())); + BindShader (GetCommonShader(m_state.ds.shader.ptr())); + BindShader (GetCommonShader(m_state.gs.shader.ptr())); + BindShader (GetCommonShader(m_state.ps.shader.ptr())); + BindShader (GetCommonShader(m_state.cs.shader.ptr())); + + ApplyInputLayout(); + ApplyPrimitiveTopology(); + ApplyBlendState(); + ApplyBlendFactor(); + ApplyDepthStencilState(); + ApplyStencilRef(); + ApplyRasterizerState(); + ApplyRasterizerSampleCount(); + ApplyViewportState(); + + BindDrawBuffers( + m_state.id.argBuffer.ptr(), + m_state.id.cntBuffer.ptr()); + + BindIndexBuffer( + m_state.ia.indexBuffer.buffer.ptr(), + m_state.ia.indexBuffer.offset, + m_state.ia.indexBuffer.format); + + for (uint32_t i = 0; i < m_state.ia.vertexBuffers.size(); i++) { + BindVertexBuffer(i, + m_state.ia.vertexBuffers[i].buffer.ptr(), + m_state.ia.vertexBuffers[i].offset, + m_state.ia.vertexBuffers[i].stride); + } + + for (uint32_t i = 0; i < m_state.so.targets.size(); i++) + BindXfbBuffer(i, m_state.so.targets[i].buffer.ptr(), ~0u); + + RestoreConstantBuffers (m_state.vs.constantBuffers); + RestoreConstantBuffers (m_state.hs.constantBuffers); + RestoreConstantBuffers (m_state.ds.constantBuffers); + RestoreConstantBuffers (m_state.gs.constantBuffers); + RestoreConstantBuffers (m_state.ps.constantBuffers); + RestoreConstantBuffers (m_state.cs.constantBuffers); + + RestoreSamplers (m_state.vs.samplers); + RestoreSamplers (m_state.hs.samplers); + RestoreSamplers (m_state.ds.samplers); + RestoreSamplers(m_state.gs.samplers); + RestoreSamplers (m_state.ps.samplers); + RestoreSamplers (m_state.cs.samplers); + + RestoreShaderResources (m_state.vs.shaderResources); + RestoreShaderResources (m_state.hs.shaderResources); + RestoreShaderResources (m_state.ds.shaderResources); + RestoreShaderResources (m_state.gs.shaderResources); + RestoreShaderResources (m_state.ps.shaderResources); + RestoreShaderResources (m_state.cs.shaderResources); + + RestoreUnorderedAccessViews (m_state.ps.unorderedAccessViews); + RestoreUnorderedAccessViews (m_state.cs.unorderedAccessViews); + } + + + template + template + void D3D11CommonContext::RestoreConstantBuffers( + D3D11ConstantBufferBindings& Bindings) { + uint32_t slotId = computeConstantBufferBinding(Stage, 0); + + for (uint32_t i = 0; i < Bindings.size(); i++) { + BindConstantBuffer(slotId + i, Bindings[i].buffer.ptr(), + Bindings[i].constantOffset, Bindings[i].constantBound); + } + } + + + template + template + void D3D11CommonContext::RestoreSamplers( + D3D11SamplerBindings& Bindings) { + uint32_t slotId = computeSamplerBinding(Stage, 0); + + for (uint32_t i = 0; i < Bindings.size(); i++) + BindSampler(slotId + i, Bindings[i]); + } + + + template + template + void D3D11CommonContext::RestoreShaderResources( + D3D11ShaderResourceBindings& Bindings) { + uint32_t slotId = computeSrvBinding(Stage, 0); + + for (uint32_t i = 0; i < Bindings.views.size(); i++) + BindShaderResource(slotId + i, Bindings.views[i].ptr()); + } + + + template + template + void D3D11CommonContext::RestoreUnorderedAccessViews( + D3D11UnorderedAccessBindings& Bindings) { + uint32_t uavSlotId = computeUavBinding (Stage, 0); + uint32_t ctrSlotId = computeUavCounterBinding(Stage, 0); + + for (uint32_t i = 0; i < Bindings.size(); i++) { + BindUnorderedAccessView( + uavSlotId + i, + Bindings[i].ptr(), + ctrSlotId + i, ~0u); + } + } + + template bool D3D11CommonContext::TestRtvUavHazards( UINT NumRTVs, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index ca7d8de57..d13fa1792 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -68,6 +68,8 @@ namespace dxvk { REFIID riid, void** ppvObject); + void STDMETHODCALLTYPE ClearState(); + void STDMETHODCALLTYPE UpdateSubresource( ID3D11Resource* pDstResource, UINT DstSubresource, @@ -584,6 +586,8 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); + void ResetState(); + template void ResolveSrvHazards( T* pView, @@ -603,6 +607,24 @@ namespace dxvk { void ResolveOmUavHazards( D3D11RenderTargetView* pView); + void RestoreState(); + + template + void RestoreConstantBuffers( + D3D11ConstantBufferBindings& Bindings); + + template + void RestoreSamplers( + D3D11SamplerBindings& Bindings); + + template + void RestoreShaderResources( + D3D11ShaderResourceBindings& Bindings); + + template + void RestoreUnorderedAccessViews( + D3D11UnorderedAccessBindings& Bindings); + template void SetConstantBuffers( D3D11ConstantBufferBindings& Bindings, From 4d498851a8c94d053f2cf20d65b7d813d0255a6c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:30:11 +0200 Subject: [PATCH 0384/1348] [d3d11] Move RS* methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 152 --------------------------- src/d3d11/d3d11_context.h | 22 ---- src/d3d11/d3d11_context_common.cpp | 158 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 22 ++++ 4 files changed, 180 insertions(+), 174 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index b79506c11..c94242638 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1168,158 +1168,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::RSSetState(ID3D11RasterizerState* pRasterizerState) { - D3D10DeviceLock lock = LockContext(); - - auto currRasterizerState = m_state.rs.state; - auto nextRasterizerState = static_cast(pRasterizerState); - - if (m_state.rs.state != nextRasterizerState) { - m_state.rs.state = nextRasterizerState; - ApplyRasterizerState(); - - // If necessary, update the rasterizer sample count push constant - uint32_t currSampleCount = currRasterizerState != nullptr ? currRasterizerState->Desc()->ForcedSampleCount : 0; - uint32_t nextSampleCount = nextRasterizerState != nullptr ? nextRasterizerState->Desc()->ForcedSampleCount : 0; - - if (currSampleCount != nextSampleCount) - ApplyRasterizerSampleCount(); - - // In D3D11, the rasterizer state defines whether the scissor test is - // enabled, so if that changes, we need to update scissor rects as well. - bool currScissorEnable = currRasterizerState != nullptr ? currRasterizerState->Desc()->ScissorEnable : false; - bool nextScissorEnable = nextRasterizerState != nullptr ? nextRasterizerState->Desc()->ScissorEnable : false; - - if (currScissorEnable != nextScissorEnable) - ApplyViewportState(); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::RSSetViewports( - UINT NumViewports, - const D3D11_VIEWPORT* pViewports) { - D3D10DeviceLock lock = LockContext(); - - if (unlikely(NumViewports > m_state.rs.viewports.size())) - return; - - bool dirty = m_state.rs.numViewports != NumViewports; - m_state.rs.numViewports = NumViewports; - - for (uint32_t i = 0; i < NumViewports; i++) { - const D3D11_VIEWPORT& vp = m_state.rs.viewports[i]; - - dirty |= vp.TopLeftX != pViewports[i].TopLeftX - || vp.TopLeftY != pViewports[i].TopLeftY - || vp.Width != pViewports[i].Width - || vp.Height != pViewports[i].Height - || vp.MinDepth != pViewports[i].MinDepth - || vp.MaxDepth != pViewports[i].MaxDepth; - - m_state.rs.viewports[i] = pViewports[i]; - } - - if (dirty) - ApplyViewportState(); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::RSSetScissorRects( - UINT NumRects, - const D3D11_RECT* pRects) { - D3D10DeviceLock lock = LockContext(); - - if (unlikely(NumRects > m_state.rs.scissors.size())) - return; - - bool dirty = m_state.rs.numScissors != NumRects; - m_state.rs.numScissors = NumRects; - - for (uint32_t i = 0; i < NumRects; i++) { - if (pRects[i].bottom >= pRects[i].top - && pRects[i].right >= pRects[i].left) { - const D3D11_RECT& sr = m_state.rs.scissors[i]; - - dirty |= sr.top != pRects[i].top - || sr.left != pRects[i].left - || sr.bottom != pRects[i].bottom - || sr.right != pRects[i].right; - - m_state.rs.scissors[i] = pRects[i]; - } - } - - if (m_state.rs.state != nullptr && dirty) { - D3D11_RASTERIZER_DESC rsDesc; - m_state.rs.state->GetDesc(&rsDesc); - - if (rsDesc.ScissorEnable) - ApplyViewportState(); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::RSGetState(ID3D11RasterizerState** ppRasterizerState) { - D3D10DeviceLock lock = LockContext(); - - if (ppRasterizerState != nullptr) - *ppRasterizerState = ref(m_state.rs.state); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::RSGetViewports( - UINT* pNumViewports, - D3D11_VIEWPORT* pViewports) { - D3D10DeviceLock lock = LockContext(); - uint32_t numWritten = m_state.rs.numViewports; - - if (pViewports) { - numWritten = std::min(numWritten, *pNumViewports); - - for (uint32_t i = 0; i < *pNumViewports; i++) { - if (i < m_state.rs.numViewports) { - pViewports[i] = m_state.rs.viewports[i]; - } else { - pViewports[i].TopLeftX = 0.0f; - pViewports[i].TopLeftY = 0.0f; - pViewports[i].Width = 0.0f; - pViewports[i].Height = 0.0f; - pViewports[i].MinDepth = 0.0f; - pViewports[i].MaxDepth = 0.0f; - } - } - } - - *pNumViewports = numWritten; - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::RSGetScissorRects( - UINT* pNumRects, - D3D11_RECT* pRects) { - D3D10DeviceLock lock = LockContext(); - uint32_t numWritten = m_state.rs.numScissors; - - if (pRects) { - numWritten = std::min(numWritten, *pNumRects); - - for (uint32_t i = 0; i < *pNumRects; i++) { - if (i < m_state.rs.numScissors) { - pRects[i] = m_state.rs.scissors[i]; - } else { - pRects[i].left = 0; - pRects[i].top = 0; - pRects[i].right = 0; - pRects[i].bottom = 0; - } - } - } - - *pNumRects = m_state.rs.numScissors; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::SOSetTargets( UINT NumBuffers, ID3D11Buffer* const* ppSOTargets, diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index e82faee49..add4f82e8 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -206,28 +206,6 @@ namespace dxvk { ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs); - void STDMETHODCALLTYPE RSSetState( - ID3D11RasterizerState* pRasterizerState); - - void STDMETHODCALLTYPE RSSetViewports( - UINT NumViewports, - const D3D11_VIEWPORT* pViewports); - - void STDMETHODCALLTYPE RSSetScissorRects( - UINT NumRects, - const D3D11_RECT* pRects); - - void STDMETHODCALLTYPE RSGetState( - ID3D11RasterizerState** ppRasterizerState); - - void STDMETHODCALLTYPE RSGetViewports( - UINT* pNumViewports, - D3D11_VIEWPORT* pViewports); - - void STDMETHODCALLTYPE RSGetScissorRects( - UINT* pNumRects, - D3D11_RECT* pRects); - void STDMETHODCALLTYPE SOSetTargets( UINT NumBuffers, ID3D11Buffer* const* ppSOTargets, diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index c8ea5cf0b..e209816bb 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -1502,6 +1502,164 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::RSSetState(ID3D11RasterizerState* pRasterizerState) { + D3D10DeviceLock lock = LockContext(); + + auto currRasterizerState = m_state.rs.state; + auto nextRasterizerState = static_cast(pRasterizerState); + + if (m_state.rs.state != nextRasterizerState) { + m_state.rs.state = nextRasterizerState; + ApplyRasterizerState(); + + // If necessary, update the rasterizer sample count push constant + uint32_t currSampleCount = currRasterizerState != nullptr ? currRasterizerState->Desc()->ForcedSampleCount : 0; + uint32_t nextSampleCount = nextRasterizerState != nullptr ? nextRasterizerState->Desc()->ForcedSampleCount : 0; + + if (currSampleCount != nextSampleCount) + ApplyRasterizerSampleCount(); + + // In D3D11, the rasterizer state defines whether the scissor test is + // enabled, so if that changes, we need to update scissor rects as well. + bool currScissorEnable = currRasterizerState != nullptr ? currRasterizerState->Desc()->ScissorEnable : false; + bool nextScissorEnable = nextRasterizerState != nullptr ? nextRasterizerState->Desc()->ScissorEnable : false; + + if (currScissorEnable != nextScissorEnable) + ApplyViewportState(); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::RSSetViewports( + UINT NumViewports, + const D3D11_VIEWPORT* pViewports) { + D3D10DeviceLock lock = LockContext(); + + if (unlikely(NumViewports > m_state.rs.viewports.size())) + return; + + bool dirty = m_state.rs.numViewports != NumViewports; + m_state.rs.numViewports = NumViewports; + + for (uint32_t i = 0; i < NumViewports; i++) { + const D3D11_VIEWPORT& vp = m_state.rs.viewports[i]; + + dirty |= vp.TopLeftX != pViewports[i].TopLeftX + || vp.TopLeftY != pViewports[i].TopLeftY + || vp.Width != pViewports[i].Width + || vp.Height != pViewports[i].Height + || vp.MinDepth != pViewports[i].MinDepth + || vp.MaxDepth != pViewports[i].MaxDepth; + + m_state.rs.viewports[i] = pViewports[i]; + } + + if (dirty) + ApplyViewportState(); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::RSSetScissorRects( + UINT NumRects, + const D3D11_RECT* pRects) { + D3D10DeviceLock lock = LockContext(); + + if (unlikely(NumRects > m_state.rs.scissors.size())) + return; + + bool dirty = m_state.rs.numScissors != NumRects; + m_state.rs.numScissors = NumRects; + + for (uint32_t i = 0; i < NumRects; i++) { + if (pRects[i].bottom >= pRects[i].top + && pRects[i].right >= pRects[i].left) { + const D3D11_RECT& sr = m_state.rs.scissors[i]; + + dirty |= sr.top != pRects[i].top + || sr.left != pRects[i].left + || sr.bottom != pRects[i].bottom + || sr.right != pRects[i].right; + + m_state.rs.scissors[i] = pRects[i]; + } + } + + if (m_state.rs.state != nullptr && dirty) { + D3D11_RASTERIZER_DESC rsDesc; + m_state.rs.state->GetDesc(&rsDesc); + + if (rsDesc.ScissorEnable) + ApplyViewportState(); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::RSGetState(ID3D11RasterizerState** ppRasterizerState) { + D3D10DeviceLock lock = LockContext(); + + if (ppRasterizerState) + *ppRasterizerState = ref(m_state.rs.state); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::RSGetViewports( + UINT* pNumViewports, + D3D11_VIEWPORT* pViewports) { + D3D10DeviceLock lock = LockContext(); + uint32_t numWritten = m_state.rs.numViewports; + + if (pViewports) { + numWritten = std::min(numWritten, *pNumViewports); + + for (uint32_t i = 0; i < *pNumViewports; i++) { + if (i < m_state.rs.numViewports) { + pViewports[i] = m_state.rs.viewports[i]; + } else { + pViewports[i].TopLeftX = 0.0f; + pViewports[i].TopLeftY = 0.0f; + pViewports[i].Width = 0.0f; + pViewports[i].Height = 0.0f; + pViewports[i].MinDepth = 0.0f; + pViewports[i].MaxDepth = 0.0f; + } + } + } + + *pNumViewports = numWritten; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::RSGetScissorRects( + UINT* pNumRects, + D3D11_RECT* pRects) { + D3D10DeviceLock lock = LockContext(); + uint32_t numWritten = m_state.rs.numScissors; + + if (pRects) { + numWritten = std::min(numWritten, *pNumRects); + + for (uint32_t i = 0; i < *pNumRects; i++) { + if (i < m_state.rs.numScissors) { + pRects[i] = m_state.rs.scissors[i]; + } else { + pRects[i].left = 0; + pRects[i].top = 0; + pRects[i].right = 0; + pRects[i].bottom = 0; + } + } + } + + *pNumRects = m_state.rs.numScissors; + } + + template BOOL STDMETHODCALLTYPE D3D11CommonContext::IsAnnotationEnabled() { return m_annotation.GetStatus(); diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index d13fa1792..4225e577c 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -503,6 +503,28 @@ namespace dxvk { ID3D11DepthStencilState** ppDepthStencilState, UINT* pStencilRef); + void STDMETHODCALLTYPE RSSetState( + ID3D11RasterizerState* pRasterizerState); + + void STDMETHODCALLTYPE RSSetViewports( + UINT NumViewports, + const D3D11_VIEWPORT* pViewports); + + void STDMETHODCALLTYPE RSSetScissorRects( + UINT NumRects, + const D3D11_RECT* pRects); + + void STDMETHODCALLTYPE RSGetState( + ID3D11RasterizerState** ppRasterizerState); + + void STDMETHODCALLTYPE RSGetViewports( + UINT* pNumViewports, + D3D11_VIEWPORT* pViewports); + + void STDMETHODCALLTYPE RSGetScissorRects( + UINT* pNumRects, + D3D11_RECT* pRects); + BOOL STDMETHODCALLTYPE IsAnnotationEnabled(); protected: From efea51c25482a3f37ac469e06d01027b413bc8d9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:31:33 +0200 Subject: [PATCH 0385/1348] [d3d11] Move SO* methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 64 ---------------------------- src/d3d11/d3d11_context.h | 14 ------- src/d3d11/d3d11_context_common.cpp | 67 ++++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 14 +++++++ 4 files changed, 81 insertions(+), 78 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index c94242638..57304ef12 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1168,70 +1168,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::SOSetTargets( - UINT NumBuffers, - ID3D11Buffer* const* ppSOTargets, - const UINT* pOffsets) { - D3D10DeviceLock lock = LockContext(); - - for (uint32_t i = 0; i < NumBuffers; i++) { - D3D11Buffer* buffer = static_cast(ppSOTargets[i]); - UINT offset = pOffsets != nullptr ? pOffsets[i] : 0; - - m_state.so.targets[i].buffer = buffer; - m_state.so.targets[i].offset = offset; - } - - for (uint32_t i = NumBuffers; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) { - m_state.so.targets[i].buffer = nullptr; - m_state.so.targets[i].offset = 0; - } - - for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) { - BindXfbBuffer(i, - m_state.so.targets[i].buffer.ptr(), - m_state.so.targets[i].offset); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::SOGetTargets( - UINT NumBuffers, - ID3D11Buffer** ppSOTargets) { - D3D10DeviceLock lock = LockContext(); - - for (uint32_t i = 0; i < NumBuffers; i++) { - ppSOTargets[i] = i < m_state.so.targets.size() - ? m_state.so.targets[i].buffer.ref() - : nullptr; - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::SOGetTargetsWithOffsets( - UINT NumBuffers, - ID3D11Buffer** ppSOTargets, - UINT* pOffsets) { - D3D10DeviceLock lock = LockContext(); - - for (uint32_t i = 0; i < NumBuffers; i++) { - const bool inRange = i < m_state.so.targets.size(); - - if (ppSOTargets != nullptr) { - ppSOTargets[i] = inRange - ? m_state.so.targets[i].buffer.ref() - : nullptr; - } - - if (pOffsets != nullptr) { - pOffsets[i] = inRange - ? m_state.so.targets[i].offset - : 0u; - } - } - } - - void STDMETHODCALLTYPE D3D11DeviceContext::SetMarkerInt( LPCWSTR pLabel, INT Data) { diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index add4f82e8..691de8baa 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -206,20 +206,6 @@ namespace dxvk { ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs); - void STDMETHODCALLTYPE SOSetTargets( - UINT NumBuffers, - ID3D11Buffer* const* ppSOTargets, - const UINT* pOffsets); - - void STDMETHODCALLTYPE SOGetTargets( - UINT NumBuffers, - ID3D11Buffer** ppSOTargets); - - void STDMETHODCALLTYPE SOGetTargetsWithOffsets( - UINT NumBuffers, - ID3D11Buffer** ppSOTargets, - UINT* pOffsets); - void STDMETHODCALLTYPE SetMarkerInt( LPCWSTR pLabel, INT Data); diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index e209816bb..5783eb2de 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -1660,6 +1660,73 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::SOSetTargets( + UINT NumBuffers, + ID3D11Buffer* const* ppSOTargets, + const UINT* pOffsets) { + D3D10DeviceLock lock = LockContext(); + + for (uint32_t i = 0; i < NumBuffers; i++) { + D3D11Buffer* buffer = static_cast(ppSOTargets[i]); + UINT offset = pOffsets != nullptr ? pOffsets[i] : 0; + + m_state.so.targets[i].buffer = buffer; + m_state.so.targets[i].offset = offset; + } + + for (uint32_t i = NumBuffers; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) { + m_state.so.targets[i].buffer = nullptr; + m_state.so.targets[i].offset = 0; + } + + for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) { + BindXfbBuffer(i, + m_state.so.targets[i].buffer.ptr(), + m_state.so.targets[i].offset); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::SOGetTargets( + UINT NumBuffers, + ID3D11Buffer** ppSOTargets) { + D3D10DeviceLock lock = LockContext(); + + for (uint32_t i = 0; i < NumBuffers; i++) { + ppSOTargets[i] = i < m_state.so.targets.size() + ? m_state.so.targets[i].buffer.ref() + : nullptr; + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::SOGetTargetsWithOffsets( + UINT NumBuffers, + ID3D11Buffer** ppSOTargets, + UINT* pOffsets) { + D3D10DeviceLock lock = LockContext(); + + for (uint32_t i = 0; i < NumBuffers; i++) { + const bool inRange = i < m_state.so.targets.size(); + + if (ppSOTargets) { + ppSOTargets[i] = inRange + ? m_state.so.targets[i].buffer.ref() + : nullptr; + } + + if (pOffsets) { + pOffsets[i] = inRange + ? m_state.so.targets[i].offset + : 0u; + } + } + } + + template BOOL STDMETHODCALLTYPE D3D11CommonContext::IsAnnotationEnabled() { return m_annotation.GetStatus(); diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 4225e577c..6d7f6542e 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -525,6 +525,20 @@ namespace dxvk { UINT* pNumRects, D3D11_RECT* pRects); + void STDMETHODCALLTYPE SOSetTargets( + UINT NumBuffers, + ID3D11Buffer* const* ppSOTargets, + const UINT* pOffsets); + + void STDMETHODCALLTYPE SOGetTargets( + UINT NumBuffers, + ID3D11Buffer** ppSOTargets); + + void STDMETHODCALLTYPE SOGetTargetsWithOffsets( + UINT NumBuffers, + ID3D11Buffer** ppSOTargets, + UINT* pOffsets); + BOOL STDMETHODCALLTYPE IsAnnotationEnabled(); protected: From b8b5662461be171d62bf520bd4406340f086f53f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:35:12 +0200 Subject: [PATCH 0386/1348] [d3d11] Move Discard* methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 101 --------------------------- src/d3d11/d3d11_context.h | 16 ----- src/d3d11/d3d11_context_common.cpp | 106 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 16 +++++ 4 files changed, 122 insertions(+), 117 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 57304ef12..9eff8b6f0 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -30,80 +30,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::DiscardResource(ID3D11Resource* pResource) { - D3D10DeviceLock lock = LockContext(); - - if (!pResource) - return; - - // We don't support the Discard API for images - D3D11_RESOURCE_DIMENSION resType = D3D11_RESOURCE_DIMENSION_UNKNOWN; - pResource->GetType(&resType); - - if (resType == D3D11_RESOURCE_DIMENSION_BUFFER) { - DiscardBuffer(pResource); - } else { - auto texture = GetCommonTexture(pResource); - - for (uint32_t i = 0; i < texture->CountSubresources(); i++) - DiscardTexture(pResource, i); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DiscardView(ID3D11View* pResourceView) { - DiscardView1(pResourceView, nullptr, 0); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DiscardView1( - ID3D11View* pResourceView, - const D3D11_RECT* pRects, - UINT NumRects) { - D3D10DeviceLock lock = LockContext(); - - // We don't support discarding individual rectangles - if (!pResourceView || (NumRects && pRects)) - return; - - // ID3D11View has no methods to query the exact type of - // the view, so we'll have to check each possible class - auto dsv = dynamic_cast(pResourceView); - auto rtv = dynamic_cast(pResourceView); - auto uav = dynamic_cast(pResourceView); - - Rc view; - if (dsv) view = dsv->GetImageView(); - if (rtv) view = rtv->GetImageView(); - if (uav) view = uav->GetImageView(); - - if (view == nullptr) - return; - - // Get information about underlying resource - Com resource; - pResourceView->GetResource(&resource); - - uint32_t mipCount = GetCommonTexture(resource.ptr())->Desc()->MipLevels; - - // Discard mip levels one by one - VkImageSubresourceRange sr = view->subresources(); - - for (uint32_t layer = 0; layer < sr.layerCount; layer++) { - for (uint32_t mip = 0; mip < sr.levelCount; mip++) { - DiscardTexture(resource.ptr(), D3D11CalcSubresource( - sr.baseMipLevel + mip, sr.baseArrayLayer + layer, mipCount)); - } - } - - // Since we don't handle SRVs here, we can assume that the - // view covers all aspects of the underlying resource. - EmitCs([cView = view] (DxvkContext* ctx) { - ctx->discardImageView(cView, cView->formatInfo()->aspectMask); - }); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::SetPredication( ID3D11Predicate* pPredicate, BOOL PredicateValue) { @@ -2010,33 +1936,6 @@ namespace dxvk { } - void D3D11DeviceContext::DiscardBuffer( - ID3D11Resource* pResource) { - auto buffer = static_cast(pResource); - - if (buffer->GetMapMode() != D3D11_COMMON_BUFFER_MAP_MODE_NONE) { - D3D11_MAPPED_SUBRESOURCE sr; - - Map(pResource, 0, D3D11_MAP_WRITE_DISCARD, 0, &sr); - Unmap(pResource, 0); - } - } - - - void D3D11DeviceContext::DiscardTexture( - ID3D11Resource* pResource, - UINT Subresource) { - auto texture = GetCommonTexture(pResource); - - if (texture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) { - D3D11_MAPPED_SUBRESOURCE sr; - - Map(pResource, Subresource, D3D11_MAP_WRITE_DISCARD, 0, &sr); - Unmap(pResource, Subresource); - } - } - - void D3D11DeviceContext::UpdateBuffer( D3D11Buffer* pDstBuffer, UINT Offset, diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 691de8baa..5c53c26e4 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -34,15 +34,6 @@ namespace dxvk { DxvkCsChunkFlags CsFlags); ~D3D11DeviceContext(); - void STDMETHODCALLTYPE DiscardResource(ID3D11Resource *pResource); - - void STDMETHODCALLTYPE DiscardView(ID3D11View* pResourceView); - - void STDMETHODCALLTYPE DiscardView1( - ID3D11View* pResourceView, - const D3D11_RECT* pRects, - UINT NumRects); - void STDMETHODCALLTYPE SetPredication( ID3D11Predicate* pPredicate, BOOL PredicateValue); @@ -337,13 +328,6 @@ namespace dxvk { VkOffset3D SrcOffset, VkExtent3D SrcExtent); - void DiscardBuffer( - ID3D11Resource* pResource); - - void DiscardTexture( - ID3D11Resource* pResource, - UINT Subresource); - void UpdateBuffer( D3D11Buffer* pDstBuffer, UINT Offset, diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 5783eb2de..6581ee6fb 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -180,6 +180,83 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::DiscardResource(ID3D11Resource* pResource) { + D3D10DeviceLock lock = LockContext(); + + if (!pResource) + return; + + // We don't support the Discard API for images + D3D11_RESOURCE_DIMENSION resType = D3D11_RESOURCE_DIMENSION_UNKNOWN; + pResource->GetType(&resType); + + if (resType == D3D11_RESOURCE_DIMENSION_BUFFER) { + DiscardBuffer(pResource); + } else { + auto texture = GetCommonTexture(pResource); + + for (uint32_t i = 0; i < texture->CountSubresources(); i++) + DiscardTexture(pResource, i); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DiscardView(ID3D11View* pResourceView) { + DiscardView1(pResourceView, nullptr, 0); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DiscardView1( + ID3D11View* pResourceView, + const D3D11_RECT* pRects, + UINT NumRects) { + D3D10DeviceLock lock = LockContext(); + + // We don't support discarding individual rectangles + if (!pResourceView || (NumRects && pRects)) + return; + + // ID3D11View has no methods to query the exact type of + // the view, so we'll have to check each possible class + auto dsv = dynamic_cast(pResourceView); + auto rtv = dynamic_cast(pResourceView); + auto uav = dynamic_cast(pResourceView); + + Rc view; + if (dsv) view = dsv->GetImageView(); + if (rtv) view = rtv->GetImageView(); + if (uav) view = uav->GetImageView(); + + if (view == nullptr) + return; + + // Get information about underlying resource + Com resource; + pResourceView->GetResource(&resource); + + uint32_t mipCount = GetCommonTexture(resource.ptr())->Desc()->MipLevels; + + // Discard mip levels one by one + VkImageSubresourceRange sr = view->subresources(); + + for (uint32_t layer = 0; layer < sr.layerCount; layer++) { + for (uint32_t mip = 0; mip < sr.levelCount; mip++) { + DiscardTexture(resource.ptr(), D3D11CalcSubresource( + sr.baseMipLevel + mip, sr.baseArrayLayer + layer, mipCount)); + } + } + + // Since we don't handle SRVs here, we can assume that the + // view covers all aspects of the underlying resource. + EmitCs([cView = view] (DxvkContext* ctx) { + ctx->discardImageView(cView, cView->formatInfo()->aspectMask); + }); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::UpdateSubresource( ID3D11Resource* pDstResource, @@ -1999,6 +2076,35 @@ namespace dxvk { } + template + void D3D11CommonContext::DiscardBuffer( + ID3D11Resource* pResource) { + auto buffer = static_cast(pResource); + + if (buffer->GetMapMode() != D3D11_COMMON_BUFFER_MAP_MODE_NONE) { + D3D11_MAPPED_SUBRESOURCE sr; + + Map(pResource, 0, D3D11_MAP_WRITE_DISCARD, 0, &sr); + Unmap(pResource, 0); + } + } + + + template + void D3D11CommonContext::DiscardTexture( + ID3D11Resource* pResource, + UINT Subresource) { + auto texture = GetCommonTexture(pResource); + + if (texture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) { + D3D11_MAPPED_SUBRESOURCE sr; + + Map(pResource, Subresource, D3D11_MAP_WRITE_DISCARD, 0, &sr); + Unmap(pResource, Subresource); + } + } + + template void D3D11CommonContext::GetConstantBuffers( const D3D11ConstantBufferBindings& Bindings, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 6d7f6542e..934902d7b 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -70,6 +70,15 @@ namespace dxvk { void STDMETHODCALLTYPE ClearState(); + void STDMETHODCALLTYPE DiscardResource(ID3D11Resource *pResource); + + void STDMETHODCALLTYPE DiscardView(ID3D11View* pResourceView); + + void STDMETHODCALLTYPE DiscardView1( + ID3D11View* pResourceView, + const D3D11_RECT* pRects, + UINT NumRects); + void STDMETHODCALLTYPE UpdateSubresource( ID3D11Resource* pDstResource, UINT DstSubresource, @@ -602,6 +611,13 @@ namespace dxvk { UINT CtrSlot, UINT Counter); + void DiscardBuffer( + ID3D11Resource* pResource); + + void DiscardTexture( + ID3D11Resource* pResource, + UINT Subresource); + void GetConstantBuffers( const D3D11ConstantBufferBindings& Bindings, UINT StartSlot, From 163af1309deafc98a4b4f2f4c4f439d9c7eb2eeb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:37:07 +0200 Subject: [PATCH 0387/1348] [d3d11] Move SetPredication to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 29 ---------------------------- src/d3d11/d3d11_context.h | 8 -------- src/d3d11/d3d11_context_common.cpp | 31 ++++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 8 ++++++++ 4 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 9eff8b6f0..732af0ab0 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -30,35 +30,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::SetPredication( - ID3D11Predicate* pPredicate, - BOOL PredicateValue) { - D3D10DeviceLock lock = LockContext(); - - auto predicate = D3D11Query::FromPredicate(pPredicate); - m_state.pr.predicateObject = predicate; - m_state.pr.predicateValue = PredicateValue; - - static bool s_errorShown = false; - - if (pPredicate && !std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::SetPredication: Stub"); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::GetPredication( - ID3D11Predicate** ppPredicate, - BOOL* pPredicateValue) { - D3D10DeviceLock lock = LockContext(); - - if (ppPredicate) - *ppPredicate = D3D11Query::AsPredicate(m_state.pr.predicateObject.ref()); - - if (pPredicateValue) - *pPredicateValue = m_state.pr.predicateValue; - } - - void STDMETHODCALLTYPE D3D11DeviceContext::CopySubresourceRegion( ID3D11Resource* pDstResource, UINT DstSubresource, diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 5c53c26e4..31c635659 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -34,14 +34,6 @@ namespace dxvk { DxvkCsChunkFlags CsFlags); ~D3D11DeviceContext(); - void STDMETHODCALLTYPE SetPredication( - ID3D11Predicate* pPredicate, - BOOL PredicateValue); - - void STDMETHODCALLTYPE GetPredication( - ID3D11Predicate** ppPredicate, - BOOL* pPredicateValue); - void STDMETHODCALLTYPE CopySubresourceRegion( ID3D11Resource* pDstResource, UINT DstSubresource, diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 6581ee6fb..8bcb9643e 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -1804,6 +1804,37 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::SetPredication( + ID3D11Predicate* pPredicate, + BOOL PredicateValue) { + D3D10DeviceLock lock = LockContext(); + + auto predicate = D3D11Query::FromPredicate(pPredicate); + m_state.pr.predicateObject = predicate; + m_state.pr.predicateValue = PredicateValue; + + static bool s_errorShown = false; + + if (pPredicate && !std::exchange(s_errorShown, true)) + Logger::err("D3D11DeviceContext::SetPredication: Stub"); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::GetPredication( + ID3D11Predicate** ppPredicate, + BOOL* pPredicateValue) { + D3D10DeviceLock lock = LockContext(); + + if (ppPredicate) + *ppPredicate = D3D11Query::AsPredicate(m_state.pr.predicateObject.ref()); + + if (pPredicateValue) + *pPredicateValue = m_state.pr.predicateValue; + } + + template BOOL STDMETHODCALLTYPE D3D11CommonContext::IsAnnotationEnabled() { return m_annotation.GetStatus(); diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 934902d7b..cb63f86ce 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -548,6 +548,14 @@ namespace dxvk { ID3D11Buffer** ppSOTargets, UINT* pOffsets); + void STDMETHODCALLTYPE SetPredication( + ID3D11Predicate* pPredicate, + BOOL PredicateValue); + + void STDMETHODCALLTYPE GetPredication( + ID3D11Predicate** ppPredicate, + BOOL* pPredicateValue); + BOOL STDMETHODCALLTYPE IsAnnotationEnabled(); protected: From 50942cd2d9dcab9270851fe4eeb7e97dd838b1fd Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:42:57 +0200 Subject: [PATCH 0388/1348] [d3d11] Move Copy* methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 482 ---------------------------- src/d3d11/d3d11_context.h | 46 --- src/d3d11/d3d11_context_common.cpp | 488 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 46 +++ 4 files changed, 534 insertions(+), 528 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 732af0ab0..bdc8dd80b 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -30,197 +30,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::CopySubresourceRegion( - ID3D11Resource* pDstResource, - UINT DstSubresource, - UINT DstX, - UINT DstY, - UINT DstZ, - ID3D11Resource* pSrcResource, - UINT SrcSubresource, - const D3D11_BOX* pSrcBox) { - CopySubresourceRegion1( - pDstResource, DstSubresource, DstX, DstY, DstZ, - pSrcResource, SrcSubresource, pSrcBox, 0); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::CopySubresourceRegion1( - ID3D11Resource* pDstResource, - UINT DstSubresource, - UINT DstX, - UINT DstY, - UINT DstZ, - ID3D11Resource* pSrcResource, - UINT SrcSubresource, - const D3D11_BOX* pSrcBox, - UINT CopyFlags) { - D3D10DeviceLock lock = LockContext(); - - if (!pDstResource || !pSrcResource) - return; - - if (pSrcBox - && (pSrcBox->left >= pSrcBox->right - || pSrcBox->top >= pSrcBox->bottom - || pSrcBox->front >= pSrcBox->back)) - return; - - D3D11_RESOURCE_DIMENSION dstResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - D3D11_RESOURCE_DIMENSION srcResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - - pDstResource->GetType(&dstResourceDim); - pSrcResource->GetType(&srcResourceDim); - - if (dstResourceDim == D3D11_RESOURCE_DIMENSION_BUFFER && srcResourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { - auto dstBuffer = static_cast(pDstResource); - auto srcBuffer = static_cast(pSrcResource); - - VkDeviceSize dstOffset = DstX; - VkDeviceSize srcOffset = 0; - VkDeviceSize byteCount = -1; - - if (pSrcBox) { - srcOffset = pSrcBox->left; - byteCount = pSrcBox->right - pSrcBox->left; - } - - CopyBuffer(dstBuffer, dstOffset, srcBuffer, srcOffset, byteCount); - } else if (dstResourceDim != D3D11_RESOURCE_DIMENSION_BUFFER && srcResourceDim != D3D11_RESOURCE_DIMENSION_BUFFER) { - auto dstTexture = GetCommonTexture(pDstResource); - auto srcTexture = GetCommonTexture(pSrcResource); - - if (DstSubresource >= dstTexture->CountSubresources() - || SrcSubresource >= srcTexture->CountSubresources()) - return; - - auto dstFormatInfo = lookupFormatInfo(dstTexture->GetPackedFormat()); - auto srcFormatInfo = lookupFormatInfo(srcTexture->GetPackedFormat()); - - auto dstLayers = vk::makeSubresourceLayers(dstTexture->GetSubresourceFromIndex(dstFormatInfo->aspectMask, DstSubresource)); - auto srcLayers = vk::makeSubresourceLayers(srcTexture->GetSubresourceFromIndex(srcFormatInfo->aspectMask, SrcSubresource)); - - VkOffset3D srcOffset = { 0, 0, 0 }; - VkOffset3D dstOffset = { int32_t(DstX), int32_t(DstY), int32_t(DstZ) }; - - VkExtent3D srcExtent = srcTexture->MipLevelExtent(srcLayers.mipLevel); - - if (pSrcBox != nullptr) { - srcOffset.x = pSrcBox->left; - srcOffset.y = pSrcBox->top; - srcOffset.z = pSrcBox->front; - - srcExtent.width = pSrcBox->right - pSrcBox->left; - srcExtent.height = pSrcBox->bottom - pSrcBox->top; - srcExtent.depth = pSrcBox->back - pSrcBox->front; - } - - CopyImage( - dstTexture, &dstLayers, dstOffset, - srcTexture, &srcLayers, srcOffset, - srcExtent); - } else { - Logger::err(str::format( - "D3D11: CopySubresourceRegion1: Incompatible resources", - "\n Dst resource type: ", dstResourceDim, - "\n Src resource type: ", srcResourceDim)); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::CopyResource( - ID3D11Resource* pDstResource, - ID3D11Resource* pSrcResource) { - D3D10DeviceLock lock = LockContext(); - - if (!pDstResource || !pSrcResource || (pDstResource == pSrcResource)) - return; - - D3D11_RESOURCE_DIMENSION dstResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - D3D11_RESOURCE_DIMENSION srcResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - - pDstResource->GetType(&dstResourceDim); - pSrcResource->GetType(&srcResourceDim); - - if (dstResourceDim != srcResourceDim) { - Logger::err(str::format( - "D3D11: CopyResource: Incompatible resources", - "\n Dst resource type: ", dstResourceDim, - "\n Src resource type: ", srcResourceDim)); - return; - } - - if (dstResourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { - auto dstBuffer = static_cast(pDstResource); - auto srcBuffer = static_cast(pSrcResource); - - if (dstBuffer->Desc()->ByteWidth != srcBuffer->Desc()->ByteWidth) - return; - - CopyBuffer(dstBuffer, 0, srcBuffer, 0, -1); - } else { - auto dstTexture = GetCommonTexture(pDstResource); - auto srcTexture = GetCommonTexture(pSrcResource); - - auto dstDesc = dstTexture->Desc(); - auto srcDesc = srcTexture->Desc(); - - // The subresource count must match as well - if (dstDesc->ArraySize != srcDesc->ArraySize - || dstDesc->MipLevels != srcDesc->MipLevels) { - Logger::err("D3D11: CopyResource: Incompatible images"); - return; - } - - auto dstFormatInfo = lookupFormatInfo(dstTexture->GetPackedFormat()); - auto srcFormatInfo = lookupFormatInfo(srcTexture->GetPackedFormat()); - - for (uint32_t i = 0; i < dstDesc->MipLevels; i++) { - VkImageSubresourceLayers dstLayers = { dstFormatInfo->aspectMask, i, 0, dstDesc->ArraySize }; - VkImageSubresourceLayers srcLayers = { srcFormatInfo->aspectMask, i, 0, srcDesc->ArraySize }; - - CopyImage( - dstTexture, &dstLayers, VkOffset3D(), - srcTexture, &srcLayers, VkOffset3D(), - srcTexture->MipLevelExtent(i)); - } - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::CopyStructureCount( - ID3D11Buffer* pDstBuffer, - UINT DstAlignedByteOffset, - ID3D11UnorderedAccessView* pSrcView) { - D3D10DeviceLock lock = LockContext(); - - auto buf = static_cast(pDstBuffer); - auto uav = static_cast(pSrcView); - - if (!buf || !uav) - return; - - auto counterSlice = uav->GetCounterSlice(); - if (!counterSlice.defined()) - return; - - EmitCs([ - cDstSlice = buf->GetBufferSlice(DstAlignedByteOffset), - cSrcSlice = std::move(counterSlice) - ] (DxvkContext* ctx) { - ctx->copyBuffer( - cDstSlice.buffer(), - cDstSlice.offset(), - cSrcSlice.buffer(), - cSrcSlice.offset(), - sizeof(uint32_t)); - }); - - if (buf->HasSequenceNumber()) - TrackBufferSequenceNumber(buf); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::CopyTiles( ID3D11Resource* pTiledResource, const D3D11_TILED_RESOURCE_COORDINATE* pTileRegionStartCoordinate, @@ -1616,297 +1425,6 @@ namespace dxvk { } - void D3D11DeviceContext::CopyBuffer( - D3D11Buffer* pDstBuffer, - VkDeviceSize DstOffset, - D3D11Buffer* pSrcBuffer, - VkDeviceSize SrcOffset, - VkDeviceSize ByteCount) { - // Clamp copy region to prevent out-of-bounds access - VkDeviceSize dstLength = pDstBuffer->Desc()->ByteWidth; - VkDeviceSize srcLength = pSrcBuffer->Desc()->ByteWidth; - - if (SrcOffset >= srcLength || DstOffset >= dstLength || !ByteCount) - return; - - ByteCount = std::min(dstLength - DstOffset, ByteCount); - ByteCount = std::min(srcLength - SrcOffset, ByteCount); - - EmitCs([ - cDstBuffer = pDstBuffer->GetBufferSlice(DstOffset, ByteCount), - cSrcBuffer = pSrcBuffer->GetBufferSlice(SrcOffset, ByteCount) - ] (DxvkContext* ctx) { - if (cDstBuffer.buffer() != cSrcBuffer.buffer()) { - ctx->copyBuffer( - cDstBuffer.buffer(), - cDstBuffer.offset(), - cSrcBuffer.buffer(), - cSrcBuffer.offset(), - cSrcBuffer.length()); - } else { - ctx->copyBufferRegion( - cDstBuffer.buffer(), - cDstBuffer.offset(), - cSrcBuffer.offset(), - cSrcBuffer.length()); - } - }); - - if (pDstBuffer->HasSequenceNumber()) - TrackBufferSequenceNumber(pDstBuffer); - if (pSrcBuffer->HasSequenceNumber()) - TrackBufferSequenceNumber(pSrcBuffer); - } - - - void D3D11DeviceContext::CopyImage( - D3D11CommonTexture* pDstTexture, - const VkImageSubresourceLayers* pDstLayers, - VkOffset3D DstOffset, - D3D11CommonTexture* pSrcTexture, - const VkImageSubresourceLayers* pSrcLayers, - VkOffset3D SrcOffset, - VkExtent3D SrcExtent) { - // Image formats must be size-compatible - auto dstFormatInfo = lookupFormatInfo(pDstTexture->GetPackedFormat()); - auto srcFormatInfo = lookupFormatInfo(pSrcTexture->GetPackedFormat()); - - if (dstFormatInfo->elementSize != srcFormatInfo->elementSize) { - Logger::err("D3D11: CopyImage: Incompatible texel size"); - return; - } - - // Sample counts must match - if (pDstTexture->Desc()->SampleDesc.Count != pSrcTexture->Desc()->SampleDesc.Count) { - Logger::err("D3D11: CopyImage: Incompatible sample count"); - return; - } - - // Obviously, the copy region must not be empty - VkExtent3D dstMipExtent = pDstTexture->MipLevelExtent(pDstLayers->mipLevel); - VkExtent3D srcMipExtent = pSrcTexture->MipLevelExtent(pSrcLayers->mipLevel); - - if (uint32_t(DstOffset.x) >= dstMipExtent.width - || uint32_t(DstOffset.y) >= dstMipExtent.height - || uint32_t(DstOffset.z) >= dstMipExtent.depth) - return; - - if (uint32_t(SrcOffset.x) >= srcMipExtent.width - || uint32_t(SrcOffset.y) >= srcMipExtent.height - || uint32_t(SrcOffset.z) >= srcMipExtent.depth) - return; - - // Don't perform the copy if the offsets aren't block-aligned - if (!util::isBlockAligned(SrcOffset, srcFormatInfo->blockSize) - || !util::isBlockAligned(DstOffset, dstFormatInfo->blockSize)) { - Logger::err(str::format("D3D11: CopyImage: Unaligned block offset")); - return; - } - - // Clamp the image region in order to avoid out-of-bounds access - VkExtent3D blockCount = util::computeBlockCount(SrcExtent, srcFormatInfo->blockSize); - VkExtent3D dstBlockCount = util::computeMaxBlockCount(DstOffset, dstMipExtent, dstFormatInfo->blockSize); - VkExtent3D srcBlockCount = util::computeMaxBlockCount(SrcOffset, srcMipExtent, srcFormatInfo->blockSize); - - blockCount = util::minExtent3D(blockCount, dstBlockCount); - blockCount = util::minExtent3D(blockCount, srcBlockCount); - - SrcExtent = util::computeBlockExtent(blockCount, srcFormatInfo->blockSize); - SrcExtent = util::snapExtent3D(SrcOffset, SrcExtent, srcMipExtent); - - if (!SrcExtent.width || !SrcExtent.height || !SrcExtent.depth) - return; - - // While copying between 2D and 3D images is allowed in CopySubresourceRegion, - // copying more than one slice at a time is not suppoted. Layer counts are 1. - if ((pDstTexture->GetVkImageType() == VK_IMAGE_TYPE_3D) - != (pSrcTexture->GetVkImageType() == VK_IMAGE_TYPE_3D)) - SrcExtent.depth = 1; - - // Certain types of copies require us to pass the destination extent to - // the backend. This may be different when copying between compressed - // and uncompressed image formats. - VkExtent3D dstExtent = util::computeBlockExtent(blockCount, dstFormatInfo->blockSize); - dstExtent = util::snapExtent3D(DstOffset, dstExtent, dstMipExtent); - - // It is possible for any of the given images to be a staging image with - // no actual image, so we need to account for all possibilities here. - bool dstIsImage = pDstTexture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING; - bool srcIsImage = pSrcTexture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING; - - if (dstIsImage && srcIsImage) { - EmitCs([ - cDstImage = pDstTexture->GetImage(), - cSrcImage = pSrcTexture->GetImage(), - cDstLayers = *pDstLayers, - cSrcLayers = *pSrcLayers, - cDstOffset = DstOffset, - cSrcOffset = SrcOffset, - cExtent = SrcExtent - ] (DxvkContext* ctx) { - // CopyResource can only copy between different images, and - // CopySubresourceRegion can only copy data from one single - // subresource at a time, so this check is safe. - if (cDstImage != cSrcImage || cDstLayers != cSrcLayers) { - ctx->copyImage( - cDstImage, cDstLayers, cDstOffset, - cSrcImage, cSrcLayers, cSrcOffset, - cExtent); - } else { - ctx->copyImageRegion( - cDstImage, cDstLayers, cDstOffset, - cSrcOffset, cExtent); - } - }); - } else { - // Since each subresource uses a dedicated buffer, we are going - // to need one call per subresource for staging resource copies - for (uint32_t i = 0; i < pDstLayers->layerCount; i++) { - uint32_t dstSubresource = D3D11CalcSubresource(pDstLayers->mipLevel, pDstLayers->baseArrayLayer + i, pDstTexture->Desc()->MipLevels); - uint32_t srcSubresource = D3D11CalcSubresource(pSrcLayers->mipLevel, pSrcLayers->baseArrayLayer + i, pSrcTexture->Desc()->MipLevels); - - // For multi-plane image data stored in a buffer, the backend - // assumes that the second plane immediately follows the first - // plane in memory, which is only true if we copy the full image. - uint32_t planeCount = 1; - - if (dstFormatInfo->flags.test(DxvkFormatFlag::MultiPlane)) { - bool needsSeparateCopies = !dstIsImage && !srcIsImage; - - if (!dstIsImage) - needsSeparateCopies |= pDstTexture->MipLevelExtent(pDstLayers->mipLevel) != SrcExtent; - if (!srcIsImage) - needsSeparateCopies |= pSrcTexture->MipLevelExtent(pSrcLayers->mipLevel) != SrcExtent; - - if (needsSeparateCopies) - planeCount = vk::getPlaneCount(srcFormatInfo->aspectMask); - } - - for (uint32_t j = 0; j < planeCount; j++) { - VkImageAspectFlags dstAspectMask = dstFormatInfo->aspectMask; - VkImageAspectFlags srcAspectMask = srcFormatInfo->aspectMask; - - if (planeCount > 1) { - dstAspectMask = vk::getPlaneAspect(j); - srcAspectMask = dstAspectMask; - } - - if (dstIsImage) { - VkImageSubresourceLayers dstLayer = { dstAspectMask, - pDstLayers->mipLevel, pDstLayers->baseArrayLayer + i, 1 }; - - EmitCs([ - cDstImage = pDstTexture->GetImage(), - cDstLayers = dstLayer, - cDstOffset = DstOffset, - cDstExtent = dstExtent, - cSrcBuffer = pSrcTexture->GetMappedBuffer(srcSubresource), - cSrcLayout = pSrcTexture->GetSubresourceLayout(srcAspectMask, srcSubresource), - cSrcOffset = pSrcTexture->ComputeMappedOffset(srcSubresource, j, SrcOffset), - cSrcCoord = SrcOffset, - cSrcExtent = srcMipExtent, - cSrcFormat = pSrcTexture->GetPackedFormat() - ] (DxvkContext* ctx) { - if (cDstLayers.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { - ctx->copyBufferToImage(cDstImage, cDstLayers, cDstOffset, cDstExtent, - cSrcBuffer, cSrcOffset, cSrcLayout.RowPitch, cSrcLayout.DepthPitch); - } else { - ctx->copyPackedBufferToDepthStencilImage(cDstImage, cDstLayers, - VkOffset2D { cDstOffset.x, cDstOffset.y }, - VkExtent2D { cDstExtent.width, cDstExtent.height }, - cSrcBuffer, cSrcLayout.Offset, - VkOffset2D { cSrcCoord.x, cSrcCoord.y }, - VkExtent2D { cSrcExtent.width, cSrcExtent.height }, - cSrcFormat); - } - }); - } else if (srcIsImage) { - VkImageSubresourceLayers srcLayer = { srcAspectMask, - pSrcLayers->mipLevel, pSrcLayers->baseArrayLayer + i, 1 }; - - EmitCs([ - cSrcImage = pSrcTexture->GetImage(), - cSrcLayers = srcLayer, - cSrcOffset = SrcOffset, - cSrcExtent = SrcExtent, - cDstBuffer = pDstTexture->GetMappedBuffer(dstSubresource), - cDstLayout = pDstTexture->GetSubresourceLayout(dstAspectMask, dstSubresource), - cDstOffset = pDstTexture->ComputeMappedOffset(dstSubresource, j, DstOffset), - cDstCoord = DstOffset, - cDstExtent = dstMipExtent, - cDstFormat = pDstTexture->GetPackedFormat() - ] (DxvkContext* ctx) { - if (cSrcLayers.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { - ctx->copyImageToBuffer(cDstBuffer, cDstOffset, cDstLayout.RowPitch, - cDstLayout.DepthPitch, cSrcImage, cSrcLayers, cSrcOffset, cSrcExtent); - } else { - ctx->copyDepthStencilImageToPackedBuffer(cDstBuffer, cDstLayout.Offset, - VkOffset2D { cDstCoord.x, cDstCoord.y }, - VkExtent2D { cDstExtent.width, cDstExtent.height }, - cSrcImage, cSrcLayers, - VkOffset2D { cSrcOffset.x, cSrcOffset.y }, - VkExtent2D { cSrcExtent.width, cSrcExtent.height }, - cDstFormat); - } - }); - } else { - // The backend is not aware of image metadata in this case, - // so we need to handle image planes and block sizes here - VkDeviceSize elementSize = dstFormatInfo->elementSize; - VkExtent3D dstBlockSize = dstFormatInfo->blockSize; - VkExtent3D srcBlockSize = srcFormatInfo->blockSize; - VkExtent3D planeBlockSize = { 1u, 1u, 1u }; - - if (planeCount > 1) { - auto plane = &dstFormatInfo->planes[j]; - dstBlockSize.width *= plane->blockSize.width; - dstBlockSize.height *= plane->blockSize.height; - srcBlockSize.width *= plane->blockSize.width; - srcBlockSize.height *= plane->blockSize.height; - - planeBlockSize.width = plane->blockSize.width; - planeBlockSize.height = plane->blockSize.height; - elementSize = plane->elementSize; - } - - EmitCs([ - cPixelSize = elementSize, - cSrcBuffer = pSrcTexture->GetMappedBuffer(srcSubresource), - cSrcStart = pSrcTexture->GetSubresourceLayout(srcAspectMask, srcSubresource).Offset, - cSrcOffset = util::computeBlockOffset(SrcOffset, srcBlockSize), - cSrcSize = util::computeBlockCount(srcMipExtent, srcBlockSize), - cDstBuffer = pDstTexture->GetMappedBuffer(dstSubresource), - cDstStart = pDstTexture->GetSubresourceLayout(dstAspectMask, dstSubresource).Offset, - cDstOffset = util::computeBlockOffset(DstOffset, dstBlockSize), - cDstSize = util::computeBlockCount(dstMipExtent, dstBlockSize), - cExtent = util::computeBlockCount(blockCount, planeBlockSize) - ] (DxvkContext* ctx) { - ctx->copyPackedBufferImage( - cDstBuffer, cDstStart, cDstOffset, cDstSize, - cSrcBuffer, cSrcStart, cSrcOffset, cSrcSize, - cExtent, cPixelSize); - }); - } - } - } - } - - if (pDstTexture->HasSequenceNumber()) { - for (uint32_t i = 0; i < pDstLayers->layerCount; i++) { - TrackTextureSequenceNumber(pDstTexture, D3D11CalcSubresource( - pDstLayers->mipLevel, pDstLayers->baseArrayLayer + i, pDstTexture->Desc()->MipLevels)); - } - } - - if (pSrcTexture->HasSequenceNumber()) { - for (uint32_t i = 0; i < pSrcLayers->layerCount; i++) { - TrackTextureSequenceNumber(pSrcTexture, D3D11CalcSubresource( - pSrcLayers->mipLevel, pSrcLayers->baseArrayLayer + i, pSrcTexture->Desc()->MipLevels)); - } - } - } - - void D3D11DeviceContext::UpdateBuffer( D3D11Buffer* pDstBuffer, UINT Offset, diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 31c635659..bacba522a 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -34,36 +34,6 @@ namespace dxvk { DxvkCsChunkFlags CsFlags); ~D3D11DeviceContext(); - void STDMETHODCALLTYPE CopySubresourceRegion( - ID3D11Resource* pDstResource, - UINT DstSubresource, - UINT DstX, - UINT DstY, - UINT DstZ, - ID3D11Resource* pSrcResource, - UINT SrcSubresource, - const D3D11_BOX* pSrcBox); - - void STDMETHODCALLTYPE CopySubresourceRegion1( - ID3D11Resource* pDstResource, - UINT DstSubresource, - UINT DstX, - UINT DstY, - UINT DstZ, - ID3D11Resource* pSrcResource, - UINT SrcSubresource, - const D3D11_BOX* pSrcBox, - UINT CopyFlags); - - void STDMETHODCALLTYPE CopyResource( - ID3D11Resource* pDstResource, - ID3D11Resource* pSrcResource); - - void STDMETHODCALLTYPE CopyStructureCount( - ID3D11Buffer* pDstBuffer, - UINT DstAlignedByteOffset, - ID3D11UnorderedAccessView* pSrcView); - void STDMETHODCALLTYPE CopyTiles( ID3D11Resource* pTiledResource, const D3D11_TILED_RESOURCE_COORDINATE* pTileRegionStartCoordinate, @@ -304,22 +274,6 @@ namespace dxvk { UINT CtrSlot, UINT Counter); - void CopyBuffer( - D3D11Buffer* pDstBuffer, - VkDeviceSize DstOffset, - D3D11Buffer* pSrcBuffer, - VkDeviceSize SrcOffset, - VkDeviceSize ByteCount); - - void CopyImage( - D3D11CommonTexture* pDstTexture, - const VkImageSubresourceLayers* pDstLayers, - VkOffset3D DstOffset, - D3D11CommonTexture* pSrcTexture, - const VkImageSubresourceLayers* pSrcLayers, - VkOffset3D SrcOffset, - VkExtent3D SrcExtent); - void UpdateBuffer( D3D11Buffer* pDstBuffer, UINT Offset, diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 8bcb9643e..5835f11c7 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -257,6 +257,201 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::CopySubresourceRegion( + ID3D11Resource* pDstResource, + UINT DstSubresource, + UINT DstX, + UINT DstY, + UINT DstZ, + ID3D11Resource* pSrcResource, + UINT SrcSubresource, + const D3D11_BOX* pSrcBox) { + CopySubresourceRegion1( + pDstResource, DstSubresource, DstX, DstY, DstZ, + pSrcResource, SrcSubresource, pSrcBox, 0); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::CopySubresourceRegion1( + ID3D11Resource* pDstResource, + UINT DstSubresource, + UINT DstX, + UINT DstY, + UINT DstZ, + ID3D11Resource* pSrcResource, + UINT SrcSubresource, + const D3D11_BOX* pSrcBox, + UINT CopyFlags) { + D3D10DeviceLock lock = LockContext(); + + if (!pDstResource || !pSrcResource) + return; + + if (pSrcBox + && (pSrcBox->left >= pSrcBox->right + || pSrcBox->top >= pSrcBox->bottom + || pSrcBox->front >= pSrcBox->back)) + return; + + D3D11_RESOURCE_DIMENSION dstResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + D3D11_RESOURCE_DIMENSION srcResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + + pDstResource->GetType(&dstResourceDim); + pSrcResource->GetType(&srcResourceDim); + + if (dstResourceDim == D3D11_RESOURCE_DIMENSION_BUFFER && srcResourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { + auto dstBuffer = static_cast(pDstResource); + auto srcBuffer = static_cast(pSrcResource); + + VkDeviceSize dstOffset = DstX; + VkDeviceSize srcOffset = 0; + VkDeviceSize byteCount = -1; + + if (pSrcBox) { + srcOffset = pSrcBox->left; + byteCount = pSrcBox->right - pSrcBox->left; + } + + CopyBuffer(dstBuffer, dstOffset, srcBuffer, srcOffset, byteCount); + } else if (dstResourceDim != D3D11_RESOURCE_DIMENSION_BUFFER && srcResourceDim != D3D11_RESOURCE_DIMENSION_BUFFER) { + auto dstTexture = GetCommonTexture(pDstResource); + auto srcTexture = GetCommonTexture(pSrcResource); + + if (DstSubresource >= dstTexture->CountSubresources() + || SrcSubresource >= srcTexture->CountSubresources()) + return; + + auto dstFormatInfo = lookupFormatInfo(dstTexture->GetPackedFormat()); + auto srcFormatInfo = lookupFormatInfo(srcTexture->GetPackedFormat()); + + auto dstLayers = vk::makeSubresourceLayers(dstTexture->GetSubresourceFromIndex(dstFormatInfo->aspectMask, DstSubresource)); + auto srcLayers = vk::makeSubresourceLayers(srcTexture->GetSubresourceFromIndex(srcFormatInfo->aspectMask, SrcSubresource)); + + VkOffset3D srcOffset = { 0, 0, 0 }; + VkOffset3D dstOffset = { int32_t(DstX), int32_t(DstY), int32_t(DstZ) }; + + VkExtent3D srcExtent = srcTexture->MipLevelExtent(srcLayers.mipLevel); + + if (pSrcBox) { + srcOffset.x = pSrcBox->left; + srcOffset.y = pSrcBox->top; + srcOffset.z = pSrcBox->front; + + srcExtent.width = pSrcBox->right - pSrcBox->left; + srcExtent.height = pSrcBox->bottom - pSrcBox->top; + srcExtent.depth = pSrcBox->back - pSrcBox->front; + } + + CopyImage( + dstTexture, &dstLayers, dstOffset, + srcTexture, &srcLayers, srcOffset, + srcExtent); + } else { + Logger::err(str::format( + "D3D11: CopySubresourceRegion1: Incompatible resources", + "\n Dst resource type: ", dstResourceDim, + "\n Src resource type: ", srcResourceDim)); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::CopyResource( + ID3D11Resource* pDstResource, + ID3D11Resource* pSrcResource) { + D3D10DeviceLock lock = LockContext(); + + if (!pDstResource || !pSrcResource || (pDstResource == pSrcResource)) + return; + + D3D11_RESOURCE_DIMENSION dstResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + D3D11_RESOURCE_DIMENSION srcResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + + pDstResource->GetType(&dstResourceDim); + pSrcResource->GetType(&srcResourceDim); + + if (dstResourceDim != srcResourceDim) { + Logger::err(str::format( + "D3D11: CopyResource: Incompatible resources", + "\n Dst resource type: ", dstResourceDim, + "\n Src resource type: ", srcResourceDim)); + return; + } + + if (dstResourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { + auto dstBuffer = static_cast(pDstResource); + auto srcBuffer = static_cast(pSrcResource); + + if (dstBuffer->Desc()->ByteWidth != srcBuffer->Desc()->ByteWidth) + return; + + CopyBuffer(dstBuffer, 0, srcBuffer, 0, -1); + } else { + auto dstTexture = GetCommonTexture(pDstResource); + auto srcTexture = GetCommonTexture(pSrcResource); + + auto dstDesc = dstTexture->Desc(); + auto srcDesc = srcTexture->Desc(); + + // The subresource count must match as well + if (dstDesc->ArraySize != srcDesc->ArraySize + || dstDesc->MipLevels != srcDesc->MipLevels) { + Logger::err("D3D11: CopyResource: Incompatible images"); + return; + } + + auto dstFormatInfo = lookupFormatInfo(dstTexture->GetPackedFormat()); + auto srcFormatInfo = lookupFormatInfo(srcTexture->GetPackedFormat()); + + for (uint32_t i = 0; i < dstDesc->MipLevels; i++) { + VkImageSubresourceLayers dstLayers = { dstFormatInfo->aspectMask, i, 0, dstDesc->ArraySize }; + VkImageSubresourceLayers srcLayers = { srcFormatInfo->aspectMask, i, 0, srcDesc->ArraySize }; + + CopyImage( + dstTexture, &dstLayers, VkOffset3D(), + srcTexture, &srcLayers, VkOffset3D(), + srcTexture->MipLevelExtent(i)); + } + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::CopyStructureCount( + ID3D11Buffer* pDstBuffer, + UINT DstAlignedByteOffset, + ID3D11UnorderedAccessView* pSrcView) { + D3D10DeviceLock lock = LockContext(); + + auto buf = static_cast(pDstBuffer); + auto uav = static_cast(pSrcView); + + if (!buf || !uav) + return; + + auto counterSlice = uav->GetCounterSlice(); + if (!counterSlice.defined()) + return; + + EmitCs([ + cDstSlice = buf->GetBufferSlice(DstAlignedByteOffset), + cSrcSlice = std::move(counterSlice) + ] (DxvkContext* ctx) { + ctx->copyBuffer( + cDstSlice.buffer(), + cDstSlice.offset(), + cSrcSlice.buffer(), + cSrcSlice.offset(), + sizeof(uint32_t)); + }); + + if (buf->HasSequenceNumber()) + TrackBufferSequenceNumber(buf); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::UpdateSubresource( ID3D11Resource* pDstResource, @@ -2107,6 +2302,299 @@ namespace dxvk { } + template + void D3D11CommonContext::CopyBuffer( + D3D11Buffer* pDstBuffer, + VkDeviceSize DstOffset, + D3D11Buffer* pSrcBuffer, + VkDeviceSize SrcOffset, + VkDeviceSize ByteCount) { + // Clamp copy region to prevent out-of-bounds access + VkDeviceSize dstLength = pDstBuffer->Desc()->ByteWidth; + VkDeviceSize srcLength = pSrcBuffer->Desc()->ByteWidth; + + if (SrcOffset >= srcLength || DstOffset >= dstLength || !ByteCount) + return; + + ByteCount = std::min(dstLength - DstOffset, ByteCount); + ByteCount = std::min(srcLength - SrcOffset, ByteCount); + + EmitCs([ + cDstBuffer = pDstBuffer->GetBufferSlice(DstOffset, ByteCount), + cSrcBuffer = pSrcBuffer->GetBufferSlice(SrcOffset, ByteCount) + ] (DxvkContext* ctx) { + if (cDstBuffer.buffer() != cSrcBuffer.buffer()) { + ctx->copyBuffer( + cDstBuffer.buffer(), + cDstBuffer.offset(), + cSrcBuffer.buffer(), + cSrcBuffer.offset(), + cSrcBuffer.length()); + } else { + ctx->copyBufferRegion( + cDstBuffer.buffer(), + cDstBuffer.offset(), + cSrcBuffer.offset(), + cSrcBuffer.length()); + } + }); + + if (pDstBuffer->HasSequenceNumber()) + TrackBufferSequenceNumber(pDstBuffer); + if (pSrcBuffer->HasSequenceNumber()) + TrackBufferSequenceNumber(pSrcBuffer); + } + + + template + void D3D11CommonContext::CopyImage( + D3D11CommonTexture* pDstTexture, + const VkImageSubresourceLayers* pDstLayers, + VkOffset3D DstOffset, + D3D11CommonTexture* pSrcTexture, + const VkImageSubresourceLayers* pSrcLayers, + VkOffset3D SrcOffset, + VkExtent3D SrcExtent) { + // Image formats must be size-compatible + auto dstFormatInfo = lookupFormatInfo(pDstTexture->GetPackedFormat()); + auto srcFormatInfo = lookupFormatInfo(pSrcTexture->GetPackedFormat()); + + if (dstFormatInfo->elementSize != srcFormatInfo->elementSize) { + Logger::err("D3D11: CopyImage: Incompatible texel size"); + return; + } + + // Sample counts must match + if (pDstTexture->Desc()->SampleDesc.Count != pSrcTexture->Desc()->SampleDesc.Count) { + Logger::err("D3D11: CopyImage: Incompatible sample count"); + return; + } + + // Obviously, the copy region must not be empty + VkExtent3D dstMipExtent = pDstTexture->MipLevelExtent(pDstLayers->mipLevel); + VkExtent3D srcMipExtent = pSrcTexture->MipLevelExtent(pSrcLayers->mipLevel); + + if (uint32_t(DstOffset.x) >= dstMipExtent.width + || uint32_t(DstOffset.y) >= dstMipExtent.height + || uint32_t(DstOffset.z) >= dstMipExtent.depth) + return; + + if (uint32_t(SrcOffset.x) >= srcMipExtent.width + || uint32_t(SrcOffset.y) >= srcMipExtent.height + || uint32_t(SrcOffset.z) >= srcMipExtent.depth) + return; + + // Don't perform the copy if the offsets aren't block-aligned + if (!util::isBlockAligned(SrcOffset, srcFormatInfo->blockSize) + || !util::isBlockAligned(DstOffset, dstFormatInfo->blockSize)) { + Logger::err(str::format("D3D11: CopyImage: Unaligned block offset")); + return; + } + + // Clamp the image region in order to avoid out-of-bounds access + VkExtent3D blockCount = util::computeBlockCount(SrcExtent, srcFormatInfo->blockSize); + VkExtent3D dstBlockCount = util::computeMaxBlockCount(DstOffset, dstMipExtent, dstFormatInfo->blockSize); + VkExtent3D srcBlockCount = util::computeMaxBlockCount(SrcOffset, srcMipExtent, srcFormatInfo->blockSize); + + blockCount = util::minExtent3D(blockCount, dstBlockCount); + blockCount = util::minExtent3D(blockCount, srcBlockCount); + + SrcExtent = util::computeBlockExtent(blockCount, srcFormatInfo->blockSize); + SrcExtent = util::snapExtent3D(SrcOffset, SrcExtent, srcMipExtent); + + if (!SrcExtent.width || !SrcExtent.height || !SrcExtent.depth) + return; + + // While copying between 2D and 3D images is allowed in CopySubresourceRegion, + // copying more than one slice at a time is not suppoted. Layer counts are 1. + if ((pDstTexture->GetVkImageType() == VK_IMAGE_TYPE_3D) + != (pSrcTexture->GetVkImageType() == VK_IMAGE_TYPE_3D)) + SrcExtent.depth = 1; + + // Certain types of copies require us to pass the destination extent to + // the backend. This may be different when copying between compressed + // and uncompressed image formats. + VkExtent3D dstExtent = util::computeBlockExtent(blockCount, dstFormatInfo->blockSize); + dstExtent = util::snapExtent3D(DstOffset, dstExtent, dstMipExtent); + + // It is possible for any of the given images to be a staging image with + // no actual image, so we need to account for all possibilities here. + bool dstIsImage = pDstTexture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING; + bool srcIsImage = pSrcTexture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING; + + if (dstIsImage && srcIsImage) { + EmitCs([ + cDstImage = pDstTexture->GetImage(), + cSrcImage = pSrcTexture->GetImage(), + cDstLayers = *pDstLayers, + cSrcLayers = *pSrcLayers, + cDstOffset = DstOffset, + cSrcOffset = SrcOffset, + cExtent = SrcExtent + ] (DxvkContext* ctx) { + // CopyResource can only copy between different images, and + // CopySubresourceRegion can only copy data from one single + // subresource at a time, so this check is safe. + if (cDstImage != cSrcImage || cDstLayers != cSrcLayers) { + ctx->copyImage( + cDstImage, cDstLayers, cDstOffset, + cSrcImage, cSrcLayers, cSrcOffset, + cExtent); + } else { + ctx->copyImageRegion( + cDstImage, cDstLayers, cDstOffset, + cSrcOffset, cExtent); + } + }); + } else { + // Since each subresource uses a dedicated buffer, we are going + // to need one call per subresource for staging resource copies + for (uint32_t i = 0; i < pDstLayers->layerCount; i++) { + uint32_t dstSubresource = D3D11CalcSubresource(pDstLayers->mipLevel, pDstLayers->baseArrayLayer + i, pDstTexture->Desc()->MipLevels); + uint32_t srcSubresource = D3D11CalcSubresource(pSrcLayers->mipLevel, pSrcLayers->baseArrayLayer + i, pSrcTexture->Desc()->MipLevels); + + // For multi-plane image data stored in a buffer, the backend + // assumes that the second plane immediately follows the first + // plane in memory, which is only true if we copy the full image. + uint32_t planeCount = 1; + + if (dstFormatInfo->flags.test(DxvkFormatFlag::MultiPlane)) { + bool needsSeparateCopies = !dstIsImage && !srcIsImage; + + if (!dstIsImage) + needsSeparateCopies |= pDstTexture->MipLevelExtent(pDstLayers->mipLevel) != SrcExtent; + if (!srcIsImage) + needsSeparateCopies |= pSrcTexture->MipLevelExtent(pSrcLayers->mipLevel) != SrcExtent; + + if (needsSeparateCopies) + planeCount = vk::getPlaneCount(srcFormatInfo->aspectMask); + } + + for (uint32_t j = 0; j < planeCount; j++) { + VkImageAspectFlags dstAspectMask = dstFormatInfo->aspectMask; + VkImageAspectFlags srcAspectMask = srcFormatInfo->aspectMask; + + if (planeCount > 1) { + dstAspectMask = vk::getPlaneAspect(j); + srcAspectMask = dstAspectMask; + } + + if (dstIsImage) { + VkImageSubresourceLayers dstLayer = { dstAspectMask, + pDstLayers->mipLevel, pDstLayers->baseArrayLayer + i, 1 }; + + EmitCs([ + cDstImage = pDstTexture->GetImage(), + cDstLayers = dstLayer, + cDstOffset = DstOffset, + cDstExtent = dstExtent, + cSrcBuffer = pSrcTexture->GetMappedBuffer(srcSubresource), + cSrcLayout = pSrcTexture->GetSubresourceLayout(srcAspectMask, srcSubresource), + cSrcOffset = pSrcTexture->ComputeMappedOffset(srcSubresource, j, SrcOffset), + cSrcCoord = SrcOffset, + cSrcExtent = srcMipExtent, + cSrcFormat = pSrcTexture->GetPackedFormat() + ] (DxvkContext* ctx) { + if (cDstLayers.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + ctx->copyBufferToImage(cDstImage, cDstLayers, cDstOffset, cDstExtent, + cSrcBuffer, cSrcOffset, cSrcLayout.RowPitch, cSrcLayout.DepthPitch); + } else { + ctx->copyPackedBufferToDepthStencilImage(cDstImage, cDstLayers, + VkOffset2D { cDstOffset.x, cDstOffset.y }, + VkExtent2D { cDstExtent.width, cDstExtent.height }, + cSrcBuffer, cSrcLayout.Offset, + VkOffset2D { cSrcCoord.x, cSrcCoord.y }, + VkExtent2D { cSrcExtent.width, cSrcExtent.height }, + cSrcFormat); + } + }); + } else if (srcIsImage) { + VkImageSubresourceLayers srcLayer = { srcAspectMask, + pSrcLayers->mipLevel, pSrcLayers->baseArrayLayer + i, 1 }; + + EmitCs([ + cSrcImage = pSrcTexture->GetImage(), + cSrcLayers = srcLayer, + cSrcOffset = SrcOffset, + cSrcExtent = SrcExtent, + cDstBuffer = pDstTexture->GetMappedBuffer(dstSubresource), + cDstLayout = pDstTexture->GetSubresourceLayout(dstAspectMask, dstSubresource), + cDstOffset = pDstTexture->ComputeMappedOffset(dstSubresource, j, DstOffset), + cDstCoord = DstOffset, + cDstExtent = dstMipExtent, + cDstFormat = pDstTexture->GetPackedFormat() + ] (DxvkContext* ctx) { + if (cSrcLayers.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + ctx->copyImageToBuffer(cDstBuffer, cDstOffset, cDstLayout.RowPitch, + cDstLayout.DepthPitch, cSrcImage, cSrcLayers, cSrcOffset, cSrcExtent); + } else { + ctx->copyDepthStencilImageToPackedBuffer(cDstBuffer, cDstLayout.Offset, + VkOffset2D { cDstCoord.x, cDstCoord.y }, + VkExtent2D { cDstExtent.width, cDstExtent.height }, + cSrcImage, cSrcLayers, + VkOffset2D { cSrcOffset.x, cSrcOffset.y }, + VkExtent2D { cSrcExtent.width, cSrcExtent.height }, + cDstFormat); + } + }); + } else { + // The backend is not aware of image metadata in this case, + // so we need to handle image planes and block sizes here + VkDeviceSize elementSize = dstFormatInfo->elementSize; + VkExtent3D dstBlockSize = dstFormatInfo->blockSize; + VkExtent3D srcBlockSize = srcFormatInfo->blockSize; + VkExtent3D planeBlockSize = { 1u, 1u, 1u }; + + if (planeCount > 1) { + auto plane = &dstFormatInfo->planes[j]; + dstBlockSize.width *= plane->blockSize.width; + dstBlockSize.height *= plane->blockSize.height; + srcBlockSize.width *= plane->blockSize.width; + srcBlockSize.height *= plane->blockSize.height; + + planeBlockSize.width = plane->blockSize.width; + planeBlockSize.height = plane->blockSize.height; + elementSize = plane->elementSize; + } + + EmitCs([ + cPixelSize = elementSize, + cSrcBuffer = pSrcTexture->GetMappedBuffer(srcSubresource), + cSrcStart = pSrcTexture->GetSubresourceLayout(srcAspectMask, srcSubresource).Offset, + cSrcOffset = util::computeBlockOffset(SrcOffset, srcBlockSize), + cSrcSize = util::computeBlockCount(srcMipExtent, srcBlockSize), + cDstBuffer = pDstTexture->GetMappedBuffer(dstSubresource), + cDstStart = pDstTexture->GetSubresourceLayout(dstAspectMask, dstSubresource).Offset, + cDstOffset = util::computeBlockOffset(DstOffset, dstBlockSize), + cDstSize = util::computeBlockCount(dstMipExtent, dstBlockSize), + cExtent = util::computeBlockCount(blockCount, planeBlockSize) + ] (DxvkContext* ctx) { + ctx->copyPackedBufferImage( + cDstBuffer, cDstStart, cDstOffset, cDstSize, + cSrcBuffer, cSrcStart, cSrcOffset, cSrcSize, + cExtent, cPixelSize); + }); + } + } + } + } + + if (pDstTexture->HasSequenceNumber()) { + for (uint32_t i = 0; i < pDstLayers->layerCount; i++) { + TrackTextureSequenceNumber(pDstTexture, D3D11CalcSubresource( + pDstLayers->mipLevel, pDstLayers->baseArrayLayer + i, pDstTexture->Desc()->MipLevels)); + } + } + + if (pSrcTexture->HasSequenceNumber()) { + for (uint32_t i = 0; i < pSrcLayers->layerCount; i++) { + TrackTextureSequenceNumber(pSrcTexture, D3D11CalcSubresource( + pSrcLayers->mipLevel, pSrcLayers->baseArrayLayer + i, pSrcTexture->Desc()->MipLevels)); + } + } + } + + template void D3D11CommonContext::DiscardBuffer( ID3D11Resource* pResource) { diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index cb63f86ce..1a5919ff9 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -79,6 +79,36 @@ namespace dxvk { const D3D11_RECT* pRects, UINT NumRects); + void STDMETHODCALLTYPE CopySubresourceRegion( + ID3D11Resource* pDstResource, + UINT DstSubresource, + UINT DstX, + UINT DstY, + UINT DstZ, + ID3D11Resource* pSrcResource, + UINT SrcSubresource, + const D3D11_BOX* pSrcBox); + + void STDMETHODCALLTYPE CopySubresourceRegion1( + ID3D11Resource* pDstResource, + UINT DstSubresource, + UINT DstX, + UINT DstY, + UINT DstZ, + ID3D11Resource* pSrcResource, + UINT SrcSubresource, + const D3D11_BOX* pSrcBox, + UINT CopyFlags); + + void STDMETHODCALLTYPE CopyResource( + ID3D11Resource* pDstResource, + ID3D11Resource* pSrcResource); + + void STDMETHODCALLTYPE CopyStructureCount( + ID3D11Buffer* pDstBuffer, + UINT DstAlignedByteOffset, + ID3D11UnorderedAccessView* pSrcView); + void STDMETHODCALLTYPE UpdateSubresource( ID3D11Resource* pDstResource, UINT DstSubresource, @@ -619,6 +649,22 @@ namespace dxvk { UINT CtrSlot, UINT Counter); + void CopyBuffer( + D3D11Buffer* pDstBuffer, + VkDeviceSize DstOffset, + D3D11Buffer* pSrcBuffer, + VkDeviceSize SrcOffset, + VkDeviceSize ByteCount); + + void CopyImage( + D3D11CommonTexture* pDstTexture, + const VkImageSubresourceLayers* pDstLayers, + VkOffset3D DstOffset, + D3D11CommonTexture* pSrcTexture, + const VkImageSubresourceLayers* pSrcLayers, + VkOffset3D SrcOffset, + VkExtent3D SrcExtent); + void DiscardBuffer( ID3D11Resource* pResource); From 751d7467df898dc07631b8e1008b111c249b54c1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:47:31 +0200 Subject: [PATCH 0389/1348] [d3d11] Move Clear* methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 421 ---------------------------- src/d3d11/d3d11_context.h | 24 -- src/d3d11/d3d11_context_common.cpp | 426 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 24 ++ 4 files changed, 450 insertions(+), 445 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index bdc8dd80b..155dc3808 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -79,427 +79,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::ClearRenderTargetView( - ID3D11RenderTargetView* pRenderTargetView, - const FLOAT ColorRGBA[4]) { - D3D10DeviceLock lock = LockContext(); - - auto rtv = static_cast(pRenderTargetView); - - if (!rtv) - return; - - auto view = rtv->GetImageView(); - auto color = ConvertColorValue(ColorRGBA, view->formatInfo()); - - EmitCs([ - cClearValue = color, - cImageView = std::move(view) - ] (DxvkContext* ctx) { - ctx->clearRenderTarget( - cImageView, - VK_IMAGE_ASPECT_COLOR_BIT, - cClearValue); - }); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::ClearUnorderedAccessViewUint( - ID3D11UnorderedAccessView* pUnorderedAccessView, - const UINT Values[4]) { - D3D10DeviceLock lock = LockContext(); - - auto uav = static_cast(pUnorderedAccessView); - - if (!uav) - return; - - // Gather UAV format info. We'll use this to determine - // whether we need to create a temporary view or not. - D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; - uav->GetDesc(&uavDesc); - - VkFormat uavFormat = m_parent->LookupFormat(uavDesc.Format, DXGI_VK_FORMAT_MODE_ANY).Format; - VkFormat rawFormat = m_parent->LookupFormat(uavDesc.Format, DXGI_VK_FORMAT_MODE_RAW).Format; - - if (uavFormat != rawFormat && rawFormat == VK_FORMAT_UNDEFINED) { - Logger::err(str::format("D3D11: ClearUnorderedAccessViewUint: No raw format found for ", uavFormat)); - return; - } - - VkClearValue clearValue; - - // R11G11B10 is a special case since there's no corresponding - // integer format with the same bit layout. Use R32 instead. - if (uavFormat == VK_FORMAT_B10G11R11_UFLOAT_PACK32) { - clearValue.color.uint32[0] = ((Values[0] & 0x7FF) << 0) - | ((Values[1] & 0x7FF) << 11) - | ((Values[2] & 0x3FF) << 22); - clearValue.color.uint32[1] = 0; - clearValue.color.uint32[2] = 0; - clearValue.color.uint32[3] = 0; - } else { - clearValue.color.uint32[0] = Values[0]; - clearValue.color.uint32[1] = Values[1]; - clearValue.color.uint32[2] = Values[2]; - clearValue.color.uint32[3] = Values[3]; - } - - if (uav->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) { - // In case of raw and structured buffers as well as typed - // buffers that can be used for atomic operations, we can - // use the fast Vulkan buffer clear function. - Rc bufferView = uav->GetBufferView(); - - if (bufferView->info().format == VK_FORMAT_R32_UINT - || bufferView->info().format == VK_FORMAT_R32_SINT - || bufferView->info().format == VK_FORMAT_R32_SFLOAT - || bufferView->info().format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) { - EmitCs([ - cClearValue = clearValue.color.uint32[0], - cDstSlice = bufferView->slice() - ] (DxvkContext* ctx) { - ctx->clearBuffer( - cDstSlice.buffer(), - cDstSlice.offset(), - cDstSlice.length(), - cClearValue); - }); - } else { - // Create a view with an integer format if necessary - if (uavFormat != rawFormat) { - DxvkBufferViewCreateInfo info = bufferView->info(); - info.format = rawFormat; - - bufferView = m_device->createBufferView( - bufferView->buffer(), info); - } - - EmitCs([ - cClearValue = clearValue, - cDstView = bufferView - ] (DxvkContext* ctx) { - ctx->clearBufferView( - cDstView, 0, - cDstView->elementCount(), - cClearValue.color); - }); - } - } else { - Rc imageView = uav->GetImageView(); - - // If the clear value is zero, we can use the original view regardless of - // the format since the bit pattern will not change in any supported format. - bool isZeroClearValue = !(clearValue.color.uint32[0] | clearValue.color.uint32[1] - | clearValue.color.uint32[2] | clearValue.color.uint32[3]); - - // Check if we can create an image view with the given raw format. If not, - // we'll have to use a fallback using a texel buffer view and buffer copies. - bool isViewCompatible = uavFormat == rawFormat; - - if (!isViewCompatible && (imageView->imageInfo().flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) { - uint32_t formatCount = imageView->imageInfo().viewFormatCount; - isViewCompatible = formatCount == 0; - - for (uint32_t i = 0; i < formatCount && !isViewCompatible; i++) - isViewCompatible = imageView->imageInfo().viewFormats[i] == rawFormat; - } - - if (isViewCompatible || isZeroClearValue) { - // Create a view with an integer format if necessary - if (uavFormat != rawFormat && !isZeroClearValue) { - DxvkImageViewCreateInfo info = imageView->info(); - info.format = rawFormat; - - imageView = m_device->createImageView(imageView->image(), info); - } - - EmitCs([ - cClearValue = clearValue, - cDstView = imageView - ] (DxvkContext* ctx) { - ctx->clearImageView(cDstView, - VkOffset3D { 0, 0, 0 }, - cDstView->mipLevelExtent(0), - VK_IMAGE_ASPECT_COLOR_BIT, - cClearValue); - }); - } else { - DxvkBufferCreateInfo bufferInfo; - bufferInfo.size = imageView->formatInfo()->elementSize - * imageView->info().numLayers - * util::flattenImageExtent(imageView->mipLevelExtent(0)); - bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT - | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; - bufferInfo.stages = VK_PIPELINE_STAGE_TRANSFER_BIT - | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - bufferInfo.access = VK_ACCESS_TRANSFER_READ_BIT - | VK_ACCESS_SHADER_WRITE_BIT; - - Rc buffer = m_device->createBuffer(bufferInfo, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - - DxvkBufferViewCreateInfo bufferViewInfo; - bufferViewInfo.format = rawFormat; - bufferViewInfo.rangeOffset = 0; - bufferViewInfo.rangeLength = bufferInfo.size; - - Rc bufferView = m_device->createBufferView(buffer, - bufferViewInfo); - - EmitCs([ - cDstView = std::move(imageView), - cSrcView = std::move(bufferView), - cClearValue = clearValue.color - ] (DxvkContext* ctx) { - ctx->clearBufferView( - cSrcView, 0, - cSrcView->elementCount(), - cClearValue); - - ctx->copyBufferToImage(cDstView->image(), - vk::pickSubresourceLayers(cDstView->subresources(), 0), - VkOffset3D { 0, 0, 0 }, - cDstView->mipLevelExtent(0), - cSrcView->buffer(), 0, 0, 0); - }); - } - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::ClearUnorderedAccessViewFloat( - ID3D11UnorderedAccessView* pUnorderedAccessView, - const FLOAT Values[4]) { - D3D10DeviceLock lock = LockContext(); - - auto uav = static_cast(pUnorderedAccessView); - - if (!uav) - return; - - auto imgView = uav->GetImageView(); - auto bufView = uav->GetBufferView(); - - const DxvkFormatInfo* info = nullptr; - if (imgView != nullptr) info = imgView->formatInfo(); - if (bufView != nullptr) info = bufView->formatInfo(); - - if (!info || info->flags.any(DxvkFormatFlag::SampledSInt, DxvkFormatFlag::SampledUInt)) - return; - - VkClearValue clearValue; - clearValue.color.float32[0] = Values[0]; - clearValue.color.float32[1] = Values[1]; - clearValue.color.float32[2] = Values[2]; - clearValue.color.float32[3] = Values[3]; - - if (uav->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) { - EmitCs([ - cClearValue = clearValue, - cDstView = std::move(bufView) - ] (DxvkContext* ctx) { - ctx->clearBufferView( - cDstView, 0, - cDstView->elementCount(), - cClearValue.color); - }); - } else { - EmitCs([ - cClearValue = clearValue, - cDstView = std::move(imgView) - ] (DxvkContext* ctx) { - ctx->clearImageView(cDstView, - VkOffset3D { 0, 0, 0 }, - cDstView->mipLevelExtent(0), - VK_IMAGE_ASPECT_COLOR_BIT, - cClearValue); - }); - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::ClearDepthStencilView( - ID3D11DepthStencilView* pDepthStencilView, - UINT ClearFlags, - FLOAT Depth, - UINT8 Stencil) { - D3D10DeviceLock lock = LockContext(); - - auto dsv = static_cast(pDepthStencilView); - - if (!dsv) - return; - - // Figure out which aspects to clear based on - // the image view properties and clear flags. - VkImageAspectFlags aspectMask = 0; - - if (ClearFlags & D3D11_CLEAR_DEPTH) - aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; - - if (ClearFlags & D3D11_CLEAR_STENCIL) - aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - - aspectMask &= dsv->GetWritableAspectMask(); - - if (!aspectMask) - return; - - VkClearValue clearValue; - clearValue.depthStencil.depth = Depth; - clearValue.depthStencil.stencil = Stencil; - - EmitCs([ - cClearValue = clearValue, - cAspectMask = aspectMask, - cImageView = dsv->GetImageView() - ] (DxvkContext* ctx) { - ctx->clearRenderTarget( - cImageView, - cAspectMask, - cClearValue); - }); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::ClearView( - ID3D11View* pView, - const FLOAT Color[4], - const D3D11_RECT* pRect, - UINT NumRects) { - D3D10DeviceLock lock = LockContext(); - - if (NumRects && !pRect) - return; - - // ID3D11View has no methods to query the exact type of - // the view, so we'll have to check each possible class - auto dsv = dynamic_cast(pView); - auto rtv = dynamic_cast(pView); - auto uav = dynamic_cast(pView); - auto vov = dynamic_cast(pView); - - // Retrieve underlying resource view - Rc bufView; - Rc imgView; - - if (dsv != nullptr) - imgView = dsv->GetImageView(); - - if (rtv != nullptr) - imgView = rtv->GetImageView(); - - if (uav != nullptr) { - bufView = uav->GetBufferView(); - imgView = uav->GetImageView(); - } - - if (vov != nullptr) - imgView = vov->GetView(); - - // 3D views are unsupported - if (imgView != nullptr - && imgView->info().type == VK_IMAGE_VIEW_TYPE_3D) - return; - - // Query the view format. We'll have to convert - // the clear color based on the format's data type. - VkFormat format = VK_FORMAT_UNDEFINED; - - if (bufView != nullptr) - format = bufView->info().format; - - if (imgView != nullptr) - format = imgView->info().format; - - if (format == VK_FORMAT_UNDEFINED) - return; - - // We'll need the format info to determine the buffer - // element size, and we also need it for depth images. - const DxvkFormatInfo* formatInfo = lookupFormatInfo(format); - - // Convert the clear color format. ClearView takes - // the clear value for integer formats as a set of - // integral floats, so we'll have to convert. - VkClearValue clearValue = ConvertColorValue(Color, formatInfo); - VkImageAspectFlags clearAspect = formatInfo->aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT); - - // Clear all the rectangles that are specified - for (uint32_t i = 0; i < NumRects || i < 1; i++) { - if (pRect) { - if (pRect[i].left >= pRect[i].right - || pRect[i].top >= pRect[i].bottom) - continue; - } - - if (bufView != nullptr) { - VkDeviceSize offset = 0; - VkDeviceSize length = bufView->info().rangeLength / formatInfo->elementSize; - - if (pRect) { - offset = pRect[i].left; - length = pRect[i].right - pRect[i].left; - } - - EmitCs([ - cBufferView = bufView, - cRangeOffset = offset, - cRangeLength = length, - cClearValue = clearValue - ] (DxvkContext* ctx) { - ctx->clearBufferView( - cBufferView, - cRangeOffset, - cRangeLength, - cClearValue.color); - }); - } - - if (imgView != nullptr) { - VkOffset3D offset = { 0, 0, 0 }; - VkExtent3D extent = imgView->mipLevelExtent(0); - - if (pRect) { - offset = { pRect[i].left, pRect[i].top, 0 }; - extent = { - uint32_t(pRect[i].right - pRect[i].left), - uint32_t(pRect[i].bottom - pRect[i].top), 1 }; - } - - EmitCs([ - cImageView = imgView, - cAreaOffset = offset, - cAreaExtent = extent, - cClearAspect = clearAspect, - cClearValue = clearValue - ] (DxvkContext* ctx) { - const VkImageUsageFlags rtUsage = - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - - bool isFullSize = cImageView->mipLevelExtent(0) == cAreaExtent; - - if ((cImageView->info().usage & rtUsage) && isFullSize) { - ctx->clearRenderTarget( - cImageView, - cClearAspect, - cClearValue); - } else { - ctx->clearImageView( - cImageView, - cAreaOffset, - cAreaExtent, - cClearAspect, - cClearValue); - } - }); - } - } - } - - void STDMETHODCALLTYPE D3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView* pShaderResourceView) { D3D10DeviceLock lock = LockContext(); diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index bacba522a..b4cb34f6d 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -58,30 +58,6 @@ namespace dxvk { ID3D11DeviceChild* pTiledResourceOrViewAccessBeforeBarrier, ID3D11DeviceChild* pTiledResourceOrViewAccessAfterBarrier); - void STDMETHODCALLTYPE ClearRenderTargetView( - ID3D11RenderTargetView* pRenderTargetView, - const FLOAT ColorRGBA[4]); - - void STDMETHODCALLTYPE ClearUnorderedAccessViewUint( - ID3D11UnorderedAccessView* pUnorderedAccessView, - const UINT Values[4]); - - void STDMETHODCALLTYPE ClearUnorderedAccessViewFloat( - ID3D11UnorderedAccessView* pUnorderedAccessView, - const FLOAT Values[4]); - - void STDMETHODCALLTYPE ClearDepthStencilView( - ID3D11DepthStencilView* pDepthStencilView, - UINT ClearFlags, - FLOAT Depth, - UINT8 Stencil); - - void STDMETHODCALLTYPE ClearView( - ID3D11View *pView, - const FLOAT Color[4], - const D3D11_RECT *pRect, - UINT NumRects); - void STDMETHODCALLTYPE GenerateMips( ID3D11ShaderResourceView* pShaderResourceView); diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 5835f11c7..73ef9ed07 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -452,6 +452,432 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::ClearRenderTargetView( + ID3D11RenderTargetView* pRenderTargetView, + const FLOAT ColorRGBA[4]) { + D3D10DeviceLock lock = LockContext(); + + auto rtv = static_cast(pRenderTargetView); + + if (!rtv) + return; + + auto view = rtv->GetImageView(); + auto color = ConvertColorValue(ColorRGBA, view->formatInfo()); + + EmitCs([ + cClearValue = color, + cImageView = std::move(view) + ] (DxvkContext* ctx) { + ctx->clearRenderTarget( + cImageView, + VK_IMAGE_ASPECT_COLOR_BIT, + cClearValue); + }); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::ClearUnorderedAccessViewUint( + ID3D11UnorderedAccessView* pUnorderedAccessView, + const UINT Values[4]) { + D3D10DeviceLock lock = LockContext(); + + auto uav = static_cast(pUnorderedAccessView); + + if (!uav) + return; + + // Gather UAV format info. We'll use this to determine + // whether we need to create a temporary view or not. + D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; + uav->GetDesc(&uavDesc); + + VkFormat uavFormat = m_parent->LookupFormat(uavDesc.Format, DXGI_VK_FORMAT_MODE_ANY).Format; + VkFormat rawFormat = m_parent->LookupFormat(uavDesc.Format, DXGI_VK_FORMAT_MODE_RAW).Format; + + if (uavFormat != rawFormat && rawFormat == VK_FORMAT_UNDEFINED) { + Logger::err(str::format("D3D11: ClearUnorderedAccessViewUint: No raw format found for ", uavFormat)); + return; + } + + VkClearValue clearValue; + + // R11G11B10 is a special case since there's no corresponding + // integer format with the same bit layout. Use R32 instead. + if (uavFormat == VK_FORMAT_B10G11R11_UFLOAT_PACK32) { + clearValue.color.uint32[0] = ((Values[0] & 0x7FF) << 0) + | ((Values[1] & 0x7FF) << 11) + | ((Values[2] & 0x3FF) << 22); + clearValue.color.uint32[1] = 0; + clearValue.color.uint32[2] = 0; + clearValue.color.uint32[3] = 0; + } else { + clearValue.color.uint32[0] = Values[0]; + clearValue.color.uint32[1] = Values[1]; + clearValue.color.uint32[2] = Values[2]; + clearValue.color.uint32[3] = Values[3]; + } + + if (uav->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) { + // In case of raw and structured buffers as well as typed + // buffers that can be used for atomic operations, we can + // use the fast Vulkan buffer clear function. + Rc bufferView = uav->GetBufferView(); + + if (bufferView->info().format == VK_FORMAT_R32_UINT + || bufferView->info().format == VK_FORMAT_R32_SINT + || bufferView->info().format == VK_FORMAT_R32_SFLOAT + || bufferView->info().format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) { + EmitCs([ + cClearValue = clearValue.color.uint32[0], + cDstSlice = bufferView->slice() + ] (DxvkContext* ctx) { + ctx->clearBuffer( + cDstSlice.buffer(), + cDstSlice.offset(), + cDstSlice.length(), + cClearValue); + }); + } else { + // Create a view with an integer format if necessary + if (uavFormat != rawFormat) { + DxvkBufferViewCreateInfo info = bufferView->info(); + info.format = rawFormat; + + bufferView = m_device->createBufferView( + bufferView->buffer(), info); + } + + EmitCs([ + cClearValue = clearValue, + cDstView = bufferView + ] (DxvkContext* ctx) { + ctx->clearBufferView( + cDstView, 0, + cDstView->elementCount(), + cClearValue.color); + }); + } + } else { + Rc imageView = uav->GetImageView(); + + // If the clear value is zero, we can use the original view regardless of + // the format since the bit pattern will not change in any supported format. + bool isZeroClearValue = !(clearValue.color.uint32[0] | clearValue.color.uint32[1] + | clearValue.color.uint32[2] | clearValue.color.uint32[3]); + + // Check if we can create an image view with the given raw format. If not, + // we'll have to use a fallback using a texel buffer view and buffer copies. + bool isViewCompatible = uavFormat == rawFormat; + + if (!isViewCompatible && (imageView->imageInfo().flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) { + uint32_t formatCount = imageView->imageInfo().viewFormatCount; + isViewCompatible = formatCount == 0; + + for (uint32_t i = 0; i < formatCount && !isViewCompatible; i++) + isViewCompatible = imageView->imageInfo().viewFormats[i] == rawFormat; + } + + if (isViewCompatible || isZeroClearValue) { + // Create a view with an integer format if necessary + if (uavFormat != rawFormat && !isZeroClearValue) { + DxvkImageViewCreateInfo info = imageView->info(); + info.format = rawFormat; + + imageView = m_device->createImageView(imageView->image(), info); + } + + EmitCs([ + cClearValue = clearValue, + cDstView = imageView + ] (DxvkContext* ctx) { + ctx->clearImageView(cDstView, + VkOffset3D { 0, 0, 0 }, + cDstView->mipLevelExtent(0), + VK_IMAGE_ASPECT_COLOR_BIT, + cClearValue); + }); + } else { + DxvkBufferCreateInfo bufferInfo; + bufferInfo.size = imageView->formatInfo()->elementSize + * imageView->info().numLayers + * util::flattenImageExtent(imageView->mipLevelExtent(0)); + bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT + | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; + bufferInfo.stages = VK_PIPELINE_STAGE_TRANSFER_BIT + | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + bufferInfo.access = VK_ACCESS_TRANSFER_READ_BIT + | VK_ACCESS_SHADER_WRITE_BIT; + + Rc buffer = m_device->createBuffer(bufferInfo, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + DxvkBufferViewCreateInfo bufferViewInfo; + bufferViewInfo.format = rawFormat; + bufferViewInfo.rangeOffset = 0; + bufferViewInfo.rangeLength = bufferInfo.size; + + Rc bufferView = m_device->createBufferView(buffer, + bufferViewInfo); + + EmitCs([ + cDstView = std::move(imageView), + cSrcView = std::move(bufferView), + cClearValue = clearValue.color + ] (DxvkContext* ctx) { + ctx->clearBufferView( + cSrcView, 0, + cSrcView->elementCount(), + cClearValue); + + ctx->copyBufferToImage(cDstView->image(), + vk::pickSubresourceLayers(cDstView->subresources(), 0), + VkOffset3D { 0, 0, 0 }, + cDstView->mipLevelExtent(0), + cSrcView->buffer(), 0, 0, 0); + }); + } + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::ClearUnorderedAccessViewFloat( + ID3D11UnorderedAccessView* pUnorderedAccessView, + const FLOAT Values[4]) { + D3D10DeviceLock lock = LockContext(); + + auto uav = static_cast(pUnorderedAccessView); + + if (!uav) + return; + + auto imgView = uav->GetImageView(); + auto bufView = uav->GetBufferView(); + + const DxvkFormatInfo* info = nullptr; + if (imgView != nullptr) info = imgView->formatInfo(); + if (bufView != nullptr) info = bufView->formatInfo(); + + if (!info || info->flags.any(DxvkFormatFlag::SampledSInt, DxvkFormatFlag::SampledUInt)) + return; + + VkClearValue clearValue; + clearValue.color.float32[0] = Values[0]; + clearValue.color.float32[1] = Values[1]; + clearValue.color.float32[2] = Values[2]; + clearValue.color.float32[3] = Values[3]; + + if (uav->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) { + EmitCs([ + cClearValue = clearValue, + cDstView = std::move(bufView) + ] (DxvkContext* ctx) { + ctx->clearBufferView( + cDstView, 0, + cDstView->elementCount(), + cClearValue.color); + }); + } else { + EmitCs([ + cClearValue = clearValue, + cDstView = std::move(imgView) + ] (DxvkContext* ctx) { + ctx->clearImageView(cDstView, + VkOffset3D { 0, 0, 0 }, + cDstView->mipLevelExtent(0), + VK_IMAGE_ASPECT_COLOR_BIT, + cClearValue); + }); + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::ClearDepthStencilView( + ID3D11DepthStencilView* pDepthStencilView, + UINT ClearFlags, + FLOAT Depth, + UINT8 Stencil) { + D3D10DeviceLock lock = LockContext(); + + auto dsv = static_cast(pDepthStencilView); + + if (!dsv) + return; + + // Figure out which aspects to clear based on + // the image view properties and clear flags. + VkImageAspectFlags aspectMask = 0; + + if (ClearFlags & D3D11_CLEAR_DEPTH) + aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; + + if (ClearFlags & D3D11_CLEAR_STENCIL) + aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; + + aspectMask &= dsv->GetWritableAspectMask(); + + if (!aspectMask) + return; + + VkClearValue clearValue; + clearValue.depthStencil.depth = Depth; + clearValue.depthStencil.stencil = Stencil; + + EmitCs([ + cClearValue = clearValue, + cAspectMask = aspectMask, + cImageView = dsv->GetImageView() + ] (DxvkContext* ctx) { + ctx->clearRenderTarget( + cImageView, + cAspectMask, + cClearValue); + }); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::ClearView( + ID3D11View* pView, + const FLOAT Color[4], + const D3D11_RECT* pRect, + UINT NumRects) { + D3D10DeviceLock lock = LockContext(); + + if (NumRects && !pRect) + return; + + // ID3D11View has no methods to query the exact type of + // the view, so we'll have to check each possible class + auto dsv = dynamic_cast(pView); + auto rtv = dynamic_cast(pView); + auto uav = dynamic_cast(pView); + auto vov = dynamic_cast(pView); + + // Retrieve underlying resource view + Rc bufView; + Rc imgView; + + if (dsv != nullptr) + imgView = dsv->GetImageView(); + + if (rtv != nullptr) + imgView = rtv->GetImageView(); + + if (uav != nullptr) { + bufView = uav->GetBufferView(); + imgView = uav->GetImageView(); + } + + if (vov != nullptr) + imgView = vov->GetView(); + + // 3D views are unsupported + if (imgView != nullptr + && imgView->info().type == VK_IMAGE_VIEW_TYPE_3D) + return; + + // Query the view format. We'll have to convert + // the clear color based on the format's data type. + VkFormat format = VK_FORMAT_UNDEFINED; + + if (bufView != nullptr) + format = bufView->info().format; + + if (imgView != nullptr) + format = imgView->info().format; + + if (format == VK_FORMAT_UNDEFINED) + return; + + // We'll need the format info to determine the buffer + // element size, and we also need it for depth images. + const DxvkFormatInfo* formatInfo = lookupFormatInfo(format); + + // Convert the clear color format. ClearView takes + // the clear value for integer formats as a set of + // integral floats, so we'll have to convert. + VkClearValue clearValue = ConvertColorValue(Color, formatInfo); + VkImageAspectFlags clearAspect = formatInfo->aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT); + + // Clear all the rectangles that are specified + for (uint32_t i = 0; i < NumRects || i < 1; i++) { + if (pRect) { + if (pRect[i].left >= pRect[i].right + || pRect[i].top >= pRect[i].bottom) + continue; + } + + if (bufView != nullptr) { + VkDeviceSize offset = 0; + VkDeviceSize length = bufView->info().rangeLength / formatInfo->elementSize; + + if (pRect) { + offset = pRect[i].left; + length = pRect[i].right - pRect[i].left; + } + + EmitCs([ + cBufferView = bufView, + cRangeOffset = offset, + cRangeLength = length, + cClearValue = clearValue + ] (DxvkContext* ctx) { + ctx->clearBufferView( + cBufferView, + cRangeOffset, + cRangeLength, + cClearValue.color); + }); + } + + if (imgView != nullptr) { + VkOffset3D offset = { 0, 0, 0 }; + VkExtent3D extent = imgView->mipLevelExtent(0); + + if (pRect) { + offset = { pRect[i].left, pRect[i].top, 0 }; + extent = { + uint32_t(pRect[i].right - pRect[i].left), + uint32_t(pRect[i].bottom - pRect[i].top), 1 }; + } + + EmitCs([ + cImageView = imgView, + cAreaOffset = offset, + cAreaExtent = extent, + cClearAspect = clearAspect, + cClearValue = clearValue + ] (DxvkContext* ctx) { + const VkImageUsageFlags rtUsage = + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + + bool isFullSize = cImageView->mipLevelExtent(0) == cAreaExtent; + + if ((cImageView->info().usage & rtUsage) && isFullSize) { + ctx->clearRenderTarget( + cImageView, + cClearAspect, + cClearValue); + } else { + ctx->clearImageView( + cImageView, + cAreaOffset, + cAreaExtent, + cClearAspect, + cClearValue); + } + }); + } + } + } + + template void STDMETHODCALLTYPE D3D11CommonContext::UpdateSubresource( ID3D11Resource* pDstResource, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 1a5919ff9..bd9fdea23 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -109,6 +109,30 @@ namespace dxvk { UINT DstAlignedByteOffset, ID3D11UnorderedAccessView* pSrcView); + void STDMETHODCALLTYPE ClearRenderTargetView( + ID3D11RenderTargetView* pRenderTargetView, + const FLOAT ColorRGBA[4]); + + void STDMETHODCALLTYPE ClearUnorderedAccessViewUint( + ID3D11UnorderedAccessView* pUnorderedAccessView, + const UINT Values[4]); + + void STDMETHODCALLTYPE ClearUnorderedAccessViewFloat( + ID3D11UnorderedAccessView* pUnorderedAccessView, + const FLOAT Values[4]); + + void STDMETHODCALLTYPE ClearDepthStencilView( + ID3D11DepthStencilView* pDepthStencilView, + UINT ClearFlags, + FLOAT Depth, + UINT8 Stencil); + + void STDMETHODCALLTYPE ClearView( + ID3D11View *pView, + const FLOAT Color[4], + const D3D11_RECT *pRect, + UINT NumRects); + void STDMETHODCALLTYPE UpdateSubresource( ID3D11Resource* pDstResource, UINT DstSubresource, From 956bad5e8468bd01a9bd49062841caa126e00d2b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:48:40 +0200 Subject: [PATCH 0390/1348] [d3d11] Move GenerateMips to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 20 -------------------- src/d3d11/d3d11_context.h | 3 --- src/d3d11/d3d11_context_common.cpp | 21 +++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 3 +++ 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 155dc3808..89dcde05e 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -79,26 +79,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView* pShaderResourceView) { - D3D10DeviceLock lock = LockContext(); - - auto view = static_cast(pShaderResourceView); - - if (!view || view->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) - return; - - D3D11_COMMON_RESOURCE_DESC resourceDesc = view->GetResourceDesc(); - - if (!(resourceDesc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)) - return; - - EmitCs([cDstImageView = view->GetImageView()] - (DxvkContext* ctx) { - ctx->generateMipmaps(cDstImageView, VK_FILTER_LINEAR); - }); - } - - HRESULT STDMETHODCALLTYPE D3D11DeviceContext::UpdateTileMappings( ID3D11Resource* pTiledResource, UINT NumTiledResourceRegions, diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index b4cb34f6d..3c0dae36f 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -58,9 +58,6 @@ namespace dxvk { ID3D11DeviceChild* pTiledResourceOrViewAccessBeforeBarrier, ID3D11DeviceChild* pTiledResourceOrViewAccessAfterBarrier); - void STDMETHODCALLTYPE GenerateMips( - ID3D11ShaderResourceView* pShaderResourceView); - HRESULT STDMETHODCALLTYPE UpdateTileMappings( ID3D11Resource* pTiledResource, UINT NumTiledResourceRegions, diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 73ef9ed07..92511a91c 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -878,6 +878,27 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::GenerateMips(ID3D11ShaderResourceView* pShaderResourceView) { + D3D10DeviceLock lock = LockContext(); + + auto view = static_cast(pShaderResourceView); + + if (!view || view->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) + return; + + D3D11_COMMON_RESOURCE_DESC resourceDesc = view->GetResourceDesc(); + + if (!(resourceDesc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)) + return; + + EmitCs([cDstImageView = view->GetImageView()] + (DxvkContext* ctx) { + ctx->generateMipmaps(cDstImageView, VK_FILTER_LINEAR); + }); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::UpdateSubresource( ID3D11Resource* pDstResource, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index bd9fdea23..b8590ec6a 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -133,6 +133,9 @@ namespace dxvk { const D3D11_RECT *pRect, UINT NumRects); + void STDMETHODCALLTYPE GenerateMips( + ID3D11ShaderResourceView* pShaderResourceView); + void STDMETHODCALLTYPE UpdateSubresource( ID3D11Resource* pDstResource, UINT DstSubresource, From 7c82ed35b2a614c7d9ec345da78d9346d427a8b1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:51:18 +0200 Subject: [PATCH 0391/1348] [d3d11] Move internal resource update methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 195 ---------------------------- src/d3d11/d3d11_context.h | 21 --- src/d3d11/d3d11_context_common.cpp | 198 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 21 +++ 4 files changed, 219 insertions(+), 216 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 89dcde05e..657160834 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -984,201 +984,6 @@ namespace dxvk { } - void D3D11DeviceContext::UpdateBuffer( - D3D11Buffer* pDstBuffer, - UINT Offset, - UINT Length, - const void* pSrcData) { - DxvkBufferSlice bufferSlice = pDstBuffer->GetBufferSlice(Offset, Length); - - if (Length <= 1024 && !(Offset & 0x3) && !(Length & 0x3)) { - // The backend has special code paths for small buffer updates, - // however both offset and size must be aligned to four bytes. - DxvkDataSlice dataSlice = AllocUpdateBufferSlice(Length); - std::memcpy(dataSlice.ptr(), pSrcData, Length); - - EmitCs([ - cDataBuffer = std::move(dataSlice), - cBufferSlice = std::move(bufferSlice) - ] (DxvkContext* ctx) { - ctx->updateBuffer( - cBufferSlice.buffer(), - cBufferSlice.offset(), - cBufferSlice.length(), - cDataBuffer.ptr()); - }); - } else { - // Otherwise, to avoid large data copies on the CS thread, - // write directly to a staging buffer and dispatch a copy - DxvkBufferSlice stagingSlice = AllocStagingBuffer(Length); - std::memcpy(stagingSlice.mapPtr(0), pSrcData, Length); - - EmitCs([ - cStagingSlice = std::move(stagingSlice), - cBufferSlice = std::move(bufferSlice) - ] (DxvkContext* ctx) { - ctx->copyBuffer( - cBufferSlice.buffer(), - cBufferSlice.offset(), - cStagingSlice.buffer(), - cStagingSlice.offset(), - cBufferSlice.length()); - }); - } - - if (pDstBuffer->HasSequenceNumber()) - TrackBufferSequenceNumber(pDstBuffer); - } - - - void D3D11DeviceContext::UpdateTexture( - D3D11CommonTexture* pDstTexture, - UINT DstSubresource, - const D3D11_BOX* pDstBox, - const void* pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch) { - if (DstSubresource >= pDstTexture->CountSubresources()) - return; - - VkFormat packedFormat = pDstTexture->GetPackedFormat(); - - auto formatInfo = lookupFormatInfo(packedFormat); - auto subresource = pDstTexture->GetSubresourceFromIndex( - formatInfo->aspectMask, DstSubresource); - - VkExtent3D mipExtent = pDstTexture->MipLevelExtent(subresource.mipLevel); - - VkOffset3D offset = { 0, 0, 0 }; - VkExtent3D extent = mipExtent; - - if (pDstBox != nullptr) { - if (pDstBox->left >= pDstBox->right - || pDstBox->top >= pDstBox->bottom - || pDstBox->front >= pDstBox->back) - return; // no-op, but legal - - offset.x = pDstBox->left; - offset.y = pDstBox->top; - offset.z = pDstBox->front; - - extent.width = pDstBox->right - pDstBox->left; - extent.height = pDstBox->bottom - pDstBox->top; - extent.depth = pDstBox->back - pDstBox->front; - } - - if (!util::isBlockAligned(offset, extent, formatInfo->blockSize, mipExtent)) { - Logger::err("D3D11: UpdateSubresource1: Unaligned region"); - return; - } - - auto stagingSlice = AllocStagingBuffer(util::computeImageDataSize(packedFormat, extent)); - - util::packImageData(stagingSlice.mapPtr(0), - pSrcData, SrcRowPitch, SrcDepthPitch, 0, 0, - pDstTexture->GetVkImageType(), extent, 1, - formatInfo, formatInfo->aspectMask); - - UpdateImage(pDstTexture, &subresource, - offset, extent, std::move(stagingSlice)); - } - - - void D3D11DeviceContext::UpdateImage( - D3D11CommonTexture* pDstTexture, - const VkImageSubresource* pDstSubresource, - VkOffset3D DstOffset, - VkExtent3D DstExtent, - DxvkBufferSlice StagingBuffer) { - bool dstIsImage = pDstTexture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING; - - uint32_t dstSubresource = D3D11CalcSubresource(pDstSubresource->mipLevel, - pDstSubresource->arrayLayer, pDstTexture->Desc()->MipLevels); - - if (dstIsImage) { - EmitCs([ - cDstImage = pDstTexture->GetImage(), - cDstLayers = vk::makeSubresourceLayers(*pDstSubresource), - cDstOffset = DstOffset, - cDstExtent = DstExtent, - cStagingSlice = std::move(StagingBuffer), - cPackedFormat = pDstTexture->GetPackedFormat() - ] (DxvkContext* ctx) { - if (cDstLayers.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { - ctx->copyBufferToImage(cDstImage, - cDstLayers, cDstOffset, cDstExtent, - cStagingSlice.buffer(), - cStagingSlice.offset(), 0, 0); - } else { - ctx->copyPackedBufferToDepthStencilImage(cDstImage, cDstLayers, - VkOffset2D { cDstOffset.x, cDstOffset.y }, - VkExtent2D { cDstExtent.width, cDstExtent.height }, - cStagingSlice.buffer(), - cStagingSlice.offset(), - VkOffset2D { 0, 0 }, - VkExtent2D { cDstExtent.width, cDstExtent.height }, - cPackedFormat); - } - }); - } else { - // If the destination image is backed only by a buffer, we need to use - // the packed buffer copy function which does not know about planes and - // format metadata, so deal with it manually here. - VkExtent3D dstMipExtent = pDstTexture->MipLevelExtent(pDstSubresource->mipLevel); - - auto dstFormat = pDstTexture->GetPackedFormat(); - auto dstFormatInfo = lookupFormatInfo(dstFormat); - - uint32_t planeCount = 1; - - if (dstFormatInfo->flags.test(DxvkFormatFlag::MultiPlane)) - planeCount = vk::getPlaneCount(dstFormatInfo->aspectMask); - - // The source data isn't stored in an image so we'll also need to - // track the offset for that while iterating over the planes. - VkDeviceSize srcPlaneOffset = 0; - - for (uint32_t i = 0; i < planeCount; i++) { - VkImageAspectFlags dstAspectMask = dstFormatInfo->aspectMask; - VkDeviceSize elementSize = dstFormatInfo->elementSize; - VkExtent3D blockSize = dstFormatInfo->blockSize; - - if (dstFormatInfo->flags.test(DxvkFormatFlag::MultiPlane)) { - dstAspectMask = vk::getPlaneAspect(i); - - auto plane = &dstFormatInfo->planes[i]; - blockSize.width *= plane->blockSize.width; - blockSize.height *= plane->blockSize.height; - elementSize = plane->elementSize; - } - - VkExtent3D blockCount = util::computeBlockCount(DstExtent, blockSize); - - EmitCs([ - cDstBuffer = pDstTexture->GetMappedBuffer(dstSubresource), - cDstStart = pDstTexture->GetSubresourceLayout(dstAspectMask, dstSubresource).Offset, - cDstOffset = util::computeBlockOffset(DstOffset, blockSize), - cDstSize = util::computeBlockCount(dstMipExtent, blockSize), - cDstExtent = blockCount, - cSrcBuffer = StagingBuffer.buffer(), - cSrcStart = StagingBuffer.offset() + srcPlaneOffset, - cPixelSize = elementSize - ] (DxvkContext* ctx) { - ctx->copyPackedBufferImage( - cDstBuffer, cDstStart, cDstOffset, cDstSize, - cSrcBuffer, cSrcStart, VkOffset3D(), cDstExtent, - cDstExtent, cPixelSize); - }); - - srcPlaneOffset += util::flattenImageExtent(blockCount) * elementSize; - } - } - - if (pDstTexture->HasSequenceNumber()) - TrackTextureSequenceNumber(pDstTexture, dstSubresource); - } - - void D3D11DeviceContext::SetDrawBuffers( ID3D11Buffer* pBufferForArgs, ID3D11Buffer* pBufferForCount) { diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 3c0dae36f..20bb19e38 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -247,27 +247,6 @@ namespace dxvk { UINT CtrSlot, UINT Counter); - void UpdateBuffer( - D3D11Buffer* pDstBuffer, - UINT Offset, - UINT Length, - const void* pSrcData); - - void UpdateTexture( - D3D11CommonTexture* pDstTexture, - UINT DstSubresource, - const D3D11_BOX* pDstBox, - const void* pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch); - - void UpdateImage( - D3D11CommonTexture* pDstTexture, - const VkImageSubresource* pDstSubresource, - VkOffset3D DstOffset, - VkExtent3D DstExtent, - DxvkBufferSlice StagingBuffer); - void SetDrawBuffers( ID3D11Buffer* pBufferForArgs, ID3D11Buffer* pBufferForCount); diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 92511a91c..16d32f9f5 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -3757,6 +3757,204 @@ namespace dxvk { } + template + void D3D11CommonContext::UpdateBuffer( + D3D11Buffer* pDstBuffer, + UINT Offset, + UINT Length, + const void* pSrcData) { + DxvkBufferSlice bufferSlice = pDstBuffer->GetBufferSlice(Offset, Length); + + if (Length <= 1024 && !(Offset & 0x3) && !(Length & 0x3)) { + // The backend has special code paths for small buffer updates, + // however both offset and size must be aligned to four bytes. + DxvkDataSlice dataSlice = AllocUpdateBufferSlice(Length); + std::memcpy(dataSlice.ptr(), pSrcData, Length); + + EmitCs([ + cDataBuffer = std::move(dataSlice), + cBufferSlice = std::move(bufferSlice) + ] (DxvkContext* ctx) { + ctx->updateBuffer( + cBufferSlice.buffer(), + cBufferSlice.offset(), + cBufferSlice.length(), + cDataBuffer.ptr()); + }); + } else { + // Otherwise, to avoid large data copies on the CS thread, + // write directly to a staging buffer and dispatch a copy + DxvkBufferSlice stagingSlice = AllocStagingBuffer(Length); + std::memcpy(stagingSlice.mapPtr(0), pSrcData, Length); + + EmitCs([ + cStagingSlice = std::move(stagingSlice), + cBufferSlice = std::move(bufferSlice) + ] (DxvkContext* ctx) { + ctx->copyBuffer( + cBufferSlice.buffer(), + cBufferSlice.offset(), + cStagingSlice.buffer(), + cStagingSlice.offset(), + cBufferSlice.length()); + }); + } + + if (pDstBuffer->HasSequenceNumber()) + TrackBufferSequenceNumber(pDstBuffer); + } + + + template + void D3D11CommonContext::UpdateTexture( + D3D11CommonTexture* pDstTexture, + UINT DstSubresource, + const D3D11_BOX* pDstBox, + const void* pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch) { + if (DstSubresource >= pDstTexture->CountSubresources()) + return; + + VkFormat packedFormat = pDstTexture->GetPackedFormat(); + + auto formatInfo = lookupFormatInfo(packedFormat); + auto subresource = pDstTexture->GetSubresourceFromIndex( + formatInfo->aspectMask, DstSubresource); + + VkExtent3D mipExtent = pDstTexture->MipLevelExtent(subresource.mipLevel); + + VkOffset3D offset = { 0, 0, 0 }; + VkExtent3D extent = mipExtent; + + if (pDstBox != nullptr) { + if (pDstBox->left >= pDstBox->right + || pDstBox->top >= pDstBox->bottom + || pDstBox->front >= pDstBox->back) + return; // no-op, but legal + + offset.x = pDstBox->left; + offset.y = pDstBox->top; + offset.z = pDstBox->front; + + extent.width = pDstBox->right - pDstBox->left; + extent.height = pDstBox->bottom - pDstBox->top; + extent.depth = pDstBox->back - pDstBox->front; + } + + if (!util::isBlockAligned(offset, extent, formatInfo->blockSize, mipExtent)) { + Logger::err("D3D11: UpdateSubresource1: Unaligned region"); + return; + } + + auto stagingSlice = AllocStagingBuffer(util::computeImageDataSize(packedFormat, extent)); + + util::packImageData(stagingSlice.mapPtr(0), + pSrcData, SrcRowPitch, SrcDepthPitch, 0, 0, + pDstTexture->GetVkImageType(), extent, 1, + formatInfo, formatInfo->aspectMask); + + UpdateImage(pDstTexture, &subresource, + offset, extent, std::move(stagingSlice)); + } + + + template + void D3D11CommonContext::UpdateImage( + D3D11CommonTexture* pDstTexture, + const VkImageSubresource* pDstSubresource, + VkOffset3D DstOffset, + VkExtent3D DstExtent, + DxvkBufferSlice StagingBuffer) { + bool dstIsImage = pDstTexture->GetMapMode() != D3D11_COMMON_TEXTURE_MAP_MODE_STAGING; + + uint32_t dstSubresource = D3D11CalcSubresource(pDstSubresource->mipLevel, + pDstSubresource->arrayLayer, pDstTexture->Desc()->MipLevels); + + if (dstIsImage) { + EmitCs([ + cDstImage = pDstTexture->GetImage(), + cDstLayers = vk::makeSubresourceLayers(*pDstSubresource), + cDstOffset = DstOffset, + cDstExtent = DstExtent, + cStagingSlice = std::move(StagingBuffer), + cPackedFormat = pDstTexture->GetPackedFormat() + ] (DxvkContext* ctx) { + if (cDstLayers.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + ctx->copyBufferToImage(cDstImage, + cDstLayers, cDstOffset, cDstExtent, + cStagingSlice.buffer(), + cStagingSlice.offset(), 0, 0); + } else { + ctx->copyPackedBufferToDepthStencilImage(cDstImage, cDstLayers, + VkOffset2D { cDstOffset.x, cDstOffset.y }, + VkExtent2D { cDstExtent.width, cDstExtent.height }, + cStagingSlice.buffer(), + cStagingSlice.offset(), + VkOffset2D { 0, 0 }, + VkExtent2D { cDstExtent.width, cDstExtent.height }, + cPackedFormat); + } + }); + } else { + // If the destination image is backed only by a buffer, we need to use + // the packed buffer copy function which does not know about planes and + // format metadata, so deal with it manually here. + VkExtent3D dstMipExtent = pDstTexture->MipLevelExtent(pDstSubresource->mipLevel); + + auto dstFormat = pDstTexture->GetPackedFormat(); + auto dstFormatInfo = lookupFormatInfo(dstFormat); + + uint32_t planeCount = 1; + + if (dstFormatInfo->flags.test(DxvkFormatFlag::MultiPlane)) + planeCount = vk::getPlaneCount(dstFormatInfo->aspectMask); + + // The source data isn't stored in an image so we'll also need to + // track the offset for that while iterating over the planes. + VkDeviceSize srcPlaneOffset = 0; + + for (uint32_t i = 0; i < planeCount; i++) { + VkImageAspectFlags dstAspectMask = dstFormatInfo->aspectMask; + VkDeviceSize elementSize = dstFormatInfo->elementSize; + VkExtent3D blockSize = dstFormatInfo->blockSize; + + if (dstFormatInfo->flags.test(DxvkFormatFlag::MultiPlane)) { + dstAspectMask = vk::getPlaneAspect(i); + + auto plane = &dstFormatInfo->planes[i]; + blockSize.width *= plane->blockSize.width; + blockSize.height *= plane->blockSize.height; + elementSize = plane->elementSize; + } + + VkExtent3D blockCount = util::computeBlockCount(DstExtent, blockSize); + + EmitCs([ + cDstBuffer = pDstTexture->GetMappedBuffer(dstSubresource), + cDstStart = pDstTexture->GetSubresourceLayout(dstAspectMask, dstSubresource).Offset, + cDstOffset = util::computeBlockOffset(DstOffset, blockSize), + cDstSize = util::computeBlockCount(dstMipExtent, blockSize), + cDstExtent = blockCount, + cSrcBuffer = StagingBuffer.buffer(), + cSrcStart = StagingBuffer.offset() + srcPlaneOffset, + cPixelSize = elementSize + ] (DxvkContext* ctx) { + ctx->copyPackedBufferImage( + cDstBuffer, cDstStart, cDstOffset, cDstSize, + cSrcBuffer, cSrcStart, VkOffset3D(), cDstExtent, + cDstExtent, cPixelSize); + }); + + srcPlaneOffset += util::flattenImageExtent(blockCount) * elementSize; + } + } + + if (pDstTexture->HasSequenceNumber()) + TrackTextureSequenceNumber(pDstTexture, dstSubresource); + } + + template void D3D11CommonContext::UpdateResource( ID3D11Resource* pDstResource, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index b8590ec6a..491475eaf 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -807,6 +807,27 @@ namespace dxvk { bool TestSrvHazards( D3D11ShaderResourceView* pView); + void UpdateBuffer( + D3D11Buffer* pDstBuffer, + UINT Offset, + UINT Length, + const void* pSrcData); + + void UpdateTexture( + D3D11CommonTexture* pDstTexture, + UINT DstSubresource, + const D3D11_BOX* pDstBox, + const void* pSrcData, + UINT SrcRowPitch, + UINT SrcDepthPitch); + + void UpdateImage( + D3D11CommonTexture* pDstTexture, + const VkImageSubresource* pDstSubresource, + VkOffset3D DstOffset, + VkExtent3D DstExtent, + DxvkBufferSlice StagingBuffer); + void UpdateResource( ID3D11Resource* pDstResource, UINT DstSubresource, From 17c318864e021e647509b7bac9c6d0a4ab23c764 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 20:58:00 +0200 Subject: [PATCH 0392/1348] [d3d11] Move Apply* methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 576 ----------------------------- src/d3d11/d3d11_context.h | 93 +---- src/d3d11/d3d11_context_common.cpp | 253 +++++++++++++ src/d3d11/d3d11_context_common.h | 18 + 4 files changed, 273 insertions(+), 667 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 657160834..739840efe 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -502,312 +502,6 @@ namespace dxvk { } - void D3D11DeviceContext::ApplyInputLayout() { - auto inputLayout = m_state.ia.inputLayout.prvRef(); - - if (likely(inputLayout != nullptr)) { - EmitCs([ - cInputLayout = std::move(inputLayout) - ] (DxvkContext* ctx) { - cInputLayout->BindToContext(ctx); - }); - } else { - EmitCs([] (DxvkContext* ctx) { - ctx->setInputLayout(0, nullptr, 0, nullptr); - }); - } - } - - - void D3D11DeviceContext::ApplyPrimitiveTopology() { - D3D11_PRIMITIVE_TOPOLOGY topology = m_state.ia.primitiveTopology; - DxvkInputAssemblyState iaState = { }; - - if (topology <= D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ) { - static const std::array s_iaStates = {{ - { VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, VK_FALSE, 0 }, - { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_FALSE, 0 }, - { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_FALSE, 0 }, - { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, VK_TRUE, 0 }, - { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_FALSE, 0 }, - { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, VK_TRUE, 0 }, - { }, { }, { }, { }, // Random gap that exists for no reason - { VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, VK_FALSE, 0 }, - { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, VK_TRUE, 0 }, - { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, VK_FALSE, 0 }, - { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, VK_TRUE, 0 }, - }}; - - iaState = s_iaStates[uint32_t(topology)]; - } else if (topology >= D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST - && topology <= D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST) { - // The number of control points per patch can be inferred from the enum value in D3D11 - uint32_t vertexCount = uint32_t(topology - D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + 1); - iaState = { VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE, vertexCount }; - } - - EmitCs([iaState] (DxvkContext* ctx) { - ctx->setInputAssemblyState(iaState); - }); - } - - - void D3D11DeviceContext::ApplyBlendState() { - if (m_state.om.cbState != nullptr) { - EmitCs([ - cBlendState = m_state.om.cbState, - cSampleMask = m_state.om.sampleMask - ] (DxvkContext* ctx) { - cBlendState->BindToContext(ctx, cSampleMask); - }); - } else { - EmitCs([ - cSampleMask = m_state.om.sampleMask - ] (DxvkContext* ctx) { - DxvkBlendMode cbState; - DxvkLogicOpState loState; - DxvkMultisampleState msState; - InitDefaultBlendState(&cbState, &loState, &msState, cSampleMask); - - for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - ctx->setBlendMode(i, cbState); - - ctx->setLogicOpState(loState); - ctx->setMultisampleState(msState); - }); - } - } - - - void D3D11DeviceContext::ApplyBlendFactor() { - EmitCs([ - cBlendConstants = DxvkBlendConstants { - m_state.om.blendFactor[0], m_state.om.blendFactor[1], - m_state.om.blendFactor[2], m_state.om.blendFactor[3] } - ] (DxvkContext* ctx) { - ctx->setBlendConstants(cBlendConstants); - }); - } - - - void D3D11DeviceContext::ApplyDepthStencilState() { - if (m_state.om.dsState != nullptr) { - EmitCs([ - cDepthStencilState = m_state.om.dsState - ] (DxvkContext* ctx) { - cDepthStencilState->BindToContext(ctx); - }); - } else { - EmitCs([] (DxvkContext* ctx) { - DxvkDepthStencilState dsState; - InitDefaultDepthStencilState(&dsState); - - ctx->setDepthStencilState(dsState); - }); - } - } - - - void D3D11DeviceContext::ApplyStencilRef() { - EmitCs([ - cStencilRef = m_state.om.stencilRef - ] (DxvkContext* ctx) { - ctx->setStencilReference(cStencilRef); - }); - } - - - void D3D11DeviceContext::ApplyRasterizerState() { - if (m_state.rs.state != nullptr) { - EmitCs([ - cRasterizerState = m_state.rs.state - ] (DxvkContext* ctx) { - cRasterizerState->BindToContext(ctx); - }); - } else { - EmitCs([] (DxvkContext* ctx) { - DxvkRasterizerState rsState; - InitDefaultRasterizerState(&rsState); - - ctx->setRasterizerState(rsState); - }); - } - } - - - void D3D11DeviceContext::ApplyRasterizerSampleCount() { - DxbcPushConstants pc; - pc.rasterizerSampleCount = m_state.om.sampleCount; - - if (unlikely(!m_state.om.sampleCount)) { - pc.rasterizerSampleCount = m_state.rs.state->Desc()->ForcedSampleCount; - - if (!m_state.om.sampleCount) - pc.rasterizerSampleCount = 1; - } - - EmitCs([ - cPushConstants = pc - ] (DxvkContext* ctx) { - ctx->pushConstants(0, sizeof(cPushConstants), &cPushConstants); - }); - } - - - void D3D11DeviceContext::ApplyViewportState() { - std::array viewports; - std::array scissors; - - // The backend can't handle a viewport count of zero, - // so we should at least specify one empty viewport - uint32_t viewportCount = m_state.rs.numViewports; - - if (unlikely(!viewportCount)) { - viewportCount = 1; - viewports[0] = VkViewport(); - scissors [0] = VkRect2D(); - } - - // D3D11's coordinate system has its origin in the bottom left, - // but the viewport coordinates are aligned to the top-left - // corner so we can get away with flipping the viewport. - for (uint32_t i = 0; i < m_state.rs.numViewports; i++) { - const D3D11_VIEWPORT& vp = m_state.rs.viewports[i]; - - viewports[i] = VkViewport { - vp.TopLeftX, vp.Height + vp.TopLeftY, - vp.Width, -vp.Height, - vp.MinDepth, vp.MaxDepth, - }; - } - - // Scissor rectangles. Vulkan does not provide an easy way - // to disable the scissor test, so we'll have to set scissor - // rects that are at least as large as the framebuffer. - bool enableScissorTest = false; - - if (m_state.rs.state != nullptr) { - D3D11_RASTERIZER_DESC rsDesc; - m_state.rs.state->GetDesc(&rsDesc); - enableScissorTest = rsDesc.ScissorEnable; - } - - for (uint32_t i = 0; i < m_state.rs.numViewports; i++) { - if (!enableScissorTest) { - scissors[i] = VkRect2D { - VkOffset2D { 0, 0 }, - VkExtent2D { - D3D11_VIEWPORT_BOUNDS_MAX, - D3D11_VIEWPORT_BOUNDS_MAX } }; - } else if (i >= m_state.rs.numScissors) { - scissors[i] = VkRect2D { - VkOffset2D { 0, 0 }, - VkExtent2D { 0, 0 } }; - } else { - D3D11_RECT sr = m_state.rs.scissors[i]; - - VkOffset2D srPosA; - srPosA.x = std::max(0, sr.left); - srPosA.y = std::max(0, sr.top); - - VkOffset2D srPosB; - srPosB.x = std::max(srPosA.x, sr.right); - srPosB.y = std::max(srPosA.y, sr.bottom); - - VkExtent2D srSize; - srSize.width = uint32_t(srPosB.x - srPosA.x); - srSize.height = uint32_t(srPosB.y - srPosA.y); - - scissors[i] = VkRect2D { srPosA, srSize }; - } - } - - if (likely(viewportCount == 1)) { - EmitCs([ - cViewport = viewports[0], - cScissor = scissors[0] - ] (DxvkContext* ctx) { - ctx->setViewports(1, - &cViewport, - &cScissor); - }); - } else { - EmitCs([ - cViewportCount = viewportCount, - cViewports = viewports, - cScissors = scissors - ] (DxvkContext* ctx) { - ctx->setViewports( - cViewportCount, - cViewports.data(), - cScissors.data()); - }); - } - } - - - template - void D3D11DeviceContext::BindShader( - const D3D11CommonShader* pShaderModule) { - // Bind the shader and the ICB at once - EmitCs([ - cSlice = pShaderModule != nullptr - && pShaderModule->GetIcb() != nullptr - ? DxvkBufferSlice(pShaderModule->GetIcb()) - : DxvkBufferSlice(), - cShader = pShaderModule != nullptr - ? pShaderModule->GetShader() - : nullptr - ] (DxvkContext* ctx) { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - - uint32_t slotId = computeConstantBufferBinding(ShaderStage, - D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); - - ctx->bindShader (stage, cShader); - ctx->bindResourceBuffer(stage, slotId, cSlice); - }); - } - - - void D3D11DeviceContext::BindFramebuffer() { - DxvkRenderTargets attachments; - uint32_t sampleCount = 0; - - // D3D11 doesn't have the concept of a framebuffer object, - // so we'll just create a new one every time the render - // target bindings are updated. Set up the attachments. - for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) { - if (m_state.om.renderTargetViews[i] != nullptr) { - attachments.color[i] = { - m_state.om.renderTargetViews[i]->GetImageView(), - m_state.om.renderTargetViews[i]->GetRenderLayout() }; - sampleCount = m_state.om.renderTargetViews[i]->GetSampleCount(); - } - } - - if (m_state.om.depthStencilView != nullptr) { - attachments.depth = { - m_state.om.depthStencilView->GetImageView(), - m_state.om.depthStencilView->GetRenderLayout() }; - sampleCount = m_state.om.depthStencilView->GetSampleCount(); - } - - // Create and bind the framebuffer object to the context - EmitCs([ - cAttachments = std::move(attachments) - ] (DxvkContext* ctx) { - ctx->bindRenderTargets(cAttachments); - }); - - // If necessary, update push constant for the sample count - if (m_state.om.sampleCount != sampleCount) { - m_state.om.sampleCount = sampleCount; - ApplyRasterizerSampleCount(); - } - } - - void D3D11DeviceContext::BindDrawBuffers( D3D11Buffer* pBufferForArgs, D3D11Buffer* pBufferForCount) { @@ -820,170 +514,6 @@ namespace dxvk { } - void D3D11DeviceContext::BindVertexBuffer( - UINT Slot, - D3D11Buffer* pBuffer, - UINT Offset, - UINT Stride) { - if (likely(pBuffer != nullptr)) { - EmitCs([ - cSlotId = Slot, - cBufferSlice = pBuffer->GetBufferSlice(Offset), - cStride = Stride - ] (DxvkContext* ctx) { - ctx->bindVertexBuffer(cSlotId, cBufferSlice, cStride); - }); - } else { - EmitCs([ - cSlotId = Slot - ] (DxvkContext* ctx) { - ctx->bindVertexBuffer(cSlotId, DxvkBufferSlice(), 0); - }); - } - } - - - void D3D11DeviceContext::BindIndexBuffer( - D3D11Buffer* pBuffer, - UINT Offset, - DXGI_FORMAT Format) { - VkIndexType indexType = Format == DXGI_FORMAT_R16_UINT - ? VK_INDEX_TYPE_UINT16 - : VK_INDEX_TYPE_UINT32; - - EmitCs([ - cBufferSlice = pBuffer != nullptr ? pBuffer->GetBufferSlice(Offset) : DxvkBufferSlice(), - cIndexType = indexType - ] (DxvkContext* ctx) { - ctx->bindIndexBuffer(cBufferSlice, cIndexType); - }); - } - - - void D3D11DeviceContext::BindXfbBuffer( - UINT Slot, - D3D11Buffer* pBuffer, - UINT Offset) { - DxvkBufferSlice bufferSlice; - DxvkBufferSlice counterSlice; - - if (pBuffer != nullptr) { - bufferSlice = pBuffer->GetBufferSlice(); - counterSlice = pBuffer->GetSOCounter(); - } - - EmitCs([ - cSlotId = Slot, - cOffset = Offset, - cBufferSlice = bufferSlice, - cCounterSlice = counterSlice - ] (DxvkContext* ctx) { - if (cCounterSlice.defined() && cOffset != ~0u) { - ctx->updateBuffer( - cCounterSlice.buffer(), - cCounterSlice.offset(), - sizeof(cOffset), - &cOffset); - } - - ctx->bindXfbBuffer(cSlotId, cBufferSlice, cCounterSlice); - }); - } - - - template - void D3D11DeviceContext::BindConstantBuffer( - UINT Slot, - D3D11Buffer* pBuffer, - UINT Offset, - UINT Length) { - EmitCs([ - cSlotId = Slot, - cBufferSlice = pBuffer ? pBuffer->GetBufferSlice(16 * Offset, 16 * Length) : DxvkBufferSlice() - ] (DxvkContext* ctx) { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceBuffer(stage, cSlotId, cBufferSlice); - }); - } - - - template - void D3D11DeviceContext::BindConstantBufferRange( - UINT Slot, - UINT Offset, - UINT Length) { - EmitCs([ - cSlotId = Slot, - cOffset = 16 * Offset, - cLength = 16 * Length - ] (DxvkContext* ctx) { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceBufferRange(stage, cSlotId, cOffset, cLength); - }); - } - - - template - void D3D11DeviceContext::BindSampler( - UINT Slot, - D3D11SamplerState* pSampler) { - EmitCs([ - cSlotId = Slot, - cSampler = pSampler != nullptr ? pSampler->GetDXVKSampler() : nullptr - ] (DxvkContext* ctx) { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceSampler(stage, cSlotId, cSampler); - }); - } - - - template - void D3D11DeviceContext::BindShaderResource( - UINT Slot, - D3D11ShaderResourceView* pResource) { - EmitCs([ - cSlotId = Slot, - cImageView = pResource != nullptr ? pResource->GetImageView() : nullptr, - cBufferView = pResource != nullptr ? pResource->GetBufferView() : nullptr - ] (DxvkContext* ctx) { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceView(stage, cSlotId, cImageView, cBufferView); - }); - } - - - template - void D3D11DeviceContext::BindUnorderedAccessView( - UINT UavSlot, - D3D11UnorderedAccessView* pUav, - UINT CtrSlot, - UINT Counter) { - EmitCs([ - cUavSlotId = UavSlot, - cCtrSlotId = CtrSlot, - cImageView = pUav != nullptr ? pUav->GetImageView() : nullptr, - cBufferView = pUav != nullptr ? pUav->GetBufferView() : nullptr, - cCounterSlice = pUav != nullptr ? pUav->GetCounterSlice() : DxvkBufferSlice(), - cCounterValue = Counter - ] (DxvkContext* ctx) { - VkShaderStageFlags stages = ShaderStage == DxbcProgramType::PixelShader - ? VK_SHADER_STAGE_ALL_GRAPHICS - : VK_SHADER_STAGE_COMPUTE_BIT; - - if (cCounterSlice.defined() && cCounterValue != ~0u) { - ctx->updateBuffer( - cCounterSlice.buffer(), - cCounterSlice.offset(), - sizeof(uint32_t), - &cCounterValue); - } - - ctx->bindResourceView (stages, cUavSlotId, cImageView, cBufferView); - ctx->bindResourceBuffer (stages, cCtrSlotId, cCounterSlice); - }); - } - - void D3D11DeviceContext::SetDrawBuffers( ID3D11Buffer* pBufferForArgs, ID3D11Buffer* pBufferForCount) { @@ -1000,112 +530,6 @@ namespace dxvk { } - bool D3D11DeviceContext::TestRtvUavHazards( - UINT NumRTVs, - ID3D11RenderTargetView* const* ppRTVs, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUAVs) { - if (NumRTVs == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) NumRTVs = 0; - if (NumUAVs == D3D11_KEEP_UNORDERED_ACCESS_VIEWS) NumUAVs = 0; - - for (uint32_t i = 0; i < NumRTVs; i++) { - auto rtv = static_cast(ppRTVs[i]); - - if (!rtv) - continue; - - for (uint32_t j = 0; j < i; j++) { - if (CheckViewOverlap(rtv, static_cast(ppRTVs[j]))) - return true; - } - - if (rtv->HasBindFlag(D3D11_BIND_UNORDERED_ACCESS)) { - for (uint32_t j = 0; j < NumUAVs; j++) { - if (CheckViewOverlap(rtv, static_cast(ppUAVs[j]))) - return true; - } - } - } - - for (uint32_t i = 0; i < NumUAVs; i++) { - auto uav = static_cast(ppUAVs[i]); - - if (!uav) - continue; - - for (uint32_t j = 0; j < i; j++) { - if (CheckViewOverlap(uav, static_cast(ppUAVs[j]))) - return true; - } - } - - return false; - } - - - template - bool D3D11DeviceContext::TestSrvHazards( - D3D11ShaderResourceView* pView) { - bool hazard = false; - - if (ShaderStage == DxbcProgramType::ComputeShader) { - int32_t uav = m_state.cs.uavMask.findNext(0); - - while (uav >= 0 && !hazard) { - hazard = CheckViewOverlap(pView, m_state.cs.unorderedAccessViews[uav].ptr()); - uav = m_state.cs.uavMask.findNext(uav + 1); - } - } else { - hazard = CheckViewOverlap(pView, m_state.om.depthStencilView.ptr()); - - for (uint32_t i = 0; !hazard && i < m_state.om.maxRtv; i++) - hazard = CheckViewOverlap(pView, m_state.om.renderTargetViews[i].ptr()); - - for (uint32_t i = 0; !hazard && i < m_state.om.maxUav; i++) - hazard = CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr()); - } - - return hazard; - } - - - template - void D3D11DeviceContext::ResolveSrvHazards( - T* pView, - D3D11ShaderResourceBindings& Bindings) { - uint32_t slotId = computeSrvBinding(ShaderStage, 0); - int32_t srvId = Bindings.hazardous.findNext(0); - - while (srvId >= 0) { - auto srv = Bindings.views[srvId].ptr(); - - if (likely(srv && srv->TestHazards())) { - bool hazard = CheckViewOverlap(pView, srv); - - if (unlikely(hazard)) { - Bindings.views[srvId] = nullptr; - Bindings.hazardous.clr(srvId); - - BindShaderResource(slotId + srvId, nullptr); - } - } else { - // Avoid further redundant iterations - Bindings.hazardous.clr(srvId); - } - - srvId = Bindings.hazardous.findNext(srvId + 1); - } - } - - - template - void D3D11DeviceContext::ResolveCsSrvHazards( - T* pView) { - if (!pView) return; - ResolveSrvHazards (pView, m_state.cs.shaderResources); - } - - VkClearValue D3D11DeviceContext::ConvertColorValue( const FLOAT Color[4], const DxvkFormatInfo* pFormatInfo) { diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 20bb19e38..b0c96be08 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -173,102 +173,13 @@ namespace dxvk { D3D11ContextState m_state; D3D11CmdData* m_cmdData; - void ApplyInputLayout(); - - void ApplyPrimitiveTopology(); - - void ApplyBlendState(); - - void ApplyBlendFactor(); - - void ApplyDepthStencilState(); - - void ApplyStencilRef(); - - void ApplyRasterizerState(); - - void ApplyRasterizerSampleCount(); - - void ApplyViewportState(); - - template - void BindShader( - const D3D11CommonShader* pShaderModule); - - void BindFramebuffer(); - void BindDrawBuffers( - D3D11Buffer* pBufferForArgs, - D3D11Buffer* pBufferForCount); - - void BindVertexBuffer( - UINT Slot, - D3D11Buffer* pBuffer, - UINT Offset, - UINT Stride); - - void BindIndexBuffer( - D3D11Buffer* pBuffer, - UINT Offset, - DXGI_FORMAT Format); - - void BindXfbBuffer( - UINT Slot, - D3D11Buffer* pBuffer, - UINT Offset); - - template - void BindConstantBuffer( - UINT Slot, - D3D11Buffer* pBuffer, - UINT Offset, - UINT Length); - - template - void BindConstantBufferRange( - UINT Slot, - UINT Offset, - UINT Length); - - template - void BindSampler( - UINT Slot, - D3D11SamplerState* pSampler); - - template - void BindShaderResource( - UINT Slot, - D3D11ShaderResourceView* pResource); - - template - void BindUnorderedAccessView( - UINT UavSlot, - D3D11UnorderedAccessView* pUav, - UINT CtrSlot, - UINT Counter); + D3D11Buffer* pBufferForArgs, + D3D11Buffer* pBufferForCount); void SetDrawBuffers( ID3D11Buffer* pBufferForArgs, ID3D11Buffer* pBufferForCount); - - bool TestRtvUavHazards( - UINT NumRTVs, - ID3D11RenderTargetView* const* ppRTVs, - UINT NumUAVs, - ID3D11UnorderedAccessView* const* ppUAVs); - - template - bool TestSrvHazards( - D3D11ShaderResourceView* pView); - - template - void ResolveSrvHazards( - T* pView, - D3D11ShaderResourceBindings& Bindings); - - template - void ResolveCsSrvHazards( - T* pView); VkClearValue ConvertColorValue( const FLOAT Color[4], diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 16d32f9f5..df8ec61be 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -2483,6 +2483,259 @@ namespace dxvk { } + template + void D3D11CommonContext::ApplyInputLayout() { + auto inputLayout = m_state.ia.inputLayout.prvRef(); + + if (likely(inputLayout != nullptr)) { + EmitCs([ + cInputLayout = std::move(inputLayout) + ] (DxvkContext* ctx) { + cInputLayout->BindToContext(ctx); + }); + } else { + EmitCs([] (DxvkContext* ctx) { + ctx->setInputLayout(0, nullptr, 0, nullptr); + }); + } + } + + + template + void D3D11CommonContext::ApplyPrimitiveTopology() { + D3D11_PRIMITIVE_TOPOLOGY topology = m_state.ia.primitiveTopology; + DxvkInputAssemblyState iaState = { }; + + if (topology <= D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ) { + static const std::array s_iaStates = {{ + { VK_PRIMITIVE_TOPOLOGY_MAX_ENUM, VK_FALSE, 0 }, + { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_FALSE, 0 }, + { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_FALSE, 0 }, + { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, VK_TRUE, 0 }, + { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_FALSE, 0 }, + { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, VK_TRUE, 0 }, + { }, { }, { }, { }, // Random gap that exists for no reason + { VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, VK_FALSE, 0 }, + { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, VK_TRUE, 0 }, + { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, VK_FALSE, 0 }, + { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, VK_TRUE, 0 }, + }}; + + iaState = s_iaStates[uint32_t(topology)]; + } else if (topology >= D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + && topology <= D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST) { + // The number of control points per patch can be inferred from the enum value in D3D11 + uint32_t vertexCount = uint32_t(topology - D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + 1); + iaState = { VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE, vertexCount }; + } + + EmitCs([iaState] (DxvkContext* ctx) { + ctx->setInputAssemblyState(iaState); + }); + } + + + template + void D3D11CommonContext::ApplyBlendState() { + if (m_state.om.cbState != nullptr) { + EmitCs([ + cBlendState = m_state.om.cbState, + cSampleMask = m_state.om.sampleMask + ] (DxvkContext* ctx) { + cBlendState->BindToContext(ctx, cSampleMask); + }); + } else { + EmitCs([ + cSampleMask = m_state.om.sampleMask + ] (DxvkContext* ctx) { + DxvkBlendMode cbState; + DxvkLogicOpState loState; + DxvkMultisampleState msState; + InitDefaultBlendState(&cbState, &loState, &msState, cSampleMask); + + for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + ctx->setBlendMode(i, cbState); + + ctx->setLogicOpState(loState); + ctx->setMultisampleState(msState); + }); + } + } + + + template + void D3D11CommonContext::ApplyBlendFactor() { + EmitCs([ + cBlendConstants = DxvkBlendConstants { + m_state.om.blendFactor[0], m_state.om.blendFactor[1], + m_state.om.blendFactor[2], m_state.om.blendFactor[3] } + ] (DxvkContext* ctx) { + ctx->setBlendConstants(cBlendConstants); + }); + } + + + template + void D3D11CommonContext::ApplyDepthStencilState() { + if (m_state.om.dsState != nullptr) { + EmitCs([ + cDepthStencilState = m_state.om.dsState + ] (DxvkContext* ctx) { + cDepthStencilState->BindToContext(ctx); + }); + } else { + EmitCs([] (DxvkContext* ctx) { + DxvkDepthStencilState dsState; + InitDefaultDepthStencilState(&dsState); + + ctx->setDepthStencilState(dsState); + }); + } + } + + + template + void D3D11CommonContext::ApplyStencilRef() { + EmitCs([ + cStencilRef = m_state.om.stencilRef + ] (DxvkContext* ctx) { + ctx->setStencilReference(cStencilRef); + }); + } + + + template + void D3D11CommonContext::ApplyRasterizerState() { + if (m_state.rs.state != nullptr) { + EmitCs([ + cRasterizerState = m_state.rs.state + ] (DxvkContext* ctx) { + cRasterizerState->BindToContext(ctx); + }); + } else { + EmitCs([] (DxvkContext* ctx) { + DxvkRasterizerState rsState; + InitDefaultRasterizerState(&rsState); + + ctx->setRasterizerState(rsState); + }); + } + } + + + template + void D3D11CommonContext::ApplyRasterizerSampleCount() { + DxbcPushConstants pc; + pc.rasterizerSampleCount = m_state.om.sampleCount; + + if (unlikely(!m_state.om.sampleCount)) { + pc.rasterizerSampleCount = m_state.rs.state->Desc()->ForcedSampleCount; + + if (!m_state.om.sampleCount) + pc.rasterizerSampleCount = 1; + } + + EmitCs([ + cPushConstants = pc + ] (DxvkContext* ctx) { + ctx->pushConstants(0, sizeof(cPushConstants), &cPushConstants); + }); + } + + + template + void D3D11CommonContext::ApplyViewportState() { + std::array viewports; + std::array scissors; + + // The backend can't handle a viewport count of zero, + // so we should at least specify one empty viewport + uint32_t viewportCount = m_state.rs.numViewports; + + if (unlikely(!viewportCount)) { + viewportCount = 1; + viewports[0] = VkViewport(); + scissors [0] = VkRect2D(); + } + + // D3D11's coordinate system has its origin in the bottom left, + // but the viewport coordinates are aligned to the top-left + // corner so we can get away with flipping the viewport. + for (uint32_t i = 0; i < m_state.rs.numViewports; i++) { + const D3D11_VIEWPORT& vp = m_state.rs.viewports[i]; + + viewports[i] = VkViewport { + vp.TopLeftX, vp.Height + vp.TopLeftY, + vp.Width, -vp.Height, + vp.MinDepth, vp.MaxDepth, + }; + } + + // Scissor rectangles. Vulkan does not provide an easy way + // to disable the scissor test, so we'll have to set scissor + // rects that are at least as large as the framebuffer. + bool enableScissorTest = false; + + if (m_state.rs.state != nullptr) { + D3D11_RASTERIZER_DESC rsDesc; + m_state.rs.state->GetDesc(&rsDesc); + enableScissorTest = rsDesc.ScissorEnable; + } + + for (uint32_t i = 0; i < m_state.rs.numViewports; i++) { + if (!enableScissorTest) { + scissors[i] = VkRect2D { + VkOffset2D { 0, 0 }, + VkExtent2D { + D3D11_VIEWPORT_BOUNDS_MAX, + D3D11_VIEWPORT_BOUNDS_MAX } }; + } else if (i >= m_state.rs.numScissors) { + scissors[i] = VkRect2D { + VkOffset2D { 0, 0 }, + VkExtent2D { 0, 0 } }; + } else { + D3D11_RECT sr = m_state.rs.scissors[i]; + + VkOffset2D srPosA; + srPosA.x = std::max(0, sr.left); + srPosA.y = std::max(0, sr.top); + + VkOffset2D srPosB; + srPosB.x = std::max(srPosA.x, sr.right); + srPosB.y = std::max(srPosA.y, sr.bottom); + + VkExtent2D srSize; + srSize.width = uint32_t(srPosB.x - srPosA.x); + srSize.height = uint32_t(srPosB.y - srPosA.y); + + scissors[i] = VkRect2D { srPosA, srSize }; + } + } + + if (likely(viewportCount == 1)) { + EmitCs([ + cViewport = viewports[0], + cScissor = scissors[0] + ] (DxvkContext* ctx) { + ctx->setViewports(1, + &cViewport, + &cScissor); + }); + } else { + EmitCs([ + cViewportCount = viewportCount, + cViewports = viewports, + cScissors = scissors + ] (DxvkContext* ctx) { + ctx->setViewports( + cViewportCount, + cViewports.data(), + cScissors.data()); + }); + } + } + + template template void D3D11CommonContext::BindShader( diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 491475eaf..dea76d44e 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -620,6 +620,24 @@ namespace dxvk { D3D11DeviceContextExt m_contextExt; D3D11UserDefinedAnnotation m_annotation; + void ApplyInputLayout(); + + void ApplyPrimitiveTopology(); + + void ApplyBlendState(); + + void ApplyBlendFactor(); + + void ApplyDepthStencilState(); + + void ApplyStencilRef(); + + void ApplyRasterizerState(); + + void ApplyRasterizerSampleCount(); + + void ApplyViewportState(); + template void BindShader( const D3D11CommonShader* pShaderModule); From 1d87af062cebfcbaacabad4ba61aa8f6fa3cbf85 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 21:03:12 +0200 Subject: [PATCH 0393/1348] [d3d11] Move ResolveSubresource to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 116 ---------------------------- src/d3d11/d3d11_context.h | 7 -- src/d3d11/d3d11_context_common.cpp | 117 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 7 ++ 4 files changed, 124 insertions(+), 123 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 739840efe..9d91ba9c1 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -132,122 +132,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::ResolveSubresource( - ID3D11Resource* pDstResource, - UINT DstSubresource, - ID3D11Resource* pSrcResource, - UINT SrcSubresource, - DXGI_FORMAT Format) { - D3D10DeviceLock lock = LockContext(); - - bool isSameSubresource = pDstResource == pSrcResource - && DstSubresource == SrcSubresource; - - if (!pDstResource || !pSrcResource || isSameSubresource) - return; - - D3D11_RESOURCE_DIMENSION dstResourceType; - D3D11_RESOURCE_DIMENSION srcResourceType; - - pDstResource->GetType(&dstResourceType); - pSrcResource->GetType(&srcResourceType); - - if (dstResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D - || srcResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D) { - Logger::err(str::format( - "D3D11: ResolveSubresource: Incompatible resources", - "\n Dst resource type: ", dstResourceType, - "\n Src resource type: ", srcResourceType)); - return; - } - - auto dstTexture = static_cast(pDstResource); - auto srcTexture = static_cast(pSrcResource); - - D3D11_TEXTURE2D_DESC dstDesc; - D3D11_TEXTURE2D_DESC srcDesc; - - dstTexture->GetDesc(&dstDesc); - srcTexture->GetDesc(&srcDesc); - - if (dstDesc.SampleDesc.Count != 1) { - Logger::err(str::format( - "D3D11: ResolveSubresource: Invalid sample counts", - "\n Dst sample count: ", dstDesc.SampleDesc.Count, - "\n Src sample count: ", srcDesc.SampleDesc.Count)); - return; - } - - D3D11CommonTexture* dstTextureInfo = GetCommonTexture(pDstResource); - D3D11CommonTexture* srcTextureInfo = GetCommonTexture(pSrcResource); - - const DXGI_VK_FORMAT_INFO dstFormatInfo = m_parent->LookupFormat(dstDesc.Format, DXGI_VK_FORMAT_MODE_ANY); - const DXGI_VK_FORMAT_INFO srcFormatInfo = m_parent->LookupFormat(srcDesc.Format, DXGI_VK_FORMAT_MODE_ANY); - - auto dstVulkanFormatInfo = lookupFormatInfo(dstFormatInfo.Format); - auto srcVulkanFormatInfo = lookupFormatInfo(srcFormatInfo.Format); - - if (DstSubresource >= dstTextureInfo->CountSubresources() - || SrcSubresource >= srcTextureInfo->CountSubresources()) - return; - - const VkImageSubresource dstSubresource = - dstTextureInfo->GetSubresourceFromIndex( - dstVulkanFormatInfo->aspectMask, DstSubresource); - - const VkImageSubresource srcSubresource = - srcTextureInfo->GetSubresourceFromIndex( - srcVulkanFormatInfo->aspectMask, SrcSubresource); - - const VkImageSubresourceLayers dstSubresourceLayers = { - dstSubresource.aspectMask, - dstSubresource.mipLevel, - dstSubresource.arrayLayer, 1 }; - - const VkImageSubresourceLayers srcSubresourceLayers = { - srcSubresource.aspectMask, - srcSubresource.mipLevel, - srcSubresource.arrayLayer, 1 }; - - if (srcDesc.SampleDesc.Count == 1 || m_parent->GetOptions()->disableMsaa) { - EmitCs([ - cDstImage = dstTextureInfo->GetImage(), - cSrcImage = srcTextureInfo->GetImage(), - cDstLayers = dstSubresourceLayers, - cSrcLayers = srcSubresourceLayers - ] (DxvkContext* ctx) { - ctx->copyImage( - cDstImage, cDstLayers, VkOffset3D { 0, 0, 0 }, - cSrcImage, cSrcLayers, VkOffset3D { 0, 0, 0 }, - cDstImage->mipLevelExtent(cDstLayers.mipLevel)); - }); - } else { - const VkFormat format = m_parent->LookupFormat( - Format, DXGI_VK_FORMAT_MODE_ANY).Format; - - EmitCs([ - cDstImage = dstTextureInfo->GetImage(), - cSrcImage = srcTextureInfo->GetImage(), - cDstSubres = dstSubresourceLayers, - cSrcSubres = srcSubresourceLayers, - cFormat = format - ] (DxvkContext* ctx) { - VkImageResolve region; - region.srcSubresource = cSrcSubres; - region.srcOffset = VkOffset3D { 0, 0, 0 }; - region.dstSubresource = cDstSubres; - region.dstOffset = VkOffset3D { 0, 0, 0 }; - region.extent = cDstImage->mipLevelExtent(cDstSubres.mipLevel); - - ctx->resolveImage(cDstImage, cSrcImage, region, cFormat); - }); - } - - if (dstTextureInfo->HasSequenceNumber()) - TrackTextureSequenceNumber(dstTextureInfo, DstSubresource); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::DrawAuto() { D3D10DeviceLock lock = LockContext(); diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index b0c96be08..8612298c5 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -84,13 +84,6 @@ namespace dxvk { FLOAT STDMETHODCALLTYPE GetResourceMinLOD( ID3D11Resource* pResource); - void STDMETHODCALLTYPE ResolveSubresource( - ID3D11Resource* pDstResource, - UINT DstSubresource, - ID3D11Resource* pSrcResource, - UINT SrcSubresource, - DXGI_FORMAT Format); - void STDMETHODCALLTYPE DrawAuto(); void STDMETHODCALLTYPE Draw( diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index df8ec61be..2228df2a1 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -899,6 +899,123 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::ResolveSubresource( + ID3D11Resource* pDstResource, + UINT DstSubresource, + ID3D11Resource* pSrcResource, + UINT SrcSubresource, + DXGI_FORMAT Format) { + D3D10DeviceLock lock = LockContext(); + + bool isSameSubresource = pDstResource == pSrcResource + && DstSubresource == SrcSubresource; + + if (!pDstResource || !pSrcResource || isSameSubresource) + return; + + D3D11_RESOURCE_DIMENSION dstResourceType; + D3D11_RESOURCE_DIMENSION srcResourceType; + + pDstResource->GetType(&dstResourceType); + pSrcResource->GetType(&srcResourceType); + + if (dstResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D + || srcResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D) { + Logger::err(str::format( + "D3D11: ResolveSubresource: Incompatible resources", + "\n Dst resource type: ", dstResourceType, + "\n Src resource type: ", srcResourceType)); + return; + } + + auto dstTexture = static_cast(pDstResource); + auto srcTexture = static_cast(pSrcResource); + + D3D11_TEXTURE2D_DESC dstDesc; + D3D11_TEXTURE2D_DESC srcDesc; + + dstTexture->GetDesc(&dstDesc); + srcTexture->GetDesc(&srcDesc); + + if (dstDesc.SampleDesc.Count != 1) { + Logger::err(str::format( + "D3D11: ResolveSubresource: Invalid sample counts", + "\n Dst sample count: ", dstDesc.SampleDesc.Count, + "\n Src sample count: ", srcDesc.SampleDesc.Count)); + return; + } + + D3D11CommonTexture* dstTextureInfo = GetCommonTexture(pDstResource); + D3D11CommonTexture* srcTextureInfo = GetCommonTexture(pSrcResource); + + const DXGI_VK_FORMAT_INFO dstFormatInfo = m_parent->LookupFormat(dstDesc.Format, DXGI_VK_FORMAT_MODE_ANY); + const DXGI_VK_FORMAT_INFO srcFormatInfo = m_parent->LookupFormat(srcDesc.Format, DXGI_VK_FORMAT_MODE_ANY); + + auto dstVulkanFormatInfo = lookupFormatInfo(dstFormatInfo.Format); + auto srcVulkanFormatInfo = lookupFormatInfo(srcFormatInfo.Format); + + if (DstSubresource >= dstTextureInfo->CountSubresources() + || SrcSubresource >= srcTextureInfo->CountSubresources()) + return; + + const VkImageSubresource dstSubresource = + dstTextureInfo->GetSubresourceFromIndex( + dstVulkanFormatInfo->aspectMask, DstSubresource); + + const VkImageSubresource srcSubresource = + srcTextureInfo->GetSubresourceFromIndex( + srcVulkanFormatInfo->aspectMask, SrcSubresource); + + const VkImageSubresourceLayers dstSubresourceLayers = { + dstSubresource.aspectMask, + dstSubresource.mipLevel, + dstSubresource.arrayLayer, 1 }; + + const VkImageSubresourceLayers srcSubresourceLayers = { + srcSubresource.aspectMask, + srcSubresource.mipLevel, + srcSubresource.arrayLayer, 1 }; + + if (srcDesc.SampleDesc.Count == 1 || m_parent->GetOptions()->disableMsaa) { + EmitCs([ + cDstImage = dstTextureInfo->GetImage(), + cSrcImage = srcTextureInfo->GetImage(), + cDstLayers = dstSubresourceLayers, + cSrcLayers = srcSubresourceLayers + ] (DxvkContext* ctx) { + ctx->copyImage( + cDstImage, cDstLayers, VkOffset3D { 0, 0, 0 }, + cSrcImage, cSrcLayers, VkOffset3D { 0, 0, 0 }, + cDstImage->mipLevelExtent(cDstLayers.mipLevel)); + }); + } else { + const VkFormat format = m_parent->LookupFormat( + Format, DXGI_VK_FORMAT_MODE_ANY).Format; + + EmitCs([ + cDstImage = dstTextureInfo->GetImage(), + cSrcImage = srcTextureInfo->GetImage(), + cDstSubres = dstSubresourceLayers, + cSrcSubres = srcSubresourceLayers, + cFormat = format + ] (DxvkContext* ctx) { + VkImageResolve region; + region.srcSubresource = cSrcSubres; + region.srcOffset = VkOffset3D { 0, 0, 0 }; + region.dstSubresource = cDstSubres; + region.dstOffset = VkOffset3D { 0, 0, 0 }; + region.extent = cDstImage->mipLevelExtent(cDstSubres.mipLevel); + + ctx->resolveImage(cDstImage, cSrcImage, region, cFormat); + }); + } + + if (dstTextureInfo->HasSequenceNumber()) + TrackTextureSequenceNumber(dstTextureInfo, DstSubresource); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::UpdateSubresource( ID3D11Resource* pDstResource, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index dea76d44e..aab3cd37f 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -136,6 +136,13 @@ namespace dxvk { void STDMETHODCALLTYPE GenerateMips( ID3D11ShaderResourceView* pShaderResourceView); + void STDMETHODCALLTYPE ResolveSubresource( + ID3D11Resource* pDstResource, + UINT DstSubresource, + ID3D11Resource* pSrcResource, + UINT SrcSubresource, + DXGI_FORMAT Format); + void STDMETHODCALLTYPE UpdateSubresource( ID3D11Resource* pDstResource, UINT DstSubresource, From 9e916edef9abde50e42742c7bc2d72652c74af80 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 21:09:23 +0200 Subject: [PATCH 0394/1348] [d3d11] Move Draw* and Dispatch* methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 213 -------------- src/d3d11/d3d11_context.h | 49 ---- src/d3d11/d3d11_context_common.cpp | 431 +++++++++++++++++++++-------- src/d3d11/d3d11_context_common.h | 48 ++++ 4 files changed, 369 insertions(+), 372 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 9d91ba9c1..f9ff67cc6 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -132,191 +132,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::DrawAuto() { - D3D10DeviceLock lock = LockContext(); - - D3D11Buffer* buffer = m_state.ia.vertexBuffers[0].buffer.ptr(); - - if (buffer == nullptr) - return; - - DxvkBufferSlice vtxBuf = buffer->GetBufferSlice(); - DxvkBufferSlice ctrBuf = buffer->GetSOCounter(); - - if (!ctrBuf.defined()) - return; - - EmitCs([=] (DxvkContext* ctx) { - ctx->drawIndirectXfb(ctrBuf, - vtxBuf.buffer()->getXfbVertexStride(), - vtxBuf.offset()); - }); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::Draw( - UINT VertexCount, - UINT StartVertexLocation) { - D3D10DeviceLock lock = LockContext(); - - EmitCs([=] (DxvkContext* ctx) { - ctx->draw( - VertexCount, 1, - StartVertexLocation, 0); - }); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DrawIndexed( - UINT IndexCount, - UINT StartIndexLocation, - INT BaseVertexLocation) { - D3D10DeviceLock lock = LockContext(); - - EmitCs([=] (DxvkContext* ctx) { - ctx->drawIndexed( - IndexCount, 1, - StartIndexLocation, - BaseVertexLocation, 0); - }); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DrawInstanced( - UINT VertexCountPerInstance, - UINT InstanceCount, - UINT StartVertexLocation, - UINT StartInstanceLocation) { - D3D10DeviceLock lock = LockContext(); - - EmitCs([=] (DxvkContext* ctx) { - ctx->draw( - VertexCountPerInstance, - InstanceCount, - StartVertexLocation, - StartInstanceLocation); - }); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DrawIndexedInstanced( - UINT IndexCountPerInstance, - UINT InstanceCount, - UINT StartIndexLocation, - INT BaseVertexLocation, - UINT StartInstanceLocation) { - D3D10DeviceLock lock = LockContext(); - - EmitCs([=] (DxvkContext* ctx) { - ctx->drawIndexed( - IndexCountPerInstance, - InstanceCount, - StartIndexLocation, - BaseVertexLocation, - StartInstanceLocation); - }); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DrawIndexedInstancedIndirect( - ID3D11Buffer* pBufferForArgs, - UINT AlignedByteOffsetForArgs) { - D3D10DeviceLock lock = LockContext(); - SetDrawBuffers(pBufferForArgs, nullptr); - - if (!ValidateDrawBufferSize(pBufferForArgs, AlignedByteOffsetForArgs, sizeof(VkDrawIndexedIndirectCommand))) - return; - - // If possible, batch up multiple indirect draw calls of - // the same type into one single multiDrawIndirect call - auto cmdData = static_cast(m_cmdData); - auto stride = 0u; - - if (cmdData && cmdData->type == D3D11CmdType::DrawIndirectIndexed) - stride = GetIndirectCommandStride(cmdData, AlignedByteOffsetForArgs, sizeof(VkDrawIndexedIndirectCommand)); - - if (stride) { - cmdData->count += 1; - cmdData->stride = stride; - } else { - cmdData = EmitCsCmd( - [] (DxvkContext* ctx, const D3D11CmdDrawIndirectData* data) { - ctx->drawIndexedIndirect(data->offset, data->count, data->stride); - }); - - cmdData->type = D3D11CmdType::DrawIndirectIndexed; - cmdData->offset = AlignedByteOffsetForArgs; - cmdData->count = 1; - cmdData->stride = 0; - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DrawInstancedIndirect( - ID3D11Buffer* pBufferForArgs, - UINT AlignedByteOffsetForArgs) { - D3D10DeviceLock lock = LockContext(); - SetDrawBuffers(pBufferForArgs, nullptr); - - if (!ValidateDrawBufferSize(pBufferForArgs, AlignedByteOffsetForArgs, sizeof(VkDrawIndirectCommand))) - return; - - // If possible, batch up multiple indirect draw calls of - // the same type into one single multiDrawIndirect call - auto cmdData = static_cast(m_cmdData); - auto stride = 0u; - - if (cmdData && cmdData->type == D3D11CmdType::DrawIndirect) - stride = GetIndirectCommandStride(cmdData, AlignedByteOffsetForArgs, sizeof(VkDrawIndirectCommand)); - - if (stride) { - cmdData->count += 1; - cmdData->stride = stride; - } else { - cmdData = EmitCsCmd( - [] (DxvkContext* ctx, const D3D11CmdDrawIndirectData* data) { - ctx->drawIndirect(data->offset, data->count, data->stride); - }); - - cmdData->type = D3D11CmdType::DrawIndirect; - cmdData->offset = AlignedByteOffsetForArgs; - cmdData->count = 1; - cmdData->stride = 0; - } - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::Dispatch( - UINT ThreadGroupCountX, - UINT ThreadGroupCountY, - UINT ThreadGroupCountZ) { - D3D10DeviceLock lock = LockContext(); - - EmitCs([=] (DxvkContext* ctx) { - ctx->dispatch( - ThreadGroupCountX, - ThreadGroupCountY, - ThreadGroupCountZ); - }); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::DispatchIndirect( - ID3D11Buffer* pBufferForArgs, - UINT AlignedByteOffsetForArgs) { - D3D10DeviceLock lock = LockContext(); - SetDrawBuffers(pBufferForArgs, nullptr); - - if (!ValidateDrawBufferSize(pBufferForArgs, AlignedByteOffsetForArgs, sizeof(VkDispatchIndirectCommand))) - return; - - EmitCs([cOffset = AlignedByteOffsetForArgs] - (DxvkContext* ctx) { - ctx->dispatchIndirect(cOffset); - }); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::SetMarkerInt( LPCWSTR pLabel, INT Data) { @@ -386,34 +201,6 @@ namespace dxvk { } - void D3D11DeviceContext::BindDrawBuffers( - D3D11Buffer* pBufferForArgs, - D3D11Buffer* pBufferForCount) { - EmitCs([ - cArgBuffer = pBufferForArgs ? pBufferForArgs->GetBufferSlice() : DxvkBufferSlice(), - cCntBuffer = pBufferForCount ? pBufferForCount->GetBufferSlice() : DxvkBufferSlice() - ] (DxvkContext* ctx) { - ctx->bindDrawBuffers(cArgBuffer, cCntBuffer); - }); - } - - - void D3D11DeviceContext::SetDrawBuffers( - ID3D11Buffer* pBufferForArgs, - ID3D11Buffer* pBufferForCount) { - auto argBuffer = static_cast(pBufferForArgs); - auto cntBuffer = static_cast(pBufferForCount); - - if (m_state.id.argBuffer != argBuffer - || m_state.id.cntBuffer != cntBuffer) { - m_state.id.argBuffer = argBuffer; - m_state.id.cntBuffer = cntBuffer; - - BindDrawBuffers(argBuffer, cntBuffer); - } - } - - VkClearValue D3D11DeviceContext::ConvertColorValue( const FLOAT Color[4], const DxvkFormatInfo* pFormatInfo) { diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 8612298c5..34c613684 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -84,47 +84,6 @@ namespace dxvk { FLOAT STDMETHODCALLTYPE GetResourceMinLOD( ID3D11Resource* pResource); - void STDMETHODCALLTYPE DrawAuto(); - - void STDMETHODCALLTYPE Draw( - UINT VertexCount, - UINT StartVertexLocation); - - void STDMETHODCALLTYPE DrawIndexed( - UINT IndexCount, - UINT StartIndexLocation, - INT BaseVertexLocation); - - void STDMETHODCALLTYPE DrawInstanced( - UINT VertexCountPerInstance, - UINT InstanceCount, - UINT StartVertexLocation, - UINT StartInstanceLocation); - - void STDMETHODCALLTYPE DrawIndexedInstanced( - UINT IndexCountPerInstance, - UINT InstanceCount, - UINT StartIndexLocation, - INT BaseVertexLocation, - UINT StartInstanceLocation); - - void STDMETHODCALLTYPE DrawIndexedInstancedIndirect( - ID3D11Buffer* pBufferForArgs, - UINT AlignedByteOffsetForArgs); - - void STDMETHODCALLTYPE DrawInstancedIndirect( - ID3D11Buffer* pBufferForArgs, - UINT AlignedByteOffsetForArgs); - - void STDMETHODCALLTYPE Dispatch( - UINT ThreadGroupCountX, - UINT ThreadGroupCountY, - UINT ThreadGroupCountZ); - - void STDMETHODCALLTYPE DispatchIndirect( - ID3D11Buffer* pBufferForArgs, - UINT AlignedByteOffsetForArgs); - void STDMETHODCALLTYPE SetMarkerInt( LPCWSTR pLabel, INT Data); @@ -166,14 +125,6 @@ namespace dxvk { D3D11ContextState m_state; D3D11CmdData* m_cmdData; - void BindDrawBuffers( - D3D11Buffer* pBufferForArgs, - D3D11Buffer* pBufferForCount); - - void SetDrawBuffers( - ID3D11Buffer* pBufferForArgs, - ID3D11Buffer* pBufferForCount); - VkClearValue ConvertColorValue( const FLOAT Color[4], const DxvkFormatInfo* pFormatInfo); diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 2228df2a1..572731b8d 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -1043,6 +1043,200 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::DrawAuto() { + D3D10DeviceLock lock = LockContext(); + + D3D11Buffer* buffer = m_state.ia.vertexBuffers[0].buffer.ptr(); + + if (!buffer) + return; + + DxvkBufferSlice vtxBuf = buffer->GetBufferSlice(); + DxvkBufferSlice ctrBuf = buffer->GetSOCounter(); + + if (!ctrBuf.defined()) + return; + + EmitCs([=] (DxvkContext* ctx) { + ctx->drawIndirectXfb(ctrBuf, + vtxBuf.buffer()->getXfbVertexStride(), + vtxBuf.offset()); + }); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::Draw( + UINT VertexCount, + UINT StartVertexLocation) { + D3D10DeviceLock lock = LockContext(); + + EmitCs([=] (DxvkContext* ctx) { + ctx->draw( + VertexCount, 1, + StartVertexLocation, 0); + }); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DrawIndexed( + UINT IndexCount, + UINT StartIndexLocation, + INT BaseVertexLocation) { + D3D10DeviceLock lock = LockContext(); + + EmitCs([=] (DxvkContext* ctx) { + ctx->drawIndexed( + IndexCount, 1, + StartIndexLocation, + BaseVertexLocation, 0); + }); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DrawInstanced( + UINT VertexCountPerInstance, + UINT InstanceCount, + UINT StartVertexLocation, + UINT StartInstanceLocation) { + D3D10DeviceLock lock = LockContext(); + + EmitCs([=] (DxvkContext* ctx) { + ctx->draw( + VertexCountPerInstance, + InstanceCount, + StartVertexLocation, + StartInstanceLocation); + }); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DrawIndexedInstanced( + UINT IndexCountPerInstance, + UINT InstanceCount, + UINT StartIndexLocation, + INT BaseVertexLocation, + UINT StartInstanceLocation) { + D3D10DeviceLock lock = LockContext(); + + EmitCs([=] (DxvkContext* ctx) { + ctx->drawIndexed( + IndexCountPerInstance, + InstanceCount, + StartIndexLocation, + BaseVertexLocation, + StartInstanceLocation); + }); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DrawIndexedInstancedIndirect( + ID3D11Buffer* pBufferForArgs, + UINT AlignedByteOffsetForArgs) { + D3D10DeviceLock lock = LockContext(); + SetDrawBuffers(pBufferForArgs, nullptr); + + if (!ValidateDrawBufferSize(pBufferForArgs, AlignedByteOffsetForArgs, sizeof(VkDrawIndexedIndirectCommand))) + return; + + // If possible, batch up multiple indirect draw calls of + // the same type into one single multiDrawIndirect call + auto cmdData = static_cast(m_cmdData); + auto stride = 0u; + + if (cmdData && cmdData->type == D3D11CmdType::DrawIndirectIndexed) + stride = GetIndirectCommandStride(cmdData, AlignedByteOffsetForArgs, sizeof(VkDrawIndexedIndirectCommand)); + + if (stride) { + cmdData->count += 1; + cmdData->stride = stride; + } else { + cmdData = EmitCsCmd( + [] (DxvkContext* ctx, const D3D11CmdDrawIndirectData* data) { + ctx->drawIndexedIndirect(data->offset, data->count, data->stride); + }); + + cmdData->type = D3D11CmdType::DrawIndirectIndexed; + cmdData->offset = AlignedByteOffsetForArgs; + cmdData->count = 1; + cmdData->stride = 0; + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DrawInstancedIndirect( + ID3D11Buffer* pBufferForArgs, + UINT AlignedByteOffsetForArgs) { + D3D10DeviceLock lock = LockContext(); + SetDrawBuffers(pBufferForArgs, nullptr); + + if (!ValidateDrawBufferSize(pBufferForArgs, AlignedByteOffsetForArgs, sizeof(VkDrawIndirectCommand))) + return; + + // If possible, batch up multiple indirect draw calls of + // the same type into one single multiDrawIndirect call + auto cmdData = static_cast(m_cmdData); + auto stride = 0u; + + if (cmdData && cmdData->type == D3D11CmdType::DrawIndirect) + stride = GetIndirectCommandStride(cmdData, AlignedByteOffsetForArgs, sizeof(VkDrawIndirectCommand)); + + if (stride) { + cmdData->count += 1; + cmdData->stride = stride; + } else { + cmdData = EmitCsCmd( + [] (DxvkContext* ctx, const D3D11CmdDrawIndirectData* data) { + ctx->drawIndirect(data->offset, data->count, data->stride); + }); + + cmdData->type = D3D11CmdType::DrawIndirect; + cmdData->offset = AlignedByteOffsetForArgs; + cmdData->count = 1; + cmdData->stride = 0; + } + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::Dispatch( + UINT ThreadGroupCountX, + UINT ThreadGroupCountY, + UINT ThreadGroupCountZ) { + D3D10DeviceLock lock = LockContext(); + + EmitCs([=] (DxvkContext* ctx) { + ctx->dispatch( + ThreadGroupCountX, + ThreadGroupCountY, + ThreadGroupCountZ); + }); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::DispatchIndirect( + ID3D11Buffer* pBufferForArgs, + UINT AlignedByteOffsetForArgs) { + D3D10DeviceLock lock = LockContext(); + SetDrawBuffers(pBufferForArgs, nullptr); + + if (!ValidateDrawBufferSize(pBufferForArgs, AlignedByteOffsetForArgs, sizeof(VkDispatchIndirectCommand))) + return; + + EmitCs([cOffset = AlignedByteOffsetForArgs] + (DxvkContext* ctx) { + ctx->dispatchIndirect(cOffset); + }); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::IASetInputLayout(ID3D11InputLayout* pInputLayout) { D3D10DeviceLock lock = LockContext(); @@ -3704,6 +3898,123 @@ namespace dxvk { } + template + void D3D11CommonContext::RestoreState() { + BindFramebuffer(); + + BindShader (GetCommonShader(m_state.vs.shader.ptr())); + BindShader (GetCommonShader(m_state.hs.shader.ptr())); + BindShader (GetCommonShader(m_state.ds.shader.ptr())); + BindShader (GetCommonShader(m_state.gs.shader.ptr())); + BindShader (GetCommonShader(m_state.ps.shader.ptr())); + BindShader (GetCommonShader(m_state.cs.shader.ptr())); + + ApplyInputLayout(); + ApplyPrimitiveTopology(); + ApplyBlendState(); + ApplyBlendFactor(); + ApplyDepthStencilState(); + ApplyStencilRef(); + ApplyRasterizerState(); + ApplyRasterizerSampleCount(); + ApplyViewportState(); + + BindDrawBuffers( + m_state.id.argBuffer.ptr(), + m_state.id.cntBuffer.ptr()); + + BindIndexBuffer( + m_state.ia.indexBuffer.buffer.ptr(), + m_state.ia.indexBuffer.offset, + m_state.ia.indexBuffer.format); + + for (uint32_t i = 0; i < m_state.ia.vertexBuffers.size(); i++) { + BindVertexBuffer(i, + m_state.ia.vertexBuffers[i].buffer.ptr(), + m_state.ia.vertexBuffers[i].offset, + m_state.ia.vertexBuffers[i].stride); + } + + for (uint32_t i = 0; i < m_state.so.targets.size(); i++) + BindXfbBuffer(i, m_state.so.targets[i].buffer.ptr(), ~0u); + + RestoreConstantBuffers (m_state.vs.constantBuffers); + RestoreConstantBuffers (m_state.hs.constantBuffers); + RestoreConstantBuffers (m_state.ds.constantBuffers); + RestoreConstantBuffers (m_state.gs.constantBuffers); + RestoreConstantBuffers (m_state.ps.constantBuffers); + RestoreConstantBuffers (m_state.cs.constantBuffers); + + RestoreSamplers (m_state.vs.samplers); + RestoreSamplers (m_state.hs.samplers); + RestoreSamplers (m_state.ds.samplers); + RestoreSamplers(m_state.gs.samplers); + RestoreSamplers (m_state.ps.samplers); + RestoreSamplers (m_state.cs.samplers); + + RestoreShaderResources (m_state.vs.shaderResources); + RestoreShaderResources (m_state.hs.shaderResources); + RestoreShaderResources (m_state.ds.shaderResources); + RestoreShaderResources (m_state.gs.shaderResources); + RestoreShaderResources (m_state.ps.shaderResources); + RestoreShaderResources (m_state.cs.shaderResources); + + RestoreUnorderedAccessViews (m_state.ps.unorderedAccessViews); + RestoreUnorderedAccessViews (m_state.cs.unorderedAccessViews); + } + + + template + template + void D3D11CommonContext::RestoreConstantBuffers( + D3D11ConstantBufferBindings& Bindings) { + uint32_t slotId = computeConstantBufferBinding(Stage, 0); + + for (uint32_t i = 0; i < Bindings.size(); i++) { + BindConstantBuffer(slotId + i, Bindings[i].buffer.ptr(), + Bindings[i].constantOffset, Bindings[i].constantBound); + } + } + + + template + template + void D3D11CommonContext::RestoreSamplers( + D3D11SamplerBindings& Bindings) { + uint32_t slotId = computeSamplerBinding(Stage, 0); + + for (uint32_t i = 0; i < Bindings.size(); i++) + BindSampler(slotId + i, Bindings[i]); + } + + + template + template + void D3D11CommonContext::RestoreShaderResources( + D3D11ShaderResourceBindings& Bindings) { + uint32_t slotId = computeSrvBinding(Stage, 0); + + for (uint32_t i = 0; i < Bindings.views.size(); i++) + BindShaderResource(slotId + i, Bindings.views[i].ptr()); + } + + + template + template + void D3D11CommonContext::RestoreUnorderedAccessViews( + D3D11UnorderedAccessBindings& Bindings) { + uint32_t uavSlotId = computeUavBinding (Stage, 0); + uint32_t ctrSlotId = computeUavCounterBinding(Stage, 0); + + for (uint32_t i = 0; i < Bindings.size(); i++) { + BindUnorderedAccessView( + uavSlotId + i, + Bindings[i].ptr(), + ctrSlotId + i, ~0u); + } + } + + template template void D3D11CommonContext::SetConstantBuffers( @@ -3940,118 +4251,18 @@ namespace dxvk { template - void D3D11CommonContext::RestoreState() { - BindFramebuffer(); - - BindShader (GetCommonShader(m_state.vs.shader.ptr())); - BindShader (GetCommonShader(m_state.hs.shader.ptr())); - BindShader (GetCommonShader(m_state.ds.shader.ptr())); - BindShader (GetCommonShader(m_state.gs.shader.ptr())); - BindShader (GetCommonShader(m_state.ps.shader.ptr())); - BindShader (GetCommonShader(m_state.cs.shader.ptr())); - - ApplyInputLayout(); - ApplyPrimitiveTopology(); - ApplyBlendState(); - ApplyBlendFactor(); - ApplyDepthStencilState(); - ApplyStencilRef(); - ApplyRasterizerState(); - ApplyRasterizerSampleCount(); - ApplyViewportState(); + void D3D11CommonContext::SetDrawBuffers( + ID3D11Buffer* pBufferForArgs, + ID3D11Buffer* pBufferForCount) { + auto argBuffer = static_cast(pBufferForArgs); + auto cntBuffer = static_cast(pBufferForCount); - BindDrawBuffers( - m_state.id.argBuffer.ptr(), - m_state.id.cntBuffer.ptr()); - - BindIndexBuffer( - m_state.ia.indexBuffer.buffer.ptr(), - m_state.ia.indexBuffer.offset, - m_state.ia.indexBuffer.format); - - for (uint32_t i = 0; i < m_state.ia.vertexBuffers.size(); i++) { - BindVertexBuffer(i, - m_state.ia.vertexBuffers[i].buffer.ptr(), - m_state.ia.vertexBuffers[i].offset, - m_state.ia.vertexBuffers[i].stride); - } + if (m_state.id.argBuffer != argBuffer + || m_state.id.cntBuffer != cntBuffer) { + m_state.id.argBuffer = argBuffer; + m_state.id.cntBuffer = cntBuffer; - for (uint32_t i = 0; i < m_state.so.targets.size(); i++) - BindXfbBuffer(i, m_state.so.targets[i].buffer.ptr(), ~0u); - - RestoreConstantBuffers (m_state.vs.constantBuffers); - RestoreConstantBuffers (m_state.hs.constantBuffers); - RestoreConstantBuffers (m_state.ds.constantBuffers); - RestoreConstantBuffers (m_state.gs.constantBuffers); - RestoreConstantBuffers (m_state.ps.constantBuffers); - RestoreConstantBuffers (m_state.cs.constantBuffers); - - RestoreSamplers (m_state.vs.samplers); - RestoreSamplers (m_state.hs.samplers); - RestoreSamplers (m_state.ds.samplers); - RestoreSamplers(m_state.gs.samplers); - RestoreSamplers (m_state.ps.samplers); - RestoreSamplers (m_state.cs.samplers); - - RestoreShaderResources (m_state.vs.shaderResources); - RestoreShaderResources (m_state.hs.shaderResources); - RestoreShaderResources (m_state.ds.shaderResources); - RestoreShaderResources (m_state.gs.shaderResources); - RestoreShaderResources (m_state.ps.shaderResources); - RestoreShaderResources (m_state.cs.shaderResources); - - RestoreUnorderedAccessViews (m_state.ps.unorderedAccessViews); - RestoreUnorderedAccessViews (m_state.cs.unorderedAccessViews); - } - - - template - template - void D3D11CommonContext::RestoreConstantBuffers( - D3D11ConstantBufferBindings& Bindings) { - uint32_t slotId = computeConstantBufferBinding(Stage, 0); - - for (uint32_t i = 0; i < Bindings.size(); i++) { - BindConstantBuffer(slotId + i, Bindings[i].buffer.ptr(), - Bindings[i].constantOffset, Bindings[i].constantBound); - } - } - - - template - template - void D3D11CommonContext::RestoreSamplers( - D3D11SamplerBindings& Bindings) { - uint32_t slotId = computeSamplerBinding(Stage, 0); - - for (uint32_t i = 0; i < Bindings.size(); i++) - BindSampler(slotId + i, Bindings[i]); - } - - - template - template - void D3D11CommonContext::RestoreShaderResources( - D3D11ShaderResourceBindings& Bindings) { - uint32_t slotId = computeSrvBinding(Stage, 0); - - for (uint32_t i = 0; i < Bindings.views.size(); i++) - BindShaderResource(slotId + i, Bindings.views[i].ptr()); - } - - - template - template - void D3D11CommonContext::RestoreUnorderedAccessViews( - D3D11UnorderedAccessBindings& Bindings) { - uint32_t uavSlotId = computeUavBinding (Stage, 0); - uint32_t ctrSlotId = computeUavCounterBinding(Stage, 0); - - for (uint32_t i = 0; i < Bindings.size(); i++) { - BindUnorderedAccessView( - uavSlotId + i, - Bindings[i].ptr(), - ctrSlotId + i, ~0u); + BindDrawBuffers(argBuffer, cntBuffer); } } diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index aab3cd37f..12059a8c5 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -55,6 +55,9 @@ namespace dxvk { class D3D11CommonContext : public D3D11DeviceContext { constexpr static bool IsDeferred = std::is_same_v; using Forwarder = D3D11ContextObjectForwarder; + + template friend class D3D11DeviceContextExt; + template friend class D3D11UserDefinedAnnotation; public: D3D11CommonContext( @@ -160,6 +163,47 @@ namespace dxvk { UINT SrcDepthPitch, UINT CopyFlags); + void STDMETHODCALLTYPE DrawAuto(); + + void STDMETHODCALLTYPE Draw( + UINT VertexCount, + UINT StartVertexLocation); + + void STDMETHODCALLTYPE DrawIndexed( + UINT IndexCount, + UINT StartIndexLocation, + INT BaseVertexLocation); + + void STDMETHODCALLTYPE DrawInstanced( + UINT VertexCountPerInstance, + UINT InstanceCount, + UINT StartVertexLocation, + UINT StartInstanceLocation); + + void STDMETHODCALLTYPE DrawIndexedInstanced( + UINT IndexCountPerInstance, + UINT InstanceCount, + UINT StartIndexLocation, + INT BaseVertexLocation, + UINT StartInstanceLocation); + + void STDMETHODCALLTYPE DrawIndexedInstancedIndirect( + ID3D11Buffer* pBufferForArgs, + UINT AlignedByteOffsetForArgs); + + void STDMETHODCALLTYPE DrawInstancedIndirect( + ID3D11Buffer* pBufferForArgs, + UINT AlignedByteOffsetForArgs); + + void STDMETHODCALLTYPE Dispatch( + UINT ThreadGroupCountX, + UINT ThreadGroupCountY, + UINT ThreadGroupCountZ); + + void STDMETHODCALLTYPE DispatchIndirect( + ID3D11Buffer* pBufferForArgs, + UINT AlignedByteOffsetForArgs); + void STDMETHODCALLTYPE IASetInputLayout( ID3D11InputLayout* pInputLayout); @@ -822,6 +866,10 @@ namespace dxvk { ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts); + void SetDrawBuffers( + ID3D11Buffer* pBufferForArgs, + ID3D11Buffer* pBufferForCount); + bool TestRtvUavHazards( UINT NumRTVs, ID3D11RenderTargetView* const* ppRTVs, From e0ea272c0d9cbb82510b8e7b7f36a24a331210f0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 21:14:49 +0200 Subject: [PATCH 0395/1348] [d3d11] Move misc methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 171 -------------------------- src/d3d11/d3d11_context.h | 72 ----------- src/d3d11/d3d11_context_common.cpp | 185 +++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 72 +++++++++++ 4 files changed, 257 insertions(+), 243 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index f9ff67cc6..415516d73 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -30,177 +30,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::CopyTiles( - ID3D11Resource* pTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pTileRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE* pTileRegionSize, - ID3D11Buffer* pBuffer, - UINT64 BufferStartOffsetInBytes, - UINT Flags) { - static bool s_errorShown = false; - - if (!std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::CopyTiles: Not implemented"); - } - - - HRESULT STDMETHODCALLTYPE D3D11DeviceContext::CopyTileMappings( - ID3D11Resource* pDestTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pDestRegionStartCoordinate, - ID3D11Resource* pSourceTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE* pTileRegionSize, - UINT Flags) { - static bool s_errorShown = false; - - if (!std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::CopyTileMappings: Not implemented"); - - return DXGI_ERROR_INVALID_CALL; - } - - - HRESULT STDMETHODCALLTYPE D3D11DeviceContext::ResizeTilePool( - ID3D11Buffer* pTilePool, - UINT64 NewSizeInBytes) { - static bool s_errorShown = false; - - if (!std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::ResizeTilePool: Not implemented"); - - return DXGI_ERROR_INVALID_CALL; - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::TiledResourceBarrier( - ID3D11DeviceChild* pTiledResourceOrViewAccessBeforeBarrier, - ID3D11DeviceChild* pTiledResourceOrViewAccessAfterBarrier) { - - } - - - HRESULT STDMETHODCALLTYPE D3D11DeviceContext::UpdateTileMappings( - ID3D11Resource* pTiledResource, - UINT NumTiledResourceRegions, - const D3D11_TILED_RESOURCE_COORDINATE* pTiledResourceRegionStartCoordinates, - const D3D11_TILE_REGION_SIZE* pTiledResourceRegionSizes, - ID3D11Buffer* pTilePool, - UINT NumRanges, - const UINT* pRangeFlags, - const UINT* pTilePoolStartOffsets, - const UINT* pRangeTileCounts, - UINT Flags) { - bool s_errorShown = false; - - if (std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::UpdateTileMappings: Not implemented"); - - return DXGI_ERROR_INVALID_CALL; - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::UpdateTiles( - ID3D11Resource* pDestTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pDestTileRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE* pDestTileRegionSize, - const void* pSourceTileData, - UINT Flags) { - bool s_errorShown = false; - - if (std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::UpdateTiles: Not implemented"); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::SetResourceMinLOD( - ID3D11Resource* pResource, - FLOAT MinLOD) { - bool s_errorShown = false; - - if (std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::SetResourceMinLOD: Not implemented"); - } - - - FLOAT STDMETHODCALLTYPE D3D11DeviceContext::GetResourceMinLOD(ID3D11Resource* pResource) { - bool s_errorShown = false; - - if (std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::GetResourceMinLOD: Not implemented"); - - return 0.0f; - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::SetMarkerInt( - LPCWSTR pLabel, - INT Data) { - // Not implemented in the backend, ignore - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::BeginEventInt( - LPCWSTR pLabel, - INT Data) { - // Not implemented in the backend, ignore - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::EndEvent() { - // Not implemented in the backend, ignore - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::GetHardwareProtectionState( - BOOL* pHwProtectionEnable) { - static bool s_errorShown = false; - - if (!std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::GetHardwareProtectionState: Not implemented"); - - if (pHwProtectionEnable) - *pHwProtectionEnable = FALSE; - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::SetHardwareProtectionState( - BOOL HwProtectionEnable) { - static bool s_errorShown = false; - - if (!std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::SetHardwareProtectionState: Not implemented"); - } - - - void STDMETHODCALLTYPE D3D11DeviceContext::TransitionSurfaceLayout( - IDXGIVkInteropSurface* pSurface, - const VkImageSubresourceRange* pSubresources, - VkImageLayout OldLayout, - VkImageLayout NewLayout) { - D3D10DeviceLock lock = LockContext(); - - // Get the underlying D3D11 resource - Com resource; - - pSurface->QueryInterface(__uuidof(ID3D11Resource), - reinterpret_cast(&resource)); - - // Get the texture from that resource - D3D11CommonTexture* texture = GetCommonTexture(resource.ptr()); - - EmitCs([ - cImage = texture->GetImage(), - cSubresources = *pSubresources, - cOldLayout = OldLayout, - cNewLayout = NewLayout - ] (DxvkContext* ctx) { - ctx->transformImage( - cImage, cSubresources, - cOldLayout, cNewLayout); - }); - } - - VkClearValue D3D11DeviceContext::ConvertColorValue( const FLOAT Color[4], const DxvkFormatInfo* pFormatInfo) { diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 34c613684..82597415b 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -34,78 +34,6 @@ namespace dxvk { DxvkCsChunkFlags CsFlags); ~D3D11DeviceContext(); - void STDMETHODCALLTYPE CopyTiles( - ID3D11Resource* pTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pTileRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE* pTileRegionSize, - ID3D11Buffer* pBuffer, - UINT64 BufferStartOffsetInBytes, - UINT Flags); - - HRESULT STDMETHODCALLTYPE CopyTileMappings( - ID3D11Resource* pDestTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pDestRegionStartCoordinate, - ID3D11Resource* pSourceTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE* pTileRegionSize, - UINT Flags); - - HRESULT STDMETHODCALLTYPE ResizeTilePool( - ID3D11Buffer* pTilePool, - UINT64 NewSizeInBytes); - - void STDMETHODCALLTYPE TiledResourceBarrier( - ID3D11DeviceChild* pTiledResourceOrViewAccessBeforeBarrier, - ID3D11DeviceChild* pTiledResourceOrViewAccessAfterBarrier); - - HRESULT STDMETHODCALLTYPE UpdateTileMappings( - ID3D11Resource* pTiledResource, - UINT NumTiledResourceRegions, - const D3D11_TILED_RESOURCE_COORDINATE* pTiledResourceRegionStartCoordinates, - const D3D11_TILE_REGION_SIZE* pTiledResourceRegionSizes, - ID3D11Buffer* pTilePool, - UINT NumRanges, - const UINT* pRangeFlags, - const UINT* pTilePoolStartOffsets, - const UINT* pRangeTileCounts, - UINT Flags); - - void STDMETHODCALLTYPE UpdateTiles( - ID3D11Resource* pDestTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pDestTileRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE* pDestTileRegionSize, - const void* pSourceTileData, - UINT Flags); - - void STDMETHODCALLTYPE SetResourceMinLOD( - ID3D11Resource* pResource, - FLOAT MinLOD); - - FLOAT STDMETHODCALLTYPE GetResourceMinLOD( - ID3D11Resource* pResource); - - void STDMETHODCALLTYPE SetMarkerInt( - LPCWSTR pLabel, - INT Data); - - void STDMETHODCALLTYPE BeginEventInt( - LPCWSTR pLabel, - INT Data); - - void STDMETHODCALLTYPE EndEvent(); - - void STDMETHODCALLTYPE GetHardwareProtectionState( - BOOL* pHwProtectionEnable); - - void STDMETHODCALLTYPE SetHardwareProtectionState( - BOOL HwProtectionEnable); - - void STDMETHODCALLTYPE TransitionSurfaceLayout( - IDXGIVkInteropSurface* pSurface, - const VkImageSubresourceRange* pSubresources, - VkImageLayout OldLayout, - VkImageLayout NewLayout); - D3D10DeviceLock LockContext() { return m_multithread.AcquireLock(); } diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 572731b8d..23859d19f 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -2788,12 +2788,197 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::SetResourceMinLOD( + ID3D11Resource* pResource, + FLOAT MinLOD) { + bool s_errorShown = false; + + if (std::exchange(s_errorShown, true)) + Logger::err("D3D11DeviceContext::SetResourceMinLOD: Not implemented"); + } + + + template + FLOAT STDMETHODCALLTYPE D3D11CommonContext::GetResourceMinLOD(ID3D11Resource* pResource) { + bool s_errorShown = false; + + if (std::exchange(s_errorShown, true)) + Logger::err("D3D11DeviceContext::GetResourceMinLOD: Not implemented"); + + return 0.0f; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::CopyTiles( + ID3D11Resource* pTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE* pTileRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE* pTileRegionSize, + ID3D11Buffer* pBuffer, + UINT64 BufferStartOffsetInBytes, + UINT Flags) { + static bool s_errorShown = false; + + if (!std::exchange(s_errorShown, true)) + Logger::err("D3D11DeviceContext::CopyTiles: Not implemented"); + } + + + template + HRESULT STDMETHODCALLTYPE D3D11CommonContext::CopyTileMappings( + ID3D11Resource* pDestTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE* pDestRegionStartCoordinate, + ID3D11Resource* pSourceTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE* pTileRegionSize, + UINT Flags) { + static bool s_errorShown = false; + + if (!std::exchange(s_errorShown, true)) + Logger::err("D3D11DeviceContext::CopyTileMappings: Not implemented"); + + return DXGI_ERROR_INVALID_CALL; + } + + + template + HRESULT STDMETHODCALLTYPE D3D11CommonContext::ResizeTilePool( + ID3D11Buffer* pTilePool, + UINT64 NewSizeInBytes) { + static bool s_errorShown = false; + + if (!std::exchange(s_errorShown, true)) + Logger::err("D3D11DeviceContext::ResizeTilePool: Not implemented"); + + return DXGI_ERROR_INVALID_CALL; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::TiledResourceBarrier( + ID3D11DeviceChild* pTiledResourceOrViewAccessBeforeBarrier, + ID3D11DeviceChild* pTiledResourceOrViewAccessAfterBarrier) { + + } + + + template + HRESULT STDMETHODCALLTYPE D3D11CommonContext::UpdateTileMappings( + ID3D11Resource* pTiledResource, + UINT NumTiledResourceRegions, + const D3D11_TILED_RESOURCE_COORDINATE* pTiledResourceRegionStartCoordinates, + const D3D11_TILE_REGION_SIZE* pTiledResourceRegionSizes, + ID3D11Buffer* pTilePool, + UINT NumRanges, + const UINT* pRangeFlags, + const UINT* pTilePoolStartOffsets, + const UINT* pRangeTileCounts, + UINT Flags) { + bool s_errorShown = false; + + if (std::exchange(s_errorShown, true)) + Logger::err("D3D11DeviceContext::UpdateTileMappings: Not implemented"); + + return DXGI_ERROR_INVALID_CALL; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::UpdateTiles( + ID3D11Resource* pDestTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE* pDestTileRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE* pDestTileRegionSize, + const void* pSourceTileData, + UINT Flags) { + bool s_errorShown = false; + + if (std::exchange(s_errorShown, true)) + Logger::err("D3D11DeviceContext::UpdateTiles: Not implemented"); + } + + template BOOL STDMETHODCALLTYPE D3D11CommonContext::IsAnnotationEnabled() { return m_annotation.GetStatus(); } + template + void STDMETHODCALLTYPE D3D11CommonContext::SetMarkerInt( + LPCWSTR pLabel, + INT Data) { + // Not implemented in the backend, ignore + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::BeginEventInt( + LPCWSTR pLabel, + INT Data) { + // Not implemented in the backend, ignore + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::EndEvent() { + // Not implemented in the backend, ignore + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::GetHardwareProtectionState( + BOOL* pHwProtectionEnable) { + static bool s_errorShown = false; + + if (!std::exchange(s_errorShown, true)) + Logger::err("D3D11DeviceContext::GetHardwareProtectionState: Not implemented"); + + if (pHwProtectionEnable) + *pHwProtectionEnable = FALSE; + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::SetHardwareProtectionState( + BOOL HwProtectionEnable) { + static bool s_errorShown = false; + + if (!std::exchange(s_errorShown, true)) + Logger::err("D3D11DeviceContext::SetHardwareProtectionState: Not implemented"); + } + + + template + void STDMETHODCALLTYPE D3D11CommonContext::TransitionSurfaceLayout( + IDXGIVkInteropSurface* pSurface, + const VkImageSubresourceRange* pSubresources, + VkImageLayout OldLayout, + VkImageLayout NewLayout) { + D3D10DeviceLock lock = LockContext(); + + // Get the underlying D3D11 resource + Com resource; + + pSurface->QueryInterface(__uuidof(ID3D11Resource), + reinterpret_cast(&resource)); + + // Get the texture from that resource + D3D11CommonTexture* texture = GetCommonTexture(resource.ptr()); + + EmitCs([ + cImage = texture->GetImage(), + cSubresources = *pSubresources, + cOldLayout = OldLayout, + cNewLayout = NewLayout + ] (DxvkContext* ctx) { + ctx->transformImage( + cImage, cSubresources, + cOldLayout, cNewLayout); + }); + } + + template void D3D11CommonContext::ApplyInputLayout() { auto inputLayout = m_state.ia.inputLayout.prvRef(); diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 12059a8c5..b3fc49bbe 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -664,8 +664,80 @@ namespace dxvk { ID3D11Predicate** ppPredicate, BOOL* pPredicateValue); + void STDMETHODCALLTYPE SetResourceMinLOD( + ID3D11Resource* pResource, + FLOAT MinLOD); + + FLOAT STDMETHODCALLTYPE GetResourceMinLOD( + ID3D11Resource* pResource); + + void STDMETHODCALLTYPE CopyTiles( + ID3D11Resource* pTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE* pTileRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE* pTileRegionSize, + ID3D11Buffer* pBuffer, + UINT64 BufferStartOffsetInBytes, + UINT Flags); + + HRESULT STDMETHODCALLTYPE CopyTileMappings( + ID3D11Resource* pDestTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE* pDestRegionStartCoordinate, + ID3D11Resource* pSourceTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE* pTileRegionSize, + UINT Flags); + + HRESULT STDMETHODCALLTYPE ResizeTilePool( + ID3D11Buffer* pTilePool, + UINT64 NewSizeInBytes); + + void STDMETHODCALLTYPE TiledResourceBarrier( + ID3D11DeviceChild* pTiledResourceOrViewAccessBeforeBarrier, + ID3D11DeviceChild* pTiledResourceOrViewAccessAfterBarrier); + + HRESULT STDMETHODCALLTYPE UpdateTileMappings( + ID3D11Resource* pTiledResource, + UINT NumTiledResourceRegions, + const D3D11_TILED_RESOURCE_COORDINATE* pTiledResourceRegionStartCoordinates, + const D3D11_TILE_REGION_SIZE* pTiledResourceRegionSizes, + ID3D11Buffer* pTilePool, + UINT NumRanges, + const UINT* pRangeFlags, + const UINT* pTilePoolStartOffsets, + const UINT* pRangeTileCounts, + UINT Flags); + + void STDMETHODCALLTYPE UpdateTiles( + ID3D11Resource* pDestTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE* pDestTileRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE* pDestTileRegionSize, + const void* pSourceTileData, + UINT Flags); + BOOL STDMETHODCALLTYPE IsAnnotationEnabled(); + void STDMETHODCALLTYPE SetMarkerInt( + LPCWSTR pLabel, + INT Data); + + void STDMETHODCALLTYPE BeginEventInt( + LPCWSTR pLabel, + INT Data); + + void STDMETHODCALLTYPE EndEvent(); + + void STDMETHODCALLTYPE GetHardwareProtectionState( + BOOL* pHwProtectionEnable); + + void STDMETHODCALLTYPE SetHardwareProtectionState( + BOOL HwProtectionEnable); + + void STDMETHODCALLTYPE TransitionSurfaceLayout( + IDXGIVkInteropSurface* pSurface, + const VkImageSubresourceRange* pSubresources, + VkImageLayout OldLayout, + VkImageLayout NewLayout); + protected: D3D11DeviceContextExt m_contextExt; From 532b3a6add97f4421c61a38e7dfd456c474d1690 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 21:19:11 +0200 Subject: [PATCH 0396/1348] [d3d11] Move EmitCs and related methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 13 ++------ src/d3d11/d3d11_context.h | 48 +----------------------------- src/d3d11/d3d11_context_common.cpp | 13 ++++++-- src/d3d11/d3d11_context_common.h | 43 ++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 60 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 415516d73..d6de7fd6f 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -12,15 +12,11 @@ namespace dxvk { D3D11DeviceContext::D3D11DeviceContext( D3D11Device* pParent, - const Rc& Device, - DxvkCsChunkFlags CsFlags) + const Rc& Device) : D3D11DeviceChild(pParent), m_multithread(this, false), m_device (Device), - m_staging (Device, StagingBufferSize), - m_csFlags (CsFlags), - m_csChunk (AllocCsChunk()), - m_cmdData (nullptr) { + m_staging (Device, StagingBufferSize) { } @@ -86,11 +82,6 @@ namespace dxvk { } - DxvkCsChunkRef D3D11DeviceContext::AllocCsChunk() { - return m_parent->AllocCsChunk(m_csFlags); - } - - void D3D11DeviceContext::InitDefaultPrimitiveTopology( DxvkInputAssemblyState* pIaState) { pIaState->primitiveTopology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 82597415b..26562e7d1 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -30,8 +30,7 @@ namespace dxvk { D3D11DeviceContext( D3D11Device* pParent, - const Rc& Device, - DxvkCsChunkFlags CsFlags); + const Rc& Device); ~D3D11DeviceContext(); D3D10DeviceLock LockContext() { @@ -47,11 +46,7 @@ namespace dxvk { DxvkStagingBuffer m_staging; - DxvkCsChunkFlags m_csFlags; - DxvkCsChunkRef m_csChunk; - D3D11ContextState m_state; - D3D11CmdData* m_cmdData; VkClearValue ConvertColorValue( const FLOAT Color[4], @@ -64,8 +59,6 @@ namespace dxvk { void ResetStagingBuffer(); - DxvkCsChunkRef AllocCsChunk(); - static void InitDefaultPrimitiveTopology( DxvkInputAssemblyState* pIaState); @@ -103,48 +96,9 @@ namespace dxvk { return bufferSize >= Offset + Size; } - template - void EmitCs(Cmd&& command) { - m_cmdData = nullptr; - - if (unlikely(!m_csChunk->push(command))) { - EmitCsChunk(std::move(m_csChunk)); - - m_csChunk = AllocCsChunk(); - m_csChunk->push(command); - } - } - - template - M* EmitCsCmd(Cmd&& command, Args&&... args) { - M* data = m_csChunk->pushCmd( - command, std::forward(args)...); - - if (unlikely(!data)) { - EmitCsChunk(std::move(m_csChunk)); - - m_csChunk = AllocCsChunk(); - data = m_csChunk->pushCmd( - command, std::forward(args)...); - } - - m_cmdData = data; - return data; - } - - void FlushCsChunk() { - if (likely(!m_csChunk->empty())) { - EmitCsChunk(std::move(m_csChunk)); - m_csChunk = AllocCsChunk(); - m_cmdData = nullptr; - } - } - void TrackResourceSequenceNumber( ID3D11Resource* pResource); - virtual void EmitCsChunk(DxvkCsChunkRef&& chunk) = 0; - virtual void TrackTextureSequenceNumber( D3D11CommonTexture* pResource, UINT Subresource) = 0; diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 23859d19f..3ab01ae58 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -9,9 +9,12 @@ namespace dxvk { D3D11Device* pParent, const Rc& Device, DxvkCsChunkFlags CsFlags) - : D3D11DeviceContext(pParent, Device, CsFlags), + : D3D11DeviceContext(pParent, Device), m_contextExt(GetTypedContext()), - m_annotation(GetTypedContext(), Device) { + m_annotation(GetTypedContext(), Device), + m_csFlags (CsFlags), + m_csChunk (AllocCsChunk()), + m_cmdData (nullptr) { } @@ -2979,6 +2982,12 @@ namespace dxvk { } + template + DxvkCsChunkRef D3D11CommonContext::AllocCsChunk() { + return m_parent->AllocCsChunk(m_csFlags); + } + + template void D3D11CommonContext::ApplyInputLayout() { auto inputLayout = m_state.ia.inputLayout.prvRef(); diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index b3fc49bbe..ed39ed6f3 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -743,6 +743,12 @@ namespace dxvk { D3D11DeviceContextExt m_contextExt; D3D11UserDefinedAnnotation m_annotation; + DxvkCsChunkFlags m_csFlags; + DxvkCsChunkRef m_csChunk; + D3D11CmdData* m_cmdData; + + DxvkCsChunkRef AllocCsChunk(); + void ApplyInputLayout(); void ApplyPrimitiveTopology(); @@ -987,6 +993,43 @@ namespace dxvk { ID3D11RenderTargetView* const* ppRenderTargetViews, ID3D11DepthStencilView* pDepthStencilView); + template + void EmitCs(Cmd&& command) { + m_cmdData = nullptr; + + if (unlikely(!m_csChunk->push(command))) { + GetTypedContext()->EmitCsChunk(std::move(m_csChunk)); + + m_csChunk = AllocCsChunk(); + m_csChunk->push(command); + } + } + + template + M* EmitCsCmd(Cmd&& command, Args&&... args) { + M* data = m_csChunk->pushCmd( + command, std::forward(args)...); + + if (unlikely(!data)) { + GetTypedContext()->EmitCsChunk(std::move(m_csChunk)); + + m_csChunk = AllocCsChunk(); + data = m_csChunk->pushCmd( + command, std::forward(args)...); + } + + m_cmdData = data; + return data; + } + + void FlushCsChunk() { + if (likely(!m_csChunk->empty())) { + GetTypedContext()->EmitCsChunk(std::move(m_csChunk)); + m_csChunk = AllocCsChunk(); + m_cmdData = nullptr; + } + } + private: ContextType* GetTypedContext() { From 9a2d8878ef7e6793ddc89092161adbc7d9890860 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 21:21:11 +0200 Subject: [PATCH 0397/1348] [d3d11] Move Track*SequenceNumber methods to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 21 ----------------- src/d3d11/d3d11_context.h | 10 -------- src/d3d11/d3d11_context_common.cpp | 38 +++++++++++++++++++++++------- src/d3d11/d3d11_context_common.h | 3 +++ 4 files changed, 33 insertions(+), 39 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index d6de7fd6f..804e23386 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -144,25 +144,4 @@ namespace dxvk { pMsState->enableAlphaToCoverage = VK_FALSE; } - - void D3D11DeviceContext::TrackResourceSequenceNumber( - ID3D11Resource* pResource) { - if (!pResource) - return; - - D3D11CommonTexture* texture = GetCommonTexture(pResource); - - if (texture) { - if (texture->HasSequenceNumber()) { - for (uint32_t i = 0; i < texture->CountSubresources(); i++) - TrackTextureSequenceNumber(texture, i); - } - } else { - D3D11Buffer* buffer = static_cast(pResource); - - if (buffer->HasSequenceNumber()) - TrackBufferSequenceNumber(buffer); - } - } - } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 26562e7d1..a25755932 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -95,16 +95,6 @@ namespace dxvk { return bufferSize >= Offset + Size; } - - void TrackResourceSequenceNumber( - ID3D11Resource* pResource); - - virtual void TrackTextureSequenceNumber( - D3D11CommonTexture* pResource, - UINT Subresource) = 0; - - virtual void TrackBufferSequenceNumber( - D3D11Buffer* pResource) = 0; }; diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 3ab01ae58..1fcdbb1ac 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -451,7 +451,7 @@ namespace dxvk { }); if (buf->HasSequenceNumber()) - TrackBufferSequenceNumber(buf); + GetTypedContext()->TrackBufferSequenceNumber(buf); } @@ -1015,7 +1015,7 @@ namespace dxvk { } if (dstTextureInfo->HasSequenceNumber()) - TrackTextureSequenceNumber(dstTextureInfo, DstSubresource); + GetTypedContext()->TrackTextureSequenceNumber(dstTextureInfo, DstSubresource); } @@ -3545,9 +3545,9 @@ namespace dxvk { }); if (pDstBuffer->HasSequenceNumber()) - TrackBufferSequenceNumber(pDstBuffer); + GetTypedContext()->TrackBufferSequenceNumber(pDstBuffer); if (pSrcBuffer->HasSequenceNumber()) - TrackBufferSequenceNumber(pSrcBuffer); + GetTypedContext()->TrackBufferSequenceNumber(pSrcBuffer); } @@ -3786,14 +3786,14 @@ namespace dxvk { if (pDstTexture->HasSequenceNumber()) { for (uint32_t i = 0; i < pDstLayers->layerCount; i++) { - TrackTextureSequenceNumber(pDstTexture, D3D11CalcSubresource( + GetTypedContext()->TrackTextureSequenceNumber(pDstTexture, D3D11CalcSubresource( pDstLayers->mipLevel, pDstLayers->baseArrayLayer + i, pDstTexture->Desc()->MipLevels)); } } if (pSrcTexture->HasSequenceNumber()) { for (uint32_t i = 0; i < pSrcLayers->layerCount; i++) { - TrackTextureSequenceNumber(pSrcTexture, D3D11CalcSubresource( + GetTypedContext()->TrackTextureSequenceNumber(pSrcTexture, D3D11CalcSubresource( pSrcLayers->mipLevel, pSrcLayers->baseArrayLayer + i, pSrcTexture->Desc()->MipLevels)); } } @@ -4532,6 +4532,28 @@ namespace dxvk { } + template + void D3D11CommonContext::TrackResourceSequenceNumber( + ID3D11Resource* pResource) { + if (!pResource) + return; + + D3D11CommonTexture* texture = GetCommonTexture(pResource); + + if (texture) { + if (texture->HasSequenceNumber()) { + for (uint32_t i = 0; i < texture->CountSubresources(); i++) + GetTypedContext()->TrackTextureSequenceNumber(texture, i); + } + } else { + D3D11Buffer* buffer = static_cast(pResource); + + if (buffer->HasSequenceNumber()) + GetTypedContext()->TrackBufferSequenceNumber(buffer); + } + } + + template void D3D11CommonContext::UpdateBuffer( D3D11Buffer* pDstBuffer, @@ -4576,7 +4598,7 @@ namespace dxvk { } if (pDstBuffer->HasSequenceNumber()) - TrackBufferSequenceNumber(pDstBuffer); + GetTypedContext()->TrackBufferSequenceNumber(pDstBuffer); } @@ -4726,7 +4748,7 @@ namespace dxvk { } if (pDstTexture->HasSequenceNumber()) - TrackTextureSequenceNumber(pDstTexture, dstSubresource); + GetTypedContext()->TrackTextureSequenceNumber(pDstTexture, dstSubresource); } diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index ed39ed6f3..442f17c35 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -958,6 +958,9 @@ namespace dxvk { bool TestSrvHazards( D3D11ShaderResourceView* pView); + void TrackResourceSequenceNumber( + ID3D11Resource* pResource); + void UpdateBuffer( D3D11Buffer* pDstBuffer, UINT Offset, From b20bfe763efcbad927d8bbf42ac85623dac371b2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 21:24:06 +0200 Subject: [PATCH 0398/1348] [d3d11] Move D3D10Multithread instance to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 1 - src/d3d11/d3d11_context.h | 11 +++-------- src/d3d11/d3d11_context_common.cpp | 1 + src/d3d11/d3d11_context_common.h | 5 +++++ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 804e23386..08a505d47 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -14,7 +14,6 @@ namespace dxvk { D3D11Device* pParent, const Rc& Device) : D3D11DeviceChild(pParent), - m_multithread(this, false), m_device (Device), m_staging (Device, StagingBufferSize) { diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index a25755932..a67b225ad 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -27,27 +27,22 @@ namespace dxvk { constexpr static VkDeviceSize StagingBufferSize = 4ull << 20; public: - + D3D11DeviceContext( D3D11Device* pParent, const Rc& Device); + ~D3D11DeviceContext(); - - D3D10DeviceLock LockContext() { - return m_multithread.AcquireLock(); - } protected: - D3D10Multithread m_multithread; - Rc m_device; Rc m_updateBuffer; DxvkStagingBuffer m_staging; D3D11ContextState m_state; - + VkClearValue ConvertColorValue( const FLOAT Color[4], const DxvkFormatInfo* pFormatInfo); diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 1fcdbb1ac..724616283 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -12,6 +12,7 @@ namespace dxvk { : D3D11DeviceContext(pParent, Device), m_contextExt(GetTypedContext()), m_annotation(GetTypedContext(), Device), + m_multithread(this, false), m_csFlags (CsFlags), m_csChunk (AllocCsChunk()), m_cmdData (nullptr) { diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 442f17c35..be33d5952 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -738,10 +738,15 @@ namespace dxvk { VkImageLayout OldLayout, VkImageLayout NewLayout); + D3D10DeviceLock LockContext() { + return m_multithread.AcquireLock(); + } + protected: D3D11DeviceContextExt m_contextExt; D3D11UserDefinedAnnotation m_annotation; + D3D10Multithread m_multithread; DxvkCsChunkFlags m_csFlags; DxvkCsChunkRef m_csChunk; From a3ed84c0c1175f3c4e5597d9eb725a1fa385a78a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 21:29:06 +0200 Subject: [PATCH 0399/1348] [d3d11] Move remaining D3D11DeviceContext members to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 40 ++-------------------------- src/d3d11/d3d11_context.h | 23 +--------------- src/d3d11/d3d11_context_common.cpp | 42 ++++++++++++++++++++++++++++-- src/d3d11/d3d11_context_common.h | 16 ++++++++++++ 4 files changed, 59 insertions(+), 62 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 08a505d47..e8a04fb3d 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -11,11 +11,8 @@ namespace dxvk { D3D11DeviceContext::D3D11DeviceContext( - D3D11Device* pParent, - const Rc& Device) - : D3D11DeviceChild(pParent), - m_device (Device), - m_staging (Device, StagingBufferSize) { + D3D11Device* pParent) + : D3D11DeviceChild(pParent) { } @@ -48,39 +45,6 @@ namespace dxvk { } - DxvkDataSlice D3D11DeviceContext::AllocUpdateBufferSlice(size_t Size) { - constexpr size_t UpdateBufferSize = 1 * 1024 * 1024; - - if (Size >= UpdateBufferSize) { - Rc buffer = new DxvkDataBuffer(Size); - return buffer->alloc(Size); - } else { - if (m_updateBuffer == nullptr) - m_updateBuffer = new DxvkDataBuffer(UpdateBufferSize); - - DxvkDataSlice slice = m_updateBuffer->alloc(Size); - - if (slice.ptr() == nullptr) { - m_updateBuffer = new DxvkDataBuffer(UpdateBufferSize); - slice = m_updateBuffer->alloc(Size); - } - - return slice; - } - } - - - DxvkBufferSlice D3D11DeviceContext::AllocStagingBuffer( - VkDeviceSize Size) { - return m_staging.alloc(256, Size); - } - - - void D3D11DeviceContext::ResetStagingBuffer() { - m_staging.reset(); - } - - void D3D11DeviceContext::InitDefaultPrimitiveTopology( DxvkInputAssemblyState* pIaState) { pIaState->primitiveTopology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index a67b225ad..edf6f877e 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -19,41 +19,20 @@ namespace dxvk { class D3D11Device; class D3D11DeviceContext : public D3D11DeviceChild { - template - friend class D3D11DeviceContextExt; - // Needed in order to call EmitCs for pushing markers - template - friend class D3D11UserDefinedAnnotation; - constexpr static VkDeviceSize StagingBufferSize = 4ull << 20; public: D3D11DeviceContext( - D3D11Device* pParent, - const Rc& Device); + D3D11Device* pParent); ~D3D11DeviceContext(); protected: - Rc m_device; - Rc m_updateBuffer; - - DxvkStagingBuffer m_staging; - - D3D11ContextState m_state; - VkClearValue ConvertColorValue( const FLOAT Color[4], const DxvkFormatInfo* pFormatInfo); - DxvkDataSlice AllocUpdateBufferSlice(size_t Size); - - DxvkBufferSlice AllocStagingBuffer( - VkDeviceSize Size); - - void ResetStagingBuffer(); - static void InitDefaultPrimitiveTopology( DxvkInputAssemblyState* pIaState); diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index 724616283..e6ae7410a 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -9,10 +9,12 @@ namespace dxvk { D3D11Device* pParent, const Rc& Device, DxvkCsChunkFlags CsFlags) - : D3D11DeviceContext(pParent, Device), + : D3D11DeviceContext(pParent), m_contextExt(GetTypedContext()), m_annotation(GetTypedContext(), Device), m_multithread(this, false), + m_device (Device), + m_staging (Device, StagingBufferSize), m_csFlags (CsFlags), m_csChunk (AllocCsChunk()), m_cmdData (nullptr) { @@ -2987,7 +2989,37 @@ namespace dxvk { DxvkCsChunkRef D3D11CommonContext::AllocCsChunk() { return m_parent->AllocCsChunk(m_csFlags); } - + + + template + DxvkDataSlice D3D11CommonContext::AllocUpdateBufferSlice(size_t Size) { + constexpr size_t UpdateBufferSize = 1 * 1024 * 1024; + + if (Size >= UpdateBufferSize) { + Rc buffer = new DxvkDataBuffer(Size); + return buffer->alloc(Size); + } else { + if (m_updateBuffer == nullptr) + m_updateBuffer = new DxvkDataBuffer(UpdateBufferSize); + + DxvkDataSlice slice = m_updateBuffer->alloc(Size); + + if (slice.ptr() == nullptr) { + m_updateBuffer = new DxvkDataBuffer(UpdateBufferSize); + slice = m_updateBuffer->alloc(Size); + } + + return slice; + } + } + + + template + DxvkBufferSlice D3D11CommonContext::AllocStagingBuffer( + VkDeviceSize Size) { + return m_staging.alloc(256, Size); + } + template void D3D11CommonContext::ApplyInputLayout() { @@ -3890,6 +3922,12 @@ namespace dxvk { } + template + void D3D11CommonContext::ResetStagingBuffer() { + m_staging.reset(); + } + + template void D3D11CommonContext::ResetState() { EmitCs([] (DxvkContext* ctx) { diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index be33d5952..1e8e98300 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -58,6 +58,8 @@ namespace dxvk { template friend class D3D11DeviceContextExt; template friend class D3D11UserDefinedAnnotation; + + constexpr static VkDeviceSize StagingBufferSize = 4ull << 20; public: D3D11CommonContext( @@ -748,12 +750,24 @@ namespace dxvk { D3D11UserDefinedAnnotation m_annotation; D3D10Multithread m_multithread; + Rc m_device; + + D3D11ContextState m_state; + + DxvkStagingBuffer m_staging; + Rc m_updateBuffer; + DxvkCsChunkFlags m_csFlags; DxvkCsChunkRef m_csChunk; D3D11CmdData* m_cmdData; DxvkCsChunkRef AllocCsChunk(); + DxvkDataSlice AllocUpdateBufferSlice(size_t Size); + + DxvkBufferSlice AllocStagingBuffer( + VkDeviceSize Size); + void ApplyInputLayout(); void ApplyPrimitiveTopology(); @@ -871,6 +885,8 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); + void ResetStagingBuffer(); + void ResetState(); template From 20df9fc899fe246677a02ce99ebf9d5384673b2e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 21:32:28 +0200 Subject: [PATCH 0400/1348] [d3d11] Move all remaining context code to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 86 ---------------------------- src/d3d11/d3d11_context.h | 43 -------------- src/d3d11/d3d11_context_common.cpp | 90 ++++++++++++++++++++++++++++++ src/d3d11/d3d11_context_common.h | 41 ++++++++++++++ 4 files changed, 131 insertions(+), 129 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index e8a04fb3d..4e13dca8d 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -21,90 +21,4 @@ namespace dxvk { } - - VkClearValue D3D11DeviceContext::ConvertColorValue( - const FLOAT Color[4], - const DxvkFormatInfo* pFormatInfo) { - VkClearValue result; - - if (pFormatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { - for (uint32_t i = 0; i < 4; i++) { - if (pFormatInfo->flags.test(DxvkFormatFlag::SampledUInt)) - result.color.uint32[i] = uint32_t(std::max(0.0f, Color[i])); - else if (pFormatInfo->flags.test(DxvkFormatFlag::SampledSInt)) - result.color.int32[i] = int32_t(Color[i]); - else - result.color.float32[i] = Color[i]; - } - } else { - result.depthStencil.depth = Color[0]; - result.depthStencil.stencil = 0; - } - - return result; - } - - - void D3D11DeviceContext::InitDefaultPrimitiveTopology( - DxvkInputAssemblyState* pIaState) { - pIaState->primitiveTopology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; - pIaState->primitiveRestart = VK_FALSE; - pIaState->patchVertexCount = 0; - } - - - void D3D11DeviceContext::InitDefaultRasterizerState( - DxvkRasterizerState* pRsState) { - pRsState->polygonMode = VK_POLYGON_MODE_FILL; - pRsState->cullMode = VK_CULL_MODE_BACK_BIT; - pRsState->frontFace = VK_FRONT_FACE_CLOCKWISE; - pRsState->depthClipEnable = VK_TRUE; - pRsState->depthBiasEnable = VK_FALSE; - pRsState->conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT; - pRsState->sampleCount = 0; - } - - - void D3D11DeviceContext::InitDefaultDepthStencilState( - DxvkDepthStencilState* pDsState) { - VkStencilOpState stencilOp; - stencilOp.failOp = VK_STENCIL_OP_KEEP; - stencilOp.passOp = VK_STENCIL_OP_KEEP; - stencilOp.depthFailOp = VK_STENCIL_OP_KEEP; - stencilOp.compareOp = VK_COMPARE_OP_ALWAYS; - stencilOp.compareMask = D3D11_DEFAULT_STENCIL_READ_MASK; - stencilOp.writeMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; - stencilOp.reference = 0; - - pDsState->enableDepthTest = VK_TRUE; - pDsState->enableDepthWrite = VK_TRUE; - pDsState->enableStencilTest = VK_FALSE; - pDsState->depthCompareOp = VK_COMPARE_OP_LESS; - pDsState->stencilOpFront = stencilOp; - pDsState->stencilOpBack = stencilOp; - } - - - void D3D11DeviceContext::InitDefaultBlendState( - DxvkBlendMode* pCbState, - DxvkLogicOpState* pLoState, - DxvkMultisampleState* pMsState, - UINT SampleMask) { - pCbState->enableBlending = VK_FALSE; - pCbState->colorSrcFactor = VK_BLEND_FACTOR_ONE; - pCbState->colorDstFactor = VK_BLEND_FACTOR_ZERO; - pCbState->colorBlendOp = VK_BLEND_OP_ADD; - pCbState->alphaSrcFactor = VK_BLEND_FACTOR_ONE; - pCbState->alphaDstFactor = VK_BLEND_FACTOR_ZERO; - pCbState->alphaBlendOp = VK_BLEND_OP_ADD; - pCbState->writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT - | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - - pLoState->enableLogicOp = VK_FALSE; - pLoState->logicOp = VK_LOGIC_OP_NO_OP; - - pMsState->sampleMask = SampleMask; - pMsState->enableAlphaToCoverage = VK_FALSE; - } - } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index edf6f877e..f884ac398 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -27,49 +27,6 @@ namespace dxvk { ~D3D11DeviceContext(); - protected: - - VkClearValue ConvertColorValue( - const FLOAT Color[4], - const DxvkFormatInfo* pFormatInfo); - - static void InitDefaultPrimitiveTopology( - DxvkInputAssemblyState* pIaState); - - static void InitDefaultRasterizerState( - DxvkRasterizerState* pRsState); - - static void InitDefaultDepthStencilState( - DxvkDepthStencilState* pDsState); - - static void InitDefaultBlendState( - DxvkBlendMode* pCbState, - DxvkLogicOpState* pLoState, - DxvkMultisampleState* pMsState, - UINT SampleMask); - - template - const D3D11CommonShader* GetCommonShader(T* pShader) const { - return pShader != nullptr ? pShader->GetCommonShader() : nullptr; - } - - static uint32_t GetIndirectCommandStride(const D3D11CmdDrawIndirectData* cmdData, uint32_t offset, uint32_t minStride) { - if (likely(cmdData->stride)) - return cmdData->offset + cmdData->count * cmdData->stride == offset ? cmdData->stride : 0; - - uint32_t stride = offset - cmdData->offset; - return stride >= minStride && stride <= 32 ? stride : 0; - } - - static bool ValidateDrawBufferSize(ID3D11Buffer* pBuffer, UINT Offset, UINT Size) { - UINT bufferSize = 0; - - if (likely(pBuffer != nullptr)) - bufferSize = static_cast(pBuffer)->Desc()->ByteWidth; - - return bufferSize >= Offset + Size; - } - }; } diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index e6ae7410a..b4797c0e7 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -3540,6 +3540,30 @@ namespace dxvk { } + template + VkClearValue D3D11CommonContext::ConvertColorValue( + const FLOAT Color[4], + const DxvkFormatInfo* pFormatInfo) { + VkClearValue result; + + if (pFormatInfo->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) { + for (uint32_t i = 0; i < 4; i++) { + if (pFormatInfo->flags.test(DxvkFormatFlag::SampledUInt)) + result.color.uint32[i] = uint32_t(std::max(0.0f, Color[i])); + else if (pFormatInfo->flags.test(DxvkFormatFlag::SampledSInt)) + result.color.int32[i] = int32_t(Color[i]); + else + result.color.float32[i] = Color[i]; + } + } else { + result.depthStencil.depth = Color[0]; + result.depthStencil.stencil = 0; + } + + return result; + } + + template void D3D11CommonContext::CopyBuffer( D3D11Buffer* pDstBuffer, @@ -4916,6 +4940,72 @@ namespace dxvk { } + template + void D3D11CommonContext::InitDefaultPrimitiveTopology( + DxvkInputAssemblyState* pIaState) { + pIaState->primitiveTopology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; + pIaState->primitiveRestart = VK_FALSE; + pIaState->patchVertexCount = 0; + } + + + template + void D3D11CommonContext::InitDefaultRasterizerState( + DxvkRasterizerState* pRsState) { + pRsState->polygonMode = VK_POLYGON_MODE_FILL; + pRsState->cullMode = VK_CULL_MODE_BACK_BIT; + pRsState->frontFace = VK_FRONT_FACE_CLOCKWISE; + pRsState->depthClipEnable = VK_TRUE; + pRsState->depthBiasEnable = VK_FALSE; + pRsState->conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT; + pRsState->sampleCount = 0; + } + + + template + void D3D11CommonContext::InitDefaultDepthStencilState( + DxvkDepthStencilState* pDsState) { + VkStencilOpState stencilOp; + stencilOp.failOp = VK_STENCIL_OP_KEEP; + stencilOp.passOp = VK_STENCIL_OP_KEEP; + stencilOp.depthFailOp = VK_STENCIL_OP_KEEP; + stencilOp.compareOp = VK_COMPARE_OP_ALWAYS; + stencilOp.compareMask = D3D11_DEFAULT_STENCIL_READ_MASK; + stencilOp.writeMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + stencilOp.reference = 0; + + pDsState->enableDepthTest = VK_TRUE; + pDsState->enableDepthWrite = VK_TRUE; + pDsState->enableStencilTest = VK_FALSE; + pDsState->depthCompareOp = VK_COMPARE_OP_LESS; + pDsState->stencilOpFront = stencilOp; + pDsState->stencilOpBack = stencilOp; + } + + + template + void D3D11CommonContext::InitDefaultBlendState( + DxvkBlendMode* pCbState, + DxvkLogicOpState* pLoState, + DxvkMultisampleState* pMsState, + UINT SampleMask) { + pCbState->enableBlending = VK_FALSE; + pCbState->colorSrcFactor = VK_BLEND_FACTOR_ONE; + pCbState->colorDstFactor = VK_BLEND_FACTOR_ZERO; + pCbState->colorBlendOp = VK_BLEND_OP_ADD; + pCbState->alphaSrcFactor = VK_BLEND_FACTOR_ONE; + pCbState->alphaDstFactor = VK_BLEND_FACTOR_ZERO; + pCbState->alphaBlendOp = VK_BLEND_OP_ADD; + pCbState->writeMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT + | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + + pLoState->enableLogicOp = VK_FALSE; + pLoState->logicOp = VK_LOGIC_OP_NO_OP; + + pMsState->sampleMask = SampleMask; + pMsState->enableAlphaToCoverage = VK_FALSE; + } + // Explicitly instantiate here template class D3D11CommonContext; template class D3D11CommonContext; diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 1e8e98300..5e6a0488d 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -842,6 +842,10 @@ namespace dxvk { UINT CtrSlot, UINT Counter); + VkClearValue ConvertColorValue( + const FLOAT Color[4], + const DxvkFormatInfo* pFormatInfo); + void CopyBuffer( D3D11Buffer* pDstBuffer, VkDeviceSize DstOffset, @@ -1017,6 +1021,21 @@ namespace dxvk { ID3D11RenderTargetView* const* ppRenderTargetViews, ID3D11DepthStencilView* pDepthStencilView); + static void InitDefaultPrimitiveTopology( + DxvkInputAssemblyState* pIaState); + + static void InitDefaultRasterizerState( + DxvkRasterizerState* pRsState); + + static void InitDefaultDepthStencilState( + DxvkDepthStencilState* pDsState); + + static void InitDefaultBlendState( + DxvkBlendMode* pCbState, + DxvkLogicOpState* pLoState, + DxvkMultisampleState* pMsState, + UINT SampleMask); + template void EmitCs(Cmd&& command) { m_cmdData = nullptr; @@ -1054,6 +1073,28 @@ namespace dxvk { } } + template + const D3D11CommonShader* GetCommonShader(T* pShader) const { + return pShader != nullptr ? pShader->GetCommonShader() : nullptr; + } + + static uint32_t GetIndirectCommandStride(const D3D11CmdDrawIndirectData* cmdData, uint32_t offset, uint32_t minStride) { + if (likely(cmdData->stride)) + return cmdData->offset + cmdData->count * cmdData->stride == offset ? cmdData->stride : 0; + + uint32_t stride = offset - cmdData->offset; + return stride >= minStride && stride <= 32 ? stride : 0; + } + + static bool ValidateDrawBufferSize(ID3D11Buffer* pBuffer, UINT Offset, UINT Size) { + UINT bufferSize = 0; + + if (likely(pBuffer != nullptr)) + bufferSize = static_cast(pBuffer)->Desc()->ByteWidth; + + return bufferSize >= Offset + Size; + } + private: ContextType* GetTypedContext() { From 30b1cac0ae67a072b7825dfcbe161b7033115067 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 21:35:59 +0200 Subject: [PATCH 0401/1348] [d3d11] Remove old D3D11DeviceContext class --- src/d3d10/d3d10_buffer.cpp | 2 +- src/d3d10/d3d10_query.cpp | 2 +- src/d3d10/d3d10_query.h | 1 - src/d3d10/d3d10_texture.cpp | 2 +- src/d3d11/d3d11_buffer.cpp | 2 +- src/d3d11/d3d11_buffer.h | 1 - src/d3d11/d3d11_cmdlist.h | 2 +- src/d3d11/d3d11_context.cpp | 24 ---------------------- src/d3d11/d3d11_context.h | 32 ------------------------------ src/d3d11/d3d11_context_common.cpp | 2 +- src/d3d11/d3d11_context_common.h | 15 ++++++++++++-- src/d3d11/d3d11_device.h | 1 - src/d3d11/d3d11_gdi.cpp | 2 +- src/d3d11/d3d11_video.cpp | 1 - src/d3d11/meson.build | 1 - 15 files changed, 20 insertions(+), 70 deletions(-) delete mode 100644 src/d3d11/d3d11_context.cpp delete mode 100644 src/d3d11/d3d11_context.h diff --git a/src/d3d10/d3d10_buffer.cpp b/src/d3d10/d3d10_buffer.cpp index 2bd089b0f..bf08aadf6 100644 --- a/src/d3d10/d3d10_buffer.cpp +++ b/src/d3d10/d3d10_buffer.cpp @@ -2,7 +2,7 @@ #include "../d3d11/d3d11_buffer.h" #include "../d3d11/d3d11_device.h" -#include "../d3d11/d3d11_context.h" +#include "../d3d11/d3d11_context_common.h" namespace dxvk { diff --git a/src/d3d10/d3d10_query.cpp b/src/d3d10/d3d10_query.cpp index 8730a611e..bb536c0d3 100644 --- a/src/d3d10/d3d10_query.cpp +++ b/src/d3d10/d3d10_query.cpp @@ -2,7 +2,7 @@ #include "d3d10_device.h" #include "../d3d11/d3d11_device.h" -#include "../d3d11/d3d11_context.h" +#include "../d3d11/d3d11_context_common.h" #include "../d3d11/d3d11_query.h" namespace dxvk { diff --git a/src/d3d10/d3d10_query.h b/src/d3d10/d3d10_query.h index c189e9798..699caa4ee 100644 --- a/src/d3d10/d3d10_query.h +++ b/src/d3d10/d3d10_query.h @@ -6,7 +6,6 @@ namespace dxvk { class D3D10Device; class D3D11Device; - class D3D11DeviceContext; class D3D11Query; class D3D10Query : public ID3D10Predicate { diff --git a/src/d3d10/d3d10_texture.cpp b/src/d3d10/d3d10_texture.cpp index d04267cbc..1a852a0cd 100644 --- a/src/d3d10/d3d10_texture.cpp +++ b/src/d3d10/d3d10_texture.cpp @@ -2,7 +2,7 @@ #include "d3d10_device.h" #include "../d3d11/d3d11_device.h" -#include "../d3d11/d3d11_context.h" +#include "../d3d11/d3d11_context_common.h" #include "../d3d11/d3d11_texture.h" namespace dxvk { diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index c53003a05..d248e3423 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -1,5 +1,5 @@ #include "d3d11_buffer.h" -#include "d3d11_context.h" +#include "d3d11_context_common.h" #include "d3d11_device.h" #include "../dxvk/dxvk_data.h" diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index c0472fd65..d59c547c9 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -12,7 +12,6 @@ namespace dxvk { class D3D11Device; - class D3D11DeviceContext; /** diff --git a/src/d3d11/d3d11_cmdlist.h b/src/d3d11/d3d11_cmdlist.h index 8be313ad6..c33972588 100644 --- a/src/d3d11/d3d11_cmdlist.h +++ b/src/d3d11/d3d11_cmdlist.h @@ -1,6 +1,6 @@ #pragma once -#include "d3d11_context.h" +#include "d3d11_context_common.h" namespace dxvk { diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp deleted file mode 100644 index 4e13dca8d..000000000 --- a/src/d3d11/d3d11_context.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include - -#include "d3d11_context.h" -#include "d3d11_device.h" -#include "d3d11_query.h" -#include "d3d11_texture.h" -#include "d3d11_video.h" - -#include "../dxbc/dxbc_util.h" - -namespace dxvk { - - D3D11DeviceContext::D3D11DeviceContext( - D3D11Device* pParent) - : D3D11DeviceChild(pParent) { - - } - - - D3D11DeviceContext::~D3D11DeviceContext() { - - } - -} diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h deleted file mode 100644 index f884ac398..000000000 --- a/src/d3d11/d3d11_context.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "../dxvk/dxvk_adapter.h" -#include "../dxvk/dxvk_cs.h" -#include "../dxvk/dxvk_device.h" -#include "../dxvk/dxvk_staging.h" - -#include "../d3d10/d3d10_multithread.h" - -#include "d3d11_annotation.h" -#include "d3d11_cmd.h" -#include "d3d11_context_ext.h" -#include "d3d11_context_state.h" -#include "d3d11_device_child.h" -#include "d3d11_texture.h" - -namespace dxvk { - - class D3D11Device; - - class D3D11DeviceContext : public D3D11DeviceChild { - - public: - - D3D11DeviceContext( - D3D11Device* pParent); - - ~D3D11DeviceContext(); - - }; - -} diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index b4797c0e7..1e333d4cc 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -9,7 +9,7 @@ namespace dxvk { D3D11Device* pParent, const Rc& Device, DxvkCsChunkFlags CsFlags) - : D3D11DeviceContext(pParent), + : D3D11DeviceChild(pParent), m_contextExt(GetTypedContext()), m_annotation(GetTypedContext(), Device), m_multithread(this, false), diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index 5e6a0488d..9974e900f 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -3,8 +3,19 @@ #include #include +#include "../dxvk/dxvk_adapter.h" +#include "../dxvk/dxvk_cs.h" +#include "../dxvk/dxvk_device.h" +#include "../dxvk/dxvk_staging.h" + +#include "../d3d10/d3d10_multithread.h" + +#include "d3d11_annotation.h" #include "d3d11_buffer.h" -#include "d3d11_context.h" +#include "d3d11_cmd.h" +#include "d3d11_context_ext.h" +#include "d3d11_context_state.h" +#include "d3d11_device_child.h" #include "d3d11_texture.h" namespace dxvk { @@ -52,7 +63,7 @@ namespace dxvk { * having to use virtual methods. */ template - class D3D11CommonContext : public D3D11DeviceContext { + class D3D11CommonContext : public D3D11DeviceChild { constexpr static bool IsDeferred = std::is_same_v; using Forwarder = D3D11ContextObjectForwarder; diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 5a99bd62a..9317eac06 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -31,7 +31,6 @@ namespace dxvk { class D3D11CommonShader; class D3D11CommonTexture; class D3D11Counter; - class D3D11DeviceContext; class D3D11DXGIDevice; class D3D11ImmediateContext; class D3D11Predicate; diff --git a/src/d3d11/d3d11_gdi.cpp b/src/d3d11/d3d11_gdi.cpp index 0958886ec..b4439fbac 100644 --- a/src/d3d11/d3d11_gdi.cpp +++ b/src/d3d11/d3d11_gdi.cpp @@ -1,4 +1,4 @@ -#include "d3d11_context.h" +#include "d3d11_context_common.h" #include "d3d11_device.h" #include "d3d11_gdi.h" diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 75dc373aa..d79e1f27e 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1,6 +1,5 @@ #include -#include "d3d11_context.h" #include "d3d11_context_imm.h" #include "d3d11_video.h" diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 4600a5a5e..4d5f2e59e 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -29,7 +29,6 @@ d3d11_src = [ 'd3d11_buffer.cpp', 'd3d11_class_linkage.cpp', 'd3d11_cmdlist.cpp', - 'd3d11_context.cpp', 'd3d11_context_common.cpp', 'd3d11_context_def.cpp', 'd3d11_context_ext.cpp', From 1d2d712dfb30c6eceb69d181517151152d618136 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 21:37:30 +0200 Subject: [PATCH 0402/1348] [d3d11] Move d3d11_context_common.* -> d3d11_context.* --- src/d3d10/d3d10_buffer.cpp | 2 +- src/d3d10/d3d10_query.cpp | 2 +- src/d3d10/d3d10_texture.cpp | 2 +- src/d3d11/d3d11_buffer.cpp | 2 +- src/d3d11/d3d11_cmdlist.h | 2 +- src/d3d11/{d3d11_context_common.cpp => d3d11_context.cpp} | 2 +- src/d3d11/{d3d11_context_common.h => d3d11_context.h} | 0 src/d3d11/d3d11_context_def.h | 2 +- src/d3d11/d3d11_context_imm.h | 2 +- src/d3d11/d3d11_gdi.cpp | 2 +- src/d3d11/meson.build | 2 +- 11 files changed, 10 insertions(+), 10 deletions(-) rename src/d3d11/{d3d11_context_common.cpp => d3d11_context.cpp} (99%) rename src/d3d11/{d3d11_context_common.h => d3d11_context.h} (100%) diff --git a/src/d3d10/d3d10_buffer.cpp b/src/d3d10/d3d10_buffer.cpp index bf08aadf6..2bd089b0f 100644 --- a/src/d3d10/d3d10_buffer.cpp +++ b/src/d3d10/d3d10_buffer.cpp @@ -2,7 +2,7 @@ #include "../d3d11/d3d11_buffer.h" #include "../d3d11/d3d11_device.h" -#include "../d3d11/d3d11_context_common.h" +#include "../d3d11/d3d11_context.h" namespace dxvk { diff --git a/src/d3d10/d3d10_query.cpp b/src/d3d10/d3d10_query.cpp index bb536c0d3..8730a611e 100644 --- a/src/d3d10/d3d10_query.cpp +++ b/src/d3d10/d3d10_query.cpp @@ -2,7 +2,7 @@ #include "d3d10_device.h" #include "../d3d11/d3d11_device.h" -#include "../d3d11/d3d11_context_common.h" +#include "../d3d11/d3d11_context.h" #include "../d3d11/d3d11_query.h" namespace dxvk { diff --git a/src/d3d10/d3d10_texture.cpp b/src/d3d10/d3d10_texture.cpp index 1a852a0cd..d04267cbc 100644 --- a/src/d3d10/d3d10_texture.cpp +++ b/src/d3d10/d3d10_texture.cpp @@ -2,7 +2,7 @@ #include "d3d10_device.h" #include "../d3d11/d3d11_device.h" -#include "../d3d11/d3d11_context_common.h" +#include "../d3d11/d3d11_context.h" #include "../d3d11/d3d11_texture.h" namespace dxvk { diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index d248e3423..c53003a05 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -1,5 +1,5 @@ #include "d3d11_buffer.h" -#include "d3d11_context_common.h" +#include "d3d11_context.h" #include "d3d11_device.h" #include "../dxvk/dxvk_data.h" diff --git a/src/d3d11/d3d11_cmdlist.h b/src/d3d11/d3d11_cmdlist.h index c33972588..8be313ad6 100644 --- a/src/d3d11/d3d11_cmdlist.h +++ b/src/d3d11/d3d11_cmdlist.h @@ -1,6 +1,6 @@ #pragma once -#include "d3d11_context_common.h" +#include "d3d11_context.h" namespace dxvk { diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context.cpp similarity index 99% rename from src/d3d11/d3d11_context_common.cpp rename to src/d3d11/d3d11_context.cpp index 1e333d4cc..e75f78ccf 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1,4 +1,4 @@ -#include "d3d11_context_common.h" +#include "d3d11_context.h" #include "d3d11_context_def.h" #include "d3d11_context_imm.h" diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context.h similarity index 100% rename from src/d3d11/d3d11_context_common.h rename to src/d3d11/d3d11_context.h diff --git a/src/d3d11/d3d11_context_def.h b/src/d3d11/d3d11_context_def.h index d88204745..06ea43cf1 100644 --- a/src/d3d11/d3d11_context_def.h +++ b/src/d3d11/d3d11_context_def.h @@ -1,7 +1,7 @@ #pragma once #include "d3d11_cmdlist.h" -#include "d3d11_context_common.h" +#include "d3d11_context.h" #include diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index ddc6304c2..97779c015 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -4,7 +4,7 @@ #include "../util/sync/sync_signal.h" -#include "d3d11_context_common.h" +#include "d3d11_context.h" #include "d3d11_state_object.h" #include "d3d11_video.h" diff --git a/src/d3d11/d3d11_gdi.cpp b/src/d3d11/d3d11_gdi.cpp index b4439fbac..0958886ec 100644 --- a/src/d3d11/d3d11_gdi.cpp +++ b/src/d3d11/d3d11_gdi.cpp @@ -1,4 +1,4 @@ -#include "d3d11_context_common.h" +#include "d3d11_context.h" #include "d3d11_device.h" #include "d3d11_gdi.h" diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 4d5f2e59e..85fe78074 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -29,7 +29,7 @@ d3d11_src = [ 'd3d11_buffer.cpp', 'd3d11_class_linkage.cpp', 'd3d11_cmdlist.cpp', - 'd3d11_context_common.cpp', + 'd3d11_context.cpp', 'd3d11_context_def.cpp', 'd3d11_context_ext.cpp', 'd3d11_context_imm.cpp', From e49524fcb0e0f5fbb274164192b8e66d1bb8a8b5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 22:19:16 +0200 Subject: [PATCH 0403/1348] [d3d11] Move GetType and GetContextFlags to D3D11CommonContext --- src/d3d11/d3d11_context.cpp | 16 ++++++++++++++++ src/d3d11/d3d11_context.h | 6 ++++++ src/d3d11/d3d11_context_def.cpp | 15 ++------------- src/d3d11/d3d11_context_def.h | 6 ------ src/d3d11/d3d11_context_imm.cpp | 12 +----------- src/d3d11/d3d11_context_imm.h | 4 ---- 6 files changed, 25 insertions(+), 34 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index e75f78ccf..a6c72c0f1 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -8,12 +8,14 @@ namespace dxvk { D3D11CommonContext::D3D11CommonContext( D3D11Device* pParent, const Rc& Device, + UINT ContextFlags, DxvkCsChunkFlags CsFlags) : D3D11DeviceChild(pParent), m_contextExt(GetTypedContext()), m_annotation(GetTypedContext(), Device), m_multithread(this, false), m_device (Device), + m_flags (ContextFlags), m_staging (Device, StagingBufferSize), m_csFlags (CsFlags), m_csChunk (AllocCsChunk()), @@ -69,6 +71,20 @@ namespace dxvk { } + template + D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE D3D11CommonContext::GetType() { + return IsDeferred + ? D3D11_DEVICE_CONTEXT_DEFERRED + : D3D11_DEVICE_CONTEXT_IMMEDIATE; + } + + + template + UINT STDMETHODCALLTYPE D3D11CommonContext::GetContextFlags() { + return m_flags; + } + + template void STDMETHODCALLTYPE D3D11CommonContext::ClearState() { D3D10DeviceLock lock = LockContext(); diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 9974e900f..314ef4c54 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -76,6 +76,7 @@ namespace dxvk { D3D11CommonContext( D3D11Device* pParent, const Rc& Device, + UINT ContextFlags, DxvkCsChunkFlags CsFlags); ~D3D11CommonContext(); @@ -84,6 +85,10 @@ namespace dxvk { REFIID riid, void** ppvObject); + D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE GetType(); + + UINT STDMETHODCALLTYPE GetContextFlags(); + void STDMETHODCALLTYPE ClearState(); void STDMETHODCALLTYPE DiscardResource(ID3D11Resource *pResource); @@ -764,6 +769,7 @@ namespace dxvk { Rc m_device; D3D11ContextState m_state; + UINT m_flags; DxvkStagingBuffer m_staging; Rc m_updateBuffer; diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 9400f0e63..851260761 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -7,23 +7,12 @@ namespace dxvk { D3D11Device* pParent, const Rc& Device, UINT ContextFlags) - : D3D11CommonContext(pParent, Device, GetCsChunkFlags(pParent)), - m_contextFlags(ContextFlags), + : D3D11CommonContext(pParent, Device, ContextFlags, GetCsChunkFlags(pParent)), m_commandList (CreateCommandList()) { ClearState(); } - D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE D3D11DeferredContext::GetType() { - return D3D11_DEVICE_CONTEXT_DEFERRED; - } - - - UINT STDMETHODCALLTYPE D3D11DeferredContext::GetContextFlags() { - return m_contextFlags; - } - - HRESULT STDMETHODCALLTYPE D3D11DeferredContext::GetData( ID3D11Asynchronous* pAsync, void* pData, @@ -371,7 +360,7 @@ namespace dxvk { Com D3D11DeferredContext::CreateCommandList() { - return new D3D11CommandList(m_parent, m_contextFlags); + return new D3D11CommandList(m_parent, m_flags); } diff --git a/src/d3d11/d3d11_context_def.h b/src/d3d11/d3d11_context_def.h index 06ea43cf1..50373c349 100644 --- a/src/d3d11/d3d11_context_def.h +++ b/src/d3d11/d3d11_context_def.h @@ -31,10 +31,6 @@ namespace dxvk { const Rc& Device, UINT ContextFlags); - D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE GetType(); - - UINT STDMETHODCALLTYPE GetContextFlags(); - HRESULT STDMETHODCALLTYPE GetData( ID3D11Asynchronous* pAsync, void* pData, @@ -86,8 +82,6 @@ namespace dxvk { private: - const UINT m_contextFlags; - // Command list that we're recording Com m_commandList; diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index a32a1c775..8edff0d19 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -13,7 +13,7 @@ namespace dxvk { D3D11ImmediateContext::D3D11ImmediateContext( D3D11Device* pParent, const Rc& Device) - : D3D11CommonContext(pParent, Device, DxvkCsChunkFlag::SingleUse), + : D3D11CommonContext(pParent, Device, 0, DxvkCsChunkFlag::SingleUse), m_csThread(Device, Device->createContext(DxvkContextType::Primary)), m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize), m_videoContext(this, Device) { @@ -61,16 +61,6 @@ namespace dxvk { } - D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE D3D11ImmediateContext::GetType() { - return D3D11_DEVICE_CONTEXT_IMMEDIATE; - } - - - UINT STDMETHODCALLTYPE D3D11ImmediateContext::GetContextFlags() { - return 0; - } - - HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::GetData( ID3D11Asynchronous* pAsync, void* pData, diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 97779c015..dd5520670 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -29,10 +29,6 @@ namespace dxvk { REFIID riid, void** ppvObject); - D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE GetType(); - - UINT STDMETHODCALLTYPE GetContextFlags(); - HRESULT STDMETHODCALLTYPE GetData( ID3D11Asynchronous* pAsync, void* pData, From 9d967f2fed6150d3e55e61bddfb2fd611595846b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 22:39:39 +0200 Subject: [PATCH 0404/1348] [d3d11] Use new binding methods in video context --- src/d3d11/d3d11_video.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index d79e1f27e..a07199046 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1196,9 +1196,9 @@ namespace dxvk { rt.color[0].view = cView; rt.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - ctx->bindRenderTargets(rt); - ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_vs); - ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_fs); + ctx->bindRenderTargets(std::move(rt)); + ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, Rc(m_vs)); + ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, Rc(m_fs)); ctx->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo)); DxvkInputAssemblyState iaState; @@ -1293,10 +1293,10 @@ namespace dxvk { ctx->invalidateBuffer(m_ubo, uboSlice); ctx->setViewports(1, &viewport, &scissor); - ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 1, m_sampler); + ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 1, Rc(m_sampler)); for (uint32_t i = 0; i < cViews.size(); i++) - ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, 2 + i, cViews[i], nullptr); + ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, 2 + i, Rc(cViews[i]), nullptr); ctx->draw(3, 1, 0, 0); }); From 77e7c7c6b803708bb7f89f007313c6d14a283942 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 22:42:43 +0200 Subject: [PATCH 0405/1348] [hud] Use new binding methods for HUD rendering --- src/dxvk/hud/dxvk_hud_renderer.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index 10720eb50..bce83c725 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -104,13 +104,13 @@ namespace dxvk::hud { if (m_mode != Mode::RenderText) { m_mode = Mode::RenderText; - m_context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_textShaders.vert); - m_context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_textShaders.frag); + m_context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, Rc(m_textShaders.vert)); + m_context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, Rc(m_textShaders.frag)); m_context->bindResourceBuffer (VK_SHADER_STAGE_VERTEX_BIT, 0, DxvkBufferSlice(m_fontBuffer)); - m_context->bindResourceView (VK_SHADER_STAGE_VERTEX_BIT, 1, nullptr, m_dataView); - m_context->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 2, m_fontSampler); - m_context->bindResourceView (VK_SHADER_STAGE_FRAGMENT_BIT, 2, m_fontView, nullptr); + m_context->bindResourceView (VK_SHADER_STAGE_VERTEX_BIT, 1, nullptr, Rc(m_dataView)); + m_context->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 2, Rc(m_fontSampler)); + m_context->bindResourceView (VK_SHADER_STAGE_FRAGMENT_BIT, 2, Rc(m_fontView), nullptr); static const DxvkInputAssemblyState iaState = { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, @@ -126,8 +126,8 @@ namespace dxvk::hud { if (m_mode != Mode::RenderGraph) { m_mode = Mode::RenderGraph; - m_context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_graphShaders.vert); - m_context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_graphShaders.frag); + m_context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, Rc(m_graphShaders.vert)); + m_context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, Rc(m_graphShaders.frag)); m_context->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_dataBuffer)); From 37337dd4a6caf5fcdadc4db28e611dcd68301e97 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 22:42:55 +0200 Subject: [PATCH 0406/1348] [dxvk] Use new binding methods for swapchain blitter --- src/dxvk/dxvk_swapchain_blitter.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index 61e0c3202..c69a89428 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -180,7 +180,7 @@ namespace dxvk { renderTargets.color[0].view = dstView; renderTargets.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - ctx->bindRenderTargets(renderTargets); + ctx->bindRenderTargets(std::move(renderTargets)); VkExtent2D dstExtent = { dstView->imageInfo().extent.width, @@ -191,14 +191,14 @@ namespace dxvk { else ctx->clearRenderTarget(dstView, VK_IMAGE_ASPECT_COLOR_BIT, VkClearValue()); - ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Image, m_samplerPresent); - ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Gamma, m_samplerGamma); + ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Image, Rc(m_samplerPresent)); + ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Gamma, Rc(m_samplerGamma)); - ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Image, srcView, nullptr); - ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Gamma, m_gammaView, nullptr); + ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Image, Rc(srcView), nullptr); + ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Gamma, Rc(m_gammaView), nullptr); - ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, m_vs); - ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, fs); + ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, Rc(m_vs)); + ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, Rc(fs)); PresenterArgs args; args.srcOffset = srcRect.offset; From 67c11e63e6f33658c9319903569fa9054d6ab2fc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 3 Aug 2022 22:45:02 +0200 Subject: [PATCH 0407/1348] [dxvk] Remove old resource binding methods --- src/dxvk/dxvk_context.h | 132 ---------------------------------------- 1 file changed, 132 deletions(-) diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index db91271b0..c203f8336 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -86,26 +86,6 @@ namespace dxvk { * and binds it using \c bindFramebuffer. * \param [in] targets Render targets to bind */ - void bindRenderTargets( - const DxvkRenderTargets& targets) { - // Set up default render pass ops - m_state.om.renderTargets = targets; - - this->resetRenderPassOps( - m_state.om.renderTargets, - m_state.om.renderPassOps); - - if (!m_state.om.framebufferInfo.hasTargets(targets)) { - // Create a new framebuffer object next - // time we start rendering something - m_flags.set(DxvkContextFlag::GpDirtyFramebuffer); - } else { - // Don't redundantly spill the render pass if - // the same render targets are bound again - m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer); - } - } - void bindRenderTargets( DxvkRenderTargets&& targets) { // Set up default render pass ops @@ -134,15 +114,6 @@ namespace dxvk { * \param [in] argBuffer New argument buffer * \param [in] cntBuffer New count buffer */ - void bindDrawBuffers( - const DxvkBufferSlice& argBuffer, - const DxvkBufferSlice& cntBuffer) { - m_state.id.argBuffer = argBuffer; - m_state.id.cntBuffer = cntBuffer; - - m_flags.set(DxvkContextFlag::DirtyDrawBuffer); - } - void bindDrawBuffers( DxvkBufferSlice&& argBuffer, DxvkBufferSlice&& cntBuffer) { @@ -160,18 +131,6 @@ namespace dxvk { * \param [in] buffer New index buffer * \param [in] indexType Index type */ - void bindIndexBuffer( - const DxvkBufferSlice& buffer, - VkIndexType indexType) { - if (!m_state.vi.indexBuffer.matchesBuffer(buffer)) - m_vbTracked.clr(MaxNumVertexBindings); - - m_state.vi.indexBuffer = buffer; - m_state.vi.indexType = indexType; - - m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer); - } - void bindIndexBuffer( DxvkBufferSlice&& buffer, VkIndexType indexType) { @@ -192,20 +151,6 @@ namespace dxvk { * \param [in] slot Resource binding slot * \param [in] buffer Buffer to bind */ - void bindResourceBuffer( - VkShaderStageFlags stages, - uint32_t slot, - const DxvkBufferSlice& buffer) { - bool needsUpdate = !m_rc[slot].bufferSlice.matchesBuffer(buffer); - - if (likely(needsUpdate)) - m_rcTracked.clr(slot); - - m_rc[slot].bufferSlice = buffer; - - m_descriptorState.dirtyBuffers(stages); - } - void bindResourceBuffer( VkShaderStageFlags stages, uint32_t slot, @@ -247,21 +192,6 @@ namespace dxvk { * \param [in] imageView Image view to bind * \param [in] bufferView Buffer view to bind */ - void bindResourceView( - VkShaderStageFlags stages, - uint32_t slot, - const Rc& imageView, - const Rc& bufferView) { - m_rc[slot].imageView = imageView; - m_rc[slot].bufferView = bufferView; - m_rc[slot].bufferSlice = bufferView != nullptr - ? bufferView->slice() - : DxvkBufferSlice(); - m_rcTracked.clr(slot); - - m_descriptorState.dirtyViews(stages); - } - void bindResourceView( VkShaderStageFlags stages, uint32_t slot, @@ -286,16 +216,6 @@ namespace dxvk { * \param [in] slot Resource binding slot * \param [in] sampler Sampler view to bind */ - void bindResourceSampler( - VkShaderStageFlags stages, - uint32_t slot, - const Rc& sampler) { - m_rc[slot].sampler = sampler; - m_rcTracked.clr(slot); - - m_descriptorState.dirtyViews(stages); - } - void bindResourceSampler( VkShaderStageFlags stages, uint32_t slot, @@ -312,33 +232,6 @@ namespace dxvk { * \param [in] stage Target shader stage * \param [in] shader The shader to bind */ - void bindShader( - VkShaderStageFlagBits stage, - const Rc& shader) { - Rc* shaderStage; - - switch (stage) { - case VK_SHADER_STAGE_VERTEX_BIT: shaderStage = &m_state.gp.shaders.vs; break; - case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: shaderStage = &m_state.gp.shaders.tcs; break; - case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: shaderStage = &m_state.gp.shaders.tes; break; - case VK_SHADER_STAGE_GEOMETRY_BIT: shaderStage = &m_state.gp.shaders.gs; break; - case VK_SHADER_STAGE_FRAGMENT_BIT: shaderStage = &m_state.gp.shaders.fs; break; - case VK_SHADER_STAGE_COMPUTE_BIT: shaderStage = &m_state.cp.shaders.cs; break; - default: return; - } - - *shaderStage = shader; - - if (stage == VK_SHADER_STAGE_COMPUTE_BIT) { - m_flags.set( - DxvkContextFlag::CpDirtyPipelineState); - } else { - m_flags.set( - DxvkContextFlag::GpDirtyPipeline, - DxvkContextFlag::GpDirtyPipelineState); - } - } - void bindShader( VkShaderStageFlagBits stage, Rc&& shader) { @@ -389,18 +282,6 @@ namespace dxvk { * \param [in] buffer New vertex buffer * \param [in] stride Stride between vertices */ - void bindVertexBuffer( - uint32_t binding, - const DxvkBufferSlice& buffer, - uint32_t stride) { - if (!m_state.vi.vertexBuffers[binding].matchesBuffer(buffer)) - m_vbTracked.clr(binding); - - m_state.vi.vertexBuffers[binding] = buffer; - m_state.vi.vertexStrides[binding] = stride; - m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers); - } - void bindVertexBuffer( uint32_t binding, DxvkBufferSlice&& buffer, @@ -420,19 +301,6 @@ namespace dxvk { * \param [in] buffer The buffer to bind * \param [in] counter Xfb counter buffer */ - void bindXfbBuffer( - uint32_t binding, - const DxvkBufferSlice& buffer, - const DxvkBufferSlice& counter) { - if (!m_state.xfb.buffers [binding].matches(buffer) - || !m_state.xfb.counters[binding].matches(counter)) { - m_state.xfb.buffers [binding] = buffer; - m_state.xfb.counters[binding] = counter; - - m_flags.set(DxvkContextFlag::GpDirtyXfbBuffers); - } - } - void bindXfbBuffer( uint32_t binding, DxvkBufferSlice&& buffer, From 37a2b025589babdac55c1ee8df3a7b443b71a82b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 18:40:07 +0200 Subject: [PATCH 0408/1348] [d3d11] Fix compiler error on GCC 10.3 --- src/d3d11/d3d11_context_def.h | 3 +-- src/d3d11/d3d11_context_imm.h | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/d3d11/d3d11_context_def.h b/src/d3d11/d3d11_context_def.h index 50373c349..4a5a41246 100644 --- a/src/d3d11/d3d11_context_def.h +++ b/src/d3d11/d3d11_context_def.h @@ -22,8 +22,7 @@ namespace dxvk { }; class D3D11DeferredContext : public D3D11CommonContext { - template - friend class D3D11CommonContext; + friend class D3D11CommonContext; public: D3D11DeferredContext( diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index dd5520670..dce444843 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -14,8 +14,7 @@ namespace dxvk { class D3D11CommonTexture; class D3D11ImmediateContext : public D3D11CommonContext { - template - friend class D3D11CommonContext; + friend class D3D11CommonContext; friend class D3D11SwapChain; friend class D3D11VideoContext; public: From 0f94971193d8320cdc74d6e5204e76cb2c4304f2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 5 Aug 2022 12:10:03 +0200 Subject: [PATCH 0409/1348] [d3d11,d3d9] Lock context/device in EndFrame Fixes #2787. --- src/d3d11/d3d11_context_imm.cpp | 2 ++ src/d3d9/d3d9_device.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 8edff0d19..a885291ec 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -652,6 +652,8 @@ namespace dxvk { void D3D11ImmediateContext::EndFrame() { + D3D10DeviceLock lock = LockContext(); + EmitCs([] (DxvkContext* ctx) { ctx->endFrame(); }); diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 716100c39..f3e490c7a 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5112,6 +5112,8 @@ namespace dxvk { void D3D9DeviceEx::EndFrame() { + D3D9DeviceLock lock = LockDevice(); + EmitCs([] (DxvkContext* ctx) { ctx->endFrame(); }); From 211ad0efccea75756e6f84bef0c984d6cdadb572 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 5 Aug 2022 12:46:41 +0200 Subject: [PATCH 0410/1348] [dxvk] Always use init barrier set for initial transition in initImage This allows us to batch image initialization barriers better. --- src/dxvk/dxvk_context.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 743c0a6d1..fc529d3bf 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1457,13 +1457,12 @@ namespace dxvk { } else { VkImageLayout clearLayout = image->pickLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - m_execAcquires.accessImage(image, subresources, + m_initBarriers.accessImage(image, subresources, initialLayout, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, clearLayout, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT); - m_execAcquires.recordCommands(m_cmd); auto formatInfo = image->formatInfo(); From 91fc0a8688bc46ef733c2af1eade7cc666da63eb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 14:07:48 +0200 Subject: [PATCH 0411/1348] [d3d11] Rename and factor out some state clearing methods --- src/d3d11/d3d11_context.cpp | 240 ++++++++++++++++---------------- src/d3d11/d3d11_context.h | 8 +- src/d3d11/d3d11_context_def.cpp | 4 +- src/d3d11/d3d11_context_imm.cpp | 4 +- src/d3d11/d3d11_video.cpp | 4 +- 5 files changed, 133 insertions(+), 127 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index a6c72c0f1..c4a7dcc14 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -89,116 +89,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11CommonContext::ClearState() { D3D10DeviceLock lock = LockContext(); - // Default shaders - m_state.vs.shader = nullptr; - m_state.hs.shader = nullptr; - m_state.ds.shader = nullptr; - m_state.gs.shader = nullptr; - m_state.ps.shader = nullptr; - m_state.cs.shader = nullptr; - - // Default constant buffers - for (uint32_t i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) { - m_state.vs.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.hs.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.ds.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.gs.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.ps.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.cs.constantBuffers[i] = { nullptr, 0, 0 }; - } - - // Default samplers - for (uint32_t i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) { - m_state.vs.samplers[i] = nullptr; - m_state.hs.samplers[i] = nullptr; - m_state.ds.samplers[i] = nullptr; - m_state.gs.samplers[i] = nullptr; - m_state.ps.samplers[i] = nullptr; - m_state.cs.samplers[i] = nullptr; - } - - // Default shader resources - for (uint32_t i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) { - m_state.vs.shaderResources.views[i] = nullptr; - m_state.hs.shaderResources.views[i] = nullptr; - m_state.ds.shaderResources.views[i] = nullptr; - m_state.gs.shaderResources.views[i] = nullptr; - m_state.ps.shaderResources.views[i] = nullptr; - m_state.cs.shaderResources.views[i] = nullptr; - } - - m_state.vs.shaderResources.hazardous.clear(); - m_state.hs.shaderResources.hazardous.clear(); - m_state.ds.shaderResources.hazardous.clear(); - m_state.gs.shaderResources.hazardous.clear(); - m_state.ps.shaderResources.hazardous.clear(); - m_state.cs.shaderResources.hazardous.clear(); - - // Default UAVs - for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) { - m_state.ps.unorderedAccessViews[i] = nullptr; - m_state.cs.unorderedAccessViews[i] = nullptr; - } - - m_state.cs.uavMask.clear(); - - // Default ID state - m_state.id.argBuffer = nullptr; - - // Default IA state - m_state.ia.inputLayout = nullptr; - m_state.ia.primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; - - for (uint32_t i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) { - m_state.ia.vertexBuffers[i].buffer = nullptr; - m_state.ia.vertexBuffers[i].offset = 0; - m_state.ia.vertexBuffers[i].stride = 0; - } - - m_state.ia.indexBuffer.buffer = nullptr; - m_state.ia.indexBuffer.offset = 0; - m_state.ia.indexBuffer.format = DXGI_FORMAT_UNKNOWN; - - // Default OM State - for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - m_state.om.renderTargetViews[i] = nullptr; - m_state.om.depthStencilView = nullptr; - - m_state.om.cbState = nullptr; - m_state.om.dsState = nullptr; - - for (uint32_t i = 0; i < 4; i++) - m_state.om.blendFactor[i] = 1.0f; - - m_state.om.sampleCount = 0; - m_state.om.sampleMask = D3D11_DEFAULT_SAMPLE_MASK; - m_state.om.stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE; - - m_state.om.maxRtv = 0; - m_state.om.maxUav = 0; - - // Default RS state - m_state.rs.state = nullptr; - m_state.rs.numViewports = 0; - m_state.rs.numScissors = 0; - - for (uint32_t i = 0; i < D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++) { - m_state.rs.viewports[i] = D3D11_VIEWPORT { }; - m_state.rs.scissors [i] = D3D11_RECT { }; - } - - // Default SO state - for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) { - m_state.so.targets[i].buffer = nullptr; - m_state.so.targets[i].offset = 0; - } - - // Default predication - m_state.pr.predicateObject = nullptr; - m_state.pr.predicateValue = FALSE; - - // Make sure to apply all state - ResetState(); + ResetCommandListState(); + ResetContextState(); } @@ -3963,13 +3855,7 @@ namespace dxvk { template - void D3D11CommonContext::ResetStagingBuffer() { - m_staging.reset(); - } - - - template - void D3D11CommonContext::ResetState() { + void D3D11CommonContext::ResetCommandListState() { EmitCs([] (DxvkContext* ctx) { // Reset render targets ctx->bindRenderTargets(DxvkRenderTargets()); @@ -4074,6 +3960,124 @@ namespace dxvk { } + template + void D3D11CommonContext::ResetContextState() { + // Default shaders + m_state.vs.shader = nullptr; + m_state.hs.shader = nullptr; + m_state.ds.shader = nullptr; + m_state.gs.shader = nullptr; + m_state.ps.shader = nullptr; + m_state.cs.shader = nullptr; + + // Default constant buffers + for (uint32_t i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) { + m_state.vs.constantBuffers[i] = { nullptr, 0, 0 }; + m_state.hs.constantBuffers[i] = { nullptr, 0, 0 }; + m_state.ds.constantBuffers[i] = { nullptr, 0, 0 }; + m_state.gs.constantBuffers[i] = { nullptr, 0, 0 }; + m_state.ps.constantBuffers[i] = { nullptr, 0, 0 }; + m_state.cs.constantBuffers[i] = { nullptr, 0, 0 }; + } + + // Default samplers + for (uint32_t i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) { + m_state.vs.samplers[i] = nullptr; + m_state.hs.samplers[i] = nullptr; + m_state.ds.samplers[i] = nullptr; + m_state.gs.samplers[i] = nullptr; + m_state.ps.samplers[i] = nullptr; + m_state.cs.samplers[i] = nullptr; + } + + // Default shader resources + for (uint32_t i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) { + m_state.vs.shaderResources.views[i] = nullptr; + m_state.hs.shaderResources.views[i] = nullptr; + m_state.ds.shaderResources.views[i] = nullptr; + m_state.gs.shaderResources.views[i] = nullptr; + m_state.ps.shaderResources.views[i] = nullptr; + m_state.cs.shaderResources.views[i] = nullptr; + } + + m_state.vs.shaderResources.hazardous.clear(); + m_state.hs.shaderResources.hazardous.clear(); + m_state.ds.shaderResources.hazardous.clear(); + m_state.gs.shaderResources.hazardous.clear(); + m_state.ps.shaderResources.hazardous.clear(); + m_state.cs.shaderResources.hazardous.clear(); + + // Default UAVs + for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) { + m_state.ps.unorderedAccessViews[i] = nullptr; + m_state.cs.unorderedAccessViews[i] = nullptr; + } + + m_state.cs.uavMask.clear(); + + // Default ID state + m_state.id.argBuffer = nullptr; + + // Default IA state + m_state.ia.inputLayout = nullptr; + m_state.ia.primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + + for (uint32_t i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) { + m_state.ia.vertexBuffers[i].buffer = nullptr; + m_state.ia.vertexBuffers[i].offset = 0; + m_state.ia.vertexBuffers[i].stride = 0; + } + + m_state.ia.indexBuffer.buffer = nullptr; + m_state.ia.indexBuffer.offset = 0; + m_state.ia.indexBuffer.format = DXGI_FORMAT_UNKNOWN; + + // Default OM State + for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + m_state.om.renderTargetViews[i] = nullptr; + m_state.om.depthStencilView = nullptr; + + m_state.om.cbState = nullptr; + m_state.om.dsState = nullptr; + + for (uint32_t i = 0; i < 4; i++) + m_state.om.blendFactor[i] = 1.0f; + + m_state.om.sampleCount = 0; + m_state.om.sampleMask = D3D11_DEFAULT_SAMPLE_MASK; + m_state.om.stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE; + + m_state.om.maxRtv = 0; + m_state.om.maxUav = 0; + + // Default RS state + m_state.rs.state = nullptr; + m_state.rs.numViewports = 0; + m_state.rs.numScissors = 0; + + for (uint32_t i = 0; i < D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++) { + m_state.rs.viewports[i] = D3D11_VIEWPORT { }; + m_state.rs.scissors [i] = D3D11_RECT { }; + } + + // Default SO state + for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) { + m_state.so.targets[i].buffer = nullptr; + m_state.so.targets[i].offset = 0; + } + + // Default predication + m_state.pr.predicateObject = nullptr; + m_state.pr.predicateValue = FALSE; + } + + + template + void D3D11CommonContext::ResetStagingBuffer() { + m_staging.reset(); + } + + template template void D3D11CommonContext::ResolveSrvHazards( @@ -4172,7 +4176,7 @@ namespace dxvk { template - void D3D11CommonContext::RestoreState() { + void D3D11CommonContext::RestoreCommandListState() { BindFramebuffer(); BindShader (GetCommonShader(m_state.vs.shader.ptr())); diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 314ef4c54..b43f25b94 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -906,9 +906,11 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); - void ResetStagingBuffer(); + void ResetCommandListState(); - void ResetState(); + void ResetContextState(); + + void ResetStagingBuffer(); template void ResolveSrvHazards( @@ -929,7 +931,7 @@ namespace dxvk { void ResolveOmUavHazards( D3D11RenderTargetView* pView); - void RestoreState(); + void RestoreCommandListState(); template void RestoreConstantBuffers( diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 851260761..211c7aaed 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -140,7 +140,7 @@ namespace dxvk { static_cast(pCommandList)->EmitToCommandList(m_commandList.ptr()); if (RestoreContextState) - RestoreState(); + RestoreCommandListState(); else ClearState(); } @@ -159,7 +159,7 @@ namespace dxvk { m_commandList = CreateCommandList(); if (RestoreDeferredContextState) - RestoreState(); + RestoreCommandListState(); else ClearState(); diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index a885291ec..e0fe09cca 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -240,7 +240,7 @@ namespace dxvk { m_csSeqNum = std::max(m_csSeqNum, csSeqNum); if (RestoreContextState) - RestoreState(); + RestoreCommandListState(); else ClearState(); @@ -630,7 +630,7 @@ namespace dxvk { oldState->SetState(m_state); newState->GetState(m_state); - RestoreState(); + RestoreCommandListState(); } diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index a07199046..4561f6d4e 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1047,7 +1047,7 @@ namespace dxvk { continue; if (!hasStreamsEnabled) { - m_ctx->ResetState(); + m_ctx->ResetCommandListState(); BindOutputView(pOutputView); hasStreamsEnabled = true; } @@ -1056,7 +1056,7 @@ namespace dxvk { } if (hasStreamsEnabled) - m_ctx->RestoreState(); + m_ctx->RestoreCommandListState(); return S_OK; } From c7d9201303c373a3c30ba4401d55d6af5008108d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 14:21:27 +0200 Subject: [PATCH 0412/1348] [d3d11] Change state clearing behaviour around deferred contexts Resetting command list state at the end of each D3D11 command list, as well as before ExecuteCommandList, will allow us to track which state needs to be reset, which may save us a significant amount of CPU work. --- src/d3d11/d3d11_context_def.cpp | 33 ++++++++++++++++++++++++++++----- src/d3d11/d3d11_context_imm.cpp | 8 +++++++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 211c7aaed..b12f5b858 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -9,7 +9,7 @@ namespace dxvk { UINT ContextFlags) : D3D11CommonContext(pParent, Device, ContextFlags, GetCsChunkFlags(pParent)), m_commandList (CreateCommandList()) { - ClearState(); + ResetContextState(); } @@ -135,14 +135,25 @@ namespace dxvk { BOOL RestoreContextState) { D3D10DeviceLock lock = LockContext(); + // Clear state so that the command list can't observe any + // current context state. The command list itself will clean + // up after execution to ensure that no state changes done + // by the command list are visible to the immediate context. + ResetCommandListState(); + + // Flush any outstanding commands so that + // we don't mess up the execution order FlushCsChunk(); - static_cast(pCommandList)->EmitToCommandList(m_commandList.ptr()); + // Record any chunks from the given command list into the + // current command list and deal with context state + auto commandList = static_cast(pCommandList); + commandList->EmitToCommandList(m_commandList.ptr()); if (RestoreContextState) RestoreCommandListState(); else - ClearState(); + ResetContextState(); } @@ -151,17 +162,29 @@ namespace dxvk { ID3D11CommandList **ppCommandList) { D3D10DeviceLock lock = LockContext(); + // End all queries that were left active by the app FinalizeQueries(); + + // Clean up command list state so that the any state changed + // by this command list does not affect the calling context + ResetCommandListState(); + + // Make sure all commands are visible to the command list FlushCsChunk(); - if (ppCommandList != nullptr) + if (ppCommandList) *ppCommandList = m_commandList.ref(); + + // Create a clean command list, and if requested, restore all + // previously set context state. Otherwise, reset the context. + // Any use of ExecuteCommandList will reset command list state + // before the command list is actually executed. m_commandList = CreateCommandList(); if (RestoreDeferredContextState) RestoreCommandListState(); else - ClearState(); + ResetContextState(); m_mappedResources.clear(); ResetStagingBuffer(); diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index e0fe09cca..2f827d4d6 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -226,6 +226,12 @@ namespace dxvk { auto commandList = static_cast(pCommandList); + // Clear state so that the command list can't observe any + // current context state. The command list itself will clean + // up after execution to ensure that no state changes done + // by the command list are visible to the immediate context. + ResetCommandListState(); + // Flush any outstanding commands so that // we don't mess up the execution order FlushCsChunk(); @@ -242,7 +248,7 @@ namespace dxvk { if (RestoreContextState) RestoreCommandListState(); else - ClearState(); + ResetContextState(); // Mark CS thread as busy so that subsequent // flush operations get executed correctly. From 7685a86494ace86e6fc18c1813d33d1c1969cb6d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 15:10:31 +0200 Subject: [PATCH 0413/1348] [d3d11] Change state restoring behaviour in SwapDeviceContextState --- src/d3d11/d3d11_context_imm.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 2f827d4d6..6703a661f 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -621,7 +621,10 @@ namespace dxvk { if (!pState) return; - + + // Reset all state affected by the current context state + ResetCommandListState(); + Com oldState = std::move(m_stateObject); Com newState = static_cast(pState); @@ -636,6 +639,7 @@ namespace dxvk { oldState->SetState(m_state); newState->GetState(m_state); + // Restore all state affected by the new context state RestoreCommandListState(); } From 33e169e85f7e19f8e83d3142fc78c001c3cfb8e4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 15:47:24 +0200 Subject: [PATCH 0414/1348] [d3d11] Refactor constant buffer state --- src/d3d11/d3d11_context.cpp | 240 ++++++++++++-------------------- src/d3d11/d3d11_context.h | 7 +- src/d3d11/d3d11_context_state.h | 56 ++++++-- 3 files changed, 137 insertions(+), 166 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index c4a7dcc14..a6c60d24b 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1334,9 +1334,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers( - m_state.vs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); + StartSlot, NumBuffers, ppConstantBuffers); } @@ -1350,11 +1348,8 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers1( - m_state.vs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -1408,10 +1403,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.vs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, nullptr, nullptr); } @@ -1425,12 +1418,9 @@ namespace dxvk { UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.vs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -1486,9 +1476,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers( - m_state.hs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); + StartSlot, NumBuffers, ppConstantBuffers); } @@ -1502,11 +1490,8 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers1( - m_state.hs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -1560,10 +1545,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.hs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, nullptr, nullptr); } @@ -1577,12 +1560,9 @@ namespace dxvk { UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.hs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -1638,9 +1618,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers( - m_state.ds.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); + StartSlot, NumBuffers, ppConstantBuffers); } @@ -1654,11 +1632,8 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers1( - m_state.ds.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -1712,10 +1687,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.ds.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, nullptr, nullptr); } @@ -1729,12 +1702,9 @@ namespace dxvk { UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.ds.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -1790,9 +1760,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers( - m_state.gs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); + StartSlot, NumBuffers, ppConstantBuffers); } @@ -1806,11 +1774,8 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers1( - m_state.gs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -1864,10 +1829,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.gs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, nullptr, nullptr); } @@ -1881,12 +1844,9 @@ namespace dxvk { UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.gs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -1942,9 +1902,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers( - m_state.ps.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); + StartSlot, NumBuffers, ppConstantBuffers); } @@ -1958,11 +1916,8 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers1( - m_state.ps.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -2016,10 +1971,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.ps.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, nullptr, nullptr); } @@ -2033,12 +1986,9 @@ namespace dxvk { UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.ps.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -2094,9 +2044,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers( - m_state.cs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers); + StartSlot, NumBuffers, ppConstantBuffers); } @@ -2110,11 +2058,8 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetConstantBuffers1( - m_state.cs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -2225,10 +2170,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.cs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, nullptr, nullptr); } @@ -2242,12 +2185,9 @@ namespace dxvk { UINT* pNumConstants) { D3D10DeviceLock lock = LockContext(); - GetConstantBuffers( - m_state.cs.constantBuffers, - StartSlot, NumBuffers, - ppConstantBuffers, - pFirstConstant, - pNumConstants); + GetConstantBuffers( + StartSlot, NumBuffers, ppConstantBuffers, + pFirstConstant, pNumConstants); } @@ -3795,31 +3735,33 @@ namespace dxvk { template + template void D3D11CommonContext::GetConstantBuffers( - const D3D11ConstantBufferBindings& Bindings, UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) { + const auto& bindings = m_state.cbv[ShaderStage]; + for (uint32_t i = 0; i < NumBuffers; i++) { - const bool inRange = StartSlot + i < Bindings.size(); + const bool inRange = StartSlot + i < bindings.buffers.size(); if (ppConstantBuffers) { ppConstantBuffers[i] = inRange - ? Bindings[StartSlot + i].buffer.ref() + ? bindings.buffers[StartSlot + i].buffer.ref() : nullptr; } if (pFirstConstant) { pFirstConstant[i] = inRange - ? Bindings[StartSlot + i].constantOffset + ? bindings.buffers[StartSlot + i].constantOffset : 0u; } if (pNumConstants) { pNumConstants[i] = inRange - ? Bindings[StartSlot + i].constantCount + ? bindings.buffers[StartSlot + i].constantCount : 0u; } } @@ -3970,15 +3912,8 @@ namespace dxvk { m_state.ps.shader = nullptr; m_state.cs.shader = nullptr; - // Default constant buffers - for (uint32_t i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) { - m_state.vs.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.hs.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.ds.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.gs.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.ps.constantBuffers[i] = { nullptr, 0, 0 }; - m_state.cs.constantBuffers[i] = { nullptr, 0, 0 }; - } + // Reset resource bindings + m_state.cbv.reset(); // Default samplers for (uint32_t i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) { @@ -4215,12 +4150,12 @@ namespace dxvk { for (uint32_t i = 0; i < m_state.so.targets.size(); i++) BindXfbBuffer(i, m_state.so.targets[i].buffer.ptr(), ~0u); - RestoreConstantBuffers (m_state.vs.constantBuffers); - RestoreConstantBuffers (m_state.hs.constantBuffers); - RestoreConstantBuffers (m_state.ds.constantBuffers); - RestoreConstantBuffers (m_state.gs.constantBuffers); - RestoreConstantBuffers (m_state.ps.constantBuffers); - RestoreConstantBuffers (m_state.cs.constantBuffers); + RestoreConstantBuffers(); + RestoreConstantBuffers(); + RestoreConstantBuffers(); + RestoreConstantBuffers(); + RestoreConstantBuffers(); + RestoreConstantBuffers(); RestoreSamplers (m_state.vs.samplers); RestoreSamplers (m_state.hs.samplers); @@ -4243,13 +4178,13 @@ namespace dxvk { template template - void D3D11CommonContext::RestoreConstantBuffers( - D3D11ConstantBufferBindings& Bindings) { + void D3D11CommonContext::RestoreConstantBuffers() { + const auto& bindings = m_state.cbv[Stage]; uint32_t slotId = computeConstantBufferBinding(Stage, 0); - for (uint32_t i = 0; i < Bindings.size(); i++) { - BindConstantBuffer(slotId + i, Bindings[i].buffer.ptr(), - Bindings[i].constantOffset, Bindings[i].constantBound); + for (uint32_t i = 0; i < bindings.buffers.size(); i++) { + BindConstantBuffer(slotId + i, bindings.buffers[i].buffer.ptr(), + bindings.buffers[i].constantOffset, bindings.buffers[i].constantBound); } } @@ -4295,10 +4230,10 @@ namespace dxvk { template template void D3D11CommonContext::SetConstantBuffers( - D3D11ConstantBufferBindings& Bindings, UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { + auto& bindings = m_state.cbv[ShaderStage]; uint32_t slotId = computeConstantBufferBinding(ShaderStage, StartSlot); for (uint32_t i = 0; i < NumBuffers; i++) { @@ -4309,12 +4244,12 @@ namespace dxvk { if (likely(newBuffer != nullptr)) constantCount = std::min(newBuffer->Desc()->ByteWidth / 16, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)); - if (Bindings[StartSlot + i].buffer != newBuffer - || Bindings[StartSlot + i].constantBound != constantCount) { - Bindings[StartSlot + i].buffer = newBuffer; - Bindings[StartSlot + i].constantOffset = 0; - Bindings[StartSlot + i].constantCount = constantCount; - Bindings[StartSlot + i].constantBound = constantCount; + if (bindings.buffers[StartSlot + i].buffer != newBuffer + || bindings.buffers[StartSlot + i].constantBound != constantCount) { + bindings.buffers[StartSlot + i].buffer = newBuffer; + bindings.buffers[StartSlot + i].constantOffset = 0; + bindings.buffers[StartSlot + i].constantCount = constantCount; + bindings.buffers[StartSlot + i].constantBound = constantCount; BindConstantBuffer(slotId + i, newBuffer, 0, constantCount); } @@ -4325,12 +4260,13 @@ namespace dxvk { template template void D3D11CommonContext::SetConstantBuffers1( - D3D11ConstantBufferBindings& Bindings, UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) { + auto& bindings = m_state.cbv[ShaderStage]; + uint32_t slotId = computeConstantBufferBinding(ShaderStage, StartSlot); for (uint32_t i = 0; i < NumBuffers; i++) { @@ -4367,25 +4303,25 @@ namespace dxvk { // Do a full rebind if either the buffer changes, or if either the current or // the previous number of bound constants were zero, since we're binding a null // buffer to the backend in that case. - bool needsUpdate = Bindings[StartSlot + i].buffer != newBuffer; + bool needsUpdate = bindings.buffers[StartSlot + i].buffer != newBuffer; if (!needsUpdate) { needsUpdate |= !constantBound; - needsUpdate |= !Bindings[StartSlot + i].constantBound; + needsUpdate |= !bindings.buffers[StartSlot + i].constantBound; } if (needsUpdate) { - Bindings[StartSlot + i].buffer = newBuffer; - Bindings[StartSlot + i].constantOffset = constantOffset; - Bindings[StartSlot + i].constantCount = constantCount; - Bindings[StartSlot + i].constantBound = constantBound; + bindings.buffers[StartSlot + i].buffer = newBuffer; + bindings.buffers[StartSlot + i].constantOffset = constantOffset; + bindings.buffers[StartSlot + i].constantCount = constantCount; + bindings.buffers[StartSlot + i].constantBound = constantBound; BindConstantBuffer(slotId + i, newBuffer, constantOffset, constantBound); - } else if (Bindings[StartSlot + i].constantOffset != constantOffset - || Bindings[StartSlot + i].constantCount != constantCount) { - Bindings[StartSlot + i].constantOffset = constantOffset; - Bindings[StartSlot + i].constantCount = constantCount; - Bindings[StartSlot + i].constantBound = constantBound; + } else if (bindings.buffers[StartSlot + i].constantOffset != constantOffset + || bindings.buffers[StartSlot + i].constantCount != constantCount) { + bindings.buffers[StartSlot + i].constantOffset = constantOffset; + bindings.buffers[StartSlot + i].constantCount = constantCount; + bindings.buffers[StartSlot + i].constantBound = constantBound; BindConstantBufferRange(slotId + i, constantOffset, constantBound); } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index b43f25b94..89e22a15e 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -886,8 +886,8 @@ namespace dxvk { ID3D11Resource* pResource, UINT Subresource); + template void GetConstantBuffers( - const D3D11ConstantBufferBindings& Bindings, UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers, @@ -934,8 +934,7 @@ namespace dxvk { void RestoreCommandListState(); template - void RestoreConstantBuffers( - D3D11ConstantBufferBindings& Bindings); + void RestoreConstantBuffers(); template void RestoreSamplers( @@ -951,14 +950,12 @@ namespace dxvk { template void SetConstantBuffers( - D3D11ConstantBufferBindings& Bindings, UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers); template void SetConstantBuffers1( - D3D11ConstantBufferBindings& Bindings, UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers, diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index d146a738d..9e1388de0 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -15,6 +15,41 @@ namespace dxvk { + /** + * \brief Per-stage state + * + * Stores an object of the given type for each shader stage. + * \tparam Object type + */ + template + class D3D11ShaderStageState { + + public: + + T& operator [] (DxbcProgramType type) { return m_state[uint32_t(type)]; } + const T& operator [] (DxbcProgramType type) const { return m_state[uint32_t(type)]; } + + /** + * \brief Calls reset method on all objects + */ + void reset() { + for (auto& state : m_state) + state.reset(); + } + + private: + + std::array m_state = { }; + + }; + + + /** + * \brief Constant buffer bindings + * + * Stores the bound buffer range from a runtime point of view, + * as well as the range that is actually bound to the context. + */ struct D3D11ConstantBufferBinding { Com buffer = nullptr; UINT constantOffset = 0; @@ -22,9 +57,16 @@ namespace dxvk { UINT constantBound = 0; }; - using D3D11ConstantBufferBindings = std::array< - D3D11ConstantBufferBinding, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT>; - + struct D3D11ShaderStageCbvBinding { + std::array buffers = { }; + + void reset() { + for (uint32_t i = 0; i < buffers.size(); i++) + buffers[i] = D3D11ConstantBufferBinding(); + } + }; + + using D3D11CbvBindings = D3D11ShaderStageState; using D3D11SamplerBindings = std::array< D3D11SamplerState*, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>; @@ -42,7 +84,6 @@ namespace dxvk { struct D3D11ContextStateVS { Com shader = nullptr; - D3D11ConstantBufferBindings constantBuffers = { }; D3D11SamplerBindings samplers = { }; D3D11ShaderResourceBindings shaderResources = { }; }; @@ -50,7 +91,6 @@ namespace dxvk { struct D3D11ContextStateHS { Com shader = nullptr; - D3D11ConstantBufferBindings constantBuffers = { }; D3D11SamplerBindings samplers = { }; D3D11ShaderResourceBindings shaderResources = { }; }; @@ -58,7 +98,6 @@ namespace dxvk { struct D3D11ContextStateDS { Com shader = nullptr; - D3D11ConstantBufferBindings constantBuffers = { }; D3D11SamplerBindings samplers = { }; D3D11ShaderResourceBindings shaderResources = { }; }; @@ -66,7 +105,6 @@ namespace dxvk { struct D3D11ContextStateGS { Com shader = nullptr; - D3D11ConstantBufferBindings constantBuffers = { }; D3D11SamplerBindings samplers = { }; D3D11ShaderResourceBindings shaderResources = { }; }; @@ -74,7 +112,6 @@ namespace dxvk { struct D3D11ContextStatePS { Com shader = nullptr; - D3D11ConstantBufferBindings constantBuffers = { }; D3D11SamplerBindings samplers = { }; D3D11ShaderResourceBindings shaderResources = { }; D3D11UnorderedAccessBindings unorderedAccessViews = { }; @@ -83,7 +120,6 @@ namespace dxvk { struct D3D11ContextStateCS { Com shader = nullptr; - D3D11ConstantBufferBindings constantBuffers = { }; D3D11SamplerBindings samplers = { }; D3D11ShaderResourceBindings shaderResources = { }; D3D11UnorderedAccessBindings unorderedAccessViews = { }; @@ -184,6 +220,8 @@ namespace dxvk { D3D11ContextStateRS rs; D3D11ContextStateSO so; D3D11ContextStatePR pr; + + D3D11CbvBindings cbv; }; } \ No newline at end of file From 1b4cb66dc360d1a798163cfe0e65cfea87777ecc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 15:56:49 +0200 Subject: [PATCH 0415/1348] [d3d11] Refactor shader resource state --- src/d3d11/d3d11_context.cpp | 119 +++++++++++++------------------- src/d3d11/d3d11_context.h | 9 +-- src/d3d11/d3d11_context_state.h | 33 +++++---- 3 files changed, 71 insertions(+), 90 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index a6c60d24b..4688f147c 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1361,9 +1361,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetShaderResources( - m_state.vs.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); + StartSlot, NumViews, ppShaderResourceViews); } @@ -1431,7 +1429,7 @@ namespace dxvk { ID3D11ShaderResourceView** ppShaderResourceViews) { D3D10DeviceLock lock = LockContext(); - GetShaderResources(m_state.vs.shaderResources, + GetShaderResources( StartSlot, NumViews, ppShaderResourceViews); } @@ -1503,9 +1501,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetShaderResources( - m_state.hs.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); + StartSlot, NumViews, ppShaderResourceViews); } @@ -1573,7 +1569,7 @@ namespace dxvk { ID3D11ShaderResourceView** ppShaderResourceViews) { D3D10DeviceLock lock = LockContext(); - GetShaderResources(m_state.hs.shaderResources, + GetShaderResources( StartSlot, NumViews, ppShaderResourceViews); } @@ -1645,9 +1641,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetShaderResources( - m_state.ds.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); + StartSlot, NumViews, ppShaderResourceViews); } @@ -1715,7 +1709,7 @@ namespace dxvk { ID3D11ShaderResourceView** ppShaderResourceViews) { D3D10DeviceLock lock = LockContext(); - GetShaderResources(m_state.ds.shaderResources, + GetShaderResources( StartSlot, NumViews, ppShaderResourceViews); } @@ -1787,9 +1781,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetShaderResources( - m_state.gs.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); + StartSlot, NumViews, ppShaderResourceViews); } @@ -1857,7 +1849,7 @@ namespace dxvk { ID3D11ShaderResourceView** ppShaderResourceViews) { D3D10DeviceLock lock = LockContext(); - GetShaderResources(m_state.gs.shaderResources, + GetShaderResources( StartSlot, NumViews, ppShaderResourceViews); } @@ -1929,9 +1921,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetShaderResources( - m_state.ps.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); + StartSlot, NumViews, ppShaderResourceViews); } @@ -1999,7 +1989,7 @@ namespace dxvk { ID3D11ShaderResourceView** ppShaderResourceViews) { D3D10DeviceLock lock = LockContext(); - GetShaderResources(m_state.ps.shaderResources, + GetShaderResources( StartSlot, NumViews, ppShaderResourceViews); } @@ -2071,9 +2061,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetShaderResources( - m_state.cs.shaderResources, - StartSlot, NumViews, - ppShaderResourceViews); + StartSlot, NumViews, ppShaderResourceViews); } @@ -2198,7 +2186,7 @@ namespace dxvk { ID3D11ShaderResourceView** ppShaderResourceViews) { D3D10DeviceLock lock = LockContext(); - GetShaderResources(m_state.cs.shaderResources, + GetShaderResources( StartSlot, NumViews, ppShaderResourceViews); } @@ -3769,14 +3757,16 @@ namespace dxvk { template + template void D3D11CommonContext::GetShaderResources( - const D3D11ShaderResourceBindings& Bindings, UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) { + const auto& bindings = m_state.srv[ShaderStage]; + for (uint32_t i = 0; i < NumViews; i++) { - ppShaderResourceViews[i] = StartSlot + i < Bindings.views.size() - ? Bindings.views[StartSlot + i].ref() + ppShaderResourceViews[i] = StartSlot + i < bindings.views.size() + ? bindings.views[StartSlot + i].ref() : nullptr; } } @@ -3914,6 +3904,7 @@ namespace dxvk { // Reset resource bindings m_state.cbv.reset(); + m_state.srv.reset(); // Default samplers for (uint32_t i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) { @@ -3925,23 +3916,6 @@ namespace dxvk { m_state.cs.samplers[i] = nullptr; } - // Default shader resources - for (uint32_t i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) { - m_state.vs.shaderResources.views[i] = nullptr; - m_state.hs.shaderResources.views[i] = nullptr; - m_state.ds.shaderResources.views[i] = nullptr; - m_state.gs.shaderResources.views[i] = nullptr; - m_state.ps.shaderResources.views[i] = nullptr; - m_state.cs.shaderResources.views[i] = nullptr; - } - - m_state.vs.shaderResources.hazardous.clear(); - m_state.hs.shaderResources.hazardous.clear(); - m_state.ds.shaderResources.hazardous.clear(); - m_state.gs.shaderResources.hazardous.clear(); - m_state.ps.shaderResources.hazardous.clear(); - m_state.cs.shaderResources.hazardous.clear(); - // Default UAVs for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) { m_state.ps.unorderedAccessViews[i] = nullptr; @@ -4016,29 +3990,30 @@ namespace dxvk { template template void D3D11CommonContext::ResolveSrvHazards( - T* pView, - D3D11ShaderResourceBindings& Bindings) { + T* pView) { + auto& bindings = m_state.srv[ShaderStage]; + uint32_t slotId = computeSrvBinding(ShaderStage, 0); - int32_t srvId = Bindings.hazardous.findNext(0); + int32_t srvId = bindings.hazardous.findNext(0); while (srvId >= 0) { - auto srv = Bindings.views[srvId].ptr(); + auto srv = bindings.views[srvId].ptr(); if (likely(srv && srv->TestHazards())) { bool hazard = CheckViewOverlap(pView, srv); if (unlikely(hazard)) { - Bindings.views[srvId] = nullptr; - Bindings.hazardous.clr(srvId); + bindings.views[srvId] = nullptr; + bindings.hazardous.clr(srvId); BindShaderResource(slotId + srvId, nullptr); } } else { // Avoid further redundant iterations - Bindings.hazardous.clr(srvId); + bindings.hazardous.clr(srvId); } - srvId = Bindings.hazardous.findNext(srvId + 1); + srvId = bindings.hazardous.findNext(srvId + 1); } } @@ -4048,7 +4023,7 @@ namespace dxvk { void D3D11CommonContext::ResolveCsSrvHazards( T* pView) { if (!pView) return; - ResolveSrvHazards (pView, m_state.cs.shaderResources); + ResolveSrvHazards(pView); } @@ -4057,11 +4032,11 @@ namespace dxvk { void D3D11CommonContext::ResolveOmSrvHazards( T* pView) { if (!pView) return; - ResolveSrvHazards (pView, m_state.vs.shaderResources); - ResolveSrvHazards (pView, m_state.hs.shaderResources); - ResolveSrvHazards (pView, m_state.ds.shaderResources); - ResolveSrvHazards (pView, m_state.gs.shaderResources); - ResolveSrvHazards (pView, m_state.ps.shaderResources); + ResolveSrvHazards(pView); + ResolveSrvHazards(pView); + ResolveSrvHazards(pView); + ResolveSrvHazards(pView); + ResolveSrvHazards(pView); } @@ -4164,12 +4139,12 @@ namespace dxvk { RestoreSamplers (m_state.ps.samplers); RestoreSamplers (m_state.cs.samplers); - RestoreShaderResources (m_state.vs.shaderResources); - RestoreShaderResources (m_state.hs.shaderResources); - RestoreShaderResources (m_state.ds.shaderResources); - RestoreShaderResources (m_state.gs.shaderResources); - RestoreShaderResources (m_state.ps.shaderResources); - RestoreShaderResources (m_state.cs.shaderResources); + RestoreShaderResources(); + RestoreShaderResources(); + RestoreShaderResources(); + RestoreShaderResources(); + RestoreShaderResources(); + RestoreShaderResources(); RestoreUnorderedAccessViews (m_state.ps.unorderedAccessViews); RestoreUnorderedAccessViews (m_state.cs.unorderedAccessViews); @@ -4202,12 +4177,12 @@ namespace dxvk { template template - void D3D11CommonContext::RestoreShaderResources( - D3D11ShaderResourceBindings& Bindings) { + void D3D11CommonContext::RestoreShaderResources() { + const auto& bindings = m_state.srv[Stage]; uint32_t slotId = computeSrvBinding(Stage, 0); - for (uint32_t i = 0; i < Bindings.views.size(); i++) - BindShaderResource(slotId + i, Bindings.views[i].ptr()); + for (uint32_t i = 0; i < bindings.views.size(); i++) + BindShaderResource(slotId + i, bindings.views[i].ptr()); } @@ -4332,16 +4307,16 @@ namespace dxvk { template template void D3D11CommonContext::SetShaderResources( - D3D11ShaderResourceBindings& Bindings, UINT StartSlot, UINT NumResources, ID3D11ShaderResourceView* const* ppResources) { + auto& bindings = m_state.srv[ShaderStage]; uint32_t slotId = computeSrvBinding(ShaderStage, StartSlot); for (uint32_t i = 0; i < NumResources; i++) { auto resView = static_cast(ppResources[i]); - if (Bindings.views[StartSlot + i] != resView) { + if (bindings.views[StartSlot + i] != resView) { if (unlikely(resView && resView->TestHazards())) { if (TestSrvHazards(resView)) resView = nullptr; @@ -4349,10 +4324,10 @@ namespace dxvk { // Only set if necessary, but don't reset it on every // bind as this would be more expensive than a few // redundant checks in OMSetRenderTargets and friends. - Bindings.hazardous.set(StartSlot + i, resView); + bindings.hazardous.set(StartSlot + i, resView); } - Bindings.views[StartSlot + i] = resView; + bindings.views[StartSlot + i] = resView; BindShaderResource(slotId + i, resView); } } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 89e22a15e..5c47ab553 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -894,8 +894,8 @@ namespace dxvk { UINT* pFirstConstant, UINT* pNumConstants); + template void GetShaderResources( - const D3D11ShaderResourceBindings& Bindings, UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews); @@ -914,8 +914,7 @@ namespace dxvk { template void ResolveSrvHazards( - T* pView, - D3D11ShaderResourceBindings& Bindings); + T* pView); template void ResolveCsSrvHazards( @@ -941,8 +940,7 @@ namespace dxvk { D3D11SamplerBindings& Bindings); template - void RestoreShaderResources( - D3D11ShaderResourceBindings& Bindings); + void RestoreShaderResources(); template void RestoreUnorderedAccessViews( @@ -964,7 +962,6 @@ namespace dxvk { template void SetShaderResources( - D3D11ShaderResourceBindings& Bindings, UINT StartSlot, UINT NumResources, ID3D11ShaderResourceView* const* ppResources); diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 9e1388de0..260e8c005 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -68,16 +68,30 @@ namespace dxvk { using D3D11CbvBindings = D3D11ShaderStageState; + /** + * \brief Shader resource bindings + * + * Stores bound shader resource views, as well as a bit + * set of views that are potentially hazardous. + */ + struct D3D11ShaderStageSrvBinding { + std::array, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> views = { }; + DxvkBindingSet hazardous = { }; + + void reset() { + for (uint32_t i = 0; i < views.size(); i++) + views[i] = nullptr; + + hazardous.clear(); + } + }; + + using D3D11SrvBindings = D3D11ShaderStageState; + using D3D11SamplerBindings = std::array< D3D11SamplerState*, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>; - struct D3D11ShaderResourceBindings { - std::array, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> views = { }; - DxvkBindingSet hazardous = { }; - }; - - using D3D11UnorderedAccessBindings = std::array< Com, D3D11_1_UAV_SLOT_COUNT>; @@ -85,35 +99,30 @@ namespace dxvk { struct D3D11ContextStateVS { Com shader = nullptr; D3D11SamplerBindings samplers = { }; - D3D11ShaderResourceBindings shaderResources = { }; }; struct D3D11ContextStateHS { Com shader = nullptr; D3D11SamplerBindings samplers = { }; - D3D11ShaderResourceBindings shaderResources = { }; }; struct D3D11ContextStateDS { Com shader = nullptr; D3D11SamplerBindings samplers = { }; - D3D11ShaderResourceBindings shaderResources = { }; }; struct D3D11ContextStateGS { Com shader = nullptr; D3D11SamplerBindings samplers = { }; - D3D11ShaderResourceBindings shaderResources = { }; }; struct D3D11ContextStatePS { Com shader = nullptr; D3D11SamplerBindings samplers = { }; - D3D11ShaderResourceBindings shaderResources = { }; D3D11UnorderedAccessBindings unorderedAccessViews = { }; }; @@ -121,7 +130,6 @@ namespace dxvk { struct D3D11ContextStateCS { Com shader = nullptr; D3D11SamplerBindings samplers = { }; - D3D11ShaderResourceBindings shaderResources = { }; D3D11UnorderedAccessBindings unorderedAccessViews = { }; DxvkBindingSet uavMask = { }; @@ -222,6 +230,7 @@ namespace dxvk { D3D11ContextStatePR pr; D3D11CbvBindings cbv; + D3D11SrvBindings srv; }; } \ No newline at end of file From 8383423fbe69a43175a54f0778e309ac09c1b1df Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 16:05:21 +0200 Subject: [PATCH 0416/1348] [d3d11] Refactor sampler state --- src/d3d11/d3d11_context.cpp | 83 +++++++++++++-------------------- src/d3d11/d3d11_context.h | 6 +-- src/d3d11/d3d11_context_state.h | 25 ++++++---- 3 files changed, 50 insertions(+), 64 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 4688f147c..244ee11f2 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1373,9 +1373,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetSamplers( - m_state.vs.samplers, - StartSlot, NumSamplers, - ppSamplers); + StartSlot, NumSamplers, ppSamplers); } @@ -1441,7 +1439,7 @@ namespace dxvk { ID3D11SamplerState** ppSamplers) { D3D10DeviceLock lock = LockContext(); - GetSamplers(m_state.vs.samplers, + GetSamplers( StartSlot, NumSamplers, ppSamplers); } @@ -1513,9 +1511,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetSamplers( - m_state.hs.samplers, - StartSlot, NumSamplers, - ppSamplers); + StartSlot, NumSamplers, ppSamplers); } @@ -1581,7 +1577,7 @@ namespace dxvk { ID3D11SamplerState** ppSamplers) { D3D10DeviceLock lock = LockContext(); - GetSamplers(m_state.hs.samplers, + GetSamplers( StartSlot, NumSamplers, ppSamplers); } @@ -1653,9 +1649,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetSamplers( - m_state.ds.samplers, - StartSlot, NumSamplers, - ppSamplers); + StartSlot, NumSamplers, ppSamplers); } @@ -1721,7 +1715,7 @@ namespace dxvk { ID3D11SamplerState** ppSamplers) { D3D10DeviceLock lock = LockContext(); - GetSamplers(m_state.ds.samplers, + GetSamplers( StartSlot, NumSamplers, ppSamplers); } @@ -1793,9 +1787,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetSamplers( - m_state.gs.samplers, - StartSlot, NumSamplers, - ppSamplers); + StartSlot, NumSamplers, ppSamplers); } @@ -1861,7 +1853,7 @@ namespace dxvk { ID3D11SamplerState** ppSamplers) { D3D10DeviceLock lock = LockContext(); - GetSamplers(m_state.gs.samplers, + GetSamplers( StartSlot, NumSamplers, ppSamplers); } @@ -1933,9 +1925,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetSamplers( - m_state.ps.samplers, - StartSlot, NumSamplers, - ppSamplers); + StartSlot, NumSamplers, ppSamplers); } @@ -2001,7 +1991,7 @@ namespace dxvk { ID3D11SamplerState** ppSamplers) { D3D10DeviceLock lock = LockContext(); - GetSamplers(m_state.ps.samplers, + GetSamplers( StartSlot, NumSamplers, ppSamplers); } @@ -2073,9 +2063,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); SetSamplers( - m_state.cs.samplers, - StartSlot, NumSamplers, - ppSamplers); + StartSlot, NumSamplers, ppSamplers); } @@ -2198,7 +2186,7 @@ namespace dxvk { ID3D11SamplerState** ppSamplers) { D3D10DeviceLock lock = LockContext(); - GetSamplers(m_state.cs.samplers, + GetSamplers( StartSlot, NumSamplers, ppSamplers); } @@ -3773,14 +3761,16 @@ namespace dxvk { template + template void D3D11CommonContext::GetSamplers( - const D3D11SamplerBindings& Bindings, UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) { + const auto& bindings = m_state.samplers[ShaderStage]; + for (uint32_t i = 0; i < NumSamplers; i++) { - ppSamplers[i] = StartSlot + i < Bindings.size() - ? ref(Bindings[StartSlot + i]) + ppSamplers[i] = StartSlot + i < bindings.samplers.size() + ? ref(bindings.samplers[StartSlot + i]) : nullptr; } } @@ -3905,16 +3895,7 @@ namespace dxvk { // Reset resource bindings m_state.cbv.reset(); m_state.srv.reset(); - - // Default samplers - for (uint32_t i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) { - m_state.vs.samplers[i] = nullptr; - m_state.hs.samplers[i] = nullptr; - m_state.ds.samplers[i] = nullptr; - m_state.gs.samplers[i] = nullptr; - m_state.ps.samplers[i] = nullptr; - m_state.cs.samplers[i] = nullptr; - } + m_state.samplers.reset(); // Default UAVs for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) { @@ -4132,13 +4113,6 @@ namespace dxvk { RestoreConstantBuffers(); RestoreConstantBuffers(); - RestoreSamplers (m_state.vs.samplers); - RestoreSamplers (m_state.hs.samplers); - RestoreSamplers (m_state.ds.samplers); - RestoreSamplers(m_state.gs.samplers); - RestoreSamplers (m_state.ps.samplers); - RestoreSamplers (m_state.cs.samplers); - RestoreShaderResources(); RestoreShaderResources(); RestoreShaderResources(); @@ -4148,6 +4122,13 @@ namespace dxvk { RestoreUnorderedAccessViews (m_state.ps.unorderedAccessViews); RestoreUnorderedAccessViews (m_state.cs.unorderedAccessViews); + + RestoreSamplers(); + RestoreSamplers(); + RestoreSamplers(); + RestoreSamplers(); + RestoreSamplers(); + RestoreSamplers(); } @@ -4166,12 +4147,12 @@ namespace dxvk { template template - void D3D11CommonContext::RestoreSamplers( - D3D11SamplerBindings& Bindings) { + void D3D11CommonContext::RestoreSamplers() { + const auto& bindings = m_state.samplers[Stage]; uint32_t slotId = computeSamplerBinding(Stage, 0); - for (uint32_t i = 0; i < Bindings.size(); i++) - BindSampler(slotId + i, Bindings[i]); + for (uint32_t i = 0; i < bindings.samplers.size(); i++) + BindSampler(slotId + i, bindings.samplers[i]); } @@ -4337,17 +4318,17 @@ namespace dxvk { template template void D3D11CommonContext::SetSamplers( - D3D11SamplerBindings& Bindings, UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { + auto& bindings = m_state.samplers[ShaderStage]; uint32_t slotId = computeSamplerBinding(ShaderStage, StartSlot); for (uint32_t i = 0; i < NumSamplers; i++) { auto sampler = static_cast(ppSamplers[i]); - if (Bindings[StartSlot + i] != sampler) { - Bindings[StartSlot + i] = sampler; + if (bindings.samplers[StartSlot + i] != sampler) { + bindings.samplers[StartSlot + i] = sampler; BindSampler(slotId + i, sampler); } } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 5c47ab553..41df199e8 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -900,8 +900,8 @@ namespace dxvk { UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews); + template void GetSamplers( - const D3D11SamplerBindings& Bindings, UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers); @@ -936,8 +936,7 @@ namespace dxvk { void RestoreConstantBuffers(); template - void RestoreSamplers( - D3D11SamplerBindings& Bindings); + void RestoreSamplers(); template void RestoreShaderResources(); @@ -968,7 +967,6 @@ namespace dxvk { template void SetSamplers( - D3D11SamplerBindings& Bindings, UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers); diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 260e8c005..7135990d5 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -87,10 +87,22 @@ namespace dxvk { }; using D3D11SrvBindings = D3D11ShaderStageState; + + /** + * \brief Sampler bindings + * + * Stores bound samplers. + */ + struct D3D11ShaderStageSamplerBinding { + std::array samplers = { }; + + void reset() { + for (uint32_t i = 0; i < samplers.size(); i++) + samplers[i] = nullptr; + } + }; - using D3D11SamplerBindings = std::array< - D3D11SamplerState*, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT>; - + using D3D11SamplerBindings = D3D11ShaderStageState; using D3D11UnorderedAccessBindings = std::array< Com, D3D11_1_UAV_SLOT_COUNT>; @@ -98,38 +110,32 @@ namespace dxvk { struct D3D11ContextStateVS { Com shader = nullptr; - D3D11SamplerBindings samplers = { }; }; struct D3D11ContextStateHS { Com shader = nullptr; - D3D11SamplerBindings samplers = { }; }; struct D3D11ContextStateDS { Com shader = nullptr; - D3D11SamplerBindings samplers = { }; }; struct D3D11ContextStateGS { Com shader = nullptr; - D3D11SamplerBindings samplers = { }; }; struct D3D11ContextStatePS { Com shader = nullptr; - D3D11SamplerBindings samplers = { }; D3D11UnorderedAccessBindings unorderedAccessViews = { }; }; struct D3D11ContextStateCS { Com shader = nullptr; - D3D11SamplerBindings samplers = { }; D3D11UnorderedAccessBindings unorderedAccessViews = { }; DxvkBindingSet uavMask = { }; @@ -231,6 +237,7 @@ namespace dxvk { D3D11CbvBindings cbv; D3D11SrvBindings srv; + D3D11SamplerBindings samplers; }; } \ No newline at end of file From 4e1f6e5efd407148f17c93ec7f7cb8b1c82dfde9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 16:23:47 +0200 Subject: [PATCH 0417/1348] [d3d11] Refactor unordered access view and output merger state --- src/d3d11/d3d11_context.cpp | 132 +++++++++++++------------------- src/d3d11/d3d11_context.h | 3 +- src/d3d11/d3d11_context_state.h | 68 +++++++++++++--- 3 files changed, 112 insertions(+), 91 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 244ee11f2..72206278d 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2082,16 +2082,16 @@ namespace dxvk { uint32_t uavSlotId = computeUavBinding (DxbcProgramType::ComputeShader, 0); uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::ComputeShader, 0); - int32_t uavId = m_state.cs.uavMask.findNext(0); + int32_t uavId = m_state.uav.mask.findNext(0); while (uavId >= 0) { if (uint32_t(uavId) < StartSlot || uint32_t(uavId) >= StartSlot + NumUAVs) { for (uint32_t i = 0; i < NumUAVs; i++) { auto uav = static_cast(ppUnorderedAccessViews[i]); - if (CheckViewOverlap(uav, m_state.cs.unorderedAccessViews[uavId].ptr())) { - m_state.cs.unorderedAccessViews[uavId] = nullptr; - m_state.cs.uavMask.clr(uavId); + if (CheckViewOverlap(uav, m_state.uav.views[uavId].ptr())) { + m_state.uav.views[uavId] = nullptr; + m_state.uav.mask.clr(uavId); BindUnorderedAccessView( uavSlotId + uavId, nullptr, @@ -2099,9 +2099,9 @@ namespace dxvk { } } - uavId = m_state.cs.uavMask.findNext(uavId + 1); + uavId = m_state.uav.mask.findNext(uavId + 1); } else { - uavId = m_state.cs.uavMask.findNext(StartSlot + NumUAVs); + uavId = m_state.uav.mask.findNext(StartSlot + NumUAVs); } } @@ -2110,9 +2110,9 @@ namespace dxvk { auto uav = static_cast(ppUnorderedAccessViews[i]); auto ctr = pUAVInitialCounts ? pUAVInitialCounts[i] : ~0u; - if (m_state.cs.unorderedAccessViews[StartSlot + i] != uav || ctr != ~0u) { - m_state.cs.unorderedAccessViews[StartSlot + i] = uav; - m_state.cs.uavMask.set(StartSlot + i, uav != nullptr); + if (m_state.uav.views[StartSlot + i] != uav || ctr != ~0u) { + m_state.uav.views[StartSlot + i] = uav; + m_state.uav.mask.set(StartSlot + i, uav != nullptr); BindUnorderedAccessView( uavSlotId + StartSlot + i, uav, @@ -2199,8 +2199,8 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); for (uint32_t i = 0; i < NumUAVs; i++) { - ppUnorderedAccessViews[i] = StartSlot + i < m_state.cs.unorderedAccessViews.size() - ? m_state.cs.unorderedAccessViews[StartSlot + i].ref() + ppUnorderedAccessViews[i] = StartSlot + i < m_state.uav.views.size() + ? m_state.uav.views[StartSlot + i].ref() : nullptr; } } @@ -2311,19 +2311,19 @@ namespace dxvk { if (ppRenderTargetViews) { for (UINT i = 0; i < NumRTVs; i++) { - ppRenderTargetViews[i] = i < m_state.om.renderTargetViews.size() - ? m_state.om.renderTargetViews[i].ref() + ppRenderTargetViews[i] = i < m_state.om.rtvs.size() + ? m_state.om.rtvs[i].ref() : nullptr; } } if (ppDepthStencilView) - *ppDepthStencilView = m_state.om.depthStencilView.ref(); + *ppDepthStencilView = m_state.om.dsv.ref(); if (ppUnorderedAccessViews) { for (UINT i = 0; i < NumUAVs; i++) { - ppUnorderedAccessViews[i] = UAVStartSlot + i < m_state.ps.unorderedAccessViews.size() - ? m_state.ps.unorderedAccessViews[UAVStartSlot + i].ref() + ppUnorderedAccessViews[i] = UAVStartSlot + i < m_state.om.uavs.size() + ? m_state.om.uavs[UAVStartSlot + i].ref() : nullptr; } } @@ -3133,20 +3133,20 @@ namespace dxvk { // D3D11 doesn't have the concept of a framebuffer object, // so we'll just create a new one every time the render // target bindings are updated. Set up the attachments. - for (UINT i = 0; i < m_state.om.renderTargetViews.size(); i++) { - if (m_state.om.renderTargetViews[i] != nullptr) { + for (UINT i = 0; i < m_state.om.rtvs.size(); i++) { + if (m_state.om.rtvs[i] != nullptr) { attachments.color[i] = { - m_state.om.renderTargetViews[i]->GetImageView(), - m_state.om.renderTargetViews[i]->GetRenderLayout() }; - sampleCount = m_state.om.renderTargetViews[i]->GetSampleCount(); + m_state.om.rtvs[i]->GetImageView(), + m_state.om.rtvs[i]->GetRenderLayout() }; + sampleCount = m_state.om.rtvs[i]->GetSampleCount(); } } - if (m_state.om.depthStencilView != nullptr) { + if (m_state.om.dsv != nullptr) { attachments.depth = { - m_state.om.depthStencilView->GetImageView(), - m_state.om.depthStencilView->GetRenderLayout() }; - sampleCount = m_state.om.depthStencilView->GetSampleCount(); + m_state.om.dsv->GetImageView(), + m_state.om.dsv->GetRenderLayout() }; + sampleCount = m_state.om.dsv->GetSampleCount(); } // Create and bind the framebuffer object to the context @@ -3895,15 +3895,9 @@ namespace dxvk { // Reset resource bindings m_state.cbv.reset(); m_state.srv.reset(); + m_state.uav.reset(); m_state.samplers.reset(); - - // Default UAVs - for (uint32_t i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) { - m_state.ps.unorderedAccessViews[i] = nullptr; - m_state.cs.unorderedAccessViews[i] = nullptr; - } - - m_state.cs.uavMask.clear(); + m_state.om.reset(); // Default ID state m_state.id.argBuffer = nullptr; @@ -3922,24 +3916,6 @@ namespace dxvk { m_state.ia.indexBuffer.offset = 0; m_state.ia.indexBuffer.format = DXGI_FORMAT_UNKNOWN; - // Default OM State - for (uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - m_state.om.renderTargetViews[i] = nullptr; - m_state.om.depthStencilView = nullptr; - - m_state.om.cbState = nullptr; - m_state.om.dsState = nullptr; - - for (uint32_t i = 0; i < 4; i++) - m_state.om.blendFactor[i] = 1.0f; - - m_state.om.sampleCount = 0; - m_state.om.sampleMask = D3D11_DEFAULT_SAMPLE_MASK; - m_state.om.stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE; - - m_state.om.maxRtv = 0; - m_state.om.maxUav = 0; - // Default RS state m_state.rs.state = nullptr; m_state.rs.numViewports = 0; @@ -4029,14 +4005,14 @@ namespace dxvk { bool hazard = false; - if (CheckViewOverlap(pView, m_state.om.depthStencilView.ptr())) { - m_state.om.depthStencilView = nullptr; + if (CheckViewOverlap(pView, m_state.om.dsv.ptr())) { + m_state.om.dsv = nullptr; hazard = true; } for (uint32_t i = 0; i < m_state.om.maxRtv; i++) { - if (CheckViewOverlap(pView, m_state.om.renderTargetViews[i].ptr())) { - m_state.om.renderTargetViews[i] = nullptr; + if (CheckViewOverlap(pView, m_state.om.rtvs[i].ptr())) { + m_state.om.rtvs[i] = nullptr; hazard = true; } } @@ -4055,8 +4031,8 @@ namespace dxvk { uint32_t ctrSlotId = computeUavCounterBinding(DxbcProgramType::PixelShader, 0); for (uint32_t i = 0; i < m_state.om.maxUav; i++) { - if (CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr())) { - m_state.ps.unorderedAccessViews[i] = nullptr; + if (CheckViewOverlap(pView, m_state.om.uavs[i].ptr())) { + m_state.om.uavs[i] = nullptr; BindUnorderedAccessView( uavSlotId + i, nullptr, @@ -4120,8 +4096,8 @@ namespace dxvk { RestoreShaderResources(); RestoreShaderResources(); - RestoreUnorderedAccessViews (m_state.ps.unorderedAccessViews); - RestoreUnorderedAccessViews (m_state.cs.unorderedAccessViews); + RestoreUnorderedAccessViews(); + RestoreUnorderedAccessViews(); RestoreSamplers(); RestoreSamplers(); @@ -4169,15 +4145,17 @@ namespace dxvk { template template - void D3D11CommonContext::RestoreUnorderedAccessViews( - D3D11UnorderedAccessBindings& Bindings) { + void D3D11CommonContext::RestoreUnorderedAccessViews() { + const auto& views = Stage == DxbcProgramType::ComputeShader + ? m_state.uav.views + : m_state.om.uavs; + uint32_t uavSlotId = computeUavBinding (Stage, 0); uint32_t ctrSlotId = computeUavCounterBinding(Stage, 0); - for (uint32_t i = 0; i < Bindings.size(); i++) { + for (uint32_t i = 0; i < views.size(); i++) { BindUnorderedAccessView( - uavSlotId + i, - Bindings[i].ptr(), + uavSlotId + i, views[i].ptr(), ctrSlotId + i, ~0u); } } @@ -4355,13 +4333,13 @@ namespace dxvk { if (!ValidateRenderTargets(NumRTVs, ppRenderTargetViews, pDepthStencilView)) return; - for (uint32_t i = 0; i < m_state.om.renderTargetViews.size(); i++) { + for (uint32_t i = 0; i < m_state.om.rtvs.size(); i++) { auto rtv = i < NumRTVs ? static_cast(ppRenderTargetViews[i]) : nullptr; - if (m_state.om.renderTargetViews[i] != rtv) { - m_state.om.renderTargetViews[i] = rtv; + if (m_state.om.rtvs[i] != rtv) { + m_state.om.rtvs[i] = rtv; needsUpdate = true; ResolveOmSrvHazards(rtv); @@ -4372,8 +4350,8 @@ namespace dxvk { auto dsv = static_cast(pDepthStencilView); - if (m_state.om.depthStencilView != dsv) { - m_state.om.depthStencilView = dsv; + if (m_state.om.dsv != dsv) { + m_state.om.dsv = dsv; needsUpdate = true; ResolveOmSrvHazards(dsv); } @@ -4398,8 +4376,8 @@ namespace dxvk { ctr = pUAVInitialCounts ? pUAVInitialCounts[i - UAVStartSlot] : ~0u; } - if (m_state.ps.unorderedAccessViews[i] != uav || ctr != ~0u) { - m_state.ps.unorderedAccessViews[i] = uav; + if (m_state.om.uavs[i] != uav || ctr != ~0u) { + m_state.om.uavs[i] = uav; BindUnorderedAccessView( uavSlotId + i, uav, @@ -4487,20 +4465,20 @@ namespace dxvk { bool hazard = false; if (ShaderStage == DxbcProgramType::ComputeShader) { - int32_t uav = m_state.cs.uavMask.findNext(0); + int32_t uav = m_state.uav.mask.findNext(0); while (uav >= 0 && !hazard) { - hazard = CheckViewOverlap(pView, m_state.cs.unorderedAccessViews[uav].ptr()); - uav = m_state.cs.uavMask.findNext(uav + 1); + hazard = CheckViewOverlap(pView, m_state.uav.views[uav].ptr()); + uav = m_state.uav.mask.findNext(uav + 1); } } else { - hazard = CheckViewOverlap(pView, m_state.om.depthStencilView.ptr()); + hazard = CheckViewOverlap(pView, m_state.om.dsv.ptr()); for (uint32_t i = 0; !hazard && i < m_state.om.maxRtv; i++) - hazard = CheckViewOverlap(pView, m_state.om.renderTargetViews[i].ptr()); + hazard = CheckViewOverlap(pView, m_state.om.rtvs[i].ptr()); for (uint32_t i = 0; !hazard && i < m_state.om.maxUav; i++) - hazard = CheckViewOverlap(pView, m_state.ps.unorderedAccessViews[i].ptr()); + hazard = CheckViewOverlap(pView, m_state.om.uavs[i].ptr()); } return hazard; diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 41df199e8..399777762 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -942,8 +942,7 @@ namespace dxvk { void RestoreShaderResources(); template - void RestoreUnorderedAccessViews( - D3D11UnorderedAccessBindings& Bindings); + void RestoreUnorderedAccessViews(); template void SetConstantBuffers( diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 7135990d5..e13e557f4 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -103,11 +103,28 @@ namespace dxvk { }; using D3D11SamplerBindings = D3D11ShaderStageState; + + /** + * \brief UAV bindings + * + * Stores bound UAVs. For compute shader UAVs, + * we also store a bit mask of bound UAVs. + */ + using D3D11ShaderStageUavBinding = std::array, D3D11_1_UAV_SLOT_COUNT>; - using D3D11UnorderedAccessBindings = std::array< - Com, D3D11_1_UAV_SLOT_COUNT>; - - + struct D3D11UavBindings { + D3D11ShaderStageUavBinding views = { }; + DxvkBindingSet mask = { }; + + void reset() { + for (uint32_t i = 0; i < views.size(); i++) + views[i] = nullptr; + + mask.clear(); + } + }; + + struct D3D11ContextStateVS { Com shader = nullptr; }; @@ -130,15 +147,11 @@ namespace dxvk { struct D3D11ContextStatePS { Com shader = nullptr; - D3D11UnorderedAccessBindings unorderedAccessViews = { }; }; struct D3D11ContextStateCS { Com shader = nullptr; - D3D11UnorderedAccessBindings unorderedAccessViews = { }; - - DxvkBindingSet uavMask = { }; }; @@ -170,10 +183,17 @@ namespace dxvk { D3D11IndexBufferBinding indexBuffer = { }; }; + /** + * \brief Output merger state + * + * Stores RTV, DSV, and graphics UAV bindings, as well as related state. + */ + using D3D11RenderTargetViewBinding = std::array, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT>; struct D3D11ContextStateOM { - std::array, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> renderTargetViews = { }; - Com depthStencilView = { }; + D3D11ShaderStageUavBinding uavs = { }; + D3D11RenderTargetViewBinding rtvs = { }; + Com dsv = { }; D3D11BlendState* cbState = nullptr; D3D11DepthStencilState* dsState = nullptr; @@ -181,11 +201,34 @@ namespace dxvk { FLOAT blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; UINT sampleCount = 0u; - UINT sampleMask = 0xFFFFFFFFu; - UINT stencilRef = 0u; + UINT sampleMask = D3D11_DEFAULT_SAMPLE_MASK; + UINT stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE; UINT maxRtv = 0u; UINT maxUav = 0u; + + void reset() { + for (uint32_t i = 0; i < maxUav; i++) + uavs[i] = nullptr; + + for (uint32_t i = 0; i < maxRtv; i++) + rtvs[i] = nullptr; + + dsv = nullptr; + + cbState = nullptr; + dsState = nullptr; + + for (uint32_t i = 0; i < 4; i++) + blendFactor[i] = 1.0f; + + sampleCount = 0u; + sampleMask = D3D11_DEFAULT_SAMPLE_MASK; + stencilRef = D3D11_DEFAULT_STENCIL_REFERENCE; + + maxRtv = 0; + maxUav = 0; + } }; @@ -237,6 +280,7 @@ namespace dxvk { D3D11CbvBindings cbv; D3D11SrvBindings srv; + D3D11UavBindings uav; D3D11SamplerBindings samplers; }; From 95ab1465abfb8e21c4edaa8d1f57a64e6852a035 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 16:34:49 +0200 Subject: [PATCH 0418/1348] [d3d11] Add reset method to more context state --- src/d3d11/d3d11_context.cpp | 46 +++-------------- src/d3d11/d3d11_context_state.h | 87 +++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 53 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 72206278d..fe7bf4d9b 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3892,49 +3892,19 @@ namespace dxvk { m_state.ps.shader = nullptr; m_state.cs.shader = nullptr; + // Reset render state + m_state.id.reset(); + m_state.ia.reset(); + m_state.om.reset(); + m_state.rs.reset(); + m_state.so.reset(); + m_state.pr.reset(); + // Reset resource bindings m_state.cbv.reset(); m_state.srv.reset(); m_state.uav.reset(); m_state.samplers.reset(); - m_state.om.reset(); - - // Default ID state - m_state.id.argBuffer = nullptr; - - // Default IA state - m_state.ia.inputLayout = nullptr; - m_state.ia.primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; - - for (uint32_t i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) { - m_state.ia.vertexBuffers[i].buffer = nullptr; - m_state.ia.vertexBuffers[i].offset = 0; - m_state.ia.vertexBuffers[i].stride = 0; - } - - m_state.ia.indexBuffer.buffer = nullptr; - m_state.ia.indexBuffer.offset = 0; - m_state.ia.indexBuffer.format = DXGI_FORMAT_UNKNOWN; - - // Default RS state - m_state.rs.state = nullptr; - m_state.rs.numViewports = 0; - m_state.rs.numScissors = 0; - - for (uint32_t i = 0; i < D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++) { - m_state.rs.viewports[i] = D3D11_VIEWPORT { }; - m_state.rs.scissors [i] = D3D11_RECT { }; - } - - // Default SO state - for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) { - m_state.so.targets[i].buffer = nullptr; - m_state.so.targets[i].offset = 0; - } - - // Default predication - m_state.pr.predicateObject = nullptr; - m_state.pr.predicateValue = FALSE; } diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index e13e557f4..46ffd287d 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -154,33 +154,41 @@ namespace dxvk { Com shader = nullptr; }; - + /** + * \brief Input assembly state + * + * Stores vertex buffers, the index buffer, the + * input layout, and the dynamic primitive topology. + */ struct D3D11VertexBufferBinding { Com buffer = nullptr; UINT offset = 0; UINT stride = 0; }; - struct D3D11IndexBufferBinding { Com buffer = nullptr; UINT offset = 0; DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; }; - - struct D3D11ContextStateID { - Com argBuffer = nullptr; - Com cntBuffer = nullptr; - }; - - struct D3D11ContextStateIA { Com inputLayout = nullptr; D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; std::array vertexBuffers = { }; D3D11IndexBufferBinding indexBuffer = { }; + + void reset() { + inputLayout = nullptr; + + primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + + for (uint32_t i = 0; i < vertexBuffers.size(); i++) + vertexBuffers[i] = D3D11VertexBufferBinding(); + + indexBuffer = D3D11IndexBufferBinding(); + } }; /** @@ -231,7 +239,27 @@ namespace dxvk { } }; - + /** + * \brief Indirect draw state + * + * Stores the current indirct draw + * argument and draw count buffer. + */ + struct D3D11ContextStateID { + Com argBuffer = nullptr; + Com cntBuffer = nullptr; + + void reset() { + argBuffer = nullptr; + cntBuffer = nullptr; + } + }; + + /** + * \brief Rasterizer state + * + * Stores viewport info and the rasterizer state object. + */ struct D3D11ContextStateRS { uint32_t numViewports = 0; uint32_t numScissors = 0; @@ -240,26 +268,55 @@ namespace dxvk { std::array scissors = { }; D3D11RasterizerState* state = nullptr; + + void reset() { + for (uint32_t i = 0; i < numViewports; i++) + viewports[i] = D3D11_VIEWPORT(); + + for (uint32_t i = 0; i < numScissors; i++) + scissors[i] = D3D11_RECT(); + + numViewports = 0; + numScissors = 0; + + state = nullptr; + } }; - + /** + * \brief Stream output binding + * + * Stores stream output buffers with offset. + */ struct D3D11ContextSoTarget { Com buffer = nullptr; UINT offset = 0; }; - struct D3D11ContextStateSO { std::array targets = { }; + + void reset() { + for (uint32_t i = 0; i < targets.size(); i++) + targets[i] = D3D11ContextSoTarget(); + } }; - + /** + * \brief Predication state + * + * Stores predication info. + */ struct D3D11ContextStatePR { Com predicateObject = nullptr; - BOOL predicateValue = FALSE; + BOOL predicateValue = false; + + void reset() { + predicateObject = nullptr; + predicateValue = false; + } }; - /** * \brief Context state */ From 9f07bc6532fafe10f3a2cdc5abd2c287517f7389 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 16:37:23 +0200 Subject: [PATCH 0419/1348] [d3d11] Refactor shader state --- src/d3d11/d3d11_context.cpp | 62 ++++++++++++++++----------------- src/d3d11/d3d11_context_state.h | 44 ++++------------------- 2 files changed, 38 insertions(+), 68 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index fe7bf4d9b..ac4ec6332 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1318,8 +1318,8 @@ namespace dxvk { if (NumClassInstances) Logger::err("D3D11: Class instances not supported"); - if (m_state.vs.shader != shader) { - m_state.vs.shader = shader; + if (m_state.vs != shader) { + m_state.vs = shader; BindShader(GetCommonShader(shader)); } @@ -1385,7 +1385,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); if (ppVertexShader) - *ppVertexShader = m_state.vs.shader.ref(); + *ppVertexShader = m_state.vs.ref(); if (pNumClassInstances) *pNumClassInstances = 0; @@ -1456,8 +1456,8 @@ namespace dxvk { if (NumClassInstances) Logger::err("D3D11: Class instances not supported"); - if (m_state.hs.shader != shader) { - m_state.hs.shader = shader; + if (m_state.hs != shader) { + m_state.hs = shader; BindShader(GetCommonShader(shader)); } @@ -1523,7 +1523,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); if (ppHullShader) - *ppHullShader = m_state.hs.shader.ref(); + *ppHullShader = m_state.hs.ref(); if (pNumClassInstances) *pNumClassInstances = 0; @@ -1594,8 +1594,8 @@ namespace dxvk { if (NumClassInstances) Logger::err("D3D11: Class instances not supported"); - if (m_state.ds.shader != shader) { - m_state.ds.shader = shader; + if (m_state.ds != shader) { + m_state.ds = shader; BindShader(GetCommonShader(shader)); } @@ -1661,7 +1661,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); if (ppDomainShader) - *ppDomainShader = m_state.ds.shader.ref(); + *ppDomainShader = m_state.ds.ref(); if (pNumClassInstances) *pNumClassInstances = 0; @@ -1732,8 +1732,8 @@ namespace dxvk { if (NumClassInstances) Logger::err("D3D11: Class instances not supported"); - if (m_state.gs.shader != shader) { - m_state.gs.shader = shader; + if (m_state.gs != shader) { + m_state.gs = shader; BindShader(GetCommonShader(shader)); } @@ -1799,7 +1799,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); if (ppGeometryShader) - *ppGeometryShader = m_state.gs.shader.ref(); + *ppGeometryShader = m_state.gs.ref(); if (pNumClassInstances) *pNumClassInstances = 0; @@ -1870,8 +1870,8 @@ namespace dxvk { if (NumClassInstances) Logger::err("D3D11: Class instances not supported"); - if (m_state.ps.shader != shader) { - m_state.ps.shader = shader; + if (m_state.ps != shader) { + m_state.ps = shader; BindShader(GetCommonShader(shader)); } @@ -1937,7 +1937,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); if (ppPixelShader) - *ppPixelShader = m_state.ps.shader.ref(); + *ppPixelShader = m_state.ps.ref(); if (pNumClassInstances) *pNumClassInstances = 0; @@ -2008,8 +2008,8 @@ namespace dxvk { if (NumClassInstances) Logger::err("D3D11: Class instances not supported"); - if (m_state.cs.shader != shader) { - m_state.cs.shader = shader; + if (m_state.cs != shader) { + m_state.cs = shader; BindShader(GetCommonShader(shader)); } @@ -2132,7 +2132,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); if (ppComputeShader) - *ppComputeShader = m_state.cs.shader.ref(); + *ppComputeShader = m_state.cs.ref(); if (pNumClassInstances) *pNumClassInstances = 0; @@ -3884,13 +3884,13 @@ namespace dxvk { template void D3D11CommonContext::ResetContextState() { - // Default shaders - m_state.vs.shader = nullptr; - m_state.hs.shader = nullptr; - m_state.ds.shader = nullptr; - m_state.gs.shader = nullptr; - m_state.ps.shader = nullptr; - m_state.cs.shader = nullptr; + // Reset shaders + m_state.vs = nullptr; + m_state.hs = nullptr; + m_state.ds = nullptr; + m_state.gs = nullptr; + m_state.ps = nullptr; + m_state.cs = nullptr; // Reset render state m_state.id.reset(); @@ -4016,12 +4016,12 @@ namespace dxvk { void D3D11CommonContext::RestoreCommandListState() { BindFramebuffer(); - BindShader (GetCommonShader(m_state.vs.shader.ptr())); - BindShader (GetCommonShader(m_state.hs.shader.ptr())); - BindShader (GetCommonShader(m_state.ds.shader.ptr())); - BindShader (GetCommonShader(m_state.gs.shader.ptr())); - BindShader (GetCommonShader(m_state.ps.shader.ptr())); - BindShader (GetCommonShader(m_state.cs.shader.ptr())); + BindShader(GetCommonShader(m_state.vs.ptr())); + BindShader(GetCommonShader(m_state.hs.ptr())); + BindShader(GetCommonShader(m_state.ds.ptr())); + BindShader(GetCommonShader(m_state.gs.ptr())); + BindShader(GetCommonShader(m_state.ps.ptr())); + BindShader(GetCommonShader(m_state.cs.ptr())); ApplyInputLayout(); ApplyPrimitiveTopology(); diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 46ffd287d..e011cf38c 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -124,36 +124,6 @@ namespace dxvk { } }; - - struct D3D11ContextStateVS { - Com shader = nullptr; - }; - - - struct D3D11ContextStateHS { - Com shader = nullptr; - }; - - - struct D3D11ContextStateDS { - Com shader = nullptr; - }; - - - struct D3D11ContextStateGS { - Com shader = nullptr; - }; - - - struct D3D11ContextStatePS { - Com shader = nullptr; - }; - - - struct D3D11ContextStateCS { - Com shader = nullptr; - }; - /** * \brief Input assembly state * @@ -321,13 +291,13 @@ namespace dxvk { * \brief Context state */ struct D3D11ContextState { - D3D11ContextStateCS cs; - D3D11ContextStateDS ds; - D3D11ContextStateGS gs; - D3D11ContextStateHS hs; - D3D11ContextStatePS ps; - D3D11ContextStateVS vs; - + Com vs; + Com hs; + Com ds; + Com gs; + Com ps; + Com cs; + D3D11ContextStateID id; D3D11ContextStateIA ia; D3D11ContextStateOM om; From ebbb77518ab0fc0e7b008ed5d6b124d69d09120a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 17:29:24 +0200 Subject: [PATCH 0420/1348] [d3d11] Clean up after performing video blit Otherwise, with the upcoming clear/restore optimizations, we'd possibly leave some resources bound. --- src/d3d11/d3d11_video.cpp | 21 ++++++++++++++++++++- src/d3d11/d3d11_video.h | 2 ++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 4561f6d4e..b8fd949fd 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1055,8 +1055,10 @@ namespace dxvk { BlitStream(streamState, &pStreams[i]); } - if (hasStreamsEnabled) + if (hasStreamsEnabled) { + UnbindResources(); m_ctx->RestoreCommandListState(); + } return S_OK; } @@ -1299,6 +1301,23 @@ namespace dxvk { ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, 2 + i, Rc(cViews[i]), nullptr); ctx->draw(3, 1, 0, 0); + + ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 1, nullptr); + + for (uint32_t i = 0; i < cViews.size(); i++) + ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, 2 + i, nullptr, nullptr); + }); + } + + + void D3D11VideoContext::UnbindResources() { + m_ctx->EmitCs([this] (DxvkContext* ctx) { + ctx->bindRenderTargets(DxvkRenderTargets()); + + ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, nullptr); + ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, nullptr); + + ctx->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice()); }); } diff --git a/src/d3d11/d3d11_video.h b/src/d3d11/d3d11_video.h index 435b7c57e..e883bbb00 100644 --- a/src/d3d11/d3d11_video.h +++ b/src/d3d11/d3d11_video.h @@ -608,6 +608,8 @@ namespace dxvk { const D3D11VideoProcessorStreamState* pStreamState, const D3D11_VIDEO_PROCESSOR_STREAM* pStream); + void UnbindResources(); + }; } From 18c4ca8e92eaa399016e405c484022ea3c9d291b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 17:20:49 +0200 Subject: [PATCH 0421/1348] [d3d11] Introduce D3D11MaxUsedBindings And use it in ResetCommandListState, in order to avoid redundant state changes. --- src/d3d11/d3d11_context.cpp | 46 +++++++++++++++++++++++++-------- src/d3d11/d3d11_context.h | 2 ++ src/d3d11/d3d11_context_state.h | 22 +++++++++++++++- 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index ac4ec6332..471c9a079 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3776,9 +3776,32 @@ namespace dxvk { } + template + D3D11MaxUsedBindings D3D11CommonContext::GetMaxUsedBindings() { + D3D11MaxUsedBindings result; + + for (uint32_t i = 0; i < result.stages.size(); i++) { + result.stages[i].cbvCount = D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; + result.stages[i].srvCount = D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; + result.stages[i].uavCount = 0; + result.stages[i].samplerCount = D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; + result.stages[i].reserved = 0; + } + + result.stages[uint32_t(DxbcProgramType::PixelShader)].uavCount = D3D11_1_UAV_SLOT_COUNT; + result.stages[uint32_t(DxbcProgramType::ComputeShader)].uavCount = D3D11_1_UAV_SLOT_COUNT; + + result.vbCount = D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; + result.soCount = D3D11_SO_BUFFER_SLOT_COUNT; + return result; + } + + template void D3D11CommonContext::ResetCommandListState() { - EmitCs([] (DxvkContext* ctx) { + EmitCs([ + cUsedBindings = GetMaxUsedBindings() + ] (DxvkContext* ctx) { // Reset render targets ctx->bindRenderTargets(DxvkRenderTargets()); @@ -3825,11 +3848,11 @@ namespace dxvk { // Unbind index and vertex buffers ctx->bindIndexBuffer(DxvkBufferSlice(), VK_INDEX_TYPE_UINT32); - for (uint32_t i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + for (uint32_t i = 0; i < cUsedBindings.vbCount; i++) ctx->bindVertexBuffer(i, DxvkBufferSlice(), 0); // Unbind transform feedback buffers - for (uint32_t i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) + for (uint32_t i = 0; i < cUsedBindings.soCount; i++) ctx->bindXfbBuffer(i, DxvkBufferSlice(), DxvkBufferSlice()); // Unbind per-shader stage resources @@ -3837,24 +3860,25 @@ namespace dxvk { auto programType = DxbcProgramType(i); auto stage = GetShaderStage(programType); - ctx->bindShader(stage, nullptr); - // Unbind constant buffers, including the shader's ICB auto cbSlotId = computeConstantBufferBinding(programType, 0); - for (uint32_t j = 0; j <= D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; j++) + ctx->bindShader(stage, nullptr); + ctx->bindResourceBuffer(stage, cbSlotId + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, DxvkBufferSlice()); + + for (uint32_t j = 0; j < cUsedBindings.stages[i].cbvCount; j++) ctx->bindResourceBuffer(stage, cbSlotId + j, DxvkBufferSlice()); // Unbind shader resource views auto srvSlotId = computeSrvBinding(programType, 0); - for (uint32_t j = 0; j < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; j++) + for (uint32_t j = 0; j < cUsedBindings.stages[i].srvCount; j++) ctx->bindResourceView(stage, srvSlotId + j, nullptr, nullptr); // Unbind texture samplers auto samplerSlotId = computeSamplerBinding(programType, 0); - for (uint32_t j = 0; j < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; j++) + for (uint32_t j = 0; j < cUsedBindings.stages[i].samplerCount; j++) ctx->bindResourceSampler(stage, samplerSlotId + j, nullptr); // Unbind UAVs for supported stages @@ -3867,9 +3891,9 @@ namespace dxvk { auto uavSlotId = computeUavBinding(programType, 0); auto ctrSlotId = computeUavCounterBinding(programType, 0); - for (uint32_t j = 0; j < D3D11_1_UAV_SLOT_COUNT; j++) { - ctx->bindResourceView (stages, uavSlotId, nullptr, nullptr); - ctx->bindResourceBuffer (stages, ctrSlotId, DxvkBufferSlice()); + for (uint32_t j = 0; j < cUsedBindings.stages[i].uavCount; j++) { + ctx->bindResourceView(stages, uavSlotId, nullptr, nullptr); + ctx->bindResourceBuffer(stages, ctrSlotId, DxvkBufferSlice()); } } } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 399777762..5ba55507c 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -906,6 +906,8 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); + D3D11MaxUsedBindings GetMaxUsedBindings(); + void ResetCommandListState(); void ResetContextState(); diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index e011cf38c..66944d12e 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -310,5 +310,25 @@ namespace dxvk { D3D11UavBindings uav; D3D11SamplerBindings samplers; }; - + + /** + * \brief Maximum used binding numbers in a shader stage + */ + struct D3D11MaxUsedStageBindings { + uint32_t cbvCount : 5; + uint32_t srvCount : 9; + uint32_t uavCount : 7; + uint32_t samplerCount : 5; + uint32_t reserved : 6; + }; + + /** + * \brief Maximum used binding numbers for all context state + */ + struct D3D11MaxUsedBindings { + std::array stages; + uint32_t vbCount; + uint32_t soCount; + }; + } \ No newline at end of file From 5dd2b2094071e82ad6dce36fcded7b819ba17ba4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 17:37:10 +0200 Subject: [PATCH 0422/1348] [d3d11] Track highest bound constant buffer --- src/d3d11/d3d11_context.cpp | 14 ++++++++++++-- src/d3d11/d3d11_context_state.h | 6 +++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 471c9a079..949bc489d 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1,3 +1,5 @@ +#include + #include "d3d11_context.h" #include "d3d11_context_def.h" #include "d3d11_context_imm.h" @@ -3781,7 +3783,9 @@ namespace dxvk { D3D11MaxUsedBindings result; for (uint32_t i = 0; i < result.stages.size(); i++) { - result.stages[i].cbvCount = D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; + auto stage = DxbcProgramType(i); + + result.stages[i].cbvCount = m_state.cbv[stage].maxCount; result.stages[i].srvCount = D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; result.stages[i].uavCount = 0; result.stages[i].samplerCount = D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; @@ -4108,7 +4112,7 @@ namespace dxvk { const auto& bindings = m_state.cbv[Stage]; uint32_t slotId = computeConstantBufferBinding(Stage, 0); - for (uint32_t i = 0; i < bindings.buffers.size(); i++) { + for (uint32_t i = 0; i < bindings.maxCount; i++) { BindConstantBuffer(slotId + i, bindings.buffers[i].buffer.ptr(), bindings.buffers[i].constantOffset, bindings.buffers[i].constantBound); } @@ -4182,6 +4186,9 @@ namespace dxvk { BindConstantBuffer(slotId + i, newBuffer, 0, constantCount); } } + + bindings.maxCount = std::clamp(StartSlot + NumBuffers, + bindings.maxCount, uint32_t(bindings.buffers.size())); } @@ -4254,6 +4261,9 @@ namespace dxvk { BindConstantBufferRange(slotId + i, constantOffset, constantBound); } } + + bindings.maxCount = std::clamp(StartSlot + NumBuffers, + bindings.maxCount, uint32_t(bindings.buffers.size())); } diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 66944d12e..846eb6466 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -60,9 +60,13 @@ namespace dxvk { struct D3D11ShaderStageCbvBinding { std::array buffers = { }; + uint32_t maxCount = 0; + void reset() { - for (uint32_t i = 0; i < buffers.size(); i++) + for (uint32_t i = 0; i < maxCount; i++) buffers[i] = D3D11ConstantBufferBinding(); + + maxCount = 0; } }; From 6c372e40f6fc4ebdb746314b2fafcf52b1561b87 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 17:54:51 +0200 Subject: [PATCH 0423/1348] [d3d11] Track highest bound shader resource --- src/d3d11/d3d11_context.cpp | 23 ++++++++++++++--------- src/d3d11/d3d11_context_state.h | 5 ++++- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 949bc489d..93e0de074 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3786,7 +3786,7 @@ namespace dxvk { auto stage = DxbcProgramType(i); result.stages[i].cbvCount = m_state.cbv[stage].maxCount; - result.stages[i].srvCount = D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; + result.stages[i].srvCount = m_state.srv[stage].maxCount; result.stages[i].uavCount = 0; result.stages[i].samplerCount = D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; result.stages[i].reserved = 0; @@ -4136,7 +4136,7 @@ namespace dxvk { const auto& bindings = m_state.srv[Stage]; uint32_t slotId = computeSrvBinding(Stage, 0); - for (uint32_t i = 0; i < bindings.views.size(); i++) + for (uint32_t i = 0; i < bindings.maxCount; i++) BindShaderResource(slotId + i, bindings.views[i].ptr()); } @@ -4280,20 +4280,25 @@ namespace dxvk { auto resView = static_cast(ppResources[i]); if (bindings.views[StartSlot + i] != resView) { - if (unlikely(resView && resView->TestHazards())) { - if (TestSrvHazards(resView)) - resView = nullptr; + if (likely(resView != nullptr)) { + if (unlikely(resView->TestHazards())) { + if (TestSrvHazards(resView)) + resView = nullptr; - // Only set if necessary, but don't reset it on every - // bind as this would be more expensive than a few - // redundant checks in OMSetRenderTargets and friends. - bindings.hazardous.set(StartSlot + i, resView); + // Only set if necessary, but don't reset it on every + // bind as this would be more expensive than a few + // redundant checks in OMSetRenderTargets and friends. + bindings.hazardous.set(StartSlot + i, resView); + } } bindings.views[StartSlot + i] = resView; BindShaderResource(slotId + i, resView); } } + + bindings.maxCount = std::clamp(StartSlot + NumResources, + bindings.maxCount, uint32_t(bindings.views.size())); } diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 846eb6466..6e4e737c4 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -82,11 +82,14 @@ namespace dxvk { std::array, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> views = { }; DxvkBindingSet hazardous = { }; + uint32_t maxCount = 0; + void reset() { - for (uint32_t i = 0; i < views.size(); i++) + for (uint32_t i = 0; i < maxCount; i++) views[i] = nullptr; hazardous.clear(); + maxCount = 0; } }; From 3dbd9d865953d2b8f37474427a36bcc67f8a7b5e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 18:04:17 +0200 Subject: [PATCH 0424/1348] [d3d11] Track highest bound sampler --- src/d3d11/d3d11_context.cpp | 7 +++++-- src/d3d11/d3d11_context_state.h | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 93e0de074..65516a456 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3788,7 +3788,7 @@ namespace dxvk { result.stages[i].cbvCount = m_state.cbv[stage].maxCount; result.stages[i].srvCount = m_state.srv[stage].maxCount; result.stages[i].uavCount = 0; - result.stages[i].samplerCount = D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; + result.stages[i].samplerCount = m_state.samplers[stage].maxCount; result.stages[i].reserved = 0; } @@ -4125,7 +4125,7 @@ namespace dxvk { const auto& bindings = m_state.samplers[Stage]; uint32_t slotId = computeSamplerBinding(Stage, 0); - for (uint32_t i = 0; i < bindings.samplers.size(); i++) + for (uint32_t i = 0; i < bindings.maxCount; i++) BindSampler(slotId + i, bindings.samplers[i]); } @@ -4319,6 +4319,9 @@ namespace dxvk { BindSampler(slotId + i, sampler); } } + + bindings.maxCount = std::clamp(StartSlot + NumSamplers, + bindings.maxCount, uint32_t(bindings.samplers.size())); } diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 6e4e737c4..493f95c2c 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -103,9 +103,13 @@ namespace dxvk { struct D3D11ShaderStageSamplerBinding { std::array samplers = { }; + uint32_t maxCount = 0; + void reset() { - for (uint32_t i = 0; i < samplers.size(); i++) + for (uint32_t i = 0; i < maxCount; i++) samplers[i] = nullptr; + + maxCount = 0; } }; From 934caa3fd70ab885b71894588f6c43c60db32f13 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 18:11:19 +0200 Subject: [PATCH 0425/1348] [d3d11] Track highest bound vertex buffer --- src/d3d11/d3d11_context.cpp | 7 +++++-- src/d3d11/d3d11_context_state.h | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 65516a456..c0b49bbf9 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1213,6 +1213,9 @@ namespace dxvk { BindVertexBuffer(StartSlot + i, newBuffer, pOffsets[i], pStrides[i]); } } + + m_state.ia.maxVbCount = std::clamp(StartSlot + NumBuffers, + m_state.ia.maxVbCount, uint32_t(m_state.ia.vertexBuffers.size())); } @@ -3795,7 +3798,7 @@ namespace dxvk { result.stages[uint32_t(DxbcProgramType::PixelShader)].uavCount = D3D11_1_UAV_SLOT_COUNT; result.stages[uint32_t(DxbcProgramType::ComputeShader)].uavCount = D3D11_1_UAV_SLOT_COUNT; - result.vbCount = D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; + result.vbCount = m_state.ia.maxVbCount; result.soCount = D3D11_SO_BUFFER_SLOT_COUNT; return result; } @@ -4070,7 +4073,7 @@ namespace dxvk { m_state.ia.indexBuffer.offset, m_state.ia.indexBuffer.format); - for (uint32_t i = 0; i < m_state.ia.vertexBuffers.size(); i++) { + for (uint32_t i = 0; i < m_state.ia.maxVbCount; i++) { BindVertexBuffer(i, m_state.ia.vertexBuffers[i].buffer.ptr(), m_state.ia.vertexBuffers[i].offset, diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 493f95c2c..6c11ff155 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -160,12 +160,14 @@ namespace dxvk { std::array vertexBuffers = { }; D3D11IndexBufferBinding indexBuffer = { }; + uint32_t maxVbCount = 0; + void reset() { inputLayout = nullptr; primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; - for (uint32_t i = 0; i < vertexBuffers.size(); i++) + for (uint32_t i = 0; i < maxVbCount; i++) vertexBuffers[i] = D3D11VertexBufferBinding(); indexBuffer = D3D11IndexBufferBinding(); From 7e237b33b7611dc63676d1037df2e213e8859492 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 4 Aug 2022 18:17:23 +0200 Subject: [PATCH 0426/1348] [d3d11] Track highest bound unordered access view --- src/d3d11/d3d11_context.cpp | 15 +++++++++++---- src/d3d11/d3d11_context_state.h | 5 ++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index c0b49bbf9..88a0a4c49 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2126,6 +2126,9 @@ namespace dxvk { ResolveCsSrvHazards(uav); } } + + m_state.uav.maxCount = std::clamp(StartSlot + NumUAVs, + m_state.uav.maxCount, uint32_t(m_state.uav.views.size())); } @@ -3795,8 +3798,8 @@ namespace dxvk { result.stages[i].reserved = 0; } - result.stages[uint32_t(DxbcProgramType::PixelShader)].uavCount = D3D11_1_UAV_SLOT_COUNT; - result.stages[uint32_t(DxbcProgramType::ComputeShader)].uavCount = D3D11_1_UAV_SLOT_COUNT; + result.stages[uint32_t(DxbcProgramType::PixelShader)].uavCount = m_state.om.maxUav; + result.stages[uint32_t(DxbcProgramType::ComputeShader)].uavCount = m_state.uav.maxCount; result.vbCount = m_state.ia.maxVbCount; result.soCount = D3D11_SO_BUFFER_SLOT_COUNT; @@ -4151,10 +4154,14 @@ namespace dxvk { ? m_state.uav.views : m_state.om.uavs; - uint32_t uavSlotId = computeUavBinding (Stage, 0); + uint32_t maxCount = Stage == DxbcProgramType::ComputeShader + ? m_state.uav.maxCount + : m_state.om.maxUav; + + uint32_t uavSlotId = computeUavBinding(Stage, 0); uint32_t ctrSlotId = computeUavCounterBinding(Stage, 0); - for (uint32_t i = 0; i < views.size(); i++) { + for (uint32_t i = 0; i < maxCount; i++) { BindUnorderedAccessView( uavSlotId + i, views[i].ptr(), ctrSlotId + i, ~0u); diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 6c11ff155..8e67b53d3 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -127,11 +127,14 @@ namespace dxvk { D3D11ShaderStageUavBinding views = { }; DxvkBindingSet mask = { }; + uint32_t maxCount = 0; + void reset() { - for (uint32_t i = 0; i < views.size(); i++) + for (uint32_t i = 0; i < maxCount; i++) views[i] = nullptr; mask.clear(); + maxCount = 0; } }; From 438ae5cdfce7e7b2b0b34b22caac5bf3310ccc41 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 18:17:21 +0000 Subject: [PATCH 0427/1348] [dxso] Fix getting sampler type of vertex textures Fixes: c7afe0dd2386f0c4acdf610fb7d2c9eaa95c3516 --- src/dxso/dxso_compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 357eccf74..a9e7fcedd 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -3050,7 +3050,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( auto SampleType = [&](DxsoSamplerType samplerType) { uint32_t typeId = m_module.defIntType(32, 0); - uint32_t offset = m_module.consti32(m_programInfo.type() == DxsoProgramTypes::VertexShader ? samplerIdx + 17 : samplerIdx); + uint32_t offset = m_module.consti32(m_programInfo.type() == DxsoProgramTypes::VertexShader ? samplerIdx + caps::MaxTexturesPS : samplerIdx); uint32_t bitCnt = m_module.consti32(1); uint32_t isNull = m_module.opBitFieldUExtract(typeId, m_nullSpecConstant, offset, bitCnt); From b2cbf198e4a7e5c5c51411d790c2d84bba501527 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 30 Jul 2022 23:58:40 +0100 Subject: [PATCH 0428/1348] [d3d9, dxso] Refactor spec constants to use a bitfield layout This allows us to use the same information to dump into a push constant for unoptimized pipelines. --- src/d3d9/d3d9_device.cpp | 234 +++++++++++++++---------------- src/d3d9/d3d9_device.h | 32 ++--- src/d3d9/d3d9_fixed_function.cpp | 47 +++---- src/d3d9/d3d9_fixed_function.h | 7 +- src/d3d9/d3d9_spec_constants.h | 124 +++++++++++++--- src/dxso/dxso_compiler.cpp | 61 +++----- src/dxso/dxso_compiler.h | 8 +- 7 files changed, 271 insertions(+), 242 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index f3e490c7a..5cc87d97d 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -144,6 +144,8 @@ namespace dxvk { m_flags.set(D3D9DeviceFlag::DirtySharedPixelShaderData); m_flags.set(D3D9DeviceFlag::DirtyDepthBounds); m_flags.set(D3D9DeviceFlag::DirtyPointScale); + + m_flags.set(D3D9DeviceFlag::DirtySpecializationEntries); } @@ -5314,42 +5316,31 @@ namespace dxvk { } - template - void D3D9DeviceEx::UpdatePointMode() { - if constexpr (!Points) { - m_lastPointMode = 0; - - EmitCs([](DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::PointMode, 0); - }); + void D3D9DeviceEx::UpdatePointMode(bool pointList) { + if (!pointList) { + UpdatePointModeSpec(0); + return; } - else { - auto& rs = m_state.renderStates; - const bool scale = rs[D3DRS_POINTSCALEENABLE] && !UseProgrammableVS(); - const bool sprite = rs[D3DRS_POINTSPRITEENABLE]; + auto& rs = m_state.renderStates; - const uint32_t scaleBit = scale ? 1u : 0u; - const uint32_t spriteBit = sprite ? 2u : 0u; + const bool scale = rs[D3DRS_POINTSCALEENABLE] && !UseProgrammableVS(); + const bool sprite = rs[D3DRS_POINTSPRITEENABLE]; - uint32_t mode = scaleBit | spriteBit; + const uint32_t scaleBit = scale ? 1u : 0u; + const uint32_t spriteBit = sprite ? 2u : 0u; - if (rs[D3DRS_POINTSCALEENABLE] && m_flags.test(D3D9DeviceFlag::DirtyPointScale)) { - m_flags.clr(D3D9DeviceFlag::DirtyPointScale); + uint32_t mode = scaleBit | spriteBit; - UpdatePushConstant(); - UpdatePushConstant(); - UpdatePushConstant(); - } + if (rs[D3DRS_POINTSCALEENABLE] && m_flags.test(D3D9DeviceFlag::DirtyPointScale)) { + m_flags.clr(D3D9DeviceFlag::DirtyPointScale); - if (unlikely(mode != m_lastPointMode)) { - EmitCs([cMode = mode] (DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::PointMode, cMode); - }); - - m_lastPointMode = mode; - } + UpdatePushConstant(); + UpdatePushConstant(); + UpdatePushConstant(); } + + UpdatePointModeSpec(mode); } @@ -5394,11 +5385,7 @@ namespace dxvk { if (m_flags.test(D3D9DeviceFlag::DirtyFogState)) { m_flags.clr(D3D9DeviceFlag::DirtyFogState); - EmitCs([cMode = mode] (DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::FogEnabled, true); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::VertexFogMode, cMode); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::PixelFogMode, D3DFOG_NONE); - }); + UpdateFogModeSpec(true, mode, D3DFOG_NONE); } } else if (pixelFog) { @@ -5409,11 +5396,7 @@ namespace dxvk { if (m_flags.test(D3D9DeviceFlag::DirtyFogState)) { m_flags.clr(D3D9DeviceFlag::DirtyFogState); - EmitCs([cMode = mode] (DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::FogEnabled, true); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::VertexFogMode, D3DFOG_NONE); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::PixelFogMode, cMode); - }); + UpdateFogModeSpec(true, D3DFOG_NONE, mode); } } else { @@ -5423,11 +5406,7 @@ namespace dxvk { if (m_flags.test(D3D9DeviceFlag::DirtyFogState)) { m_flags.clr(D3D9DeviceFlag::DirtyFogState); - EmitCs([cEnabled = fogEnabled] (DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::FogEnabled, cEnabled); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::VertexFogMode, D3DFOG_NONE); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::PixelFogMode, D3DFOG_NONE); - }); + UpdateFogModeSpec(fogEnabled, D3DFOG_NONE, D3DFOG_NONE); } } } @@ -5756,9 +5735,7 @@ namespace dxvk { ? DecodeCompareOp(D3DCMPFUNC(rs[D3DRS_ALPHAFUNC])) : VK_COMPARE_OP_ALWAYS; - EmitCs([cAlphaOp = alphaOp] (DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::AlphaCompareOp, cAlphaOp); - }); + UpdateAlphaTestSpec(alphaOp); } @@ -6029,10 +6006,7 @@ namespace dxvk { if (m_flags.test(D3D9DeviceFlag::DirtyClipPlanes)) UpdateClipPlanes(); - if (PrimitiveType == D3DPT_POINTLIST) - UpdatePointMode(); - else if (m_lastPointMode != 0) - UpdatePointMode(); + UpdatePointMode(PrimitiveType == D3DPT_POINTLIST); if (likely(UseProgrammableVS())) { if (unlikely(m_flags.test(D3D9DeviceFlag::DirtyProgVertexShader))) { @@ -6045,14 +6019,14 @@ namespace dxvk { UploadConstants(); if (likely(!CanSWVP())) { - UpdateBoolSpecConstantVertex( + UpdateVertexBoolSpec( m_state.vsConsts.bConsts[0] & m_consts[DxsoProgramType::VertexShader].meta.boolConstantMask); } else - UpdateBoolSpecConstantVertex(0); + UpdateVertexBoolSpec(0); } else { - UpdateBoolSpecConstantVertex(0); + UpdateVertexBoolSpec(0); UpdateFixedFunctionVS(); } @@ -6069,24 +6043,24 @@ namespace dxvk { const auto& programInfo = GetCommonShader(m_state.pixelShader)->GetInfo(); if (programInfo.majorVersion() >= 2) - UpdatePsSamplerSpecConstants(m_d3d9Options.forceSamplerTypeSpecConstants ? m_textureTypes : 0u, 0u, fetch4); + UpdatePixelShaderSamplerSpec(m_d3d9Options.forceSamplerTypeSpecConstants ? m_textureTypes : 0u, 0u, fetch4); else - UpdatePsSamplerSpecConstants(m_textureTypes, programInfo.minorVersion() >= 4 ? 0u : projected, fetch4); // For implicit samplers... + UpdatePixelShaderSamplerSpec(m_textureTypes, programInfo.minorVersion() >= 4 ? 0u : projected, fetch4); // For implicit samplers... - UpdateBoolSpecConstantPixel( + UpdatePixelBoolSpec( m_state.psConsts.bConsts[0] & m_consts[DxsoProgramType::PixelShader].meta.boolConstantMask); } else { - UpdateBoolSpecConstantPixel(0); - UpdatePsSamplerSpecConstants(0u, 0u, 0u); + UpdatePixelBoolSpec(0); + UpdatePixelShaderSamplerSpec(0u, 0u, 0u); UpdateFixedFunctionPS(); } const uint32_t nullTextureMask = usedSamplerMask & ~usedTextureMask; const uint32_t depthTextureMask = m_depthTextures & usedTextureMask; - UpdateCommonSamplerSpecConstants(nullTextureMask, depthTextureMask); + UpdateCommonSamplerSpec(nullTextureMask, depthTextureMask); if (m_flags.test(D3D9DeviceFlag::DirtySharedPixelShaderData)) { m_flags.clr(D3D9DeviceFlag::DirtySharedPixelShaderData); @@ -6123,6 +6097,8 @@ namespace dxvk { ctx->setDepthBounds(cDepthBounds); }); } + + BindSpecConstants(); } @@ -6717,65 +6693,6 @@ namespace dxvk { } - void D3D9DeviceEx::UpdateBoolSpecConstantVertex(uint32_t value) { - if (value == m_lastBoolSpecConstantVertex) - return; - - EmitCs([cBitfield = value](DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::VertexShaderBools, cBitfield); - }); - - m_lastBoolSpecConstantVertex = value; - } - - - void D3D9DeviceEx::UpdateBoolSpecConstantPixel(uint32_t value) { - if (value == m_lastBoolSpecConstantPixel) - return; - - EmitCs([cBitfield = value](DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::PixelShaderBools, cBitfield); - }); - - m_lastBoolSpecConstantPixel = value; - } - - - void D3D9DeviceEx::UpdatePsSamplerSpecConstants(uint32_t types, uint32_t projections, uint32_t fetch4) { - if (m_lastSamplerTypes != types || m_lastProjectionBitfield != projections || m_lastFetch4 != fetch4) { - m_lastSamplerTypes = types; - m_lastProjectionBitfield = projections; - m_lastFetch4 = fetch4; - - EmitCs([ - cSamplerType = types, - cProjectionType = projections, - cFetch4 = fetch4 - ] (DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::SamplerType, cSamplerType); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::ProjectionType, cProjectionType); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::Fetch4, cFetch4); - }); - } - } - - - void D3D9DeviceEx::UpdateCommonSamplerSpecConstants(uint32_t nullMask, uint32_t depthMask) { - if (m_lastSamplerNull != nullMask || m_lastSamplerDepthMode != depthMask) { - m_lastSamplerNull = nullMask; - m_lastSamplerDepthMode = depthMask; - - EmitCs([ - cNullMask = nullMask, - cDepthMask = depthMask - ] (DxvkContext* ctx) { - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::SamplerNull, cNullMask); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, D3D9SpecConstantId::SamplerDepthMode, cDepthMask); - }); - } - } - - void D3D9DeviceEx::ApplyPrimitiveType( DxvkContext* pContext, D3DPRIMITIVETYPE PrimType) { @@ -7018,7 +6935,7 @@ namespace dxvk { UpdatePushConstant(); UpdatePushConstant(); m_flags.set(D3D9DeviceFlag::DirtyPointScale); - UpdatePointMode(); + UpdatePointMode(false); rs[D3DRS_SRGBWRITEENABLE] = 0; @@ -7140,10 +7057,10 @@ namespace dxvk { // We should do this... m_flags.set(D3D9DeviceFlag::DirtyInputLayout); - UpdatePsSamplerSpecConstants(0u, 0u, 0u); - UpdateBoolSpecConstantVertex(0u); - UpdateBoolSpecConstantPixel(0u); - UpdateCommonSamplerSpecConstants(0u, 0u); + UpdatePixelShaderSamplerSpec(0u, 0u, 0u); + UpdateVertexBoolSpec(0u); + UpdatePixelBoolSpec(0u); + UpdateCommonSamplerSpec(0u, 0u); return D3D_OK; } @@ -7302,4 +7219,75 @@ namespace dxvk { #endif } + //////////////////////////////////// + // D3D9 Device Specialization State + //////////////////////////////////// + + void D3D9DeviceEx::UpdateAlphaTestSpec(VkCompareOp alphaOp) { + uint32_t value = uint32_t(alphaOp); + + if (m_specInfo.set(value)) + m_flags.set(D3D9DeviceFlag::DirtySpecializationEntries); + } + + + void D3D9DeviceEx::UpdateVertexBoolSpec(uint32_t value) { + if (m_specInfo.set(value)) + m_flags.set(D3D9DeviceFlag::DirtySpecializationEntries); + } + + + void D3D9DeviceEx::UpdatePixelBoolSpec(uint32_t value) { + if (m_specInfo.set(value)) + m_flags.set(D3D9DeviceFlag::DirtySpecializationEntries); + } + + + void D3D9DeviceEx::UpdatePixelShaderSamplerSpec(uint32_t types, uint32_t projections, uint32_t fetch4) { + bool dirty = m_specInfo.set(types); + dirty |= m_specInfo.set(projections); + dirty |= m_specInfo.set(fetch4); + + if (dirty) + m_flags.set(D3D9DeviceFlag::DirtySpecializationEntries); + } + + + void D3D9DeviceEx::UpdateCommonSamplerSpec(uint32_t nullMask, uint32_t depthMask) { + bool dirty = m_specInfo.set(depthMask); + dirty |= m_specInfo.set(nullMask); + + if (dirty) + m_flags.set(D3D9DeviceFlag::DirtySpecializationEntries); + } + + + void D3D9DeviceEx::UpdatePointModeSpec(uint32_t mode) { + if (m_specInfo.set(mode)) + m_flags.set(D3D9DeviceFlag::DirtySpecializationEntries); + } + + + void D3D9DeviceEx::UpdateFogModeSpec(bool fogEnabled, D3DFOGMODE vertexFogMode, D3DFOGMODE pixelFogMode) { + bool dirty = m_specInfo.set(fogEnabled); + dirty |= m_specInfo.set(vertexFogMode); + dirty |= m_specInfo.set(pixelFogMode); + + if (dirty) + m_flags.set(D3D9DeviceFlag::DirtySpecializationEntries); + } + + + void D3D9DeviceEx::BindSpecConstants() { + if (!m_flags.test(D3D9DeviceFlag::DirtySpecializationEntries)) + return; + + EmitCs([cSpecInfo = m_specInfo](DxvkContext* ctx) { + for (size_t i = 0; i < cSpecInfo.data.size(); i++) + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, i, cSpecInfo.data[i]); + }); + + m_flags.clr(D3D9DeviceFlag::DirtySpecializationEntries); + } + } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 6b1d26412..0e1b5401b 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -26,6 +26,7 @@ #include "d3d9_fixed_function.h" #include "d3d9_swvp_emu.h" +#include "d3d9_spec_constants.h" #include "d3d9_shader_permutations.h" #include @@ -80,6 +81,8 @@ namespace dxvk { DirtyPointScale, InScene, + + DirtySpecializationEntries, }; using D3D9DeviceFlags = Flags; @@ -776,8 +779,7 @@ namespace dxvk { void MarkTextureUploaded(D3D9CommonTexture* pResource); - template - void UpdatePointMode(); + void UpdatePointMode(bool pointList); void UpdateFog(); @@ -826,8 +828,6 @@ namespace dxvk { void BindDepthBias(); - void BindAlphaTestState(); - inline void UploadSoftwareConstantSet(const D3D9ShaderConstantsVSSoftware& Src, const D3D9ConstantLayout& Layout); inline void* CopySoftwareConstants(D3D9ConstantBuffer& dstBuffer, const void* src, uint32_t size); @@ -1134,13 +1134,17 @@ namespace dxvk { bool UseProgrammablePS(); - void UpdateBoolSpecConstantVertex(uint32_t value); + void BindAlphaTestState(); - void UpdateBoolSpecConstantPixel(uint32_t value); + void UpdateAlphaTestSpec(VkCompareOp alphaOp); + void UpdateVertexBoolSpec(uint32_t value); + void UpdatePixelBoolSpec(uint32_t value); + void UpdatePixelShaderSamplerSpec(uint32_t types, uint32_t projections, uint32_t fetch4); + void UpdateCommonSamplerSpec(uint32_t boundMask, uint32_t depthMask); + void UpdatePointModeSpec(uint32_t mode); + void UpdateFogModeSpec(bool fogEnabled, D3DFOGMODE vertexFogMode, D3DFOGMODE pixelFogMode); - void UpdatePsSamplerSpecConstants(uint32_t types, uint32_t projections, uint32_t fetch4); - - void UpdateCommonSamplerSpecConstants(uint32_t boundMask, uint32_t depthMask); + void BindSpecConstants(); void TrackBufferMappingBufferSequenceNumber( D3D9CommonBuffer* pResource); @@ -1239,17 +1243,11 @@ namespace dxvk { uint32_t m_fetch4Enabled = 0; uint32_t m_fetch4 = 0; - uint32_t m_lastBoolSpecConstantVertex = 0; - uint32_t m_lastBoolSpecConstantPixel = 0; - uint32_t m_lastSamplerDepthMode = 0; - uint32_t m_lastProjectionBitfield = 0; - uint32_t m_lastSamplerNull = 0; - uint32_t m_lastSamplerTypes = 0; - uint32_t m_lastPointMode = 0; - uint32_t m_lastFetch4 = 0; uint32_t m_lastHazardsDS = 0; uint32_t m_lastSamplerTypesFF = 0; + D3D9SpecializationInfo m_specInfo = D3D9SpecializationInfo(); + D3D9ShaderMasks m_vsShaderMasks = D3D9ShaderMasks(); D3D9ShaderMasks m_psShaderMasks = FixedFunctionMask; diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 0fc845f75..45224b748 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -16,9 +16,8 @@ namespace dxvk { invariantPosition = options->invariantPosition; } - uint32_t DoFixedFunctionFog(SpirvModule& spvModule, const D3D9FogContext& fogCtx) { + uint32_t DoFixedFunctionFog(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, const D3D9FogContext& fogCtx) { uint32_t floatType = spvModule.defFloatType(32); - uint32_t uint32Type = spvModule.defIntType(32, 0); uint32_t vec3Type = spvModule.defVectorType(floatType, 3); uint32_t vec4Type = spvModule.defVectorType(floatType, 4); uint32_t floatPtr = spvModule.defPointerType(floatType, spv::StorageClassPushConstant); @@ -40,20 +39,12 @@ namespace dxvk { uint32_t fogDensity = spvModule.opLoad(floatType, spvModule.opAccessChain(floatPtr, fogCtx.RenderState, 1, &fogDensityMember)); - uint32_t fogMode = spvModule.specConst32(uint32Type, 0); + uint32_t fogMode = spec.get( + spvModule, + fogCtx.IsPixel ? SpecPixelFogMode : SpecVertexFogMode); - if (!fogCtx.IsPixel) { - spvModule.setDebugName(fogMode, "vertex_fog_mode"); - spvModule.decorateSpecId(fogMode, D3D9SpecConstantId::VertexFogMode); - } - else { - spvModule.setDebugName(fogMode, "pixel_fog_mode"); - spvModule.decorateSpecId(fogMode, D3D9SpecConstantId::PixelFogMode); - } - - uint32_t fogEnabled = spvModule.specConstBool(false); - spvModule.setDebugName(fogEnabled, "fog_enabled"); - spvModule.decorateSpecId(fogEnabled, D3D9SpecConstantId::FogEnabled); + uint32_t fogEnabled = spec.get(spvModule, SpecFogEnabled); + fogEnabled = spvModule.opINotEqual(spvModule.defBoolType(), fogEnabled, spvModule.constu32(0)); uint32_t doFog = spvModule.allocateId(); uint32_t skipFog = spvModule.allocateId(); @@ -253,7 +244,7 @@ namespace dxvk { } - D3D9PointSizeInfoVS GetPointSizeInfoVS(SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock, bool isFixedFunction) { + D3D9PointSizeInfoVS GetPointSizeInfoVS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock, bool isFixedFunction) { uint32_t floatType = spvModule.defFloatType(32); uint32_t floatPtr = spvModule.defPointerType(floatType, spv::StorageClassPushConstant); uint32_t vec3Type = spvModule.defVectorType(floatType, 3); @@ -269,9 +260,7 @@ namespace dxvk { uint32_t value = perVertPointSize != 0 ? perVertPointSize : LoadFloat(D3D9RenderStateItem::PointSize); if (isFixedFunction) { - uint32_t pointMode = spvModule.specConst32(uint32Type, 0); - spvModule.setDebugName(pointMode, "point_mode"); - spvModule.decorateSpecId(pointMode, D3D9SpecConstantId::PointMode); + uint32_t pointMode = spec.get(spvModule, SpecPointMode); uint32_t scaleBit = spvModule.opBitFieldUExtract(uint32Type, pointMode, spvModule.consti32(0), spvModule.consti32(1)); uint32_t isScale = spvModule.opIEqual(boolType, scaleBit, spvModule.constu32(1)); @@ -317,14 +306,12 @@ namespace dxvk { } - D3D9PointSizeInfoPS GetPointSizeInfoPS(SpirvModule& spvModule, uint32_t rsBlock) { + D3D9PointSizeInfoPS GetPointSizeInfoPS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t rsBlock) { uint32_t uint32Type = spvModule.defIntType(32, 0); uint32_t boolType = spvModule.defBoolType(); uint32_t boolVec4 = spvModule.defVectorType(boolType, 4); - uint32_t pointMode = spvModule.specConst32(uint32Type, 0); - spvModule.setDebugName(pointMode, "point_mode"); - spvModule.decorateSpecId(pointMode, D3D9SpecConstantId::PointMode); + uint32_t pointMode = spec.get(spvModule, SpecPointMode); uint32_t spriteBit = spvModule.opBitFieldUExtract(uint32Type, pointMode, spvModule.consti32(1), spvModule.consti32(1)); uint32_t isSprite = spvModule.opIEqual(boolType, spriteBit, spvModule.constu32(1)); @@ -631,6 +618,8 @@ namespace dxvk { uint32_t m_mainFuncLabel; D3D9FixedFunctionOptions m_options; + + D3D9ShaderSpecConstantManager m_spec; }; D3D9FFShaderCompiler::D3D9FFShaderCompiler( @@ -1164,9 +1153,9 @@ namespace dxvk { fogCtx.IsPositionT = m_vsKey.Data.Contents.HasPositionT; fogCtx.HasSpecular = m_vsKey.Data.Contents.HasColor1; fogCtx.Specular = m_vs.in.COLOR[1]; - m_module.opStore(m_vs.out.FOG, DoFixedFunctionFog(m_module, fogCtx)); + m_module.opStore(m_vs.out.FOG, DoFixedFunctionFog(m_spec, m_module, fogCtx)); - auto pointInfo = GetPointSizeInfoVS(m_module, 0, vtx, m_vs.in.POINTSIZE, m_rsBlock, true); + auto pointInfo = GetPointSizeInfoVS(m_spec, m_module, 0, vtx, m_vs.in.POINTSIZE, m_rsBlock, true); uint32_t pointSize = m_module.opFClamp(m_floatType, pointInfo.defaultValue, pointInfo.min, pointInfo.max); m_module.opStore(m_vs.out.POINTSIZE, pointSize); @@ -1957,7 +1946,7 @@ namespace dxvk { fogCtx.IsPositionT = false; fogCtx.HasSpecular = false; fogCtx.Specular = 0; - current = DoFixedFunctionFog(m_module, fogCtx); + current = DoFixedFunctionFog(m_spec, m_module, fogCtx); m_module.opStore(m_ps.out.COLOR, current); @@ -1974,7 +1963,7 @@ namespace dxvk { spv::ExecutionModeOriginUpperLeft); uint32_t pointCoord = GetPointCoord(m_module); - auto pointInfo = GetPointSizeInfoPS(m_module, m_rsBlock); + auto pointInfo = GetPointSizeInfoPS(m_spec, m_module, m_rsBlock); // We need to replace TEXCOORD inputs with gl_PointCoord // if D3DRS_POINTSPRITEENABLE is set. @@ -2193,9 +2182,7 @@ namespace dxvk { uint32_t floatPtr = m_module.defPointerType(m_floatType, spv::StorageClassPushConstant); // Declare spec constants for render states - uint32_t alphaFuncId = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.setDebugName(alphaFuncId, "alpha_func"); - m_module.decorateSpecId(alphaFuncId, D3D9SpecConstantId::AlphaCompareOp); + uint32_t alphaFuncId = m_spec.get(m_module, SpecAlphaCompareOp); // Implement alpha test auto oC0 = m_ps.out.COLOR; diff --git a/src/d3d9/d3d9_fixed_function.h b/src/d3d9/d3d9_fixed_function.h index e91de84a5..0649f8424 100644 --- a/src/d3d9/d3d9_fixed_function.h +++ b/src/d3d9/d3d9_fixed_function.h @@ -17,6 +17,7 @@ namespace dxvk { class SpirvModule; struct D3D9Options; + class D3D9ShaderSpecConstantManager; struct D3D9FogContext { // General inputs... @@ -44,7 +45,7 @@ namespace dxvk { // Returns new oFog if VS // Returns new oColor if PS - uint32_t DoFixedFunctionFog(SpirvModule& spvModule, const D3D9FogContext& fogCtx); + uint32_t DoFixedFunctionFog(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, const D3D9FogContext& fogCtx); // Returns a render state block uint32_t SetupRenderStateBlock(SpirvModule& spvModule, uint32_t count); @@ -56,13 +57,13 @@ namespace dxvk { }; // Default point size and point scale magic! - D3D9PointSizeInfoVS GetPointSizeInfoVS(SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock, bool isFixedFunction); + D3D9PointSizeInfoVS GetPointSizeInfoVS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock, bool isFixedFunction); struct D3D9PointSizeInfoPS { uint32_t isSprite; }; - D3D9PointSizeInfoPS GetPointSizeInfoPS(SpirvModule& spvModule, uint32_t rsBlock); + D3D9PointSizeInfoPS GetPointSizeInfoPS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t rsBlock); uint32_t GetPointCoord(SpirvModule& spvModule); diff --git a/src/d3d9/d3d9_spec_constants.h b/src/d3d9/d3d9_spec_constants.h index 2c4fcc162..f30551cf3 100644 --- a/src/d3d9/d3d9_spec_constants.h +++ b/src/d3d9/d3d9_spec_constants.h @@ -1,31 +1,119 @@ #pragma once +#include + #include +#include "../spirv/spirv_module.h" + +class D3D9DeviceEx; + namespace dxvk { enum D3D9SpecConstantId : uint32_t { - AlphaCompareOp = 0, // Range: 0 -> 7 | Bits: 3 - SamplerType = 1, // 2 bits for 16 samplers | Bits: 32 - // ^ not used for vertex shaders - FogEnabled = 2, // Range: 0 -> 1 | Bits: 1 - VertexFogMode = 3, // Range: 0 -> 3 | Bits: 2 - PixelFogMode = 4, // Range: 0 -> 3 | Bits: 2 + SpecSamplerType, // 2 bits for 16 PS samplers | Bits: 32 - PointMode = 5, // Range: 0 -> 3 | Bits: 3 - ProjectionType = 6, // 1 bit for 6 samplers | Bits: 6 - // ^ not supported for vertex shaders - // PS 1.x only supports up to 6 samplers + SpecSamplerDepthMode, // 1 bit for 20 VS + PS samplers | Bits: 20 + SpecAlphaCompareOp, // Range: 0 -> 7 | Bits: 3 + SpecPointMode, // Range: 0 -> 3 | Bits: 2 + SpecVertexFogMode, // Range: 0 -> 3 | Bits: 2 + SpecPixelFogMode, // Range: 0 -> 3 | Bits: 2 + SpecFogEnabled, // Range: 0 -> 1 | Bits: 1 - VertexShaderBools = 7, // 16 bools | Bits: 16 - PixelShaderBools = 8, // 16 bools | Bits: 16 - Fetch4 = 9, // 1 bit for 16 samplers | Bits: 16 - // ^ not supported for vertex shaders + SpecSamplerNull, // 1 bit for 20 samplers | Bits: 20 + SpecProjectionType, // 1 bit for 6 PS 1.x samplers | Bits: 6 - SamplerDepthMode = 10, // 1 bit for 20 samplers | Bits: 20 - // ^ vs + ps - SamplerNull = 11, // 1 bit for 20 samplers | Bits: 20 - // ^ vs + ps + SpecVertexShaderBools, // 16 bools | Bits: 16 + SpecPixelShaderBools, // 16 bools | Bits: 16 + + SpecFetch4, // 1 bit for 16 PS samplers | Bits: 16 + + SpecConstantCount, + }; + + struct BitfieldPosition { + constexpr uint32_t mask() const { + return uint32_t((1ull << sizeInBits) - 1) << bitOffset; + } + + uint32_t dwordOffset; + uint32_t bitOffset; + uint32_t sizeInBits; + }; + + struct D3D9SpecializationInfo { + static constexpr uint32_t MaxSpecDwords = 5; + + static constexpr std::array Layout{{ + { 0, 0, 32 }, // SamplerType + + { 1, 0, 20 }, // SamplerDepthMode + { 1, 20, 3 }, // AlphaCompareOp + { 1, 23, 2 }, // PointMode + { 1, 25, 2 }, // VertexFogMode + { 1, 27, 2 }, // PixelFogMode + { 1, 29, 1 }, // FogEnabled + + { 2, 0, 20 }, // SamplerNull + { 2, 20, 6 }, // ProjectionType + + { 3, 0, 16 }, // VertexShaderBools + { 3, 16, 16 }, // PixelShaderBools + + { 4, 0, 16 }, // Fetch4 + }}; + + template + bool set(const T& value) { + const uint32_t x = uint32_t(value); + if (get() == x) + return false; + + constexpr auto& layout = Layout[Id]; + + data[layout.dwordOffset] &= ~layout.mask(); + data[layout.dwordOffset] |= (x << layout.bitOffset) & layout.mask(); + + return true; + } + + template + uint32_t get() const { + constexpr auto& layout = Layout[Id]; + + return (data[layout.dwordOffset] & layout.mask()) >> layout.bitOffset; + } + + std::array data = {}; + }; + + class D3D9ShaderSpecConstantManager { + public: + uint32_t get(SpirvModule &module, D3D9SpecConstantId id) { + const auto &layout = D3D9SpecializationInfo::Layout[id]; + + uint32_t val = getSpecConstDword(module, layout.dwordOffset); + if (layout.sizeInBits == 32) + return val; + + return module.opBitFieldUExtract( + module.defIntType(32, 0), + val, + module.consti32(layout.bitOffset), + module.consti32(layout.sizeInBits)); + } + + private: + uint32_t getSpecConstDword(SpirvModule &module, uint32_t idx) { + if (!m_specConstantIds[idx]) { + m_specConstantIds[idx] = module.specConst32(module.defIntType(32, 0), 0); + module.decorateSpecId(m_specConstantIds[idx], idx); + } + + return m_specConstantIds[idx]; + } + + std::array m_specConstantIds = {}; }; } \ No newline at end of file diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index a9e7fcedd..fc77d8183 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -270,14 +270,6 @@ namespace dxvk { this->emitDclConstantBuffer(); } - m_nullSpecConstant = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_nullSpecConstant, D3D9SpecConstantId::SamplerNull); - m_module.setDebugName(m_nullSpecConstant, "nullSamplers"); - - m_depthSpecConstant = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_depthSpecConstant, D3D9SpecConstantId::SamplerDepthMode); - m_module.setDebugName(m_depthSpecConstant, "depthSamplers"); - this->emitDclInputArray(); // Initialize the shader module with capabilities @@ -338,13 +330,6 @@ namespace dxvk { binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; m_bindings.push_back(binding); - - m_boolSpecConstant = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_boolSpecConstant, - m_programInfo.type() == DxsoProgramType::VertexShader - ? D3D9SpecConstantId::VertexShaderBools - : D3D9SpecConstantId::PixelShaderBools); - m_module.setDebugName(m_boolSpecConstant, "boolConstants"); } template @@ -533,22 +518,6 @@ namespace dxvk { m_ps.functionId = m_module.allocateId(); m_module.setDebugName(m_ps.functionId, "ps_main"); - if (m_programInfo.majorVersion() < 2 || m_moduleInfo.options.forceSamplerTypeSpecConstants) { - m_ps.samplerTypeSpec = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_ps.samplerTypeSpec, D3D9SpecConstantId::SamplerType); - m_module.setDebugName(m_ps.samplerTypeSpec, "s_sampler_types"); - - if (m_programInfo.majorVersion() < 2) { - m_ps.projectionSpec = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_ps.projectionSpec, D3D9SpecConstantId::ProjectionType); - m_module.setDebugName(m_ps.projectionSpec, "s_projections"); - } - } - - m_ps.fetch4Spec = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.decorateSpecId(m_ps.fetch4Spec, D3D9SpecConstantId::Fetch4); - m_module.setDebugName(m_ps.fetch4Spec, "s_fetch4"); - this->setupRenderStateInfo(); this->emitPsSharedConstants(); @@ -1059,8 +1028,12 @@ namespace dxvk { bitfield = m_module.opLoad(accessType, ptrId); } - else - bitfield = m_boolSpecConstant; + else { + bitfield = m_spec.get(m_module, + m_programInfo.type() == DxsoProgramType::VertexShader + ? SpecVertexShaderBools + : SpecPixelShaderBools); + } uint32_t bitIdx = m_module.consti32(reg.id.num % 32); @@ -2790,7 +2763,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t bool_t = m_module.defBoolType(); uint32_t shouldProj = m_module.opBitFieldUExtract( - m_module.defIntType(32, 0), m_ps.projectionSpec, + m_module.defIntType(32, 0), m_spec.get(m_module, SpecProjectionType), m_module.consti32(samplerIdx), m_module.consti32(1)); shouldProj = m_module.opIEqual(bool_t, shouldProj, m_module.constu32(1)); @@ -2957,7 +2930,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t fetch4 = 0; if (m_programInfo.type() == DxsoProgramType::PixelShader && samplerType != SamplerTypeTexture3D) { fetch4 = m_module.opBitFieldUExtract( - m_module.defIntType(32, 0), m_ps.fetch4Spec, + m_module.defIntType(32, 0), m_spec.get(m_module, SpecFetch4), m_module.consti32(samplerIdx), m_module.consti32(1)); uint32_t bool_t = m_module.defBoolType(); @@ -2990,7 +2963,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( imageOperands); uint32_t shouldProj = m_module.opBitFieldUExtract( - m_module.defIntType(32, 0), m_ps.projectionSpec, + m_module.defIntType(32, 0), m_spec.get(m_module, SpecProjectionType), m_module.consti32(samplerIdx), m_module.consti32(1)); shouldProj = m_module.opIEqual(m_module.defBoolType(), shouldProj, m_module.constu32(1)); @@ -3053,7 +3026,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t offset = m_module.consti32(m_programInfo.type() == DxsoProgramTypes::VertexShader ? samplerIdx + caps::MaxTexturesPS : samplerIdx); uint32_t bitCnt = m_module.consti32(1); - uint32_t isNull = m_module.opBitFieldUExtract(typeId, m_nullSpecConstant, offset, bitCnt); + uint32_t isNull = m_module.opBitFieldUExtract(typeId, m_spec.get(m_module, SpecSamplerNull), offset, bitCnt); isNull = m_module.opIEqual(m_module.defBoolType(), isNull, m_module.constu32(1)); // Only do the check for depth comp. samplers @@ -3063,7 +3036,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t depthLabel = m_module.allocateId(); uint32_t endLabel = m_module.allocateId(); - uint32_t isDepth = m_module.opBitFieldUExtract(typeId, m_depthSpecConstant, offset, bitCnt); + uint32_t isDepth = m_module.opBitFieldUExtract(typeId, m_spec.get(m_module, SpecSamplerDepthMode), offset, bitCnt); isDepth = m_module.opIEqual(m_module.defBoolType(), isDepth, m_module.constu32(1)); m_module.opSelectionMerge(endLabel, spv::SelectionControlMaskNone); @@ -3103,7 +3076,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t offset = m_module.consti32(samplerIdx * 2); uint32_t bitCnt = m_module.consti32(2); - uint32_t type = m_module.opBitFieldUExtract(typeId, m_ps.samplerTypeSpec, offset, bitCnt); + uint32_t type = m_module.opBitFieldUExtract(typeId, m_spec.get(m_module, SpecSamplerType), offset, bitCnt); m_module.opSelectionMerge(switchEndLabel, spv::SelectionControlMaskNone); m_module.opSwitch(type, @@ -3367,7 +3340,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( if (m_programInfo.type() == DxsoProgramType::PixelShader) { pointCoord = GetPointCoord(m_module); - pointInfo = GetPointSizeInfoPS(m_module, m_rsBlock); + pointInfo = GetPointSizeInfoPS(m_spec, m_module, m_rsBlock); } for (uint32_t i = 0; i < m_isgn.elemCount; i++) { @@ -3597,7 +3570,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( if (!outputtedColor1) OutputDefault(DxsoSemantic{ DxsoUsage::Color, 1 }); - auto pointInfo = GetPointSizeInfoVS(m_module, m_vs.oPos.id, 0, 0, m_rsBlock, false); + auto pointInfo = GetPointSizeInfoVS(m_spec, m_module, m_vs.oPos.id, 0, 0, m_rsBlock, false); if (m_vs.oPSize.id == 0) { m_vs.oPSize = this->emitRegisterPtr( @@ -3749,7 +3722,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( fogCtx.HasSpecular = false; fogCtx.Specular = 0; - m_module.opStore(oColor0Ptr.id, DoFixedFunctionFog(m_module, fogCtx)); + m_module.opStore(oColor0Ptr.id, DoFixedFunctionFog(m_spec, m_module, fogCtx)); } @@ -3758,9 +3731,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t floatType = m_module.defFloatType(32); uint32_t floatPtr = m_module.defPointerType(floatType, spv::StorageClassPushConstant); - uint32_t alphaFuncId = m_module.specConst32(m_module.defIntType(32, 0), 0); - m_module.setDebugName (alphaFuncId, "alpha_func"); - m_module.decorateSpecId (alphaFuncId, D3D9SpecConstantId::AlphaCompareOp); + uint32_t alphaFuncId = m_spec.get(m_module, SpecAlphaCompareOp); // Implement alpha test and fog DxsoRegister color0; diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h index 93ee78fc5..c5f1b8a80 100644 --- a/src/dxso/dxso_compiler.h +++ b/src/dxso/dxso_compiler.h @@ -8,6 +8,7 @@ #include "../d3d9/d3d9_constant_layout.h" #include "../d3d9/d3d9_shader_permutations.h" +#include "../d3d9/d3d9_spec_constants.h" #include "../spirv/spirv_module.h" namespace dxvk { @@ -155,9 +156,6 @@ namespace dxvk { */ struct DxsoCompilerPsPart { uint32_t functionId = 0; - uint32_t samplerTypeSpec = 0; - uint32_t projectionSpec = 0; - uint32_t fetch4Spec = 0; ////////////// // Misc Types @@ -269,9 +267,7 @@ namespace dxvk { SpirvModule m_module; - uint32_t m_boolSpecConstant; - uint32_t m_nullSpecConstant; - uint32_t m_depthSpecConstant; + D3D9ShaderSpecConstantManager m_spec; /////////////////////////////////////////////////////// // Resource slot description for the shader. This will From 9619377723bfddcfedc8d4f6d68f3bcc2f0030f1 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 31 Jul 2022 00:22:11 +0100 Subject: [PATCH 0429/1348] [dxso] Convert opIEqual 1 -> opINotEqual 0 Better chance of getting optimized --- src/dxso/dxso_compiler.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index fc77d8183..40155365f 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -2766,7 +2766,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( m_module.defIntType(32, 0), m_spec.get(m_module, SpecProjectionType), m_module.consti32(samplerIdx), m_module.consti32(1)); - shouldProj = m_module.opIEqual(bool_t, shouldProj, m_module.constu32(1)); + shouldProj = m_module.opINotEqual(bool_t, shouldProj, m_module.constu32(0)); uint32_t bvec4_t = m_module.defVectorType(bool_t, 4); std::array indices = { shouldProj, shouldProj, shouldProj, shouldProj }; @@ -2934,7 +2934,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( m_module.consti32(samplerIdx), m_module.consti32(1)); uint32_t bool_t = m_module.defBoolType(); - fetch4 = m_module.opIEqual(bool_t, fetch4, m_module.constu32(1)); + fetch4 = m_module.opINotEqual(bool_t, fetch4, m_module.constu32(0)); uint32_t bvec4_t = m_module.defVectorType(bool_t, 4); std::array indices = { fetch4, fetch4, fetch4, fetch4 }; @@ -2966,7 +2966,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( m_module.defIntType(32, 0), m_spec.get(m_module, SpecProjectionType), m_module.consti32(samplerIdx), m_module.consti32(1)); - shouldProj = m_module.opIEqual(m_module.defBoolType(), shouldProj, m_module.constu32(1)); + shouldProj = m_module.opINotEqual(m_module.defBoolType(), shouldProj, m_module.constu32(0)); // Depth -> .x // Colour -> .xyzw @@ -3027,7 +3027,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t bitCnt = m_module.consti32(1); uint32_t isNull = m_module.opBitFieldUExtract(typeId, m_spec.get(m_module, SpecSamplerNull), offset, bitCnt); - isNull = m_module.opIEqual(m_module.defBoolType(), isNull, m_module.constu32(1)); + isNull = m_module.opINotEqual(m_module.defBoolType(), isNull, m_module.constu32(0)); // Only do the check for depth comp. samplers // if we aren't a 3D texture @@ -3037,7 +3037,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t endLabel = m_module.allocateId(); uint32_t isDepth = m_module.opBitFieldUExtract(typeId, m_spec.get(m_module, SpecSamplerDepthMode), offset, bitCnt); - isDepth = m_module.opIEqual(m_module.defBoolType(), isDepth, m_module.constu32(1)); + isDepth = m_module.opINotEqual(m_module.defBoolType(), isDepth, m_module.constu32(0)); m_module.opSelectionMerge(endLabel, spv::SelectionControlMaskNone); m_module.opBranchConditional(isDepth, depthLabel, colorLabel); From d498551a23d27629cd048743de2051d9d58e9721 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 1 Aug 2022 16:31:13 +0200 Subject: [PATCH 0430/1348] [dxso] Add bit selectors to D3D9ShaderSpecConstantManager Avoids doing double bitfield extractions which isn't optimized right now. --- src/d3d9/d3d9_spec_constants.h | 15 ++++++--- src/dxso/dxso_compiler.cpp | 58 +++++++++++++--------------------- 2 files changed, 32 insertions(+), 41 deletions(-) diff --git a/src/d3d9/d3d9_spec_constants.h b/src/d3d9/d3d9_spec_constants.h index f30551cf3..2a8e6679d 100644 --- a/src/d3d9/d3d9_spec_constants.h +++ b/src/d3d9/d3d9_spec_constants.h @@ -90,17 +90,22 @@ namespace dxvk { class D3D9ShaderSpecConstantManager { public: uint32_t get(SpirvModule &module, D3D9SpecConstantId id) { + return get(module, id, 0, 32); + } + + uint32_t get(SpirvModule &module, D3D9SpecConstantId id, uint32_t bitOffset, uint32_t bitCount) { const auto &layout = D3D9SpecializationInfo::Layout[id]; uint32_t val = getSpecConstDword(module, layout.dwordOffset); - if (layout.sizeInBits == 32) + bitCount = std::min(bitCount, layout.sizeInBits - bitOffset); + + if (bitCount == 32) return val; return module.opBitFieldUExtract( - module.defIntType(32, 0), - val, - module.consti32(layout.bitOffset), - module.consti32(layout.sizeInBits)); + module.defIntType(32, 0), val, + module.consti32(bitOffset + layout.bitOffset), + module.consti32(bitCount)); } private: diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 40155365f..df1f3d62f 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -1015,7 +1015,7 @@ namespace dxvk { uint32_t uvec4Type = getVectorTypeId({ DxsoScalarType::Uint32, 4 }); // If not SWVP, spec const this - uint32_t bitfield; + uint32_t bit; if (m_layout->bitmaskCount != 1) { std::array indices = { m_module.constu32(0), m_module.constu32(reg.id.num / 128) }; @@ -1026,23 +1026,22 @@ namespace dxvk { m_module.defPointerType(accessType, spv::StorageClassUniform), m_cBoolBuffer, indexCount, indices.data()); - bitfield = m_module.opLoad(accessType, ptrId); - } - else { - bitfield = m_spec.get(m_module, - m_programInfo.type() == DxsoProgramType::VertexShader - ? SpecVertexShaderBools - : SpecPixelShaderBools); - } + uint32_t bitfield = m_module.opLoad(accessType, ptrId); + uint32_t bitIdx = m_module.consti32(reg.id.num % 32); - uint32_t bitIdx = m_module.consti32(reg.id.num % 32); - - if (m_layout->bitmaskCount != 1) { uint32_t index = (reg.id.num % 128) / 32; bitfield = m_module.opCompositeExtract(uintType, bitfield, 1, &index); + + bit = m_module.opBitFieldUExtract( + uintType, bitfield, bitIdx, m_module.consti32(1)); + } + else { + bit = m_spec.get(m_module, + m_programInfo.type() == DxsoProgramType::VertexShader + ? SpecVertexShaderBools + : SpecPixelShaderBools, + reg.id.num, 1); } - uint32_t bit = m_module.opBitFieldUExtract( - uintType, bitfield, bitIdx, m_module.consti32(1)); result.id = m_module.opINotEqual( getVectorTypeId(result.type), @@ -2762,10 +2761,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( // Of course it does... uint32_t bool_t = m_module.defBoolType(); - uint32_t shouldProj = m_module.opBitFieldUExtract( - m_module.defIntType(32, 0), m_spec.get(m_module, SpecProjectionType), - m_module.consti32(samplerIdx), m_module.consti32(1)); - + uint32_t shouldProj = m_spec.get(m_module, SpecProjectionType, samplerIdx, 1); shouldProj = m_module.opINotEqual(bool_t, shouldProj, m_module.constu32(0)); uint32_t bvec4_t = m_module.defVectorType(bool_t, 4); @@ -2929,9 +2925,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t fetch4 = 0; if (m_programInfo.type() == DxsoProgramType::PixelShader && samplerType != SamplerTypeTexture3D) { - fetch4 = m_module.opBitFieldUExtract( - m_module.defIntType(32, 0), m_spec.get(m_module, SpecFetch4), - m_module.consti32(samplerIdx), m_module.consti32(1)); + fetch4 = m_spec.get(m_module, SpecFetch4, samplerIdx, 1); uint32_t bool_t = m_module.defBoolType(); fetch4 = m_module.opINotEqual(bool_t, fetch4, m_module.constu32(0)); @@ -2962,10 +2956,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( fetch4, imageOperands); - uint32_t shouldProj = m_module.opBitFieldUExtract( - m_module.defIntType(32, 0), m_spec.get(m_module, SpecProjectionType), - m_module.consti32(samplerIdx), m_module.consti32(1)); - + uint32_t shouldProj = m_spec.get(m_module, SpecProjectionType, samplerIdx, 1); shouldProj = m_module.opINotEqual(m_module.defBoolType(), shouldProj, m_module.constu32(0)); // Depth -> .x @@ -3022,11 +3013,11 @@ void DxsoCompiler::emitControlFlowGenericLoop( }; auto SampleType = [&](DxsoSamplerType samplerType) { - uint32_t typeId = m_module.defIntType(32, 0); - uint32_t offset = m_module.consti32(m_programInfo.type() == DxsoProgramTypes::VertexShader ? samplerIdx + caps::MaxTexturesPS : samplerIdx); - uint32_t bitCnt = m_module.consti32(1); + uint32_t bitOffset = m_programInfo.type() == DxsoProgramTypes::VertexShader + ? samplerIdx + caps::MaxTexturesPS + : samplerIdx; - uint32_t isNull = m_module.opBitFieldUExtract(typeId, m_spec.get(m_module, SpecSamplerNull), offset, bitCnt); + uint32_t isNull = m_spec.get(m_module, SpecSamplerNull, bitOffset, 1); isNull = m_module.opINotEqual(m_module.defBoolType(), isNull, m_module.constu32(0)); // Only do the check for depth comp. samplers @@ -3036,7 +3027,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t depthLabel = m_module.allocateId(); uint32_t endLabel = m_module.allocateId(); - uint32_t isDepth = m_module.opBitFieldUExtract(typeId, m_spec.get(m_module, SpecSamplerDepthMode), offset, bitCnt); + uint32_t isDepth = m_spec.get(m_module, SpecSamplerDepthMode, bitOffset, 1); isDepth = m_module.opINotEqual(m_module.defBoolType(), isDepth, m_module.constu32(0)); m_module.opSelectionMerge(endLabel, spv::SelectionControlMaskNone); @@ -3071,12 +3062,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( }}; uint32_t switchEndLabel = m_module.allocateId(); - - uint32_t typeId = m_module.defIntType(32, 0); - - uint32_t offset = m_module.consti32(samplerIdx * 2); - uint32_t bitCnt = m_module.consti32(2); - uint32_t type = m_module.opBitFieldUExtract(typeId, m_spec.get(m_module, SpecSamplerType), offset, bitCnt); + uint32_t type = m_spec.get(m_module, SpecSamplerType, samplerIdx * 2, 2); m_module.opSelectionMerge(switchEndLabel, spv::SelectionControlMaskNone); m_module.opSwitch(type, From 9e1ecec79fc91011cd2ff4cdd5b56b3f2f0e4d19 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Wed, 3 Aug 2022 02:21:46 +0200 Subject: [PATCH 0431/1348] [d3d9] Disable fetch4 when binding an incompatible texture Fixes lighting in Spider-Man: Shattered Dimensions. --- src/d3d9/d3d9_device.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 5cc87d97d..8f9f964ff 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3779,13 +3779,20 @@ namespace dxvk { m_dirtySamplerStates |= 1u << StateSampler; } - if (unlikely(m_fetch4Enabled & (1u << StateSampler) && !(m_fetch4 & (1u << StateSampler)))) { - bool textureSupportsFetch4 = newTexture->SupportsFetch4(); - if (textureSupportsFetch4 - && m_state.samplerStates[StateSampler][D3DSAMP_MAGFILTER] == D3DTEXF_POINT - && m_state.samplerStates[StateSampler][D3DSAMP_MINFILTER] == D3DTEXF_POINT) { + if (unlikely(m_fetch4Enabled & (1u << StateSampler))) { + const bool samplerFetch4 = (m_fetch4 & (1u << StateSampler)) != 0; + const bool pointFilter = m_state.samplerStates[StateSampler][D3DSAMP_MAGFILTER] == D3DTEXF_POINT + && m_state.samplerStates[StateSampler][D3DSAMP_MINFILTER] == D3DTEXF_POINT; + const bool textureSupportsFetch4 = newTexture->SupportsFetch4(); + + if (unlikely(textureSupportsFetch4 && pointFilter && !samplerFetch4)) { + // We're swapping a multi channel texture for a single channel texture => turn on fetch4 m_fetch4 |= 1u << StateSampler; m_dirtySamplerStates |= 1u << StateSampler; + } else if (unlikely(!textureSupportsFetch4 && samplerFetch4)) { + // We're swapping a single channel texture for a multi channel one => turn off fetch4 + m_fetch4 &= ~(1u << StateSampler); + m_dirtySamplerStates |= 1u << StateSampler; } } } else if (unlikely(m_fetch4 & (1u << StateSampler))) { From 2fe61675bf0f50f7f998d3435d56242ab1bb66c9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 5 Aug 2022 21:13:26 +0200 Subject: [PATCH 0432/1348] [dxvk] Use existing bit mask iterator when updating descriptor sets And clean up the code a little. --- src/dxvk/dxvk_context.cpp | 115 ++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 60 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index fc529d3bf..1169d31c0 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4675,17 +4675,12 @@ namespace dxvk { : m_descriptorState.getDirtyComputeSets(); dirtySetMask &= layoutSetMask; - uint32_t bindCount = 0; - uint32_t k = 0; - std::array sets; m_descriptorPool->alloc(layout, dirtySetMask, sets.data()); - while (dirtySetMask) { - uint32_t setIndex = bit::tzcnt(dirtySetMask); + uint32_t descriptorCount = 0; - // Initialize binding mask for the current set, only - // clear bits if certain resources are actually unbound. + for (auto setIndex : bit::BitMask(dirtySetMask)) { uint32_t bindingCount = bindings.getBindingCount(setIndex); VkDescriptorSet set = sets[setIndex]; @@ -4693,26 +4688,29 @@ namespace dxvk { const auto& binding = bindings.getBinding(setIndex, j); if (!useDescriptorTemplates) { - m_descriptorWrites[k].dstSet = set; - m_descriptorWrites[k].dstBinding = j; - m_descriptorWrites[k].descriptorType = binding.descriptorType; + auto& descriptorWrite = m_descriptorWrites[descriptorCount]; + descriptorWrite.dstSet = set; + descriptorWrite.dstBinding = j; + descriptorWrite.descriptorType = binding.descriptorType; } + auto& descriptorInfo = m_descriptors[descriptorCount++]; + switch (binding.descriptorType) { case VK_DESCRIPTOR_TYPE_SAMPLER: { const auto& res = m_rc[binding.resourceBinding]; if (res.sampler != nullptr) { - m_descriptors[k].image.sampler = res.sampler->handle(); - m_descriptors[k].image.imageView = VK_NULL_HANDLE; - m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + descriptorInfo.image.sampler = res.sampler->handle(); + descriptorInfo.image.imageView = VK_NULL_HANDLE; + descriptorInfo.image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.sampler); } else { - m_descriptors[k].image.sampler = m_common->dummyResources().samplerHandle(); - m_descriptors[k].image.imageView = VK_NULL_HANDLE; - m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + descriptorInfo.image.sampler = m_common->dummyResources().samplerHandle(); + descriptorInfo.image.imageView = VK_NULL_HANDLE; + descriptorInfo.image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; } } break; @@ -4720,18 +4718,18 @@ namespace dxvk { const auto& res = m_rc[binding.resourceBinding]; if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - m_descriptors[k].image.sampler = VK_NULL_HANDLE; - m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); - m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout; + descriptorInfo.image.sampler = VK_NULL_HANDLE; + descriptorInfo.image.imageView = res.imageView->handle(binding.viewType); + descriptorInfo.image.imageLayout = res.imageView->imageInfo().layout; if (m_rcTracked.set(binding.resourceBinding)) { m_cmd->trackResource(res.imageView); m_cmd->trackResource(res.imageView->image()); } } else { - m_descriptors[k].image.sampler = VK_NULL_HANDLE; - m_descriptors[k].image.imageView = VK_NULL_HANDLE; - m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + descriptorInfo.image.sampler = VK_NULL_HANDLE; + descriptorInfo.image.imageView = VK_NULL_HANDLE; + descriptorInfo.image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; } } break; @@ -4739,18 +4737,18 @@ namespace dxvk { const auto& res = m_rc[binding.resourceBinding]; if (res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - m_descriptors[k].image.sampler = VK_NULL_HANDLE; - m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); - m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout; + descriptorInfo.image.sampler = VK_NULL_HANDLE; + descriptorInfo.image.imageView = res.imageView->handle(binding.viewType); + descriptorInfo.image.imageLayout = res.imageView->imageInfo().layout; if (m_rcTracked.set(binding.resourceBinding)) { m_cmd->trackResource(res.imageView); m_cmd->trackResource(res.imageView->image()); } } else { - m_descriptors[k].image.sampler = VK_NULL_HANDLE; - m_descriptors[k].image.imageView = VK_NULL_HANDLE; - m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + descriptorInfo.image.sampler = VK_NULL_HANDLE; + descriptorInfo.image.imageView = VK_NULL_HANDLE; + descriptorInfo.image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; } } break; @@ -4759,9 +4757,9 @@ namespace dxvk { if (res.sampler != nullptr && res.imageView != nullptr && res.imageView->handle(binding.viewType) != VK_NULL_HANDLE) { - m_descriptors[k].image.sampler = res.sampler->handle(); - m_descriptors[k].image.imageView = res.imageView->handle(binding.viewType); - m_descriptors[k].image.imageLayout = res.imageView->imageInfo().layout; + descriptorInfo.image.sampler = res.sampler->handle(); + descriptorInfo.image.imageView = res.imageView->handle(binding.viewType); + descriptorInfo.image.imageLayout = res.imageView->imageInfo().layout; if (m_rcTracked.set(binding.resourceBinding)) { m_cmd->trackResource(res.sampler); @@ -4769,9 +4767,9 @@ namespace dxvk { m_cmd->trackResource(res.imageView->image()); } } else { - m_descriptors[k].image.sampler = m_common->dummyResources().samplerHandle(); - m_descriptors[k].image.imageView = VK_NULL_HANDLE; - m_descriptors[k].image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + descriptorInfo.image.sampler = m_common->dummyResources().samplerHandle(); + descriptorInfo.image.imageView = VK_NULL_HANDLE; + descriptorInfo.image.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; } } break; @@ -4780,14 +4778,14 @@ namespace dxvk { if (res.bufferView != nullptr) { res.bufferView->updateView(); - m_descriptors[k].texelBuffer = res.bufferView->handle(); + descriptorInfo.texelBuffer = res.bufferView->handle(); if (m_rcTracked.set(binding.resourceBinding)) { m_cmd->trackResource(res.bufferView); m_cmd->trackResource(res.bufferView->buffer()); } } else { - m_descriptors[k].texelBuffer = VK_NULL_HANDLE; + descriptorInfo.texelBuffer = VK_NULL_HANDLE; } } break; @@ -4796,14 +4794,14 @@ namespace dxvk { if (res.bufferView != nullptr) { res.bufferView->updateView(); - m_descriptors[k].texelBuffer = res.bufferView->handle(); + descriptorInfo.texelBuffer = res.bufferView->handle(); if (m_rcTracked.set(binding.resourceBinding)) { m_cmd->trackResource(res.bufferView); m_cmd->trackResource(res.bufferView->buffer()); } } else { - m_descriptors[k].texelBuffer = VK_NULL_HANDLE; + descriptorInfo.texelBuffer = VK_NULL_HANDLE; } } break; @@ -4811,14 +4809,14 @@ namespace dxvk { const auto& res = m_rc[binding.resourceBinding]; if (res.bufferSlice.defined()) { - m_descriptors[k] = res.bufferSlice.getDescriptor(); + descriptorInfo = res.bufferSlice.getDescriptor(); if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.bufferSlice.buffer()); } else { - m_descriptors[k].buffer.buffer = VK_NULL_HANDLE; - m_descriptors[k].buffer.offset = 0; - m_descriptors[k].buffer.range = VK_WHOLE_SIZE; + descriptorInfo.buffer.buffer = VK_NULL_HANDLE; + descriptorInfo.buffer.offset = 0; + descriptorInfo.buffer.range = VK_WHOLE_SIZE; } } break; @@ -4826,51 +4824,48 @@ namespace dxvk { const auto& res = m_rc[binding.resourceBinding]; if (res.bufferSlice.defined()) { - m_descriptors[k] = res.bufferSlice.getDescriptor(); + descriptorInfo = res.bufferSlice.getDescriptor(); if (m_rcTracked.set(binding.resourceBinding)) m_cmd->trackResource(res.bufferSlice.buffer()); } else { - m_descriptors[k].buffer.buffer = VK_NULL_HANDLE; - m_descriptors[k].buffer.offset = 0; - m_descriptors[k].buffer.range = VK_WHOLE_SIZE; + descriptorInfo.buffer.buffer = VK_NULL_HANDLE; + descriptorInfo.buffer.offset = 0; + descriptorInfo.buffer.range = VK_WHOLE_SIZE; } } break; default: break; } - - k += 1; } if (useDescriptorTemplates) { m_cmd->updateDescriptorSetWithTemplate(set, layout->getSetUpdateTemplate(setIndex), - &m_descriptors[k - bindingCount]); + &m_descriptors[0]); + descriptorCount = 0; } - bindCount += 1; - // If the next set is not dirty, update and bind all previously // updated sets in one go in order to reduce api call overhead. - if (!(dirtySetMask & (1u << (setIndex + 1)))) { + if (!(((dirtySetMask >> 1) >> setIndex) & 1u)) { if (!useDescriptorTemplates) { - m_cmd->updateDescriptorSets(k, m_descriptorWrites.data()); - k = 0; + m_cmd->updateDescriptorSets(descriptorCount, + m_descriptorWrites.data()); + descriptorCount = 0; } - uint32_t firstSet = setIndex + 1 - bindCount; + // Find first dirty set in the mask and clear bits + // for all sets that we're going to update here. + uint32_t firstSet = bit::tzcnt(dirtySetMask); + dirtySetMask &= (~1u) << setIndex; m_cmd->cmdBindDescriptorSets(BindPoint, layout->getPipelineLayout(independentSets), - firstSet, bindCount, &sets[firstSet], + firstSet, setIndex - firstSet + 1, &sets[firstSet], 0, nullptr); - - bindCount = 0; } - - dirtySetMask &= dirtySetMask - 1; } } From 6fba4c47fe43340188ba3f33b3384e89482da289 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 6 Aug 2022 01:37:17 +0200 Subject: [PATCH 0433/1348] [dxvk] Don't use MaxNumActiveBindings when creating descriptor set layouts --- src/dxvk/dxvk_pipelayout.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index 895b685b3..ef2cd26ce 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -1,4 +1,5 @@ #include +#include #include "dxvk_device.h" #include "dxvk_descriptor.h" @@ -158,38 +159,43 @@ namespace dxvk { : m_device(device) { auto vk = m_device->vkd(); - std::array bindingInfos; - std::array templateInfos; + std::vector bindingInfos; + std::vector templateInfos; - VkDescriptorSetLayoutCreateInfo layoutInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; - layoutInfo.bindingCount = key.getBindingCount(); - layoutInfo.pBindings = bindingInfos.data(); + bindingInfos.reserve(key.getBindingCount()); + templateInfos.reserve(key.getBindingCount()); for (uint32_t i = 0; i < key.getBindingCount(); i++) { auto entry = key.getBinding(i); - VkDescriptorSetLayoutBinding& bindingInfo = bindingInfos[i]; + VkDescriptorSetLayoutBinding bindingInfo; bindingInfo.binding = i; bindingInfo.descriptorType = entry.descriptorType; bindingInfo.descriptorCount = 1; bindingInfo.stageFlags = entry.stages; bindingInfo.pImmutableSamplers = nullptr; + bindingInfos.push_back(bindingInfo); - VkDescriptorUpdateTemplateEntry& templateInfo = templateInfos[i]; + VkDescriptorUpdateTemplateEntry templateInfo; templateInfo.dstBinding = i; templateInfo.dstArrayElement = 0; templateInfo.descriptorCount = 1; templateInfo.descriptorType = entry.descriptorType; templateInfo.offset = sizeof(DxvkDescriptorInfo) * i; templateInfo.stride = sizeof(DxvkDescriptorInfo); + templateInfos.push_back(templateInfo); } + VkDescriptorSetLayoutCreateInfo layoutInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; + layoutInfo.bindingCount = bindingInfos.size(); + layoutInfo.pBindings = bindingInfos.data(); + if (vk->vkCreateDescriptorSetLayout(vk->device(), &layoutInfo, nullptr, &m_layout) != VK_SUCCESS) throw DxvkError("DxvkBindingSetLayoutKey: Failed to create descriptor set layout"); if (layoutInfo.bindingCount) { VkDescriptorUpdateTemplateCreateInfo templateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO }; - templateInfo.descriptorUpdateEntryCount = layoutInfo.bindingCount; + templateInfo.descriptorUpdateEntryCount = templateInfos.size(); templateInfo.pDescriptorUpdateEntries = templateInfos.data(); templateInfo.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET; templateInfo.descriptorSetLayout = m_layout; From b950102233c9cd4143cb603b91ca71d6e30863f8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 6 Aug 2022 01:44:56 +0200 Subject: [PATCH 0434/1348] [dxvk] Don't use MaxNumActiveBindings for descriptor updates --- src/dxvk/dxvk_context.cpp | 30 ++++++++++++++++++++---------- src/dxvk/dxvk_context.h | 7 +++++-- src/dxvk/dxvk_pipelayout.cpp | 4 +++- src/dxvk/dxvk_pipelayout.h | 9 +++++++++ 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 1169d31c0..a747394f5 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -21,16 +21,6 @@ namespace dxvk { // Init framebuffer info with default render pass in case // the app does not explicitly bind any render targets m_state.om.framebufferInfo = makeFramebufferInfo(m_state.om.renderTargets); - - for (uint32_t i = 0; i < MaxNumActiveBindings; i++) { - m_descriptorWrites[i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; - m_descriptorWrites[i].descriptorCount = 1; - m_descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_MAX_ENUM; - m_descriptorWrites[i].pImageInfo = &m_descriptors[i].image; - m_descriptorWrites[i].pBufferInfo = &m_descriptors[i].buffer; - m_descriptorWrites[i].pTexelBufferView = &m_descriptors[i].texelBuffer; - } - m_descriptorManager = new DxvkDescriptorManager(device.ptr(), type); // Default destination barriers for graphics pipelines @@ -4661,6 +4651,10 @@ namespace dxvk { void DxvkContext::updateResourceBindings(const DxvkBindingLayoutObjects* layout) { const auto& bindings = layout->layout(); + // Ensure that the arrays we write descriptor info to are big enough + if (unlikely(layout->getBindingCount() > m_descriptors.size())) + this->resizeDescriptorArrays(layout->getBindingCount()); + // On 32-bit wine, vkUpdateDescriptorSets has significant overhead due // to struct conversion, so we should use descriptor update templates. // For 64-bit applications, using templates is slower on some drivers. @@ -5849,4 +5843,20 @@ namespace dxvk { return m_zeroBuffer; } + + void DxvkContext::resizeDescriptorArrays( + uint32_t bindingCount) { + m_descriptors.resize(bindingCount); + m_descriptorWrites.resize(bindingCount); + + for (uint32_t i = 0; i < bindingCount; i++) { + m_descriptorWrites[i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET }; + m_descriptorWrites[i].descriptorCount = 1; + m_descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_MAX_ENUM; + m_descriptorWrites[i].pImageInfo = &m_descriptors[i].image; + m_descriptorWrites[i].pBufferInfo = &m_descriptors[i].buffer; + m_descriptorWrites[i].pTexelBufferView = &m_descriptors[i].texelBuffer; + } + } + } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index c203f8336..a716d31be 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1237,8 +1237,8 @@ namespace dxvk { std::vector m_deferredClears; - std::array m_descriptorWrites; - std::array m_descriptors; + std::vector m_descriptorWrites; + std::vector m_descriptors; std::array m_rc; std::array m_gpLookupCache = { }; @@ -1499,6 +1499,9 @@ namespace dxvk { Rc createZeroBuffer( VkDeviceSize size); + void resizeDescriptorArrays( + uint32_t bindingCount); + }; } diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index ef2cd26ce..e112ea78f 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -324,8 +324,10 @@ namespace dxvk { m_mapping.insert({ binding.resourceBinding, mapping }); } - if (bindingCount) + if (bindingCount) { + m_bindingCount += bindingCount; m_setMask |= 1u << i; + } } } diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 4cfcf50ff..1e8aa121c 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -411,6 +411,14 @@ namespace dxvk { return m_layout; } + /** + * \brief Queries total number of bindings + * \returns Binding count in all sets + */ + uint32_t getBindingCount() const { + return m_bindingCount; + } + /** * \brief Queries active descriptor set mask * \returns Bit mask of non-empty descriptor sets @@ -483,6 +491,7 @@ namespace dxvk { VkPipelineLayout m_completeLayout = VK_NULL_HANDLE; VkPipelineLayout m_independentLayout = VK_NULL_HANDLE; + uint32_t m_bindingCount = 0; uint32_t m_setMask = 0; std::array m_bindingObjects = { }; From 3aa786fb6fd4ef25cc34e7aafef489511625c3ee Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 6 Aug 2022 01:50:25 +0200 Subject: [PATCH 0435/1348] [dxvk] Get rid of MaxNumActiveBindings This only existed due to the binding mask, which we removed with the null descriptor rework. We can basically support an unlimited number of descriptors now. --- src/dxvk/dxvk_bind_mask.h | 3 --- src/dxvk/dxvk_limits.h | 1 - src/dxvk/dxvk_state_cache.cpp | 11 +++-------- src/dxvk/dxvk_state_cache_types.h | 15 ++------------- 4 files changed, 5 insertions(+), 25 deletions(-) diff --git a/src/dxvk/dxvk_bind_mask.h b/src/dxvk/dxvk_bind_mask.h index 57931064e..cabebaa1b 100644 --- a/src/dxvk/dxvk_bind_mask.h +++ b/src/dxvk/dxvk_bind_mask.h @@ -178,9 +178,6 @@ namespace dxvk { }; - using DxvkBindingMask = DxvkBindingSet; - - /** * \brief Bound shader resources * diff --git a/src/dxvk/dxvk_limits.h b/src/dxvk/dxvk_limits.h index eb2431e68..d197acb78 100644 --- a/src/dxvk/dxvk_limits.h +++ b/src/dxvk/dxvk_limits.h @@ -12,7 +12,6 @@ namespace dxvk { MaxNumXfbStreams = 4, MaxNumViewports = 16, MaxNumResourceSlots = 1216, - MaxNumActiveBindings = 384, MaxNumQueuedCommandBuffers = 18, MaxNumQueryCountPerPool = 128, MaxNumSpecConstants = 12, diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 770fedc5a..92962dacf 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -44,19 +44,14 @@ namespace dxvk { return read(data); } - bool read(DxvkBindingMask& data, uint32_t version) { + bool read(DxvkBindingMaskV10& data, uint32_t version) { // v11 removes this field if (version >= 11) return true; if (version < 9) { DxvkBindingMaskV8 v8; - - if (!read(v8)) - return false; - - data = v8.convert(); - return true; + return read(v8); } return read(data); @@ -577,7 +572,7 @@ namespace dxvk { keys[i] = g_nullShaderKey; } - DxvkBindingMask dummyBindingMask = { }; + DxvkBindingMaskV10 dummyBindingMask = { }; if (stageMask & VK_SHADER_STAGE_COMPUTE_BIT) { if (!data.read(dummyBindingMask, version)) diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index e12ca5d07..d257325a4 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -58,19 +58,8 @@ namespace dxvk { static_assert(sizeof(DxvkStateCacheHeader) == 12); - - class DxvkBindingMaskV8 : DxvkBindingSet<128> { - - public: - - DxvkBindingMask convert() const { - DxvkBindingMask result = { }; - for (uint32_t i = 0; i < 128; i++) - result.set(i, test(i)); - return result; - } - - }; + using DxvkBindingMaskV10 = DxvkBindingSet<384>; + using DxvkBindingMaskV8 = DxvkBindingSet<128>; class DxvkIlBindingV9 { From 4d9c09b5e7faf980de0e215d235475663ace3657 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 6 Aug 2022 02:09:55 +0200 Subject: [PATCH 0436/1348] [dxvk] Don't use pipeline libraries for VS that doesn't export position --- src/dxvk/dxvk_shader.cpp | 10 ++++++++++ src/dxvk/dxvk_shader.h | 1 + 2 files changed, 11 insertions(+) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index dc25c61b5..b2ef37e3f 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -89,6 +89,11 @@ namespace dxvk { varIds.push_back(varId); } + if (ins.arg(2) == spv::DecorationBuiltIn) { + if (ins.arg(3) == spv::BuiltInPosition) + m_flags.set(DxvkShaderFlag::ExportsPosition); + } + if (ins.arg(2) == spv::DecorationDescriptorSet) { uint32_t varId = ins.arg(1); bindingOffsets.resize(std::max(bindingOffsets.size(), size_t(varId + 1))); @@ -190,6 +195,11 @@ namespace dxvk { && m_info.stage != VK_SHADER_STAGE_COMPUTE_BIT) return false; + // Standalone vertex shaders must export vertex position + if (m_info.stage == VK_SHADER_STAGE_VERTEX_BIT + && !m_flags.test(DxvkShaderFlag::ExportsPosition)) + return false; + // Ignore shaders that have user-defined spec constants // and no selector to read their contents from elsewhere return !m_specConstantMask || (m_specConstantMask & (1u << MaxNumSpecConstants)); diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index e0eec2e0f..0a628054c 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -27,6 +27,7 @@ namespace dxvk { enum DxvkShaderFlag : uint64_t { HasSampleRateShading, HasTransformFeedback, + ExportsPosition, ExportsStencilRef, ExportsViewportIndexLayerFromVertexStage, }; From e7b7299ec12f1439c72091434048c3d53ed93004 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 6 Aug 2022 02:28:39 +0200 Subject: [PATCH 0437/1348] [dxvk] Also consider built-ins declared via OpMemberDecorate Otherwise we'll miss D3D11 shaders. Oops... --- src/dxvk/dxvk_shader.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index b2ef37e3f..0f556b680 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -114,6 +114,13 @@ namespace dxvk { m_o1IdxOffset = ins.offset() + 3; } + if (ins.opCode() == spv::OpMemberDecorate) { + if (ins.arg(3) == spv::DecorationBuiltIn) { + if (ins.arg(4) == spv::BuiltInPosition) + m_flags.set(DxvkShaderFlag::ExportsPosition); + } + } + if (ins.opCode() == spv::OpExecutionMode) { if (ins.arg(2) == spv::ExecutionModeStencilRefReplacingEXT) m_flags.set(DxvkShaderFlag::ExportsStencilRef); From 3c4e85d6302d2118a459caeeb8545d87352d0a65 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 18:51:11 +0000 Subject: [PATCH 0438/1348] [meta] Update Vulkan headers to 1.3.224 --- include/vulkan/vk_platform.h | 4 +- include/vulkan/vulkan.h | 2 +- include/vulkan/vulkan_core.h | 175 ++++++++++++++++++++++++++++++++-- include/vulkan/vulkan_win32.h | 2 +- 4 files changed, 173 insertions(+), 10 deletions(-) diff --git a/include/vulkan/vk_platform.h b/include/vulkan/vk_platform.h index 18b913abc..3ff8c5d14 100644 --- a/include/vulkan/vk_platform.h +++ b/include/vulkan/vk_platform.h @@ -2,7 +2,7 @@ // File: vk_platform.h // /* -** Copyright 2014-2021 The Khronos Group Inc. +** Copyright 2014-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -42,7 +42,7 @@ extern "C" #define VKAPI_CALL __stdcall #define VKAPI_PTR VKAPI_CALL #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 - #error "Vulkan isn't supported for the 'armeabi' NDK ABI" + #error "Vulkan is not supported for the 'armeabi' NDK ABI" #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" // calling convention, i.e. float parameters are passed in registers. This diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h index 3f7cdba58..004fa7095 100644 --- a/include/vulkan/vulkan.h +++ b/include/vulkan/vulkan.h @@ -2,7 +2,7 @@ #define VULKAN_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/vulkan/vulkan_core.h b/include/vulkan/vulkan_core.h index aef16f96d..9e28ee241 100644 --- a/include/vulkan/vulkan_core.h +++ b/include/vulkan/vulkan_core.h @@ -72,7 +72,7 @@ extern "C" { #define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 // Version of this file -#define VK_HEADER_VERSION 219 +#define VK_HEADER_VERSION 224 // Complete version of this file #define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) @@ -614,6 +614,9 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000, VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, + VK_STRUCTURE_TYPE_PIPELINE_ROBUSTNESS_CREATE_INFO_EXT = 1000068000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT = 1000068001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES_EXT = 1000068002, VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001, VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002, @@ -926,6 +929,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_EXT = 1000338002, VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_EXT = 1000338003, VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT = 1000338004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT = 1000339000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM = 1000342000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT = 1000344000, @@ -988,6 +992,9 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM = 1000425002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV = 1000430000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT = 1000437000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM = 1000440000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_PROPERTIES_QCOM = 1000440001, + VK_STRUCTURE_TYPE_IMAGE_VIEW_SAMPLE_WEIGHT_CREATE_INFO_QCOM = 1000440002, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_MERGE_FEEDBACK_FEATURES_EXT = 1000458000, VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_CONTROL_EXT = 1000458001, VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000458002, @@ -996,6 +1003,10 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT = 1000462001, VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT = 1000462002, VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT = 1000462003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM = 1000484000, + VK_STRUCTURE_TYPE_TILE_PROPERTIES_QCOM = 1000484001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC = 1000485000, + VK_STRUCTURE_TYPE_AMIGO_PROFILING_SUBMIT_INFO_SEC = 1000485001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, @@ -1214,6 +1225,7 @@ typedef enum VkImageLayout { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR = 1000299002, #endif + VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT = 1000339000, VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, @@ -1913,8 +1925,8 @@ typedef enum VkBorderColor { typedef enum VkFilter { VK_FILTER_NEAREST = 0, VK_FILTER_LINEAR = 1, - VK_FILTER_CUBIC_IMG = 1000015000, - VK_FILTER_CUBIC_EXT = VK_FILTER_CUBIC_IMG, + VK_FILTER_CUBIC_EXT = 1000015000, + VK_FILTER_CUBIC_IMG = VK_FILTER_CUBIC_EXT, VK_FILTER_MAX_ENUM = 0x7FFFFFFF } VkFilter; @@ -1950,6 +1962,8 @@ typedef enum VkDescriptorType { VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, VK_DESCRIPTOR_TYPE_MUTABLE_VALVE = 1000351000, + VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM = 1000440000, + VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM = 1000440001, VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF } VkDescriptorType; @@ -2085,7 +2099,6 @@ typedef enum VkFormatFeatureFlagBits { VK_FORMAT_FEATURE_DISJOINT_BIT = 0x00400000, VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000, #ifdef VK_ENABLE_BETA_EXTENSIONS VK_FORMAT_FEATURE_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000, #endif @@ -2093,6 +2106,7 @@ typedef enum VkFormatFeatureFlagBits { VK_FORMAT_FEATURE_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000, #endif VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000, VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000, VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000, #ifdef VK_ENABLE_BETA_EXTENSIONS @@ -2101,6 +2115,7 @@ typedef enum VkFormatFeatureFlagBits { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_FORMAT_FEATURE_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000, #endif + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT, VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, @@ -2111,7 +2126,6 @@ typedef enum VkFormatFeatureFlagBits { VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, VK_FORMAT_FEATURE_DISJOINT_BIT_KHR = VK_FORMAT_FEATURE_DISJOINT_BIT, VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG, VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkFormatFeatureFlagBits; typedef VkFlags VkFormatFeatureFlags; @@ -2186,7 +2200,10 @@ typedef enum VkImageUsageFlagBits { #ifdef VK_ENABLE_BETA_EXTENSIONS VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR = 0x00008000, #endif + VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x00080000, VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI = 0x00040000, + VK_IMAGE_USAGE_SAMPLE_WEIGHT_BIT_QCOM = 0x00100000, + VK_IMAGE_USAGE_SAMPLE_BLOCK_MATCH_BIT_QCOM = 0x00200000, VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkImageUsageFlagBits; @@ -2435,6 +2452,8 @@ typedef enum VkPipelineCreateFlagBits { VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT = 0x00800000, VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT = 0x00000400, VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000, + VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x02000000, + VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x04000000, VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT, @@ -2522,6 +2541,7 @@ typedef enum VkSamplerCreateFlagBits { VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT = 0x00000001, VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT = 0x00000002, VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT = 0x00000004, + VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM = 0x00000010, VK_SAMPLER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkSamplerCreateFlagBits; typedef VkFlags VkSamplerCreateFlags; @@ -2555,6 +2575,7 @@ typedef enum VkDependencyFlagBits { VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, VK_DEPENDENCY_DEVICE_GROUP_BIT = 0x00000004, VK_DEPENDENCY_VIEW_LOCAL_BIT = 0x00000002, + VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT = 0x00000008, VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR = VK_DEPENDENCY_VIEW_LOCAL_BIT, VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR = VK_DEPENDENCY_DEVICE_GROUP_BIT, VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF @@ -6586,6 +6607,10 @@ static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000ULL; #endif static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV = 0x4000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_WEIGHT_IMAGE_BIT_QCOM = 0x400000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_WEIGHT_SAMPLED_IMAGE_BIT_QCOM = 0x800000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM = 0x1000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BOX_FILTER_SAMPLED_BIT_QCOM = 0x2000000000ULL; typedef struct VkPhysicalDeviceVulkan13Features { VkStructureType sType; @@ -10290,6 +10315,51 @@ typedef struct VkPhysicalDeviceASTCDecodeFeaturesEXT { +#define VK_EXT_pipeline_robustness 1 +#define VK_EXT_PIPELINE_ROBUSTNESS_SPEC_VERSION 1 +#define VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_pipeline_robustness" + +typedef enum VkPipelineRobustnessBufferBehaviorEXT { + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT = 0, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT = 1, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT = 2, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT = 3, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_MAX_ENUM_EXT = 0x7FFFFFFF +} VkPipelineRobustnessBufferBehaviorEXT; + +typedef enum VkPipelineRobustnessImageBehaviorEXT { + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT_EXT = 0, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT = 1, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_EXT = 2, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2_EXT = 3, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_MAX_ENUM_EXT = 0x7FFFFFFF +} VkPipelineRobustnessImageBehaviorEXT; +typedef struct VkPhysicalDevicePipelineRobustnessFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 pipelineRobustness; +} VkPhysicalDevicePipelineRobustnessFeaturesEXT; + +typedef struct VkPhysicalDevicePipelineRobustnessPropertiesEXT { + VkStructureType sType; + void* pNext; + VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessStorageBuffers; + VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessUniformBuffers; + VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessVertexInputs; + VkPipelineRobustnessImageBehaviorEXT defaultRobustnessImages; +} VkPhysicalDevicePipelineRobustnessPropertiesEXT; + +typedef struct VkPipelineRobustnessCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPipelineRobustnessBufferBehaviorEXT storageBuffers; + VkPipelineRobustnessBufferBehaviorEXT uniformBuffers; + VkPipelineRobustnessBufferBehaviorEXT vertexInputs; + VkPipelineRobustnessImageBehaviorEXT images; +} VkPipelineRobustnessCreateInfoEXT; + + + #define VK_EXT_conditional_rendering 1 #define VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION 2 #define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering" @@ -13121,7 +13191,7 @@ typedef VkPhysicalDeviceTexelBufferAlignmentProperties VkPhysicalDeviceTexelBuff #define VK_QCOM_render_pass_transform 1 -#define VK_QCOM_RENDER_PASS_TRANSFORM_SPEC_VERSION 2 +#define VK_QCOM_RENDER_PASS_TRANSFORM_SPEC_VERSION 3 #define VK_QCOM_RENDER_PASS_TRANSFORM_EXTENSION_NAME "VK_QCOM_render_pass_transform" typedef struct VkRenderPassTransformBeginInfoQCOM { VkStructureType sType; @@ -13663,6 +13733,17 @@ VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout2EXT( #endif +#define VK_EXT_attachment_feedback_loop_layout 1 +#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_SPEC_VERSION 2 +#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME "VK_EXT_attachment_feedback_loop_layout" +typedef struct VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 attachmentFeedbackLoopLayout; +} VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT; + + + #define VK_EXT_4444_formats 1 #define VK_EXT_4444_FORMATS_SPEC_VERSION 1 #define VK_EXT_4444_FORMATS_EXTENSION_NAME "VK_EXT_4444_formats" @@ -14268,6 +14349,36 @@ typedef struct VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT { +#define VK_QCOM_image_processing 1 +#define VK_QCOM_IMAGE_PROCESSING_SPEC_VERSION 1 +#define VK_QCOM_IMAGE_PROCESSING_EXTENSION_NAME "VK_QCOM_image_processing" +typedef struct VkImageViewSampleWeightCreateInfoQCOM { + VkStructureType sType; + const void* pNext; + VkOffset2D filterCenter; + VkExtent2D filterSize; + uint32_t numPhases; +} VkImageViewSampleWeightCreateInfoQCOM; + +typedef struct VkPhysicalDeviceImageProcessingFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 textureSampleWeighted; + VkBool32 textureBoxFilter; + VkBool32 textureBlockMatch; +} VkPhysicalDeviceImageProcessingFeaturesQCOM; + +typedef struct VkPhysicalDeviceImageProcessingPropertiesQCOM { + VkStructureType sType; + void* pNext; + uint32_t maxWeightFilterPhases; + VkExtent2D maxWeightFilterDimension; + VkExtent2D maxBlockMatchRegion; + VkExtent2D maxBoxFilterBlockSize; +} VkPhysicalDeviceImageProcessingPropertiesQCOM; + + + #define VK_EXT_subpass_merge_feedback 1 #define VK_EXT_SUBPASS_MERGE_FEEDBACK_SPEC_VERSION 2 #define VK_EXT_SUBPASS_MERGE_FEEDBACK_EXTENSION_NAME "VK_EXT_subpass_merge_feedback" @@ -14371,6 +14482,58 @@ VKAPI_ATTR void VKAPI_CALL vkGetShaderModuleCreateInfoIdentifierEXT( #endif +#define VK_QCOM_tile_properties 1 +#define VK_QCOM_TILE_PROPERTIES_SPEC_VERSION 1 +#define VK_QCOM_TILE_PROPERTIES_EXTENSION_NAME "VK_QCOM_tile_properties" +typedef struct VkPhysicalDeviceTilePropertiesFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 tileProperties; +} VkPhysicalDeviceTilePropertiesFeaturesQCOM; + +typedef struct VkTilePropertiesQCOM { + VkStructureType sType; + void* pNext; + VkExtent3D tileSize; + VkExtent2D apronSize; + VkOffset2D origin; +} VkTilePropertiesQCOM; + +typedef VkResult (VKAPI_PTR *PFN_vkGetFramebufferTilePropertiesQCOM)(VkDevice device, VkFramebuffer framebuffer, uint32_t* pPropertiesCount, VkTilePropertiesQCOM* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetDynamicRenderingTilePropertiesQCOM)(VkDevice device, const VkRenderingInfo* pRenderingInfo, VkTilePropertiesQCOM* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetFramebufferTilePropertiesQCOM( + VkDevice device, + VkFramebuffer framebuffer, + uint32_t* pPropertiesCount, + VkTilePropertiesQCOM* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDynamicRenderingTilePropertiesQCOM( + VkDevice device, + const VkRenderingInfo* pRenderingInfo, + VkTilePropertiesQCOM* pProperties); +#endif + + +#define VK_SEC_amigo_profiling 1 +#define VK_SEC_AMIGO_PROFILING_SPEC_VERSION 1 +#define VK_SEC_AMIGO_PROFILING_EXTENSION_NAME "VK_SEC_amigo_profiling" +typedef struct VkPhysicalDeviceAmigoProfilingFeaturesSEC { + VkStructureType sType; + void* pNext; + VkBool32 amigoProfiling; +} VkPhysicalDeviceAmigoProfilingFeaturesSEC; + +typedef struct VkAmigoProfilingSubmitInfoSEC { + VkStructureType sType; + const void* pNext; + uint64_t firstDrawTimestamp; + uint64_t swapBufferTimestamp; +} VkAmigoProfilingSubmitInfoSEC; + + + #define VK_KHR_acceleration_structure 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) #define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 diff --git a/include/vulkan/vulkan_win32.h b/include/vulkan/vulkan_win32.h index 1b680f0b1..affe0c02a 100644 --- a/include/vulkan/vulkan_win32.h +++ b/include/vulkan/vulkan_win32.h @@ -2,7 +2,7 @@ #define VULKAN_WIN32_H_ 1 /* -** Copyright 2015-2021 The Khronos Group Inc. +** Copyright 2015-2022 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ From 9cf5c648d3b009f862ab08935cd0483bb72855bb Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 23:12:46 +0000 Subject: [PATCH 0439/1348] [vulkan] Add feedback loop layout to getWritableAspectsForLayout --- src/vulkan/vulkan_util.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vulkan/vulkan_util.h b/src/vulkan/vulkan_util.h index 38e0217cc..7fa064dd8 100644 --- a/src/vulkan/vulkan_util.h +++ b/src/vulkan/vulkan_util.h @@ -90,6 +90,7 @@ namespace dxvk::vk { inline VkImageAspectFlags getWritableAspectsForLayout(VkImageLayout layout) { switch (layout) { + case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT: case VK_IMAGE_LAYOUT_GENERAL: return VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: From 49b76fdd0793a1fbc8d195034aa72af1a49f0e1d Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 23:15:18 +0000 Subject: [PATCH 0440/1348] [dxvk] Support feedback loop layout in pickLayout --- src/dxvk/dxvk_image.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index 314584139..42d95971a 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -251,6 +251,13 @@ namespace dxvk { * \returns A compatible image layout */ VkImageLayout pickLayout(VkImageLayout layout) const { + if (unlikely(m_info.layout == VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT)) { + if (layout != VK_IMAGE_LAYOUT_GENERAL + && layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL + && layout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + return VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT; + } + return m_info.layout == VK_IMAGE_LAYOUT_GENERAL ? VK_IMAGE_LAYOUT_GENERAL : layout; } From 43f53f3c0e4e37c47c0f4f6136d21477daffa87f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 19:07:01 +0000 Subject: [PATCH 0441/1348] [dxvk] Enable VK_EXT_attachment_feedback_loop_layout if available --- src/dxvk/dxvk_adapter.cpp | 17 ++++++++++++++++- src/dxvk/dxvk_device_info.h | 1 + src/dxvk/dxvk_extensions.h | 1 + 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 42514ebdc..11982556e 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -244,6 +244,8 @@ namespace dxvk { || !required.vk13.dynamicRendering) && (m_deviceFeatures.vk13.maintenance4 || !required.vk13.maintenance4) + && (m_deviceFeatures.extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout + || !required.extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout) && (m_deviceFeatures.extCustomBorderColor.customBorderColors || !required.extCustomBorderColor.customBorderColors) && (m_deviceFeatures.extCustomBorderColor.customBorderColorWithoutFormat @@ -283,9 +285,10 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, + &devExtensions.extAttachmentFeedbackLoopLayout, &devExtensions.extConservativeRasterization, &devExtensions.extCustomBorderColor, &devExtensions.extDepthClipEnable, @@ -403,6 +406,11 @@ namespace dxvk { enabledFeatures.vk13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; enabledFeatures.vk13.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.vk13); + if (devExtensions.extAttachmentFeedbackLoopLayout) { + enabledFeatures.extAttachmentFeedbackLoopLayout.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT; + enabledFeatures.extAttachmentFeedbackLoopLayout.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extAttachmentFeedbackLoopLayout); + } + if (devExtensions.extCustomBorderColor) { enabledFeatures.extCustomBorderColor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT; enabledFeatures.extCustomBorderColor.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extCustomBorderColor); @@ -681,6 +689,11 @@ namespace dxvk { m_deviceFeatures.vk13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; m_deviceFeatures.vk13.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.vk13); + if (m_deviceExtensions.supports(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME)) { + m_deviceFeatures.extAttachmentFeedbackLoopLayout.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT; + m_deviceFeatures.extAttachmentFeedbackLoopLayout.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extAttachmentFeedbackLoopLayout); + } + if (m_deviceExtensions.supports(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME)) { m_deviceFeatures.extCustomBorderColor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT; m_deviceFeatures.extCustomBorderColor.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extCustomBorderColor); @@ -811,6 +824,8 @@ namespace dxvk { "\n synchronization2 : ", features.vk13.synchronization2, "\n dynamicRendering : ", features.vk13.dynamicRendering, "\n maintenance4 : ", features.vk13.maintenance4, + "\n", VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME, + "\n attachmentFeedbackLoopLayout : ", features.extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout ? "1" : "0", "\n", VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, "\n customBorderColors : ", features.extCustomBorderColor.customBorderColors ? "1" : "0", "\n customBorderColorWithoutFormat : ", features.extCustomBorderColor.customBorderColorWithoutFormat ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index d8bc9ffdb..212bd69c5 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -39,6 +39,7 @@ namespace dxvk { VkPhysicalDeviceVulkan11Features vk11; VkPhysicalDeviceVulkan12Features vk12; VkPhysicalDeviceVulkan13Features vk13; + VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT extAttachmentFeedbackLoopLayout; VkPhysicalDeviceCustomBorderColorFeaturesEXT extCustomBorderColor; VkPhysicalDeviceDepthClipEnableFeaturesEXT extDepthClipEnable; VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT extGraphicsPipelineLibrary; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index ffc7c3730..c9d9030e8 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -278,6 +278,7 @@ namespace dxvk { struct DxvkDeviceExtensions { DxvkExt amdMemoryOverallocationBehaviour = { VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt amdShaderFragmentMask = { VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extAttachmentFeedbackLoopLayout = { VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extConservativeRasterization = { VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extCustomBorderColor = { VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extDepthClipEnable = { VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, DxvkExtMode::Optional }; From dff514c924ca2d163c0bc637493696b0cf8a8cc3 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 22:21:43 +0000 Subject: [PATCH 0442/1348] [dxvk] Add hazard tracking to fragment output state We need this to set the right pipeline bits for supporting attachment feedback loops on some vendors. --- src/dxvk/dxvk_context.cpp | 3 ++- src/dxvk/dxvk_graphics.cpp | 21 +++++++++++++++++++-- src/dxvk/dxvk_graphics.h | 2 ++ src/dxvk/dxvk_graphics_state.h | 17 ++++++++++++++--- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index a747394f5..8d74b4364 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2452,7 +2452,8 @@ namespace dxvk { void DxvkContext::setLogicOpState(const DxvkLogicOpState& lo) { m_state.gp.state.om = DxvkOmInfo( lo.enableLogicOp, - lo.logicOp); + lo.logicOp, + m_state.gp.state.om.feedbackLoop()); m_flags.set(DxvkContextFlag::GpDirtyPipelineState); } diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 86633ba1a..822c4a832 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -225,6 +225,8 @@ namespace dxvk { cbInfo.logicOpEnable = state.om.enableLogicOp(); cbInfo.logicOp = state.om.logicOp(); + feedbackLoop = state.om.feedbackLoop(); + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { rtColorFormats[i] = state.rt.getColorFormat(i); @@ -321,7 +323,8 @@ namespace dxvk { && msInfo.alphaToCoverageEnable == other.msInfo.alphaToCoverageEnable && msInfo.alphaToOneEnable == other.msInfo.alphaToOneEnable && msSampleMask == other.msSampleMask - && cbUseDynamicBlendConstants == other.cbUseDynamicBlendConstants; + && cbUseDynamicBlendConstants == other.cbUseDynamicBlendConstants + && feedbackLoop == other.feedbackLoop; for (uint32_t i = 0; i < rtInfo.colorAttachmentCount && eq; i++) eq = rtColorFormats[i] == other.rtColorFormats[i]; @@ -360,6 +363,7 @@ namespace dxvk { hash.add(uint32_t(msInfo.alphaToOneEnable)); hash.add(uint32_t(msSampleMask)); hash.add(uint32_t(cbUseDynamicBlendConstants)); + hash.add(uint32_t(feedbackLoop)); for (uint32_t i = 0; i < rtInfo.colorAttachmentCount; i++) hash.add(uint32_t(rtColorFormats[i])); @@ -396,6 +400,13 @@ namespace dxvk { dyInfo.pDynamicStates = &dynamicState; } + VkPipelineCreateFlags flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + if (state.feedbackLoop & VK_IMAGE_ASPECT_COLOR_BIT) + flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + + if (state.feedbackLoop & VK_IMAGE_ASPECT_DEPTH_BIT) + flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + // pNext is non-const for some reason, but this is only an input // structure, so we should be able to safely use const_cast. VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT }; @@ -403,7 +414,7 @@ namespace dxvk { libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT; VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; - info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + info.flags = flags; info.pColorBlendState = &state.cbInfo; info.pMultisampleState = &state.msInfo; info.pDynamicState = &dyInfo; @@ -1159,6 +1170,12 @@ namespace dxvk { stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, key.shState.fsInfo), &key.scState.scInfo); } + if (key.foState.feedbackLoop & VK_IMAGE_ASPECT_COLOR_BIT) + flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + + if (key.foState.feedbackLoop & VK_IMAGE_ASPECT_DEPTH_BIT) + flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &key.foState.rtInfo }; info.flags = flags; info.stageCount = stageInfo.getStageCount(); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index a0c0bfbaa..4c234f812 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -119,6 +119,8 @@ namespace dxvk { std::array cbAttachments = { }; std::array rtColorFormats = { }; + VkImageAspectFlags feedbackLoop = 0u; + bool eq(const DxvkGraphicsPipelineFragmentOutputState& other) const; size_t hash() const; diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 49f081a35..5713115c1 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -433,10 +433,12 @@ namespace dxvk { DxvkOmInfo() = default; DxvkOmInfo( - VkBool32 enableLogicOp, - VkLogicOp logicOp) + VkBool32 enableLogicOp, + VkLogicOp logicOp, + VkImageAspectFlags feedbackLoop) : m_enableLogicOp (uint16_t(enableLogicOp)), m_logicOp (uint16_t(logicOp)), + m_feedbackLoop (uint16_t(feedbackLoop)), m_reserved (0) { } VkBool32 enableLogicOp() const { @@ -447,11 +449,20 @@ namespace dxvk { return VkLogicOp(m_logicOp); } + VkImageAspectFlags feedbackLoop() const { + return VkImageAspectFlags(m_feedbackLoop); + } + + void setFeedbackLoop(VkImageAspectFlags feedbackLoop) { + m_feedbackLoop = uint16_t(feedbackLoop); + } + private: uint16_t m_enableLogicOp : 1; uint16_t m_logicOp : 4; - uint16_t m_reserved : 11; + uint16_t m_feedbackLoop : 2; + uint16_t m_reserved : 9; }; From 31d17efb48efcabf4dd688602624f6a99e13c9e1 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 23:09:40 +0000 Subject: [PATCH 0443/1348] [dxvk] Add feedback loop aspect flags to bindRenderTargets --- src/d3d11/d3d11_context.cpp | 4 ++-- src/d3d11/d3d11_video.cpp | 4 ++-- src/d3d9/d3d9_device.cpp | 2 +- src/dxvk/dxvk_context.h | 8 +++++++- src/dxvk/dxvk_swapchain_blitter.cpp | 2 +- 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 88a0a4c49..656b1ceff 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3161,7 +3161,7 @@ namespace dxvk { EmitCs([ cAttachments = std::move(attachments) ] (DxvkContext* ctx) mutable { - ctx->bindRenderTargets(Forwarder::move(cAttachments)); + ctx->bindRenderTargets(Forwarder::move(cAttachments), 0u); }); // If necessary, update push constant for the sample count @@ -3813,7 +3813,7 @@ namespace dxvk { cUsedBindings = GetMaxUsedBindings() ] (DxvkContext* ctx) { // Reset render targets - ctx->bindRenderTargets(DxvkRenderTargets()); + ctx->bindRenderTargets(DxvkRenderTargets(), 0u); // Reset vertex input state ctx->setInputLayout(0, nullptr, 0, nullptr); diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index b8fd949fd..96e1486b8 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1198,7 +1198,7 @@ namespace dxvk { rt.color[0].view = cView; rt.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - ctx->bindRenderTargets(std::move(rt)); + ctx->bindRenderTargets(std::move(rt), 0u); ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, Rc(m_vs)); ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, Rc(m_fs)); ctx->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo)); @@ -1312,7 +1312,7 @@ namespace dxvk { void D3D11VideoContext::UnbindResources() { m_ctx->EmitCs([this] (DxvkContext* ctx) { - ctx->bindRenderTargets(DxvkRenderTargets()); + ctx->bindRenderTargets(DxvkRenderTargets(), 0u); ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, nullptr); ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, nullptr); diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 8f9f964ff..f972daa42 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5465,7 +5465,7 @@ namespace dxvk { EmitCs([ cAttachments = std::move(attachments) ] (DxvkContext* ctx) mutable { - ctx->bindRenderTargets(std::move(cAttachments)); + ctx->bindRenderTargets(std::move(cAttachments), 0u); }); } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index a716d31be..bebbcd527 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -87,10 +87,16 @@ namespace dxvk { * \param [in] targets Render targets to bind */ void bindRenderTargets( - DxvkRenderTargets&& targets) { + DxvkRenderTargets&& targets, + VkImageAspectFlags feedbackLoop) { // Set up default render pass ops m_state.om.renderTargets = std::move(targets); + if (unlikely(m_state.gp.state.om.feedbackLoop() != feedbackLoop)) { + m_state.gp.state.om.setFeedbackLoop(feedbackLoop); + m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + } + this->resetRenderPassOps( m_state.om.renderTargets, m_state.om.renderPassOps); diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index c69a89428..603e1497d 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -180,7 +180,7 @@ namespace dxvk { renderTargets.color[0].view = dstView; renderTargets.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - ctx->bindRenderTargets(std::move(renderTargets)); + ctx->bindRenderTargets(std::move(renderTargets), 0u); VkExtent2D dstExtent = { dstView->imageInfo().extent.width, From 8d070e54a1b36f695299b6a89705c7946c596e54 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 19:07:59 +0000 Subject: [PATCH 0444/1348] [d3d9] Enable extAttachmentFeedbackLoopLayout feature if available --- src/d3d9/d3d9_device.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index f972daa42..b483ba35d 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3963,6 +3963,9 @@ namespace dxvk { enabled.extCustomBorderColor.customBorderColorWithoutFormat = VK_TRUE; } + if (supported.extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout) + enabled.extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout = VK_TRUE; + enabled.extNonSeamlessCubeMap.nonSeamlessCubeMap = supported.extNonSeamlessCubeMap.nonSeamlessCubeMap; return enabled; From 90abd993d4734dedbe37ff4619019aec0dcd78d1 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 23:12:03 +0000 Subject: [PATCH 0445/1348] [d3d9] Pass feedback loop aspect mask to backend --- src/d3d9/d3d9_device.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index b483ba35d..f629f5524 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5464,11 +5464,20 @@ namespace dxvk { } } + VkImageAspectFlags feedbackLoopAspects = 0u; + if (m_hazardLayout == VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT) { + if (m_activeHazardsRT != 0) + feedbackLoopAspects |= VK_IMAGE_ASPECT_COLOR_BIT; + if (m_activeHazardsDS != 0) + feedbackLoopAspects |= VK_IMAGE_ASPECT_DEPTH_BIT; + } + // Create and bind the framebuffer object to the context EmitCs([ - cAttachments = std::move(attachments) + cAttachments = std::move(attachments), + cFeedbackLoopAspects = feedbackLoopAspects ] (DxvkContext* ctx) mutable { - ctx->bindRenderTargets(std::move(cAttachments), 0u); + ctx->bindRenderTargets(std::move(cAttachments), cFeedbackLoopAspects); }); } From 63d582a6e7ab63e18503d1238101705a818f5ad0 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 19:12:21 +0000 Subject: [PATCH 0446/1348] [d3d9] Use VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_EXT for hazards if available --- src/d3d9/d3d9_common_texture.h | 12 +++++++----- src/d3d9/d3d9_device.cpp | 10 +++++++--- src/d3d9/d3d9_device.h | 2 ++ src/d3d9/d3d9_subresource.h | 8 ++++---- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index c29a9243c..7d15ca954 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -343,20 +343,22 @@ namespace dxvk { return m_sampleView.Pick(srgb && IsSrgbCompatible()); } - VkImageLayout DetermineRenderTargetLayout() const { + VkImageLayout DetermineRenderTargetLayout(VkImageLayout hazardLayout) const { + if (unlikely(m_hazardous)) + return hazardLayout; + return m_image != nullptr && - m_image->info().tiling == VK_IMAGE_TILING_OPTIMAL && - !m_hazardous + m_image->info().tiling == VK_IMAGE_TILING_OPTIMAL ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL; } - VkImageLayout DetermineDepthStencilLayout(bool write, bool hazardous) const { + VkImageLayout DetermineDepthStencilLayout(bool write, bool hazardous, VkImageLayout hazardLayout) const { VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; if (unlikely(hazardous)) { layout = write - ? VK_IMAGE_LAYOUT_GENERAL + ? hazardLayout : VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; } diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index f629f5524..edae98ac1 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -115,6 +115,10 @@ namespace dxvk { m_availableMemory = DetermineInitialTextureMemory(); + m_hazardLayout = dxvkDevice->features().extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout + ? VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT + : VK_IMAGE_LAYOUT_GENERAL; + // Initially set all the dirty flags so we // always end up giving the backend *something* to work with. m_flags.set(D3D9DeviceFlag::DirtyFramebuffer); @@ -5241,7 +5245,7 @@ namespace dxvk { // Guaranteed to not be nullptr... auto tex = m_state.renderTargets[rtIdx]->GetCommonTexture(); if (unlikely(!tex->MarkHazardous())) { - TransitionImage(tex, VK_IMAGE_LAYOUT_GENERAL); + TransitionImage(tex, m_hazardLayout); m_flags.set(D3D9DeviceFlag::DirtyFramebuffer); } } @@ -5447,7 +5451,7 @@ namespace dxvk { attachments.color[i] = { m_state.renderTargets[i]->GetRenderTargetView(srgb), - m_state.renderTargets[i]->GetRenderTargetLayout() }; + m_state.renderTargets[i]->GetRenderTargetLayout(m_hazardLayout) }; } if (m_state.depthStencil != nullptr && @@ -5460,7 +5464,7 @@ namespace dxvk { if (likely(sampleCount == VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM || sampleCount == dsImageInfo.sampleCount)) { attachments.depth = { m_state.depthStencil->GetDepthStencilView(), - m_state.depthStencil->GetDepthStencilLayout(depthWrite, m_activeHazardsDS != 0) }; + m_state.depthStencil->GetDepthStencilLayout(depthWrite, m_activeHazardsDS != 0, m_hazardLayout) }; } } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 0e1b5401b..78b16337e 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1255,6 +1255,8 @@ namespace dxvk { bool m_amdATOC = false; bool m_nvATOC = false; bool m_ffZTest = false; + + VkImageLayout m_hazardLayout = VK_IMAGE_LAYOUT_GENERAL; float m_depthBiasScale = 0.0f; diff --git a/src/d3d9/d3d9_subresource.h b/src/d3d9/d3d9_subresource.h index 8d0475018..3431cec47 100644 --- a/src/d3d9/d3d9_subresource.h +++ b/src/d3d9/d3d9_subresource.h @@ -95,8 +95,8 @@ namespace dxvk { return view; } - inline VkImageLayout GetRenderTargetLayout() const { - return m_texture->DetermineRenderTargetLayout(); + inline VkImageLayout GetRenderTargetLayout(VkImageLayout hazardLayout) const { + return m_texture->DetermineRenderTargetLayout(hazardLayout); } inline const Rc& GetDepthStencilView() { @@ -108,8 +108,8 @@ namespace dxvk { return view; } - inline VkImageLayout GetDepthStencilLayout(bool write, bool hazardous) const { - return m_texture->DetermineDepthStencilLayout(write, hazardous); + inline VkImageLayout GetDepthStencilLayout(bool write, bool hazardous, VkImageLayout hazardLayout) const { + return m_texture->DetermineDepthStencilLayout(write, hazardous, hazardLayout); } inline bool IsNull() { From 8c9601b4cd27c0699b52c538aba74572892619c6 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 19:15:27 +0000 Subject: [PATCH 0447/1348] [d3d9] Remove generalHazards option Move everything into MarkRenderHazard. We are doing a big bump for driver support anyway, no reason to keep this around. Old drivers can take the perf penalty. --- src/d3d9/d3d9_device.cpp | 14 ++++++-------- src/d3d9/d3d9_options.cpp | 7 ------- src/d3d9/d3d9_options.h | 4 ---- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index edae98ac1..336baacea 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5241,6 +5241,10 @@ namespace dxvk { void D3D9DeviceEx::MarkRenderHazards() { + EmitCs([](DxvkContext* ctx) { + ctx->emitGraphicsBarrier(); + }); + for (uint32_t rtIdx : bit::BitMask(m_activeHazardsRT)) { // Guaranteed to not be nullptr... auto tex = m_state.renderTargets[rtIdx]->GetCommonTexture(); @@ -5957,14 +5961,8 @@ namespace dxvk { void D3D9DeviceEx::PrepareDraw(D3DPRIMITIVETYPE PrimitiveType) { - if (unlikely(m_activeHazardsRT != 0)) { - EmitCs([](DxvkContext* ctx) { - ctx->emitGraphicsBarrier(); - }); - - if (m_d3d9Options.generalHazards) - MarkRenderHazards(); - } + if (unlikely(m_activeHazardsRT != 0)) + MarkRenderHazards(); if (unlikely((m_lastHazardsDS == 0) != (m_activeHazardsDS == 0))) { m_flags.set(D3D9DeviceFlag::DirtyFramebuffer); diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index ec44bf245..822bc4551 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -75,13 +75,6 @@ namespace dxvk { this->seamlessCubes = config.getOption ("d3d9.seamlessCubes", false); this->textureMemory = config.getOption ("d3d9.textureMemory", 100) << 20; - // If we are not Nvidia, enable general hazards. - this->generalHazards = adapter != nullptr - && !adapter->matchesDriver( - VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, - 0, 0); - applyTristate(this->generalHazards, config.getOption("d3d9.generalHazards", Tristate::Auto)); - std::string floatEmulation = Config::toLower(config.getOption("d3d9.floatEmulation", "auto")); if (floatEmulation == "strict") { d3d9FloatEmulation = D3D9FloatEmulation::Strict; diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index 34d3ae1f1..2a091fc45 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -67,10 +67,6 @@ namespace dxvk { /// Defer surface creation bool deferSurfaceCreation; - /// Whether to transition to general - /// for rendering hazards - bool generalHazards; - /// Anisotropic filter override /// /// Enforces anisotropic filtering with the From 9108f8c76c19cb526d77c06fbb401fdaa4348d54 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 5 Aug 2022 18:46:32 +0000 Subject: [PATCH 0448/1348] [d3d9] Clean up fetch4 handling --- src/d3d9/d3d9_device.cpp | 81 +++++++++++++++++++--------------------- src/d3d9/d3d9_device.h | 8 ++++ 2 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 336baacea..716ab5b34 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3691,6 +3691,8 @@ namespace dxvk { state[StateSampler][Type] = Value; + const uint32_t samplerBit = 1u << StateSampler; + if (Type == D3DSAMP_ADDRESSU || Type == D3DSAMP_ADDRESSV || Type == D3DSAMP_ADDRESSW @@ -3701,38 +3703,24 @@ namespace dxvk { || Type == D3DSAMP_MIPMAPLODBIAS || Type == D3DSAMP_MAXMIPLEVEL || Type == D3DSAMP_BORDERCOLOR) - m_dirtySamplerStates |= 1u << StateSampler; - else if (Type == D3DSAMP_SRGBTEXTURE && (m_activeTextures & (1u << StateSampler))) - m_dirtyTextures |= 1u << StateSampler; + m_dirtySamplerStates |= samplerBit; + else if (Type == D3DSAMP_SRGBTEXTURE && (m_activeTextures & samplerBit)) + m_dirtyTextures |= samplerBit; constexpr DWORD Fetch4Enabled = MAKEFOURCC('G', 'E', 'T', '4'); constexpr DWORD Fetch4Disabled = MAKEFOURCC('G', 'E', 'T', '1'); if (unlikely(Type == D3DSAMP_MIPMAPLODBIAS)) { - auto texture = GetCommonTexture(m_state.textures[StateSampler]); - bool textureSupportsFetch4 = texture != nullptr && texture->SupportsFetch4(); + if (unlikely(Value == Fetch4Enabled)) + m_fetch4Enabled |= samplerBit; + else if (unlikely(Value == Fetch4Disabled)) + m_fetch4Enabled &= ~samplerBit; - if (unlikely(Value == Fetch4Enabled)) { - m_fetch4Enabled |= 1u << StateSampler; - if (textureSupportsFetch4 && state[StateSampler][D3DSAMP_MAGFILTER] == D3DTEXF_POINT) { - m_fetch4 |= 1u << StateSampler; - } - } - else if (unlikely(Value == Fetch4Disabled)) { - m_fetch4Enabled &= ~(1u << StateSampler); - m_fetch4 &= ~(1u << StateSampler); - } + UpdateActiveFetch4(StateSampler); } - if (unlikely(Type == D3DSAMP_MAGFILTER && (m_fetch4Enabled & (1u << StateSampler)))) { - auto texture = GetCommonTexture(m_state.textures[StateSampler]); - bool textureSupportsFetch4 = texture != nullptr && texture->SupportsFetch4(); - - if (Value == D3DTEXF_POINT && textureSupportsFetch4) - m_fetch4 |= 1u << StateSampler; - else - m_fetch4 &= ~(1u << StateSampler); - } + if (unlikely(Type == D3DSAMP_MAGFILTER && (m_fetch4Enabled & samplerBit))) + UpdateActiveFetch4(StateSampler); return D3D_OK; } @@ -3783,25 +3771,11 @@ namespace dxvk { m_dirtySamplerStates |= 1u << StateSampler; } - if (unlikely(m_fetch4Enabled & (1u << StateSampler))) { - const bool samplerFetch4 = (m_fetch4 & (1u << StateSampler)) != 0; - const bool pointFilter = m_state.samplerStates[StateSampler][D3DSAMP_MAGFILTER] == D3DTEXF_POINT - && m_state.samplerStates[StateSampler][D3DSAMP_MINFILTER] == D3DTEXF_POINT; - const bool textureSupportsFetch4 = newTexture->SupportsFetch4(); - - if (unlikely(textureSupportsFetch4 && pointFilter && !samplerFetch4)) { - // We're swapping a multi channel texture for a single channel texture => turn on fetch4 - m_fetch4 |= 1u << StateSampler; - m_dirtySamplerStates |= 1u << StateSampler; - } else if (unlikely(!textureSupportsFetch4 && samplerFetch4)) { - // We're swapping a single channel texture for a multi channel one => turn off fetch4 - m_fetch4 &= ~(1u << StateSampler); - m_dirtySamplerStates |= 1u << StateSampler; - } - } - } else if (unlikely(m_fetch4 & (1u << StateSampler))) { - m_fetch4 &= ~(1u << StateSampler); - m_dirtySamplerStates |= 1u << StateSampler; + if (unlikely(m_fetch4Enabled & (1u << StateSampler))) + UpdateActiveFetch4(StateSampler); + } else { + if (unlikely(m_fetch4 & (1u << StateSampler))) + UpdateActiveFetch4(StateSampler); } DWORD combinedUsage = oldUsage | newUsage; @@ -5256,6 +5230,27 @@ namespace dxvk { } + void D3D9DeviceEx::UpdateActiveFetch4(uint32_t stateSampler) { + auto& state = m_state.samplerStates; + + const uint32_t samplerBit = 1u << stateSampler; + + auto texture = GetCommonTexture(m_state.textures[stateSampler]); + const bool textureSupportsFetch4 = texture != nullptr && texture->SupportsFetch4(); + + const bool fetch4Enabled = m_fetch4Enabled & samplerBit; + const bool pointSampled = state[stateSampler][D3DSAMP_MAGFILTER] == D3DTEXF_POINT; + const bool shouldFetch4 = fetch4Enabled && textureSupportsFetch4 && pointSampled; + + if (unlikely(shouldFetch4 != !!(m_fetch4 & samplerBit))) { + if (shouldFetch4) + m_fetch4 |= samplerBit; + else + m_fetch4 &= ~samplerBit; + } + } + + void D3D9DeviceEx::UploadManagedTexture(D3D9CommonTexture* pResource) { for (uint32_t subresource = 0; subresource < pResource->CountSubresources(); subresource++) { if (!pResource->NeedsUpload(subresource)) diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 78b16337e..6641b25aa 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -767,6 +767,8 @@ namespace dxvk { void MarkRenderHazards(); + void UpdateActiveFetch4(uint32_t stateSampler); + void UploadManagedTexture(D3D9CommonTexture* pResource); void UploadManagedTextures(uint32_t mask); @@ -1240,6 +1242,12 @@ namespace dxvk { uint32_t m_activeTexturesToUpload = 0; uint32_t m_activeTexturesToGen = 0; + // m_fetch4Enabled is whether fetch4 is currently enabled + // from the application. + // + // m_fetch4 is whether it should be enabled in the shader + // ie. are we in a correct state to use it + // (enabled + texture supports it + point sampled) uint32_t m_fetch4Enabled = 0; uint32_t m_fetch4 = 0; From 65da0da9547cd31a30b00bd6503796807ea6b9b7 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 6 Aug 2022 01:20:01 +0000 Subject: [PATCH 0449/1348] [d3d9] Support for graphics pipeline libraries --- src/d3d9/d3d9_device.cpp | 16 +++++++++ src/d3d9/d3d9_device.h | 3 ++ src/d3d9/d3d9_fixed_function.cpp | 57 +++++++++++++++++++++++++++----- src/d3d9/d3d9_fixed_function.h | 7 ++-- src/d3d9/d3d9_spec_constants.h | 37 ++++++++++++++++++--- src/dxso/dxso_compiler.cpp | 23 +++++++------ src/dxso/dxso_compiler.h | 2 ++ 7 files changed, 119 insertions(+), 26 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 716ab5b34..2572e3423 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -111,6 +111,8 @@ namespace dxvk { } } + m_usingGraphicsPipelines = dxvkDevice->features().extGraphicsPipelineLibrary.graphicsPipelineLibrary; + CreateConstantBuffers(); m_availableMemory = DetermineInitialTextureMemory(); @@ -4862,6 +4864,13 @@ namespace dxvk { CanSWVP() ? sizeof(D3D9FixedFunctionVertexBlendDataSW) : sizeof(D3D9FixedFunctionVertexBlendDataHW)); + + if (m_usingGraphicsPipelines) { + m_specBuffer = D3D9ConstantBuffer(this, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, + getSpecConstantBufferSlot(), + sizeof(D3D9SpecializationInfo)); + } } @@ -7303,6 +7312,13 @@ namespace dxvk { ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, i, cSpecInfo.data[i]); }); + if (m_usingGraphicsPipelines) { + // TODO: Make uploading specialization information less naive. + auto mapPtr = m_specBuffer.AllocSlice(); + auto dst = reinterpret_cast(mapPtr); + *dst = m_specInfo; + } + m_flags.clr(D3D9DeviceFlag::DirtySpecializationEntries); } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 6641b25aa..487d038f6 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1188,6 +1188,7 @@ namespace dxvk { D3D9ConstantBuffer m_vsVertexBlend; D3D9ConstantBuffer m_psFixedFunction; D3D9ConstantBuffer m_psShared; + D3D9ConstantBuffer m_specBuffer; Rc m_upBuffer; VkDeviceSize m_upBufferOffset = 0ull; @@ -1266,6 +1267,8 @@ namespace dxvk { VkImageLayout m_hazardLayout = VK_IMAGE_LAYOUT_GENERAL; + bool m_usingGraphicsPipelines = false; + float m_depthBiasScale = 0.0f; uint32_t m_robustSSBOAlignment = 1; diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 45224b748..a525d4508 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -40,10 +40,10 @@ namespace dxvk { spvModule.opAccessChain(floatPtr, fogCtx.RenderState, 1, &fogDensityMember)); uint32_t fogMode = spec.get( - spvModule, + spvModule, fogCtx.SpecUBO, fogCtx.IsPixel ? SpecPixelFogMode : SpecVertexFogMode); - uint32_t fogEnabled = spec.get(spvModule, SpecFogEnabled); + uint32_t fogEnabled = spec.get(spvModule, fogCtx.SpecUBO, SpecFogEnabled); fogEnabled = spvModule.opINotEqual(spvModule.defBoolType(), fogEnabled, spvModule.constu32(0)); uint32_t doFog = spvModule.allocateId(); @@ -244,7 +244,43 @@ namespace dxvk { } - D3D9PointSizeInfoVS GetPointSizeInfoVS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock, bool isFixedFunction) { + uint32_t SetupSpecUBO(SpirvModule& spvModule, std::vector& bindings) { + uint32_t uintType = spvModule.defIntType(32, 0); + + std::array specMembers; + for (auto& x : specMembers) + x = uintType; + + uint32_t specStruct = spvModule.defStructTypeUnique(uint32_t(specMembers.size()), specMembers.data()); + + spvModule.setDebugName (specStruct, "spec_state_t"); + spvModule.decorate (specStruct, spv::DecorationBlock); + + for (uint32_t i = 0; i < SpecConstantCount; i++) { + std::string name = str::format("dword", i); + spvModule.setDebugMemberName (specStruct, i, name.c_str()); + spvModule.memberDecorateOffset (specStruct, i, sizeof(uint32_t) * i); + } + + uint32_t specBlock = spvModule.newVar( + spvModule.defPointerType(specStruct, spv::StorageClassUniform), + spv::StorageClassUniform); + + spvModule.setDebugName (specBlock, "spec_state"); + spvModule.decorateDescriptorSet(specBlock, 0); + spvModule.decorateBinding (specBlock, getSpecConstantBufferSlot()); + + DxvkBindingInfo binding = { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }; + binding.resourceBinding = getSpecConstantBufferSlot(); + binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; + binding.access = VK_ACCESS_UNIFORM_READ_BIT; + bindings.push_back(binding); + + return specBlock; + } + + + D3D9PointSizeInfoVS GetPointSizeInfoVS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock, uint32_t specUbo, bool isFixedFunction) { uint32_t floatType = spvModule.defFloatType(32); uint32_t floatPtr = spvModule.defPointerType(floatType, spv::StorageClassPushConstant); uint32_t vec3Type = spvModule.defVectorType(floatType, 3); @@ -260,7 +296,7 @@ namespace dxvk { uint32_t value = perVertPointSize != 0 ? perVertPointSize : LoadFloat(D3D9RenderStateItem::PointSize); if (isFixedFunction) { - uint32_t pointMode = spec.get(spvModule, SpecPointMode); + uint32_t pointMode = spec.get(spvModule, specUbo, SpecPointMode); uint32_t scaleBit = spvModule.opBitFieldUExtract(uint32Type, pointMode, spvModule.consti32(0), spvModule.consti32(1)); uint32_t isScale = spvModule.opIEqual(boolType, scaleBit, spvModule.constu32(1)); @@ -306,12 +342,12 @@ namespace dxvk { } - D3D9PointSizeInfoPS GetPointSizeInfoPS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t rsBlock) { + D3D9PointSizeInfoPS GetPointSizeInfoPS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t rsBlock, uint32_t specUbo) { uint32_t uint32Type = spvModule.defIntType(32, 0); uint32_t boolType = spvModule.defBoolType(); uint32_t boolVec4 = spvModule.defVectorType(boolType, 4); - uint32_t pointMode = spec.get(spvModule, SpecPointMode); + uint32_t pointMode = spec.get(spvModule, specUbo, SpecPointMode); uint32_t spriteBit = spvModule.opBitFieldUExtract(uint32Type, pointMode, spvModule.consti32(1), spvModule.consti32(1)); uint32_t isSprite = spvModule.opIEqual(boolType, spriteBit, spvModule.constu32(1)); @@ -615,6 +651,7 @@ namespace dxvk { uint32_t m_entryPointId; uint32_t m_rsBlock; + uint32_t m_specUbo; uint32_t m_mainFuncLabel; D3D9FixedFunctionOptions m_options; @@ -1155,7 +1192,7 @@ namespace dxvk { fogCtx.Specular = m_vs.in.COLOR[1]; m_module.opStore(m_vs.out.FOG, DoFixedFunctionFog(m_spec, m_module, fogCtx)); - auto pointInfo = GetPointSizeInfoVS(m_spec, m_module, 0, vtx, m_vs.in.POINTSIZE, m_rsBlock, true); + auto pointInfo = GetPointSizeInfoVS(m_spec, m_module, 0, vtx, m_vs.in.POINTSIZE, m_rsBlock, m_specUbo, true); uint32_t pointSize = m_module.opFClamp(m_floatType, pointInfo.defaultValue, pointInfo.min, pointInfo.max); m_module.opStore(m_vs.out.POINTSIZE, pointSize); @@ -1946,6 +1983,7 @@ namespace dxvk { fogCtx.IsPositionT = false; fogCtx.HasSpecular = false; fogCtx.Specular = 0; + fogCtx.SpecUBO = m_specUbo; current = DoFixedFunctionFog(m_spec, m_module, fogCtx); m_module.opStore(m_ps.out.COLOR, current); @@ -1955,6 +1993,7 @@ namespace dxvk { void D3D9FFShaderCompiler::setupPS() { setupRenderStateInfo(); + m_specUbo = SetupSpecUBO(m_module, m_bindings); // PS Caps m_module.enableCapability(spv::CapabilityDerivativeControl); @@ -1963,7 +2002,7 @@ namespace dxvk { spv::ExecutionModeOriginUpperLeft); uint32_t pointCoord = GetPointCoord(m_module); - auto pointInfo = GetPointSizeInfoPS(m_spec, m_module, m_rsBlock); + auto pointInfo = GetPointSizeInfoPS(m_spec, m_module, m_rsBlock, m_specUbo); // We need to replace TEXCOORD inputs with gl_PointCoord // if D3DRS_POINTSPRITEENABLE is set. @@ -2182,7 +2221,7 @@ namespace dxvk { uint32_t floatPtr = m_module.defPointerType(m_floatType, spv::StorageClassPushConstant); // Declare spec constants for render states - uint32_t alphaFuncId = m_spec.get(m_module, SpecAlphaCompareOp); + uint32_t alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp); // Implement alpha test auto oC0 = m_ps.out.COLOR; diff --git a/src/d3d9/d3d9_fixed_function.h b/src/d3d9/d3d9_fixed_function.h index 0649f8424..c60077919 100644 --- a/src/d3d9/d3d9_fixed_function.h +++ b/src/d3d9/d3d9_fixed_function.h @@ -35,6 +35,7 @@ namespace dxvk { bool IsPositionT; bool HasSpecular; uint32_t Specular; + uint32_t SpecUBO; }; struct D3D9FixedFunctionOptions { @@ -57,18 +58,20 @@ namespace dxvk { }; // Default point size and point scale magic! - D3D9PointSizeInfoVS GetPointSizeInfoVS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock, bool isFixedFunction); + D3D9PointSizeInfoVS GetPointSizeInfoVS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock, uint32_t specUbo, bool isFixedFunction); struct D3D9PointSizeInfoPS { uint32_t isSprite; }; - D3D9PointSizeInfoPS GetPointSizeInfoPS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t rsBlock); + D3D9PointSizeInfoPS GetPointSizeInfoPS(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, uint32_t rsBlock, uint32_t specUbo); uint32_t GetPointCoord(SpirvModule& spvModule); uint32_t GetSharedConstants(SpirvModule& spvModule); + uint32_t SetupSpecUBO(SpirvModule& spvModule, std::vector& bindings); + constexpr uint32_t TCIOffset = 16; constexpr uint32_t TCIMask = 0b111 << TCIOffset; diff --git a/src/d3d9/d3d9_spec_constants.h b/src/d3d9/d3d9_spec_constants.h index 2a8e6679d..ba45cccb9 100644 --- a/src/d3d9/d3d9_spec_constants.h +++ b/src/d3d9/d3d9_spec_constants.h @@ -89,14 +89,20 @@ namespace dxvk { class D3D9ShaderSpecConstantManager { public: - uint32_t get(SpirvModule &module, D3D9SpecConstantId id) { - return get(module, id, 0, 32); + uint32_t get(SpirvModule &module, uint32_t specUbo, D3D9SpecConstantId id) { + return get(module, specUbo, id, 0, 32); } - uint32_t get(SpirvModule &module, D3D9SpecConstantId id, uint32_t bitOffset, uint32_t bitCount) { + uint32_t get(SpirvModule &module, uint32_t specUbo, D3D9SpecConstantId id, uint32_t bitOffset, uint32_t bitCount) { const auto &layout = D3D9SpecializationInfo::Layout[id]; - uint32_t val = getSpecConstDword(module, layout.dwordOffset); + uint32_t uintType = module.defIntType(32, 0); + uint32_t optimized = getOptimizedBool(module); + + uint32_t quickValue = getSpecUBODword(module, specUbo, layout.dwordOffset); + uint32_t optimizedValue = getSpecConstDword(module, layout.dwordOffset); + + uint32_t val = module.opSelect(uintType, optimized, optimizedValue, quickValue); bitCount = std::min(bitCount, layout.sizeInBits - bitOffset); if (bitCount == 32) @@ -118,7 +124,28 @@ namespace dxvk { return m_specConstantIds[idx]; } - std::array m_specConstantIds = {}; + uint32_t getSpecUBODword(SpirvModule& module, uint32_t specUbo, uint32_t idx) { + uint32_t uintType = module.defIntType(32, 0); + uint32_t uintPtr = module.defPointerType(uintType, spv::StorageClassUniform); + + uint32_t member = module.constu32(idx); + uint32_t dword = module.opLoad(uintType, module.opAccessChain(uintPtr, specUbo, 1, &member)); + + return dword; + } + + uint32_t getOptimizedBool(SpirvModule& module) { + uint32_t boolType = module.defBoolType(); + + // The spec constant at MaxNumSpecConstants is set to True + // when this is an optimized pipeline. + uint32_t optimized = getSpecConstDword(module, MaxNumSpecConstants); + optimized = module.opINotEqual(boolType, optimized, module.constu32(0)); + + return optimized; + } + + std::array m_specConstantIds = {}; }; } \ No newline at end of file diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index df1f3d62f..7405f7437 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -480,6 +480,8 @@ namespace dxvk { this->setupRenderStateInfo(); + m_specUbo = SetupSpecUBO(m_module, m_bindings); + this->emitFunctionBegin( m_vs.functionId, m_module.defVoidType(), @@ -1036,7 +1038,7 @@ namespace dxvk { uintType, bitfield, bitIdx, m_module.consti32(1)); } else { - bit = m_spec.get(m_module, + bit = m_spec.get(m_module, m_specUbo, m_programInfo.type() == DxsoProgramType::VertexShader ? SpecVertexShaderBools : SpecPixelShaderBools, @@ -2761,7 +2763,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( // Of course it does... uint32_t bool_t = m_module.defBoolType(); - uint32_t shouldProj = m_spec.get(m_module, SpecProjectionType, samplerIdx, 1); + uint32_t shouldProj = m_spec.get(m_module, m_specUbo, SpecProjectionType, samplerIdx, 1); shouldProj = m_module.opINotEqual(bool_t, shouldProj, m_module.constu32(0)); uint32_t bvec4_t = m_module.defVectorType(bool_t, 4); @@ -2925,7 +2927,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t fetch4 = 0; if (m_programInfo.type() == DxsoProgramType::PixelShader && samplerType != SamplerTypeTexture3D) { - fetch4 = m_spec.get(m_module, SpecFetch4, samplerIdx, 1); + fetch4 = m_spec.get(m_module, m_specUbo, SpecFetch4, samplerIdx, 1); uint32_t bool_t = m_module.defBoolType(); fetch4 = m_module.opINotEqual(bool_t, fetch4, m_module.constu32(0)); @@ -2956,7 +2958,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( fetch4, imageOperands); - uint32_t shouldProj = m_spec.get(m_module, SpecProjectionType, samplerIdx, 1); + uint32_t shouldProj = m_spec.get(m_module, m_specUbo, SpecProjectionType, samplerIdx, 1); shouldProj = m_module.opINotEqual(m_module.defBoolType(), shouldProj, m_module.constu32(0)); // Depth -> .x @@ -3017,7 +3019,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( ? samplerIdx + caps::MaxTexturesPS : samplerIdx; - uint32_t isNull = m_spec.get(m_module, SpecSamplerNull, bitOffset, 1); + uint32_t isNull = m_spec.get(m_module, m_specUbo, SpecSamplerNull, bitOffset, 1); isNull = m_module.opINotEqual(m_module.defBoolType(), isNull, m_module.constu32(0)); // Only do the check for depth comp. samplers @@ -3027,7 +3029,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t depthLabel = m_module.allocateId(); uint32_t endLabel = m_module.allocateId(); - uint32_t isDepth = m_spec.get(m_module, SpecSamplerDepthMode, bitOffset, 1); + uint32_t isDepth = m_spec.get(m_module, m_specUbo, SpecSamplerDepthMode, bitOffset, 1); isDepth = m_module.opINotEqual(m_module.defBoolType(), isDepth, m_module.constu32(0)); m_module.opSelectionMerge(endLabel, spv::SelectionControlMaskNone); @@ -3062,7 +3064,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( }}; uint32_t switchEndLabel = m_module.allocateId(); - uint32_t type = m_spec.get(m_module, SpecSamplerType, samplerIdx * 2, 2); + uint32_t type = m_spec.get(m_module, m_specUbo, SpecSamplerType, samplerIdx * 2, 2); m_module.opSelectionMerge(switchEndLabel, spv::SelectionControlMaskNone); m_module.opSwitch(type, @@ -3326,7 +3328,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( if (m_programInfo.type() == DxsoProgramType::PixelShader) { pointCoord = GetPointCoord(m_module); - pointInfo = GetPointSizeInfoPS(m_spec, m_module, m_rsBlock); + pointInfo = GetPointSizeInfoPS(m_spec, m_module, m_rsBlock, m_specUbo); } for (uint32_t i = 0; i < m_isgn.elemCount; i++) { @@ -3556,7 +3558,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( if (!outputtedColor1) OutputDefault(DxsoSemantic{ DxsoUsage::Color, 1 }); - auto pointInfo = GetPointSizeInfoVS(m_spec, m_module, m_vs.oPos.id, 0, 0, m_rsBlock, false); + auto pointInfo = GetPointSizeInfoVS(m_spec, m_module, m_vs.oPos.id, 0, 0, m_rsBlock, m_specUbo, false); if (m_vs.oPSize.id == 0) { m_vs.oPSize = this->emitRegisterPtr( @@ -3707,6 +3709,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( fogCtx.IsPositionT = false; fogCtx.HasSpecular = false; fogCtx.Specular = 0; + fogCtx.SpecUBO = m_specUbo; m_module.opStore(oColor0Ptr.id, DoFixedFunctionFog(m_spec, m_module, fogCtx)); } @@ -3717,7 +3720,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t floatType = m_module.defFloatType(32); uint32_t floatPtr = m_module.defPointerType(floatType, spv::StorageClassPushConstant); - uint32_t alphaFuncId = m_spec.get(m_module, SpecAlphaCompareOp); + uint32_t alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp); // Implement alpha test and fog DxsoRegister color0; diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h index c5f1b8a80..4360e599e 100644 --- a/src/dxso/dxso_compiler.h +++ b/src/dxso/dxso_compiler.h @@ -367,6 +367,8 @@ namespace dxvk { uint32_t m_usedSamplers; uint32_t m_usedRTs; + uint32_t m_specUbo = 0; + uint32_t m_rsBlock = 0; uint32_t m_mainFuncLabel = 0; From 6589966fcefae96e74b75925957b0322407d2a41 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Sat, 6 Aug 2022 12:06:47 +0200 Subject: [PATCH 0450/1348] [d3d9] Fix FF VS fog with GPL --- src/d3d9/d3d9_fixed_function.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index a525d4508..45e26ab94 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -1190,6 +1190,7 @@ namespace dxvk { fogCtx.IsPositionT = m_vsKey.Data.Contents.HasPositionT; fogCtx.HasSpecular = m_vsKey.Data.Contents.HasColor1; fogCtx.Specular = m_vs.in.COLOR[1]; + fogCtx.SpecUBO = m_specUbo; m_module.opStore(m_vs.out.FOG, DoFixedFunctionFog(m_spec, m_module, fogCtx)); auto pointInfo = GetPointSizeInfoVS(m_spec, m_module, 0, vtx, m_vs.in.POINTSIZE, m_rsBlock, m_specUbo, true); @@ -1453,6 +1454,7 @@ namespace dxvk { void D3D9FFShaderCompiler::setupVS() { setupRenderStateInfo(); + m_specUbo = SetupSpecUBO(m_module, m_bindings); // VS Caps m_module.enableCapability(spv::CapabilityClipDistance); From 135b8a0e53fd88c70d68faa2d008f6f089559f48 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Sat, 6 Aug 2022 12:18:18 +0200 Subject: [PATCH 0451/1348] [dxso] Setup spec ubo for pixel shaders --- src/dxso/dxso_compiler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 7405f7437..de5735d1c 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -523,6 +523,8 @@ namespace dxvk { this->setupRenderStateInfo(); this->emitPsSharedConstants(); + m_specUbo = SetupSpecUBO(m_module, m_bindings); + this->emitFunctionBegin( m_ps.functionId, m_module.defVoidType(), From 7b28bbae11dac158d244643a7efd5b5a59076496 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sat, 6 Aug 2022 16:18:57 +0200 Subject: [PATCH 0452/1348] [util] Disable unmapping for Saints Row 2 --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 5f7f6bbba..90a3eb223 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -599,6 +599,10 @@ namespace dxvk { { R"(\\yso_win\.exe$)", {{ { "d3d9.maxFrameLatency", "1" }, }} }, + /* Saints Row 2 - Prevents unmap crash */ + { R"(\\SR2_pc\.exe$)", {{ + { "d3d9.textureMemory", "0" }, + }} }, }}; From ddb528cc8eda52c9b779d85d855ee5a5564a2896 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sun, 7 Aug 2022 01:09:38 +0200 Subject: [PATCH 0453/1348] [d3d9] Change texture before updating fetch4 --- src/d3d9/d3d9_device.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 2572e3423..92d775616 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3760,6 +3760,10 @@ namespace dxvk { DWORD oldUsage = oldTexture != nullptr ? oldTexture->Desc()->Usage : 0; DWORD newUsage = newTexture != nullptr ? newTexture->Desc()->Usage : 0; + DWORD combinedUsage = oldUsage | newUsage; + TextureChangePrivate(m_state.textures[StateSampler], pTexture); + m_dirtyTextures |= 1u << StateSampler; + UpdateActiveTextures(StateSampler, combinedUsage); if (newTexture != nullptr) { const bool oldDepth = m_depthTextures & (1u << StateSampler); @@ -3780,14 +3784,6 @@ namespace dxvk { UpdateActiveFetch4(StateSampler); } - DWORD combinedUsage = oldUsage | newUsage; - - TextureChangePrivate(m_state.textures[StateSampler], pTexture); - - m_dirtyTextures |= 1u << StateSampler; - - UpdateActiveTextures(StateSampler, combinedUsage); - return D3D_OK; } From bb8a87196f8240c486ccafa386270602826558e0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 16:45:29 +0200 Subject: [PATCH 0454/1348] [dxvk] Add vertex extent to vertex binding info --- src/dxvk/dxvk_constant_state.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dxvk/dxvk_constant_state.h b/src/dxvk/dxvk_constant_state.h index b17dd9b52..222c6ee5e 100644 --- a/src/dxvk/dxvk_constant_state.h +++ b/src/dxvk/dxvk_constant_state.h @@ -188,6 +188,7 @@ namespace dxvk { uint32_t binding; uint32_t fetchRate; VkVertexInputRate inputRate; + uint32_t extent; }; From 64169316e638ec4d60e1904dd2ffc48b01f21a6e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 16:46:46 +0200 Subject: [PATCH 0455/1348] [d3d9] Compute vertex extent in BindInputLayout --- src/d3d9/d3d9_device.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 92d775616..52cfca35c 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -6206,6 +6206,7 @@ namespace dxvk { DxvkVertexBinding binding; binding.binding = attrib.binding; + binding.extent = attrib.offset + lookupFormatInfo(attrib.format)->elementSize; uint32_t instanceData = cStreamFreq[binding.binding % caps::MaxStreams]; if (instanceData & D3DSTREAMSOURCE_INSTANCEDATA) { @@ -6217,19 +6218,12 @@ namespace dxvk { binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; } - // Check if the binding was already defined. - bool bindingDefined = false; - - for (uint32_t j = 0; j < i; j++) { - uint32_t bindingId = attrList.at(j).binding; - - if (binding.binding == bindingId) { - bindingDefined = true; - } - } - - if (!bindingDefined) + if (bindMask & (1u << binding.binding)) { + bindList.at(binding.binding).extent = std::max( + bindList.at(binding.binding).extent, binding.extent); + } else { bindList.at(binding.binding) = binding; + } attrMask |= 1u << i; bindMask |= 1u << binding.binding; From 6bcb0a0d61b369ac0697b1bde0de3b504767f968 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 16:47:52 +0200 Subject: [PATCH 0456/1348] [d3d11] Compute vertex extent in CreateInputLayout --- src/d3d11/d3d11_device.cpp | 85 ++++++++++++-------------------------- 1 file changed, 26 insertions(+), 59 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 0984f73e0..f5fbc13ea 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -603,29 +603,23 @@ namespace dxvk { uint32_t attrMask = 0; uint32_t bindMask = 0; + uint32_t bindingsDefined = 0; - std::array attrList; - std::array bindList; + std::array attrList = { }; + std::array bindList = { }; for (uint32_t i = 0; i < NumElements; i++) { const DxbcSgnEntry* entry = inputSignature->find( pInputElementDescs[i].SemanticName, pInputElementDescs[i].SemanticIndex, 0); - - if (entry == nullptr) { - Logger::debug(str::format( - "D3D11Device: No such vertex shader semantic: ", - pInputElementDescs[i].SemanticName, - pInputElementDescs[i].SemanticIndex)); - } - + // Create vertex input attribute description DxvkVertexAttribute attrib; attrib.location = entry != nullptr ? entry->registerId : 0; attrib.binding = pInputElementDescs[i].InputSlot; attrib.format = LookupFormat(pInputElementDescs[i].Format, DXGI_VK_FORMAT_MODE_COLOR).Format; attrib.offset = pInputElementDescs[i].AlignedByteOffset; - + // The application may choose to let the implementation // generate the exact vertex layout. In that case we'll // pack attributes on the same binding in the order they @@ -635,10 +629,10 @@ namespace dxvk { if (attrib.offset == D3D11_APPEND_ALIGNED_ELEMENT) { attrib.offset = 0; - + for (uint32_t j = 1; j <= i; j++) { const DxvkVertexAttribute& prev = attrList.at(i - j); - + if (prev.binding == attrib.binding) { attrib.offset = align(prev.offset + lookupFormatInfo(prev.format)->elementSize, alignment); break; @@ -648,7 +642,7 @@ namespace dxvk { return E_INVALIDARG; attrList.at(i) = attrib; - + // Create vertex input binding description. The // stride is dynamic state in D3D11 and will be // set by D3D11DeviceContext::IASetVertexBuffers. @@ -657,30 +651,22 @@ namespace dxvk { binding.fetchRate = pInputElementDescs[i].InstanceDataStepRate; binding.inputRate = pInputElementDescs[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; - + binding.extent = entry ? uint32_t(attrib.offset + formatInfo->elementSize) : 0u; + // Check if the binding was already defined. If so, the // parameters must be identical (namely, the input rate). - bool bindingDefined = false; - - for (uint32_t j = 0; j < i; j++) { - uint32_t bindingId = attrList.at(j).binding; + if (bindingsDefined & (1u << binding.binding)) { + if (bindList.at(binding.binding).inputRate != binding.inputRate) + return E_INVALIDARG; - if (binding.binding == bindingId) { - bindingDefined = true; - - if (binding.inputRate != bindList.at(bindingId).inputRate) { - Logger::err(str::format( - "D3D11Device: Conflicting input rate for binding ", - binding.binding)); - return E_INVALIDARG; - } - } + bindList.at(binding.binding).extent = std::max( + bindList.at(binding.binding).extent, binding.extent); + } else { + bindList.at(binding.binding) = binding; + bindingsDefined |= 1u << binding.binding; } - if (!bindingDefined) - bindList.at(binding.binding) = binding; - - if (entry != nullptr) { + if (entry) { attrMask |= 1u << i; bindMask |= 1u << binding.binding; } @@ -691,32 +677,13 @@ namespace dxvk { uint32_t attrCount = CompactSparseList(attrList.data(), attrMask); uint32_t bindCount = CompactSparseList(bindList.data(), bindMask); - // Check if there are any semantics defined in the - // shader that are not included in the current input - // layout. - for (auto i = inputSignature->begin(); i != inputSignature->end(); i++) { - bool found = i->systemValue != DxbcSystemValue::None; - - for (uint32_t j = 0; j < attrCount && !found; j++) - found = attrList.at(j).location == i->registerId; - - if (!found) { - Logger::warn(str::format( - "D3D11Device: Vertex input '", - i->semanticName, i->semanticIndex, - "' not defined by input layout")); - } - } - - // Create the actual input layout object - // if the application requests it. - if (ppInputLayout != nullptr) { - *ppInputLayout = ref( - new D3D11InputLayout(this, - attrCount, attrList.data(), - bindCount, bindList.data())); - } - + if (!ppInputLayout) + return S_FALSE; + + *ppInputLayout = ref( + new D3D11InputLayout(this, + attrCount, attrList.data(), + bindCount, bindList.data())); return S_OK; } catch (const DxvkError& e) { Logger::err(e.message()); From 88bdf2b5920dd2533993e3b74965d766420f91a2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 16:48:05 +0200 Subject: [PATCH 0457/1348] [dxvk] Use vertex extent from vertex binding info Computing this at runtime is fairly expensive, so try to avoid. --- src/dxvk/dxvk_context.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 8d74b4364..52908ca9a 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2371,20 +2371,18 @@ namespace dxvk { m_state.gp.state.ilBindings[i] = DxvkIlBinding( bindings[i].binding, 0, bindings[i].inputRate, bindings[i].fetchRate); - m_state.vi.vertexExtents[bindings[i].binding] = 0; + m_state.vi.vertexExtents[i] = bindings[i].extent; } - for (uint32_t i = bindingCount; i < m_state.gp.state.il.bindingCount(); i++) + for (uint32_t i = bindingCount; i < m_state.gp.state.il.bindingCount(); i++) { m_state.gp.state.ilBindings[i] = DxvkIlBinding(); + m_state.vi.vertexExtents[i] = 0; + } for (uint32_t i = 0; i < attributeCount; i++) { m_state.gp.state.ilAttributes[i] = DxvkIlAttribute( attributes[i].location, attributes[i].binding, attributes[i].format, attributes[i].offset); - - uint32_t extent = attributes[i].offset + lookupFormatInfo(attributes[i].format)->elementSize; - m_state.vi.vertexExtents[attributes[i].binding] = std::max(extent, - m_state.vi.vertexExtents[attributes[i].binding]); } for (uint32_t i = attributeCount; i < m_state.gp.state.il.attributeCount(); i++) @@ -5137,7 +5135,7 @@ namespace dxvk { if (strides[i]) { // Dynamic strides are only allowed if the stride is not smaller // than highest attribute offset + format size for given binding - newDynamicStrides &= strides[i] >= m_state.vi.vertexExtents[binding]; + newDynamicStrides &= strides[i] >= m_state.vi.vertexExtents[i]; } if (m_vbTracked.set(binding)) From 317850e16f38af7ee5e187d3028215196cec0283 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 13:55:57 +0200 Subject: [PATCH 0458/1348] [dxvk] Introduce bindResourceImageView and bindResourceBufferView methods --- src/dxvk/dxvk_context.h | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index bebbcd527..dd2eb9471 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -213,6 +213,55 @@ namespace dxvk { m_descriptorState.dirtyViews(stages); } + /** + * \brief Binds image view + * + * \param [in] stages Shader stages that access the binding + * \param [in] slot Resource binding slot + * \param [in] view Image view to bind + */ + void bindResourceImageView( + VkShaderStageFlags stages, + uint32_t slot, + Rc&& view) { + if (m_rc[slot].bufferView != nullptr) { + m_rc[slot].bufferSlice = DxvkBufferSlice(); + m_rc[slot].bufferView = nullptr; + } + + m_rc[slot].imageView = std::move(view); + m_rcTracked.clr(slot); + + m_descriptorState.dirtyViews(stages); + } + + /** + * \brief Binds buffer view + * + * \param [in] stages Shader stages that access the binding + * \param [in] slot Resource binding slot + * \param [in] view Buffer view to bind + */ + void bindResourceBufferView( + VkShaderStageFlags stages, + uint32_t slot, + Rc&& view) { + if (m_rc[slot].imageView != nullptr) + m_rc[slot].imageView = nullptr; + + if (view != nullptr) { + m_rc[slot].bufferSlice = view->slice(); + m_rc[slot].bufferView = std::move(view); + } else { + m_rc[slot].bufferSlice = DxvkBufferSlice(); + m_rc[slot].bufferView = nullptr; + } + + m_rcTracked.clr(slot); + + m_descriptorState.dirtyViews(stages); + } + /** * \brief Binds image sampler * From 28ecf8268d6eb9f8b509bdc955ee2ec88ef03ec8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 14:06:46 +0200 Subject: [PATCH 0459/1348] [d3d11] Use new resource view binding methods --- src/d3d11/d3d11_context.cpp | 116 +++++++++++++++++++++++++----------- src/d3d11/d3d11_video.cpp | 4 +- 2 files changed, 83 insertions(+), 37 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 656b1ceff..7a9df8bb2 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3323,16 +3323,34 @@ namespace dxvk { void D3D11CommonContext::BindShaderResource( UINT Slot, D3D11ShaderResourceView* pResource) { - EmitCs([ - cSlotId = Slot, - cImageView = pResource != nullptr ? pResource->GetImageView() : nullptr, - cBufferView = pResource != nullptr ? pResource->GetBufferView() : nullptr - ] (DxvkContext* ctx) mutable { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceView(stage, cSlotId, - Forwarder::move(cImageView), - Forwarder::move(cBufferView)); - }); + if (pResource) { + if (pResource->GetViewInfo().Dimension != D3D11_RESOURCE_DIMENSION_BUFFER) { + EmitCs([ + cSlotId = Slot, + cView = pResource->GetImageView() + ] (DxvkContext* ctx) mutable { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceImageView(stage, cSlotId, + Forwarder::move(cView)); + }); + } else { + EmitCs([ + cSlotId = Slot, + cView = pResource->GetBufferView() + ] (DxvkContext* ctx) mutable { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceBufferView(stage, cSlotId, + Forwarder::move(cView)); + }); + } + } else { + EmitCs([ + cSlotId = Slot + ] (DxvkContext* ctx) { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceImageView(stage, cSlotId, nullptr); + }); + } } @@ -3343,32 +3361,60 @@ namespace dxvk { D3D11UnorderedAccessView* pUav, UINT CtrSlot, UINT Counter) { - EmitCs([ - cUavSlotId = UavSlot, - cCtrSlotId = CtrSlot, - cImageView = pUav != nullptr ? pUav->GetImageView() : nullptr, - cBufferView = pUav != nullptr ? pUav->GetBufferView() : nullptr, - cCounterSlice = pUav != nullptr ? pUav->GetCounterSlice() : DxvkBufferSlice(), - cCounterValue = Counter - ] (DxvkContext* ctx) mutable { - VkShaderStageFlags stages = ShaderStage == DxbcProgramType::PixelShader - ? VK_SHADER_STAGE_ALL_GRAPHICS - : VK_SHADER_STAGE_COMPUTE_BIT; + if (pUav) { + if (pUav->GetViewInfo().Dimension == D3D11_RESOURCE_DIMENSION_BUFFER) { + EmitCs([ + cUavSlotId = UavSlot, + cCtrSlotId = CtrSlot, + cBufferView = pUav->GetBufferView(), + cCounterSlice = pUav->GetCounterSlice(), + cCounterValue = Counter + ] (DxvkContext* ctx) mutable { + VkShaderStageFlags stages = ShaderStage == DxbcProgramType::ComputeShader + ? VK_SHADER_STAGE_COMPUTE_BIT + : VK_SHADER_STAGE_ALL_GRAPHICS; - if (cCounterSlice.defined() && cCounterValue != ~0u) { - ctx->updateBuffer( - cCounterSlice.buffer(), - cCounterSlice.offset(), - sizeof(uint32_t), - &cCounterValue); + if (cCounterSlice.defined() && cCounterValue != ~0u) { + ctx->updateBuffer( + cCounterSlice.buffer(), + cCounterSlice.offset(), + sizeof(uint32_t), + &cCounterValue); + } + + ctx->bindResourceBufferView(stages, cUavSlotId, + Forwarder::move(cBufferView)); + ctx->bindResourceBuffer(stages, cCtrSlotId, + Forwarder::move(cCounterSlice)); + }); + } else { + EmitCs([ + cUavSlotId = UavSlot, + cCtrSlotId = CtrSlot, + cImageView = pUav->GetImageView() + ] (DxvkContext* ctx) mutable { + VkShaderStageFlags stages = ShaderStage == DxbcProgramType::ComputeShader + ? VK_SHADER_STAGE_COMPUTE_BIT + : VK_SHADER_STAGE_ALL_GRAPHICS; + + ctx->bindResourceImageView(stages, cUavSlotId, + Forwarder::move(cImageView)); + ctx->bindResourceBuffer(stages, cCtrSlotId, DxvkBufferSlice()); + }); } + } else { + EmitCs([ + cUavSlotId = UavSlot, + cCtrSlotId = CtrSlot + ] (DxvkContext* ctx) { + VkShaderStageFlags stages = ShaderStage == DxbcProgramType::ComputeShader + ? VK_SHADER_STAGE_COMPUTE_BIT + : VK_SHADER_STAGE_ALL_GRAPHICS; - ctx->bindResourceView(stages, cUavSlotId, - Forwarder::move(cImageView), - Forwarder::move(cBufferView)); - ctx->bindResourceBuffer(stages, cCtrSlotId, - Forwarder::move(cCounterSlice)); - }); + ctx->bindResourceImageView(stages, cUavSlotId, nullptr); + ctx->bindResourceBuffer(stages, cCtrSlotId, DxvkBufferSlice()); + }); + } } @@ -3883,7 +3929,7 @@ namespace dxvk { auto srvSlotId = computeSrvBinding(programType, 0); for (uint32_t j = 0; j < cUsedBindings.stages[i].srvCount; j++) - ctx->bindResourceView(stage, srvSlotId + j, nullptr, nullptr); + ctx->bindResourceImageView(stage, srvSlotId + j, nullptr); // Unbind texture samplers auto samplerSlotId = computeSamplerBinding(programType, 0); @@ -3902,7 +3948,7 @@ namespace dxvk { auto ctrSlotId = computeUavCounterBinding(programType, 0); for (uint32_t j = 0; j < cUsedBindings.stages[i].uavCount; j++) { - ctx->bindResourceView(stages, uavSlotId, nullptr, nullptr); + ctx->bindResourceImageView(stages, uavSlotId, nullptr); ctx->bindResourceBuffer(stages, ctrSlotId, DxvkBufferSlice()); } } diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 96e1486b8..4cc3f08c0 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1298,14 +1298,14 @@ namespace dxvk { ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 1, Rc(m_sampler)); for (uint32_t i = 0; i < cViews.size(); i++) - ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, 2 + i, Rc(cViews[i]), nullptr); + ctx->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, 2 + i, Rc(cViews[i])); ctx->draw(3, 1, 0, 0); ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 1, nullptr); for (uint32_t i = 0; i < cViews.size(); i++) - ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, 2 + i, nullptr, nullptr); + ctx->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, 2 + i, nullptr); }); } From 1c1958be44d899a1aaac29fba28982a7b199d828 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 14:07:47 +0200 Subject: [PATCH 0460/1348] [d3d9] Use new resource view binding methods --- src/d3d9/d3d9_device.cpp | 6 +++--- src/d3d9/d3d9_format_helpers.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 52cfca35c..f32abf62a 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5889,7 +5889,7 @@ namespace dxvk { cImageView = commonTex->GetSampleView(srgb) ](DxvkContext* ctx) mutable { VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; - ctx->bindResourceView(stage, cSlot, std::move(cImageView), nullptr); + ctx->bindResourceImageView(stage, cSlot, std::move(cImageView)); }); } @@ -5905,7 +5905,7 @@ namespace dxvk { DxsoBindingType::Image, uint32_t(shaderSampler.second)); VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; - ctx->bindResourceView(stage, slot, nullptr, nullptr); + ctx->bindResourceImageView(stage, slot, nullptr); } }); } @@ -7035,7 +7035,7 @@ namespace dxvk { for (uint32_t i = 0; i < cSize; i++) { auto samplerInfo = RemapStateSamplerShader(DWORD(i)); uint32_t slot = computeResourceSlotId(samplerInfo.first, DxsoBindingType::Image, uint32_t(samplerInfo.second)); - ctx->bindResourceView(stage, slot, nullptr, nullptr); + ctx->bindResourceImageView(stage, slot, nullptr); } }); diff --git a/src/d3d9/d3d9_format_helpers.cpp b/src/d3d9/d3d9_format_helpers.cpp index 59dc3868f..d8cd3233d 100644 --- a/src/d3d9/d3d9_format_helpers.cpp +++ b/src/d3d9/d3d9_format_helpers.cpp @@ -94,8 +94,8 @@ namespace dxvk { auto tmpBufferView = m_device->createBufferView(srcSlice.buffer(), bufferViewInfo); m_context->setSpecConstant(VK_PIPELINE_BIND_POINT_COMPUTE, 0, specConstantValue); - m_context->bindResourceView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Image, std::move(tmpImageView), nullptr); - m_context->bindResourceView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Buffer, nullptr, std::move(tmpBufferView)); + m_context->bindResourceImageView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Image, std::move(tmpImageView)); + m_context->bindResourceBufferView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Buffer, std::move(tmpBufferView)); m_context->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, Rc(m_shaders[videoFormat.FormatType])); m_context->pushConstants(0, sizeof(VkExtent2D), &imageExtent); m_context->dispatch( From eebcfcf973fc70cb0d4a6aa46486015ad75231cb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 14:08:57 +0200 Subject: [PATCH 0461/1348] [hud] Use new resource view binding methods --- src/dxvk/hud/dxvk_hud_renderer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index bce83c725..5d47d7c79 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -107,10 +107,10 @@ namespace dxvk::hud { m_context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, Rc(m_textShaders.vert)); m_context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, Rc(m_textShaders.frag)); - m_context->bindResourceBuffer (VK_SHADER_STAGE_VERTEX_BIT, 0, DxvkBufferSlice(m_fontBuffer)); - m_context->bindResourceView (VK_SHADER_STAGE_VERTEX_BIT, 1, nullptr, Rc(m_dataView)); + m_context->bindResourceBuffer(VK_SHADER_STAGE_VERTEX_BIT, 0, DxvkBufferSlice(m_fontBuffer)); + m_context->bindResourceBufferView(VK_SHADER_STAGE_VERTEX_BIT, 1, Rc(m_dataView)); m_context->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 2, Rc(m_fontSampler)); - m_context->bindResourceView (VK_SHADER_STAGE_FRAGMENT_BIT, 2, Rc(m_fontView), nullptr); + m_context->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, 2, Rc(m_fontView)); static const DxvkInputAssemblyState iaState = { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, From 69b15b7fe68ce462f8e2ba05897e45f09718049a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 14:08:10 +0200 Subject: [PATCH 0462/1348] [dxvk] Use new resource view binding methods in swapchain blitter --- src/dxvk/dxvk_swapchain_blitter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index 603e1497d..eca02445d 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -194,8 +194,8 @@ namespace dxvk { ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Image, Rc(m_samplerPresent)); ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Gamma, Rc(m_samplerGamma)); - ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Image, Rc(srcView), nullptr); - ctx->bindResourceView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Gamma, Rc(m_gammaView), nullptr); + ctx->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Image, Rc(srcView)); + ctx->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Gamma, Rc(m_gammaView)); ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, Rc(m_vs)); ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, Rc(fs)); From 12c2d24d5cb55c217f1b2f55d75fc6d7080d1af7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 14:09:18 +0200 Subject: [PATCH 0463/1348] [dxvk] Remove bindResourceView method --- src/dxvk/dxvk_context.h | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index dd2eb9471..4da4bb14a 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -187,32 +187,6 @@ namespace dxvk { m_descriptorState.dirtyBuffers(stages); } - /** - * \brief Binds image or buffer view - * - * Can be used for sampled images with a dedicated - * sampler and for storage images, as well as for - * uniform texel buffers and storage texel buffers. - * \param [in] stages Shader stages that access the binding - * \param [in] slot Resource binding slot - * \param [in] imageView Image view to bind - * \param [in] bufferView Buffer view to bind - */ - void bindResourceView( - VkShaderStageFlags stages, - uint32_t slot, - Rc&& imageView, - Rc&& bufferView) { - m_rc[slot].bufferSlice = bufferView != nullptr - ? bufferView->slice() - : DxvkBufferSlice(); - m_rc[slot].bufferView = std::move(bufferView); - m_rc[slot].imageView = std::move(imageView); - m_rcTracked.clr(slot); - - m_descriptorState.dirtyViews(stages); - } - /** * \brief Binds image view * From 29a2cb9a5e99d706bb9ad992829f7ebef6de4b37 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 14:59:05 +0200 Subject: [PATCH 0464/1348] [d3d9,d3d11] Make GetShaderStage functions constexpr --- src/d3d11/d3d11_context.cpp | 2 +- src/d3d11/d3d11_util.cpp | 13 ------------- src/d3d11/d3d11_util.h | 21 ++++++++++++++++++--- src/d3d9/d3d9_device.cpp | 3 ++- src/d3d9/d3d9_util.h | 2 +- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 7a9df8bb2..c9110bc7a 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3120,7 +3120,7 @@ namespace dxvk { ? pShaderModule->GetShader() : nullptr ] (DxvkContext* ctx) mutable { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + constexpr VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); uint32_t slotId = computeConstantBufferBinding(ShaderStage, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); diff --git a/src/d3d11/d3d11_util.cpp b/src/d3d11/d3d11_util.cpp index d4448c54f..92f5f6d46 100644 --- a/src/d3d11/d3d11_util.cpp +++ b/src/d3d11/d3d11_util.cpp @@ -78,19 +78,6 @@ namespace dxvk { } - VkShaderStageFlagBits GetShaderStage(DxbcProgramType ProgramType) { - switch (ProgramType) { - case DxbcProgramType::VertexShader: return VK_SHADER_STAGE_VERTEX_BIT; - case DxbcProgramType::HullShader: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; - case DxbcProgramType::DomainShader: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; - case DxbcProgramType::GeometryShader: return VK_SHADER_STAGE_GEOMETRY_BIT; - case DxbcProgramType::PixelShader: return VK_SHADER_STAGE_FRAGMENT_BIT; - case DxbcProgramType::ComputeShader: return VK_SHADER_STAGE_COMPUTE_BIT; - default: return VkShaderStageFlagBits(0); - } - } - - VkFormatFeatureFlags GetBufferFormatFeatures(UINT BindFlags) { VkFormatFeatureFlags features = 0; diff --git a/src/d3d11/d3d11_util.h b/src/d3d11/d3d11_util.h index 749dc8bed..8913d2c3a 100644 --- a/src/d3d11/d3d11_util.h +++ b/src/d3d11/d3d11_util.h @@ -31,9 +31,6 @@ namespace dxvk { VkConservativeRasterizationModeEXT DecodeConservativeRasterizationMode( D3D11_CONSERVATIVE_RASTERIZATION_MODE Mode); - VkShaderStageFlagBits GetShaderStage( - DxbcProgramType ProgramType); - VkFormatFeatureFlags GetBufferFormatFeatures( UINT BindFlags); @@ -43,4 +40,22 @@ namespace dxvk { VkFormat GetPackedDepthStencilFormat( DXGI_FORMAT Format); + /** + * \brief Translates D3D11 shader stage to corresponding Vulkan stage + * + * \param [in] ProgramType DXBC program type + * \returns Corresponding Vulkan shader stage + */ + constexpr VkShaderStageFlagBits GetShaderStage(DxbcProgramType ProgramType) { + switch (ProgramType) { + case DxbcProgramType::VertexShader: return VK_SHADER_STAGE_VERTEX_BIT; + case DxbcProgramType::HullShader: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + case DxbcProgramType::DomainShader: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + case DxbcProgramType::GeometryShader: return VK_SHADER_STAGE_GEOMETRY_BIT; + case DxbcProgramType::PixelShader: return VK_SHADER_STAGE_FRAGMENT_BIT; + case DxbcProgramType::ComputeShader: return VK_SHADER_STAGE_COMPUTE_BIT; + default: return VkShaderStageFlagBits(0); + } + } + } \ No newline at end of file diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index f32abf62a..95cade416 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -6130,7 +6130,8 @@ namespace dxvk { EmitCs([ cShader = pShaderModule->GetShader(Permutation) ] (DxvkContext* ctx) mutable { - ctx->bindShader(GetShaderStage(ShaderStage), std::move(cShader)); + constexpr VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindShader(stage, std::move(cShader)); }); } diff --git a/src/d3d9/d3d9_util.h b/src/d3d9/d3d9_util.h index 5899cd4c5..bbde19add 100644 --- a/src/d3d9/d3d9_util.h +++ b/src/d3d9/d3d9_util.h @@ -110,7 +110,7 @@ namespace dxvk { return srgb ? srgbFormat : format; } - inline VkShaderStageFlagBits GetShaderStage(DxsoProgramType ProgramType) { + constexpr VkShaderStageFlagBits GetShaderStage(DxsoProgramType ProgramType) { switch (ProgramType) { case DxsoProgramTypes::VertexShader: return VK_SHADER_STAGE_VERTEX_BIT; case DxsoProgramTypes::PixelShader: return VK_SHADER_STAGE_FRAGMENT_BIT; From 2e6a2f1be379ce8dc64880cac518dcd15fd89df6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 15:02:48 +0200 Subject: [PATCH 0465/1348] [dxvk] Make shader stage parameter in bindShader a template parameter --- src/d3d11/d3d11_context.cpp | 12 +++++++++--- src/d3d11/d3d11_video.cpp | 8 ++++---- src/d3d9/d3d9_device.cpp | 12 ++++++------ src/d3d9/d3d9_format_helpers.cpp | 2 +- src/dxvk/dxvk_context.h | 6 +++--- src/dxvk/dxvk_swapchain_blitter.cpp | 4 ++-- src/dxvk/hud/dxvk_hud_renderer.cpp | 8 ++++---- 7 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index c9110bc7a..a6edc4a31 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3125,7 +3125,7 @@ namespace dxvk { uint32_t slotId = computeConstantBufferBinding(ShaderStage, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); - ctx->bindShader(stage, + ctx->bindShader( Forwarder::move(cShader)); ctx->bindResourceBuffer(stage, slotId, Forwarder::move(cSlice)); @@ -3911,6 +3911,14 @@ namespace dxvk { for (uint32_t i = 0; i < cUsedBindings.soCount; i++) ctx->bindXfbBuffer(i, DxvkBufferSlice(), DxvkBufferSlice()); + // Unbind all shaders + ctx->bindShader(nullptr); + ctx->bindShader(nullptr); + ctx->bindShader(nullptr); + ctx->bindShader(nullptr); + ctx->bindShader(nullptr); + ctx->bindShader(nullptr); + // Unbind per-shader stage resources for (uint32_t i = 0; i < 6; i++) { auto programType = DxbcProgramType(i); @@ -3918,8 +3926,6 @@ namespace dxvk { // Unbind constant buffers, including the shader's ICB auto cbSlotId = computeConstantBufferBinding(programType, 0); - - ctx->bindShader(stage, nullptr); ctx->bindResourceBuffer(stage, cbSlotId + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, DxvkBufferSlice()); for (uint32_t j = 0; j < cUsedBindings.stages[i].cbvCount; j++) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 4cc3f08c0..72346bc85 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1199,8 +1199,8 @@ namespace dxvk { rt.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; ctx->bindRenderTargets(std::move(rt), 0u); - ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, Rc(m_vs)); - ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, Rc(m_fs)); + ctx->bindShader(Rc(m_vs)); + ctx->bindShader(Rc(m_fs)); ctx->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo)); DxvkInputAssemblyState iaState; @@ -1314,8 +1314,8 @@ namespace dxvk { m_ctx->EmitCs([this] (DxvkContext* ctx) { ctx->bindRenderTargets(DxvkRenderTargets(), 0u); - ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, nullptr); - ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, nullptr); + ctx->bindShader(nullptr); + ctx->bindShader(nullptr); ctx->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice()); }); diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 95cade416..56f1206ba 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2668,15 +2668,15 @@ namespace dxvk { // Unbind the pixel shader, we aren't drawing // to avoid val errors / UB. - ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, nullptr); + ctx->bindShader(nullptr); - ctx->bindShader(VK_SHADER_STAGE_GEOMETRY_BIT, std::move(shader)); + ctx->bindShader(std::move(shader)); ctx->bindResourceBuffer(VK_SHADER_STAGE_GEOMETRY_BIT, getSWVPBufferSlot(), std::move(cBufferSlice)); ctx->draw( drawInfo.vertexCount, drawInfo.instanceCount, cStartIndex, 0); ctx->bindResourceBuffer(VK_SHADER_STAGE_GEOMETRY_BIT, getSWVPBufferSlot(), DxvkBufferSlice()); - ctx->bindShader(VK_SHADER_STAGE_GEOMETRY_BIT, nullptr); + ctx->bindShader(nullptr); }); // We unbound the pixel shader before, @@ -6131,7 +6131,7 @@ namespace dxvk { cShader = pShaderModule->GetShader(Permutation) ] (DxvkContext* ctx) mutable { constexpr VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindShader(stage, std::move(cShader)); + ctx->bindShader(std::move(cShader)); }); } @@ -6504,7 +6504,7 @@ namespace dxvk { &cShaders = m_ffModules ](DxvkContext* ctx) { auto shader = cShaders.GetShaderModule(this, cKey); - ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, shader.GetShader()); + ctx->bindShader(shader.GetShader()); }); } @@ -6679,7 +6679,7 @@ namespace dxvk { &cShaders = m_ffModules ](DxvkContext* ctx) { auto shader = cShaders.GetShaderModule(this, cKey); - ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, shader.GetShader()); + ctx->bindShader(shader.GetShader()); }); } diff --git a/src/d3d9/d3d9_format_helpers.cpp b/src/d3d9/d3d9_format_helpers.cpp index d8cd3233d..de73fdbe7 100644 --- a/src/d3d9/d3d9_format_helpers.cpp +++ b/src/d3d9/d3d9_format_helpers.cpp @@ -96,7 +96,7 @@ namespace dxvk { m_context->setSpecConstant(VK_PIPELINE_BIND_POINT_COMPUTE, 0, specConstantValue); m_context->bindResourceImageView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Image, std::move(tmpImageView)); m_context->bindResourceBufferView(VK_SHADER_STAGE_COMPUTE_BIT, BindingIds::Buffer, std::move(tmpBufferView)); - m_context->bindShader(VK_SHADER_STAGE_COMPUTE_BIT, Rc(m_shaders[videoFormat.FormatType])); + m_context->bindShader(Rc(m_shaders[videoFormat.FormatType])); m_context->pushConstants(0, sizeof(VkExtent2D), &imageExtent); m_context->dispatch( (imageExtent.width / 8) + (imageExtent.width % 8), diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 4da4bb14a..6a55ef739 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -261,10 +261,10 @@ namespace dxvk { * \param [in] stage Target shader stage * \param [in] shader The shader to bind */ + template void bindShader( - VkShaderStageFlagBits stage, Rc&& shader) { - switch (stage) { + switch (Stage) { case VK_SHADER_STAGE_VERTEX_BIT: m_state.gp.shaders.vs = std::move(shader); break; @@ -293,7 +293,7 @@ namespace dxvk { return; } - if (stage == VK_SHADER_STAGE_COMPUTE_BIT) { + if (Stage == VK_SHADER_STAGE_COMPUTE_BIT) { m_flags.set( DxvkContextFlag::CpDirtyPipelineState); } else { diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index eca02445d..591cce3ad 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -197,8 +197,8 @@ namespace dxvk { ctx->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Image, Rc(srcView)); ctx->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, BindingIds::Gamma, Rc(m_gammaView)); - ctx->bindShader(VK_SHADER_STAGE_VERTEX_BIT, Rc(m_vs)); - ctx->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, Rc(fs)); + ctx->bindShader(Rc(m_vs)); + ctx->bindShader(Rc(fs)); PresenterArgs args; args.srcOffset = srcRect.offset; diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index 5d47d7c79..b638c7d73 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -104,8 +104,8 @@ namespace dxvk::hud { if (m_mode != Mode::RenderText) { m_mode = Mode::RenderText; - m_context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, Rc(m_textShaders.vert)); - m_context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, Rc(m_textShaders.frag)); + m_context->bindShader(Rc(m_textShaders.vert)); + m_context->bindShader(Rc(m_textShaders.frag)); m_context->bindResourceBuffer(VK_SHADER_STAGE_VERTEX_BIT, 0, DxvkBufferSlice(m_fontBuffer)); m_context->bindResourceBufferView(VK_SHADER_STAGE_VERTEX_BIT, 1, Rc(m_dataView)); @@ -126,8 +126,8 @@ namespace dxvk::hud { if (m_mode != Mode::RenderGraph) { m_mode = Mode::RenderGraph; - m_context->bindShader(VK_SHADER_STAGE_VERTEX_BIT, Rc(m_graphShaders.vert)); - m_context->bindShader(VK_SHADER_STAGE_FRAGMENT_BIT, Rc(m_graphShaders.frag)); + m_context->bindShader(Rc(m_graphShaders.vert)); + m_context->bindShader(Rc(m_graphShaders.frag)); m_context->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_dataBuffer)); From 45a1587b883d6bff414a231022671ebeff5b7714 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 15:54:53 +0200 Subject: [PATCH 0466/1348] [d3d11] Fix some possible constant buffer binding bugs --- src/d3d11/d3d11_context.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index a6edc4a31..7442f347c 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -4233,13 +4233,13 @@ namespace dxvk { for (uint32_t i = 0; i < NumBuffers; i++) { auto newBuffer = static_cast(ppConstantBuffers[i]); - UINT constantCount = 0; - - if (likely(newBuffer != nullptr)) - constantCount = std::min(newBuffer->Desc()->ByteWidth / 16, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)); + uint32_t constantCount = newBuffer + ? std::min(newBuffer->Desc()->ByteWidth / 16, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)) + : 0u; if (bindings.buffers[StartSlot + i].buffer != newBuffer - || bindings.buffers[StartSlot + i].constantBound != constantCount) { + || bindings.buffers[StartSlot + i].constantOffset != 0 + || bindings.buffers[StartSlot + i].constantCount != constantCount) { bindings.buffers[StartSlot + i].buffer = newBuffer; bindings.buffers[StartSlot + i].constantOffset = 0; bindings.buffers[StartSlot + i].constantCount = constantCount; From d314bee86d17967c9f4ffe2de1ad6d32b2760d2d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 14:47:07 +0200 Subject: [PATCH 0467/1348] [d3d11] Fix bad signature of various BindToContext methods --- src/d3d11/d3d11_blend.cpp | 2 +- src/d3d11/d3d11_blend.h | 2 +- src/d3d11/d3d11_depth_stencil.cpp | 2 +- src/d3d11/d3d11_depth_stencil.h | 3 +-- src/d3d11/d3d11_input_layout.cpp | 2 +- src/d3d11/d3d11_input_layout.h | 3 +-- src/d3d11/d3d11_rasterizer.cpp | 2 +- src/d3d11/d3d11_rasterizer.h | 3 +-- 8 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/d3d11/d3d11_blend.cpp b/src/d3d11/d3d11_blend.cpp index caacc869e..38752b691 100644 --- a/src/d3d11/d3d11_blend.cpp +++ b/src/d3d11/d3d11_blend.cpp @@ -87,7 +87,7 @@ namespace dxvk { void D3D11BlendState::BindToContext( - const Rc& ctx, + DxvkContext* ctx, uint32_t sampleMask) const { // We handled Independent Blend during object creation // already, so if it is disabled, all elements in the diff --git a/src/d3d11/d3d11_blend.h b/src/d3d11/d3d11_blend.h index 5761d3ca7..a5546c6e9 100644 --- a/src/d3d11/d3d11_blend.h +++ b/src/d3d11/d3d11_blend.h @@ -33,7 +33,7 @@ namespace dxvk { D3D11_BLEND_DESC1* pDesc) final; void BindToContext( - const Rc& ctx, + DxvkContext* ctx, UINT sampleMask) const; D3D10BlendState* GetD3D10Iface() { diff --git a/src/d3d11/d3d11_depth_stencil.cpp b/src/d3d11/d3d11_depth_stencil.cpp index b095e5eac..ded08d02c 100644 --- a/src/d3d11/d3d11_depth_stencil.cpp +++ b/src/d3d11/d3d11_depth_stencil.cpp @@ -52,7 +52,7 @@ namespace dxvk { } - void D3D11DepthStencilState::BindToContext(const Rc& ctx) { + void D3D11DepthStencilState::BindToContext(DxvkContext* ctx) { ctx->setDepthStencilState(m_state); } diff --git a/src/d3d11/d3d11_depth_stencil.h b/src/d3d11/d3d11_depth_stencil.h index 6311259f4..5cc1dba86 100644 --- a/src/d3d11/d3d11_depth_stencil.h +++ b/src/d3d11/d3d11_depth_stencil.h @@ -29,8 +29,7 @@ namespace dxvk { void STDMETHODCALLTYPE GetDesc( D3D11_DEPTH_STENCIL_DESC* pDesc) final; - void BindToContext( - const Rc& ctx); + void BindToContext(DxvkContext* ctx); D3D10DepthStencilState* GetD3D10Iface() { return &m_d3d10; diff --git a/src/d3d11/d3d11_input_layout.cpp b/src/d3d11/d3d11_input_layout.cpp index abf3d125b..257e38a79 100644 --- a/src/d3d11/d3d11_input_layout.cpp +++ b/src/d3d11/d3d11_input_layout.cpp @@ -52,7 +52,7 @@ namespace dxvk { } - void D3D11InputLayout::BindToContext(const Rc& ctx) { + void D3D11InputLayout::BindToContext(DxvkContext* ctx) { ctx->setInputLayout( m_attributes.size(), m_attributes.data(), diff --git a/src/d3d11/d3d11_input_layout.h b/src/d3d11/d3d11_input_layout.h index 8e472e2eb..e761c647e 100644 --- a/src/d3d11/d3d11_input_layout.h +++ b/src/d3d11/d3d11_input_layout.h @@ -25,8 +25,7 @@ namespace dxvk { REFIID riid, void** ppvObject) final; - void BindToContext( - const Rc& ctx); + void BindToContext(DxvkContext* ctx); bool Compare( const D3D11InputLayout* pOther) const; diff --git a/src/d3d11/d3d11_rasterizer.cpp b/src/d3d11/d3d11_rasterizer.cpp index 6d70847e4..8d8ba1c2e 100644 --- a/src/d3d11/d3d11_rasterizer.cpp +++ b/src/d3d11/d3d11_rasterizer.cpp @@ -113,7 +113,7 @@ namespace dxvk { } - void D3D11RasterizerState::BindToContext(const Rc& ctx) { + void D3D11RasterizerState::BindToContext(DxvkContext* ctx) { ctx->setRasterizerState(m_state); if (m_state.depthBiasEnable) diff --git a/src/d3d11/d3d11_rasterizer.h b/src/d3d11/d3d11_rasterizer.h index 7b542f2ca..b72e0299f 100644 --- a/src/d3d11/d3d11_rasterizer.h +++ b/src/d3d11/d3d11_rasterizer.h @@ -38,8 +38,7 @@ namespace dxvk { return &m_desc; } - void BindToContext( - const Rc& ctx); + void BindToContext(DxvkContext* ctx); D3D10RasterizerState* GetD3D10Iface() { return &m_d3d10; From 26d46e7f80a09d72bdd9137ad21d47ccff76ed7d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 15:19:03 +0200 Subject: [PATCH 0468/1348] [dxvk] Handle bound buffers with zero size in the backend --- src/dxvk/dxvk_context.cpp | 31 ++++++++++++++----------------- src/dxvk/dxvk_context.h | 1 - 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 52908ca9a..502f3a71b 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4801,7 +4801,7 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: { const auto& res = m_rc[binding.resourceBinding]; - if (res.bufferSlice.defined()) { + if (res.bufferSlice.length()) { descriptorInfo = res.bufferSlice.getDescriptor(); if (m_rcTracked.set(binding.resourceBinding)) @@ -4816,7 +4816,7 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: { const auto& res = m_rc[binding.resourceBinding]; - if (res.bufferSlice.defined()) { + if (res.bufferSlice.length()) { descriptorInfo = res.bufferSlice.getDescriptor(); if (m_rcTracked.set(binding.resourceBinding)) @@ -5088,7 +5088,7 @@ namespace dxvk { bool DxvkContext::updateIndexBufferBinding() { - if (unlikely(!m_state.vi.indexBuffer.defined())) + if (unlikely(!m_state.vi.indexBuffer.length())) return false; m_flags.clr(DxvkContextFlag::GpDirtyIndexBuffer); @@ -5124,7 +5124,7 @@ namespace dxvk { for (uint32_t i = 0; i < m_state.gp.state.il.bindingCount(); i++) { uint32_t binding = m_state.gp.state.ilBindings[i].binding(); - if (likely(m_state.vi.vertexBuffers[binding].defined())) { + if (likely(m_state.vi.vertexBuffers[binding].length())) { auto vbo = m_state.vi.vertexBuffers[binding].getDescriptor(); buffers[i] = vbo.buffer.buffer; @@ -5440,8 +5440,7 @@ namespace dxvk { switch (binding.descriptorType) { case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - if (likely(slot.bufferSlice.defined())) { + if (likely(slot.bufferSlice.length())) { srcAccess = m_execBarriers.getBufferAccess( slot.bufferSlice.getSliceHandle()); } @@ -5509,8 +5508,7 @@ namespace dxvk { switch (binding.descriptorType) { case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - if (likely(slot.bufferSlice.defined())) { + if (likely(slot.bufferSlice.length())) { m_execBarriers.accessBuffer( slot.bufferSlice.getSliceHandle(), stages, access, @@ -5573,7 +5571,7 @@ namespace dxvk { }}; for (uint32_t i = 0; i < slices.size() && !requiresBarrier; i++) { - if ((slices[i]->defined()) + if ((slices[i]->length()) && (slices[i]->bufferInfo().access & storageBufferAccess)) { requiresBarrier = this->checkGfxBufferBarrier(*slices[i], VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, @@ -5587,7 +5585,7 @@ namespace dxvk { if (m_flags.test(DxvkContextFlag::GpDirtyIndexBuffer) && !requiresBarrier && Indexed) { const auto& indexBufferSlice = m_state.vi.indexBuffer; - if ((indexBufferSlice.defined()) + if ((indexBufferSlice.length()) && (indexBufferSlice.bufferInfo().access & storageBufferAccess)) { requiresBarrier = this->checkGfxBufferBarrier(indexBufferSlice, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, @@ -5603,7 +5601,7 @@ namespace dxvk { uint32_t binding = m_state.gp.state.ilBindings[i].binding(); const auto& vertexBufferSlice = m_state.vi.vertexBuffers[binding]; - if ((vertexBufferSlice.defined()) + if ((vertexBufferSlice.length()) && (vertexBufferSlice.bufferInfo().access & storageBufferAccess)) { requiresBarrier = this->checkGfxBufferBarrier(vertexBufferSlice, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, @@ -5620,12 +5618,12 @@ namespace dxvk { const auto& xfbBufferSlice = m_state.xfb.buffers[i]; const auto& xfbCounterSlice = m_state.xfb.counters[i]; - if (xfbBufferSlice.defined()) { + if (xfbBufferSlice.length()) { requiresBarrier = this->checkGfxBufferBarrier(xfbBufferSlice, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT) != 0; - if (xfbCounterSlice.defined()) { + if (xfbCounterSlice.length()) { requiresBarrier |= this->checkGfxBufferBarrier(xfbCounterSlice, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, @@ -5652,8 +5650,7 @@ namespace dxvk { switch (binding.descriptorType) { case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - if ((slot.bufferSlice.defined()) + if ((slot.bufferSlice.length()) && (slot.bufferSlice.bufferInfo().access & storageBufferAccess)) { srcAccess = this->checkGfxBufferBarrier(slot.bufferSlice, util::pipelineStages(binding.stages), binding.access); @@ -5768,10 +5765,10 @@ namespace dxvk { if (m_flags.test(DxvkContextFlag::DirtyDrawBuffer)) { m_flags.clr(DxvkContextFlag::DirtyDrawBuffer); - if (m_state.id.argBuffer.defined()) + if (m_state.id.argBuffer.length()) m_cmd->trackResource(m_state.id.argBuffer.buffer()); - if (m_state.id.cntBuffer.defined()) + if (m_state.id.cntBuffer.length()) m_cmd->trackResource(m_state.id.cntBuffer.buffer()); } } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 6a55ef739..7e7ed485b 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -306,7 +306,6 @@ namespace dxvk { /** * \brief Binds vertex buffer * - * When binding a null buffer, stride must be 0. * \param [in] binding Vertex buffer binding * \param [in] buffer New vertex buffer * \param [in] stride Stride between vertices From 08b9b0eb443ff2da41521f3d2b85609704491814 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 15:37:35 +0200 Subject: [PATCH 0469/1348] [dxvk] Introduce bindVertexBufferRange and bindIndexBufferRange --- src/dxvk/dxvk_context.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 7e7ed485b..67bb8d0d7 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -149,6 +149,24 @@ namespace dxvk { m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer); } + /** + * \brief Binds index buffer range + * + * Canges the offset and size of the bound index buffer. + * \param [in] offset Index buffer offset + * \param [in] length Index buffer size + * \param [in] indexType Index type + */ + void bindIndexBufferRange( + VkDeviceSize offset, + VkDeviceSize length, + VkIndexType indexType) { + m_state.vi.indexBuffer.setRange(offset, length); + m_state.vi.indexType = indexType; + + m_flags.set(DxvkContextFlag::GpDirtyIndexBuffer); + } + /** * \brief Binds buffer as a shader resource * @@ -322,6 +340,25 @@ namespace dxvk { m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers); } + /** + * \brief Binds vertex buffer range + * + * Only changes offsets of a bound vertex buffer. + * \param [in] binding Vertex buffer binding + * \param [in] offset Vertex buffer offset + * \param [in] length Vertex buffer size + * \param [in] stride Stride between vertices + */ + void bindVertexBufferRange( + uint32_t binding, + VkDeviceSize offset, + VkDeviceSize length, + uint32_t stride) { + m_state.vi.vertexBuffers[binding].setRange(offset, length); + m_state.vi.vertexStrides[binding] = stride; + m_flags.set(DxvkContextFlag::GpDirtyVertexBuffers); + } + /** * \brief Binds transform feedback buffer * From 897e7816f0b16889d644eb57f9e1e5411451173e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 15:32:46 +0200 Subject: [PATCH 0470/1348] [d3d11] Don't return undefined slices from GetBufferSlice Instead, return a slice with length zero. --- src/d3d11/d3d11_buffer.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index d59c547c9..866e8d213 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -80,18 +80,14 @@ namespace dxvk { DxvkBufferSlice GetBufferSlice(VkDeviceSize offset) const { VkDeviceSize size = m_desc.ByteWidth; - - return likely(offset < size) - ? DxvkBufferSlice(m_buffer, offset, size - offset) - : DxvkBufferSlice(); + offset = std::min(offset, size); + return DxvkBufferSlice(m_buffer, offset, size - offset); } DxvkBufferSlice GetBufferSlice(VkDeviceSize offset, VkDeviceSize length) const { VkDeviceSize size = m_desc.ByteWidth; - - return likely(offset < size) - ? DxvkBufferSlice(m_buffer, offset, std::min(length, size - offset)) - : DxvkBufferSlice(); + offset = std::min(offset, size); + return DxvkBufferSlice(m_buffer, offset, std::min(length, size - offset)); } DxvkBufferSlice GetSOCounter() { From 35dde3e1b995f440b140b0a3c2b79f6e35fe472d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 15:33:39 +0200 Subject: [PATCH 0471/1348] [d3d11] Change how resourece binding treats null resources --- src/d3d11/d3d11_context.cpp | 139 ++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 60 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 7442f347c..416bfa30e 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3193,7 +3193,7 @@ namespace dxvk { D3D11Buffer* pBuffer, UINT Offset, UINT Stride) { - if (likely(pBuffer != nullptr)) { + if (pBuffer) { EmitCs([ cSlotId = Slot, cBufferSlice = pBuffer->GetBufferSlice(Offset), @@ -3222,14 +3222,22 @@ namespace dxvk { ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32; - EmitCs([ - cBufferSlice = pBuffer != nullptr ? pBuffer->GetBufferSlice(Offset) : DxvkBufferSlice(), - cIndexType = indexType - ] (DxvkContext* ctx) mutable { - ctx->bindIndexBuffer( - Forwarder::move(cBufferSlice), - cIndexType); - }); + if (pBuffer) { + EmitCs([ + cBufferSlice = pBuffer->GetBufferSlice(Offset), + cIndexType = indexType + ] (DxvkContext* ctx) mutable { + ctx->bindIndexBuffer( + Forwarder::move(cBufferSlice), + cIndexType); + }); + } else { + EmitCs([ + cIndexType = indexType + ] (DxvkContext* ctx) { + ctx->bindIndexBuffer(DxvkBufferSlice(), cIndexType); + }); + } } @@ -3238,32 +3246,34 @@ namespace dxvk { UINT Slot, D3D11Buffer* pBuffer, UINT Offset) { - DxvkBufferSlice bufferSlice; - DxvkBufferSlice counterSlice; + if (pBuffer) { + EmitCs([ + cSlotId = Slot, + cOffset = Offset, + cBufferSlice = pBuffer->GetBufferSlice(), + cCounterSlice = pBuffer->GetSOCounter() + ] (DxvkContext* ctx) mutable { + if (cCounterSlice.defined() && cOffset != ~0u) { + ctx->updateBuffer( + cCounterSlice.buffer(), + cCounterSlice.offset(), + sizeof(cOffset), + &cOffset); + } - if (pBuffer != nullptr) { - bufferSlice = pBuffer->GetBufferSlice(); - counterSlice = pBuffer->GetSOCounter(); + ctx->bindXfbBuffer(cSlotId, + Forwarder::move(cBufferSlice), + Forwarder::move(cCounterSlice)); + }); + } else { + EmitCs([ + cSlotId = Slot + ] (DxvkContext* ctx) { + ctx->bindXfbBuffer(cSlotId, + DxvkBufferSlice(), + DxvkBufferSlice()); + }); } - - EmitCs([ - cSlotId = Slot, - cOffset = Offset, - cBufferSlice = bufferSlice, - cCounterSlice = counterSlice - ] (DxvkContext* ctx) mutable { - if (cCounterSlice.defined() && cOffset != ~0u) { - ctx->updateBuffer( - cCounterSlice.buffer(), - cCounterSlice.offset(), - sizeof(cOffset), - &cOffset); - } - - ctx->bindXfbBuffer(cSlotId, - Forwarder::move(cBufferSlice), - Forwarder::move(cCounterSlice)); - }); } @@ -3274,14 +3284,23 @@ namespace dxvk { D3D11Buffer* pBuffer, UINT Offset, UINT Length) { - EmitCs([ - cSlotId = Slot, - cBufferSlice = pBuffer ? pBuffer->GetBufferSlice(16 * Offset, 16 * Length) : DxvkBufferSlice() - ] (DxvkContext* ctx) mutable { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceBuffer(stage, cSlotId, - Forwarder::move(cBufferSlice)); - }); + if (pBuffer) { + EmitCs([ + cSlotId = Slot, + cBufferSlice = pBuffer->GetBufferSlice(16 * Offset, 16 * Length) + ] (DxvkContext* ctx) mutable { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceBuffer(stage, cSlotId, + Forwarder::move(cBufferSlice)); + }); + } else { + EmitCs([ + cSlotId = Slot + ] (DxvkContext* ctx) { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceBuffer(stage, cSlotId, DxvkBufferSlice()); + }); + } } @@ -3307,14 +3326,23 @@ namespace dxvk { void D3D11CommonContext::BindSampler( UINT Slot, D3D11SamplerState* pSampler) { - EmitCs([ - cSlotId = Slot, - cSampler = pSampler != nullptr ? pSampler->GetDXVKSampler() : nullptr - ] (DxvkContext* ctx) mutable { - VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceSampler(stage, cSlotId, - Forwarder::move(cSampler)); - }); + if (pSampler) { + EmitCs([ + cSlotId = Slot, + cSampler = pSampler->GetDXVKSampler() + ] (DxvkContext* ctx) mutable { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceSampler(stage, cSlotId, + Forwarder::move(cSampler)); + }); + } else { + EmitCs([ + cSlotId = Slot + ] (DxvkContext* ctx) { + VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + ctx->bindResourceSampler(stage, cSlotId, nullptr); + }); + } } @@ -4297,17 +4325,8 @@ namespace dxvk { constantBound = 0; } - // Do a full rebind if either the buffer changes, or if either the current or - // the previous number of bound constants were zero, since we're binding a null - // buffer to the backend in that case. - bool needsUpdate = bindings.buffers[StartSlot + i].buffer != newBuffer; - - if (!needsUpdate) { - needsUpdate |= !constantBound; - needsUpdate |= !bindings.buffers[StartSlot + i].constantBound; - } - - if (needsUpdate) { + // Do a full rebind if either the buffer changes + if (bindings.buffers[StartSlot + i].buffer != newBuffer) { bindings.buffers[StartSlot + i].buffer = newBuffer; bindings.buffers[StartSlot + i].constantOffset = constantOffset; bindings.buffers[StartSlot + i].constantCount = constantCount; From 97f0d1dfb85dd9a26525c192a91c42575443aa3b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 15:45:22 +0200 Subject: [PATCH 0472/1348] [d3d11] Use bindIndexBufferRange whenever possible --- src/d3d11/d3d11_buffer.h | 6 ++++++ src/d3d11/d3d11_context.cpp | 42 ++++++++++++++++++++++++++++++------- src/d3d11/d3d11_context.h | 5 +++++ 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index 866e8d213..a20121457 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -90,6 +90,12 @@ namespace dxvk { return DxvkBufferSlice(m_buffer, offset, std::min(length, size - offset)); } + VkDeviceSize GetRemainingSize(VkDeviceSize offset) const { + VkDeviceSize size = m_desc.ByteWidth; + offset = std::min(offset, size); + return size - offset; + } + DxvkBufferSlice GetSOCounter() { return m_soCounter != nullptr ? DxvkBufferSlice(m_soCounter) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 416bfa30e..c56aaa1fa 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1227,19 +1227,19 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); auto newBuffer = static_cast(pIndexBuffer); - bool needsUpdate = m_state.ia.indexBuffer.buffer != newBuffer; - if (needsUpdate) + if (m_state.ia.indexBuffer.buffer != newBuffer) { m_state.ia.indexBuffer.buffer = newBuffer; - - needsUpdate |= m_state.ia.indexBuffer.offset != Offset - || m_state.ia.indexBuffer.format != Format; - - if (needsUpdate) { m_state.ia.indexBuffer.offset = Offset; m_state.ia.indexBuffer.format = Format; BindIndexBuffer(newBuffer, Offset, Format); + } else if (m_state.ia.indexBuffer.offset != Offset + || m_state.ia.indexBuffer.format != Format) { + m_state.ia.indexBuffer.offset = Offset; + m_state.ia.indexBuffer.format = Format; + + BindIndexBufferRange(newBuffer, Offset, Format); } } @@ -3239,7 +3239,33 @@ namespace dxvk { }); } } - + + + template + void D3D11CommonContext::BindIndexBufferRange( + D3D11Buffer* pBuffer, + UINT Offset, + DXGI_FORMAT Format) { + if (pBuffer) { + VkIndexType indexType = Format == DXGI_FORMAT_R16_UINT + ? VK_INDEX_TYPE_UINT16 + : VK_INDEX_TYPE_UINT32; + + VkDeviceSize offset = Offset; + VkDeviceSize length = pBuffer->GetRemainingSize(Offset); + + EmitCs([ + cBufferOffset = offset, + cBufferLength = length, + cIndexType = indexType + ] (DxvkContext* ctx) mutable { + ctx->bindIndexBufferRange( + cBufferOffset, cBufferLength, + cIndexType); + }); + } + } + template void D3D11CommonContext::BindXfbBuffer( diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 5ba55507c..2b1f52e34 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -824,6 +824,11 @@ namespace dxvk { UINT Offset, DXGI_FORMAT Format); + void BindIndexBufferRange( + D3D11Buffer* pBuffer, + UINT Offset, + DXGI_FORMAT Format); + void BindXfbBuffer( UINT Slot, D3D11Buffer* pBuffer, From a74f8da7b787d94f938dd9bcfda73f8e3f91d8d2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 15:50:13 +0200 Subject: [PATCH 0473/1348] [d3d11] Use bindVertexBufferRange whenever possible --- src/d3d11/d3d11_context.cpp | 37 ++++++++++++++++++++++++++++++------- src/d3d11/d3d11_context.h | 6 ++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index c56aaa1fa..62313593d 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1198,19 +1198,19 @@ namespace dxvk { for (uint32_t i = 0; i < NumBuffers; i++) { auto newBuffer = static_cast(ppVertexBuffers[i]); - bool needsUpdate = m_state.ia.vertexBuffers[StartSlot + i].buffer != newBuffer; - if (needsUpdate) + if (m_state.ia.vertexBuffers[StartSlot + i].buffer != newBuffer) { m_state.ia.vertexBuffers[StartSlot + i].buffer = newBuffer; - - needsUpdate |= m_state.ia.vertexBuffers[StartSlot + i].offset != pOffsets[i] - || m_state.ia.vertexBuffers[StartSlot + i].stride != pStrides[i]; - - if (needsUpdate) { m_state.ia.vertexBuffers[StartSlot + i].offset = pOffsets[i]; m_state.ia.vertexBuffers[StartSlot + i].stride = pStrides[i]; BindVertexBuffer(StartSlot + i, newBuffer, pOffsets[i], pStrides[i]); + } else if (m_state.ia.vertexBuffers[StartSlot + i].offset != pOffsets[i] + || m_state.ia.vertexBuffers[StartSlot + i].stride != pStrides[i]) { + m_state.ia.vertexBuffers[StartSlot + i].offset = pOffsets[i]; + m_state.ia.vertexBuffers[StartSlot + i].stride = pStrides[i]; + + BindVertexBufferRange(StartSlot + i, newBuffer, pOffsets[i], pStrides[i]); } } @@ -3213,6 +3213,29 @@ namespace dxvk { } + template + void D3D11CommonContext::BindVertexBufferRange( + UINT Slot, + D3D11Buffer* pBuffer, + UINT Offset, + UINT Stride) { + if (pBuffer) { + VkDeviceSize offset = Offset; + VkDeviceSize length = pBuffer->GetRemainingSize(Offset); + + EmitCs([ + cSlotId = Slot, + cBufferOffset = offset, + cBufferLength = length, + cStride = Stride + ] (DxvkContext* ctx) mutable { + ctx->bindVertexBufferRange(cSlotId, + cBufferOffset, cBufferLength, cStride); + }); + } + } + + template void D3D11CommonContext::BindIndexBuffer( D3D11Buffer* pBuffer, diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 2b1f52e34..a9acbbdce 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -819,6 +819,12 @@ namespace dxvk { UINT Offset, UINT Stride); + void BindVertexBufferRange( + UINT Slot, + D3D11Buffer* pBuffer, + UINT Offset, + UINT Stride); + void BindIndexBuffer( D3D11Buffer* pBuffer, UINT Offset, From 4831909656521f6650578a62bd0151ef76feb6ee Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 20:04:37 +0200 Subject: [PATCH 0474/1348] [d3d9] Enable apitrace mode for The Witcher --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 90a3eb223..a80df9ce9 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -603,6 +603,10 @@ namespace dxvk { { R"(\\SR2_pc\.exe$)", {{ { "d3d9.textureMemory", "0" }, }} }, + /* Witcher 1: Very long loading times */ + { R"(\\witcher\.exe$)", {{ + { "d3d9.apitraceMode", "True" }, + }} }, }}; From 2b2c44aa998f6743ec07bdf3e81566ad24978012 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 7 Aug 2022 21:24:57 +0200 Subject: [PATCH 0475/1348] [dxvk] Move image view cookie to DxvkResource --- src/dxvk/dxvk_image.cpp | 5 +---- src/dxvk/dxvk_image.h | 16 ---------------- src/dxvk/dxvk_resource.cpp | 9 +++++++++ src/dxvk/dxvk_resource.h | 21 +++++++++++++++++++-- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index f08ce410c..d48fc05ed 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -4,9 +4,6 @@ namespace dxvk { - std::atomic DxvkImageView::s_cookie = { 0ull }; - - DxvkImage::DxvkImage( const DxvkDevice* device, const DxvkImageCreateInfo& createInfo, @@ -220,7 +217,7 @@ namespace dxvk { const Rc& vkd, const Rc& image, const DxvkImageViewCreateInfo& info) - : m_vkd(vkd), m_image(image), m_info(info), m_cookie(++s_cookie) { + : m_vkd(vkd), m_image(image), m_info(info) { for (uint32_t i = 0; i < ViewCount; i++) m_views[i] = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index 42d95971a..285c5e9ee 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -438,18 +438,6 @@ namespace dxvk { return lookupFormatInfo(m_info.format); } - /** - * \brief Unique object identifier - * - * Can be used to identify an object even when - * the lifetime of the object is unknown, and - * without referencing the actual object. - * \returns Unique identifier - */ - uint64_t cookie() const { - return m_cookie; - } - /** * \brief Mip level size * @@ -567,10 +555,6 @@ namespace dxvk { DxvkImageViewCreateInfo m_info; VkImageView m_views[ViewCount]; - uint64_t m_cookie; - - static std::atomic s_cookie; - void createView(VkImageViewType type, uint32_t numLayers); }; diff --git a/src/dxvk/dxvk_resource.cpp b/src/dxvk/dxvk_resource.cpp index af7a2ea4e..4dff5d7c2 100644 --- a/src/dxvk/dxvk_resource.cpp +++ b/src/dxvk/dxvk_resource.cpp @@ -2,6 +2,15 @@ namespace dxvk { + std::atomic DxvkResource::s_cookie = { 0ull }; + + + DxvkResource::DxvkResource() + : m_useCount(0ull), m_cookie(++s_cookie) { + + } + + DxvkResource::~DxvkResource() { } diff --git a/src/dxvk/dxvk_resource.h b/src/dxvk/dxvk_resource.h index 80a935270..97e82cb72 100644 --- a/src/dxvk/dxvk_resource.h +++ b/src/dxvk/dxvk_resource.h @@ -31,9 +31,23 @@ namespace dxvk { static constexpr uint64_t RdAccessInc = 1ull << RdAccessShift; static constexpr uint64_t WrAccessInc = 1ull << WrAccessShift; public: - + + DxvkResource(); + virtual ~DxvkResource(); + /** + * \brief Unique object identifier + * + * Can be used to identify an object even when + * the lifetime of the object is unknown, and + * without referencing the actual object. + * \returns Unique identifier + */ + uint64_t cookie() const { + return m_cookie; + } + /** * \brief Increments reference count * \returns New reference count @@ -104,7 +118,8 @@ namespace dxvk { private: - std::atomic m_useCount = { 0ull }; + std::atomic m_useCount; + uint64_t m_cookie; static constexpr uint64_t getIncrement(DxvkAccess access) { uint64_t increment = RefcountInc; @@ -117,6 +132,8 @@ namespace dxvk { return increment; } + static std::atomic s_cookie; + }; } \ No newline at end of file From 43df6cfa45709545ab075d071a52173d6a1aa432 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 04:50:26 +0200 Subject: [PATCH 0476/1348] [dxvk] Fix indentation Thanks, VSCode. --- src/dxvk/dxvk_graphics.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 822c4a832..4a8e7a829 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -1102,9 +1102,9 @@ namespace dxvk { key.foLibrary->getHandle(), }}; - VkPipelineLibraryCreateInfoKHR libInfo = { VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR }; - libInfo.libraryCount = libraries.size(); - libInfo.pLibraries = libraries.data(); + VkPipelineLibraryCreateInfoKHR libInfo = { VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR }; + libInfo.libraryCount = libraries.size(); + libInfo.pLibraries = libraries.data(); VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; info.layout = m_bindings->getPipelineLayout(true); From 4f0c217633c5b4a2c7257ba552485ce416dceb93 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 8 Aug 2022 03:53:25 +0100 Subject: [PATCH 0477/1348] [d3d9] Fix recording MultiplyTransform --- src/d3d9/d3d9_device.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 56f1206ba..74a8e5b0e 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -1606,10 +1606,10 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D9DeviceEx::MultiplyTransform(D3DTRANSFORMSTATETYPE TransformState, const D3DMATRIX* pMatrix) { D3D9DeviceLock lock = LockDevice(); - if (unlikely(ShouldRecord())) - return m_recorder->MultiplyStateTransform(TransformState, pMatrix); + const uint32_t idx = GetTransformIndex(TransformState); - uint32_t idx = GetTransformIndex(TransformState); + if (unlikely(ShouldRecord())) + return m_recorder->MultiplyStateTransform(idx, pMatrix); m_state.transforms[idx] = m_state.transforms[idx] * ConvertMatrix(pMatrix); From 0adf64f08545706b863319a7df2de419fd7fcb39 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 02:33:37 +0200 Subject: [PATCH 0478/1348] [dxvk] Add flat shading parameter to rasterizer state --- src/d3d11/d3d11_context.cpp | 1 + src/d3d11/d3d11_rasterizer.cpp | 1 + src/d3d9/d3d9_device.cpp | 4 +--- src/dxvk/dxvk_constant_state.h | 1 + src/dxvk/dxvk_swapchain_blitter.cpp | 1 + src/dxvk/hud/dxvk_hud.cpp | 1 + 6 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 62313593d..340017a4d 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -4991,6 +4991,7 @@ namespace dxvk { pRsState->depthBiasEnable = VK_FALSE; pRsState->conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT; pRsState->sampleCount = 0; + pRsState->flatShading = VK_FALSE; } diff --git a/src/d3d11/d3d11_rasterizer.cpp b/src/d3d11/d3d11_rasterizer.cpp index 8d8ba1c2e..169ce3b58 100644 --- a/src/d3d11/d3d11_rasterizer.cpp +++ b/src/d3d11/d3d11_rasterizer.cpp @@ -37,6 +37,7 @@ namespace dxvk { m_state.depthClipEnable = desc.DepthClipEnable; m_state.conservativeMode = DecodeConservativeRasterizationMode(desc.ConservativeRaster); m_state.sampleCount = VkSampleCountFlags(desc.ForcedSampleCount); + m_state.flatShading = VK_FALSE; m_depthBias.depthBiasConstant = float(desc.DepthBias); m_depthBias.depthBiasSlope = desc.SlopeScaledDepthBias; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 74a8e5b0e..4bc5e738a 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5715,14 +5715,12 @@ namespace dxvk { auto& rs = m_state.renderStates; - DxvkRasterizerState state; + DxvkRasterizerState state = { }; state.cullMode = DecodeCullMode(D3DCULL(rs[D3DRS_CULLMODE])); state.depthBiasEnable = IsDepthBiasEnabled(); state.depthClipEnable = true; state.frontFace = VK_FRONT_FACE_CLOCKWISE; state.polygonMode = DecodeFillMode(D3DFILLMODE(rs[D3DRS_FILLMODE])); - state.conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT; - state.sampleCount = 0; EmitCs([ cState = state diff --git a/src/dxvk/dxvk_constant_state.h b/src/dxvk/dxvk_constant_state.h index 222c6ee5e..46d3d2afa 100644 --- a/src/dxvk/dxvk_constant_state.h +++ b/src/dxvk/dxvk_constant_state.h @@ -105,6 +105,7 @@ namespace dxvk { VkBool32 depthBiasEnable; VkConservativeRasterizationModeEXT conservativeMode; VkSampleCountFlags sampleCount; + VkBool32 flatShading; }; diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index 591cce3ad..29b413f68 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -124,6 +124,7 @@ namespace dxvk { rsState.depthBiasEnable = VK_FALSE; rsState.conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT; rsState.sampleCount = VK_SAMPLE_COUNT_1_BIT; + rsState.flatShading = VK_FALSE; ctx->setRasterizerState(rsState); DxvkMultisampleState msState; diff --git a/src/dxvk/hud/dxvk_hud.cpp b/src/dxvk/hud/dxvk_hud.cpp index 935760c06..5a1af3c39 100644 --- a/src/dxvk/hud/dxvk_hud.cpp +++ b/src/dxvk/hud/dxvk_hud.cpp @@ -22,6 +22,7 @@ namespace dxvk::hud { m_rsState.depthBiasEnable = VK_FALSE; m_rsState.conservativeMode = VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT; m_rsState.sampleCount = VK_SAMPLE_COUNT_1_BIT; + m_rsState.flatShading = VK_FALSE; m_blendMode.enableBlending = VK_TRUE; m_blendMode.colorSrcFactor = VK_BLEND_FACTOR_ONE; From a84beae1127b9d33c09a93cf13ef6a16f738e2c0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 02:35:58 +0200 Subject: [PATCH 0479/1348] [dxvk] Add flat shading field to pipeline state --- src/dxvk/dxvk_context.cpp | 3 ++- src/dxvk/dxvk_graphics.cpp | 4 ++++ src/dxvk/dxvk_graphics_state.h | 11 +++++++++-- src/dxvk/dxvk_state_cache_types.h | 6 ++++-- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 502f3a71b..48eb05f57 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2405,7 +2405,8 @@ namespace dxvk { rs.depthBiasEnable, rs.polygonMode, rs.sampleCount, - rs.conservativeMode); + rs.conservativeMode, + rs.flatShading); if (!m_state.gp.state.rs.eq(rsInfo)) { m_flags.set(DxvkContextFlag::GpDirtyPipelineState); diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 4a8e7a829..8e295e609 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -1050,6 +1050,10 @@ namespace dxvk { if (state.useDualSourceBlending()) return false; + // Flat shading requires patching the fragment shader + if (state.rs.flatShading() && m_shaders.fs->info().flatShadingInputs) + return false; + // Multisample state must match in this case, and the // library assumes that MSAA is disabled in this case. if (m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading)) { diff --git a/src/dxvk/dxvk_graphics_state.h b/src/dxvk/dxvk_graphics_state.h index 5713115c1..24c7dbb34 100644 --- a/src/dxvk/dxvk_graphics_state.h +++ b/src/dxvk/dxvk_graphics_state.h @@ -222,12 +222,14 @@ namespace dxvk { VkBool32 depthBiasEnable, VkPolygonMode polygonMode, VkSampleCountFlags sampleCount, - VkConservativeRasterizationModeEXT conservativeMode) + VkConservativeRasterizationModeEXT conservativeMode, + VkBool32 flatShading) : m_depthClipEnable (uint16_t(depthClipEnable)), m_depthBiasEnable (uint16_t(depthBiasEnable)), m_polygonMode (uint16_t(polygonMode)), m_sampleCount (uint16_t(sampleCount)), m_conservativeMode(uint16_t(conservativeMode)), + m_flatShading (uint16_t(flatShading)), m_reserved (0) { } VkBool32 depthClipEnable() const { @@ -250,6 +252,10 @@ namespace dxvk { return VkConservativeRasterizationModeEXT(m_conservativeMode); } + VkBool32 flatShading() const { + return VkBool32(m_flatShading); + } + bool eq(const DxvkRsInfo& other) const { return !std::memcmp(this, &other, sizeof(*this)); } @@ -261,7 +267,8 @@ namespace dxvk { uint16_t m_polygonMode : 2; uint16_t m_sampleCount : 5; uint16_t m_conservativeMode : 2; - uint16_t m_reserved : 5; + uint16_t m_flatShading : 1; + uint16_t m_reserved : 4; }; diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index d257325a4..c2f818683 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -133,7 +133,8 @@ namespace dxvk { VkBool32(m_depthBiasEnable), VkPolygonMode(m_polygonMode), VkSampleCountFlags(m_sampleCount), - VkConservativeRasterizationModeEXT(m_conservativeMode)); + VkConservativeRasterizationModeEXT(m_conservativeMode), + VK_FALSE); } }; @@ -158,7 +159,8 @@ namespace dxvk { VkBool32(m_depthBiasEnable), VkPolygonMode(m_polygonMode), VkSampleCountFlags(m_sampleCount), - VkConservativeRasterizationModeEXT(m_conservativeMode)); + VkConservativeRasterizationModeEXT(m_conservativeMode), + VK_FALSE); } }; From dfdb7294769e4635427a352c159a9fdaf6a6718b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 03:13:40 +0200 Subject: [PATCH 0480/1348] [dxvk] Add SPIR-V pass to decorate variables as flat on demand --- src/dxvk/dxvk_graphics.cpp | 1 + src/dxvk/dxvk_shader.cpp | 95 ++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_shader.h | 7 +++ 3 files changed, 103 insertions(+) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 8e295e609..1070859d8 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -720,6 +720,7 @@ namespace dxvk { if (shaderInfo.stage == VK_SHADER_STAGE_FRAGMENT_BIT) { info.fsDualSrcBlend = state.useDualSourceBlending(); + info.fsFlatShading = state.rs.flatShading() && shader->info().flatShadingInputs; for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { if ((shaderInfo.outputMask & (1u << i)) && state.writesRenderTarget(i)) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 0f556b680..d64305659 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -12,6 +12,7 @@ namespace dxvk { bool DxvkShaderModuleCreateInfo::eq(const DxvkShaderModuleCreateInfo& other) const { bool eq = fsDualSrcBlend == other.fsDualSrcBlend + && fsFlatShading == other.fsFlatShading && undefinedInputs == other.undefinedInputs; for (uint32_t i = 0; i < rtSwizzles.size() && eq; i++) { @@ -28,6 +29,7 @@ namespace dxvk { size_t DxvkShaderModuleCreateInfo::hash() const { DxvkHashState hash; hash.add(uint32_t(fsDualSrcBlend)); + hash.add(uint32_t(fsFlatShading)); hash.add(undefinedInputs); for (uint32_t i = 0; i < rtSwizzles.size(); i++) { @@ -189,6 +191,10 @@ namespace dxvk { if (m_info.stage == VK_SHADER_STAGE_FRAGMENT_BIT) emitOutputSwizzles(spirvCode, m_info.outputMask, state.rtSwizzles.data()); + // Emit input decorations for flat shading as necessary + if (m_info.stage == VK_SHADER_STAGE_FRAGMENT_BIT && state.fsFlatShading) + emitFlatShadingDeclarations(spirvCode, m_info.flatShadingInputs); + return spirvCode; } @@ -696,6 +702,95 @@ namespace dxvk { } + void DxvkShader::emitFlatShadingDeclarations( + SpirvCodeBuffer& code, + uint32_t inputMask) { + if (!inputMask) + return; + + struct VarInfo { + uint32_t varId; + size_t decorationOffset; + }; + + std::unordered_set candidates; + std::unordered_map decorations; + std::vector flatVars; + + size_t decorateOffset = 0; + + for (auto ins : code) { + switch (ins.opCode()) { + case spv::OpDecorate: { + decorateOffset = ins.offset() + ins.length(); + uint32_t varId = ins.arg(1); + + switch (ins.arg(2)) { + case spv::DecorationLocation: { + uint32_t location = ins.arg(3); + + if (inputMask & (1u << location)) + candidates.insert(varId); + } break; + + case spv::DecorationFlat: + case spv::DecorationCentroid: + case spv::DecorationSample: + case spv::DecorationNoPerspective: { + decorations.insert({ varId, ins.offset() + 2 }); + } break; + + default: ; + } + } break; + + case spv::OpVariable: { + if (ins.arg(3) == spv::StorageClassInput) { + uint32_t varId = ins.arg(2); + + // Only consider variables that have a desired location + if (candidates.find(varId) != candidates.end()) { + VarInfo varInfo; + varInfo.varId = varId; + varInfo.decorationOffset = 0; + + auto decoration = decorations.find(varId); + if (decoration != decorations.end()) + varInfo.decorationOffset = decoration->second; + + flatVars.push_back(varInfo); + } + } + } break; + + default: + break; + } + } + + // Change existing decorations as necessary + for (const auto& var : flatVars) { + if (var.decorationOffset) { + uint32_t* rawCode = code.data(); + rawCode[var.decorationOffset] = spv::DecorationFlat; + } + } + + // Insert new decorations for remaining variables + code.beginInsertion(decorateOffset); + + for (const auto& var : flatVars) { + if (!var.decorationOffset) { + code.putIns(spv::OpDecorate, 3); + code.putWord(var.varId); + code.putWord(spv::DecorationFlat); + } + } + + code.endInsertion(); + } + + DxvkShaderStageInfo::DxvkShaderStageInfo(const DxvkDevice* device) : m_device(device) { diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 0a628054c..6363e3a41 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -46,6 +46,8 @@ namespace dxvk { /// Input and output register mask uint32_t inputMask = 0; uint32_t outputMask = 0; + /// Flat shading input mask + uint32_t flatShadingInputs = 0; /// Push constant range uint32_t pushConstOffset = 0; uint32_t pushConstSize = 0; @@ -64,6 +66,7 @@ namespace dxvk { */ struct DxvkShaderModuleCreateInfo { bool fsDualSrcBlend = false; + bool fsFlatShading = false; uint32_t undefinedInputs = 0; std::array rtSwizzles = { }; @@ -237,6 +240,10 @@ namespace dxvk { uint32_t outputMask, const VkComponentMapping* swizzles); + static void emitFlatShadingDeclarations( + SpirvCodeBuffer& code, + uint32_t inputMask); + }; From 8f1024c09442eb0d51c3e14d9335aac16897d95e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 03:23:59 +0200 Subject: [PATCH 0481/1348] [d3d9] Use new flat shading state for DXSO shaders --- src/d3d9/d3d9_device.cpp | 32 ++++++++----------------- src/d3d9/d3d9_device.h | 15 +----------- src/d3d9/d3d9_shader.cpp | 16 ++++--------- src/d3d9/d3d9_shader.h | 9 ++++---- src/d3d9/d3d9_shader_permutations.h | 20 ---------------- src/dxso/dxso_compiler.cpp | 36 +++++------------------------ src/dxso/dxso_compiler.h | 8 ++----- src/dxso/dxso_module.cpp | 2 +- src/dxso/dxso_module.h | 3 +-- 9 files changed, 29 insertions(+), 112 deletions(-) delete mode 100644 src/d3d9/d3d9_shader_permutations.h diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 4bc5e738a..8b15b82c6 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2098,13 +2098,9 @@ namespace dxvk { break; case D3DRS_SHADEMODE: - if (m_state.pixelShader != nullptr) { - BindShader( - GetCommonShader(m_state.pixelShader), - GetPixelShaderPermutation()); - } - - m_flags.set(D3D9DeviceFlag::DirtyFFPixelShader); + m_flags.set( + D3D9DeviceFlag::DirtyFFPixelShader, + D3D9DeviceFlag::DirtyRasterizerState); break; case D3DRS_TWEENFACTOR: @@ -2685,8 +2681,7 @@ namespace dxvk { if (m_state.pixelShader != nullptr) { BindShader( - GetCommonShader(m_state.pixelShader), - GetPixelShaderPermutation()); + GetCommonShader(m_state.pixelShader)); } if (dst->GetMapMode() == D3D9_COMMON_BUFFER_MAP_MODE_BUFFER) { @@ -2873,10 +2868,7 @@ namespace dxvk { m_flags.clr(D3D9DeviceFlag::DirtyProgVertexShader); m_flags.set(D3D9DeviceFlag::DirtyFFVertexShader); - BindShader( - GetCommonShader(shader), - GetVertexShaderPermutation()); - + BindShader(GetCommonShader(shader)); m_vsShaderMasks = newShader->GetShaderMask(); } else @@ -3204,10 +3196,7 @@ namespace dxvk { if (shader != nullptr) { m_flags.set(D3D9DeviceFlag::DirtyFFPixelShader); - BindShader( - GetCommonShader(shader), - GetPixelShaderPermutation()); - + BindShader(GetCommonShader(shader)); m_psShaderMasks = newShader->GetShaderMask(); } else { @@ -5721,6 +5710,7 @@ namespace dxvk { state.depthClipEnable = true; state.frontFace = VK_FRONT_FACE_CLOCKWISE; state.polygonMode = DecodeFillMode(D3DFILLMODE(rs[D3DRS_FILLMODE])); + state.flatShading = m_state.renderStates[D3DRS_SHADEMODE] == D3DSHADE_FLAT; EmitCs([ cState = state @@ -6032,8 +6022,7 @@ namespace dxvk { m_flags.set(D3D9DeviceFlag::DirtyInputLayout); BindShader( - GetCommonShader(m_state.vertexShader), - GetVertexShaderPermutation()); + GetCommonShader(m_state.vertexShader)); } UploadConstants(); @@ -6123,10 +6112,9 @@ namespace dxvk { template void D3D9DeviceEx::BindShader( - const D3D9CommonShader* pShaderModule, - D3D9ShaderPermutation Permutation) { + const D3D9CommonShader* pShaderModule) { EmitCs([ - cShader = pShaderModule->GetShader(Permutation) + cShader = pShaderModule->GetShader() ] (DxvkContext* ctx) mutable { constexpr VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); ctx->bindShader(std::move(cShader)); diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 487d038f6..a815699e2 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -27,7 +27,6 @@ #include "d3d9_swvp_emu.h" #include "d3d9_spec_constants.h" -#include "d3d9_shader_permutations.h" #include #include @@ -871,8 +870,7 @@ namespace dxvk { template void BindShader( - const D3D9CommonShader* pShaderModule, - D3D9ShaderPermutation Permutation); + const D3D9CommonShader* pShaderModule); void BindInputLayout(); @@ -973,17 +971,6 @@ namespace dxvk { return m_behaviorFlags & (D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_SOFTWARE_VERTEXPROCESSING); } - inline constexpr D3D9ShaderPermutation GetVertexShaderPermutation() { - return D3D9ShaderPermutations::None; - } - - inline D3D9ShaderPermutation GetPixelShaderPermutation() { - if (unlikely(m_state.renderStates[D3DRS_SHADEMODE] == D3DSHADE_FLAT)) - return D3D9ShaderPermutations::FlatShade; - - return D3D9ShaderPermutations::None; - } - void DetermineConstantLayouts(bool canSWVP); D3D9BufferSlice AllocUPBuffer(VkDeviceSize size); diff --git a/src/d3d9/d3d9_shader.cpp b/src/d3d9/d3d9_shader.cpp index 664ebbdbc..2aa2f444e 100644 --- a/src/d3d9/d3d9_shader.cpp +++ b/src/d3d9/d3d9_shader.cpp @@ -56,7 +56,7 @@ namespace dxvk { const D3D9ConstantLayout& constantLayout = ShaderStage == VK_SHADER_STAGE_VERTEX_BIT ? pDevice->GetVertexConstantLayout() : pDevice->GetPixelConstantLayout(); - m_shaders = pModule->compile(*pDxsoModuleInfo, name, AnalysisInfo, constantLayout); + m_shader = pModule->compile(*pDxsoModuleInfo, name, AnalysisInfo, constantLayout); m_isgn = pModule->isgn(); m_usedSamplers = pModule->usedSamplers(); @@ -73,25 +73,17 @@ namespace dxvk { m_constants = pModule->constants(); m_maxDefinedConst = pModule->maxDefinedConstant(); - m_shaders[0]->setShaderKey(Key); + m_shader->setShaderKey(Key); - if (m_shaders[1] != nullptr) { - // Lets lie about the shader key type for the state cache. - m_shaders[1]->setShaderKey({ VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, Key.sha1() }); - } - if (dumpPath.size() != 0) { std::ofstream dumpStream( str::tows(str::format(dumpPath, "/", name, ".spv").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc); - m_shaders[0]->dump(dumpStream); + m_shader->dump(dumpStream); } - pDevice->GetDXVKDevice()->registerShader(m_shaders[0]); - - if (m_shaders[1] != nullptr && m_shaders[1] != m_shaders[0]) - pDevice->GetDXVKDevice()->registerShader(m_shaders[1]); + pDevice->GetDXVKDevice()->registerShader(m_shader); } diff --git a/src/d3d9/d3d9_shader.h b/src/d3d9/d3d9_shader.h index d896f019c..fc281c502 100644 --- a/src/d3d9/d3d9_shader.h +++ b/src/d3d9/d3d9_shader.h @@ -2,7 +2,6 @@ #include "d3d9_resource.h" #include "../dxso/dxso_module.h" -#include "d3d9_shader_permutations.h" #include "d3d9_util.h" #include @@ -33,12 +32,12 @@ namespace dxvk { DxsoModule* pModule); - Rc GetShader(D3D9ShaderPermutation Permutation) const { - return m_shaders[Permutation]; + Rc GetShader() const { + return m_shader; } std::string GetName() const { - return m_shaders[D3D9ShaderPermutations::None]->debugName(); + return m_shader->debugName(); } const std::vector& GetBytecode() const { @@ -69,7 +68,7 @@ namespace dxvk { DxsoDefinedConstants m_constants; uint32_t m_maxDefinedConst; - DxsoPermutations m_shaders; + Rc m_shader; std::vector m_bytecode; diff --git a/src/d3d9/d3d9_shader_permutations.h b/src/d3d9/d3d9_shader_permutations.h deleted file mode 100644 index cf2301d29..000000000 --- a/src/d3d9/d3d9_shader_permutations.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "d3d9_include.h" - -namespace dxvk { - - class DxvkShader; - - namespace D3D9ShaderPermutations { - enum D3D9ShaderPermutation { - None, - FlatShade, - Count - }; - } - using D3D9ShaderPermutation = D3D9ShaderPermutations::D3D9ShaderPermutation; - - using DxsoPermutations = std::array, D3D9ShaderPermutations::Count>; - -} \ No newline at end of file diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index de5735d1c..d0e5fc452 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -219,32 +219,7 @@ namespace dxvk { } - DxsoPermutations DxsoCompiler::compile() { - DxsoPermutations permutations = { }; - - // Create the shader module object - permutations[D3D9ShaderPermutations::None] = compileShader(); - - // If we need to add more permuations, might be worth making a copy of module - // before we do anything more. :-) - if (m_programInfo.type() == DxsoProgramType::PixelShader) { - if (m_ps.diffuseColorIn) - m_module.decorate(m_ps.diffuseColorIn, spv::DecorationFlat); - - if (m_ps.specularColorIn) - m_module.decorate(m_ps.specularColorIn, spv::DecorationFlat); - - if (m_ps.diffuseColorIn || m_ps.specularColorIn) - permutations[D3D9ShaderPermutations::FlatShade] = compileShader(); - else - permutations[D3D9ShaderPermutations::FlatShade] = permutations[D3D9ShaderPermutations::None]; - } - - return permutations; - } - - - Rc DxsoCompiler::compileShader() { + Rc DxsoCompiler::compile() { DxvkShaderCreateInfo info; info.stage = m_programInfo.shaderStage(); info.bindingCount = m_bindings.size(); @@ -254,6 +229,9 @@ namespace dxvk { info.pushConstOffset = m_pushConstOffset; info.pushConstSize = m_pushConstSize; + if (m_programInfo.type() == DxsoProgramTypes::PixelShader) + info.flatShadingInputs = m_ps.flatShadingMask; + return new DxvkShader(info, m_module.compile()); } @@ -3396,10 +3374,8 @@ void DxsoCompiler::emitControlFlowGenericLoop( workingReg.id = m_module.opSelect(getVectorTypeId(workingReg.type), pointInfo.isSprite, pointCoord, workingReg.id); if (m_programInfo.type() == DxsoProgramType::PixelShader && elem.semantic.usage == DxsoUsage::Color) { - if (elem.semantic.usageIndex == 0) - m_ps.diffuseColorIn = inputPtr.id; - else if (elem.semantic.usageIndex == 1) - m_ps.specularColorIn = inputPtr.id; + if (elem.semantic.usageIndex < 2) + m_ps.flatShadingMask |= 1u << slot; } m_module.opStore(indexPtr.id, workingReg.id); diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h index 4360e599e..eb16eeee6 100644 --- a/src/dxso/dxso_compiler.h +++ b/src/dxso/dxso_compiler.h @@ -7,7 +7,6 @@ #include "dxso_util.h" #include "../d3d9/d3d9_constant_layout.h" -#include "../d3d9/d3d9_shader_permutations.h" #include "../d3d9/d3d9_spec_constants.h" #include "../spirv/spirv_module.h" @@ -177,8 +176,7 @@ namespace dxvk { uint32_t killState = 0; uint32_t builtinLaneId = 0; - uint32_t diffuseColorIn = 0; - uint32_t specularColorIn = 0; + uint32_t flatShadingMask = 0; }; struct DxsoCfgBlockIf { @@ -243,7 +241,7 @@ namespace dxvk { * \brief Compiles the shader * \returns The final shader objects */ - DxsoPermutations compile(); + Rc compile(); const DxsoIsgn& isgn() { return m_isgn; } const DxsoIsgn& osgn() { return m_osgn; } @@ -626,8 +624,6 @@ namespace dxvk { return this->emitRegisterLoad(lookup, writeMask); } - Rc compileShader(); - /////////////////////////////// // Handle shader ops void emitDcl(const DxsoInstructionContext& ctx); diff --git a/src/dxso/dxso_module.cpp b/src/dxso/dxso_module.cpp index cf32cdaa2..4cc6eb3e7 100644 --- a/src/dxso/dxso_module.cpp +++ b/src/dxso/dxso_module.cpp @@ -21,7 +21,7 @@ namespace dxvk { return info; } - DxsoPermutations DxsoModule::compile( + Rc DxsoModule::compile( const DxsoModuleInfo& moduleInfo, const std::string& fileName, const DxsoAnalysisInfo& analysis, diff --git a/src/dxso/dxso_module.h b/src/dxso/dxso_module.h index 4b8238df3..b3de38632 100644 --- a/src/dxso/dxso_module.h +++ b/src/dxso/dxso_module.h @@ -9,7 +9,6 @@ #include "dxso_analysis.h" #include "../d3d9/d3d9_constant_layout.h" -#include "../d3d9/d3d9_shader_permutations.h" #include @@ -42,7 +41,7 @@ namespace dxvk { * the compiled SPIR-V for debugging purposes. * \returns The compiled shader object */ - DxsoPermutations compile( + Rc compile( const DxsoModuleInfo& moduleInfo, const std::string& fileName, const DxsoAnalysisInfo& analysis, From 7789fd53ff0eec5697957a1b12758ed7f167727a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 03:51:10 +0200 Subject: [PATCH 0482/1348] [d3d9] Use new flat shading state for fixed-function pipelines --- src/d3d9/d3d9_device.cpp | 5 +---- src/d3d9/d3d9_fixed_function.cpp | 6 ++++-- src/d3d9/d3d9_fixed_function.h | 1 - 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 8b15b82c6..85c96faab 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2098,9 +2098,7 @@ namespace dxvk { break; case D3DRS_SHADEMODE: - m_flags.set( - D3D9DeviceFlag::DirtyFFPixelShader, - D3D9DeviceFlag::DirtyRasterizerState); + m_flags.set(D3D9DeviceFlag::DirtyRasterizerState); break; case D3DRS_TWEENFACTOR: @@ -6653,7 +6651,6 @@ namespace dxvk { } stage0.GlobalSpecularEnable = m_state.renderStates[D3DRS_SPECULARENABLE]; - stage0.GlobalFlatShade = m_state.renderStates[D3DRS_SHADEMODE] == D3DSHADE_FLAT; // The last stage *always* writes to current. if (idx >= 1) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 45e26ab94..a2c2e41f7 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -627,6 +627,7 @@ namespace dxvk { uint32_t m_inputMask = 0u; uint32_t m_outputMask = 0u; + uint32_t m_flatShadingMask = 0u; uint32_t m_pushConstOffset = 0u; uint32_t m_pushConstSize = 0u; @@ -737,6 +738,7 @@ namespace dxvk { info.bindings = m_bindings.data(); info.inputMask = m_inputMask; info.outputMask = m_outputMask; + info.flatShadingInputs = m_flatShadingMask; info.pushConstOffset = m_pushConstOffset; info.pushConstSize = m_pushConstSize; @@ -788,8 +790,8 @@ namespace dxvk { bool diffuseOrSpec = semantic == DxsoSemantic{ DxsoUsage::Color, 0 } || semantic == DxsoSemantic{ DxsoUsage::Color, 1 }; - if (diffuseOrSpec && m_fsKey.Stages[0].Contents.GlobalFlatShade) - m_module.decorate(ptr, spv::DecorationFlat); + if (diffuseOrSpec) + m_flatShadingMask |= 1u << slot; std::string name = str::format(input ? "in_" : "out_", semantic.usage, semantic.usageIndex); m_module.setDebugName(ptr, name.c_str()); diff --git a/src/d3d9/d3d9_fixed_function.h b/src/d3d9/d3d9_fixed_function.h index c60077919..8880f8515 100644 --- a/src/d3d9/d3d9_fixed_function.h +++ b/src/d3d9/d3d9_fixed_function.h @@ -159,7 +159,6 @@ namespace dxvk { // Included in here, read from Stage 0 for packing reasons // Affects all stages. uint32_t GlobalSpecularEnable : 1; - uint32_t GlobalFlatShade : 1; } Contents; uint32_t Primitive[2]; From c392308e6fb612bb3cac08fa6146cf77babc09c9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 18:53:41 +0200 Subject: [PATCH 0483/1348] [dxvk] Fix spec constant selector test for compute shaders This isn't supported on compute. --- src/dxvk/dxvk_shader.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index d64305659..71f8abc9c 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -213,9 +213,13 @@ namespace dxvk { && !m_flags.test(DxvkShaderFlag::ExportsPosition)) return false; - // Ignore shaders that have user-defined spec constants - // and no selector to read their contents from elsewhere - return !m_specConstantMask || (m_specConstantMask & (1u << MaxNumSpecConstants)); + // Spec constant selectors are only supported in graphics + if (m_specConstantMask & (1u << MaxNumSpecConstants)) + return m_info.stage != VK_SHADER_STAGE_COMPUTE_BIT; + + // Always late-compile shaders with spec constants + // that don't use the spec constant selector + return !m_specConstantMask; } From 0ad7a08c4937a98baf5c0740d65a43d36a8399f1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 18:58:22 +0200 Subject: [PATCH 0484/1348] [dxvk] Get rid of some old debug code for compute pipelines --- src/dxvk/dxvk_compute.cpp | 52 +++++++++++++++++++++++---------------- src/dxvk/dxvk_compute.h | 6 ++++- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 448408dcb..0006ce145 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include "../util/util_time.h" @@ -101,11 +103,6 @@ namespace dxvk { const DxvkComputePipelineStateInfo& state) const { auto vk = m_device->vkd(); - if (Logger::logLevel() <= LogLevel::Debug) { - Logger::debug("Compiling compute pipeline..."); - Logger::debug(str::format(" cs : ", m_shaders.cs->debugName())); - } - DxvkPipelineSpecConstantState scState(m_shaders.cs->getSpecConstantMask(), state.sc); DxvkShaderStageInfo stageInfo(m_device); @@ -117,26 +114,16 @@ namespace dxvk { info.stage = *stageInfo.getStageInfos(); info.layout = m_bindings->getPipelineLayout(false); info.basePipelineIndex = -1; - - // Time pipeline compilation for debugging purposes - dxvk::high_resolution_clock::time_point t0, t1; - if (Logger::logLevel() <= LogLevel::Debug) - t0 = dxvk::high_resolution_clock::now(); - VkPipeline pipeline = VK_NULL_HANDLE; - if (vk->vkCreateComputePipelines(vk->device(), - VK_NULL_HANDLE, 1, &info, nullptr, &pipeline) != VK_SUCCESS) { - Logger::err("DxvkComputePipeline: Failed to compile pipeline"); - Logger::err(str::format(" cs : ", m_shaders.cs->debugName())); + VkResult vr = vk->vkCreateComputePipelines(vk->device(), + VK_NULL_HANDLE, 1, &info, nullptr, &pipeline); + + if (vr != VK_SUCCESS) { + Logger::err(str::format("DxvkComputePipeline: Failed to compile pipeline: ", vr)); + this->logPipelineState(LogLevel::Error, state); return VK_NULL_HANDLE; } - - if (Logger::logLevel() <= LogLevel::Debug) { - t1 = dxvk::high_resolution_clock::now(); - auto td = std::chrono::duration_cast(t1 - t0); - Logger::debug(str::format("DxvkComputePipeline: Finished in ", td.count(), " ms")); - } return pipeline; } @@ -159,4 +146,27 @@ namespace dxvk { m_stateCache->addComputePipeline(key, state); } + + void DxvkComputePipeline::logPipelineState( + LogLevel level, + const DxvkComputePipelineStateInfo& state) const { + std::stringstream sstr; + sstr << " cs : " << m_shaders.cs->debugName() << std::endl; + + bool hasSpecConstants = false; + + for (uint32_t i = 0; i < MaxNumSpecConstants; i++) { + if (state.sc.specConstants[i]) { + if (!hasSpecConstants) { + sstr << "Specialization constants:" << std::endl; + hasSpecConstants = true; + } + + sstr << " " << i << ": 0x" << std::hex << std::setw(8) << std::setfill('0') << state.sc.specConstants[i] << std::dec << std::endl; + } + } + + Logger::log(level, sstr.str()); + } + } diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index 560e59ab5..141a11335 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -151,7 +151,11 @@ namespace dxvk { void writePipelineStateToCache( const DxvkComputePipelineStateInfo& state) const; - + + void logPipelineState( + LogLevel level, + const DxvkComputePipelineStateInfo& state) const; + }; } \ No newline at end of file From 57dcf73a5447e57dfd4c2051fdf29b9302b33206 Mon Sep 17 00:00:00 2001 From: Derek Lesho Date: Mon, 8 Aug 2022 15:40:12 -0400 Subject: [PATCH 0485/1348] d3d11: Fix shared textures that export both NT and KMT handles. We should always create the DxvkImage with the KMT handle type, so that the call later to openKmtHandle succeeds. Also, don't free sharedHandle when exporting an NT handle. --- src/d3d11/d3d11_texture.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index e1846559a..1c88c6556 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -51,9 +51,9 @@ namespace dxvk { imageInfo.shared = true; imageInfo.sharing.mode = hSharedHandle == INVALID_HANDLE_VALUE ? DxvkSharedHandleMode::Export : DxvkSharedHandleMode::Import; - imageInfo.sharing.type = m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_NTHANDLE - ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT - : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT; + imageInfo.sharing.type = (m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED) + ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT + : VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT; imageInfo.sharing.handle = hSharedHandle; } @@ -627,7 +627,7 @@ namespace dxvk { Logger::warn("D3D11: Failed to write shared resource info for a texture"); } - if (hSharedHandle != INVALID_HANDLE_VALUE) + if ((m_desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED) && hSharedHandle != INVALID_HANDLE_VALUE) CloseHandle(hSharedHandle); } From ac1e44f1207083fff3ac38ace48ced716769c357 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 8 Aug 2022 22:24:23 +0200 Subject: [PATCH 0486/1348] [d3d9] Fix typo --- src/d3d9/d3d9_common_texture.h | 2 +- src/d3d9/d3d9_device.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index 7d15ca954..667d3f9d7 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -331,7 +331,7 @@ namespace dxvk { void SetNeedsReadback(UINT Subresource, bool value) { m_needsReadback.set(Subresource, value); } - bool NeedsReachback(UINT Subresource) const { return m_needsReadback.get(Subresource); } + bool NeedsReadback(UINT Subresource) const { return m_needsReadback.get(Subresource); } void MarkAllNeedReadback() { m_needsReadback.setAll(); } diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 85c96faab..b078f6603 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4163,7 +4163,7 @@ namespace dxvk { // then we need to copy -> buffer // We are also always dirty if we are a render target, // a depth stencil, or auto generate mipmaps. - bool needsReadback = pResource->NeedsReachback(Subresource) || renderable; + bool needsReadback = pResource->NeedsReadback(Subresource) || renderable; pResource->SetNeedsReadback(Subresource, false); void* mapPtr; From 36d8bb77a596c42c44d0b4f6782d72209e1d5c31 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 8 Aug 2022 23:46:10 +0200 Subject: [PATCH 0487/1348] [d3d9] Fix synchronization in UpdateTextureFromBuffer --- src/d3d9/d3d9_device.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index b078f6603..4d445514f 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4427,6 +4427,12 @@ namespace dxvk { auto convertFormat = pDestTexture->GetFormatMapping().ConversionFormatInfo; + if (unlikely(pSrcTexture->NeedsReadback(SrcSubresource))) { + const Rc& buffer = pSrcTexture->GetBuffer(SrcSubresource, false); + WaitForResource(buffer, pSrcTexture->GetMappingBufferSequenceNumber(SrcSubresource), 0); + pSrcTexture->SetNeedsReadback(SrcSubresource, false); + } + if (likely(convertFormat.FormatType == D3D9ConversionFormat_None)) { VkOffset3D alignedDestOffset = { int32_t(alignDown(DestOffset.x, formatInfo->blockSize.width)), From 01fb40423db43a70966ffce39e27d8d1d5302ab2 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 8 Aug 2022 13:05:45 +0200 Subject: [PATCH 0488/1348] [d3d9] Remove some dead debug code Oops. --- src/d3d9/d3d9_mem.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/d3d9/d3d9_mem.h b/src/d3d9/d3d9_mem.h index 20ac138cc..b0d61f053 100644 --- a/src/d3d9/d3d9_mem.h +++ b/src/d3d9/d3d9_mem.h @@ -47,11 +47,6 @@ namespace dxvk { D3D9MemoryChunk (D3D9MemoryChunk&& other) = delete; D3D9MemoryChunk& operator = (D3D9MemoryChunk&& other) = delete; -#ifdef D3D9_MEM_MAP_CHUNKS - void IncMapCounter(); - void DecMapCounter(); - void* Ptr() const { return m_ptr; } -#endif D3D9Memory Alloc(uint32_t Size); void Free(D3D9Memory* Memory); bool IsEmpty(); @@ -71,11 +66,6 @@ namespace dxvk { uint32_t m_mappingGranularity; std::vector m_freeRanges; std::vector m_mappingRanges; - -#ifdef D3D9_MEM_MAP_CHUNKS - uint32_t m_mapCounter = 0; - void* m_ptr; -#endif }; class D3D9Memory { From 1628b9e63a07204de8cdba0badb2d76803b00a97 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 8 Aug 2022 13:36:23 +0200 Subject: [PATCH 0489/1348] [d3d9] Add 64bit implementation for D3D9MemoryAllocator This just uses malloc & free but allows us to use the same code for D3D9 shader bytecode on 64 bit builds. --- src/d3d9/d3d9_mem.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++ src/d3d9/d3d9_mem.h | 38 ++++++++++++++++++++++++------ 2 files changed, 86 insertions(+), 7 deletions(-) diff --git a/src/d3d9/d3d9_mem.cpp b/src/d3d9/d3d9_mem.cpp index c288fd3ac..ec2562469 100644 --- a/src/d3d9/d3d9_mem.cpp +++ b/src/d3d9/d3d9_mem.cpp @@ -7,6 +7,8 @@ #ifdef D3D9_ALLOW_UNMAPPING #include +#else +#include #endif namespace dxvk { @@ -287,6 +289,59 @@ namespace dxvk { return m_ptr; } +#else + + D3D9Memory D3D9MemoryAllocator::Alloc(uint32_t Size) { + D3D9Memory memory(this, Size); + m_allocatedMemory += Size; + return memory; + } + + uint32_t D3D9MemoryAllocator::MappedMemory() { + return m_allocatedMemory.load(); + } + + uint32_t D3D9MemoryAllocator::UsedMemory() { + return m_allocatedMemory.load(); + } + + uint32_t D3D9MemoryAllocator::AllocatedMemory() { + return m_allocatedMemory.load(); + } + + D3D9Memory::D3D9Memory(D3D9MemoryAllocator* pAllocator, size_t Size) + : m_allocator (pAllocator), + m_ptr (malloc(Size)), + m_size (Size) {} + + D3D9Memory::D3D9Memory(D3D9Memory&& other) + : m_allocator(std::exchange(other.m_allocator, nullptr)), + m_ptr(std::exchange(other.m_ptr, nullptr)), + m_size(std::exchange(other.m_size, 0)) {} + + D3D9Memory::~D3D9Memory() { + this->Free(); + } + + D3D9Memory& D3D9Memory::operator = (D3D9Memory&& other) { + this->Free(); + + m_allocator = std::exchange(other.m_allocator, nullptr); + m_ptr = std::exchange(other.m_ptr, nullptr); + m_size = std::exchange(other.m_size, 0); + return *this; + } + + void D3D9Memory::Free() { + if (m_ptr == nullptr) + return; + + free(m_ptr); + m_ptr = nullptr; + m_allocator->NotifyFreed(m_size); + } + + #endif } diff --git a/src/d3d9/d3d9_mem.h b/src/d3d9/d3d9_mem.h index b0d61f053..1da862653 100644 --- a/src/d3d9/d3d9_mem.h +++ b/src/d3d9/d3d9_mem.h @@ -126,25 +126,49 @@ namespace dxvk { }; #else - class D3D9Memory { + class D3D9Memory { + friend D3D9MemoryAllocator; + public: - operator bool() const { return false; } + D3D9Memory() {} + ~D3D9Memory(); + + D3D9Memory (const D3D9Memory&) = delete; + D3D9Memory& operator = (const D3D9Memory&) = delete; + + D3D9Memory (D3D9Memory&& other); + D3D9Memory& operator = (D3D9Memory&& other); + + operator bool() const { return m_ptr != nullptr; } void Map() {} void Unmap() {} - void* Ptr() { return nullptr; } + void* Ptr() { return m_ptr; } + size_t GetSize() const { return m_size; } private: + D3D9Memory(D3D9MemoryAllocator* pAllocator, size_t Size); void Free(); + + D3D9MemoryAllocator* m_allocator = nullptr; + void* m_ptr = nullptr; + size_t m_size = 0; }; class D3D9MemoryAllocator { public: - D3D9Memory Alloc(uint32_t Size) { return { }; } - uint32_t MappedMemory() { return 0; } - uint32_t UsedMemory() { return 0; } - uint32_t AllocatedMemory() { return 0; } + D3D9Memory Alloc(uint32_t Size); + uint32_t MappedMemory(); + uint32_t UsedMemory(); + uint32_t AllocatedMemory(); + void NotifyFreed(uint32_t Size) { + m_allocatedMemory -= Size; + } + + private: + std::atomic m_allocatedMemory = 0; + }; #endif From 49e9ba2ca7adf6926fdc0bc0172f4ed8601a4362 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 8 Aug 2022 14:46:39 +0200 Subject: [PATCH 0490/1348] [d3d9] Move d3d9 bytecode into D3D9Shader This reduces the amount of times we copy the bytecode and actually frees it when the game frees the associated shader. --- src/d3d9/d3d9_device.cpp | 11 ++++++++--- src/d3d9/d3d9_device.h | 1 + src/d3d9/d3d9_shader.cpp | 4 ++-- src/d3d9/d3d9_shader.h | 39 ++++++++++++++++++++++----------------- 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 4d445514f..507415710 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2820,14 +2820,16 @@ namespace dxvk { moduleInfo.options = m_dxsoOptions; D3D9CommonShader module; + uint32_t bytecodeLength; if (FAILED(this->CreateShaderModule(&module, + &bytecodeLength, VK_SHADER_STAGE_VERTEX_BIT, pFunction, &moduleInfo))) return D3DERR_INVALIDCALL; - *ppShader = ref(new D3D9VertexShader(this, module)); + *ppShader = ref(new D3D9VertexShader(this, module, pFunction, bytecodeLength)); return D3D_OK; } @@ -3149,14 +3151,16 @@ namespace dxvk { moduleInfo.options = m_dxsoOptions; D3D9CommonShader module; + uint32_t bytecodeLength; if (FAILED(this->CreateShaderModule(&module, + &bytecodeLength, VK_SHADER_STAGE_FRAGMENT_BIT, pFunction, &moduleInfo))) return D3DERR_INVALIDCALL; - *ppShader = ref(new D3D9PixelShader(this, module)); + *ppShader = ref(new D3D9PixelShader(this, module, pFunction, bytecodeLength)); return D3D_OK; } @@ -6312,12 +6316,13 @@ namespace dxvk { HRESULT D3D9DeviceEx::CreateShaderModule( D3D9CommonShader* pShaderModule, + uint32_t* pLength, VkShaderStageFlagBits ShaderStage, const DWORD* pShaderBytecode, const DxsoModuleInfo* pModuleInfo) { try { m_shaderModules->GetShaderModule(this, pShaderModule, - ShaderStage, pModuleInfo, pShaderBytecode); + pLength, ShaderStage, pModuleInfo, pShaderBytecode); return D3D_OK; } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index a815699e2..40dcc9557 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -981,6 +981,7 @@ namespace dxvk { HRESULT CreateShaderModule( D3D9CommonShader* pShaderModule, + uint32_t* pLength, VkShaderStageFlagBits ShaderStage, const DWORD* pShaderBytecode, const DxsoModuleInfo* pModuleInfo); diff --git a/src/d3d9/d3d9_shader.cpp b/src/d3d9/d3d9_shader.cpp index 2aa2f444e..6b22a26e0 100644 --- a/src/d3d9/d3d9_shader.cpp +++ b/src/d3d9/d3d9_shader.cpp @@ -17,8 +17,6 @@ namespace dxvk { const DxsoAnalysisInfo& AnalysisInfo, DxsoModule* pModule) { const uint32_t bytecodeLength = AnalysisInfo.bytecodeByteLength; - m_bytecode.resize(bytecodeLength); - std::memcpy(m_bytecode.data(), pShaderBytecode, bytecodeLength); const std::string name = Key.toString(); Logger::debug(str::format("Compiling shader ", name)); @@ -90,6 +88,7 @@ namespace dxvk { void D3D9ShaderModuleSet::GetShaderModule( D3D9DeviceEx* pDevice, D3D9CommonShader* pShaderModule, + uint32_t* pLength, VkShaderStageFlagBits ShaderStage, const DxsoModuleInfo* pDxbcModuleInfo, const void* pShaderBytecode) { @@ -105,6 +104,7 @@ namespace dxvk { throw DxvkError("GetShaderModule: Bytecode does not match shader stage"); DxsoAnalysisInfo info = module.analyze(); + *pLength = info.bytecodeByteLength; DxvkShaderKey lookupKey = DxvkShaderKey( ShaderStage, diff --git a/src/d3d9/d3d9_shader.h b/src/d3d9/d3d9_shader.h index fc281c502..c8705711d 100644 --- a/src/d3d9/d3d9_shader.h +++ b/src/d3d9/d3d9_shader.h @@ -40,10 +40,6 @@ namespace dxvk { return m_shader->debugName(); } - const std::vector& GetBytecode() const { - return m_bytecode; - } - const DxsoIsgn& GetIsgn() const { return m_isgn; } @@ -70,8 +66,6 @@ namespace dxvk { Rc m_shader; - std::vector m_bytecode; - }; /** @@ -88,9 +82,15 @@ namespace dxvk { D3D9Shader( D3D9DeviceEx* pDevice, - const D3D9CommonShader& CommonShader) + const D3D9CommonShader& CommonShader, + const void* pShaderBytecode, + uint32_t BytecodeLength) : D3D9DeviceChild( pDevice ) - , m_shader ( CommonShader ) { } + , m_shader ( CommonShader ) { + + m_bytecode.resize(BytecodeLength); + std::memcpy(m_bytecode.data(), pShaderBytecode, BytecodeLength); + } HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) { if (ppvObject == nullptr) @@ -113,15 +113,13 @@ namespace dxvk { if (pSizeOfData == nullptr) return D3DERR_INVALIDCALL; - const auto& bytecode = m_shader.GetBytecode(); - if (pOut == nullptr) { - *pSizeOfData = bytecode.size(); + *pSizeOfData = m_bytecode.size(); return D3D_OK; } - size_t copyAmount = std::min(size_t(*pSizeOfData), bytecode.size()); - std::memcpy(pOut, bytecode.data(), copyAmount); + size_t copyAmount = std::min(size_t(*pSizeOfData), m_bytecode.size()); + std::memcpy(pOut, m_bytecode.data(), copyAmount); return D3D_OK; } @@ -134,6 +132,8 @@ namespace dxvk { D3D9CommonShader m_shader; + std::vector m_bytecode; + }; // Needs their own classes and not usings for forward decl. @@ -144,8 +144,10 @@ namespace dxvk { D3D9VertexShader( D3D9DeviceEx* pDevice, - const D3D9CommonShader& CommonShader) - : D3D9Shader( pDevice, CommonShader ) { } + const D3D9CommonShader& CommonShader, + const void* pShaderBytecode, + uint32_t BytecodeLength) + : D3D9Shader( pDevice, CommonShader, pShaderBytecode, BytecodeLength ) { } }; @@ -155,8 +157,10 @@ namespace dxvk { D3D9PixelShader( D3D9DeviceEx* pDevice, - const D3D9CommonShader& CommonShader) - : D3D9Shader( pDevice, CommonShader ) { } + const D3D9CommonShader& CommonShader, + const void* pShaderBytecode, + uint32_t BytecodeLength) + : D3D9Shader( pDevice, CommonShader, pShaderBytecode, BytecodeLength ) { } }; @@ -175,6 +179,7 @@ namespace dxvk { void GetShaderModule( D3D9DeviceEx* pDevice, D3D9CommonShader* pShaderModule, + uint32_t* pLength, VkShaderStageFlagBits ShaderStage, const DxsoModuleInfo* pDxbcModuleInfo, const void* pShaderBytecode); From 1fcd5dc0af61914ff08cdab7e05050bf47c948b5 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 8 Aug 2022 14:56:03 +0200 Subject: [PATCH 0491/1348] [d3d9] Unmap stored shader bytecode --- src/d3d9/d3d9_device.cpp | 13 ++++++++-- src/d3d9/d3d9_device.h | 5 ++++ src/d3d9/d3d9_shader.h | 52 ++++++++++++++++++++++++---------------- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 507415710..99fb0e1b9 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -47,6 +47,7 @@ namespace dxvk { , m_adapter ( pAdapter ) , m_dxvkDevice ( dxvkDevice ) , m_memoryAllocator ( ) + , m_shaderAllocator ( ) , m_shaderModules ( new D3D9ShaderModuleSet ) , m_stagingBuffer ( dxvkDevice, StagingBufferSize ) , m_d3d9Options ( dxvkDevice, pParent->GetInstance()->config() ) @@ -2829,7 +2830,11 @@ namespace dxvk { &moduleInfo))) return D3DERR_INVALIDCALL; - *ppShader = ref(new D3D9VertexShader(this, module, pFunction, bytecodeLength)); + *ppShader = ref(new D3D9VertexShader(this, + &m_shaderAllocator, + module, + pFunction, + bytecodeLength)); return D3D_OK; } @@ -3160,7 +3165,11 @@ namespace dxvk { &moduleInfo))) return D3DERR_INVALIDCALL; - *ppShader = ref(new D3D9PixelShader(this, module, pFunction, bytecodeLength)); + *ppShader = ref(new D3D9PixelShader(this, + &m_shaderAllocator, + module, + pFunction, + bytecodeLength)); return D3D_OK; } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 40dcc9557..0df0496f3 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1158,6 +1158,11 @@ namespace dxvk { D3D9MemoryAllocator m_memoryAllocator; + // Second memory allocator used for D3D9 shader bytecode. + // Most games never access the stored bytecode, so putting that + // into the same chunks as texture memory would waste address space. + D3D9MemoryAllocator m_shaderAllocator; + uint32_t m_frameLatency = DefaultFrameLatency; D3D9Initializer* m_initializer = nullptr; diff --git a/src/d3d9/d3d9_shader.h b/src/d3d9/d3d9_shader.h index c8705711d..997d15259 100644 --- a/src/d3d9/d3d9_shader.h +++ b/src/d3d9/d3d9_shader.h @@ -3,6 +3,7 @@ #include "d3d9_resource.h" #include "../dxso/dxso_module.h" #include "d3d9_util.h" +#include "d3d9_mem.h" #include @@ -81,15 +82,19 @@ namespace dxvk { public: D3D9Shader( - D3D9DeviceEx* pDevice, - const D3D9CommonShader& CommonShader, - const void* pShaderBytecode, - uint32_t BytecodeLength) + D3D9DeviceEx* pDevice, + D3D9MemoryAllocator* pAllocator, + const D3D9CommonShader& CommonShader, + const void* pShaderBytecode, + uint32_t BytecodeLength) : D3D9DeviceChild( pDevice ) - , m_shader ( CommonShader ) { + , m_shader ( CommonShader ) + , m_bytecodeLength ( BytecodeLength ) { - m_bytecode.resize(BytecodeLength); - std::memcpy(m_bytecode.data(), pShaderBytecode, BytecodeLength); + m_bytecode = pAllocator->Alloc(BytecodeLength); + m_bytecode.Map(); + std::memcpy(m_bytecode.Ptr(), pShaderBytecode, BytecodeLength); + m_bytecode.Unmap(); } HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) { @@ -114,12 +119,14 @@ namespace dxvk { return D3DERR_INVALIDCALL; if (pOut == nullptr) { - *pSizeOfData = m_bytecode.size(); + *pSizeOfData = m_bytecodeLength; return D3D_OK; } - size_t copyAmount = std::min(size_t(*pSizeOfData), m_bytecode.size()); - std::memcpy(pOut, m_bytecode.data(), copyAmount); + m_bytecode.Map(); + uint32_t copyAmount = std::min(*pSizeOfData, m_bytecodeLength); + std::memcpy(pOut, m_bytecode.Ptr(), copyAmount); + m_bytecode.Unmap(); return D3D_OK; } @@ -132,7 +139,8 @@ namespace dxvk { D3D9CommonShader m_shader; - std::vector m_bytecode; + D3D9Memory m_bytecode; + uint32_t m_bytecodeLength; }; @@ -143,11 +151,12 @@ namespace dxvk { public: D3D9VertexShader( - D3D9DeviceEx* pDevice, - const D3D9CommonShader& CommonShader, - const void* pShaderBytecode, - uint32_t BytecodeLength) - : D3D9Shader( pDevice, CommonShader, pShaderBytecode, BytecodeLength ) { } + D3D9DeviceEx* pDevice, + D3D9MemoryAllocator* pAllocator, + const D3D9CommonShader& CommonShader, + const void* pShaderBytecode, + uint32_t BytecodeLength) + : D3D9Shader( pDevice, pAllocator, CommonShader, pShaderBytecode, BytecodeLength ) { } }; @@ -156,11 +165,12 @@ namespace dxvk { public: D3D9PixelShader( - D3D9DeviceEx* pDevice, - const D3D9CommonShader& CommonShader, - const void* pShaderBytecode, - uint32_t BytecodeLength) - : D3D9Shader( pDevice, CommonShader, pShaderBytecode, BytecodeLength ) { } + D3D9DeviceEx* pDevice, + D3D9MemoryAllocator* pAllocator, + const D3D9CommonShader& CommonShader, + const void* pShaderBytecode, + uint32_t BytecodeLength) + : D3D9Shader( pDevice, pAllocator, CommonShader, pShaderBytecode, BytecodeLength ) { } }; From d6253aeae6a413028f69ed7ad01c6ac977c65a6e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 9 Aug 2022 02:39:21 +0200 Subject: [PATCH 0492/1348] [dxvk] Order descriptors by type and binding Reduces the number of unique descriptor set layouts further, which may help with descriptor pool usage, and also makes branching more predictable for the CPU. --- src/dxvk/dxvk_pipelayout.cpp | 27 +++++++-------------------- src/dxvk/dxvk_pipelayout.h | 20 ++++---------------- 2 files changed, 11 insertions(+), 36 deletions(-) diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index e112ea78f..ff3b097ef 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -25,19 +25,8 @@ namespace dxvk { } - bool DxvkBindingInfo::canMerge(const DxvkBindingInfo& binding) const { - if ((stages & VK_SHADER_STAGE_FRAGMENT_BIT) != (binding.stages & VK_SHADER_STAGE_FRAGMENT_BIT)) - return false; - - return descriptorType == binding.descriptorType - && resourceBinding == binding.resourceBinding - && viewType == binding.viewType; - } - - - void DxvkBindingInfo::merge(const DxvkBindingInfo& binding) { - stages |= binding.stages; - access |= binding.access; + uint32_t DxvkBindingInfo::value() const { + return (uint32_t(descriptorType) << 24) | resourceBinding; } @@ -72,14 +61,12 @@ namespace dxvk { void DxvkBindingList::addBinding(const DxvkBindingInfo& binding) { - for (auto& b : m_bindings) { - if (b.canMerge(binding)) { - b.merge(binding); - return; - } - } + auto iter = m_bindings.begin(); - m_bindings.push_back(binding); + while (iter != m_bindings.end() && iter->value() <= binding.value()) + iter++; + + m_bindings.insert(iter, binding); } diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 1e8aa121c..f559e6c0f 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -43,24 +43,12 @@ namespace dxvk { uint32_t computeSetIndex() const; /** - * \brief Checks whether bindings can be merged + * \brief Numeric value of the binding * - * Bindings can be merged if they access the same resource with - * the same view and descriptor type and are part of the same - * descriptor set. - * \param [in] binding The binding to probe - * \returns \c true if the bindings can be merged + * Used when sorting bindings. + * \returns Numeric value */ - bool canMerge(const DxvkBindingInfo& binding) const; - - /** - * \brief Merges bindings - * - * Merges the stage and access flags of two - * otherwise identical binding declarations. - * \param [in] binding The binding to merge - */ - void merge(const DxvkBindingInfo& binding); + uint32_t value() const; /** * \brief Checks for equality From eddbe73ba4d48453d5e277526ba33c0b75e021ad Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 9 Aug 2022 02:44:05 +0200 Subject: [PATCH 0493/1348] [dxbc] Fix off-by-one error for primitive vertex counts Not sure if it's even possible to use this, but this was clearly a bug. --- src/dxbc/dxbc_util.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/dxbc/dxbc_util.cpp b/src/dxbc/dxbc_util.cpp index 848f8ad78..3d885fc9c 100644 --- a/src/dxbc/dxbc_util.cpp +++ b/src/dxbc/dxbc_util.cpp @@ -15,11 +15,11 @@ namespace dxvk { }; if (primitive >= DxbcPrimitive::Patch1) { - return static_cast(primitive) - - static_cast(DxbcPrimitive::Patch1); + return uint32_t(primitive) + - uint32_t(DxbcPrimitive::Patch1) + + 1u; } else { - return s_vertexCounts.at( - static_cast(primitive)); + return s_vertexCounts.at(uint32_t(primitive)); } } From 915b03ba7b0ec1a99c24a2493dfbcf1ff6b5f1d7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 9 Aug 2022 04:54:42 +0200 Subject: [PATCH 0494/1348] [dxvk] Add option to control pipeline lifetime tracking --- dxvk.conf | 14 ++++++++++++++ src/dxvk/dxvk_device.cpp | 7 +++++++ src/dxvk/dxvk_device.h | 6 ++++++ src/dxvk/dxvk_options.cpp | 1 + src/dxvk/dxvk_options.h | 3 +++ 5 files changed, 31 insertions(+) diff --git a/dxvk.conf b/dxvk.conf index 1cce94d8b..dba455426 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -286,6 +286,20 @@ # dxvk.enableGraphicsPipelineLibrary = Auto +# Controls pipeline lifetime tracking +# +# If enabled, pipeline libraries will be freed aggressively in order +# save memory and address space. Has no effect if graphics pipeline +# libraries are not supported or disabled. +# +# Supported values: +# - Auto: Enable tracking for 32-bit applications only +# - True: Always enable tracking +# - False: Always disable tracking + +# dxvk.trackPipelineLifetime = Auto + + # Sets enabled HUD elements # # Behaves like the DXVK_HUD environment variable if the diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 482e1d898..d8bd98a09 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -68,6 +68,13 @@ namespace dxvk { } + bool DxvkDevice::mustTrackPipelineLifetime() const { + bool result = env::is32BitHostPlatform(); + applyTristate(result, m_options.trackPipelineLifetime); + return result && canUseGraphicsPipelineLibrary(); + } + + DxvkFramebufferSize DxvkDevice::getDefaultFramebufferSize() const { return DxvkFramebufferSize { m_properties.core.properties.limits.maxFramebufferWidth, diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index d2096cdf2..cbc04041b 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -209,6 +209,12 @@ namespace dxvk { */ bool canUsePipelineCacheControl() const; + /** + * \brief Checks whether pipelines should be tracked + * \returns \c true if pipelines need to be tracked + */ + bool mustTrackPipelineLifetime() const; + /** * \brief Queries default framebuffer size * \returns Default framebuffer size diff --git a/src/dxvk/dxvk_options.cpp b/src/dxvk/dxvk_options.cpp index d251cbcf6..652bcc405 100644 --- a/src/dxvk/dxvk_options.cpp +++ b/src/dxvk/dxvk_options.cpp @@ -7,6 +7,7 @@ namespace dxvk { enableStateCache = config.getOption ("dxvk.enableStateCache", true); numCompilerThreads = config.getOption ("dxvk.numCompilerThreads", 0); enableGraphicsPipelineLibrary = config.getOption("dxvk.enableGraphicsPipelineLibrary", Tristate::Auto); + trackPipelineLifetime = config.getOption("dxvk.trackPipelineLifetime", Tristate::Auto); useRawSsbo = config.getOption("dxvk.useRawSsbo", Tristate::Auto); shrinkNvidiaHvvHeap = config.getOption ("dxvk.shrinkNvidiaHvvHeap", false); hud = config.getOption("dxvk.hud", ""); diff --git a/src/dxvk/dxvk_options.h b/src/dxvk/dxvk_options.h index c2f7f11ba..b3cd8a2db 100644 --- a/src/dxvk/dxvk_options.h +++ b/src/dxvk/dxvk_options.h @@ -21,6 +21,9 @@ namespace dxvk { /// Enable graphics pipeline library Tristate enableGraphicsPipelineLibrary; + /// Enables pipeline lifetime tracking + Tristate trackPipelineLifetime; + /// Shader-related options Tristate useRawSsbo; From 4bc2d713fbbba2950af81105e7e07602f0bf67a4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 14:25:34 +0200 Subject: [PATCH 0495/1348] [dxvk] Destroy shader pipeline libraries after initial compile on 32-bit This alone saves ~700 MiB of address space in the Resident Evil 6 main menu on Nvidia. --- src/dxvk/dxvk_shader.cpp | 80 +++++++++++++++++++++++++++++----------- src/dxvk/dxvk_shader.h | 6 +++ 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 71f8abc9c..c044b465f 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -915,10 +915,7 @@ namespace dxvk { const DxvkShaderPipelineLibraryCompileArgs& args) { std::lock_guard lock(m_mutex); - VkShaderStageFlagBits stage = VK_SHADER_STAGE_FRAGMENT_BIT; - - if (m_shader) - stage = m_shader->info().stage; + VkShaderStageFlagBits stage = getShaderStage(); VkPipeline& pipeline = (stage == VK_SHADER_STAGE_VERTEX_BIT && !args.depthClipEnable) ? m_pipelineNoDepthClip @@ -927,28 +924,54 @@ namespace dxvk { if (pipeline) return pipeline; - bool usesDefaultArgs = (args == DxvkShaderPipelineLibraryCompileArgs()); + pipeline = compileShaderPipelineLocked(args); + return pipeline; + } + + void DxvkShaderPipelineLibrary::compilePipeline() { + std::lock_guard lock(m_mutex); + + // Skip if a pipeline has already been compiled + if (m_pipeline) + return; + + // Compile the pipeline with default args + VkPipeline pipeline = compileShaderPipelineLocked( + DxvkShaderPipelineLibraryCompileArgs()); + + // On 32-bit, destroy the pipeline immediately in order to + // save memory. We should hit the driver's disk cache once + // we need to recreate the pipeline. + if (m_device->mustTrackPipelineLifetime()) { + auto vk = m_device->vkd(); + vk->vkDestroyPipeline(vk->device(), pipeline, nullptr); + + pipeline = VK_NULL_HANDLE; + } + + // Write back pipeline handle for future use + m_pipeline = pipeline; + } + + + VkPipeline DxvkShaderPipelineLibrary::compileShaderPipelineLocked( + const DxvkShaderPipelineLibraryCompileArgs& args) { + VkShaderStageFlagBits stage = getShaderStage(); + VkPipeline pipeline = VK_NULL_HANDLE; + + // Compile pipeline of the appropriate type switch (stage) { case VK_SHADER_STAGE_VERTEX_BIT: pipeline = compileVertexShaderPipeline(args); - - if (usesDefaultArgs) - m_stats->numGraphicsLibraries += 1; break; case VK_SHADER_STAGE_FRAGMENT_BIT: pipeline = compileFragmentShaderPipeline(); - - if (usesDefaultArgs) - m_stats->numGraphicsLibraries += 1; break; case VK_SHADER_STAGE_COMPUTE_BIT: pipeline = compileComputeShaderPipeline(); - - if (usesDefaultArgs) - m_stats->numComputePipelines += 1; break; default: @@ -956,18 +979,21 @@ namespace dxvk { return VK_NULL_HANDLE; } + // Increment stat counter the first time this + // shader pipeline gets compiled successfully + if (!m_compiledOnce && pipeline) { + if (stage == VK_SHADER_STAGE_COMPUTE_BIT) + m_stats->numComputePipelines += 1; + else + m_stats->numGraphicsLibraries += 1; + + m_compiledOnce = true; + } + return pipeline; } - void DxvkShaderPipelineLibrary::compilePipeline() { - // Just compile the pipeline with default args. Implicitly skips - // this step if another thread has compiled the pipeline in the - // meantime, in order to avoid duplicate work. - getPipelineHandle(DxvkShaderPipelineLibraryCompileArgs()); - } - - VkPipeline DxvkShaderPipelineLibrary::compileVertexShaderPipeline( const DxvkShaderPipelineLibraryCompileArgs& args) { auto vk = m_device->vkd(); @@ -1175,4 +1201,14 @@ namespace dxvk { vk->device(), &info, &m_identifier); } + + VkShaderStageFlagBits DxvkShaderPipelineLibrary::getShaderStage() const { + VkShaderStageFlagBits stage = VK_SHADER_STAGE_FRAGMENT_BIT; + + if (m_shader != nullptr) + stage = m_shader->info().stage; + + return stage; + } + } \ No newline at end of file diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 6363e3a41..6086b1c87 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -425,10 +425,14 @@ namespace dxvk { dxvk::mutex m_mutex; VkPipeline m_pipeline = VK_NULL_HANDLE; VkPipeline m_pipelineNoDepthClip = VK_NULL_HANDLE; + bool m_compiledOnce = false; dxvk::mutex m_identifierMutex; VkShaderModuleIdentifierEXT m_identifier = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT }; + VkPipeline compileShaderPipelineLocked( + const DxvkShaderPipelineLibraryCompileArgs& args); + VkPipeline compileVertexShaderPipeline( const DxvkShaderPipelineLibraryCompileArgs& args); @@ -444,6 +448,8 @@ namespace dxvk { void generateModuleIdentifierLocked( const SpirvCodeBuffer& spirvCode); + VkShaderStageFlagBits getShaderStage() const; + }; } \ No newline at end of file From b97dba3712d63dd165188d551153179024c40ec5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 15:11:51 +0200 Subject: [PATCH 0496/1348] [dxvk] Use shader module identifier for subsequent pipeline libary compiles Should further reduce the hit we take from destroying pipeline libraries. --- src/dxvk/dxvk_shader.cpp | 155 +++++++++++++++++++++++---------------- src/dxvk/dxvk_shader.h | 22 ++++-- 2 files changed, 108 insertions(+), 69 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index c044b465f..4d7c468db 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -960,28 +960,24 @@ namespace dxvk { VkShaderStageFlagBits stage = getShaderStage(); VkPipeline pipeline = VK_NULL_HANDLE; - // Compile pipeline of the appropriate type - switch (stage) { - case VK_SHADER_STAGE_VERTEX_BIT: - pipeline = compileVertexShaderPipeline(args); - break; - - case VK_SHADER_STAGE_FRAGMENT_BIT: - pipeline = compileFragmentShaderPipeline(); - break; - - case VK_SHADER_STAGE_COMPUTE_BIT: - pipeline = compileComputeShaderPipeline(); - break; - - default: - // Should be unreachable - return VK_NULL_HANDLE; + // If this is not the first time we're compiling the pipeline, + // try to get a cache hit using the shader module identifier + // so that we don't have to decompress our SPIR-V shader again. + if (m_compiledOnce && canUsePipelineCacheControl()) { + pipeline = this->compileShaderPipeline(args, stage, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT); } + if (!pipeline) + pipeline = this->compileShaderPipeline(args, stage, 0); + + // Well that didn't work + if (!pipeline) + return VK_NULL_HANDLE; + // Increment stat counter the first time this // shader pipeline gets compiled successfully - if (!m_compiledOnce && pipeline) { + if (!m_compiledOnce) { if (stage == VK_SHADER_STAGE_COMPUTE_BIT) m_stats->numComputePipelines += 1; else @@ -994,16 +990,56 @@ namespace dxvk { } - VkPipeline DxvkShaderPipelineLibrary::compileVertexShaderPipeline( - const DxvkShaderPipelineLibraryCompileArgs& args) { - auto vk = m_device->vkd(); - - SpirvCodeBuffer spirvCode = this->getShaderCode(); - this->generateModuleIdentifier(spirvCode); - - // Set up shader stage info + VkPipeline DxvkShaderPipelineLibrary::compileShaderPipeline( + const DxvkShaderPipelineLibraryCompileArgs& args, + VkShaderStageFlagBits stage, + VkPipelineCreateFlags flags) { DxvkShaderStageInfo stageInfo(m_device); - stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, std::move(spirvCode), nullptr); + + { std::lock_guard lock(m_identifierMutex); + + if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) { + // Fail if we have no idenfitier for whatever reason, caller + // should fall back to the slow path if this happens + if (!m_identifier.identifierSize) + return VK_NULL_HANDLE; + + stageInfo.addStage(stage, m_identifier, nullptr); + } else { + // Decompress code and generate identifier as needed + SpirvCodeBuffer spirvCode = this->getShaderCode(); + + if (!m_identifier.identifierSize) + this->generateModuleIdentifierLocked(spirvCode); + + stageInfo.addStage(stage, std::move(spirvCode), nullptr); + } + } + + switch (stage) { + case VK_SHADER_STAGE_VERTEX_BIT: + return compileVertexShaderPipeline(args, stageInfo, flags); + break; + + case VK_SHADER_STAGE_FRAGMENT_BIT: + return compileFragmentShaderPipeline(stageInfo, flags); + break; + + case VK_SHADER_STAGE_COMPUTE_BIT: + return compileComputeShaderPipeline(stageInfo, flags); + + default: + // Should be unreachable + return VK_NULL_HANDLE; + } + } + + + VkPipeline DxvkShaderPipelineLibrary::compileVertexShaderPipeline( + const DxvkShaderPipelineLibraryCompileArgs& args, + const DxvkShaderStageInfo& stageInfo, + VkPipelineCreateFlags flags) { + auto vk = m_device->vkd(); // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. @@ -1047,7 +1083,7 @@ namespace dxvk { libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT; VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; - info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | flags; info.stageCount = stageInfo.getStageCount(); info.pStages = stageInfo.getStageInfos(); info.pViewportState = &vpInfo; @@ -1057,24 +1093,20 @@ namespace dxvk { info.basePipelineIndex = -1; VkPipeline pipeline = VK_NULL_HANDLE; + VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline); - if (vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline)) - throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); + if (vr && !(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT)) + throw DxvkError(str::format("DxvkShaderPipelineLibrary: Failed to create vertex shader pipeline: ", vr)); return pipeline; } - VkPipeline DxvkShaderPipelineLibrary::compileFragmentShaderPipeline() { + VkPipeline DxvkShaderPipelineLibrary::compileFragmentShaderPipeline( + const DxvkShaderStageInfo& stageInfo, + VkPipelineCreateFlags flags) { auto vk = m_device->vkd(); - SpirvCodeBuffer spirvCode = this->getShaderCode(); - this->generateModuleIdentifier(spirvCode); - - // Set up shader stage info with the given code - DxvkShaderStageInfo stageInfo(m_device); - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, std::move(spirvCode), nullptr); - // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. uint32_t dynamicStateCount = 0; @@ -1120,7 +1152,7 @@ namespace dxvk { libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT; VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; - info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | flags; info.stageCount = stageInfo.getStageCount(); info.pStages = stageInfo.getStageInfos(); info.pDepthStencilState = &dsInfo; @@ -1132,34 +1164,32 @@ namespace dxvk { info.pMultisampleState = &msInfo; VkPipeline pipeline = VK_NULL_HANDLE; + VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline); - if (vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline)) - throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); + if (vr && !(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT)) + throw DxvkError(str::format("DxvkShaderPipelineLibrary: Failed to create fragment shader pipeline: ", vr)); return pipeline; } - VkPipeline DxvkShaderPipelineLibrary::compileComputeShaderPipeline() { + VkPipeline DxvkShaderPipelineLibrary::compileComputeShaderPipeline( + const DxvkShaderStageInfo& stageInfo, + VkPipelineCreateFlags flags) { auto vk = m_device->vkd(); - SpirvCodeBuffer spirvCode = this->getShaderCode(); - this->generateModuleIdentifier(spirvCode); - - // Set up shader stage info - DxvkShaderStageInfo stageInfo(m_device); - stageInfo.addStage(VK_SHADER_STAGE_COMPUTE_BIT, std::move(spirvCode), nullptr); - // Compile the compute pipeline as normal VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; + info.flags = flags; info.stage = *stageInfo.getStageInfos(); info.layout = m_layout->getPipelineLayout(false); info.basePipelineIndex = -1; VkPipeline pipeline = VK_NULL_HANDLE; + VkResult vr = vk->vkCreateComputePipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline); - if (vk->vkCreateComputePipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline)) - throw DxvkError("DxvkShaderPipelineLibrary: Failed to create compute pipeline"); + if (vr && !(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT)) + throw DxvkError(str::format("DxvkShaderPipelineLibrary: Failed to create compute shader pipeline: ", vr)); return pipeline; } @@ -1177,22 +1207,13 @@ namespace dxvk { } - void DxvkShaderPipelineLibrary::generateModuleIdentifier( - const SpirvCodeBuffer& spirvCode) { - if (!m_device->features().extShaderModuleIdentifier.shaderModuleIdentifier) - return; - - std::lock_guard lock(m_identifierMutex); - - if (!m_identifier.identifierSize) - this->generateModuleIdentifierLocked(spirvCode); - } - - void DxvkShaderPipelineLibrary::generateModuleIdentifierLocked( const SpirvCodeBuffer& spirvCode) { auto vk = m_device->vkd(); + if (!canUsePipelineCacheControl()) + return; + VkShaderModuleCreateInfo info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; info.codeSize = spirvCode.size(); info.pCode = spirvCode.data(); @@ -1211,4 +1232,12 @@ namespace dxvk { return stage; } + + bool DxvkShaderPipelineLibrary::canUsePipelineCacheControl() const { + const auto& features = m_device->features(); + + return features.vk13.pipelineCreationCacheControl + && features.extShaderModuleIdentifier.shaderModuleIdentifier; + } + } \ No newline at end of file diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 6086b1c87..a794e0361 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -433,23 +433,33 @@ namespace dxvk { VkPipeline compileShaderPipelineLocked( const DxvkShaderPipelineLibraryCompileArgs& args); + VkPipeline compileShaderPipeline( + const DxvkShaderPipelineLibraryCompileArgs& args, + VkShaderStageFlagBits stage, + VkPipelineCreateFlags flags); + VkPipeline compileVertexShaderPipeline( - const DxvkShaderPipelineLibraryCompileArgs& args); + const DxvkShaderPipelineLibraryCompileArgs& args, + const DxvkShaderStageInfo& stageInfo, + VkPipelineCreateFlags flags); - VkPipeline compileFragmentShaderPipeline(); + VkPipeline compileFragmentShaderPipeline( + const DxvkShaderStageInfo& stageInfo, + VkPipelineCreateFlags flags); - VkPipeline compileComputeShaderPipeline(); + VkPipeline compileComputeShaderPipeline( + const DxvkShaderStageInfo& stageInfo, + VkPipelineCreateFlags flags); SpirvCodeBuffer getShaderCode() const; - void generateModuleIdentifier( - const SpirvCodeBuffer& spirvCode); - void generateModuleIdentifierLocked( const SpirvCodeBuffer& spirvCode); VkShaderStageFlagBits getShaderStage() const; + bool canUsePipelineCacheControl() const; + }; } \ No newline at end of file From 1f9db49727f77f2786a799c63ec4da8f938ed03f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 16:10:36 +0200 Subject: [PATCH 0497/1348] [dxvk] Change member order in pipeline manager Ensures that pipelines are destroyed before pipeline libraries. --- src/dxvk/dxvk_pipemanager.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 9e6ed35e4..5661dd86f 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -237,16 +237,6 @@ namespace dxvk { DxvkBindingLayoutObjects, DxvkHash, DxvkEq> m_pipelineLayouts; - std::unordered_map< - DxvkComputePipelineShaders, - DxvkComputePipeline, - DxvkHash, DxvkEq> m_computePipelines; - - std::unordered_map< - DxvkGraphicsPipelineShaders, - DxvkGraphicsPipeline, - DxvkHash, DxvkEq> m_graphicsPipelines; - std::unordered_map< DxvkGraphicsPipelineVertexInputState, DxvkGraphicsPipelineVertexInputLibrary, @@ -262,6 +252,16 @@ namespace dxvk { DxvkShaderPipelineLibrary, DxvkHash, DxvkEq> m_shaderLibraries; + std::unordered_map< + DxvkComputePipelineShaders, + DxvkComputePipeline, + DxvkHash, DxvkEq> m_computePipelines; + + std::unordered_map< + DxvkGraphicsPipelineShaders, + DxvkGraphicsPipeline, + DxvkHash, DxvkEq> m_graphicsPipelines; + DxvkBindingSetLayout* createDescriptorSetLayout( const DxvkBindingSetLayoutKey& key); From 764de6ff82d187362d9b4964111662f76d4eadb5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 16:12:26 +0200 Subject: [PATCH 0498/1348] [dxvk] Add use counter to pipeline libraries And destroy Vulkan pipeline objects once the counter reaches zero. --- src/dxvk/dxvk_compute.cpp | 5 ++++- src/dxvk/dxvk_graphics.cpp | 10 +++++++--- src/dxvk/dxvk_shader.cpp | 31 ++++++++++++++++++++++++++----- src/dxvk/dxvk_shader.h | 17 +++++++++++++++-- 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index 0006ce145..fdc7394d2 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -30,6 +30,9 @@ namespace dxvk { DxvkComputePipeline::~DxvkComputePipeline() { + if (m_libraryHandle) + m_library->releasePipelineHandle(); + for (const auto& instance : m_pipelines) this->destroyPipeline(instance.handle); } @@ -45,7 +48,7 @@ namespace dxvk { // Retrieve actual pipeline handle on first use. This // may wait for an ongoing compile job to finish, or // compile the pipeline immediately on the calling thread. - m_libraryHandle = m_library->getPipelineHandle( + m_libraryHandle = m_library->acquirePipelineHandle( DxvkShaderPipelineLibraryCompileArgs()); return m_libraryHandle; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 1070859d8..dbd8c7d02 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -880,9 +880,13 @@ namespace dxvk { DxvkGraphicsPipeline::~DxvkGraphicsPipeline() { - for (const auto& instance : m_fastPipelines) + for (const auto& instance : m_fastPipelines) { this->destroyPipeline(instance.second); + m_vsLibrary->releasePipelineHandle(); + m_fsLibrary->releasePipelineHandle(); + } + for (const auto& instance : m_basePipelines) this->destroyPipeline(instance.second); } @@ -1102,8 +1106,8 @@ namespace dxvk { std::array libraries = {{ key.viLibrary->getHandle(), - m_vsLibrary->getPipelineHandle(key.args), - m_fsLibrary->getPipelineHandle(key.args), + m_vsLibrary->acquirePipelineHandle(key.args), + m_fsLibrary->acquirePipelineHandle(key.args), key.foLibrary->getHandle(), }}; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 4d7c468db..d5eba8499 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -890,10 +890,7 @@ namespace dxvk { DxvkShaderPipelineLibrary::~DxvkShaderPipelineLibrary() { - auto vk = m_device->vkd(); - - vk->vkDestroyPipeline(vk->device(), m_pipeline, nullptr); - vk->vkDestroyPipeline(vk->device(), m_pipelineNoDepthClip, nullptr); + this->destroyShaderPipelinesLocked(); } @@ -911,10 +908,13 @@ namespace dxvk { } - VkPipeline DxvkShaderPipelineLibrary::getPipelineHandle( + VkPipeline DxvkShaderPipelineLibrary::acquirePipelineHandle( const DxvkShaderPipelineLibraryCompileArgs& args) { std::lock_guard lock(m_mutex); + if (m_device->mustTrackPipelineLifetime()) + m_useCount += 1; + VkShaderStageFlagBits stage = getShaderStage(); VkPipeline& pipeline = (stage == VK_SHADER_STAGE_VERTEX_BIT && !args.depthClipEnable) @@ -929,6 +929,16 @@ namespace dxvk { } + void DxvkShaderPipelineLibrary::releasePipelineHandle() { + if (m_device->mustTrackPipelineLifetime()) { + std::lock_guard lock(m_mutex); + + if (!(--m_useCount)) + this->destroyShaderPipelinesLocked(); + } + } + + void DxvkShaderPipelineLibrary::compilePipeline() { std::lock_guard lock(m_mutex); @@ -955,6 +965,17 @@ namespace dxvk { } + void DxvkShaderPipelineLibrary::destroyShaderPipelinesLocked() { + auto vk = m_device->vkd(); + + vk->vkDestroyPipeline(vk->device(), m_pipeline, nullptr); + vk->vkDestroyPipeline(vk->device(), m_pipelineNoDepthClip, nullptr); + + m_pipeline = VK_NULL_HANDLE; + m_pipelineNoDepthClip = VK_NULL_HANDLE; + } + + VkPipeline DxvkShaderPipelineLibrary::compileShaderPipelineLocked( const DxvkShaderPipelineLibraryCompileArgs& args) { VkShaderStageFlagBits stage = getShaderStage(); diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index a794e0361..3c273a28e 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -396,16 +396,26 @@ namespace dxvk { VkShaderModuleIdentifierEXT getModuleIdentifier(); /** - * \brief Queries pipeline handle for the given set of arguments + * \brief Acquires pipeline handle for the given set of arguments * * Either returns an already compiled pipeline library object, or * performs the compilation step if that has not happened yet. + * Increments the use count by one. * \param [in] args Compile arguments * \returns Vulkan pipeline handle */ - VkPipeline getPipelineHandle( + VkPipeline acquirePipelineHandle( const DxvkShaderPipelineLibraryCompileArgs& args); + /** + * \brief Releases pipeline + * + * Decrements the use count by 1. If the use count reaches 0, + * any previously compiled pipeline library object may be + * destroyed in order to save memory. + */ + void releasePipelineHandle(); + /** * \brief Compiles the pipeline with default arguments * @@ -425,11 +435,14 @@ namespace dxvk { dxvk::mutex m_mutex; VkPipeline m_pipeline = VK_NULL_HANDLE; VkPipeline m_pipelineNoDepthClip = VK_NULL_HANDLE; + uint32_t m_useCount = 0u; bool m_compiledOnce = false; dxvk::mutex m_identifierMutex; VkShaderModuleIdentifierEXT m_identifier = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT }; + void destroyShaderPipelinesLocked(); + VkPipeline compileShaderPipelineLocked( const DxvkShaderPipelineLibraryCompileArgs& args); From ab1d629961c7902d1171f6c6fc08ad275b47058d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 8 Aug 2022 16:37:47 +0200 Subject: [PATCH 0499/1348] [dxvk] Implement lifetime tracking for graphics pipelines --- src/dxvk/dxvk_cmdlist.cpp | 7 +++ src/dxvk/dxvk_cmdlist.h | 14 +++++- src/dxvk/dxvk_context.cpp | 8 ++++ src/dxvk/dxvk_context_state.h | 3 +- src/dxvk/dxvk_graphics.cpp | 80 +++++++++++++++++++++++++++++------ src/dxvk/dxvk_graphics.h | 28 ++++++++++-- src/dxvk/dxvk_pipemanager.cpp | 7 ++- 7 files changed, 128 insertions(+), 19 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 107850753..adff122d3 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -219,11 +219,18 @@ namespace dxvk { m_signalTracker.reset(); m_statCounters.reset(); + // Recycle descriptor pools for (const auto& descriptorPools : m_descriptorPools) descriptorPools.second->recycleDescriptorPool(descriptorPools.first); m_descriptorPools.clear(); + // Release pipelines + for (auto pipeline : m_pipelines) + pipeline->releasePipeline(); + + m_pipelines.clear(); + m_waitSemaphores.clear(); m_signalSemaphores.clear(); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 1e8625396..f4492a063 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -8,6 +8,7 @@ #include "dxvk_fence.h" #include "dxvk_gpu_event.h" #include "dxvk_gpu_query.h" +#include "dxvk_graphics.h" #include "dxvk_lifetime.h" #include "dxvk_limits.h" #include "dxvk_pipelayout.h" @@ -30,7 +31,7 @@ namespace dxvk { }; using DxvkCmdBufferFlags = Flags; - + /** * \brief Queue submission info * @@ -176,6 +177,15 @@ namespace dxvk { m_gpuQueryTracker.trackQuery(handle); } + /** + * \brief Tracks a graphics pipeline + * \param [in] pipeline Pipeline + */ + void trackGraphicsPipeline(DxvkGraphicsPipeline* pipeline) { + pipeline->acquirePipeline(); + m_pipelines.push_back(pipeline); + } + /** * \brief Queues signal * @@ -822,6 +832,8 @@ namespace dxvk { Rc, Rc>> m_descriptorPools; + std::vector m_pipelines; + VkCommandBuffer getCmdBuffer(DxvkCmdBuffer cmdBuffer) const { if (cmdBuffer == DxvkCmdBuffer::ExecBuffer) return m_execBuffer; if (cmdBuffer == DxvkCmdBuffer::InitBuffer) return m_initBuffer; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 48eb05f57..56778c045 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -49,6 +49,11 @@ namespace dxvk { if (m_device->features().extTransformFeedback.transformFeedback) m_globalRwGraphicsBarrier.access |= VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT; + + // Store the lifetime tracking bit as a context feature so + // that we don't have to scan device features at draw time + if (m_device->mustTrackPipelineLifetime()) + m_features.set(DxvkContextFeature::TrackGraphicsPipeline); } @@ -4484,6 +4489,9 @@ namespace dxvk { return false; } + if (m_features.test(DxvkContextFeature::TrackGraphicsPipeline)) + m_cmd->trackGraphicsPipeline(newPipeline); + if (unlikely(newPipeline->getSpecConstantMask() != m_state.gp.constants.mask)) this->resetSpecConstants(newPipeline->getSpecConstantMask()); diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index d0b4d5630..c13d996ca 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -60,7 +60,8 @@ namespace dxvk { /** * \brief Context feature bits */ - enum class DxvkContextFeature { + enum class DxvkContextFeature : uint32_t { + TrackGraphicsPipeline, FeatureCount }; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index dbd8c7d02..c0ecbbb40 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -880,15 +880,8 @@ namespace dxvk { DxvkGraphicsPipeline::~DxvkGraphicsPipeline() { - for (const auto& instance : m_fastPipelines) { - this->destroyPipeline(instance.second); - - m_vsLibrary->releasePipelineHandle(); - m_fsLibrary->releasePipelineHandle(); - } - - for (const auto& instance : m_basePipelines) - this->destroyPipeline(instance.second); + this->destroyBasePipelines(); + this->destroyOptimizedPipelines(); } @@ -915,7 +908,7 @@ namespace dxvk { return std::make_pair(VK_NULL_HANDLE, DxvkGraphicsPipelineType::FastPipeline); // Prevent other threads from adding new instances and check again - std::lock_guard lock(m_mutex); + std::unique_lock lock(m_mutex); instance = this->findInstance(state); if (!instance) { @@ -924,6 +917,10 @@ namespace dxvk { bool canCreateBasePipeline = this->canCreateBasePipeline(state); instance = this->createInstance(state, canCreateBasePipeline); + // Unlock here since we may dispatch the pipeline to a worker, + // which will then acquire it to increment the use counter. + lock.unlock(); + // If necessary, compile an optimized pipeline variant if (!instance->fastHandle.load()) m_workers->compileGraphicsPipeline(this, state); @@ -965,7 +962,7 @@ namespace dxvk { return; // Prevent other threads from adding new instances and check again - std::lock_guard lock(m_mutex); + std::unique_lock lock(m_mutex); instance = this->findInstance(state); if (!instance) @@ -987,6 +984,45 @@ namespace dxvk { } + void DxvkGraphicsPipeline::acquirePipeline() { + if (!m_device->mustTrackPipelineLifetime()) + return; + + // We need to lock here to make sure that any ongoing pipeline + // destruction finishes before the calling thread can access the + // pipeline, and that no pipelines get destroyed afterwards. + std::unique_lock lock(m_mutex); + m_useCount += 1; + } + + + void DxvkGraphicsPipeline::releasePipeline() { + if (!m_device->mustTrackPipelineLifetime()) + return; + + std::unique_lock lock(m_mutex); + + if (!(--m_useCount)) { + // Don't destroy base pipelines if that's all we're going to + // use, since that would pretty much ruin the experience. + if (m_device->config().enableGraphicsPipelineLibrary == Tristate::True) + return; + + // Exit early if there's nothing to do + if (m_basePipelines.empty()) + return; + + // Remove any base pipeline references, but + // keep the optimized pipelines around. + for (auto& entry : m_pipelines) + entry.baseHandle.store(VK_NULL_HANDLE); + + // Destroy the actual Vulkan pipelines + this->destroyBasePipelines(); + } + } + + DxvkGraphicsPipelineInstance* DxvkGraphicsPipeline::createInstance( const DxvkGraphicsPipelineStateInfo& state, bool doCreateBasePipeline) { @@ -1220,7 +1256,27 @@ namespace dxvk { } - void DxvkGraphicsPipeline::destroyPipeline(VkPipeline pipeline) const { + void DxvkGraphicsPipeline::destroyBasePipelines() { + for (const auto& instance : m_basePipelines) { + this->destroyVulkanPipeline(instance.second); + + m_vsLibrary->releasePipelineHandle(); + m_fsLibrary->releasePipelineHandle(); + } + + m_basePipelines.clear(); + } + + + void DxvkGraphicsPipeline::destroyOptimizedPipelines() { + for (const auto& instance : m_fastPipelines) + this->destroyVulkanPipeline(instance.second); + + m_fastPipelines.clear(); + } + + + void DxvkGraphicsPipeline::destroyVulkanPipeline(VkPipeline pipeline) const { auto vk = m_device->vkd(); vk->vkDestroyPipeline(vk->device(), pipeline, nullptr); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 4c234f812..cfc424cd7 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -535,7 +535,24 @@ namespace dxvk { */ void compilePipeline( const DxvkGraphicsPipelineStateInfo& state); - + + /** + * \brief Acquires the pipeline + * + * Increments the use count by one and prevents any Vulkan + * pipelines from being destroyed. Must be called before + * \ref getPipelineHandle or \ref compilePipeline. + */ + void acquirePipeline(); + + /** + * \brief Releases the pipeline + * + * Decrements the use count by one. If the counter reaches + * zero, any Vulkan pipeline objects may be destroyed. + */ + void releasePipeline(); + private: DxvkDevice* m_device; @@ -560,11 +577,12 @@ namespace dxvk { alignas(CACHE_LINE_SIZE) dxvk::mutex m_mutex; sync::List m_pipelines; + uint32_t m_useCount = 0; std::unordered_map< DxvkGraphicsPipelineBaseInstanceKey, VkPipeline, DxvkHash, DxvkEq> m_basePipelines; - + alignas(CACHE_LINE_SIZE) dxvk::mutex m_fastMutex; std::unordered_map< @@ -595,7 +613,11 @@ namespace dxvk { const DxvkGraphicsPipelineFastInstanceKey& key, VkPipelineCreateFlags flags) const; - void destroyPipeline( + void destroyBasePipelines(); + + void destroyOptimizedPipelines(); + + void destroyVulkanPipeline( VkPipeline pipeline) const; SpirvCodeBuffer getShaderCode( diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 589f095f6..426443d75 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -64,6 +64,7 @@ namespace dxvk { std::unique_lock lock(m_queueLock); this->startWorkers(); + pipeline->acquirePipeline(); m_pendingTasks += 1; PipelineEntry e = { }; @@ -148,10 +149,12 @@ namespace dxvk { } if (p) { - if (p->computePipeline) + if (p->computePipeline) { p->computePipeline->compilePipeline(p->computeState); - else if (p->graphicsPipeline) + } else if (p->graphicsPipeline) { p->graphicsPipeline->compilePipeline(p->graphicsState); + p->graphicsPipeline->releasePipeline(); + } m_pendingTasks -= 1; } From 8c3a44cac418955853b44acf584644e10bd6163a Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 12:05:23 +0100 Subject: [PATCH 0500/1348] [util] Add stubs for GDI functions on other platforms --- src/util/util_gdi.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/util/util_gdi.cpp b/src/util/util_gdi.cpp index 901dd05ca..fd5c3c327 100644 --- a/src/util/util_gdi.cpp +++ b/src/util/util_gdi.cpp @@ -3,7 +3,8 @@ namespace dxvk { - HMODULE GetGDIModule() { +#ifdef _WIN32 + static HMODULE GetGDIModule() { static HMODULE module = LoadLibraryA("gdi32.dll"); return module; } @@ -29,5 +30,16 @@ namespace dxvk { Logger::warn("D3DKMTDestroyDCFromMemory: Unable to query proc address."); return -1; } +#else + NTSTATUS D3DKMTCreateDCFromMemory(D3DKMT_CREATEDCFROMMEMORY* Arg1) { + Logger::warn("D3DKMTCreateDCFromMemory: Not available on this platform."); + return -1; + } + + NTSTATUS D3DKMTDestroyDCFromMemory(D3DKMT_DESTROYDCFROMMEMORY* Arg1) { + Logger::warn("D3DKMTDestroyDCFromMemory: Not available on this platform."); + return -1; + } +#endif } \ No newline at end of file From d9000485ea6a0143215f08422f7ea22ae4ab335f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 12:05:47 +0100 Subject: [PATCH 0501/1348] [util] Add stubs for shared resources on other platforms --- src/util/util_shared_res.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/util/util_shared_res.cpp b/src/util/util_shared_res.cpp index d6ff1423c..2a86da717 100644 --- a/src/util/util_shared_res.cpp +++ b/src/util/util_shared_res.cpp @@ -1,9 +1,13 @@ #include "util_shared_res.h" +#include "log/log.h" -#include "winioctl.h" +#ifdef _WIN32 +#include +#endif namespace dxvk { +#ifdef _WIN32 #define IOCTL_SHARED_GPU_RESOURCE_OPEN CTL_CODE(FILE_DEVICE_VIDEO, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS) HANDLE openKmtHandle(HANDLE kmt_handle) { @@ -42,5 +46,21 @@ namespace dxvk { *metadataSize = retSize; return ret; } +#else + HANDLE openKmtHandle(HANDLE kmt_handle) { + Logger::warn("openKmtHandle: Shared resources not available on this platform."); + return INVALID_HANDLE_VALUE; + } + + bool setSharedMetadata(HANDLE handle, void *buf, uint32_t bufSize) { + Logger::warn("setSharedMetadata: Shared resources not available on this platform."); + return false; + } + + bool getSharedMetadata(HANDLE handle, void *buf, uint32_t bufSize, uint32_t *metadataSize) { + Logger::warn("getSharedMetadata: Shared resources not available on this platform."); + return false; + } +#endif } From 5de058e14aebab9c24fd0f6e9563d316a9b972c3 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 12:13:23 +0100 Subject: [PATCH 0502/1348] [util] Introduce topath helper Manages converting strings to the right type for paths per-platform --- src/util/util_string.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/util/util_string.h b/src/util/util_string.h index 95addf2b6..114bf63ef 100644 --- a/src/util/util_string.h +++ b/src/util/util_string.h @@ -176,6 +176,12 @@ namespace dxvk::str { * \returns Wide string object */ std::wstring tows(const char* mbs); + +#ifdef _WIN32 + inline std::wstring topath(const char* mbs) { return tows(mbs); } +#else + inline std::string topath(const char* mbs) { return std::string(mbs); } +#endif inline void format1(std::stringstream&) { } From 50018de483f12b21ee1f5247d7b35015c0f1e8ab Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 12:13:43 +0100 Subject: [PATCH 0503/1348] [util] Use topath helper for fstreams --- src/util/config/config.cpp | 2 +- src/util/log/log.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index a80df9ce9..151fc0543 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -889,7 +889,7 @@ namespace dxvk { filePath = "dxvk.conf"; // Open the file if it exists - std::ifstream stream(str::tows(filePath.c_str()).c_str()); + std::ifstream stream(str::topath(filePath.c_str()).c_str()); if (!stream) return config; diff --git a/src/util/log/log.cpp b/src/util/log/log.cpp index 59c9e6050..b3eaa37ad 100644 --- a/src/util/log/log.cpp +++ b/src/util/log/log.cpp @@ -10,7 +10,7 @@ namespace dxvk { auto path = getFileName(file_name); if (!path.empty()) - m_fileStream = std::ofstream(str::tows(path.c_str()).c_str()); + m_fileStream = std::ofstream(str::topath(path.c_str()).c_str()); } } From 8580bb32ca243d94ee27ce9f4ac272fb9a738c62 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 12:15:21 +0100 Subject: [PATCH 0504/1348] [vulkan] Only define VK_USE_PLATFORM_WIN32_KHR on Windows --- src/vulkan/vulkan_loader.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 6f469c650..841a0f12a 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -3,7 +3,9 @@ #include "../util/rc/util_rc.h" #include "../util/rc/util_rc_ptr.h" +#ifdef _WIN32 #define VK_USE_PLATFORM_WIN32_KHR 1 +#endif #include #define VULKAN_FN(name) \ From 59441b1ff568c181afcf0cc3bdd854df21e1f885 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Tue, 9 Aug 2022 14:47:19 -0500 Subject: [PATCH 0505/1348] [dxgi] Also support use after free in IDXGISwapChain::SetFullscreenState() --- src/dxgi/dxgi_swapchain_dispatcher.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dxgi/dxgi_swapchain_dispatcher.h b/src/dxgi/dxgi_swapchain_dispatcher.h index 4ef50d046..c8a503b38 100644 --- a/src/dxgi/dxgi_swapchain_dispatcher.h +++ b/src/dxgi/dxgi_swapchain_dispatcher.h @@ -224,7 +224,9 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE SetFullscreenState( BOOL Fullscreen, IDXGIOutput* pTarget) final { - return m_dispatch->SetFullscreenState(Fullscreen, pTarget); + if (likely(m_dispatch != nullptr)) + return m_dispatch->SetFullscreenState(Fullscreen, pTarget); + return S_OK; } From ec0c377cf8cf5ca9496dc3786077d3aba79b06d5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 10 Aug 2022 01:03:37 +0200 Subject: [PATCH 0506/1348] [dxvk] Disable maintenance4 feature We don't *really* need it (although some of the guarantees are nice to have). For some reason, this completely destroys GPU-bound performance on AMDVLK and AMD's Windows driver. --- src/dxvk/dxvk_adapter.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 11982556e..da5912771 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -364,7 +364,6 @@ namespace dxvk { // Core features that we're relying on in various places enabledFeatures.vk13.synchronization2 = VK_TRUE; enabledFeatures.vk13.dynamicRendering = VK_TRUE; - enabledFeatures.vk13.maintenance4 = VK_TRUE; // Used for both pNext shader module info, and fast-linking pipelines provided // that graphicsPipelineLibraryIndependentInterpolationDecoration is supported @@ -823,7 +822,6 @@ namespace dxvk { "\n shaderZeroInitializeWorkgroupMemory : ", features.vk13.shaderZeroInitializeWorkgroupMemory, "\n synchronization2 : ", features.vk13.synchronization2, "\n dynamicRendering : ", features.vk13.dynamicRendering, - "\n maintenance4 : ", features.vk13.maintenance4, "\n", VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME, "\n attachmentFeedbackLoopLayout : ", features.extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout ? "1" : "0", "\n", VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, From 5540df955cd8a0963de014fe3b09234b28cea644 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 10 Aug 2022 14:11:47 +0200 Subject: [PATCH 0507/1348] [dxbc] Rework semantic name matching --- src/dxbc/dxbc_chunk_isgn.cpp | 14 +++++++++++--- src/dxbc/dxbc_chunk_isgn.h | 8 ++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/dxbc/dxbc_chunk_isgn.cpp b/src/dxbc/dxbc_chunk_isgn.cpp index ce6617bd1..47f4eef46 100644 --- a/src/dxbc/dxbc_chunk_isgn.cpp +++ b/src/dxbc/dxbc_chunk_isgn.cpp @@ -99,13 +99,21 @@ namespace dxvk { bool DxbcIsgn::compareSemanticNames( - const std::string& a, const std::string& b) const { + const std::string& a, const std::string& b) { if (a.size() != b.size()) return false; for (size_t i = 0; i < a.size(); i++) { - if (std::toupper(a[i]) != std::toupper(b[i])) - return false; + char ac = a[i]; + char bc = b[i]; + + if (ac != bc) { + if (ac >= 'A' && ac <= 'Z') ac += 'a' - 'A'; + if (bc >= 'A' && bc <= 'Z') bc += 'a' - 'A'; + + if (ac != bc) + return false; + } } return true; diff --git a/src/dxbc/dxbc_chunk_isgn.h b/src/dxbc/dxbc_chunk_isgn.h index 030372f3f..1dce64add 100644 --- a/src/dxbc/dxbc_chunk_isgn.h +++ b/src/dxbc/dxbc_chunk_isgn.h @@ -56,14 +56,14 @@ namespace dxvk { void printEntries() const; + static bool compareSemanticNames( + const std::string& a, + const std::string& b); + private: std::vector m_entries; - bool compareSemanticNames( - const std::string& a, - const std::string& b) const; - }; } From 3edb0ef11405bf908efcde821d206a28b91901b8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 10 Aug 2022 14:12:39 +0200 Subject: [PATCH 0508/1348] [d3d11] Ensure that all required inputs are defined by input layout --- src/d3d11/d3d11_device.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index f5fbc13ea..3cdc0bf79 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -591,7 +591,10 @@ namespace dxvk { ID3D11InputLayout** ppInputLayout) { InitReturnPtr(ppInputLayout); - if (pInputElementDescs == nullptr) + // This check is somehow even correct, passing null with zero + // size will always fail but passing non-null with zero size + // works, provided the shader does not have any actual inputs + if (!pInputElementDescs) return E_INVALIDARG; try { @@ -603,6 +606,7 @@ namespace dxvk { uint32_t attrMask = 0; uint32_t bindMask = 0; + uint32_t locationMask = 0; uint32_t bindingsDefined = 0; std::array attrList = { }; @@ -669,9 +673,19 @@ namespace dxvk { if (entry) { attrMask |= 1u << i; bindMask |= 1u << binding.binding; + locationMask |= 1u << attrib.location; } } + // Ensure that all inputs used by the shader are defined + for (auto i = inputSignature->begin(); i != inputSignature->end(); i++) { + bool isBuiltIn = DxbcIsgn::compareSemanticNames(i->semanticName, "sv_instanceid") + || DxbcIsgn::compareSemanticNames(i->semanticName, "sv_vertexid"); + + if (!isBuiltIn && !(locationMask & (1u << i->registerId))) + return E_INVALIDARG; + } + // Compact the attribute and binding lists to filter // out attributes and bindings not used by the shader uint32_t attrCount = CompactSparseList(attrList.data(), attrMask); From 67f937111d7245b7780dc6f382b0c99830fd2c8f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 10 Aug 2022 16:39:58 +0200 Subject: [PATCH 0509/1348] [dxvk] Remove shrinkNvidiaHVVHeap workaround No longer needed. --- dxvk.conf | 13 ------------- src/dxvk/dxvk_memory.cpp | 24 ------------------------ src/dxvk/dxvk_options.cpp | 1 - src/dxvk/dxvk_options.h | 3 --- src/util/config/config.cpp | 4 ++-- 5 files changed, 2 insertions(+), 43 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index dba455426..1bf8a99a1 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -259,19 +259,6 @@ # dxvk.useRawSsbo = Auto -# Controls Nvidia HVV behaviour. -# -# Restricts use of the host-visible, device-local heap on Nvidia drivers. -# This is used to avoid NVIDIA driver bug 3114283 on affected drivers, as -# well as in specific games on newer drivers. -# -# Supported values: -# - True: Restrict HVV usage -# - False: Do not restrict HVV usage - -# dxvk.shrinkNvidiaHvvHeap = False - - # Controls graphics pipeline library behaviour # # Can be used to change VK_EXT_graphics_pipeline_library usage for diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 308bee3e1..e59e7ddce 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -202,30 +202,6 @@ namespace dxvk { m_memTypes[i].memType = m_memProps.memoryTypes[i]; m_memTypes[i].memTypeId = i; } - - /* Check what kind of heap the HVV memory type is on, if any. If the - * HVV memory type is on the largest device-local heap, we either have - * an UMA system or an RBAR-enabled system. Otherwise, there will likely - * be a separate, smaller heap for it. */ - VkDeviceSize largestDeviceLocalHeap = 0; - - for (uint32_t i = 0; i < m_memProps.memoryTypeCount; i++) { - if (m_memTypes[i].memType.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) - largestDeviceLocalHeap = std::max(largestDeviceLocalHeap, m_memTypes[i].heap->properties.size); - } - - /* Work around an issue on Nvidia drivers where using the - * entire HVV heap can cause slowdowns in specific games */ - if (device->adapter()->matchesDriver(VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0) - && device->config().shrinkNvidiaHvvHeap) { - for (uint32_t i = 0; i < m_memProps.memoryTypeCount; i++) { - VkMemoryPropertyFlags hvvFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - - if ((m_memTypes[i].memType.propertyFlags & hvvFlags) == hvvFlags - && (m_memTypes[i].heap->properties.size < largestDeviceLocalHeap)) - m_memTypes[i].heap->budget = 32 << 20; - } - } } diff --git a/src/dxvk/dxvk_options.cpp b/src/dxvk/dxvk_options.cpp index 652bcc405..00f284aa6 100644 --- a/src/dxvk/dxvk_options.cpp +++ b/src/dxvk/dxvk_options.cpp @@ -9,7 +9,6 @@ namespace dxvk { enableGraphicsPipelineLibrary = config.getOption("dxvk.enableGraphicsPipelineLibrary", Tristate::Auto); trackPipelineLifetime = config.getOption("dxvk.trackPipelineLifetime", Tristate::Auto); useRawSsbo = config.getOption("dxvk.useRawSsbo", Tristate::Auto); - shrinkNvidiaHvvHeap = config.getOption ("dxvk.shrinkNvidiaHvvHeap", false); hud = config.getOption("dxvk.hud", ""); } diff --git a/src/dxvk/dxvk_options.h b/src/dxvk/dxvk_options.h index b3cd8a2db..da5bf406e 100644 --- a/src/dxvk/dxvk_options.h +++ b/src/dxvk/dxvk_options.h @@ -27,9 +27,6 @@ namespace dxvk { /// Shader-related options Tristate useRawSsbo; - /// Workaround for NVIDIA driver bug 3114283 - bool shrinkNvidiaHvvHeap; - /// HUD elements std::string hud; }; diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 151fc0543..a46688a4b 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -237,9 +237,9 @@ namespace dxvk { { R"(\\MarySkelter2\.exe$)", {{ { "d3d11.disableMsaa", "True" }, }} }, - /* Final Fantasy XIV - Stuttering on NV */ + /* Final Fantasy XIV: Uses lots of HVV and * + * also reads some uncached memory. */ { R"(\\ffxiv_dx11\.exe$)", {{ - { "dxvk.shrinkNvidiaHvvHeap", "True" }, { "d3d11.cachedDynamicResources", "vi" }, }} }, /* God of War - relies on NVAPI/AMDAGS for * From f031ce44cf9c7c958ab2a704192341552caf5bdf Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Fri, 29 Jul 2022 23:40:46 +0200 Subject: [PATCH 0510/1348] [util] Set lower memory limits for Guitar Hero WT --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index a46688a4b..9f96cba75 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -607,6 +607,11 @@ namespace dxvk { { R"(\\witcher\.exe$)", {{ { "d3d9.apitraceMode", "True" }, }} }, + /* Guitar Hero World Tour * + * Very prone to address space crashes */ + { R"(\\(GHWT|GHWT_Definitive)\.exe$)", {{ + { "d3d9.textureMemory", "16" }, + }} }, }}; From 8feabc653e0b74c5344d3441c60a73bdb902c2c9 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 8 Aug 2022 17:14:05 +0200 Subject: [PATCH 0511/1348] [d3d9] Do implicit flush after uploading textures or buffers --- src/d3d9/d3d9_device.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 99fb0e1b9..561a64369 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4533,6 +4533,7 @@ namespace dxvk { slice.slice); } UnmapTextures(); + FlushImplicit(false); } void D3D9DeviceEx::EmitGenerateMips( @@ -4688,6 +4689,7 @@ namespace dxvk { TrackBufferMappingBufferSequenceNumber(pResource); UnmapTextures(); + FlushImplicit(false); return D3D_OK; } @@ -4710,8 +4712,6 @@ namespace dxvk { if (pResource->Desc()->Pool != D3DPOOL_DEFAULT) return D3D_OK; - FlushImplicit(FALSE); - FlushBuffer(pResource); return D3D_OK; From 9d981ec1a88476a06d37efed24fa60800fc872a3 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Wed, 3 Aug 2022 19:16:30 +0200 Subject: [PATCH 0512/1348] [dxvk] Introduce DxvkMarker Co-authored-by: Philip Rebohle --- src/dxvk/dxvk_context.h | 10 ++++++++++ src/dxvk/dxvk_device.h | 3 ++- src/dxvk/dxvk_marker.h | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/dxvk/dxvk_marker.h diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 67bb8d0d7..3d5c5c437 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -8,6 +8,7 @@ #include "dxvk_objects.h" #include "dxvk_resource.h" #include "dxvk_util.h" +#include "dxvk_marker.h" namespace dxvk { @@ -1252,6 +1253,15 @@ namespace dxvk { */ void insertDebugLabel(VkDebugUtilsLabelEXT *label); + /** + * \brief Inserts a marker object + * \param [in] marker The marker + */ + template + void insertMarker(const Rc>& marker) { + m_cmd->trackResource(marker); + } + /** * \brief Increments a given stat counter * diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index cbc04041b..f47850104 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -22,6 +22,7 @@ #include "dxvk_shader.h" #include "dxvk_stats.h" #include "dxvk_unbound.h" +#include "dxvk_marker.h" #include "../vulkan/vulkan_presenter.h" @@ -348,7 +349,7 @@ namespace dxvk { */ Rc createSampler( const DxvkSamplerCreateInfo& createInfo); - + /** * \brief Retrieves stat counters * diff --git a/src/dxvk/dxvk_marker.h b/src/dxvk/dxvk_marker.h new file mode 100644 index 000000000..3e6f686b2 --- /dev/null +++ b/src/dxvk/dxvk_marker.h @@ -0,0 +1,35 @@ +#pragma once + +#include "dxvk_resource.h" + +namespace dxvk { + + /** + * \brief Marker + * + * Arbitrary marker that can be used to track whether + * the GPU has finished processing certain commands, + * and stores some data. + */ + template + class DxvkMarker : public DxvkResource { + + public: + + DxvkMarker(T&& payload) + : m_payload(std::move(payload)) { } + + DxvkMarker(const T& payload) + : m_payload(payload) { } + + const T& payload() const { + return m_payload; + } + + private: + + T m_payload; + + }; + +} From 02f653fdd27e59a38da1196ddc4fa27ef6350047 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 9 Aug 2022 15:06:35 +0200 Subject: [PATCH 0513/1348] [d3d9] Limit amount of staging memory in flight --- src/d3d9/d3d9_device.cpp | 88 +++++++++++++++++++++++++++++++++++++++- src/d3d9/d3d9_device.h | 15 +++++++ 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 561a64369..fe8d16f09 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4018,12 +4018,91 @@ namespace dxvk { D3D9BufferSlice D3D9DeviceEx::AllocStagingBuffer(VkDeviceSize size) { + m_stagingBufferAllocated += size; + D3D9BufferSlice result; result.slice = m_stagingBuffer.alloc(256, size); result.mapPtr = result.slice.mapPtr(0); return result; } + + void D3D9DeviceEx::EmitStagingBufferMarker() { + if (m_stagingBufferLastAllocated == m_stagingBufferAllocated) + return; + + D3D9StagingBufferMarkerPayload payload; + payload.sequenceNumber = GetCurrentSequenceNumber(); + payload.allocated = m_stagingBufferAllocated; + m_stagingBufferLastAllocated = m_stagingBufferAllocated; + + Rc marker = new D3D9StagingBufferMarker(payload); + m_stagingBufferMarkers.push(marker); + + EmitCs([ + cMarker = std::move(marker) + ] (DxvkContext* ctx) { + ctx->insertMarker(cMarker); + }); + } + + + void D3D9DeviceEx::WaitStagingBuffer() { + // The number below is not a hard limit, however we can be reasonably + // sure that there will never be more than two additional staging buffers + // in flight in addition to the number of staging buffers specified here. + constexpr VkDeviceSize maxStagingMemoryInFlight = env::is32BitHostPlatform() + ? StagingBufferSize * 4 + : StagingBufferSize * 16; + + // If the game uploads a significant amount of data at once, it's + // possible that we exceed the limit while the queue is empty. In + // that case, enforce a flush early to populate the marker queue. + bool didFlush = false; + + if (m_stagingBufferLastSignaled + maxStagingMemoryInFlight < m_stagingBufferAllocated + && m_stagingBufferMarkers.empty()) { + Flush(); + didFlush = true; + } + + // Process the marker queue. We'll remove as many markers as we + // can without stalling, and will stall until we're below the + // allocation limit again. + uint64_t lastSequenceNumber = m_csThread.lastSequenceNumber(); + + while (!m_stagingBufferMarkers.empty()) { + const auto& marker = m_stagingBufferMarkers.front(); + const auto& payload = marker->payload(); + + bool needsStall = m_stagingBufferLastSignaled + maxStagingMemoryInFlight < m_stagingBufferAllocated; + + if (payload.sequenceNumber > lastSequenceNumber) { + if (!needsStall) + break; + + m_csThread.synchronize(payload.sequenceNumber); + lastSequenceNumber = payload.sequenceNumber; + } + + if (marker->isInUse(DxvkAccess::Read)) { + if (!needsStall) + break; + + if (!didFlush) { + Flush(); + didFlush = true; + } + + m_dxvkDevice->waitForResource(marker, DxvkAccess::Read); + } + + m_stagingBufferLastSignaled = marker->payload().allocated; + m_stagingBufferMarkers.pop(); + } + } + + bool D3D9DeviceEx::ShouldRecord() { return m_recorder != nullptr && !m_recorder->IsApplying(); } @@ -4419,8 +4498,9 @@ namespace dxvk { UINT SrcSubresource, VkOffset3D SrcOffset, VkExtent3D SrcExtent, - VkOffset3D DestOffset - ) { + VkOffset3D DestOffset) { + WaitStagingBuffer(); + const Rc image = pDestTexture->GetImage(); // Now that data has been written into the buffer, @@ -4662,6 +4742,8 @@ namespace dxvk { HRESULT D3D9DeviceEx::FlushBuffer( D3D9CommonBuffer* pResource) { + WaitStagingBuffer(); + auto dstBuffer = pResource->GetBufferSlice(); auto srcSlice = pResource->GetMappedSlice(); @@ -5096,6 +5178,8 @@ namespace dxvk { m_initializer->Flush(); m_converter->Flush(); + EmitStagingBufferMarker(); + if (m_csIsBusy || !m_csChunk->empty()) { // Add commands to flush the threaded // context, then flush the command list diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 0df0496f3..6486f3679 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -96,6 +96,13 @@ namespace dxvk { void* mapPtr = nullptr; }; + struct D3D9StagingBufferMarkerPayload { + uint64_t sequenceNumber; + VkDeviceSize allocated; + }; + + using D3D9StagingBufferMarker = DxvkMarker; + class D3D9DeviceEx final : public ComObjectClamp { constexpr static uint32_t DefaultFrameLatency = 3; constexpr static uint32_t MaxFrameLatency = 20; @@ -977,6 +984,10 @@ namespace dxvk { D3D9BufferSlice AllocStagingBuffer(VkDeviceSize size); + void EmitStagingBufferMarker(); + + void WaitStagingBuffer(); + bool ShouldRecord(); HRESULT CreateShaderModule( @@ -1188,6 +1199,10 @@ namespace dxvk { void* m_upBufferMapPtr = nullptr; DxvkStagingBuffer m_stagingBuffer; + VkDeviceSize m_stagingBufferAllocated = 0ull; + VkDeviceSize m_stagingBufferLastAllocated = 0ull; + VkDeviceSize m_stagingBufferLastSignaled = 0ull; + std::queue> m_stagingBufferMarkers; D3D9Cursor m_cursor; From 9a6c378f3d7219961706f73dc85c8fcfa9a23e0c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 10 Aug 2022 17:58:04 +0200 Subject: [PATCH 0514/1348] [dxvk] Only use one descriptor set for compute shaders Simplifies things a bit and avoids redundant sets in the pipeline layout. --- src/dxvk/dxvk_pipelayout.cpp | 23 +++++++++++++++++------ src/dxvk/dxvk_pipelayout.h | 9 +++++---- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index ff3b097ef..67c01ca89 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -9,7 +9,10 @@ namespace dxvk { uint32_t DxvkBindingInfo::computeSetIndex() const { - if (stages & (VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT)) { + if (stages & VK_SHADER_STAGE_COMPUTE_BIT) { + // Use one single set for compute shaders + return DxvkDescriptorSets::CsAll; + } else if (stages & VK_SHADER_STAGE_FRAGMENT_BIT) { // For fragment shaders, create a separate set for UBOs if (descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) @@ -215,12 +218,15 @@ namespace dxvk { uint32_t DxvkBindingLayout::getSetMask() const { uint32_t mask = 0; - if (m_stages & (VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT)) { + if (m_stages & VK_SHADER_STAGE_COMPUTE_BIT) + mask |= (1u << DxvkDescriptorSets::CsAll); + + if (m_stages & VK_SHADER_STAGE_FRAGMENT_BIT) { mask |= (1u << DxvkDescriptorSets::FsViews) | (1u << DxvkDescriptorSets::FsBuffers); } - if (m_stages & (VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_VERTEX_BIT)) + if (m_stages & VK_SHADER_STAGE_VERTEX_BIT) mask |= (1u << DxvkDescriptorSets::VsAll); return mask; @@ -292,7 +298,12 @@ namespace dxvk { std::array setLayouts = { }; - for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + // Use minimum number of sets for the given pipeline layout type + uint32_t setCount = m_layout.getStages() == VK_SHADER_STAGE_COMPUTE_BIT + ? DxvkDescriptorSets::CsSetCount + : DxvkDescriptorSets::SetCount; + + for (uint32_t i = 0; i < setCount; i++) { m_bindingObjects[i] = setObjects[i]; // Sets can be null for partial layouts @@ -322,7 +333,7 @@ namespace dxvk { VkPushConstantRange pushConst = m_layout.getPushConstantRange(); VkPipelineLayoutCreateInfo pipelineLayoutInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; - pipelineLayoutInfo.setLayoutCount = setLayouts.size(); + pipelineLayoutInfo.setLayoutCount = setCount; pipelineLayoutInfo.pSetLayouts = setLayouts.data(); if (pushConst.stageFlags && pushConst.size) { @@ -331,7 +342,7 @@ namespace dxvk { } // If the full set is defined, create a layout without INDEPENDENT_SET_BITS - if (m_layout.getSetMask() == (1u << DxvkDescriptorSets::SetCount) - 1) { + if (m_layout.getSetMask() == (1u << setCount) - 1) { if (vk->vkCreatePipelineLayout(vk->device(), &pipelineLayoutInfo, nullptr, &m_completeLayout)) throw DxvkError("DxvkBindingLayoutObjects: Failed to create pipeline layout"); } diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index f559e6c0f..b7b16c35c 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -19,6 +19,9 @@ namespace dxvk { static constexpr uint32_t FsBuffers = 1; static constexpr uint32_t VsAll = 2; static constexpr uint32_t SetCount = 3; + + static constexpr uint32_t CsAll = 0; + static constexpr uint32_t CsSetCount = 1; }; /** @@ -535,10 +538,8 @@ namespace dxvk { uint32_t getDirtyComputeSets() const { uint32_t result = 0; - if (m_dirtyBuffers & VK_SHADER_STAGE_COMPUTE_BIT) - result |= (1u << DxvkDescriptorSets::FsBuffers); - if (m_dirtyViews & VK_SHADER_STAGE_COMPUTE_BIT) - result |= (1u << DxvkDescriptorSets::FsViews) | (1u << DxvkDescriptorSets::FsBuffers); + if ((m_dirtyBuffers | m_dirtyViews) & VK_SHADER_STAGE_COMPUTE_BIT) + result |= (1u << DxvkDescriptorSets::CsAll); return result; } From 01014c1a2b22fe66cfaf175a34e6e1025b61d486 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 10 Aug 2022 17:20:25 +0200 Subject: [PATCH 0515/1348] [dxvk] Rework checkGfx*Barrier methods --- src/dxvk/dxvk_context.cpp | 39 +++++++++++++++++++++++++++++---------- src/dxvk/dxvk_context.h | 10 ++++++++-- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 56778c045..14c13111b 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5582,7 +5582,7 @@ namespace dxvk { for (uint32_t i = 0; i < slices.size() && !requiresBarrier; i++) { if ((slices[i]->length()) && (slices[i]->bufferInfo().access & storageBufferAccess)) { - requiresBarrier = this->checkGfxBufferBarrier(*slices[i], + requiresBarrier = this->checkBufferBarrier(*slices[i], VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_ACCESS_INDIRECT_COMMAND_READ_BIT).test(DxvkAccess::Write); } @@ -5596,7 +5596,7 @@ namespace dxvk { if ((indexBufferSlice.length()) && (indexBufferSlice.bufferInfo().access & storageBufferAccess)) { - requiresBarrier = this->checkGfxBufferBarrier(indexBufferSlice, + requiresBarrier = this->checkBufferBarrier(indexBufferSlice, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_INDEX_READ_BIT).test(DxvkAccess::Write); } @@ -5612,7 +5612,7 @@ namespace dxvk { if ((vertexBufferSlice.length()) && (vertexBufferSlice.bufferInfo().access & storageBufferAccess)) { - requiresBarrier = this->checkGfxBufferBarrier(vertexBufferSlice, + requiresBarrier = this->checkBufferBarrier(vertexBufferSlice, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT).test(DxvkAccess::Write); } @@ -5628,12 +5628,12 @@ namespace dxvk { const auto& xfbCounterSlice = m_state.xfb.counters[i]; if (xfbBufferSlice.length()) { - requiresBarrier = this->checkGfxBufferBarrier(xfbBufferSlice, + requiresBarrier = this->checkBufferBarrier(xfbBufferSlice, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT) != 0; if (xfbCounterSlice.length()) { - requiresBarrier |= this->checkGfxBufferBarrier(xfbCounterSlice, + requiresBarrier |= this->checkBufferBarrier(xfbCounterSlice, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT | @@ -5661,7 +5661,7 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: if ((slot.bufferSlice.length()) && (slot.bufferSlice.bufferInfo().access & storageBufferAccess)) { - srcAccess = this->checkGfxBufferBarrier(slot.bufferSlice, + srcAccess = this->checkBufferBarrier(slot.bufferSlice, util::pipelineStages(binding.stages), binding.access); } break; @@ -5670,7 +5670,7 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: if ((slot.bufferView != nullptr) && (slot.bufferView->bufferInfo().access & storageBufferAccess)) { - srcAccess = this->checkGfxBufferBarrier(slot.bufferView->slice(), + srcAccess = this->checkBufferViewBarrier(slot.bufferView, util::pipelineStages(binding.stages), binding.access); } break; @@ -5680,7 +5680,7 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: if ((slot.imageView != nullptr) && (slot.imageView->imageInfo().access & storageImageAccess)) { - srcAccess = this->checkGfxImageBarrier(slot.imageView, + srcAccess = this->checkImageViewBarrier(slot.imageView, util::pipelineStages(binding.stages), binding.access); } break; @@ -5710,7 +5710,7 @@ namespace dxvk { template - DxvkAccessFlags DxvkContext::checkGfxBufferBarrier( + DxvkAccessFlags DxvkContext::checkBufferBarrier( const DxvkBufferSlice& slice, VkPipelineStageFlags stages, VkAccessFlags access) { @@ -5728,7 +5728,26 @@ namespace dxvk { template - DxvkAccessFlags DxvkContext::checkGfxImageBarrier( + DxvkAccessFlags DxvkContext::checkBufferViewBarrier( + const Rc& view, + VkPipelineStageFlags stages, + VkAccessFlags access) { + if constexpr (DoEmit) { + m_execBarriers.accessBuffer( + view->getSliceHandle(), + stages, access, + view->bufferInfo().stages, + view->bufferInfo().access); + return DxvkAccessFlags(); + } else { + return m_execBarriers.getBufferAccess( + view->getSliceHandle()); + } + } + + + template + DxvkAccessFlags DxvkContext::checkImageViewBarrier( const Rc& imageView, VkPipelineStageFlags stages, VkAccessFlags access) { diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 3d5c5c437..cc3b7ba34 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1542,13 +1542,19 @@ namespace dxvk { void commitGraphicsBarriers(); template - DxvkAccessFlags checkGfxBufferBarrier( + DxvkAccessFlags checkBufferBarrier( const DxvkBufferSlice& slice, VkPipelineStageFlags stages, VkAccessFlags access); template - DxvkAccessFlags checkGfxImageBarrier( + DxvkAccessFlags checkBufferViewBarrier( + const Rc& slice, + VkPipelineStageFlags stages, + VkAccessFlags access); + + template + DxvkAccessFlags checkImageViewBarrier( const Rc& imageView, VkPipelineStageFlags stages, VkAccessFlags access); From 11fbcd31315c0e046d85f5a3bf01255b79bef0df Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 10 Aug 2022 18:45:53 +0200 Subject: [PATCH 0516/1348] [dxvk] Rework compute barrier handling to use common functions Cleans up code a bit and should technically even make things a bit more efficient. --- src/dxvk/dxvk_context.cpp | 120 +++++++++----------------------------- src/dxvk/dxvk_context.h | 4 +- 2 files changed, 31 insertions(+), 93 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 14c13111b..d57d1c402 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1239,7 +1239,8 @@ namespace dxvk { uint32_t y, uint32_t z) { if (this->commitComputeState()) { - this->commitComputeInitBarriers(); + this->commitComputeBarriers(); + this->commitComputeBarriers(); m_queryManager.beginQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); @@ -1248,8 +1249,6 @@ namespace dxvk { m_queryManager.endQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); - - this->commitComputePostBarriers(); } m_cmd->addStatCtr(DxvkStatCounter::CmdDispatchCalls, 1); @@ -1265,7 +1264,8 @@ namespace dxvk { m_execBarriers.recordCommands(m_cmd); if (this->commitComputeState()) { - this->commitComputeInitBarriers(); + this->commitComputeBarriers(); + this->commitComputeBarriers(); m_queryManager.beginQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); @@ -1277,8 +1277,6 @@ namespace dxvk { m_queryManager.endQueries(m_cmd, VK_QUERY_TYPE_PIPELINE_STATISTICS); - this->commitComputePostBarriers(); - m_execBarriers.accessBuffer(bufferSlice, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_ACCESS_INDIRECT_COMMAND_READ_BIT, @@ -5429,47 +5427,47 @@ namespace dxvk { } - void DxvkContext::commitComputeInitBarriers() { + template + void DxvkContext::commitComputeBarriers() { const auto& layout = m_state.cp.pipeline->getBindings()->layout(); - bool requiresBarrier = false; + // Exit early if we're only checking for hazards and + // if the barrier set is empty, to avoid some overhead. + if (!DoEmit && !m_execBarriers.hasResourceBarriers()) + return; - uint32_t index = 0; - - for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount && !requiresBarrier; i++) { + for (uint32_t i = 0; i < DxvkDescriptorSets::CsSetCount; i++) { uint32_t bindingCount = layout.getBindingCount(i); - for (uint32_t j = 0; j < bindingCount && !requiresBarrier; j++) { + for (uint32_t j = 0; j < bindingCount; j++) { const DxvkBindingInfo& binding = layout.getBinding(i, j); const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; - DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); DxvkAccessFlags srcAccess = 0; - + switch (binding.descriptorType) { case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: if (likely(slot.bufferSlice.length())) { - srcAccess = m_execBarriers.getBufferAccess( - slot.bufferSlice.getSliceHandle()); + srcAccess = this->checkBufferBarrier(slot.bufferSlice, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, binding.access); } break; - + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: if (likely(slot.bufferView != nullptr)) { - srcAccess = m_execBarriers.getBufferAccess( - slot.bufferView->getSliceHandle()); + srcAccess = this->checkBufferViewBarrier(slot.bufferView, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, binding.access); } break; - + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: if (likely(slot.imageView != nullptr)) { - srcAccess = m_execBarriers.getImageAccess( - slot.imageView->image(), - slot.imageView->imageSubresources()); + srcAccess = this->checkImageViewBarrier(slot.imageView, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, binding.access); } break; @@ -5477,10 +5475,12 @@ namespace dxvk { /* nothing to do */; } - if (srcAccess == 0) + if (DoEmit || srcAccess == 0) continue; // Skip write-after-write barriers if explicitly requested + DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); + VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; @@ -5489,79 +5489,15 @@ namespace dxvk { && ((srcAccess | dstAccess) == DxvkAccess::Write)) continue; - requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); - } - - index += bindingCount; - } - - if (requiresBarrier) - m_execBarriers.recordCommands(m_cmd); - } - - - void DxvkContext::commitComputePostBarriers() { - const auto& layout = m_state.cp.pipeline->getBindings()->layout(); - uint32_t index = 0; - - for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { - uint32_t bindingCount = layout.getBindingCount(i); - - for (uint32_t j = 0; j < bindingCount; j++) { - const DxvkBindingInfo& binding = layout.getBinding(i, j); - const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; - - VkPipelineStageFlags stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - VkAccessFlags access = binding.access; - - switch (binding.descriptorType) { - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - if (likely(slot.bufferSlice.length())) { - m_execBarriers.accessBuffer( - slot.bufferSlice.getSliceHandle(), - stages, access, - slot.bufferSlice.bufferInfo().stages, - slot.bufferSlice.bufferInfo().access); - } - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - if (likely(slot.bufferView != nullptr)) { - m_execBarriers.accessBuffer( - slot.bufferView->getSliceHandle(), - stages, access, - slot.bufferView->bufferInfo().stages, - slot.bufferView->bufferInfo().access); - } - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - if (likely(slot.imageView != nullptr)) { - m_execBarriers.accessImage( - slot.imageView->image(), - slot.imageView->imageSubresources(), - slot.imageView->imageInfo().layout, - stages, access, - slot.imageView->imageInfo().layout, - slot.imageView->imageInfo().stages, - slot.imageView->imageInfo().access); - } - break; - - default: - /* nothing to do */; + if ((srcAccess | dstAccess).test(DxvkAccess::Write)) { + m_execBarriers.recordCommands(m_cmd); + return; } } - - index += bindingCount; } } - + template void DxvkContext::commitGraphicsBarriers() { if (m_barrierControl.test(DxvkBarrierControl::IgnoreGraphicsBarriers)) diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index cc3b7ba34..7a827a5dd 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1535,7 +1535,9 @@ namespace dxvk { template bool commitGraphicsState(); - void commitComputeInitBarriers(); + template + void commitComputeBarriers(); + void commitComputePostBarriers(); template From ad020c23f9b712e2398c99ebf4c75456aeb4fda7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 10 Aug 2022 20:45:05 +0200 Subject: [PATCH 0517/1348] [dxvk] Optimize barrier logic The is*Dirty methods can exit early if the resource to check is only used for reading. Only call get*Access to check for write-after-write scenarios. --- src/dxvk/dxvk_context.cpp | 133 +++++++++++++++++++++----------------- src/dxvk/dxvk_context.h | 13 ++-- 2 files changed, 81 insertions(+), 65 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index d57d1c402..2f5460026 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5443,13 +5443,13 @@ namespace dxvk { const DxvkBindingInfo& binding = layout.getBinding(i, j); const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; - DxvkAccessFlags srcAccess = 0; + bool requiresBarrier = false; switch (binding.descriptorType) { case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: if (likely(slot.bufferSlice.length())) { - srcAccess = this->checkBufferBarrier(slot.bufferSlice, + requiresBarrier = this->checkBufferBarrier(slot.bufferSlice, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, binding.access); } break; @@ -5457,7 +5457,7 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: if (likely(slot.bufferView != nullptr)) { - srcAccess = this->checkBufferViewBarrier(slot.bufferView, + requiresBarrier = this->checkBufferViewBarrier(slot.bufferView, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, binding.access); } break; @@ -5466,7 +5466,7 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: if (likely(slot.imageView != nullptr)) { - srcAccess = this->checkImageViewBarrier(slot.imageView, + requiresBarrier = this->checkImageViewBarrier(slot.imageView, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, binding.access); } break; @@ -5475,21 +5475,7 @@ namespace dxvk { /* nothing to do */; } - if (DoEmit || srcAccess == 0) - continue; - - // Skip write-after-write barriers if explicitly requested - DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); - - VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT - | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; - - if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) - && (!(m_execBarriers.getSrcStages() & ~stageMask)) - && ((srcAccess | dstAccess) == DxvkAccess::Write)) - continue; - - if ((srcAccess | dstAccess).test(DxvkAccess::Write)) { + if (requiresBarrier) { m_execBarriers.recordCommands(m_cmd); return; } @@ -5520,7 +5506,7 @@ namespace dxvk { && (slices[i]->bufferInfo().access & storageBufferAccess)) { requiresBarrier = this->checkBufferBarrier(*slices[i], VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, - VK_ACCESS_INDIRECT_COMMAND_READ_BIT).test(DxvkAccess::Write); + VK_ACCESS_INDIRECT_COMMAND_READ_BIT); } } } @@ -5534,7 +5520,7 @@ namespace dxvk { && (indexBufferSlice.bufferInfo().access & storageBufferAccess)) { requiresBarrier = this->checkBufferBarrier(indexBufferSlice, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, - VK_ACCESS_INDEX_READ_BIT).test(DxvkAccess::Write); + VK_ACCESS_INDEX_READ_BIT); } } @@ -5550,7 +5536,7 @@ namespace dxvk { && (vertexBufferSlice.bufferInfo().access & storageBufferAccess)) { requiresBarrier = this->checkBufferBarrier(vertexBufferSlice, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, - VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT).test(DxvkAccess::Write); + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT); } } } @@ -5566,14 +5552,14 @@ namespace dxvk { if (xfbBufferSlice.length()) { requiresBarrier = this->checkBufferBarrier(xfbBufferSlice, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, - VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT) != 0; + VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT); if (xfbCounterSlice.length()) { requiresBarrier |= this->checkBufferBarrier(xfbCounterSlice, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT | - VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT) != 0; + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT); } } } @@ -5582,22 +5568,19 @@ namespace dxvk { // Check shader resources on every draw to handle WAW hazards auto layout = m_state.gp.pipeline->getBindings()->layout(); - for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { + for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount && !requiresBarrier; i++) { uint32_t bindingCount = layout.getBindingCount(i); for (uint32_t j = 0; j < bindingCount && !requiresBarrier; j++) { const DxvkBindingInfo& binding = layout.getBinding(i, j); const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; - DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access); - DxvkAccessFlags srcAccess = 0; - switch (binding.descriptorType) { case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: if ((slot.bufferSlice.length()) && (slot.bufferSlice.bufferInfo().access & storageBufferAccess)) { - srcAccess = this->checkBufferBarrier(slot.bufferSlice, + requiresBarrier = this->checkBufferBarrier(slot.bufferSlice, util::pipelineStages(binding.stages), binding.access); } break; @@ -5606,7 +5589,7 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: if ((slot.bufferView != nullptr) && (slot.bufferView->bufferInfo().access & storageBufferAccess)) { - srcAccess = this->checkBufferViewBarrier(slot.bufferView, + requiresBarrier = this->checkBufferViewBarrier(slot.bufferView, util::pipelineStages(binding.stages), binding.access); } break; @@ -5616,7 +5599,7 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: if ((slot.imageView != nullptr) && (slot.imageView->imageInfo().access & storageImageAccess)) { - srcAccess = this->checkImageViewBarrier(slot.imageView, + requiresBarrier = this->checkImageViewBarrier(slot.imageView, util::pipelineStages(binding.stages), binding.access); } break; @@ -5624,16 +5607,6 @@ namespace dxvk { default: /* nothing to do */; } - - if (srcAccess == 0) - continue; - - // Skip write-after-write barriers if explicitly requested - if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) - && ((srcAccess | dstAccess) == DxvkAccess::Write)) - continue; - - requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); } } @@ -5646,44 +5619,61 @@ namespace dxvk { template - DxvkAccessFlags DxvkContext::checkBufferBarrier( - const DxvkBufferSlice& slice, + bool DxvkContext::checkBufferBarrier( + const DxvkBufferSlice& bufferSlice, VkPipelineStageFlags stages, VkAccessFlags access) { if constexpr (DoEmit) { m_execBarriers.accessBuffer( - slice.getSliceHandle(), + bufferSlice.getSliceHandle(), stages, access, - slice.bufferInfo().stages, - slice.bufferInfo().access); - return DxvkAccessFlags(); + bufferSlice.bufferInfo().stages, + bufferSlice.bufferInfo().access); + return false; } else { - return m_execBarriers.getBufferAccess(slice.getSliceHandle()); + DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(access); + + bool dirty = m_execBarriers.isBufferDirty( + bufferSlice.getSliceHandle(), dstAccess); + + if (!dirty || dstAccess.test(DxvkAccess::Read) || !this->canIgnoreWawHazards(stages)) + return dirty; + + DxvkAccessFlags srcAccess = m_execBarriers.getBufferAccess(bufferSlice.getSliceHandle()); + return srcAccess.test(DxvkAccess::Read); } } template - DxvkAccessFlags DxvkContext::checkBufferViewBarrier( - const Rc& view, + bool DxvkContext::checkBufferViewBarrier( + const Rc& bufferView, VkPipelineStageFlags stages, VkAccessFlags access) { if constexpr (DoEmit) { m_execBarriers.accessBuffer( - view->getSliceHandle(), + bufferView->getSliceHandle(), stages, access, - view->bufferInfo().stages, - view->bufferInfo().access); - return DxvkAccessFlags(); + bufferView->bufferInfo().stages, + bufferView->bufferInfo().access); + return false; } else { - return m_execBarriers.getBufferAccess( - view->getSliceHandle()); + DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(access); + + bool dirty = m_execBarriers.isBufferDirty( + bufferView->getSliceHandle(), dstAccess); + + if (!dirty || dstAccess.test(DxvkAccess::Read) || !this->canIgnoreWawHazards(stages)) + return dirty; + + DxvkAccessFlags srcAccess = m_execBarriers.getBufferAccess(bufferView->getSliceHandle()); + return srcAccess.test(DxvkAccess::Read); } } template - DxvkAccessFlags DxvkContext::checkImageViewBarrier( + bool DxvkContext::checkImageViewBarrier( const Rc& imageView, VkPipelineStageFlags stages, VkAccessFlags access) { @@ -5696,15 +5686,38 @@ namespace dxvk { imageView->imageInfo().layout, imageView->imageInfo().stages, imageView->imageInfo().access); - return DxvkAccessFlags(); + return false; } else { - return m_execBarriers.getImageAccess( + DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(access); + + bool dirty = m_execBarriers.isImageDirty( imageView->image(), - imageView->imageSubresources()); + imageView->imageSubresources(), + dstAccess); + + if (!dirty || dstAccess.test(DxvkAccess::Read) || !this->canIgnoreWawHazards(stages)) + return dirty; + + DxvkAccessFlags srcAccess = m_execBarriers.getImageAccess( + imageView->image(), imageView->imageSubresources()); + return srcAccess.test(DxvkAccess::Read); } } + bool DxvkContext::canIgnoreWawHazards(VkPipelineStageFlags stages) { + if (!m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) + return false; + + if (stages & VK_SHADER_STAGE_COMPUTE_BIT) { + VkPipelineStageFlags stageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; + return !(m_execBarriers.getSrcStages() & ~stageMask); + } + + return true; + } + + void DxvkContext::emitMemoryBarrier( VkPipelineStageFlags srcStages, VkAccessFlags srcAccess, diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 7a827a5dd..fe24c556e 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1544,23 +1544,26 @@ namespace dxvk { void commitGraphicsBarriers(); template - DxvkAccessFlags checkBufferBarrier( - const DxvkBufferSlice& slice, + bool checkBufferBarrier( + const DxvkBufferSlice& bufferSlice, VkPipelineStageFlags stages, VkAccessFlags access); template - DxvkAccessFlags checkBufferViewBarrier( - const Rc& slice, + bool checkBufferViewBarrier( + const Rc& bufferView, VkPipelineStageFlags stages, VkAccessFlags access); template - DxvkAccessFlags checkImageViewBarrier( + bool checkImageViewBarrier( const Rc& imageView, VkPipelineStageFlags stages, VkAccessFlags access); + bool canIgnoreWawHazards( + VkPipelineStageFlags stages); + void emitMemoryBarrier( VkPipelineStageFlags srcStages, VkAccessFlags srcAccess, From 8aae9c85bbffaf58c80c9e8fe9b7b75c27ba1357 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 10 Aug 2022 23:08:28 +0200 Subject: [PATCH 0518/1348] [dxvk] Optimize barrier hash table lookup Using a prime as the table size is technically better, but that integer division kind of hurts when we're spamming look-ups. --- src/dxvk/dxvk_barrier.h | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/dxvk/dxvk_barrier.h b/src/dxvk/dxvk_barrier.h index ebe7080ba..d6ad03ea2 100644 --- a/src/dxvk/dxvk_barrier.h +++ b/src/dxvk/dxvk_barrier.h @@ -357,22 +357,28 @@ namespace dxvk { uint64_t m_version = 1ull; uint64_t m_used = 0ull; + size_t m_indexMask = 0; std::vector m_list; std::vector m_hashMap; static size_t computeHash(K key) { - return size_t(uint64_t(key)); + size_t hash = size_t(key) * 93887; + return hash ^ (hash >> 16); + } + + size_t computeSize() const { + return m_indexMask + ? m_indexMask + 1 + : 0; } size_t computeIndex(K key) const { - return computeHash(key) % m_hashMap.size(); + return computeHash(key) & (m_indexMask); } size_t advanceIndex(size_t index) const { - size_t size = m_hashMap.size(); - size_t next = index + 1; - return next < size ? next : 0; + return (index + 1) & m_indexMask; } HashEntry* findHashEntry(K key) { @@ -416,7 +422,7 @@ namespace dxvk { } void growHashMap(size_t newSize) { - size_t oldSize = m_hashMap.size(); + size_t oldSize = computeSize(); m_hashMap.resize(newSize); // Relocate hash entries in place @@ -436,14 +442,15 @@ namespace dxvk { } m_version += 1; + m_indexMask = newSize - 1; } void growHashMapBeforeInsert() { // Allow a load factor of 0.7 for performance reasons - size_t oldSize = m_hashMap.size(); + size_t oldSize = computeSize(); if (10 * m_used >= 7 * oldSize) { - size_t newSize = oldSize ? (oldSize * 2 + 5) : 37; + size_t newSize = oldSize ? oldSize * 2 : 64; growHashMap(newSize); } } From 4c7da80c1410044e548b696ca9f8ad66422bcf17 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 10 Aug 2022 23:45:19 +0200 Subject: [PATCH 0519/1348] [dxvk] Simplify barrier image and buffer slice implementations Pre-process the given ranges so that compare and merge operations become both simpler and faster. --- src/dxvk/dxvk_barrier.h | 104 ++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 41 deletions(-) diff --git a/src/dxvk/dxvk_barrier.h b/src/dxvk/dxvk_barrier.h index d6ad03ea2..27e421cf2 100644 --- a/src/dxvk/dxvk_barrier.h +++ b/src/dxvk/dxvk_barrier.h @@ -20,10 +20,12 @@ namespace dxvk { public: DxvkBarrierBufferSlice() - : m_offset(0), m_length(0), m_access(0) { } + : m_loAddr(0), m_hiAddr(0), m_access(0) { } DxvkBarrierBufferSlice(VkDeviceSize offset, VkDeviceSize length, DxvkAccessFlags access) - : m_offset(offset), m_length(length), m_access(access) { } + : m_loAddr(offset), + m_hiAddr(offset + length), + m_access(access) { } /** * \brief Checks whether two slices overlap @@ -32,8 +34,8 @@ namespace dxvk { * \returns \c true if the two slices overlap */ bool overlaps(const DxvkBarrierBufferSlice& slice) const { - return m_offset + m_length > slice.m_offset - && m_offset < slice.m_offset + slice.m_length; + return m_hiAddr > slice.m_loAddr + && m_loAddr < slice.m_hiAddr; } /** @@ -58,11 +60,11 @@ namespace dxvk { */ bool canMerge(const DxvkBarrierBufferSlice& slice) const { if (m_access == slice.m_access) { - return m_offset + m_length >= slice.m_offset - && m_offset <= slice.m_offset + slice.m_length; + return m_hiAddr >= slice.m_loAddr + && m_loAddr <= slice.m_hiAddr; } else { - return m_offset == slice.m_offset - && m_length == slice.m_length; + return m_loAddr == slice.m_loAddr + && m_hiAddr == slice.m_hiAddr; } } @@ -75,10 +77,8 @@ namespace dxvk { * \param [in] slice The slice to merge */ void merge(const DxvkBarrierBufferSlice& slice) { - VkDeviceSize end = std::max(m_offset + m_length, slice.m_offset + slice.m_length); - - m_offset = std::min(m_offset, slice.m_offset); - m_length = end - m_offset; + m_loAddr = std::min(m_loAddr, slice.m_loAddr); + m_hiAddr = std::max(m_hiAddr, slice.m_hiAddr); m_access.set(slice.m_access); } @@ -87,13 +87,13 @@ namespace dxvk { * \returns Access flags */ DxvkAccessFlags getAccess() const { - return m_access; + return DxvkAccessFlags(m_access); } private: - VkDeviceSize m_offset; - VkDeviceSize m_length; + VkDeviceSize m_loAddr; + VkDeviceSize m_hiAddr; DxvkAccessFlags m_access; }; @@ -110,10 +110,20 @@ namespace dxvk { public: DxvkBarrierImageSlice() - : m_range(VkImageSubresourceRange()), m_access(0) { } + : m_aspects(0), + m_minLayer(0), + m_maxLayer(0), + m_minLevel(0), + m_maxLevel(0), + m_access(0) { } DxvkBarrierImageSlice(VkImageSubresourceRange range, DxvkAccessFlags access) - : m_range(range), m_access(access) { } + : m_aspects(range.aspectMask), + m_minLayer(range.baseArrayLayer), + m_maxLayer(range.baseArrayLayer + range.layerCount), + m_minLevel(range.baseMipLevel), + m_maxLevel(range.baseMipLevel + range.levelCount), + m_access(access) { } /** * \brief Checks whether two slices overlap @@ -122,11 +132,11 @@ namespace dxvk { * \returns \c true if the two slices overlap */ bool overlaps(const DxvkBarrierImageSlice& slice) const { - return (m_range.aspectMask & slice.m_range.aspectMask) - && (m_range.baseArrayLayer < slice.m_range.baseArrayLayer + slice.m_range.layerCount) - && (m_range.baseArrayLayer + m_range.layerCount > slice.m_range.baseArrayLayer) - && (m_range.baseMipLevel < slice.m_range.baseMipLevel + slice.m_range.levelCount) - && (m_range.baseMipLevel + m_range.levelCount > slice.m_range.baseMipLevel); + return (m_aspects & slice.m_aspects) + && (m_minLayer < slice.m_maxLayer) + && (m_maxLayer > slice.m_minLayer) + && (m_minLevel < slice.m_maxLevel) + && (m_maxLevel > slice.m_minLevel); } /** @@ -143,18 +153,30 @@ namespace dxvk { /** * \brief Checks whether two slices can be merged * - * This is a simplified implementation that does not check for - * adjacent or overlapping layers or levels, and instead only - * returns \c true if both slices contain the same mip levels - * and array layers. Access flags and image aspects may differ. + * This is a simplified implementation that does only + * checks for adjacent subresources in one dimension. * \param [in] slice The other image slice to check * \returns \c true if the slices can be merged. */ bool canMerge(const DxvkBarrierImageSlice& slice) const { - return m_range.baseMipLevel == slice.m_range.baseMipLevel - && m_range.levelCount == slice.m_range.levelCount - && m_range.baseArrayLayer == slice.m_range.baseArrayLayer - && m_range.layerCount == slice.m_range.layerCount; + bool sameLayers = m_minLayer == slice.m_minLayer + && m_maxLayer == slice.m_maxLayer; + bool sameLevels = m_minLevel == slice.m_minLevel + && m_maxLevel == slice.m_maxLevel; + + if (sameLayers == sameLevels) + return sameLayers; + + if (m_access != slice.m_access) + return false; + + if (sameLayers) { + return m_maxLevel >= slice.m_minLevel + && m_minLevel <= slice.m_maxLevel; + } else /* if (sameLevels) */ { + return m_maxLayer >= slice.m_minLayer + && m_minLayer <= slice.m_maxLayer; + } } /** @@ -166,15 +188,11 @@ namespace dxvk { * \param [in] slice The slice to merge */ void merge(const DxvkBarrierImageSlice& slice) { - uint32_t maxMipLevel = std::max(m_range.baseMipLevel + m_range.levelCount, - slice.m_range.baseMipLevel + slice.m_range.levelCount); - uint32_t maxArrayLayer = std::max(m_range.baseArrayLayer + m_range.layerCount, - slice.m_range.baseArrayLayer + slice.m_range.layerCount); - m_range.aspectMask |= slice.m_range.aspectMask; - m_range.baseMipLevel = std::min(m_range.baseMipLevel, slice.m_range.baseMipLevel); - m_range.levelCount = maxMipLevel - m_range.baseMipLevel; - m_range.baseArrayLayer = std::min(m_range.baseMipLevel, slice.m_range.baseArrayLayer); - m_range.layerCount = maxArrayLayer - m_range.baseArrayLayer; + m_aspects |= slice.m_aspects; + m_minLayer = std::min(m_minLayer, slice.m_minLayer); + m_maxLayer = std::max(m_maxLayer, slice.m_maxLayer); + m_minLevel = std::min(m_minLevel, slice.m_minLevel); + m_maxLevel = std::max(m_maxLevel, slice.m_maxLevel); m_access.set(slice.m_access); } @@ -188,8 +206,12 @@ namespace dxvk { private: - VkImageSubresourceRange m_range; - DxvkAccessFlags m_access; + VkImageAspectFlags m_aspects; + uint32_t m_minLayer; + uint32_t m_maxLayer; + uint32_t m_minLevel; + uint32_t m_maxLevel; + DxvkAccessFlags m_access; }; From 85c278f515cd1884d7288f976a4406dde7c79958 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 11 Aug 2022 00:38:49 +0200 Subject: [PATCH 0520/1348] [dxvk] Don't try to merge buffer ranges in barrier list Too slow, doesn't work most of the time anyway. --- src/dxvk/dxvk_barrier.h | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/dxvk/dxvk_barrier.h b/src/dxvk/dxvk_barrier.h index 27e421cf2..9b83ee390 100644 --- a/src/dxvk/dxvk_barrier.h +++ b/src/dxvk/dxvk_barrier.h @@ -321,23 +321,29 @@ namespace dxvk { if (hashEntry) { ListEntry* listEntry = getListEntry(hashEntry->next); - // Only create the linear list if absolutely necessary - if (!listEntry && !hashEntry->data.canMerge(slice)) - listEntry = insertListEntry(hashEntry->data, hashEntry); - if (listEntry) { - while (listEntry) { - // Avoid adding new list entries if possible - if (listEntry->data.canMerge(slice)) { - listEntry->data.merge(slice); - break; - } + if (std::is_same_v) { + // For images, try to merge the slice with existing + // entries if possible to keep the list small + do { + if (listEntry->data.canMerge(slice)) { + listEntry->data.merge(slice); + break; + } + } while ((listEntry = getListEntry(listEntry->next))); - listEntry = getListEntry(listEntry->next); - } - - if (!listEntry) + if (!listEntry) + insertListEntry(slice, hashEntry); + } else { + // For buffers it's not even worth trying. Most of the + // time we won't be able to merge, and traversing the + // entire list every time is slow. insertListEntry(slice, hashEntry); + } + } else if (!hashEntry->data.canMerge(slice)) { + // Only create the linear list if absolutely necessary + insertListEntry(hashEntry->data, hashEntry); + insertListEntry(slice, hashEntry); } // Merge hash entry data so that it stores From 5cdee453875f76189e10c65b9c973d62637fbb05 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Thu, 11 Aug 2022 03:00:20 +0200 Subject: [PATCH 0521/1348] [util] Disable direct buffer mapping for GHWT The game ends up discarding a 11MB buffer which causes it to run out of address space and crash. Disabling direct buffer mapping makes it use staging buffers and the staging buffer limit saves the day. --- src/util/config/config.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 9f96cba75..be6a1c04a 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -611,6 +611,7 @@ namespace dxvk { * Very prone to address space crashes */ { R"(\\(GHWT|GHWT_Definitive)\.exe$)", {{ { "d3d9.textureMemory", "16" }, + { "d3d9.allowDirectBufferMapping", "False" }, }} }, }}; From b5b74116fa61fa06d8891f2db578773ff93c7b64 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Thu, 11 Aug 2022 02:59:05 +0200 Subject: [PATCH 0522/1348] [d3d9] Fix rare hang when waiting for staging buffer markers --- src/d3d9/d3d9_device.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index fe8d16f09..c785a0b60 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4081,7 +4081,7 @@ namespace dxvk { if (!needsStall) break; - m_csThread.synchronize(payload.sequenceNumber); + SynchronizeCsThread(payload.sequenceNumber); lastSequenceNumber = payload.sequenceNumber; } @@ -4829,7 +4829,8 @@ namespace dxvk { // Dispatch current chunk so that all commands // recorded prior to this function will be run - FlushCsChunk(); + if (SequenceNumber > m_csSeqNum) + FlushCsChunk(); m_csThread.synchronize(SequenceNumber); } @@ -5178,9 +5179,9 @@ namespace dxvk { m_initializer->Flush(); m_converter->Flush(); - EmitStagingBufferMarker(); - if (m_csIsBusy || !m_csChunk->empty()) { + EmitStagingBufferMarker(); + // Add commands to flush the threaded // context, then flush the command list EmitCs([](DxvkContext* ctx) { From f09f11aad04f2bad15d3305ccf3581fa536e6b80 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 11 Aug 2022 02:05:52 +0200 Subject: [PATCH 0523/1348] [dxvk] Track pipeline library compile for each shader --- src/dxvk/dxvk_shader.cpp | 9 ++++++++- src/dxvk/dxvk_shader.h | 27 +++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index d5eba8499..9ee0e2feb 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -152,6 +152,10 @@ namespace dxvk { if (info.bindingOffset) m_bindingOffsets.push_back(info); } + + // Don't set pipeline library flag if the shader + // doesn't actually support pipeline libraries + m_needsLibraryCompile = canUsePipelineLibrary(); } @@ -879,7 +883,7 @@ namespace dxvk { DxvkShaderPipelineLibrary::DxvkShaderPipelineLibrary( const DxvkDevice* device, DxvkPipelineManager* manager, - const DxvkShader* shader, + DxvkShader* shader, const DxvkBindingLayoutObjects* layout) : m_device (device), m_stats (&manager->m_stats), @@ -981,6 +985,9 @@ namespace dxvk { VkShaderStageFlagBits stage = getShaderStage(); VkPipeline pipeline = VK_NULL_HANDLE; + if (m_shader) + m_shader->notifyLibraryCompile(); + // If this is not the first time we're compiling the pipeline, // try to get a cache hit using the shader module identifier // so that we don't have to decompress our SPIR-V shader again. diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 3c273a28e..d3de90ea2 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -127,6 +127,28 @@ namespace dxvk { return m_specConstantMask; } + /** + * \brief Tests whether this shader needs to be compiled + * + * If pipeline libraries are supported, this will return + * \c false once the pipeline library is being compiled. + * \returns \c true if compilation is still needed + */ + bool needsLibraryCompile() const { + return m_needsLibraryCompile.load(); + } + + /** + * \brief Notifies library compile + * + * Called automatically when pipeline compilation begins. + * Subsequent calls to \ref needsLibraryCompile will return + * \c false. + */ + void notifyLibraryCompile() { + m_needsLibraryCompile.store(false); + } + /** * \brief Patches code using given info * @@ -225,6 +247,7 @@ namespace dxvk { size_t m_o1LocOffset = 0; uint32_t m_specConstantMask = 0; + std::atomic m_needsLibraryCompile = { true }; std::vector m_uniformData; std::vector m_bindingOffsets; @@ -380,7 +403,7 @@ namespace dxvk { DxvkShaderPipelineLibrary( const DxvkDevice* device, DxvkPipelineManager* manager, - const DxvkShader* shader, + DxvkShader* shader, const DxvkBindingLayoutObjects* layout); ~DxvkShaderPipelineLibrary(); @@ -429,7 +452,7 @@ namespace dxvk { const DxvkDevice* m_device; DxvkPipelineStats* m_stats; - const DxvkShader* m_shader; + DxvkShader* m_shader; const DxvkBindingLayoutObjects* m_layout; dxvk::mutex m_mutex; From c3a53127d746a597d2cfab68d833d134976d6fbd Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 11 Aug 2022 02:37:36 +0200 Subject: [PATCH 0524/1348] [dxvk] Add high-priority queue for shader compiles As well as an API to queue shaders as high priority. --- src/dxvk/dxvk_device.cpp | 6 ++ src/dxvk/dxvk_device.h | 7 +++ src/dxvk/dxvk_pipemanager.cpp | 109 ++++++++++++++++++++++++++++------ src/dxvk/dxvk_pipemanager.h | 34 +++++++++-- 4 files changed, 133 insertions(+), 23 deletions(-) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index d8bd98a09..08289cee0 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -213,6 +213,12 @@ namespace dxvk { } + void DxvkDevice::requestCompileShader( + const Rc& shader) { + m_objects.pipelineManager().requestCompileShader(shader); + } + + void DxvkDevice::presentImage( const Rc& presenter, DxvkSubmitStatus* status) { diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index f47850104..e8f44ee6a 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -380,6 +380,13 @@ namespace dxvk { void registerShader( const Rc& shader); + /** + * \brief Prioritizes compilation of a given shader + * \param [in] shader Shader to start compiling + */ + void requestCompileShader( + const Rc& shader); + /** * \brief Presents a swap chain image * diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 426443d75..ffd52f2b3 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -7,17 +7,9 @@ namespace dxvk { DxvkPipelineWorkers::DxvkPipelineWorkers( - DxvkDevice* device) { - // Use a reasonably large number of threads for compiling, but - // leave some cores to the application to avoid excessive stutter - uint32_t numCpuCores = dxvk::thread::hardware_concurrency(); - m_workerCount = ((std::max(1u, numCpuCores) - 1) * 5) / 7; + DxvkDevice* device) + : m_device(device) { - if (m_workerCount < 1) m_workerCount = 1; - if (m_workerCount > 32) m_workerCount = 32; - - if (device->config().numCompilerThreads > 0) - m_workerCount = device->config().numCompilerThreads; } @@ -27,7 +19,8 @@ namespace dxvk { void DxvkPipelineWorkers::compilePipelineLibrary( - DxvkShaderPipelineLibrary* library) { + DxvkShaderPipelineLibrary* library, + DxvkPipelinePriority priority) { std::unique_lock lock(m_queueLock); this->startWorkers(); @@ -36,7 +29,13 @@ namespace dxvk { PipelineLibraryEntry e = { }; e.pipelineLibrary = library; - m_queuedLibraries.push(e); + if (priority == DxvkPipelinePriority::High) { + m_queuedLibrariesPrioritized.push(e); + m_queueCondPrioritized.notify_one(); + } else { + m_queuedLibraries.push(e); + } + m_queueCond.notify_one(); } @@ -100,14 +99,37 @@ namespace dxvk { void DxvkPipelineWorkers::startWorkers() { if (!m_workersRunning) { + // Use all available cores by default + uint32_t workerCount = dxvk::thread::hardware_concurrency(); + + if (workerCount < 1) workerCount = 1; + if (workerCount > 64) workerCount = 64; + + // Reduce worker count on 32-bit to save adderss space + if (env::is32BitHostPlatform()) + workerCount = std::min(workerCount, 16u); + + if (m_device->config().numCompilerThreads > 0) + workerCount = m_device->config().numCompilerThreads; + + // Number of workers that can process pipeline pipelines with normal + // priority. Any other workers can only build high-priority pipelines. + uint32_t npWorkerCount = m_device->canUseGraphicsPipelineLibrary() + ? std::max(((workerCount - 1) * 5) / 7, 1u) + : workerCount; + uint32_t hpWorkerCount = workerCount - npWorkerCount; + + Logger::info(str::format("DXVK: Using ", npWorkerCount, " + ", hpWorkerCount, " compiler threads")); + m_workers.resize(npWorkerCount + hpWorkerCount); + + // Set worker flag so that they don't exit immediately m_workersRunning = true; - Logger::info(str::format("DXVK: Using ", m_workerCount, " compiler threads")); - m_workers.resize(m_workerCount); - - for (auto& worker : m_workers) { - worker = dxvk::thread([this] { runWorker(); }); - worker.set_priority(ThreadPriority::Lowest); + for (size_t i = 0; i < m_workers.size(); i++) { + m_workers[i] = i >= npWorkerCount + ? dxvk::thread([this] { runWorkerPrioritized(); }) + : dxvk::thread([this] { runWorker(); }); + m_workers[i].set_priority(ThreadPriority::Lowest); } } } @@ -124,6 +146,7 @@ namespace dxvk { m_queueCond.wait(lock, [this] { return !m_workersRunning + || !m_queuedLibrariesPrioritized.empty() || !m_queuedLibraries.empty() || !m_queuedPipelines.empty(); }); @@ -132,6 +155,9 @@ namespace dxvk { // Skip pending work, exiting early is // more important in this case. break; + } else if (!m_queuedLibrariesPrioritized.empty()) { + l = m_queuedLibrariesPrioritized.front(); + m_queuedLibrariesPrioritized.pop(); } else if (!m_queuedLibraries.empty()) { l = m_queuedLibraries.front(); m_queuedLibraries.pop(); @@ -162,6 +188,34 @@ namespace dxvk { } + void DxvkPipelineWorkers::runWorkerPrioritized() { + env::setThreadName("dxvk-shader-p"); + + while (true) { + PipelineLibraryEntry l = { }; + + { std::unique_lock lock(m_queueLock); + + m_queueCondPrioritized.wait(lock, [this] { + return !m_workersRunning + || !m_queuedLibrariesPrioritized.empty(); + }); + + if (!m_workersRunning) + break; + + l = m_queuedLibrariesPrioritized.front(); + m_queuedLibrariesPrioritized.pop(); + } + + if (l.pipelineLibrary) + l.pipelineLibrary->compilePipeline(); + + m_pendingTasks -= 1; + } + } + + DxvkPipelineManager::DxvkPipelineManager( DxvkDevice* device) : m_device (device), @@ -285,13 +339,30 @@ namespace dxvk { const Rc& shader) { if (canPrecompileShader(shader)) { auto library = createPipelineLibrary(shader); - m_workers.compilePipelineLibrary(library); + m_workers.compilePipelineLibrary(library, DxvkPipelinePriority::Normal); } m_stateCache.registerShader(shader); } + void DxvkPipelineManager::requestCompileShader( + const Rc& shader) { + if (!shader->needsLibraryCompile()) + return; + + // Dispatch high-priority compile job + auto library = findPipelineLibrary(shader); + + if (library) + m_workers.compilePipelineLibrary(library, DxvkPipelinePriority::High); + + // Notify immediately so that this only gets called + // once, even if compilation does ot start immediately + shader->notifyLibraryCompile(); + } + + DxvkPipelineCount DxvkPipelineManager::getPipelineCount() const { DxvkPipelineCount result; result.numGraphicsPipelines = m_stats.numGraphicsPipelines.load(); diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 5661dd86f..b71751dde 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -34,6 +34,14 @@ namespace dxvk { std::atomic numComputePipelines = { 0u }; }; + /** + * \brief Pipeline priority + */ + enum class DxvkPipelinePriority : uint32_t { + Normal = 0, + High = 1, + }; + /** * \brief Pipeline manager worker threads * @@ -56,9 +64,11 @@ namespace dxvk { * the pipeline with default compile arguments. * Note that pipeline libraries are high priority. * \param [in] library The pipeline library + * \param [in] priority Pipeline priority */ void compilePipelineLibrary( - DxvkShaderPipelineLibrary* library); + DxvkShaderPipelineLibrary* library, + DxvkPipelinePriority priority); /** * \brief Compiles an optimized compute pipeline @@ -107,15 +117,18 @@ namespace dxvk { DxvkShaderPipelineLibrary* pipelineLibrary; }; + DxvkDevice* m_device; + std::atomic m_pendingTasks = { 0ull }; dxvk::mutex m_queueLock; dxvk::condition_variable m_queueCond; + dxvk::condition_variable m_queueCondPrioritized; + std::queue m_queuedLibrariesPrioritized; std::queue m_queuedLibraries; std::queue m_queuedPipelines; - uint32_t m_workerCount = 0; bool m_workersRunning = false; std::vector m_workers; @@ -123,6 +136,8 @@ namespace dxvk { void runWorker(); + void runWorkerPrioritized(); + }; @@ -188,7 +203,7 @@ namespace dxvk { DxvkGraphicsPipelineFragmentOutputLibrary* createFragmentOutputLibrary( const DxvkGraphicsPipelineFragmentOutputState& state); - /* + /** * \brief Registers a shader * * Starts compiling pipelines asynchronously @@ -198,7 +213,18 @@ namespace dxvk { */ void registerShader( const Rc& shader); - + + /** + * \brief Prioritizes compilation of a given shader + * + * Adds the pipeline library for the given shader + * to the high-priority queue of the background + * workers to make sure it gets compiled quickly. + * \param [in] shader Newly compiled shader + */ + void requestCompileShader( + const Rc& shader); + /** * \brief Retrieves total pipeline count * \returns Number of compute/graphics pipelines From d3ab9056211cc1882c076b9936503ce8b76338ab Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 11 Aug 2022 01:56:17 +0200 Subject: [PATCH 0525/1348] [d3d11] Request high-priority shader compiles as necessary This can reduce stutter in case shaders are needed immediately while background threads are still busy compiling a different set of shaders. --- src/d3d11/d3d11_context.cpp | 48 +++++++++++++++++++++++-------------- src/d3d11/d3d11_shader.h | 6 +++-- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 340017a4d..55963c7c0 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3110,26 +3110,38 @@ namespace dxvk { template void D3D11CommonContext::BindShader( const D3D11CommonShader* pShaderModule) { - // Bind the shader and the ICB at once - EmitCs([ - cSlice = pShaderModule != nullptr - && pShaderModule->GetIcb() != nullptr - ? DxvkBufferSlice(pShaderModule->GetIcb()) - : DxvkBufferSlice(), - cShader = pShaderModule != nullptr - ? pShaderModule->GetShader() - : nullptr - ] (DxvkContext* ctx) mutable { - constexpr VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + if (pShaderModule) { + auto buffer = pShaderModule->GetIcb(); + auto shader = pShaderModule->GetShader(); - uint32_t slotId = computeConstantBufferBinding(ShaderStage, - D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); + if (unlikely(shader->needsLibraryCompile())) + m_device->requestCompileShader(shader); - ctx->bindShader( - Forwarder::move(cShader)); - ctx->bindResourceBuffer(stage, slotId, - Forwarder::move(cSlice)); - }); + EmitCs([ + cBuffer = std::move(buffer), + cShader = std::move(shader) + ] (DxvkContext* ctx) mutable { + constexpr VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + + uint32_t slotId = computeConstantBufferBinding(ShaderStage, + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); + + ctx->bindShader( + Forwarder::move(cShader)); + ctx->bindResourceBuffer(stage, slotId, + Forwarder::move(cBuffer)); + }); + } else { + EmitCs([] (DxvkContext* ctx) { + constexpr VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); + + uint32_t slotId = computeConstantBufferBinding(ShaderStage, + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); + + ctx->bindShader(nullptr); + ctx->bindResourceBuffer(stage, slotId, DxvkBufferSlice()); + }); + } } diff --git a/src/d3d11/d3d11_shader.h b/src/d3d11/d3d11_shader.h index 3ab16854e..4ef2e4b90 100644 --- a/src/d3d11/d3d11_shader.h +++ b/src/d3d11/d3d11_shader.h @@ -43,8 +43,10 @@ namespace dxvk { return m_shader; } - Rc GetIcb() const { - return m_buffer; + DxvkBufferSlice GetIcb() const { + return m_buffer != nullptr + ? DxvkBufferSlice(m_buffer) + : DxvkBufferSlice(); } std::string GetName() const { From 9bd0040a90de94c7b0d4805ba649a15166e6ef93 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 11 Aug 2022 02:44:05 +0200 Subject: [PATCH 0526/1348] [d3d9] Request high-priority shader compiles as necessary --- src/d3d9/d3d9_device.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index c785a0b60..07d683603 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -6215,8 +6215,13 @@ namespace dxvk { template void D3D9DeviceEx::BindShader( const D3D9CommonShader* pShaderModule) { + auto shader = pShaderModule->GetShader(); + + if (unlikely(shader->needsLibraryCompile())) + m_dxvkDevice->requestCompileShader(shader); + EmitCs([ - cShader = pShaderModule->GetShader() + cShader = std::move(shader) ] (DxvkContext* ctx) mutable { constexpr VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); ctx->bindShader(std::move(cShader)); From a4848201f82514789ac4e122ad20abc0ad2e042c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 11 Aug 2022 13:13:02 +0200 Subject: [PATCH 0527/1348] [dxvk] Update buffer views in commitGraphicsBarriers Otherwise we might end up accessing stale buffer slices, since this happens before descriptor updates. This is not needed for compute. Also fix weird indentation while we're at it. --- src/dxvk/dxvk_context.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 2f5460026..6486d2671 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5580,8 +5580,8 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: if ((slot.bufferSlice.length()) && (slot.bufferSlice.bufferInfo().access & storageBufferAccess)) { - requiresBarrier = this->checkBufferBarrier(slot.bufferSlice, - util::pipelineStages(binding.stages), binding.access); + requiresBarrier = this->checkBufferBarrier(slot.bufferSlice, + util::pipelineStages(binding.stages), binding.access); } break; @@ -5589,8 +5589,9 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: if ((slot.bufferView != nullptr) && (slot.bufferView->bufferInfo().access & storageBufferAccess)) { - requiresBarrier = this->checkBufferViewBarrier(slot.bufferView, - util::pipelineStages(binding.stages), binding.access); + slot.bufferView->updateView(); + requiresBarrier = this->checkBufferViewBarrier(slot.bufferView, + util::pipelineStages(binding.stages), binding.access); } break; @@ -5599,8 +5600,8 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: if ((slot.imageView != nullptr) && (slot.imageView->imageInfo().access & storageImageAccess)) { - requiresBarrier = this->checkImageViewBarrier(slot.imageView, - util::pipelineStages(binding.stages), binding.access); + requiresBarrier = this->checkImageViewBarrier(slot.imageView, + util::pipelineStages(binding.stages), binding.access); } break; From 715b5119e6344726fb85ac7ecea25292647ccdc1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 11 Aug 2022 13:43:38 +0200 Subject: [PATCH 0528/1348] [dxvk] Fix check in DxvkShaderPipelineLibrary::compilePipeline Since we destroy pipelines on 32-bit we should just make sure this doesn't get executed unnecessarily. --- src/dxvk/dxvk_shader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 9ee0e2feb..e840d95cc 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -947,7 +947,7 @@ namespace dxvk { std::lock_guard lock(m_mutex); // Skip if a pipeline has already been compiled - if (m_pipeline) + if (m_compiledOnce) return; // Compile the pipeline with default args From 673797c36af91037ea2f16750c8d55dcdf8b6686 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 11 Aug 2022 14:00:57 +0200 Subject: [PATCH 0529/1348] [dxvk] Fix hang on exit with high priority queue No idea why I'm not seeing hangs on my end, but this is definitely a bug. --- src/dxvk/dxvk_pipemanager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index ffd52f2b3..8004f2089 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -88,6 +88,7 @@ namespace dxvk { m_workersRunning = false; m_queueCond.notify_all(); + m_queueCondPrioritized.notify_all(); } for (auto& worker : m_workers) From 0d33d063ca671b159e1ec6d3a4fcb25cc98a7a82 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 11 Aug 2022 16:01:53 +0200 Subject: [PATCH 0530/1348] [dxvk] Remove device LUID workaround winevulkan properly supports this now. --- src/d3d9/d3d9_adapter.cpp | 6 +++--- src/dxgi/dxgi_adapter.cpp | 6 +++--- src/dxvk/dxvk_adapter.cpp | 3 --- src/dxvk/dxvk_device_info.h | 1 - src/dxvk/dxvk_instance.cpp | 4 ++-- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/d3d9/d3d9_adapter.cpp b/src/d3d9/d3d9_adapter.cpp index 6a5762d4c..7ca05fffe 100644 --- a/src/d3d9/d3d9_adapter.cpp +++ b/src/d3d9/d3d9_adapter.cpp @@ -702,10 +702,10 @@ namespace dxvk { if (pLUID == nullptr) return D3DERR_INVALIDCALL; - auto& deviceId = m_adapter->devicePropertiesExt().coreDeviceId; + auto& vk11 = m_adapter->devicePropertiesExt().vk11; - if (deviceId.deviceLUIDValid) - *pLUID = bit::cast(deviceId.deviceLUID); + if (vk11.deviceLUIDValid) + *pLUID = bit::cast(vk11.deviceLUID); else *pLUID = dxvk::GetAdapterLUID(m_ordinal); diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index 84a43bc73..7c1de323e 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -244,7 +244,7 @@ namespace dxvk { auto deviceProp = m_adapter->deviceProperties(); auto memoryProp = m_adapter->memoryProperties(); - auto deviceId = m_adapter->devicePropertiesExt().coreDeviceId; + auto vk11 = m_adapter->devicePropertiesExt().vk11; // Custom Vendor / Device ID if (options->customVendorId >= 0) @@ -324,8 +324,8 @@ namespace dxvk { pDesc->GraphicsPreemptionGranularity = DXGI_GRAPHICS_PREEMPTION_DMA_BUFFER_BOUNDARY; pDesc->ComputePreemptionGranularity = DXGI_COMPUTE_PREEMPTION_DMA_BUFFER_BOUNDARY; - if (deviceId.deviceLUIDValid) - std::memcpy(&pDesc->AdapterLuid, deviceId.deviceLUID, VK_LUID_SIZE); + if (vk11.deviceLUIDValid) + std::memcpy(&pDesc->AdapterLuid, vk11.deviceLUID, VK_LUID_SIZE); else pDesc->AdapterLuid = GetAdapterLUID(m_index); diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index da5912771..cf694c0b5 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -618,9 +618,6 @@ namespace dxvk { m_deviceInfo.vk13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES; m_deviceInfo.vk13.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.vk13); - m_deviceInfo.coreDeviceId.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; - m_deviceInfo.coreDeviceId.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.coreDeviceId); - if (m_deviceExtensions.supports(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) { m_deviceInfo.extConservativeRasterization.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT; m_deviceInfo.extConservativeRasterization.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extConservativeRasterization); diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 212bd69c5..895dfcb84 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -14,7 +14,6 @@ namespace dxvk { */ struct DxvkDeviceInfo { VkPhysicalDeviceProperties2 core; - VkPhysicalDeviceIDProperties coreDeviceId; VkPhysicalDeviceVulkan11Properties vk11; VkPhysicalDeviceVulkan12Properties vk12; VkPhysicalDeviceVulkan13Properties vk13; diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index 189418c72..1d56910d9 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -61,9 +61,9 @@ namespace dxvk { Rc DxvkInstance::findAdapterByLuid(const void* luid) const { for (const auto& adapter : m_adapters) { - const auto& deviceId = adapter->devicePropertiesExt().coreDeviceId; + const auto& vk11 = adapter->devicePropertiesExt().vk11; - if (deviceId.deviceLUIDValid && !std::memcmp(luid, deviceId.deviceLUID, VK_LUID_SIZE)) + if (vk11.deviceLUIDValid && !std::memcmp(luid, vk11.deviceLUID, VK_LUID_SIZE)) return adapter; } From 67614917c353b65e0d9b3428e34955077a2379a9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 11 Aug 2022 20:20:59 +0200 Subject: [PATCH 0531/1348] [meta] Update README on shader compiler threads --- dxvk.conf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dxvk.conf b/dxvk.conf index 1bf8a99a1..83a1b0d57 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -237,8 +237,12 @@ # Sets number of pipeline compiler threads. # +# If the graphics pipeline library feature is enabled, the given +# number of threads will be used for shader compilation. Some of +# these threads will be reserved for high-priority work. +# # Supported values: -# - 0 to automatically determine the number of threads to use +# - 0 to use all available CPU cores # - any positive number to enforce the thread count # dxvk.numCompilerThreads = 0 From 46cb05ce452e38351da8062dc74d27eedafbdfcd Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Thu, 11 Aug 2022 14:23:50 +0200 Subject: [PATCH 0532/1348] [d3d9+util] Always ignore D3DLOCK_DONOTWAIT We only ever stall when locking a texture that was previously used with GetRenderTargetData or GetFrontBufferData. Games are known to break if locking those textures doesn't succeed. --- src/d3d9/d3d9_device.cpp | 5 +++-- src/d3d9/d3d9_options.cpp | 1 - src/d3d9/d3d9_options.h | 3 --- src/util/config/config.cpp | 19 ------------------- 4 files changed, 3 insertions(+), 25 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 07d683603..63c92dd68 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4200,8 +4200,9 @@ namespace dxvk { if (unlikely((Flags & (D3DLOCK_DISCARD | D3DLOCK_READONLY)) == (D3DLOCK_DISCARD | D3DLOCK_READONLY))) return D3DERR_INVALIDCALL; - if (unlikely(!m_d3d9Options.allowDoNotWait)) - Flags &= ~D3DLOCK_DONOTWAIT; + // We only ever wait for textures that were used with GetRenderTargetData or GetFrontBufferData anyway. + // Games like Beyond Good and Evil break if this doesn't succeed. + Flags &= ~D3DLOCK_DONOTWAIT; if (unlikely((Flags & (D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE)) == (D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE))) Flags &= ~D3DLOCK_DISCARD; diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index 822bc4551..ce0a43204 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -63,7 +63,6 @@ namespace dxvk { this->forceSamplerTypeSpecConstants = config.getOption ("d3d9.forceSamplerTypeSpecConstants", false); this->forceSwapchainMSAA = config.getOption ("d3d9.forceSwapchainMSAA", -1); this->forceAspectRatio = config.getOption ("d3d9.forceAspectRatio", ""); - this->allowDoNotWait = config.getOption ("d3d9.allowDoNotWait", true); this->allowDiscard = config.getOption ("d3d9.allowDiscard", true); this->enumerateByDisplays = config.getOption ("d3d9.enumerateByDisplays", true); this->longMad = config.getOption ("d3d9.longMad", false); diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index 2a091fc45..51dd57faf 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -120,9 +120,6 @@ namespace dxvk { /// Forces an MSAA level on the swapchain int32_t forceSwapchainMSAA; - /// Allow D3DLOCK_DONOTWAIT - bool allowDoNotWait; - /// Allow D3DLOCK_DISCARD bool allowDiscard; diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index be6a1c04a..c26474e2a 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -386,15 +386,6 @@ namespace dxvk { { R"(\\TESV\.exe$)", {{ { "d3d9.customVendorId", "1002" }, }} }, - /* RTHDRIBL Demo - Uses DONOTWAIT after GetRenderTargetData - then goes into an infinite loop if it gets - D3DERR_WASSTILLDRAWING. - This is a better solution than penalizing - other apps that use this properly. */ - { R"(\\rthdribl\.exe$)", {{ - { "d3d9.allowDoNotWait", "False" }, - }} }, /* Hyperdimension Neptunia U: Action Unleashed */ { R"(\\Neptunia\.exe$)", {{ { "d3d9.forceAspectRatio", "16:9" }, @@ -562,11 +553,6 @@ namespace dxvk { { R"(\\eoa\.exe$)", {{ { "d3d9.customVendorId", "10de" }, }} }, - /* Beyond Good And Evil * - * Fixes missing sun and light shafts */ - { R"(\\BGE\.exe$)", {{ - { "d3d9.allowDoNotWait", "False" }, - }} }, /* Supreme Commander & Forged Alliance Forever */ { R"(\\(SupremeCommander|ForgedAlliance)\.exe$)", {{ { "d3d9.floatEmulation", "Strict" }, @@ -580,11 +566,6 @@ namespace dxvk { { R"(\\bionic_commando\.exe$)", {{ { "d3d9.maxFrameRate", "60" }, }} }, - /* Port Royale 3 * - * Fixes infinite loading screens */ - { R"(\\PortRoyale3\.exe$)", {{ - { "d3d9.allowDoNotWait", "False" }, - }} }, /* Need For Speed 3 modern patch */ { R"(\\nfs3\.exe$)", {{ { "d3d9.enableDialogMode", "True" }, From de8d2b37bb0dfcb521730c496eab194830fdd2f9 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sat, 13 Aug 2022 15:35:27 +0200 Subject: [PATCH 0533/1348] [d3d9] FF: Don't change flatShadingMask for outputs --- src/d3d9/d3d9_fixed_function.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index a2c2e41f7..7c7629a9b 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -790,7 +790,7 @@ namespace dxvk { bool diffuseOrSpec = semantic == DxsoSemantic{ DxsoUsage::Color, 0 } || semantic == DxsoSemantic{ DxsoUsage::Color, 1 }; - if (diffuseOrSpec) + if (diffuseOrSpec && input) m_flatShadingMask |= 1u << slot; std::string name = str::format(input ? "in_" : "out_", semantic.usage, semantic.usageIndex); From 7506f658017f4d915a975127b44e662420b03c7e Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 14 Aug 2022 17:15:44 +0000 Subject: [PATCH 0534/1348] [d3d9] Move window proc handling code to own file --- src/d3d9/d3d9_swapchain.cpp | 166 +----------------------------------- src/d3d9/d3d9_window.cpp | 143 +++++++++++++++++++++++++++++++ src/d3d9/d3d9_window.h | 37 ++++++++ src/d3d9/meson.build | 3 +- 4 files changed, 183 insertions(+), 166 deletions(-) create mode 100644 src/d3d9/d3d9_window.cpp create mode 100644 src/d3d9/d3d9_window.h diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 0caa562d8..450070784 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -3,174 +3,10 @@ #include "d3d9_monitor.h" #include "d3d9_hud.h" +#include "d3d9_window.h" namespace dxvk { - - struct D3D9WindowData { - bool unicode; - bool filter; - bool activateProcessed; - WNDPROC proc; - D3D9SwapChainEx* swapchain; - }; - - - static dxvk::recursive_mutex g_windowProcMapMutex; - static std::unordered_map g_windowProcMap; - - static void SetActivateProcessed(HWND window, bool processed) - { - std::lock_guard lock(g_windowProcMapMutex); - auto it = g_windowProcMap.find(window); - if (it != g_windowProcMap.end()) - it->second.activateProcessed = processed; - } - - template - auto CallCharsetFunction(T unicode, J ascii, bool isUnicode, Args... args) { - return isUnicode - ? unicode(args...) - : ascii (args...); - } - - - class D3D9WindowMessageFilter { - - public: - - D3D9WindowMessageFilter(HWND window, bool filter = true) - : m_window(window) { - std::lock_guard lock(g_windowProcMapMutex); - auto it = g_windowProcMap.find(m_window); - m_filter = std::exchange(it->second.filter, filter); - } - - ~D3D9WindowMessageFilter() { - std::lock_guard lock(g_windowProcMapMutex); - auto it = g_windowProcMap.find(m_window); - it->second.filter = m_filter; - } - - D3D9WindowMessageFilter (const D3D9WindowMessageFilter&) = delete; - D3D9WindowMessageFilter& operator = (const D3D9WindowMessageFilter&) = delete; - - private: - - HWND m_window; - bool m_filter; - - }; - - - LRESULT CALLBACK D3D9WindowProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam); - - - void ResetWindowProc(HWND window) { - std::lock_guard lock(g_windowProcMapMutex); - - auto it = g_windowProcMap.find(window); - if (it == g_windowProcMap.end()) - return; - - auto proc = reinterpret_cast( - CallCharsetFunction( - GetWindowLongPtrW, GetWindowLongPtrA, it->second.unicode, - window, GWLP_WNDPROC)); - - - if (proc == D3D9WindowProc) - CallCharsetFunction( - SetWindowLongPtrW, SetWindowLongPtrA, it->second.unicode, - window, GWLP_WNDPROC, reinterpret_cast(it->second.proc)); - - g_windowProcMap.erase(window); - } - - - void HookWindowProc(HWND window, D3D9SwapChainEx* swapchain) { - std::lock_guard lock(g_windowProcMapMutex); - - ResetWindowProc(window); - - D3D9WindowData windowData; - windowData.unicode = IsWindowUnicode(window); - windowData.filter = false; - windowData.activateProcessed = false; - windowData.proc = reinterpret_cast( - CallCharsetFunction( - SetWindowLongPtrW, SetWindowLongPtrA, windowData.unicode, - window, GWLP_WNDPROC, reinterpret_cast(D3D9WindowProc))); - windowData.swapchain = swapchain; - - g_windowProcMap[window] = std::move(windowData); - } - - - LRESULT CALLBACK D3D9WindowProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) { - if (message == WM_NCCALCSIZE && wparam == TRUE) - return 0; - - D3D9WindowData windowData = {}; - - { - std::lock_guard lock(g_windowProcMapMutex); - - auto it = g_windowProcMap.find(window); - if (it != g_windowProcMap.end()) - windowData = it->second; - } - - bool unicode = windowData.proc - ? windowData.unicode - : IsWindowUnicode(window); - - if (!windowData.proc || windowData.filter) - return CallCharsetFunction( - DefWindowProcW, DefWindowProcA, unicode, - window, message, wparam, lparam); - - if (message == WM_DESTROY) - ResetWindowProc(window); - else if (message == WM_ACTIVATEAPP) { - D3DDEVICE_CREATION_PARAMETERS create_parms; - windowData.swapchain->GetDevice()->GetCreationParameters(&create_parms); - - if (!(create_parms.BehaviorFlags & D3DCREATE_NOWINDOWCHANGES)) { - D3D9WindowMessageFilter filter(window); - if (wparam && !windowData.activateProcessed) { - // Heroes of Might and Magic V needs this to resume drawing after a focus loss - D3DPRESENT_PARAMETERS params; - RECT rect; - - GetMonitorRect(GetDefaultMonitor(), &rect); - windowData.swapchain->GetPresentParameters(¶ms); - SetWindowPos(window, nullptr, rect.left, rect.top, params.BackBufferWidth, params.BackBufferHeight, - SWP_NOACTIVATE | SWP_NOZORDER); - SetActivateProcessed(window, true); - } - else if (!wparam) { - if (IsWindowVisible(window)) - ShowWindow(window, SW_MINIMIZE); - SetActivateProcessed(window, false); - } - } - } - else if (message == WM_SIZE) - { - D3DDEVICE_CREATION_PARAMETERS create_parms; - windowData.swapchain->GetDevice()->GetCreationParameters(&create_parms); - - if (!(create_parms.BehaviorFlags & D3DCREATE_NOWINDOWCHANGES) && !IsIconic(window)) - PostMessageW(window, WM_ACTIVATEAPP, 1, GetCurrentThreadId()); - } - - return CallCharsetFunction( - CallWindowProcW, CallWindowProcA, unicode, - windowData.proc, window, message, wparam, lparam); - } - - static uint16_t MapGammaControlPoint(float x) { if (x < 0.0f) x = 0.0f; if (x > 1.0f) x = 1.0f; diff --git a/src/d3d9/d3d9_window.cpp b/src/d3d9/d3d9_window.cpp new file mode 100644 index 000000000..68dadcdc0 --- /dev/null +++ b/src/d3d9/d3d9_window.cpp @@ -0,0 +1,143 @@ +#include "d3d9_window.h" + +#include "d3d9_swapchain.h" + +namespace dxvk +{ + + struct D3D9WindowData { + bool unicode; + bool filter; + bool activateProcessed; + WNDPROC proc; + D3D9SwapChainEx* swapchain; + }; + + static dxvk::recursive_mutex g_windowProcMapMutex; + static std::unordered_map g_windowProcMap; + + D3D9WindowMessageFilter::D3D9WindowMessageFilter(HWND window, bool filter) + : m_window(window) { + std::lock_guard lock(g_windowProcMapMutex); + auto it = g_windowProcMap.find(m_window); + m_filter = std::exchange(it->second.filter, filter); + } + + D3D9WindowMessageFilter::~D3D9WindowMessageFilter() { + std::lock_guard lock(g_windowProcMapMutex); + auto it = g_windowProcMap.find(m_window); + it->second.filter = m_filter; + } + + LRESULT CALLBACK D3D9WindowProc(HWND window, UINT message, WPARAM wparam, LPARAM lparam) { + if (message == WM_NCCALCSIZE && wparam == TRUE) + return 0; + + D3D9WindowData windowData = {}; + + { + std::lock_guard lock(g_windowProcMapMutex); + + auto it = g_windowProcMap.find(window); + if (it != g_windowProcMap.end()) + windowData = it->second; + } + + bool unicode = windowData.proc + ? windowData.unicode + : IsWindowUnicode(window); + + if (!windowData.proc || windowData.filter) + return CallCharsetFunction( + DefWindowProcW, DefWindowProcA, unicode, + window, message, wparam, lparam); + + if (message == WM_DESTROY) + ResetWindowProc(window); + else if (message == WM_ACTIVATEAPP) { + D3DDEVICE_CREATION_PARAMETERS create_parms; + windowData.swapchain->GetDevice()->GetCreationParameters(&create_parms); + + if (!(create_parms.BehaviorFlags & D3DCREATE_NOWINDOWCHANGES)) { + D3D9WindowMessageFilter filter(window); + if (wparam && !windowData.activateProcessed) { + // Heroes of Might and Magic V needs this to resume drawing after a focus loss + D3DPRESENT_PARAMETERS params; + RECT rect; + + GetMonitorRect(GetDefaultMonitor(), &rect); + windowData.swapchain->GetPresentParameters(¶ms); + SetWindowPos(window, nullptr, rect.left, rect.top, params.BackBufferWidth, params.BackBufferHeight, + SWP_NOACTIVATE | SWP_NOZORDER); + SetActivateProcessed(window, true); + } + else if (!wparam) { + if (IsWindowVisible(window)) + ShowWindow(window, SW_MINIMIZE); + SetActivateProcessed(window, false); + } + } + } + else if (message == WM_SIZE) + { + D3DDEVICE_CREATION_PARAMETERS create_parms; + windowData.swapchain->GetDevice()->GetCreationParameters(&create_parms); + + if (!(create_parms.BehaviorFlags & D3DCREATE_NOWINDOWCHANGES) && !IsIconic(window)) + PostMessageW(window, WM_ACTIVATEAPP, 1, GetCurrentThreadId()); + } + + return CallCharsetFunction( + CallWindowProcW, CallWindowProcA, unicode, + windowData.proc, window, message, wparam, lparam); + } + + void ResetWindowProc(HWND window) { + std::lock_guard lock(g_windowProcMapMutex); + + auto it = g_windowProcMap.find(window); + if (it == g_windowProcMap.end()) + return; + + auto proc = reinterpret_cast( + CallCharsetFunction( + GetWindowLongPtrW, GetWindowLongPtrA, it->second.unicode, + window, GWLP_WNDPROC)); + + + if (proc == D3D9WindowProc) + CallCharsetFunction( + SetWindowLongPtrW, SetWindowLongPtrA, it->second.unicode, + window, GWLP_WNDPROC, reinterpret_cast(it->second.proc)); + + g_windowProcMap.erase(window); + } + + + void HookWindowProc(HWND window, D3D9SwapChainEx* swapchain) { + std::lock_guard lock(g_windowProcMapMutex); + + ResetWindowProc(window); + + D3D9WindowData windowData; + windowData.unicode = IsWindowUnicode(window); + windowData.filter = false; + windowData.activateProcessed = false; + windowData.proc = reinterpret_cast( + CallCharsetFunction( + SetWindowLongPtrW, SetWindowLongPtrA, windowData.unicode, + window, GWLP_WNDPROC, reinterpret_cast(D3D9WindowProc))); + windowData.swapchain = swapchain; + + g_windowProcMap[window] = std::move(windowData); + } + + void SetActivateProcessed(HWND window, bool processed) + { + std::lock_guard lock(g_windowProcMapMutex); + auto it = g_windowProcMap.find(window); + if (it != g_windowProcMap.end()) + it->second.activateProcessed = processed; + } + +} diff --git a/src/d3d9/d3d9_window.h b/src/d3d9/d3d9_window.h new file mode 100644 index 000000000..84fcc0048 --- /dev/null +++ b/src/d3d9/d3d9_window.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +namespace dxvk { + + class D3D9SwapChainEx; + + class D3D9WindowMessageFilter { + + public: + + D3D9WindowMessageFilter(HWND window, bool filter = true); + ~D3D9WindowMessageFilter(); + + D3D9WindowMessageFilter (const D3D9WindowMessageFilter&) = delete; + D3D9WindowMessageFilter& operator = (const D3D9WindowMessageFilter&) = delete; + + private: + + HWND m_window; + bool m_filter; + + }; + + template + auto CallCharsetFunction(T unicode, J ascii, bool isUnicode, Args... args) { + return isUnicode + ? unicode(args...) + : ascii (args...); + } + + void ResetWindowProc(HWND window); + void HookWindowProc(HWND window, D3D9SwapChainEx* swapchain); + void SetActivateProcessed(HWND window, bool processed); + +} diff --git a/src/d3d9/meson.build b/src/d3d9/meson.build index 2641f58ee..1af266270 100644 --- a/src/d3d9/meson.build +++ b/src/d3d9/meson.build @@ -41,7 +41,8 @@ d3d9_src = [ 'd3d9_format_helpers.cpp', 'd3d9_hud.cpp', 'd3d9_annotation.cpp', - 'd3d9_mem.cpp' + 'd3d9_mem.cpp', + 'd3d9_window.cpp' ] d3d9_dll = shared_library('d3d9'+dll_ext, d3d9_src, glsl_generator.process(d3d9_shaders), d3d9_res, From 6baaa3a5f21d2fc1820dbab5492c2e92b6a1f838 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 14 Aug 2022 17:22:11 +0000 Subject: [PATCH 0535/1348] [d3d9] New window proc code on multiple platforms --- src/d3d9/d3d9_window.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/d3d9/d3d9_window.cpp b/src/d3d9/d3d9_window.cpp index 68dadcdc0..a7fa4a7de 100644 --- a/src/d3d9/d3d9_window.cpp +++ b/src/d3d9/d3d9_window.cpp @@ -5,6 +5,7 @@ namespace dxvk { +#ifdef _WIN32 struct D3D9WindowData { bool unicode; bool filter; @@ -139,5 +140,25 @@ namespace dxvk if (it != g_windowProcMap.end()) it->second.activateProcessed = processed; } +#else + D3D9WindowMessageFilter::D3D9WindowMessageFilter(HWND window, bool filter) { + + } + + D3D9WindowMessageFilter::~D3D9WindowMessageFilter() { + + } + + void ResetWindowProc(HWND window) { + + } + + void HookWindowProc(HWND window, D3D9SwapChainEx* swapchain) { + + } + + void SetActivateProcessed(HWND window, bool processed) { + } +#endif } From 870dd18f92157f3d9fd041fb2b695c7b24c93f01 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 16 Aug 2022 08:43:52 +0000 Subject: [PATCH 0536/1348] [d3d9] Set VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT for render targets Closes: #2825 --- src/d3d9/d3d9_common_texture.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 74100dfc8..8983a6f64 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -299,6 +299,13 @@ namespace dxvk { | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; } + const bool hasAttachmentFeedbackLoops = + m_device->GetDXVKDevice()->features().extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout; + const bool isRT = m_desc.Usage & D3DUSAGE_RENDERTARGET; + + if (isRT && hasAttachmentFeedbackLoops) + imageInfo.usage |= VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + if (ResourceType == D3DRTYPE_CUBETEXTURE) imageInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; From a78aab147e1c2d800c9685658354365660ec6c17 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 16 Aug 2022 10:39:06 +0000 Subject: [PATCH 0537/1348] [d3d9] Add feedback loop usage for DS --- src/d3d9/d3d9_common_texture.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 8983a6f64..a1a0ac0a5 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -283,15 +283,21 @@ namespace dxvk { imageInfo.viewFormats = m_mapping.Formats; } + const bool hasAttachmentFeedbackLoops = + m_device->GetDXVKDevice()->features().extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout; + const bool isRT = m_desc.Usage & D3DUSAGE_RENDERTARGET; + const bool isDS = m_desc.Usage & D3DUSAGE_DEPTHSTENCIL; + const bool isAutoGen = m_desc.Usage & D3DUSAGE_AUTOGENMIPMAP; + // Are we an RT, need to gen mips or an offscreen plain surface? - if (m_desc.Usage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP) || TryOffscreenRT) { + if (isRT || isAutoGen || TryOffscreenRT) { imageInfo.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; imageInfo.stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; imageInfo.access |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; } - if (m_desc.Usage & D3DUSAGE_DEPTHSTENCIL) { + if (isDS) { imageInfo.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; imageInfo.stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; @@ -299,11 +305,7 @@ namespace dxvk { | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; } - const bool hasAttachmentFeedbackLoops = - m_device->GetDXVKDevice()->features().extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout; - const bool isRT = m_desc.Usage & D3DUSAGE_RENDERTARGET; - - if (isRT && hasAttachmentFeedbackLoops) + if ((isRT || isDS) && hasAttachmentFeedbackLoops) imageInfo.usage |= VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; if (ResourceType == D3DRTYPE_CUBETEXTURE) From b885883e066ede39c116e96596ba284ce3c779ba Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 16 Aug 2022 08:46:40 +0000 Subject: [PATCH 0538/1348] [util] Rename NtTimerDuration to TimerDuration --- src/util/util_fps_limiter.cpp | 40 +++++++++++++++++------------------ src/util/util_fps_limiter.h | 16 +++++++------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/util/util_fps_limiter.cpp b/src/util/util_fps_limiter.cpp index 7716500b4..61677b013 100644 --- a/src/util/util_fps_limiter.cpp +++ b/src/util/util_fps_limiter.cpp @@ -33,8 +33,8 @@ namespace dxvk { if (!m_envOverride) { m_targetInterval = frameRate > 0.0 - ? NtTimerDuration(int64_t(double(NtTimerDuration::period::den) / frameRate)) - : NtTimerDuration::zero(); + ? TimerDuration(int64_t(double(TimerDuration::period::den) / frameRate)) + : TimerDuration::zero(); if (isEnabled() && !m_initialized) initialize(); @@ -46,8 +46,8 @@ namespace dxvk { std::lock_guard lock(m_mutex); m_refreshInterval = refreshRate > 0.0 - ? NtTimerDuration(int64_t(double(NtTimerDuration::period::den) / refreshRate)) - : NtTimerDuration::zero(); + ? TimerDuration(int64_t(double(TimerDuration::period::den) / refreshRate)) + : TimerDuration::zero(); } @@ -67,22 +67,22 @@ namespace dxvk { auto t0 = m_lastFrame; auto t1 = dxvk::high_resolution_clock::now(); - auto frameTime = std::chrono::duration_cast(t1 - t0); + auto frameTime = std::chrono::duration_cast(t1 - t0); if (frameTime * 100 > m_targetInterval * 103 - m_deviation * 100) { // If we have a slow frame, reset the deviation since we // do not want to compensate for low performance later on - m_deviation = NtTimerDuration::zero(); + m_deviation = TimerDuration::zero(); } else { // Don't call sleep if the amount of time to sleep is shorter // than the time the function calls are likely going to take - NtTimerDuration sleepDuration = m_targetInterval - m_deviation - frameTime; + TimerDuration sleepDuration = m_targetInterval - m_deviation - frameTime; t1 = sleep(t1, sleepDuration); // Compensate for any sleep inaccuracies in the next frame, and // limit cumulative deviation in order to avoid stutter in case we // have a number of slow frames immediately followed by a fast one. - frameTime = std::chrono::duration_cast(t1 - t0); + frameTime = std::chrono::duration_cast(t1 - t0); m_deviation += frameTime - m_targetInterval; m_deviation = std::min(m_deviation, m_targetInterval / 16); } @@ -91,8 +91,8 @@ namespace dxvk { } - FpsLimiter::TimePoint FpsLimiter::sleep(TimePoint t0, NtTimerDuration duration) { - if (duration <= NtTimerDuration::zero()) + FpsLimiter::TimePoint FpsLimiter::sleep(TimePoint t0, TimerDuration duration) { + if (duration <= TimerDuration::zero()) return t0; // On wine, we can rely on NtDelayExecution waiting for more or @@ -100,16 +100,16 @@ namespace dxvk { // spamming QueryPerformanceCounter for performance reasons. // On Windows, we busy-wait for the last couple of milliseconds // since sleeping is highly inaccurate and inconsistent. - NtTimerDuration sleepThreshold = m_sleepThreshold; + TimerDuration sleepThreshold = m_sleepThreshold; - if (m_sleepGranularity != NtTimerDuration::zero()) + if (m_sleepGranularity != TimerDuration::zero()) sleepThreshold += duration / 6; - NtTimerDuration remaining = duration; + TimerDuration remaining = duration; TimePoint t1 = t0; while (remaining > sleepThreshold) { - NtTimerDuration sleepDuration = remaining - sleepThreshold; + TimerDuration sleepDuration = remaining - sleepThreshold; if (NtDelayExecution) { LARGE_INTEGER ticks; @@ -121,14 +121,14 @@ namespace dxvk { } t1 = dxvk::high_resolution_clock::now(); - remaining -= std::chrono::duration_cast(t1 - t0); + remaining -= std::chrono::duration_cast(t1 - t0); t0 = t1; } // Busy-wait until we have slept long enough - while (remaining > NtTimerDuration::zero()) { + while (remaining > TimerDuration::zero()) { t1 = dxvk::high_resolution_clock::now(); - remaining -= std::chrono::duration_cast(t1 - t0); + remaining -= std::chrono::duration_cast(t1 - t0); t0 = t1; } @@ -152,16 +152,16 @@ namespace dxvk { // Wine's implementation of these functions is a stub as of 6.10, which is fine // since it uses select() in NtDelayExecution. This is only relevant for Windows. if (NtQueryTimerResolution && !NtQueryTimerResolution(&min, &max, &cur)) { - m_sleepGranularity = NtTimerDuration(cur); + m_sleepGranularity = TimerDuration(cur); if (NtSetTimerResolution && !NtSetTimerResolution(max, TRUE, &cur)) { Logger::info(str::format("Setting timer interval to ", (double(max) / 10.0), " us")); - m_sleepGranularity = NtTimerDuration(max); + m_sleepGranularity = TimerDuration(max); } } } else { // Assume 1ms sleep granularity by default - m_sleepGranularity = NtTimerDuration(10000); + m_sleepGranularity = TimerDuration(10000); } m_sleepThreshold = 4 * m_sleepGranularity; diff --git a/src/util/util_fps_limiter.h b/src/util/util_fps_limiter.h index 9601dc96f..ac3d92c8b 100644 --- a/src/util/util_fps_limiter.h +++ b/src/util/util_fps_limiter.h @@ -53,34 +53,34 @@ namespace dxvk { * \returns \c true if the target frame rate is non-zero. */ bool isEnabled() const { - return m_targetInterval != NtTimerDuration::zero(); + return m_targetInterval != TimerDuration::zero(); } private: using TimePoint = dxvk::high_resolution_clock::time_point; - using NtTimerDuration = std::chrono::duration>; + using TimerDuration = std::chrono::duration>; using NtQueryTimerResolutionProc = UINT (WINAPI *) (ULONG*, ULONG*, ULONG*); using NtSetTimerResolutionProc = UINT (WINAPI *) (ULONG, BOOL, ULONG*); using NtDelayExecutionProc = UINT (WINAPI *) (BOOL, LARGE_INTEGER*); dxvk::mutex m_mutex; - NtTimerDuration m_targetInterval = NtTimerDuration::zero(); - NtTimerDuration m_refreshInterval = NtTimerDuration::zero(); - NtTimerDuration m_deviation = NtTimerDuration::zero(); + TimerDuration m_targetInterval = TimerDuration::zero(); + TimerDuration m_refreshInterval = TimerDuration::zero(); + TimerDuration m_deviation = TimerDuration::zero(); TimePoint m_lastFrame; bool m_initialized = false; bool m_envOverride = false; - NtTimerDuration m_sleepGranularity = NtTimerDuration::zero(); - NtTimerDuration m_sleepThreshold = NtTimerDuration::zero(); + TimerDuration m_sleepGranularity = TimerDuration::zero(); + TimerDuration m_sleepThreshold = TimerDuration::zero(); NtDelayExecutionProc NtDelayExecution = nullptr; - TimePoint sleep(TimePoint t0, NtTimerDuration duration); + TimePoint sleep(TimePoint t0, TimerDuration duration); void initialize(); From 05a5b82f59a9db1d51f6849bcaa262fdb3b913a8 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 16 Aug 2022 08:52:24 +0000 Subject: [PATCH 0539/1348] [util] Move sleep granularity getting to own function --- src/util/util_fps_limiter.cpp | 12 ++++++++---- src/util/util_fps_limiter.h | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/util/util_fps_limiter.cpp b/src/util/util_fps_limiter.cpp index 61677b013..7bc9ed179 100644 --- a/src/util/util_fps_limiter.cpp +++ b/src/util/util_fps_limiter.cpp @@ -137,6 +137,14 @@ namespace dxvk { void FpsLimiter::initialize() { + updateSleepGranularity(); + m_sleepThreshold = 4 * m_sleepGranularity; + m_lastFrame = dxvk::high_resolution_clock::now(); + m_initialized = true; + } + + + void FpsLimiter::updateSleepGranularity() { HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll"); if (ntdll) { @@ -163,10 +171,6 @@ namespace dxvk { // Assume 1ms sleep granularity by default m_sleepGranularity = TimerDuration(10000); } - - m_sleepThreshold = 4 * m_sleepGranularity; - m_lastFrame = dxvk::high_resolution_clock::now(); - m_initialized = true; } } diff --git a/src/util/util_fps_limiter.h b/src/util/util_fps_limiter.h index ac3d92c8b..b5ad21bee 100644 --- a/src/util/util_fps_limiter.h +++ b/src/util/util_fps_limiter.h @@ -84,6 +84,8 @@ namespace dxvk { void initialize(); + void updateSleepGranularity(); + }; } From 5fcc9a1bd15cdfe34d78eee6c1781129d2beba6b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 16 Aug 2022 08:55:39 +0000 Subject: [PATCH 0540/1348] [util] Move platform specific sleep to own function in fps limiter --- src/util/util_fps_limiter.cpp | 21 +++++++++++++-------- src/util/util_fps_limiter.h | 2 ++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/util/util_fps_limiter.cpp b/src/util/util_fps_limiter.cpp index 7bc9ed179..66737eafe 100644 --- a/src/util/util_fps_limiter.cpp +++ b/src/util/util_fps_limiter.cpp @@ -111,14 +111,7 @@ namespace dxvk { while (remaining > sleepThreshold) { TimerDuration sleepDuration = remaining - sleepThreshold; - if (NtDelayExecution) { - LARGE_INTEGER ticks; - ticks.QuadPart = -sleepDuration.count(); - - NtDelayExecution(FALSE, &ticks); - } else { - std::this_thread::sleep_for(sleepDuration); - } + performSleep(sleepDuration); t1 = dxvk::high_resolution_clock::now(); remaining -= std::chrono::duration_cast(t1 - t0); @@ -173,4 +166,16 @@ namespace dxvk { } } + + void FpsLimiter::performSleep(TimerDuration sleepDuration) { + if (NtDelayExecution) { + LARGE_INTEGER ticks; + ticks.QuadPart = -sleepDuration.count(); + + NtDelayExecution(FALSE, &ticks); + } else { + std::this_thread::sleep_for(sleepDuration); + } + } + } diff --git a/src/util/util_fps_limiter.h b/src/util/util_fps_limiter.h index b5ad21bee..94890c2ce 100644 --- a/src/util/util_fps_limiter.h +++ b/src/util/util_fps_limiter.h @@ -86,6 +86,8 @@ namespace dxvk { void updateSleepGranularity(); + void performSleep(TimerDuration sleepDuration); + }; } From d1e2b892827a5aee8173259ac3860d843b61dded Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 16 Aug 2022 08:56:01 +0000 Subject: [PATCH 0541/1348] [util] Use chrono literal for ms in fps limiter --- src/util/util_fps_limiter.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/util/util_fps_limiter.cpp b/src/util/util_fps_limiter.cpp index 66737eafe..9354d6634 100644 --- a/src/util/util_fps_limiter.cpp +++ b/src/util/util_fps_limiter.cpp @@ -7,6 +7,8 @@ #include "./log/log.h" +using namespace std::chrono_literals; + namespace dxvk { FpsLimiter::FpsLimiter() { @@ -162,7 +164,7 @@ namespace dxvk { } } else { // Assume 1ms sleep granularity by default - m_sleepGranularity = TimerDuration(10000); + m_sleepGranularity = TimerDuration(1ms); } } From cf9e217e7b1cf78b949b52d7a2f6d38ca9d43d85 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 16 Aug 2022 08:57:40 +0000 Subject: [PATCH 0542/1348] [util] Support for fps limiter on non-Windows platforms Defaults to a sleep granularity of 0.5ms, which is slightly on the cautious side. Calls through to std::this_thread::sleep_for directly, which calls through to nanosleep. --- src/util/util_fps_limiter.cpp | 9 +++++++++ src/util/util_fps_limiter.h | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/util/util_fps_limiter.cpp b/src/util/util_fps_limiter.cpp index 9354d6634..f7255a2d4 100644 --- a/src/util/util_fps_limiter.cpp +++ b/src/util/util_fps_limiter.cpp @@ -140,6 +140,7 @@ namespace dxvk { void FpsLimiter::updateSleepGranularity() { +#ifdef _WIN32 HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll"); if (ntdll) { @@ -166,10 +167,15 @@ namespace dxvk { // Assume 1ms sleep granularity by default m_sleepGranularity = TimerDuration(1ms); } +#else + // Assume 0.5ms sleep granularity by default + m_sleepGranularity = TimerDuration(500us); +#endif } void FpsLimiter::performSleep(TimerDuration sleepDuration) { +#ifdef _WIN32 if (NtDelayExecution) { LARGE_INTEGER ticks; ticks.QuadPart = -sleepDuration.count(); @@ -178,6 +184,9 @@ namespace dxvk { } else { std::this_thread::sleep_for(sleepDuration); } +#else + std::this_thread::sleep_for(sleepDuration); +#endif } } diff --git a/src/util/util_fps_limiter.h b/src/util/util_fps_limiter.h index 94890c2ce..a45f3c0e9 100644 --- a/src/util/util_fps_limiter.h +++ b/src/util/util_fps_limiter.h @@ -60,10 +60,17 @@ namespace dxvk { using TimePoint = dxvk::high_resolution_clock::time_point; +#ifdef _WIN32 + // On Windows, we use NtDelayExecution which has units of 100ns. using TimerDuration = std::chrono::duration>; using NtQueryTimerResolutionProc = UINT (WINAPI *) (ULONG*, ULONG*, ULONG*); using NtSetTimerResolutionProc = UINT (WINAPI *) (ULONG, BOOL, ULONG*); using NtDelayExecutionProc = UINT (WINAPI *) (BOOL, LARGE_INTEGER*); + NtDelayExecutionProc NtDelayExecution = nullptr; +#else + // On other platforms, we use the std library, which calls through to nanosleep -- which is ns. + using TimerDuration = std::chrono::nanoseconds; +#endif dxvk::mutex m_mutex; @@ -78,8 +85,6 @@ namespace dxvk { TimerDuration m_sleepGranularity = TimerDuration::zero(); TimerDuration m_sleepThreshold = TimerDuration::zero(); - NtDelayExecutionProc NtDelayExecution = nullptr; - TimePoint sleep(TimePoint t0, TimerDuration duration); void initialize(); From 084969135b08129f2f262ed0c98610bb6ad3dd11 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 16 Aug 2022 12:32:32 +0000 Subject: [PATCH 0543/1348] [d3d9] Only set feedback loop usage on textures, not plain surfaces --- src/d3d9/d3d9_common_texture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index a1a0ac0a5..55b7182d9 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -305,7 +305,7 @@ namespace dxvk { | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; } - if ((isRT || isDS) && hasAttachmentFeedbackLoops) + if (ResourceType == D3DRTYPE_TEXTURE && (isRT || isDS) && hasAttachmentFeedbackLoops) imageInfo.usage |= VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; if (ResourceType == D3DRTYPE_CUBETEXTURE) From 9f9324c421b0749b9f9ae5cd1a14d66638bbf245 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 16 Aug 2022 15:24:16 +0200 Subject: [PATCH 0544/1348] [dxvk] Use existing bit mask iterator for descriptor set allocation --- src/dxvk/dxvk_descriptor.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index bb09d5178..ae155c265 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -82,15 +82,12 @@ namespace dxvk { VkDescriptorSet* sets) { auto setMap = getSetMapCached(layout); - while (setMask) { - uint32_t setIndex = bit::tzcnt(setMask); - + for (auto setIndex : bit::BitMask(setMask)) { sets[setIndex] = allocSet( setMap->sets[setIndex], layout->getSetLayout(setIndex)); m_setsUsed += 1; - setMask &= setMask - 1; } } From e0af668f6c4729b5fcb14c9bba764d69f7b8cca8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 16 Aug 2022 15:35:57 +0200 Subject: [PATCH 0545/1348] [dxvk] Use DxvkBindingLayoutObjects for set lookup directly Avoids pointer dereferencing on a really hot code path. This is also safe since there's a 1:1 mapping between the VkPipelineLayout and the given ovbject type. --- src/dxvk/dxvk_descriptor.cpp | 7 +++---- src/dxvk/dxvk_descriptor.h | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index ae155c265..13cc93a63 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -161,14 +161,13 @@ namespace dxvk { DxvkDescriptorSetMap* DxvkDescriptorPool::getSetMap( const DxvkBindingLayoutObjects* layout) { - auto pair = m_setMaps.find(layout->getPipelineLayout(false)); - if (likely(pair != m_setMaps.end())) { + auto pair = m_setMaps.find(layout); + if (likely(pair != m_setMaps.end())) return &pair->second; - } auto iter = m_setMaps.emplace( std::piecewise_construct, - std::tuple(layout->getPipelineLayout(false)), + std::tuple(layout), std::tuple()); for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { diff --git a/src/dxvk/dxvk_descriptor.h b/src/dxvk/dxvk_descriptor.h index 7c874f65d..876aae04b 100644 --- a/src/dxvk/dxvk_descriptor.h +++ b/src/dxvk/dxvk_descriptor.h @@ -136,10 +136,19 @@ namespace dxvk { DxvkDescriptorManager* m_manager; DxvkContextType m_contextType; - std::vector m_descriptorPools; - std::unordered_map m_setLists; - std::unordered_map m_setMaps; - std::pair m_cachedEntry; + std::vector m_descriptorPools; + + std::unordered_map< + VkDescriptorSetLayout, + DxvkDescriptorSetList> m_setLists; + + std::unordered_map< + const DxvkBindingLayoutObjects*, + DxvkDescriptorSetMap> m_setMaps; + + std::pair< + const DxvkBindingLayoutObjects*, + DxvkDescriptorSetMap*> m_cachedEntry; uint32_t m_setsAllocated = 0; uint32_t m_setsUsed = 0; From 04bc1bac730363b0706b2da13aff550e0f865ac8 Mon Sep 17 00:00:00 2001 From: Riesi Date: Tue, 16 Aug 2022 17:21:42 +0200 Subject: [PATCH 0546/1348] [util] Limit Beyond Good and Evil FPS to 60 UI breaks on higher FPS --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index c26474e2a..c4e2141bb 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -570,6 +570,11 @@ namespace dxvk { { R"(\\nfs3\.exe$)", {{ { "d3d9.enableDialogMode", "True" }, }} }, + /* Beyond Good And Evil * + * UI breaks at high fps */ + { R"(\\BGE\.exe$)", {{ + { "d3d9.maxFrameRate", "60" }, + }} }, /* Ninja Blade * * Transparent main character on Nvidia */ { R"(\\NinjaBlade\.exe$)", {{ From 61025c0079cfc452f0a6e65a022905053f904174 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 01:49:42 +0200 Subject: [PATCH 0547/1348] [dxvk] Don't disable frame rate limiter if vsync is enabled This only works if we know the actual refresh rate of the display. However, in a wine virtual desktop or with proton's fshack, this is often not the case, so we'd see a 60 Hz mode on a high-refresh rate display and never actually enable the limiter. --- dxvk.conf | 7 ++++--- src/d3d11/d3d11_swapchain.cpp | 4 ---- src/d3d9/d3d9_swapchain.cpp | 4 ---- src/util/util_fps_limiter.cpp | 16 ---------------- src/util/util_fps_limiter.h | 11 ----------- src/vulkan/vulkan_presenter.cpp | 5 ----- src/vulkan/vulkan_presenter.h | 10 ---------- 7 files changed, 4 insertions(+), 53 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index 83a1b0d57..a18e4d65d 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -19,9 +19,10 @@ # d3d9.maxFrameLatency = 0 -# Enables a frame rate limiter, unless the game is already -# limited to the same refresh rate by vertical synchronization. -# +# Enables frame rate limiter. The main purpose of this is to work around +# bugs in games that have physics or other simulation tied to their frame +# rate, but do not provide their own limiter. +# # Supported values : Any non-negative integer # dxgi.maxFrameRate = 0 diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 9cc114625..22e006c40 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -252,9 +252,6 @@ namespace dxvk { DXGI_RATIONAL rate = pDisplayMode->RefreshRate; m_displayRefreshRate = double(rate.Numerator) / double(rate.Denominator); } - - if (m_presenter != nullptr) - m_presenter->setFrameRateLimiterRefreshRate(m_displayRefreshRate); } @@ -407,7 +404,6 @@ namespace dxvk { presenterDesc); m_presenter->setFrameRateLimit(m_parent->GetOptions()->maxFrameRate); - m_presenter->setFrameRateLimiterRefreshRate(m_displayRefreshRate); CreateRenderTargetViews(); } diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 450070784..8ffe91765 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -798,7 +798,6 @@ namespace dxvk { presenterDesc); m_presenter->setFrameRateLimit(m_parent->GetOptions()->maxFrameRate); - m_presenter->setFrameRateLimiterRefreshRate(m_displayRefreshRate); CreateRenderTargetViews(); } @@ -1026,9 +1025,6 @@ namespace dxvk { void D3D9SwapChainEx::NotifyDisplayRefreshRate( double RefreshRate) { m_displayRefreshRate = RefreshRate; - - if (m_presenter != nullptr) - m_presenter->setFrameRateLimiterRefreshRate(RefreshRate); } diff --git a/src/util/util_fps_limiter.cpp b/src/util/util_fps_limiter.cpp index f7255a2d4..1bddcd410 100644 --- a/src/util/util_fps_limiter.cpp +++ b/src/util/util_fps_limiter.cpp @@ -44,28 +44,12 @@ namespace dxvk { } - void FpsLimiter::setDisplayRefreshRate(double refreshRate) { - std::lock_guard lock(m_mutex); - - m_refreshInterval = refreshRate > 0.0 - ? TimerDuration(int64_t(double(TimerDuration::period::den) / refreshRate)) - : TimerDuration::zero(); - } - - void FpsLimiter::delay(bool vsyncEnabled) { std::lock_guard lock(m_mutex); if (!isEnabled()) return; - // If the swap chain is known to have vsync enabled and the - // refresh rate is similar to the target frame rate, disable - // the limiter so it does not screw up frame times - if (vsyncEnabled && !m_envOverride - && m_refreshInterval * 100 > m_targetInterval * 97) - return; - auto t0 = m_lastFrame; auto t1 = dxvk::high_resolution_clock::now(); diff --git a/src/util/util_fps_limiter.h b/src/util/util_fps_limiter.h index a45f3c0e9..0d2d63258 100644 --- a/src/util/util_fps_limiter.h +++ b/src/util/util_fps_limiter.h @@ -28,16 +28,6 @@ namespace dxvk { */ void setTargetFrameRate(double frameRate); - /** - * \brief Sets display refresh rate - * - * This information is used to decide whether or not - * the limiter should be active in the first place in - * case vertical synchronization is enabled. - * \param [in] refreshRate Current refresh rate - */ - void setDisplayRefreshRate(double refreshRate); - /** * \brief Stalls calling thread as necessary * @@ -75,7 +65,6 @@ namespace dxvk { dxvk::mutex m_mutex; TimerDuration m_targetInterval = TimerDuration::zero(); - TimerDuration m_refreshInterval = TimerDuration::zero(); TimerDuration m_deviation = TimerDuration::zero(); TimePoint m_lastFrame; diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index f83ed22e0..b8c2d1225 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -232,11 +232,6 @@ namespace dxvk::vk { } - void Presenter::setFrameRateLimiterRefreshRate(double refreshRate) { - m_fpsLimiter.setDisplayRefreshRate(refreshRate); - } - - VkResult Presenter::getSupportedFormats(std::vector& formats, const PresenterDesc& desc) { uint32_t numFormats = 0; diff --git a/src/vulkan/vulkan_presenter.h b/src/vulkan/vulkan_presenter.h index 40562f6e6..8df19ea93 100644 --- a/src/vulkan/vulkan_presenter.h +++ b/src/vulkan/vulkan_presenter.h @@ -161,16 +161,6 @@ namespace dxvk::vk { */ void setFrameRateLimit(double frameRate); - /** - * \brief Notifies frame rate limiter about the display refresh rate - * - * Used to dynamically disable the frame rate limiter in case - * vertical synchronization is used and the target frame rate - * roughly equals the display's refresh rate. - * \param [in] refresnRate Current refresh rate - */ - void setFrameRateLimiterRefreshRate(double refreshRate); - /** * \brief Checks whether a Vulkan swap chain exists * From cc8010fb7ce16b2d0eece6b8863856717412d152 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 14:01:45 +0200 Subject: [PATCH 0548/1348] [dxvk] Add format feature queries to DxvkDevice --- src/dxvk/dxvk_adapter.cpp | 13 +++++++++++++ src/dxvk/dxvk_adapter.h | 10 ++++++++++ src/dxvk/dxvk_device.cpp | 33 +++++++++++++++++++++++++++++++++ src/dxvk/dxvk_device.h | 29 +++++++++++++++++++++++++++++ src/dxvk/dxvk_format.h | 22 +++++++++++++++++++++- 5 files changed, 106 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index cf694c0b5..62c08e4d1 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -60,6 +60,19 @@ namespace dxvk { } + DxvkFormatFeatures DxvkAdapter::getFormatFeatures(VkFormat format) const { + VkFormatProperties3 properties3 = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 }; + VkFormatProperties2 properties2 = { VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, &properties3 }; + m_vki->vkGetPhysicalDeviceFormatProperties2(m_handle, format, &properties2); + + DxvkFormatFeatures result; + result.optimal = properties3.optimalTilingFeatures; + result.linear = properties3.linearTilingFeatures; + result.buffer = properties3.bufferFeatures; + return result; + } + + VkFormatProperties DxvkAdapter::formatProperties(VkFormat format) const { VkFormatProperties formatProperties; m_vki->vkGetPhysicalDeviceFormatProperties(m_handle, format, &formatProperties); diff --git a/src/dxvk/dxvk_adapter.h b/src/dxvk/dxvk_adapter.h index 42af9d153..18ff77f5e 100644 --- a/src/dxvk/dxvk_adapter.h +++ b/src/dxvk/dxvk_adapter.h @@ -3,6 +3,7 @@ #include "dxvk_device_info.h" #include "dxvk_extensions.h" #include "dxvk_include.h" +#include "dxvk_format.h" namespace dxvk { @@ -135,6 +136,15 @@ namespace dxvk { */ VkPhysicalDeviceMemoryProperties memoryProperties() const; + /** + * \brief Queries format feature support + * + * \param [in] format Format to query + * \returns Format feature bits + */ + DxvkFormatFeatures getFormatFeatures( + VkFormat format) const; + /** * \brief Queries format support * diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 08289cee0..5f3f08774 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -43,6 +43,39 @@ namespace dxvk { } + std::optional DxvkDevice::getFormatLimits( + VkFormat format, + VkImageType type, + VkImageTiling tiling, + VkImageUsageFlags usage, + VkImageCreateFlags flags) const { + auto vk = m_adapter->vki(); + + VkPhysicalDeviceImageFormatInfo2 info = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 }; + info.format = format; + info.type = type; + info.tiling = tiling; + info.usage = usage; + info.flags = flags; + + VkImageFormatProperties2 properties = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 }; + + VkResult vr = vk->vkGetPhysicalDeviceImageFormatProperties2( + m_adapter->handle(), &info, &properties); + + if (vr != VK_SUCCESS) + return std::nullopt; + + DxvkFormatLimits result; + result.maxExtent = properties.imageFormatProperties.maxExtent; + result.maxMipLevels = properties.imageFormatProperties.maxMipLevels; + result.maxArrayLayers = properties.imageFormatProperties.maxArrayLayers; + result.sampleCounts = properties.imageFormatProperties.sampleCounts; + result.maxResourceSize = properties.imageFormatProperties.maxResourceSize; + return result; + } + + bool DxvkDevice::isUnifiedMemoryArchitecture() const { return m_adapter->isUnifiedMemoryArchitecture(); } diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index e8f44ee6a..7918c7b33 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "dxvk_adapter.h" #include "dxvk_buffer.h" #include "dxvk_compute.h" @@ -178,6 +180,33 @@ namespace dxvk { return m_properties; } + /** + * \brief Queries format feature support + * + * \param [in] format Format to query + * \returns Format feature bits + */ + DxvkFormatFeatures getFormatFeatures(VkFormat format) const { + return m_adapter->getFormatFeatures(format); + } + + /** + * \brief Queries format limits + * + * \param [in] format Image format to quers + * \param [in] type Image type + * \param [in] tiling Image tiling + * \param [in] usage Image usage flags + * \param [in] flags Image create flags + * \returns Format limits if the given image is supported + */ + std::optional getFormatLimits( + VkFormat format, + VkImageType type, + VkImageTiling tiling, + VkImageUsageFlags usage, + VkImageCreateFlags flags) const; + /** * \brief Get device status * diff --git a/src/dxvk/dxvk_format.h b/src/dxvk/dxvk_format.h index 5697ee9a3..6585deac5 100644 --- a/src/dxvk/dxvk_format.h +++ b/src/dxvk/dxvk_format.h @@ -13,7 +13,27 @@ namespace dxvk { }; using DxvkFormatFlags = Flags; - + + /** + * \brief Format support info + */ + struct DxvkFormatFeatures { + VkFormatFeatureFlags2 optimal; + VkFormatFeatureFlags2 linear; + VkFormatFeatureFlags2 buffer; + }; + + /** + * \brief Format support limits for a given set of image usage flags + */ + struct DxvkFormatLimits { + VkExtent3D maxExtent; + uint32_t maxMipLevels; + uint32_t maxArrayLayers; + VkSampleCountFlags sampleCounts; + VkDeviceSize maxResourceSize; + }; + /** * \brief Planar format info */ From 653a98f01b43673754a355ae26d6061953bec083 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 15:19:45 +0200 Subject: [PATCH 0549/1348] [dxvk] Use new format support queries --- src/dxvk/dxvk_graphics.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index c0ecbbb40..4285d04e1 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -1352,9 +1352,9 @@ namespace dxvk { if (!(ilBindingMask & (1u << attribute.binding()))) return false; - VkFormatProperties formatInfo = m_device->adapter()->formatProperties(attribute.format()); + DxvkFormatFeatures formatInfo = m_device->getFormatFeatures(attribute.format()); - if (!(formatInfo.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT)) + if (!(formatInfo.buffer & VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT)) return false; ilLocationMask |= 1u << attribute.location(); @@ -1378,9 +1378,9 @@ namespace dxvk { VkFormat depthFormat = state.rt.getDepthStencilFormat(); if (depthFormat) { - VkFormatProperties formatInfo = m_device->adapter()->formatProperties(depthFormat); + DxvkFormatFeatures formatInfo = m_device->getFormatFeatures(depthFormat); - if (!(formatInfo.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) + if (!(formatInfo.optimal & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) return false; } @@ -1388,9 +1388,9 @@ namespace dxvk { VkFormat colorFormat = state.rt.getColorFormat(i); if (colorFormat) { - VkFormatProperties formatInfo = m_device->adapter()->formatProperties(colorFormat); + DxvkFormatFeatures formatInfo = m_device->getFormatFeatures(colorFormat); - if (!(formatInfo.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) + if (!(formatInfo.optimal & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT)) return false; } } From 37179223818b3f46cabd97db033d31716d789ebb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 14:37:18 +0200 Subject: [PATCH 0550/1348] [d3d11,dxbc] Rework check for TypedUAVLoadAdditionalFormats --- src/d3d11/d3d11_device.cpp | 4 +--- src/d3d11/d3d11_device.h | 2 +- src/dxbc/dxbc_compiler.cpp | 4 ++-- src/dxbc/dxbc_options.cpp | 38 +++++++++++++++++++++++++++++++++++--- src/dxbc/dxbc_options.h | 6 ++++-- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 3cdc0bf79..8d7f38b21 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1681,10 +1681,9 @@ namespace dxvk { return E_INVALIDARG; const auto& extensions = m_dxvkDevice->extensions(); - const auto& features = m_dxvkDevice->features(); info->PSSpecifiedStencilRefSupported = extensions.extShaderStencilExport; - info->TypedUAVLoadAdditionalFormats = features.core.features.shaderStorageImageReadWithoutFormat; + info->TypedUAVLoadAdditionalFormats = m_dxbcOptions.supportsTypedUavLoadExtended; info->ROVsSupported = FALSE; info->ConservativeRasterizationTier = D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED; info->MapOnDefaultTextures = TRUE; @@ -1977,7 +1976,6 @@ namespace dxvk { enabled.core.features.multiDrawIndirect = VK_TRUE; enabled.core.features.shaderFloat64 = supported.core.features.shaderFloat64; enabled.core.features.shaderInt64 = supported.core.features.shaderInt64; - enabled.core.features.shaderStorageImageReadWithoutFormat = supported.core.features.shaderStorageImageReadWithoutFormat; enabled.core.features.tessellationShader = VK_TRUE; } diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 9317eac06..da0e481b1 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -454,7 +454,7 @@ namespace dxvk { D3D11StateObjectSet m_rsStateObjects; D3D11StateObjectSet m_samplerObjects; D3D11ShaderModuleSet m_shaderModules; - + HRESULT CreateShaderModule( D3D11CommonShader* pShaderModule, DxvkShaderKey ShaderKey, diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 70aaa2e3f..c3028fbe4 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -876,7 +876,7 @@ namespace dxvk { const bool isUav = ins.op == DxbcOpcode::DclUavTyped; if (isUav) { - if (m_moduleInfo.options.useStorageImageReadWithoutFormat) + if (m_moduleInfo.options.supportsTypedUavLoadR32) m_module.enableCapability(spv::CapabilityStorageImageReadWithoutFormat); m_module.enableCapability(spv::CapabilityStorageImageWriteWithoutFormat); } @@ -951,7 +951,7 @@ namespace dxvk { if (isUav) { if ((m_analysis->uavInfos[registerId].accessAtomicOp) || (m_analysis->uavInfos[registerId].accessTypedLoad - && !m_moduleInfo.options.useStorageImageReadWithoutFormat)) + && !m_moduleInfo.options.supportsTypedUavLoadR32)) imageFormat = getScalarImageFormat(sampledType); } diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index f4f8b1726..f6b111a12 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -17,8 +17,6 @@ namespace dxvk { useDepthClipWorkaround = !devFeatures.extDepthClipEnable.depthClipEnable; - useStorageImageReadWithoutFormat - = devFeatures.core.features.shaderStorageImageReadWithoutFormat; useSubgroupOpsForAtomicCounters = (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_COMPUTE_BIT) && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); @@ -28,7 +26,41 @@ namespace dxvk { = (devInfo.vk11.subgroupSize >= 4) && (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); - + + supportsTypedUavLoadR32 = true; + supportsTypedUavLoadExtended = true; + + static const std::array, 18> s_typedUavFormats = { + std::make_pair(VK_FORMAT_R32_SFLOAT, false), + std::make_pair(VK_FORMAT_R32_UINT, false), + std::make_pair(VK_FORMAT_R32_SINT, false), + std::make_pair(VK_FORMAT_R32G32B32A32_SFLOAT, true), + std::make_pair(VK_FORMAT_R32G32B32A32_UINT, true), + std::make_pair(VK_FORMAT_R32G32B32A32_SINT, true), + std::make_pair(VK_FORMAT_R16G16B16A16_SFLOAT, true), + std::make_pair(VK_FORMAT_R16G16B16A16_UINT, true), + std::make_pair(VK_FORMAT_R16G16B16A16_SINT, true), + std::make_pair(VK_FORMAT_R8G8B8A8_UNORM, true), + std::make_pair(VK_FORMAT_R8G8B8A8_UINT, true), + std::make_pair(VK_FORMAT_R8G8B8A8_SINT, true), + std::make_pair(VK_FORMAT_R16_SFLOAT, true), + std::make_pair(VK_FORMAT_R16_UINT, true), + std::make_pair(VK_FORMAT_R16_SINT, true), + std::make_pair(VK_FORMAT_R8_UNORM, true), + std::make_pair(VK_FORMAT_R8_UINT, true), + std::make_pair(VK_FORMAT_R8_SINT, true), + }; + + for (const auto& f : s_typedUavFormats) { + DxvkFormatFeatures features = device->getFormatFeatures(f.first); + VkFormatFeatureFlags2 imgFeatures = features.optimal | features.linear; + + if (!(imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT)) { + supportsTypedUavLoadR32 &= f.second; + supportsTypedUavLoadExtended = false; + } + } + switch (device->config().useRawSsbo) { case Tristate::Auto: minSsboAlignment = devInfo.core.properties.limits.minStorageBufferOffsetAlignment; break; case Tristate::True: minSsboAlignment = 4u; break; diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index 1edec4c7b..3d13ad6a8 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -23,8 +23,10 @@ namespace dxvk { // clip device feature is not supported bool useDepthClipWorkaround = false; - /// Use the ShaderImageReadWithoutFormat capability. - bool useStorageImageReadWithoutFormat = false; + /// Determines whether format qualifiers + /// on typed UAV loads are required + bool supportsTypedUavLoadR32 = false; + bool supportsTypedUavLoadExtended = false; /// Use subgroup operations to reduce the number of /// atomic operations for append/consume buffers. From 099c70c2bdd13a22278692497101b2c3b5763083 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 14:09:50 +0200 Subject: [PATCH 0551/1348] [d3d11] Use new format support queries in resource creation --- src/d3d11/d3d11_buffer.cpp | 8 ++--- src/d3d11/d3d11_buffer.h | 2 +- src/d3d11/d3d11_texture.cpp | 58 +++++++++++++++++-------------------- src/d3d11/d3d11_texture.h | 2 +- src/d3d11/d3d11_util.cpp | 20 ++++++------- src/d3d11/d3d11_util.h | 4 +-- 6 files changed, 45 insertions(+), 49 deletions(-) diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index c53003a05..3069d71ef 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -156,7 +156,7 @@ namespace dxvk { // Check whether the given combination of buffer view // type and view format is supported by the device DXGI_VK_FORMAT_INFO viewFormat = m_parent->LookupFormat(Format, DXGI_VK_FORMAT_MODE_ANY); - VkFormatFeatureFlags features = GetBufferFormatFeatures(BindFlags); + VkFormatFeatureFlags2 features = GetBufferFormatFeatures(BindFlags); return CheckFormatFeatureSupport(viewFormat.Format, features); } @@ -201,9 +201,9 @@ namespace dxvk { BOOL D3D11Buffer::CheckFormatFeatureSupport( VkFormat Format, - VkFormatFeatureFlags Features) const { - VkFormatProperties properties = m_parent->GetDXVKDevice()->adapter()->formatProperties(Format); - return (properties.bufferFeatures & Features) == Features; + VkFormatFeatureFlags2 Features) const { + DxvkFormatFeatures support = m_parent->GetDXVKDevice()->getFormatFeatures(Format); + return (support.buffer & Features) == Features; } diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index a20121457..b13b18aa0 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -158,7 +158,7 @@ namespace dxvk { BOOL CheckFormatFeatureSupport( VkFormat Format, - VkFormatFeatureFlags Features) const; + VkFormatFeatureFlags2 Features) const; VkMemoryPropertyFlags GetMemoryFlags() const; diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 1c88c6556..5f8149026 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -359,7 +359,7 @@ namespace dxvk { if (imageInfo.flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) { // Check whether the given combination of image // view type and view format is actually supported - VkFormatFeatureFlags features = GetImageFormatFeatures(BindFlags); + VkFormatFeatureFlags2 features = GetImageFormatFeatures(BindFlags); if (!CheckFormatFeatureSupport(viewFormat.Format, features)) return false; @@ -444,77 +444,73 @@ namespace dxvk { BOOL D3D11CommonTexture::CheckImageSupport( const DxvkImageCreateInfo* pImageInfo, VkImageTiling Tiling) const { - const Rc adapter = m_device->GetDXVKDevice()->adapter(); - VkImageUsageFlags usage = pImageInfo->usage; if (pImageInfo->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - VkImageFormatProperties formatProps = { }; - VkResult status = adapter->imageFormatProperties( - pImageInfo->format, pImageInfo->type, Tiling, - usage, pImageInfo->flags, formatProps); + auto properties = m_device->GetDXVKDevice()->getFormatLimits( + pImageInfo->format, pImageInfo->type, Tiling, usage, pImageInfo->flags); - if (status != VK_SUCCESS) + if (!properties) return FALSE; - return (pImageInfo->extent.width <= formatProps.maxExtent.width) - && (pImageInfo->extent.height <= formatProps.maxExtent.height) - && (pImageInfo->extent.depth <= formatProps.maxExtent.depth) - && (pImageInfo->numLayers <= formatProps.maxArrayLayers) - && (pImageInfo->mipLevels <= formatProps.maxMipLevels) - && (pImageInfo->sampleCount & formatProps.sampleCounts); + return (pImageInfo->extent.width <= properties->maxExtent.width) + && (pImageInfo->extent.height <= properties->maxExtent.height) + && (pImageInfo->extent.depth <= properties->maxExtent.depth) + && (pImageInfo->numLayers <= properties->maxArrayLayers) + && (pImageInfo->mipLevels <= properties->maxMipLevels) + && (pImageInfo->sampleCount & properties->sampleCounts); } BOOL D3D11CommonTexture::CheckFormatFeatureSupport( VkFormat Format, - VkFormatFeatureFlags Features) const { - VkFormatProperties properties = m_device->GetDXVKDevice()->adapter()->formatProperties(Format); + VkFormatFeatureFlags2 Features) const { + DxvkFormatFeatures support = m_device->GetDXVKDevice()->getFormatFeatures(Format); - return (properties.linearTilingFeatures & Features) == Features - || (properties.optimalTilingFeatures & Features) == Features; + return (support.linear & Features) == Features + || (support.optimal & Features) == Features; } VkImageUsageFlags D3D11CommonTexture::EnableMetaCopyUsage( VkFormat Format, VkImageTiling Tiling) const { - VkFormatFeatureFlags requestedFeatures = 0; + VkFormatFeatureFlags2 requestedFeatures = 0; if (Format == VK_FORMAT_D16_UNORM || Format == VK_FORMAT_D32_SFLOAT) { - requestedFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT - | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; + requestedFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT + | VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT; } if (Format == VK_FORMAT_R16_UNORM || Format == VK_FORMAT_R32_SFLOAT) { - requestedFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT - | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; + requestedFeatures |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT + | VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT; } if (Format == VK_FORMAT_D32_SFLOAT_S8_UINT || Format == VK_FORMAT_D24_UNORM_S8_UINT) - requestedFeatures |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; + requestedFeatures |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT; - if (requestedFeatures == 0) + if (!requestedFeatures) return 0; // Enable usage flags for all supported and requested features - VkFormatProperties properties = m_device->GetDXVKDevice()->adapter()->formatProperties(Format); + DxvkFormatFeatures support = m_device->GetDXVKDevice()->getFormatFeatures(Format); requestedFeatures &= Tiling == VK_IMAGE_TILING_OPTIMAL - ? properties.optimalTilingFeatures - : properties.linearTilingFeatures; + ? support.optimal + : support.linear; VkImageUsageFlags requestedUsage = 0; - if (requestedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) + if (requestedFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT) requestedUsage |= VK_IMAGE_USAGE_SAMPLED_BIT; - if (requestedFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) + if (requestedFeatures & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT) requestedUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - if (requestedFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) + if (requestedFeatures & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT) requestedUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; return requestedUsage; diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index 2db2bc0c0..3ca91da21 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -405,7 +405,7 @@ namespace dxvk { BOOL CheckFormatFeatureSupport( VkFormat Format, - VkFormatFeatureFlags Features) const; + VkFormatFeatureFlags2 Features) const; VkImageUsageFlags EnableMetaCopyUsage( VkFormat Format, diff --git a/src/d3d11/d3d11_util.cpp b/src/d3d11/d3d11_util.cpp index 92f5f6d46..6c31ce3f7 100644 --- a/src/d3d11/d3d11_util.cpp +++ b/src/d3d11/d3d11_util.cpp @@ -78,29 +78,29 @@ namespace dxvk { } - VkFormatFeatureFlags GetBufferFormatFeatures(UINT BindFlags) { - VkFormatFeatureFlags features = 0; + VkFormatFeatureFlags2 GetBufferFormatFeatures(UINT BindFlags) { + VkFormatFeatureFlags2 features = 0; if (BindFlags & D3D11_BIND_SHADER_RESOURCE) - features |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT; + features |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT; if (BindFlags & D3D11_BIND_UNORDERED_ACCESS) - features |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT; + features |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT; return features; } - VkFormatFeatureFlags GetImageFormatFeatures(UINT BindFlags) { - VkFormatFeatureFlags features = 0; + VkFormatFeatureFlags2 GetImageFormatFeatures(UINT BindFlags) { + VkFormatFeatureFlags2 features = 0; if (BindFlags & D3D11_BIND_DEPTH_STENCIL) - features |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; + features |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT; if (BindFlags & D3D11_BIND_RENDER_TARGET) - features |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; + features |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT; if (BindFlags & D3D11_BIND_SHADER_RESOURCE) - features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; + features |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT; if (BindFlags & D3D11_BIND_UNORDERED_ACCESS) - features |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; + features |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT; return features; } diff --git a/src/d3d11/d3d11_util.h b/src/d3d11/d3d11_util.h index 8913d2c3a..beb3e13bc 100644 --- a/src/d3d11/d3d11_util.h +++ b/src/d3d11/d3d11_util.h @@ -31,10 +31,10 @@ namespace dxvk { VkConservativeRasterizationModeEXT DecodeConservativeRasterizationMode( D3D11_CONSERVATIVE_RASTERIZATION_MODE Mode); - VkFormatFeatureFlags GetBufferFormatFeatures( + VkFormatFeatureFlags2 GetBufferFormatFeatures( UINT BindFlags); - VkFormatFeatureFlags GetImageFormatFeatures( + VkFormatFeatureFlags2 GetImageFormatFeatures( UINT BindFlags); VkFormat GetPackedDepthStencilFormat( From 4aeb397ba31aa3f4e94e9ba28f7193720f6e2ce6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 14:30:00 +0200 Subject: [PATCH 0552/1348] [d3d11] Use new format support queries to check D3D11 format support --- src/d3d11/d3d11_device.cpp | 120 ++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 62 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 8d7f38b21..a42f06009 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1477,13 +1477,10 @@ namespace dxvk { // Check if the device supports the given combination of format // and sample count. D3D exposes the opaque concept of quality // levels to the application, we'll just define one such level. - VkImageFormatProperties formatProps; + auto properties = m_dxvkDevice->getFormatLimits(format, + VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, 0); - VkResult status = m_dxvkAdapter->imageFormatProperties( - format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_SAMPLED_BIT, 0, formatProps); - - if ((status == VK_SUCCESS) && (formatProps.sampleCounts & sampleCountFlag)) + if (properties && (properties->sampleCounts & sampleCountFlag)) *pNumQualityLevels = 1; return S_OK; } @@ -1914,7 +1911,6 @@ namespace dxvk { enabled.core.features.geometryShader = VK_TRUE; enabled.core.features.robustBufferAccess = VK_TRUE; - enabled.core.features.shaderStorageImageWriteWithoutFormat = VK_TRUE; enabled.core.features.depthBounds = supported.core.features.depthBounds; enabled.vk11.shaderDrawParameters = VK_TRUE; @@ -2032,33 +2028,33 @@ namespace dxvk { if (pFlags2 != nullptr) *pFlags2 = 0; // Unsupported or invalid format - if (Format != DXGI_FORMAT_UNKNOWN && fmtMapping.Format == VK_FORMAT_UNDEFINED) + if (Format && fmtMapping.Format == VK_FORMAT_UNDEFINED) return E_FAIL; // Query Vulkan format properties and supported features for it const DxvkFormatInfo* fmtProperties = lookupFormatInfo(fmtMapping.Format); - VkFormatProperties fmtSupport = fmtMapping.Format != VK_FORMAT_UNDEFINED - ? m_dxvkAdapter->formatProperties(fmtMapping.Format) - : VkFormatProperties(); + DxvkFormatFeatures fmtSupport = fmtMapping.Format != VK_FORMAT_UNDEFINED + ? m_dxvkDevice->getFormatFeatures(fmtMapping.Format) + : DxvkFormatFeatures(); - VkFormatFeatureFlags bufFeatures = fmtSupport.bufferFeatures; - VkFormatFeatureFlags imgFeatures = fmtSupport.optimalTilingFeatures | fmtSupport.linearTilingFeatures; + VkFormatFeatureFlags2 bufFeatures = fmtSupport.buffer; + VkFormatFeatureFlags2 imgFeatures = fmtSupport.optimal | fmtSupport.linear; // For multi-plane images, we want to check available view formats as well if (fmtProperties->flags.test(DxvkFormatFlag::MultiPlane)) { - const VkFormatFeatureFlags featureMask - = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT - | VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT - | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT - | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT - | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; + const VkFormatFeatureFlags2 featureMask + = VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT + | VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT + | VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT + | VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT + | VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT; DXGI_VK_FORMAT_FAMILY formatFamily = LookupFamily(Format, DXGI_VK_FORMAT_MODE_ANY); for (uint32_t i = 0; i < formatFamily.FormatCount; i++) { - VkFormatProperties viewFmtSupport = m_dxvkAdapter->formatProperties(formatFamily.Formats[i]); - imgFeatures |= (viewFmtSupport.optimalTilingFeatures | viewFmtSupport.linearTilingFeatures) & featureMask; + DxvkFormatFeatures viewFmtSupport = m_dxvkDevice->getFormatFeatures(formatFamily.Formats[i]); + imgFeatures |= (viewFmtSupport.optimal | viewFmtSupport.linear) & featureMask; } } @@ -2066,12 +2062,11 @@ namespace dxvk { UINT flags2 = 0; // Format can be used for shader resource views with buffers - if (bufFeatures & VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT - || Format == DXGI_FORMAT_UNKNOWN) + if ((bufFeatures & VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT) || !Format) flags1 |= D3D11_FORMAT_SUPPORT_BUFFER; // Format can be used for vertex data - if (bufFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) + if (bufFeatures & VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT) flags1 |= D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER; // Format can be used for index data. Only @@ -2097,19 +2092,18 @@ namespace dxvk { || Format == DXGI_FORMAT_R32G32B32A32_SINT) flags1 |= D3D11_FORMAT_SUPPORT_SO_BUFFER; - if (imgFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT - || imgFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) { + if (imgFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) { const VkFormat depthFormat = LookupFormat(Format, DXGI_VK_FORMAT_MODE_DEPTH).Format; if (GetImageTypeSupport(fmtMapping.Format, VK_IMAGE_TYPE_1D)) flags1 |= D3D11_FORMAT_SUPPORT_TEXTURE1D; if (GetImageTypeSupport(fmtMapping.Format, VK_IMAGE_TYPE_2D)) flags1 |= D3D11_FORMAT_SUPPORT_TEXTURE2D; if (GetImageTypeSupport(fmtMapping.Format, VK_IMAGE_TYPE_3D)) flags1 |= D3D11_FORMAT_SUPPORT_TEXTURE3D; - + flags1 |= D3D11_FORMAT_SUPPORT_MIP | D3D11_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT; - + // Format can be read - if (imgFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) { + if (imgFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT) { flags1 |= D3D11_FORMAT_SUPPORT_TEXTURECUBE | D3D11_FORMAT_SUPPORT_SHADER_LOAD | D3D11_FORMAT_SUPPORT_SHADER_GATHER @@ -2123,7 +2117,7 @@ namespace dxvk { } // Format is a color format that can be used for rendering - if (imgFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) { + if (imgFeatures & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT) { flags1 |= D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_MIP_AUTOGEN | D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT; @@ -2133,14 +2127,14 @@ namespace dxvk { } // Format supports blending when used for rendering - if (imgFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) + if (imgFeatures & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT) flags1 |= D3D11_FORMAT_SUPPORT_BLENDABLE; // Format is a depth-stencil format that can be used for rendering - if (imgFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) + if (imgFeatures & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT) flags1 |= D3D11_FORMAT_SUPPORT_DEPTH_STENCIL; - // FIXME implement properly. This would require a VkSurface. + // Report supported swap chain formats if (Format == DXGI_FORMAT_R8G8B8A8_UNORM || Format == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB || Format == DXGI_FORMAT_B8G8R8A8_UNORM @@ -2151,16 +2145,14 @@ namespace dxvk { flags1 |= D3D11_FORMAT_SUPPORT_DISPLAY; // Query multisample support for this format - VkImageFormatProperties imgFmtProperties; - - VkResult status = m_dxvkAdapter->imageFormatProperties(fmtMapping.Format, - VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, - (fmtProperties->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) - ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT - : VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - 0, imgFmtProperties); - - if (status == VK_SUCCESS && imgFmtProperties.sampleCounts > VK_SAMPLE_COUNT_1_BIT) { + VkImageUsageFlags usage = (fmtProperties->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) + ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT + : VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + auto limits = m_dxvkDevice->getFormatLimits(fmtMapping.Format, + VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage, 0); + + if (limits && limits->sampleCounts > VK_SAMPLE_COUNT_1_BIT) { flags1 |= D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE | D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD; @@ -2168,19 +2160,27 @@ namespace dxvk { } // Format can be used for storage images or storage texel buffers - if ((bufFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) - && (imgFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) { + if ((bufFeatures & VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT) + && (imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT) + && (imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT)) { flags1 |= D3D11_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW; flags2 |= D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE; - if (m_dxvkDevice->features().core.features.shaderStorageImageReadWithoutFormat - || Format == DXGI_FORMAT_R32_UINT - || Format == DXGI_FORMAT_R32_SINT - || Format == DXGI_FORMAT_R32_FLOAT) - flags2 |= D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD; + if (m_dxbcOptions.supportsTypedUavLoadR32) { + // If the R32 formats are supported without format declarations, + // we can optionally support additional formats for typed loads + if (imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT) + flags2 |= D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD; + } else { + // Otherwise, we need to emit format declarations, so we can + // only support the basic set of R32 formats for typed loads + if (Format == DXGI_FORMAT_R32_FLOAT + || Format == DXGI_FORMAT_R32_UINT + || Format == DXGI_FORMAT_R32_SINT) + flags2 |= D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD; + } - if (Format == DXGI_FORMAT_R32_UINT - || Format == DXGI_FORMAT_R32_SINT) { + if (Format == DXGI_FORMAT_R32_UINT || Format == DXGI_FORMAT_R32_SINT) { flags2 |= D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_ADD | D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS | D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE @@ -2206,19 +2206,15 @@ namespace dxvk { BOOL D3D11Device::GetImageTypeSupport(VkFormat Format, VkImageType Type) const { - VkImageFormatProperties props; + auto properties = m_dxvkDevice->getFormatLimits(Format, + Type, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, 0); - VkResult status = m_dxvkAdapter->imageFormatProperties( - Format, Type, VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_SAMPLED_BIT, 0, props); - - if (status != VK_SUCCESS) { - status = m_dxvkAdapter->imageFormatProperties( - Format, Type, VK_IMAGE_TILING_LINEAR, - VK_IMAGE_USAGE_SAMPLED_BIT, 0, props); + if (!properties) { + properties = m_dxvkDevice->getFormatLimits(Format, + Type, VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_SAMPLED_BIT, 0); } - return status == VK_SUCCESS; + return properties.has_value(); } From 13152088d4524eacfbfdb856e5e1a6a56a79cb78 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 15:06:36 +0200 Subject: [PATCH 0553/1348] [dxgi] Use new format support queries to initialize format table --- src/d3d11/d3d11_device.cpp | 2 +- src/dxgi/dxgi_format.cpp | 18 +++++++++--------- src/dxgi/dxgi_format.h | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index a42f06009..b575f7ea6 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -41,7 +41,7 @@ namespace dxvk { m_featureFlags (FeatureFlags), m_dxvkDevice (pContainer->GetDXVKDevice()), m_dxvkAdapter (m_dxvkDevice->adapter()), - m_d3d11Formats (m_dxvkAdapter), + m_d3d11Formats (m_dxvkDevice), m_d3d11Options (m_dxvkDevice->instance()->config(), m_dxvkDevice), m_dxbcOptions (m_dxvkDevice, m_d3d11Options) { m_initializer = new D3D11Initializer(this); diff --git a/src/dxgi/dxgi_format.cpp b/src/dxgi/dxgi_format.cpp index 7c8278909..306f773ec 100644 --- a/src/dxgi/dxgi_format.cpp +++ b/src/dxgi/dxgi_format.cpp @@ -847,13 +847,13 @@ namespace dxvk { }}; - DXGIVkFormatTable::DXGIVkFormatTable(const Rc& adapter) + DXGIVkFormatTable::DXGIVkFormatTable(const Rc& device) : m_dxgiFormats (g_dxgiFormats), m_dxgiFamilies(g_dxgiFamilies) { // AMD do not support 24-bit depth buffers on Vulkan, // so we have to fall back to a 32-bit depth format. - if (!CheckImageFormatSupport(adapter, VK_FORMAT_D24_UNORM_S8_UINT, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { + if (!CheckImageFormatSupport(device, VK_FORMAT_D24_UNORM_S8_UINT, + VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) { Logger::info("DXGI: VK_FORMAT_D24_UNORM_S8_UINT -> VK_FORMAT_D32_SFLOAT_S8_UINT"); RemapDepthFormat(DXGI_FORMAT_R24G8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT); RemapDepthFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT); @@ -943,13 +943,13 @@ namespace dxvk { bool DXGIVkFormatTable::CheckImageFormatSupport( - const Rc& Adapter, + const Rc& Device, VkFormat Format, - VkFormatFeatureFlags Features) const { - VkFormatProperties supported = Adapter->formatProperties(Format); + VkFormatFeatureFlags2 Features) const { + DxvkFormatFeatures supported = Device->getFormatFeatures(Format); - return (supported.linearTilingFeatures & Features) == Features - || (supported.optimalTilingFeatures & Features) == Features; + return (supported.linear & Features) == Features + || (supported.optimal & Features) == Features; } diff --git a/src/dxgi/dxgi_format.h b/src/dxgi/dxgi_format.h index 59e64937f..01e001796 100644 --- a/src/dxgi/dxgi_format.h +++ b/src/dxgi/dxgi_format.h @@ -2,7 +2,7 @@ #include "dxgi_include.h" -#include "../dxvk/dxvk_adapter.h" +#include "../dxvk/dxvk_device.h" #include "../dxvk/dxvk_format.h" namespace dxvk { @@ -100,7 +100,7 @@ namespace dxvk { public: DXGIVkFormatTable( - const Rc& adapter); + const Rc& device); ~DXGIVkFormatTable(); /** @@ -155,9 +155,9 @@ namespace dxvk { DXGI_FORMAT Format) const; bool CheckImageFormatSupport( - const Rc& Adapter, + const Rc& Device, VkFormat Format, - VkFormatFeatureFlags Features) const; + VkFormatFeatureFlags2 Features) const; void RemapDepthFormat( DXGI_FORMAT Format, From 80fc1d8b25d86f3bf1dda4c0e4262b95b75805e3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 15:16:23 +0200 Subject: [PATCH 0554/1348] [d3d9] Use new format support queries --- src/d3d9/d3d9_adapter.cpp | 22 +++++++++--------- src/d3d9/d3d9_common_texture.cpp | 40 ++++++++++++++------------------ src/d3d9/d3d9_device.cpp | 1 - src/d3d9/d3d9_format.cpp | 16 ++++++------- src/d3d9/d3d9_format.h | 2 +- src/d3d9/d3d9_util.cpp | 8 +++---- src/d3d9/d3d9_util.h | 2 +- 7 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/d3d9/d3d9_adapter.cpp b/src/d3d9/d3d9_adapter.cpp index 7ca05fffe..c8e813c8a 100644 --- a/src/d3d9/d3d9_adapter.cpp +++ b/src/d3d9/d3d9_adapter.cpp @@ -717,32 +717,32 @@ namespace dxvk { VkFormat Format, DWORD Usage, D3DRESOURCETYPE RType) { - VkFormatFeatureFlags checkFlags = 0; + VkFormatFeatureFlags2 checkFlags = 0; if (RType != D3DRTYPE_SURFACE) - checkFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; + checkFlags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT; if (Usage & D3DUSAGE_RENDERTARGET) { - checkFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; + checkFlags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT; if (Usage & D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) - checkFlags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; + checkFlags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT; } if (Usage & D3DUSAGE_DEPTHSTENCIL) - checkFlags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; + checkFlags |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT; else - checkFlags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; + checkFlags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT; - VkFormatFeatureFlags checkFlagsMipGen = checkFlags; + VkFormatFeatureFlags2 checkFlagsMipGen = checkFlags; if (Usage & D3DUSAGE_AUTOGENMIPMAP) { - checkFlagsMipGen |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; - checkFlagsMipGen |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; + checkFlagsMipGen |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT; + checkFlagsMipGen |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT; } - VkFormatProperties fmtSupport = m_adapter->formatProperties(Format); - VkFormatFeatureFlags imgFeatures = fmtSupport.optimalTilingFeatures | fmtSupport.linearTilingFeatures; + DxvkFormatFeatures fmtSupport = m_adapter->getFormatFeatures(Format); + VkFormatFeatureFlags2 imgFeatures = fmtSupport.optimal | fmtSupport.linear; if ((imgFeatures & checkFlags) != checkFlags) return D3DERR_NOTAVAILABLE; diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 55b7182d9..e1d675b91 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -379,53 +379,49 @@ namespace dxvk { BOOL D3D9CommonTexture::CheckImageSupport( const DxvkImageCreateInfo* pImageInfo, VkImageTiling Tiling) const { - const Rc adapter = m_device->GetDXVKDevice()->adapter(); - - VkImageFormatProperties formatProps = { }; - - VkResult status = adapter->imageFormatProperties( + auto properties = m_device->GetDXVKDevice()->getFormatLimits( pImageInfo->format, pImageInfo->type, Tiling, - pImageInfo->usage, pImageInfo->flags, formatProps); + pImageInfo->usage, pImageInfo->flags); - if (status != VK_SUCCESS) + if (!properties) return FALSE; - return (pImageInfo->extent.width <= formatProps.maxExtent.width) - && (pImageInfo->extent.height <= formatProps.maxExtent.height) - && (pImageInfo->extent.depth <= formatProps.maxExtent.depth) - && (pImageInfo->numLayers <= formatProps.maxArrayLayers) - && (pImageInfo->mipLevels <= formatProps.maxMipLevels) - && (pImageInfo->sampleCount & formatProps.sampleCounts); + return (pImageInfo->extent.width <= properties->maxExtent.width) + && (pImageInfo->extent.height <= properties->maxExtent.height) + && (pImageInfo->extent.depth <= properties->maxExtent.depth) + && (pImageInfo->numLayers <= properties->maxArrayLayers) + && (pImageInfo->mipLevels <= properties->maxMipLevels) + && (pImageInfo->sampleCount & properties->sampleCounts); } VkImageUsageFlags D3D9CommonTexture::EnableMetaCopyUsage( VkFormat Format, VkImageTiling Tiling) const { - VkFormatFeatureFlags requestedFeatures = 0; + VkFormatFeatureFlags2 requestedFeatures = 0; if (Format == VK_FORMAT_D16_UNORM || Format == VK_FORMAT_D32_SFLOAT) - requestedFeatures |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; + requestedFeatures |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT; if (Format == VK_FORMAT_R16_UNORM || Format == VK_FORMAT_R32_SFLOAT) - requestedFeatures |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; + requestedFeatures |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT; - if (requestedFeatures == 0) + if (!requestedFeatures) return 0; // Enable usage flags for all supported and requested features - VkFormatProperties properties = m_device->GetDXVKDevice()->adapter()->formatProperties(Format); + DxvkFormatFeatures properties = m_device->GetDXVKDevice()->getFormatFeatures(Format); requestedFeatures &= Tiling == VK_IMAGE_TILING_OPTIMAL - ? properties.optimalTilingFeatures - : properties.linearTilingFeatures; + ? properties.optimal + : properties.linear; VkImageUsageFlags requestedUsage = 0; - if (requestedFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) + if (requestedFeatures & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT) requestedUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - if (requestedFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) + if (requestedFeatures & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT) requestedUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; return requestedUsage; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 63c92dd68..69064448e 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3903,7 +3903,6 @@ namespace dxvk { enabled.core.features.vertexPipelineStoresAndAtomics = supported.core.features.vertexPipelineStoresAndAtomics; // DXVK Meta - enabled.core.features.shaderStorageImageWriteWithoutFormat = VK_TRUE; enabled.core.features.imageCubeArray = VK_TRUE; // SM1 level hardware diff --git a/src/d3d9/d3d9_format.cpp b/src/d3d9/d3d9_format.cpp index 28da31584..089d9b1c0 100644 --- a/src/d3d9/d3d9_format.cpp +++ b/src/d3d9/d3d9_format.cpp @@ -435,14 +435,14 @@ namespace dxvk { // AMD do not support 24-bit depth buffers on Vulkan, // so we have to fall back to a 32-bit depth format. m_d24s8Support = CheckImageFormatSupport(adapter, VK_FORMAT_D24_UNORM_S8_UINT, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); + VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT); // NVIDIA do not support 16-bit depth buffers with stencil on Vulkan, // so we have to fall back to a 32-bit depth format. m_d16s8Support = CheckImageFormatSupport(adapter, VK_FORMAT_D16_UNORM_S8_UINT, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); + VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT); // VK_EXT_4444_formats if (!m_d24s8Support) @@ -538,11 +538,11 @@ namespace dxvk { bool D3D9VkFormatTable::CheckImageFormatSupport( const Rc& Adapter, VkFormat Format, - VkFormatFeatureFlags Features) const { - VkFormatProperties supported = Adapter->formatProperties(Format); + VkFormatFeatureFlags2 Features) const { + DxvkFormatFeatures supported = Adapter->getFormatFeatures(Format); - return (supported.linearTilingFeatures & Features) == Features - || (supported.optimalTilingFeatures & Features) == Features; + return (supported.linear & Features) == Features + || (supported.optimal & Features) == Features; } } \ No newline at end of file diff --git a/src/d3d9/d3d9_format.h b/src/d3d9/d3d9_format.h index 1b9f72a78..1bdb4fb02 100644 --- a/src/d3d9/d3d9_format.h +++ b/src/d3d9/d3d9_format.h @@ -209,7 +209,7 @@ namespace dxvk { bool CheckImageFormatSupport( const Rc& Adapter, VkFormat Format, - VkFormatFeatureFlags Features) const; + VkFormatFeatureFlags2 Features) const; bool m_d24s8Support; bool m_d16s8Support; diff --git a/src/d3d9/d3d9_util.cpp b/src/d3d9/d3d9_util.cpp index b5d24f44c..d740313e7 100644 --- a/src/d3d9/d3d9_util.cpp +++ b/src/d3d9/d3d9_util.cpp @@ -97,14 +97,14 @@ namespace dxvk { } - VkFormatFeatureFlags GetImageFormatFeatures(DWORD Usage) { - VkFormatFeatureFlags features = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; + VkFormatFeatureFlags2 GetImageFormatFeatures(DWORD Usage) { + VkFormatFeatureFlags2 features = VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT; if (Usage & D3DUSAGE_DEPTHSTENCIL) - features |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; + features |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT; if (Usage & D3DUSAGE_RENDERTARGET) - features |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; + features |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT; return features; } diff --git a/src/d3d9/d3d9_util.h b/src/d3d9/d3d9_util.h index bbde19add..ab564f907 100644 --- a/src/d3d9/d3d9_util.h +++ b/src/d3d9/d3d9_util.h @@ -102,7 +102,7 @@ namespace dxvk { VkFormat GetPackedDepthStencilFormat(D3D9Format Format); - VkFormatFeatureFlags GetImageFormatFeatures(DWORD Usage); + VkFormatFeatureFlags2 GetImageFormatFeatures(DWORD Usage); VkImageUsageFlags GetImageUsageFlags(DWORD Usage); From 5e394b5554fd282558e39cbd63787c73a438490b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 15:20:44 +0200 Subject: [PATCH 0555/1348] [dxvk] Remove old format support queries --- src/dxvk/dxvk_adapter.cpp | 19 ------------------- src/dxvk/dxvk_adapter.h | 30 +----------------------------- 2 files changed, 1 insertion(+), 48 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 62c08e4d1..b8ff0acfd 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -73,25 +73,6 @@ namespace dxvk { } - VkFormatProperties DxvkAdapter::formatProperties(VkFormat format) const { - VkFormatProperties formatProperties; - m_vki->vkGetPhysicalDeviceFormatProperties(m_handle, format, &formatProperties); - return formatProperties; - } - - - VkResult DxvkAdapter::imageFormatProperties( - VkFormat format, - VkImageType type, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkImageCreateFlags flags, - VkImageFormatProperties& properties) const { - return m_vki->vkGetPhysicalDeviceImageFormatProperties( - m_handle, format, type, tiling, usage, flags, &properties); - } - - DxvkAdapterQueueIndices DxvkAdapter::findQueueFamilies() const { uint32_t graphicsQueue = findQueueFamily( VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, diff --git a/src/dxvk/dxvk_adapter.h b/src/dxvk/dxvk_adapter.h index 18ff77f5e..c35fc47c5 100644 --- a/src/dxvk/dxvk_adapter.h +++ b/src/dxvk/dxvk_adapter.h @@ -21,7 +21,7 @@ namespace dxvk { }; /** - * \brief Adapter memory heap info + * \brief Adapter memory hfeap info * * Stores info about a heap, and the amount * of memory allocated from it by the app. @@ -145,34 +145,6 @@ namespace dxvk { DxvkFormatFeatures getFormatFeatures( VkFormat format) const; - /** - * \brief Queries format support - * - * \param [in] format The format to query - * \returns Format support info - */ - VkFormatProperties formatProperties( - VkFormat format) const; - - /** - * \brief Queries image format support - * - * \param [in] format Format to query - * \param [in] type Image type - * \param [in] tiling Image tiling - * \param [in] usage Image usage flags - * \param [in] flags Image create flags - * \param [out] properties Format properties - * \returns \c VK_SUCCESS or \c VK_ERROR_FORMAT_NOT_SUPPORTED - */ - VkResult imageFormatProperties( - VkFormat format, - VkImageType type, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkImageCreateFlags flags, - VkImageFormatProperties& properties) const; - /** * \brief Retrieves queue family indices * \returns Indices for all queue families From 52314ba4fd73674e0ed34785dc357d885157d24f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 15:37:54 +0200 Subject: [PATCH 0556/1348] [dxvk] Do not log storage image features that we no longer enable --- src/dxvk/dxvk_adapter.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index b8ff0acfd..3e5187129 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -787,9 +787,6 @@ namespace dxvk { "\n vertexPipelineStoresAndAtomics : ", features.core.features.vertexPipelineStoresAndAtomics ? "1" : "0", "\n fragmentStoresAndAtomics : ", features.core.features.fragmentStoresAndAtomics ? "1" : "0", "\n shaderImageGatherExtended : ", features.core.features.shaderImageGatherExtended ? "1" : "0", - "\n shaderStorageImageExtendedFormats : ", features.core.features.shaderStorageImageExtendedFormats ? "1" : "0", - "\n shaderStorageImageReadWithoutFormat : ", features.core.features.shaderStorageImageReadWithoutFormat ? "1" : "0", - "\n shaderStorageImageWriteWithoutFormat : ", features.core.features.shaderStorageImageWriteWithoutFormat ? "1" : "0", "\n shaderClipDistance : ", features.core.features.shaderClipDistance ? "1" : "0", "\n shaderCullDistance : ", features.core.features.shaderCullDistance ? "1" : "0", "\n shaderFloat64 : ", features.core.features.shaderFloat64 ? "1" : "0", From 7ddfcfeb207bf5a379ae457e3e9b0ee94a9316e5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 15:56:02 +0200 Subject: [PATCH 0557/1348] [tests] Also log D3D11_FEATURE_FORMAT_SUPPORT2 in format tester --- tests/d3d11/test_d3d11_formats.cpp | 33 +++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/tests/d3d11/test_d3d11_formats.cpp b/tests/d3d11/test_d3d11_formats.cpp index daac8365d..3ec7f26a5 100644 --- a/tests/d3d11/test_d3d11_formats.cpp +++ b/tests/d3d11/test_d3d11_formats.cpp @@ -158,6 +158,25 @@ std::string GetFormatFlagName(D3D11_FORMAT_SUPPORT Flag) { } +std::string GetFormatFlagName2(UINT Flag) { + switch (Flag) { + ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_ADD); + ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS); + ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE); + ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE); + ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX); + ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX); + ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD); + ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE); + ENUM_NAME(D3D11_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP); + ENUM_NAME(D3D11_FORMAT_SUPPORT2_TILED); + ENUM_NAME(D3D11_FORMAT_SUPPORT2_SHAREABLE); + ENUM_NAME(D3D11_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY); + default: return std::to_string(Flag); + } +} + + int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, @@ -263,7 +282,19 @@ int WINAPI WinMain(HINSTANCE hInstance, << std::endl; } } - + + D3D11_FEATURE_DATA_FORMAT_SUPPORT2 support2 = { }; + support2.InFormat = format; + + if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT2, &support2, sizeof(support2)))) { + for (uint32_t i = 0; i < 32; i++) { + if (support2.OutFormatSupport2 & (1u << i)) { + std::cout << " " + << GetFormatFlagName2(1u << i) + << std::endl; + } + } + } } else { std::cout << " Not supported" << std::endl; } From 3c2fc41e4c3832095388b656a7d0192f32e47172 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 12:56:45 +0200 Subject: [PATCH 0558/1348] [d3d9] Re-bind framebuffer if RT hazards change Otherwise we never set the feedback loop bits in the backend. --- src/d3d9/d3d9_device.cpp | 4 +++- src/d3d9/d3d9_device.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 69064448e..8f21204eb 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -6054,9 +6054,11 @@ namespace dxvk { if (unlikely(m_activeHazardsRT != 0)) MarkRenderHazards(); - if (unlikely((m_lastHazardsDS == 0) != (m_activeHazardsDS == 0))) { + if (unlikely((!m_lastHazardsDS) != (!m_activeHazardsDS)) + || unlikely((!m_lastHazardsRT) != (!m_activeHazardsRT))) { m_flags.set(D3D9DeviceFlag::DirtyFramebuffer); m_lastHazardsDS = m_activeHazardsDS; + m_lastHazardsRT = m_activeHazardsRT; } for (uint32_t i = 0; i < caps::MaxStreams; i++) { diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 6486f3679..7b226c2ea 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1261,6 +1261,7 @@ namespace dxvk { uint32_t m_fetch4 = 0; uint32_t m_lastHazardsDS = 0; + uint32_t m_lastHazardsRT = 0; uint32_t m_lastSamplerTypesFF = 0; D3D9SpecializationInfo m_specInfo = D3D9SpecializationInfo(); From 3806bd44d80e8db343fb1e713f54ab481a6d9851 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 22:39:52 +0200 Subject: [PATCH 0559/1348] [dxvk] Change descriptor info to take only one shader stage And fix the binding index -> descriptor mapping. This affects D3D9 since the spec constant change. --- src/d3d11/d3d11_video.cpp | 8 +++---- src/d3d9/d3d9_format_helpers.cpp | 4 ++-- src/d3d9/d3d9_swvp_emu.cpp | 2 +- src/dxvk/dxvk_context.cpp | 6 ++--- src/dxvk/dxvk_pipelayout.cpp | 22 ++++++++++------- src/dxvk/dxvk_pipelayout.h | 37 ++++++++++++++++++++++------- src/dxvk/dxvk_shader.cpp | 4 ++-- src/dxvk/dxvk_swapchain_blitter.cpp | 4 ++-- src/dxvk/hud/dxvk_hud_renderer.cpp | 8 +++---- 9 files changed, 60 insertions(+), 35 deletions(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 72346bc85..d3422466f 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -329,10 +329,10 @@ namespace dxvk { SpirvCodeBuffer fsCode(d3d11_video_blit_frag); const std::array fsBindings = {{ - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_UNIFORM_READ_BIT }, - { VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, 0 }, - { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_READ_BIT }, - { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_UNIFORM_READ_BIT }, + { VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, 0 }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, }}; DxvkShaderCreateInfo vsInfo; diff --git a/src/d3d9/d3d9_format_helpers.cpp b/src/d3d9/d3d9_format_helpers.cpp index de73fdbe7..7d37bb598 100644 --- a/src/d3d9/d3d9_format_helpers.cpp +++ b/src/d3d9/d3d9_format_helpers.cpp @@ -120,8 +120,8 @@ namespace dxvk { Rc D3D9FormatHelper::InitShader(SpirvCodeBuffer code) { const std::array bindings = { { - { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, BindingIds::Image, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_WRITE_BIT }, - { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, BindingIds::Buffer, VK_IMAGE_VIEW_TYPE_1D, 0, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, BindingIds::Image, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_COMPUTE_BIT, VK_ACCESS_SHADER_WRITE_BIT }, + { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, BindingIds::Buffer, VK_IMAGE_VIEW_TYPE_1D, VK_SHADER_STAGE_COMPUTE_BIT, VK_ACCESS_SHADER_READ_BIT }, } }; DxvkShaderCreateInfo info; diff --git a/src/d3d9/d3d9_swvp_emu.cpp b/src/d3d9/d3d9_swvp_emu.cpp index 4c5eeaddb..140534956 100644 --- a/src/d3d9/d3d9_swvp_emu.cpp +++ b/src/d3d9/d3d9_swvp_emu.cpp @@ -133,8 +133,8 @@ namespace dxvk { m_bufferBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; m_bufferBinding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; m_bufferBinding.resourceBinding = bufferSlot; + m_bufferBinding.stage = VK_SHADER_STAGE_GEOMETRY_BIT; m_bufferBinding.access = VK_ACCESS_SHADER_WRITE_BIT; - m_bufferBinding.stages = 0; // Load our builtins uint32_t primitiveIdPtr = m_module.newVar(m_module.defPointerType(uint_t, spv::StorageClassInput), spv::StorageClassInput); diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 6486d2671..f493e0ce4 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5581,7 +5581,7 @@ namespace dxvk { if ((slot.bufferSlice.length()) && (slot.bufferSlice.bufferInfo().access & storageBufferAccess)) { requiresBarrier = this->checkBufferBarrier(slot.bufferSlice, - util::pipelineStages(binding.stages), binding.access); + util::pipelineStages(binding.stage), binding.access); } break; @@ -5591,7 +5591,7 @@ namespace dxvk { && (slot.bufferView->bufferInfo().access & storageBufferAccess)) { slot.bufferView->updateView(); requiresBarrier = this->checkBufferViewBarrier(slot.bufferView, - util::pipelineStages(binding.stages), binding.access); + util::pipelineStages(binding.stage), binding.access); } break; @@ -5601,7 +5601,7 @@ namespace dxvk { if ((slot.imageView != nullptr) && (slot.imageView->imageInfo().access & storageImageAccess)) { requiresBarrier = this->checkImageViewBarrier(slot.imageView, - util::pipelineStages(binding.stages), binding.access); + util::pipelineStages(binding.stage), binding.access); } break; diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index 67c01ca89..ef40431b9 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -9,10 +9,10 @@ namespace dxvk { uint32_t DxvkBindingInfo::computeSetIndex() const { - if (stages & VK_SHADER_STAGE_COMPUTE_BIT) { + if (stage == VK_SHADER_STAGE_COMPUTE_BIT) { // Use one single set for compute shaders return DxvkDescriptorSets::CsAll; - } else if (stages & VK_SHADER_STAGE_FRAGMENT_BIT) { + } else if (stage == VK_SHADER_STAGE_FRAGMENT_BIT) { // For fragment shaders, create a separate set for UBOs if (descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) @@ -37,17 +37,17 @@ namespace dxvk { return descriptorType == other.descriptorType && resourceBinding == other.resourceBinding && viewType == other.viewType - && stages == other.stages + && stage == other.stage && access == other.access; } size_t DxvkBindingInfo::hash() const { DxvkHashState hash; - hash.add(descriptorType); + hash.add(uint32_t(descriptorType)); hash.add(resourceBinding); - hash.add(viewType); - hash.add(stages); + hash.add(uint32_t(viewType)); + hash.add(uint32_t(stage)); hash.add(access); return hash; } @@ -107,7 +107,7 @@ namespace dxvk { for (uint32_t i = 0; i < list.getBindingCount(); i++) { m_bindings[i].descriptorType = list.getBinding(i).descriptorType; - m_bindings[i].stages = list.getBinding(i).stages; + m_bindings[i].stages = list.getBinding(i).stage; } } @@ -315,11 +315,15 @@ namespace dxvk { for (uint32_t j = 0; j < bindingCount; j++) { const DxvkBindingInfo& binding = m_layout.getBinding(i, j); + DxvkBindingKey key; + key.stage = binding.stage; + key.binding = binding.resourceBinding; + DxvkBindingMapping mapping; mapping.set = i; mapping.binding = j; - m_mapping.insert({ binding.resourceBinding, mapping }); + m_mapping.insert({ key, mapping }); } if (bindingCount) { @@ -372,7 +376,7 @@ namespace dxvk { for (uint32_t i = 0; i < DxvkDescriptorSets::SetCount; i++) { for (uint32_t j = 0; j < m_layout.getBindingCount(i); j++) { const auto& binding = m_layout.getBinding(i, j); - barrier.stages |= util::pipelineStages(binding.stages); + barrier.stages |= util::pipelineStages(binding.stage); barrier.access |= binding.access; } } diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index b7b16c35c..8c03d6dd6 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -31,11 +31,11 @@ namespace dxvk { * a given shader, or for the whole pipeline. */ struct DxvkBindingInfo { - VkDescriptorType descriptorType; ///< Vulkan descriptor type - uint32_t resourceBinding; ///< API binding slot for the resource - VkImageViewType viewType; ///< Image view type - VkShaderStageFlags stages; ///< Shader stage mask - VkAccessFlags access; ///< Access mask for the resource + VkDescriptorType descriptorType; ///< Vulkan descriptor type + uint32_t resourceBinding; ///< API binding slot for the resource + VkImageViewType viewType; ///< Image view type + VkShaderStageFlagBits stage; ///< Shader stage + VkAccessFlags access; ///< Access mask for the resource /** * \brief Computes descriptor set index for the given binding @@ -364,6 +364,25 @@ namespace dxvk { uint32_t binding; }; + /** + * \brief Key for binding lookups + */ + struct DxvkBindingKey { + VkShaderStageFlagBits stage; + uint32_t binding; + + size_t hash() const { + DxvkHashState hash; + hash.add(uint32_t(stage)); + hash.add(binding); + return hash; + } + + bool eq(const DxvkBindingKey& other) const { + return stage == other.stage && binding == other.binding; + } + }; + /** * \brief Global resource barrier * @@ -453,11 +472,13 @@ namespace dxvk { /** * \brief Looks up set and binding number by resource binding * + * \param [in] stage Shader stage * \param [in] index Resource binding index * \returns Descriptor set and binding number */ - std::optional lookupBinding(uint32_t index) const { - auto entry = m_mapping.find(index); + std::optional lookupBinding(VkShaderStageFlagBits stage, uint32_t index) const { + DxvkBindingKey key = { stage, index }; + auto entry = m_mapping.find(key); if (entry != m_mapping.end()) return entry->second; @@ -487,7 +508,7 @@ namespace dxvk { std::array m_bindingObjects = { }; - std::unordered_map m_mapping; + std::unordered_map m_mapping; }; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index e840d95cc..9c06b96c3 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -53,7 +53,7 @@ namespace dxvk { // Copy resource binding slot infos for (uint32_t i = 0; i < info.bindingCount; i++) { DxvkBindingInfo binding = info.bindings[i]; - binding.stages = info.stage; + binding.stage = info.stage; m_bindings.addBinding(binding); } @@ -172,7 +172,7 @@ namespace dxvk { // Remap resource binding IDs for (const auto& info : m_bindingOffsets) { - auto mappedBinding = layout->lookupBinding(info.bindingId); + auto mappedBinding = layout->lookupBinding(m_info.stage, info.bindingId); if (mappedBinding) { code[info.bindingOffset] = mappedBinding->binding; diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index 29b413f68..846dd8916 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -321,8 +321,8 @@ namespace dxvk { SpirvCodeBuffer fsCodeResolveAmd(dxvk_present_frag_ms_amd); const std::array fsBindings = {{ - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, BindingIds::Image, VK_IMAGE_VIEW_TYPE_2D, 0, VK_ACCESS_SHADER_READ_BIT }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, BindingIds::Gamma, VK_IMAGE_VIEW_TYPE_1D, 0, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, BindingIds::Image, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, BindingIds::Gamma, VK_IMAGE_VIEW_TYPE_1D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, }}; DxvkShaderCreateInfo vsInfo; diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index b638c7d73..893d6d346 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -160,12 +160,12 @@ namespace dxvk::hud { SpirvCodeBuffer fsCode(hud_text_frag); const std::array vsBindings = {{ - { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_SHADER_READ_BIT }, - { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_VERTEX_BIT, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_VERTEX_BIT, VK_ACCESS_SHADER_READ_BIT }, }}; const std::array fsBindings = {{ - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, }}; DxvkShaderCreateInfo vsInfo; @@ -195,7 +195,7 @@ namespace dxvk::hud { SpirvCodeBuffer fsCode(hud_graph_frag); const std::array fsBindings = {{ - { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, 0, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, }}; DxvkShaderCreateInfo vsInfo; From 2c713a34c9088dd726fd4d10cd022ed0be49e2fb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 12 Aug 2022 16:58:07 +0200 Subject: [PATCH 0560/1348] [d3d9,dxso] Factor out common alpha test code --- src/d3d9/d3d9_fixed_function.cpp | 175 ++++++++++++++++--------------- src/d3d9/d3d9_fixed_function.h | 8 ++ src/d3d9/d3d9_state.h | 2 +- src/dxso/dxso_compiler.cpp | 107 ++----------------- 4 files changed, 105 insertions(+), 187 deletions(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 7c7629a9b..6f60e5ad2 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -189,6 +189,86 @@ namespace dxvk { } + void DoFixedFunctionAlphaTest(SpirvModule& spvModule, const D3D9AlphaTestContext& ctx) { + // Labels for the alpha test + std::array atestCaseLabels = {{ + { uint32_t(VK_COMPARE_OP_NEVER), spvModule.allocateId() }, + { uint32_t(VK_COMPARE_OP_LESS), spvModule.allocateId() }, + { uint32_t(VK_COMPARE_OP_EQUAL), spvModule.allocateId() }, + { uint32_t(VK_COMPARE_OP_LESS_OR_EQUAL), spvModule.allocateId() }, + { uint32_t(VK_COMPARE_OP_GREATER), spvModule.allocateId() }, + { uint32_t(VK_COMPARE_OP_NOT_EQUAL), spvModule.allocateId() }, + { uint32_t(VK_COMPARE_OP_GREATER_OR_EQUAL), spvModule.allocateId() }, + { uint32_t(VK_COMPARE_OP_ALWAYS), spvModule.allocateId() }, + }}; + + uint32_t atestBeginLabel = spvModule.allocateId(); + uint32_t atestTestLabel = spvModule.allocateId(); + uint32_t atestDiscardLabel = spvModule.allocateId(); + uint32_t atestKeepLabel = spvModule.allocateId(); + uint32_t atestSkipLabel = spvModule.allocateId(); + + // if (alpha_func != ALWAYS) { ... } + uint32_t boolType = spvModule.defBoolType(); + uint32_t isNotAlways = spvModule.opINotEqual(boolType, ctx.alphaFuncId, spvModule.constu32(VK_COMPARE_OP_ALWAYS)); + spvModule.opSelectionMerge(atestSkipLabel, spv::SelectionControlMaskNone); + spvModule.opBranchConditional(isNotAlways, atestBeginLabel, atestSkipLabel); + spvModule.opLabel(atestBeginLabel); + + // switch (alpha_func) { ... } + spvModule.opSelectionMerge(atestTestLabel, spv::SelectionControlMaskNone); + spvModule.opSwitch(ctx.alphaFuncId, + atestCaseLabels[uint32_t(VK_COMPARE_OP_ALWAYS)].labelId, + atestCaseLabels.size(), + atestCaseLabels.data()); + + std::array atestVariables; + + for (uint32_t i = 0; i < atestCaseLabels.size(); i++) { + spvModule.opLabel(atestCaseLabels[i].labelId); + + atestVariables[i].labelId = atestCaseLabels[i].labelId; + atestVariables[i].varId = [&] { + switch (VkCompareOp(atestCaseLabels[i].literal)) { + case VK_COMPARE_OP_NEVER: return spvModule.constBool(false); + case VK_COMPARE_OP_LESS: return spvModule.opFOrdLessThan (boolType, ctx.alphaId, ctx.alphaRefId); + case VK_COMPARE_OP_EQUAL: return spvModule.opFOrdEqual (boolType, ctx.alphaId, ctx.alphaRefId); + case VK_COMPARE_OP_LESS_OR_EQUAL: return spvModule.opFOrdLessThanEqual (boolType, ctx.alphaId, ctx.alphaRefId); + case VK_COMPARE_OP_GREATER: return spvModule.opFOrdGreaterThan (boolType, ctx.alphaId, ctx.alphaRefId); + case VK_COMPARE_OP_NOT_EQUAL: return spvModule.opFOrdNotEqual (boolType, ctx.alphaId, ctx.alphaRefId); + case VK_COMPARE_OP_GREATER_OR_EQUAL: return spvModule.opFOrdGreaterThanEqual(boolType, ctx.alphaId, ctx.alphaRefId); + default: + case VK_COMPARE_OP_ALWAYS: return spvModule.constBool(true); + } + }(); + + spvModule.opBranch(atestTestLabel); + } + + // end switch + spvModule.opLabel(atestTestLabel); + + uint32_t atestResult = spvModule.opPhi(boolType, + atestVariables.size(), + atestVariables.data()); + uint32_t atestDiscard = spvModule.opLogicalNot(boolType, atestResult); + + // if (do_discard) { ... } + spvModule.opSelectionMerge(atestKeepLabel, spv::SelectionControlMaskNone); + spvModule.opBranchConditional(atestDiscard, atestDiscardLabel, atestKeepLabel); + + spvModule.opLabel(atestDiscardLabel); + spvModule.opKill(); + + // end if (do_discard) + spvModule.opLabel(atestKeepLabel); + spvModule.opBranch(atestSkipLabel); + + // end if (alpha_test) + spvModule.opLabel(atestSkipLabel); + } + + uint32_t SetupRenderStateBlock(SpirvModule& spvModule, uint32_t count) { uint32_t floatType = spvModule.defFloatType(32); uint32_t vec3Type = spvModule.defVectorType(floatType, 3); @@ -2220,101 +2300,22 @@ namespace dxvk { void D3D9FFShaderCompiler::alphaTestPS() { - // Alpha testing - uint32_t boolType = m_module.defBoolType(); uint32_t floatPtr = m_module.defPointerType(m_floatType, spv::StorageClassPushConstant); - // Declare spec constants for render states - uint32_t alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp); - - // Implement alpha test auto oC0 = m_ps.out.COLOR; - // Labels for the alpha test - std::array atestCaseLabels = { { - { uint32_t(VK_COMPARE_OP_NEVER), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_LESS), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_EQUAL), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_LESS_OR_EQUAL), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_GREATER), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_NOT_EQUAL), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_GREATER_OR_EQUAL), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_ALWAYS), m_module.allocateId() }, - } }; - uint32_t atestBeginLabel = m_module.allocateId(); - uint32_t atestTestLabel = m_module.allocateId(); - uint32_t atestDiscardLabel = m_module.allocateId(); - uint32_t atestKeepLabel = m_module.allocateId(); - uint32_t atestSkipLabel = m_module.allocateId(); - - // if (alpha_test) { ... } - uint32_t isNotAlways = m_module.opINotEqual(boolType, alphaFuncId, m_module.constu32(VK_COMPARE_OP_ALWAYS)); - m_module.opSelectionMerge(atestSkipLabel, spv::SelectionControlMaskNone); - m_module.opBranchConditional(isNotAlways, atestBeginLabel, atestSkipLabel); - m_module.opLabel(atestBeginLabel); - - // Load alpha component uint32_t alphaComponentId = 3; - uint32_t alphaId = m_module.opCompositeExtract(m_floatType, + uint32_t alphaRefMember = m_module.constu32(uint32_t(D3D9RenderStateItem::AlphaRef)); + + D3D9AlphaTestContext alphaTestContext; + alphaTestContext.alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp); + alphaTestContext.alphaRefId = m_module.opLoad(m_floatType, + m_module.opAccessChain(floatPtr, m_rsBlock, 1, &alphaRefMember)); + alphaTestContext.alphaId = m_module.opCompositeExtract(m_floatType, m_module.opLoad(m_vec4Type, oC0), 1, &alphaComponentId); - // Load alpha reference - uint32_t alphaRefMember = m_module.constu32(uint32_t(D3D9RenderStateItem::AlphaRef)); - uint32_t alphaRefId = m_module.opLoad(m_floatType, - m_module.opAccessChain(floatPtr, m_rsBlock, 1, &alphaRefMember)); - - // switch (alpha_func) { ... } - m_module.opSelectionMerge(atestTestLabel, spv::SelectionControlMaskNone); - m_module.opSwitch(alphaFuncId, - atestCaseLabels[uint32_t(VK_COMPARE_OP_ALWAYS)].labelId, - atestCaseLabels.size(), - atestCaseLabels.data()); - - std::array atestVariables; - - for (uint32_t i = 0; i < atestCaseLabels.size(); i++) { - m_module.opLabel(atestCaseLabels[i].labelId); - - atestVariables[i].labelId = atestCaseLabels[i].labelId; - atestVariables[i].varId = [&] { - switch (VkCompareOp(atestCaseLabels[i].literal)) { - case VK_COMPARE_OP_NEVER: return m_module.constBool(false); - case VK_COMPARE_OP_LESS: return m_module.opFOrdLessThan(boolType, alphaId, alphaRefId); - case VK_COMPARE_OP_EQUAL: return m_module.opFOrdEqual(boolType, alphaId, alphaRefId); - case VK_COMPARE_OP_LESS_OR_EQUAL: return m_module.opFOrdLessThanEqual(boolType, alphaId, alphaRefId); - case VK_COMPARE_OP_GREATER: return m_module.opFOrdGreaterThan(boolType, alphaId, alphaRefId); - case VK_COMPARE_OP_NOT_EQUAL: return m_module.opFOrdNotEqual(boolType, alphaId, alphaRefId); - case VK_COMPARE_OP_GREATER_OR_EQUAL: return m_module.opFOrdGreaterThanEqual(boolType, alphaId, alphaRefId); - default: - case VK_COMPARE_OP_ALWAYS: return m_module.constBool(true); - } - }(); - - m_module.opBranch(atestTestLabel); - } - - // end switch - m_module.opLabel(atestTestLabel); - - uint32_t atestResult = m_module.opPhi(boolType, - atestVariables.size(), - atestVariables.data()); - uint32_t atestDiscard = m_module.opLogicalNot(boolType, atestResult); - - // if (do_discard) { ... } - m_module.opSelectionMerge(atestKeepLabel, spv::SelectionControlMaskNone); - m_module.opBranchConditional(atestDiscard, atestDiscardLabel, atestKeepLabel); - - m_module.opLabel(atestDiscardLabel); - m_module.opKill(); - - // end if (do_discard) - m_module.opLabel(atestKeepLabel); - m_module.opBranch(atestSkipLabel); - - // end if (alpha_test) - m_module.opLabel(atestSkipLabel); + DoFixedFunctionAlphaTest(m_module, alphaTestContext); } diff --git a/src/d3d9/d3d9_fixed_function.h b/src/d3d9/d3d9_fixed_function.h index 8880f8515..492c265fd 100644 --- a/src/d3d9/d3d9_fixed_function.h +++ b/src/d3d9/d3d9_fixed_function.h @@ -38,6 +38,12 @@ namespace dxvk { uint32_t SpecUBO; }; + struct D3D9AlphaTestContext { + uint32_t alphaId; + uint32_t alphaFuncId; + uint32_t alphaRefId; + }; + struct D3D9FixedFunctionOptions { D3D9FixedFunctionOptions(const D3D9Options* options); @@ -48,6 +54,8 @@ namespace dxvk { // Returns new oColor if PS uint32_t DoFixedFunctionFog(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, const D3D9FogContext& fogCtx); + void DoFixedFunctionAlphaTest(SpirvModule& spvModule, const D3D9AlphaTestContext& ctx); + // Returns a render state block uint32_t SetupRenderStateBlock(SpirvModule& spvModule, uint32_t count); diff --git a/src/d3d9/d3d9_state.h b/src/d3d9/d3d9_state.h index d87b8f531..a3dd0a570 100644 --- a/src/d3d9/d3d9_state.h +++ b/src/d3d9/d3d9_state.h @@ -36,7 +36,7 @@ namespace dxvk { float fogEnd = 1.0f; float fogDensity = 1.0f; - float alphaRef = 0.0f; + uint32_t alphaRef = 0u; float pointSize = 1.0f; float pointSizeMin = 1.0f; diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index d0e5fc452..05028daa3 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -3698,8 +3698,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t floatType = m_module.defFloatType(32); uint32_t floatPtr = m_module.defPointerType(floatType, spv::StorageClassPushConstant); - uint32_t alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp); - // Implement alpha test and fog DxsoRegister color0; color0.id = DxsoRegisterId{ DxsoRegisterType::ColorOut, 0 }; @@ -3709,107 +3707,18 @@ void DxsoCompiler::emitControlFlowGenericLoop( if (m_programInfo.majorVersion() < 3) emitFog(); - // Labels for the alpha test - std::array atestCaseLabels = {{ - { uint32_t(VK_COMPARE_OP_NEVER), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_LESS), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_EQUAL), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_LESS_OR_EQUAL), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_GREATER), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_NOT_EQUAL), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_GREATER_OR_EQUAL), m_module.allocateId() }, - { uint32_t(VK_COMPARE_OP_ALWAYS), m_module.allocateId() }, - }}; - - uint32_t atestBeginLabel = m_module.allocateId(); - uint32_t atestTestLabel = m_module.allocateId(); - uint32_t atestDiscardLabel = m_module.allocateId(); - uint32_t atestKeepLabel = m_module.allocateId(); - uint32_t atestSkipLabel = m_module.allocateId(); - - // if (alpha_func != ALWAYS) { ... } - uint32_t isNotAlways = m_module.opINotEqual(boolType, alphaFuncId, m_module.constu32(VK_COMPARE_OP_ALWAYS)); - m_module.opSelectionMerge(atestSkipLabel, spv::SelectionControlMaskNone); - m_module.opBranchConditional(isNotAlways, atestBeginLabel, atestSkipLabel); - m_module.opLabel(atestBeginLabel); - - // Load alpha component + uint32_t alphaRefMember = m_module.constu32(uint32_t(D3D9RenderStateItem::AlphaRef)); uint32_t alphaComponentId = 3; - uint32_t alphaId = m_module.opCompositeExtract(floatType, + + D3D9AlphaTestContext alphaTestContext; + alphaTestContext.alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp); + alphaTestContext.alphaRefId = m_module.opLoad(floatType, + m_module.opAccessChain(floatPtr, m_rsBlock, 1, &alphaRefMember)); + alphaTestContext.alphaId = m_module.opCompositeExtract(floatType, m_module.opLoad(m_module.defVectorType(floatType, 4), oC0.id), 1, &alphaComponentId); - if (m_moduleInfo.options.alphaTestWiggleRoom) { - // NV has wonky interpolation of all 1's in a VS -> PS going to 0.999999... - // This causes garbage-looking graphics on people's clothing in EverQuest 2 as it does alpha == 1.0. - - // My testing shows the alpha test has a precision of 1/256 for all A8 and below formats, - // and around 1 / 2048 for A32F formats and 1 / 4096 for A16F formats (It makes no sense to me too) - // so anyway, we're just going to round this to a precision of 1 / 4096 and hopefully this should make things happy - // everywhere. - const uint32_t alphaSizeId = m_module.constf32(4096.0f); - - alphaId = m_module.opFMul(floatType, alphaId, alphaSizeId); - alphaId = m_module.opRound(floatType, alphaId); - alphaId = m_module.opFDiv(floatType, alphaId, alphaSizeId); - } - - // Load alpha reference - uint32_t alphaRefMember = m_module.constu32(uint32_t(D3D9RenderStateItem::AlphaRef)); - uint32_t alphaRefId = m_module.opLoad(floatType, - m_module.opAccessChain(floatPtr, m_rsBlock, 1, &alphaRefMember)); - - // switch (alpha_func) { ... } - m_module.opSelectionMerge(atestTestLabel, spv::SelectionControlMaskNone); - m_module.opSwitch(alphaFuncId, - atestCaseLabels[uint32_t(VK_COMPARE_OP_ALWAYS)].labelId, - atestCaseLabels.size(), - atestCaseLabels.data()); - - std::array atestVariables; - - for (uint32_t i = 0; i < atestCaseLabels.size(); i++) { - m_module.opLabel(atestCaseLabels[i].labelId); - - atestVariables[i].labelId = atestCaseLabels[i].labelId; - atestVariables[i].varId = [&] { - switch (VkCompareOp(atestCaseLabels[i].literal)) { - case VK_COMPARE_OP_NEVER: return m_module.constBool(false); - case VK_COMPARE_OP_LESS: return m_module.opFOrdLessThan (boolType, alphaId, alphaRefId); - case VK_COMPARE_OP_EQUAL: return m_module.opFOrdEqual (boolType, alphaId, alphaRefId); - case VK_COMPARE_OP_LESS_OR_EQUAL: return m_module.opFOrdLessThanEqual (boolType, alphaId, alphaRefId); - case VK_COMPARE_OP_GREATER: return m_module.opFOrdGreaterThan (boolType, alphaId, alphaRefId); - case VK_COMPARE_OP_NOT_EQUAL: return m_module.opFOrdNotEqual (boolType, alphaId, alphaRefId); - case VK_COMPARE_OP_GREATER_OR_EQUAL: return m_module.opFOrdGreaterThanEqual(boolType, alphaId, alphaRefId); - default: - case VK_COMPARE_OP_ALWAYS: return m_module.constBool(true); - } - }(); - - m_module.opBranch(atestTestLabel); - } - - // end switch - m_module.opLabel(atestTestLabel); - - uint32_t atestResult = m_module.opPhi(boolType, - atestVariables.size(), - atestVariables.data()); - uint32_t atestDiscard = m_module.opLogicalNot(boolType, atestResult); - - // if (do_discard) { ... } - m_module.opSelectionMerge(atestKeepLabel, spv::SelectionControlMaskNone); - m_module.opBranchConditional(atestDiscard, atestDiscardLabel, atestKeepLabel); - - m_module.opLabel(atestDiscardLabel); - m_module.opKill(); - - // end if (do_discard) - m_module.opLabel(atestKeepLabel); - m_module.opBranch(atestSkipLabel); - - // end if (alpha_test) - m_module.opLabel(atestSkipLabel); + DoFixedFunctionAlphaTest(m_module, alphaTestContext); } } From 47fa3824dc208d1f04b045a2d7ec4ef0aa518a2a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 12 Aug 2022 17:35:19 +0200 Subject: [PATCH 0561/1348] [d3d9] Re-implement alpha test to support configurable accuracy The current implementation always uses 12 bits of accuracy. --- src/d3d9/d3d9_device.cpp | 4 +- src/d3d9/d3d9_fixed_function.cpp | 86 ++++++++++++++++++++++++++++---- src/d3d9/d3d9_fixed_function.h | 1 + src/d3d9/d3d9_spec_constants.h | 2 + src/dxso/dxso_compiler.cpp | 9 ++-- 5 files changed, 87 insertions(+), 15 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 8f21204eb..ff91bdc22 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5117,8 +5117,8 @@ namespace dxvk { auto& rs = m_state.renderStates; if constexpr (Item == D3D9RenderStateItem::AlphaRef) { - float alpha = float(rs[D3DRS_ALPHAREF] & 0xFF) / 255.0f; - UpdatePushConstant(&alpha); + uint32_t alpha = rs[D3DRS_ALPHAREF]; + UpdatePushConstant(&alpha); } else if constexpr (Item == D3D9RenderStateItem::FogColor) { Vector4 color; diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 6f60e5ad2..bd9edc575 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -215,6 +215,71 @@ namespace dxvk { spvModule.opBranchConditional(isNotAlways, atestBeginLabel, atestSkipLabel); spvModule.opLabel(atestBeginLabel); + // The lower 8 bits of the alpha ref contain the actual reference value + // from the API, the upper bits store the accuracy bit count minus 8. + // So if we want 12 bits of accuracy (i.e. 0-4095), that value will be 4. + uint32_t uintType = spvModule.defIntType(32, 0); + + // Check if the given bit precision is supported + uint32_t precisionIntLabel = spvModule.allocateId(); + uint32_t precisionFloatLabel = spvModule.allocateId(); + uint32_t precisionEndLabel = spvModule.allocateId(); + + uint32_t useIntPrecision = spvModule.opULessThanEqual(boolType, + ctx.alphaPrecisionId, spvModule.constu32(8)); + + spvModule.opSelectionMerge(precisionEndLabel, spv::SelectionControlMaskNone); + spvModule.opBranchConditional(useIntPrecision, precisionIntLabel, precisionFloatLabel); + spvModule.opLabel(precisionIntLabel); + + // Adjust alpha ref to the given range + uint32_t alphaRefIdInt = spvModule.opBitwiseOr(uintType, + spvModule.opShiftLeftLogical(uintType, ctx.alphaRefId, ctx.alphaPrecisionId), + spvModule.opShiftRightLogical(uintType, ctx.alphaRefId, + spvModule.opISub(uintType, spvModule.constu32(8), ctx.alphaPrecisionId))); + + // Convert alpha ref to float since we'll do the comparison based on that + uint32_t floatType = spvModule.defFloatType(32); + alphaRefIdInt = spvModule.opConvertUtoF(floatType, alphaRefIdInt); + + // Adjust alpha to the given range and round + uint32_t alphaFactorId = spvModule.opISub(uintType, + spvModule.opShiftLeftLogical(uintType, spvModule.constu32(256), ctx.alphaPrecisionId), + spvModule.constu32(1)); + alphaFactorId = spvModule.opConvertUtoF(floatType, alphaFactorId); + + uint32_t alphaIdInt = spvModule.opRoundEven(floatType, + spvModule.opFMul(floatType, ctx.alphaId, alphaFactorId)); + + spvModule.opBranch(precisionEndLabel); + spvModule.opLabel(precisionFloatLabel); + + // If we're not using integer precision, normalize the alpha ref + uint32_t alphaRefIdFloat = spvModule.opFDiv(floatType, + spvModule.opConvertUtoF(floatType, ctx.alphaRefId), + spvModule.constf32(255.0f)); + + spvModule.opBranch(precisionEndLabel); + spvModule.opLabel(precisionEndLabel); + + std::array alphaRefLabels = { + SpirvPhiLabel { alphaRefIdInt, precisionIntLabel }, + SpirvPhiLabel { alphaRefIdFloat, precisionFloatLabel }, + }; + + uint32_t alphaRefId = spvModule.opPhi(floatType, + alphaRefLabels.size(), + alphaRefLabels.data()); + + std::array alphaIdLabels = { + SpirvPhiLabel { alphaIdInt, precisionIntLabel }, + SpirvPhiLabel { ctx.alphaId, precisionFloatLabel }, + }; + + uint32_t alphaId = spvModule.opPhi(floatType, + alphaIdLabels.size(), + alphaIdLabels.data()); + // switch (alpha_func) { ... } spvModule.opSelectionMerge(atestTestLabel, spv::SelectionControlMaskNone); spvModule.opSwitch(ctx.alphaFuncId, @@ -231,12 +296,12 @@ namespace dxvk { atestVariables[i].varId = [&] { switch (VkCompareOp(atestCaseLabels[i].literal)) { case VK_COMPARE_OP_NEVER: return spvModule.constBool(false); - case VK_COMPARE_OP_LESS: return spvModule.opFOrdLessThan (boolType, ctx.alphaId, ctx.alphaRefId); - case VK_COMPARE_OP_EQUAL: return spvModule.opFOrdEqual (boolType, ctx.alphaId, ctx.alphaRefId); - case VK_COMPARE_OP_LESS_OR_EQUAL: return spvModule.opFOrdLessThanEqual (boolType, ctx.alphaId, ctx.alphaRefId); - case VK_COMPARE_OP_GREATER: return spvModule.opFOrdGreaterThan (boolType, ctx.alphaId, ctx.alphaRefId); - case VK_COMPARE_OP_NOT_EQUAL: return spvModule.opFOrdNotEqual (boolType, ctx.alphaId, ctx.alphaRefId); - case VK_COMPARE_OP_GREATER_OR_EQUAL: return spvModule.opFOrdGreaterThanEqual(boolType, ctx.alphaId, ctx.alphaRefId); + case VK_COMPARE_OP_LESS: return spvModule.opFOrdLessThan (boolType, alphaId, alphaRefId); + case VK_COMPARE_OP_EQUAL: return spvModule.opFOrdEqual (boolType, alphaId, alphaRefId); + case VK_COMPARE_OP_LESS_OR_EQUAL: return spvModule.opFOrdLessThanEqual (boolType, alphaId, alphaRefId); + case VK_COMPARE_OP_GREATER: return spvModule.opFOrdGreaterThan (boolType, alphaId, alphaRefId); + case VK_COMPARE_OP_NOT_EQUAL: return spvModule.opFOrdNotEqual (boolType, alphaId, alphaRefId); + case VK_COMPARE_OP_GREATER_OR_EQUAL: return spvModule.opFOrdGreaterThanEqual(boolType, alphaId, alphaRefId); default: case VK_COMPARE_OP_ALWAYS: return spvModule.constBool(true); } @@ -271,6 +336,7 @@ namespace dxvk { uint32_t SetupRenderStateBlock(SpirvModule& spvModule, uint32_t count) { uint32_t floatType = spvModule.defFloatType(32); + uint32_t uintType = spvModule.defIntType(32, 0); uint32_t vec3Type = spvModule.defVectorType(floatType, 3); std::array rsMembers = {{ @@ -278,7 +344,8 @@ namespace dxvk { floatType, floatType, floatType, - floatType, + + uintType, floatType, floatType, @@ -2300,7 +2367,7 @@ namespace dxvk { void D3D9FFShaderCompiler::alphaTestPS() { - uint32_t floatPtr = m_module.defPointerType(m_floatType, spv::StorageClassPushConstant); + uint32_t uintPtr = m_module.defPointerType(m_uint32Type, spv::StorageClassPushConstant); auto oC0 = m_ps.out.COLOR; @@ -2309,8 +2376,9 @@ namespace dxvk { D3D9AlphaTestContext alphaTestContext; alphaTestContext.alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp); + alphaTestContext.alphaPrecisionId = m_spec.get(m_module, m_specUbo, SpecAlphaPrecisionBits); alphaTestContext.alphaRefId = m_module.opLoad(m_floatType, - m_module.opAccessChain(floatPtr, m_rsBlock, 1, &alphaRefMember)); + m_module.opAccessChain(uintPtr, m_rsBlock, 1, &alphaRefMember)); alphaTestContext.alphaId = m_module.opCompositeExtract(m_floatType, m_module.opLoad(m_vec4Type, oC0), 1, &alphaComponentId); diff --git a/src/d3d9/d3d9_fixed_function.h b/src/d3d9/d3d9_fixed_function.h index 492c265fd..4fe8d82c0 100644 --- a/src/d3d9/d3d9_fixed_function.h +++ b/src/d3d9/d3d9_fixed_function.h @@ -40,6 +40,7 @@ namespace dxvk { struct D3D9AlphaTestContext { uint32_t alphaId; + uint32_t alphaPrecisionId; uint32_t alphaFuncId; uint32_t alphaRefId; }; diff --git a/src/d3d9/d3d9_spec_constants.h b/src/d3d9/d3d9_spec_constants.h index ba45cccb9..78a850301 100644 --- a/src/d3d9/d3d9_spec_constants.h +++ b/src/d3d9/d3d9_spec_constants.h @@ -22,6 +22,7 @@ namespace dxvk { SpecSamplerNull, // 1 bit for 20 samplers | Bits: 20 SpecProjectionType, // 1 bit for 6 PS 1.x samplers | Bits: 6 + SpecAlphaPrecisionBits, // Range: 0 -> 8 or 0xF | Bits: 4 SpecVertexShaderBools, // 16 bools | Bits: 16 SpecPixelShaderBools, // 16 bools | Bits: 16 @@ -56,6 +57,7 @@ namespace dxvk { { 2, 0, 20 }, // SamplerNull { 2, 20, 6 }, // ProjectionType + { 2, 26, 4 }, // AlphaPrecisionBits { 3, 0, 16 }, // VertexShaderBools { 3, 16, 16 }, // PixelShaderBools diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 05028daa3..15436fb92 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -3694,9 +3694,9 @@ void DxsoCompiler::emitControlFlowGenericLoop( void DxsoCompiler::emitPsProcessing() { - uint32_t boolType = m_module.defBoolType(); uint32_t floatType = m_module.defFloatType(32); - uint32_t floatPtr = m_module.defPointerType(floatType, spv::StorageClassPushConstant); + uint32_t uintType = m_module.defIntType(32, 0); + uint32_t uintPtr = m_module.defPointerType(uintType, spv::StorageClassPushConstant); // Implement alpha test and fog DxsoRegister color0; @@ -3712,8 +3712,9 @@ void DxsoCompiler::emitControlFlowGenericLoop( D3D9AlphaTestContext alphaTestContext; alphaTestContext.alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp); - alphaTestContext.alphaRefId = m_module.opLoad(floatType, - m_module.opAccessChain(floatPtr, m_rsBlock, 1, &alphaRefMember)); + alphaTestContext.alphaPrecisionId = m_spec.get(m_module, m_specUbo, SpecAlphaPrecisionBits); + alphaTestContext.alphaRefId = m_module.opLoad(uintType, + m_module.opAccessChain(uintPtr, m_rsBlock, 1, &alphaRefMember)); alphaTestContext.alphaId = m_module.opCompositeExtract(floatType, m_module.opLoad(m_module.defVectorType(floatType, 4), oC0.id), 1, &alphaComponentId); From 5a3cb5ad3e2b8a133158497a5c33492520152355 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 20:19:42 +0200 Subject: [PATCH 0562/1348] [d3d9] Adjust alpha test precision based on render target format More or less matches what Nvidia's D3D9 driver does on Turing. --- src/d3d9/d3d9_device.cpp | 51 ++++++++++++++++++++++++++++++++++++---- src/d3d9/d3d9_device.h | 4 +++- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index ff91bdc22..68ce10094 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -1283,6 +1283,8 @@ namespace dxvk { m_flags.set(D3D9DeviceFlag::DirtyViewportScissor); m_state.scissorRect = scissorRect; } + + m_flags.set(D3D9DeviceFlag::DirtyAlphaTestState); } if (m_state.renderTargets[RenderTargetIndex] == rt) @@ -5843,6 +5845,42 @@ namespace dxvk { } + uint32_t D3D9DeviceEx::GetAlphaTestPrecision() { + if (m_state.renderTargets[0] == nullptr) + return 0; + + D3D9Format format = m_state.renderTargets[0]->GetCommonTexture()->Desc()->Format; + + switch (format) { + case D3D9Format::A2B10G10R10: + case D3D9Format::A2R10G10B10: + case D3D9Format::A2W10V10U10: + case D3D9Format::A2B10G10R10_XR_BIAS: + return 0x2; /* 10 bit */ + + case D3D9Format::R16F: + case D3D9Format::G16R16F: + case D3D9Format::A16B16G16R16F: + return 0x7; /* 15 bit */ + + case D3D9Format::G16R16: + case D3D9Format::A16B16G16R16: + case D3D9Format::V16U16: + case D3D9Format::L16: + case D3D9Format::Q16W16V16U16: + return 0x8; /* 16 bit */ + + case D3D9Format::R32F: + case D3D9Format::G32R32F: + case D3D9Format::A32B32G32R32F: + return 0xF; /* float */ + + default: + return 0x0; /* 8 bit */ + } + } + + void D3D9DeviceEx::BindAlphaTestState() { m_flags.clr(D3D9DeviceFlag::DirtyAlphaTestState); @@ -5852,7 +5890,11 @@ namespace dxvk { ? DecodeCompareOp(D3DCMPFUNC(rs[D3DRS_ALPHAFUNC])) : VK_COMPARE_OP_ALWAYS; - UpdateAlphaTestSpec(alphaOp); + uint32_t precision = alphaOp != VK_COMPARE_OP_ALWAYS + ? GetAlphaTestPrecision() + : 0u; + + UpdateAlphaTestSpec(alphaOp, precision); } @@ -7334,10 +7376,11 @@ namespace dxvk { // D3D9 Device Specialization State //////////////////////////////////// - void D3D9DeviceEx::UpdateAlphaTestSpec(VkCompareOp alphaOp) { - uint32_t value = uint32_t(alphaOp); + void D3D9DeviceEx::UpdateAlphaTestSpec(VkCompareOp alphaOp, uint32_t precision) { + bool dirty = m_specInfo.set(uint32_t(alphaOp)); + dirty |= m_specInfo.set(precision); - if (m_specInfo.set(value)) + if (dirty) m_flags.set(D3D9DeviceFlag::DirtySpecializationEntries); } diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 7b226c2ea..883d3de03 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1135,9 +1135,11 @@ namespace dxvk { bool UseProgrammablePS(); + uint32_t GetAlphaTestPrecision(); + void BindAlphaTestState(); - void UpdateAlphaTestSpec(VkCompareOp alphaOp); + void UpdateAlphaTestSpec(VkCompareOp alphaOp, uint32_t precision); void UpdateVertexBoolSpec(uint32_t value); void UpdatePixelBoolSpec(uint32_t value); void UpdatePixelShaderSamplerSpec(uint32_t types, uint32_t projections, uint32_t fetch4); From a695644fead65e8fac186fb91641f31bdb6b4db1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 12 Aug 2022 17:37:54 +0200 Subject: [PATCH 0563/1348] [d3d9] Remove alphaTestWiggleRoom option --- dxvk.conf | 10 ---------- src/d3d9/d3d9_options.cpp | 1 - src/d3d9/d3d9_options.h | 4 ---- src/dxso/dxso_options.cpp | 3 --- src/dxso/dxso_options.h | 4 ---- src/util/config/config.cpp | 9 --------- 6 files changed, 31 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index a18e4d65d..9eaa9f7e7 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -414,16 +414,6 @@ # d3d9.longMad = False -# Alpha Test Wiggle Room -# -# Workaround for games using alpha test == 1.0, etc due to wonky interpolation or -# misc. imprecision on some vendors -# -# Supported values: -# - True/False - -# d3d9.alphaTestWiggleRoom = False - # Device Local Constant Buffers # # Enables using device local, host accessible memory for constant buffers in D3D9. diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index ce0a43204..0b1ce723e 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -67,7 +67,6 @@ namespace dxvk { this->enumerateByDisplays = config.getOption ("d3d9.enumerateByDisplays", true); this->longMad = config.getOption ("d3d9.longMad", false); this->tearFree = config.getOption ("d3d9.tearFree", Tristate::Auto); - this->alphaTestWiggleRoom = config.getOption ("d3d9.alphaTestWiggleRoom", false); this->apitraceMode = config.getOption ("d3d9.apitraceMode", false); this->deviceLocalConstantBuffers = config.getOption ("d3d9.deviceLocalConstantBuffers", false); this->allowDirectBufferMapping = config.getOption ("d3d9.allowDirectBufferMapping", true); diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index 51dd57faf..99fef6b14 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -135,10 +135,6 @@ namespace dxvk { /// Tearing mode if vsync is enabled Tristate tearFree; - /// Workaround for games using alpha test == 1.0, etc due to wonky interpolation or - /// misc. imprecision on some vendors - bool alphaTestWiggleRoom; - /// Apitrace mode: Maps all buffers in cached memory. bool apitraceMode; diff --git a/src/dxso/dxso_options.cpp b/src/dxso/dxso_options.cpp index a4382c7b4..6f9dec89b 100644 --- a/src/dxso/dxso_options.cpp +++ b/src/dxso/dxso_options.cpp @@ -41,9 +41,6 @@ namespace dxvk { vertexFloatConstantBufferAsSSBO = pDevice->GetVertexConstantLayout().floatSize() > devInfo.core.properties.limits.maxUniformBufferRange; longMad = options.longMad; - - alphaTestWiggleRoom = options.alphaTestWiggleRoom; - robustness2Supported = devFeatures.extRobustness2.robustBufferAccess2; } diff --git a/src/dxso/dxso_options.h b/src/dxso/dxso_options.h index c977ce8a3..85c65ec1b 100644 --- a/src/dxso/dxso_options.h +++ b/src/dxso/dxso_options.h @@ -51,10 +51,6 @@ namespace dxvk { /// don't match entirely to the regular vertex shader in this way. bool longMad; - /// Workaround for games using alpha test == 1.0, etc due to wonky interpolation or - /// misc. imprecision on some vendors - bool alphaTestWiggleRoom; - /// Whether or not we can rely on robustness2 to handle oob constant access bool robustness2Supported; }; diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index c4e2141bb..1636c4017 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -413,10 +413,6 @@ namespace dxvk { { R"(\\SpellForce2.*\.exe$)", {{ { "d3d9.forceSamplerTypeSpecConstants", "True" }, }} }, - /* Everquest 2 */ - { R"(\\EverQuest2.*\.exe$)", {{ - { "d3d9.alphaTestWiggleRoom", "True" }, - }} }, /* Tomb Raider: Legend */ { R"(\\trl\.exe$)", {{ { "d3d9.apitraceMode", "True" }, @@ -575,11 +571,6 @@ namespace dxvk { { R"(\\BGE\.exe$)", {{ { "d3d9.maxFrameRate", "60" }, }} }, - /* Ninja Blade * - * Transparent main character on Nvidia */ - { R"(\\NinjaBlade\.exe$)", {{ - { "d3d9.alphaTestWiggleRoom", "True" }, - }} }, /* YS Origin * * Helps very bad frametimes in some areas */ { R"(\\yso_win\.exe$)", {{ From 4869b0defacc7806cc76d490252b941263294c03 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 18 Aug 2022 02:57:45 +0200 Subject: [PATCH 0564/1348] [dxvk] Fix race condition requestCompileShader --- src/dxvk/dxvk_pipemanager.cpp | 13 ++++++++++--- src/dxvk/dxvk_pipemanager.h | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 8004f2089..76ad41e9a 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -249,7 +249,7 @@ namespace dxvk { return &pair->second; auto layout = createPipelineLayout(shaders.cs->getBindings()); - auto library = findPipelineLibrary(shaders.cs); + auto library = findPipelineLibraryLocked(shaders.cs); auto iter = m_computePipelines.emplace( std::piecewise_construct, @@ -291,8 +291,8 @@ namespace dxvk { DxvkShaderPipelineLibrary* fsLibrary = nullptr; if (shaders.tcs == nullptr && shaders.tes == nullptr && shaders.gs == nullptr) { - vsLibrary = findPipelineLibrary(shaders.vs); - fsLibrary = findPipelineLibrary(shaders.fs); + vsLibrary = findPipelineLibraryLocked(shaders.vs); + fsLibrary = findPipelineLibraryLocked(shaders.fs); } auto iter = m_graphicsPipelines.emplace( @@ -445,6 +445,13 @@ namespace dxvk { DxvkShaderPipelineLibrary* DxvkPipelineManager::findPipelineLibrary( + const Rc& shader) { + std::lock_guard lock(m_mutex); + return findPipelineLibraryLocked(shader); + } + + + DxvkShaderPipelineLibrary* DxvkPipelineManager::findPipelineLibraryLocked( const Rc& shader) { DxvkShaderPipelineLibraryKey key; key.shader = shader; diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index b71751dde..b43e12cc8 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -302,6 +302,9 @@ namespace dxvk { DxvkShaderPipelineLibrary* findPipelineLibrary( const Rc& shader); + DxvkShaderPipelineLibrary* findPipelineLibraryLocked( + const Rc& shader); + bool canPrecompileShader( const Rc& shader) const; From 658d824ddd81f82971f7d1b27a048335a27872d1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 18 Aug 2022 14:48:29 +0200 Subject: [PATCH 0565/1348] [d3d11] Silence log spam for invalid image operations --- src/d3d11/d3d11_context.cpp | 46 +++++++------------------------------ 1 file changed, 8 insertions(+), 38 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 55963c7c0..80671283b 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -264,11 +264,6 @@ namespace dxvk { dstTexture, &dstLayers, dstOffset, srcTexture, &srcLayers, srcOffset, srcExtent); - } else { - Logger::err(str::format( - "D3D11: CopySubresourceRegion1: Incompatible resources", - "\n Dst resource type: ", dstResourceDim, - "\n Src resource type: ", srcResourceDim)); } } @@ -288,13 +283,8 @@ namespace dxvk { pDstResource->GetType(&dstResourceDim); pSrcResource->GetType(&srcResourceDim); - if (dstResourceDim != srcResourceDim) { - Logger::err(str::format( - "D3D11: CopyResource: Incompatible resources", - "\n Dst resource type: ", dstResourceDim, - "\n Src resource type: ", srcResourceDim)); + if (dstResourceDim != srcResourceDim) return; - } if (dstResourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) { auto dstBuffer = static_cast(pDstResource); @@ -313,10 +303,8 @@ namespace dxvk { // The subresource count must match as well if (dstDesc->ArraySize != srcDesc->ArraySize - || dstDesc->MipLevels != srcDesc->MipLevels) { - Logger::err("D3D11: CopyResource: Incompatible images"); + || dstDesc->MipLevels != srcDesc->MipLevels) return; - } auto dstFormatInfo = lookupFormatInfo(dstTexture->GetPackedFormat()); auto srcFormatInfo = lookupFormatInfo(srcTexture->GetPackedFormat()); @@ -837,13 +825,8 @@ namespace dxvk { pSrcResource->GetType(&srcResourceType); if (dstResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D - || srcResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D) { - Logger::err(str::format( - "D3D11: ResolveSubresource: Incompatible resources", - "\n Dst resource type: ", dstResourceType, - "\n Src resource type: ", srcResourceType)); + || srcResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D) return; - } auto dstTexture = static_cast(pDstResource); auto srcTexture = static_cast(pSrcResource); @@ -854,13 +837,8 @@ namespace dxvk { dstTexture->GetDesc(&dstDesc); srcTexture->GetDesc(&srcDesc); - if (dstDesc.SampleDesc.Count != 1) { - Logger::err(str::format( - "D3D11: ResolveSubresource: Invalid sample counts", - "\n Dst sample count: ", dstDesc.SampleDesc.Count, - "\n Src sample count: ", srcDesc.SampleDesc.Count)); + if (dstDesc.SampleDesc.Count != 1) return; - } D3D11CommonTexture* dstTextureInfo = GetCommonTexture(pDstResource); D3D11CommonTexture* srcTextureInfo = GetCommonTexture(pSrcResource); @@ -3588,16 +3566,12 @@ namespace dxvk { auto dstFormatInfo = lookupFormatInfo(pDstTexture->GetPackedFormat()); auto srcFormatInfo = lookupFormatInfo(pSrcTexture->GetPackedFormat()); - if (dstFormatInfo->elementSize != srcFormatInfo->elementSize) { - Logger::err("D3D11: CopyImage: Incompatible texel size"); + if (dstFormatInfo->elementSize != srcFormatInfo->elementSize) return; - } // Sample counts must match - if (pDstTexture->Desc()->SampleDesc.Count != pSrcTexture->Desc()->SampleDesc.Count) { - Logger::err("D3D11: CopyImage: Incompatible sample count"); + if (pDstTexture->Desc()->SampleDesc.Count != pSrcTexture->Desc()->SampleDesc.Count) return; - } // Obviously, the copy region must not be empty VkExtent3D dstMipExtent = pDstTexture->MipLevelExtent(pDstLayers->mipLevel); @@ -3615,10 +3589,8 @@ namespace dxvk { // Don't perform the copy if the offsets aren't block-aligned if (!util::isBlockAligned(SrcOffset, srcFormatInfo->blockSize) - || !util::isBlockAligned(DstOffset, dstFormatInfo->blockSize)) { - Logger::err(str::format("D3D11: CopyImage: Unaligned block offset")); + || !util::isBlockAligned(DstOffset, dstFormatInfo->blockSize)) return; - } // Clamp the image region in order to avoid out-of-bounds access VkExtent3D blockCount = util::computeBlockCount(SrcExtent, srcFormatInfo->blockSize); @@ -4746,10 +4718,8 @@ namespace dxvk { extent.depth = pDstBox->back - pDstBox->front; } - if (!util::isBlockAligned(offset, extent, formatInfo->blockSize, mipExtent)) { - Logger::err("D3D11: UpdateSubresource1: Unaligned region"); + if (!util::isBlockAligned(offset, extent, formatInfo->blockSize, mipExtent)) return; - } auto stagingSlice = AllocStagingBuffer(util::computeImageDataSize(packedFormat, extent)); From 85cc87e42a9adaa631593abfd06ec281001eae63 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 18 Aug 2022 17:08:59 +0200 Subject: [PATCH 0566/1348] [d3d9] Fix invalid shader in fixed-function alpha test --- src/d3d9/d3d9_fixed_function.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index bd9edc575..cc6628214 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -2377,7 +2377,7 @@ namespace dxvk { D3D9AlphaTestContext alphaTestContext; alphaTestContext.alphaFuncId = m_spec.get(m_module, m_specUbo, SpecAlphaCompareOp); alphaTestContext.alphaPrecisionId = m_spec.get(m_module, m_specUbo, SpecAlphaPrecisionBits); - alphaTestContext.alphaRefId = m_module.opLoad(m_floatType, + alphaTestContext.alphaRefId = m_module.opLoad(m_uint32Type, m_module.opAccessChain(uintPtr, m_rsBlock, 1, &alphaRefMember)); alphaTestContext.alphaId = m_module.opCompositeExtract(m_floatType, m_module.opLoad(m_vec4Type, oC0), From 155944c2b4b699e8dfae839ff55a602617c2a822 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Fri, 19 Aug 2022 10:27:23 +0200 Subject: [PATCH 0567/1348] [dxso] normalize 0 to 0 with strict float emulation --- src/dxso/dxso_compiler.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 15436fb92..a713648bb 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -2070,18 +2070,18 @@ namespace dxvk { DxsoRegMask srcMask(true, true, true, false); auto vec3 = emitRegisterLoad(src[0], srcMask); - DxsoRegisterValue dot = emitDot(vec3, vec3); - dot.id = m_module.opInverseSqrt (scalarTypeId, dot.id); + // No need for emitDot, either both arguments or none are zero. + // mul_zero has the same result as ieee mul. + uint32_t dot = m_module.opDot(scalarTypeId, vec3.id, vec3.id); + DxsoRegisterValue rcpLength; + rcpLength.type = scalarType; + rcpLength.id = m_module.opInverseSqrt(scalarTypeId, dot); if (m_moduleInfo.options.d3d9FloatEmulation == D3D9FloatEmulation::Enabled) { - dot.id = m_module.opNMin (scalarTypeId, dot.id, - m_module.constf32(FLT_MAX)); + rcpLength.id = m_module.opNMin(scalarTypeId, rcpLength.id, m_module.constf32(FLT_MAX)); } - // r * rsq(r . r); - result.id = m_module.opVectorTimesScalar( - typeId, - emitRegisterLoad(src[0], mask).id, - dot.id); + // r * rsq(r . r) + result.id = emitMul(vec3, emitRegisterExtend(rcpLength, 3)).id; break; } case DxsoOpcode::SinCos: { From ea4e0bc47000b8da2cbaf56d0aca458121e23616 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 17:34:18 +0200 Subject: [PATCH 0568/1348] [d3d9,d3d11] Require shaderDemoteToHelperInvocation feature --- src/d3d11/d3d11_device.cpp | 2 +- src/d3d9/d3d9_device.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index b575f7ea6..376f06e69 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1918,7 +1918,7 @@ namespace dxvk { enabled.vk12.samplerMirrorClampToEdge = VK_TRUE; enabled.vk12.timelineSemaphore = VK_TRUE; - enabled.vk13.shaderDemoteToHelperInvocation = supported.vk13.shaderDemoteToHelperInvocation; + enabled.vk13.shaderDemoteToHelperInvocation = VK_TRUE; enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 68ce10094..a55b0bad0 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3894,7 +3894,7 @@ namespace dxvk { enabled.vk12.samplerMirrorClampToEdge = VK_TRUE; - enabled.vk13.shaderDemoteToHelperInvocation = supported.vk13.shaderDemoteToHelperInvocation; + enabled.vk13.shaderDemoteToHelperInvocation = VK_TRUE; enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; From 165648017e4716f52c57fd3a152eaa512d064724 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 17:41:07 +0200 Subject: [PATCH 0569/1348] [dxbc] Remove fallback path for discards --- src/dxbc/dxbc_compiler.cpp | 178 +++--------------------------- src/dxbc/dxbc_compiler.h | 9 -- src/dxbc/dxbc_options.cpp | 6 - src/dxbc/dxbc_options.h | 7 -- tests/dxbc/test_dxbc_compiler.cpp | 1 - 5 files changed, 14 insertions(+), 187 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index c3028fbe4..3cf2da356 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -2273,9 +2273,6 @@ namespace dxvk { && bufferInfo.type != DxbcResourceType::Typed && isUav; - // Perform atomic operations on UAVs only if the invocation is alive - DxbcConditional cond = emitBeginPsKillTest(); - // Retrieve destination pointer for the atomic operation> const DxbcRegisterPointer pointer = emitGetAtomicPointer( ins.dst[ins.dstCount - 1], ins.src[0]); @@ -2399,8 +2396,6 @@ namespace dxvk { // register if this is an imm_atomic_* opcode. if (isImm) emitRegisterStore(ins.dst[0], value); - - emitEndPsKillTest(cond); } @@ -2413,9 +2408,6 @@ namespace dxvk { if (m_uavs.at(registerId).ctrId == 0) m_uavs.at(registerId).ctrId = emitDclUavCounter(registerId); - // Only perform the operation if the invocation is alive - DxbcConditional cond = emitBeginPsKillTest(); - // Only use subgroup ops on compute to avoid having to // deal with helper invocations or hardware limitations bool useSubgroupOps = m_moduleInfo.options.useSubgroupOpsForAtomicCounters @@ -2537,7 +2529,6 @@ namespace dxvk { // Store the result emitRegisterStore(ins.dst[0], value); - emitEndPsKillTest(cond); } @@ -3656,9 +3647,6 @@ namespace dxvk { // (src1) The value to store const DxbcBufferInfo uavInfo = getBufferInfo(ins.dst[0]); - // Execute write op only if the invocation is active - DxbcConditional cond = emitBeginPsKillTest(); - // Load texture coordinates DxbcRegisterValue texCoord = emitLoadTexCoord(ins.src[0], uavInfo.image); @@ -3672,8 +3660,6 @@ namespace dxvk { m_module.opImageWrite( m_module.opLoad(uavInfo.typeId, uavInfo.varId), texCoord.id, texValue.id, SpirvImageOperands()); - - emitEndPsKillTest(cond); } @@ -4031,80 +4017,20 @@ namespace dxvk { const DxbcRegisterValue zeroTest = emitRegisterZeroTest( condition, ins.controls.zeroTest()); - if (m_ps.killState == 0) { - DxbcConditional cond; - cond.labelIf = m_module.allocateId(); - cond.labelEnd = m_module.allocateId(); - - m_module.opSelectionMerge(cond.labelEnd, spv::SelectionControlMaskNone); - m_module.opBranchConditional(zeroTest.id, cond.labelIf, cond.labelEnd); - - m_module.opLabel(cond.labelIf); + DxbcConditional cond; + cond.labelIf = m_module.allocateId(); + cond.labelEnd = m_module.allocateId(); + + m_module.opSelectionMerge(cond.labelEnd, spv::SelectionControlMaskNone); + m_module.opBranchConditional(zeroTest.id, cond.labelIf, cond.labelEnd); + + m_module.opLabel(cond.labelIf); + m_module.opDemoteToHelperInvocation(); + m_module.opBranch(cond.labelEnd); + + m_module.opLabel(cond.labelEnd); - if (m_moduleInfo.options.useDemoteToHelperInvocation) { - m_module.opDemoteToHelperInvocation(); - m_module.opBranch(cond.labelEnd); - } else { - // OpKill terminates the block - m_module.opKill(); - } - - m_module.opLabel(cond.labelEnd); - } else { - uint32_t typeId = m_module.defBoolType(); - - uint32_t killState = m_module.opLoad (typeId, m_ps.killState); - killState = m_module.opLogicalOr(typeId, killState, zeroTest.id); - m_module.opStore(m_ps.killState, killState); - - if (m_moduleInfo.options.useSubgroupOpsForEarlyDiscard) { - uint32_t ballot = m_module.opGroupNonUniformBallot( - getVectorTypeId({ DxbcScalarType::Uint32, 4 }), - m_module.constu32(spv::ScopeSubgroup), - killState); - - uint32_t laneId = m_module.opLoad( - getScalarTypeId(DxbcScalarType::Uint32), - m_ps.builtinLaneId); - - uint32_t laneIdPart = m_module.opShiftRightLogical( - getScalarTypeId(DxbcScalarType::Uint32), - laneId, m_module.constu32(5)); - - uint32_t laneMask = m_module.opVectorExtractDynamic( - getScalarTypeId(DxbcScalarType::Uint32), - ballot, laneIdPart); - - uint32_t laneIdQuad = m_module.opBitwiseAnd( - getScalarTypeId(DxbcScalarType::Uint32), - laneId, m_module.constu32(0x1c)); - - laneMask = m_module.opShiftRightLogical( - getScalarTypeId(DxbcScalarType::Uint32), - laneMask, laneIdQuad); - - laneMask = m_module.opBitwiseAnd( - getScalarTypeId(DxbcScalarType::Uint32), - laneMask, m_module.constu32(0xf)); - - uint32_t killSubgroup = m_module.opIEqual( - m_module.defBoolType(), - laneMask, m_module.constu32(0xf)); - - DxbcConditional cond; - cond.labelIf = m_module.allocateId(); - cond.labelEnd = m_module.allocateId(); - - m_module.opSelectionMerge(cond.labelEnd, spv::SelectionControlMaskNone); - m_module.opBranchConditional(killSubgroup, cond.labelIf, cond.labelEnd); - - // OpKill terminates the block - m_module.opLabel(cond.labelIf); - m_module.opKill(); - - m_module.opLabel(cond.labelEnd); - } - } + m_module.enableCapability(spv::CapabilityDemoteToHelperInvocation); } @@ -5120,9 +5046,6 @@ namespace dxvk { bool isSsbo = m_moduleInfo.options.minSsboAlignment <= bufferInfo.align && !isTgsm; - // Perform UAV writes only if the invocation is active - DxbcConditional cond = emitBeginPsKillTest(); - // Perform the actual write operation uint32_t bufferId = isTgsm || isSsbo ? 0 : m_module.opLoad(bufferInfo.typeId, bufferInfo.varId); @@ -5183,8 +5106,6 @@ namespace dxvk { m_module.constu32(spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsAcquireReleaseMask)); } - - emitEndPsKillTest(cond); } @@ -6434,35 +6355,6 @@ namespace dxvk { } - DxbcConditional DxbcCompiler::emitBeginPsKillTest() { - if (!m_ps.killState) - return DxbcConditional(); - - uint32_t boolId = m_module.defBoolType(); - uint32_t killState = m_module.opLoad(boolId, m_ps.killState); - uint32_t testId = m_module.opLogicalNot(boolId, killState); - - DxbcConditional cond; - cond.labelIf = m_module.allocateId(); - cond.labelEnd = m_module.allocateId(); - - m_module.opSelectionMerge(cond.labelEnd, spv::SelectionControlMaskNone); - m_module.opBranchConditional(testId, cond.labelIf, cond.labelEnd); - - m_module.opLabel(cond.labelIf); - return cond; - } - - - void DxbcCompiler::emitEndPsKillTest(const DxbcConditional& cond) { - if (!m_ps.killState) - return; - - m_module.opBranch(cond.labelEnd); - m_module.opLabel(cond.labelEnd); - } - - void DxbcCompiler::emitInit() { // Set up common capabilities for all shaders m_module.enableCapability(spv::CapabilityShader); @@ -6704,32 +6596,6 @@ namespace dxvk { m_module.defFunctionType( m_module.defVoidType(), 0, nullptr)); this->emitFunctionLabel(); - - if (m_analysis->usesKill && m_moduleInfo.options.useDemoteToHelperInvocation) { - // This extension basically implements D3D-style discard - m_module.enableCapability(spv::CapabilityDemoteToHelperInvocation); - } else if (m_analysis->usesKill && m_analysis->usesDerivatives) { - // We may have to defer kill operations to the end of - // the shader in order to keep derivatives correct. - m_ps.killState = m_module.newVarInit( - m_module.defPointerType(m_module.defBoolType(), spv::StorageClassPrivate), - spv::StorageClassPrivate, m_module.constBool(false)); - - m_module.setDebugName(m_ps.killState, "ps_kill"); - - if (m_moduleInfo.options.useSubgroupOpsForEarlyDiscard) { - m_module.enableCapability(spv::CapabilityGroupNonUniform); - m_module.enableCapability(spv::CapabilityGroupNonUniformBallot); - - DxbcRegisterInfo laneId; - laneId.type = { DxbcScalarType::Uint32, 1, 0 }; - laneId.sclass = spv::StorageClassInput; - - m_ps.builtinLaneId = emitNewBuiltinVariable( - laneId, spv::BuiltInSubgroupLocalInvocationId, - "fLaneId"); - } - } } @@ -6823,23 +6689,7 @@ namespace dxvk { m_module.opFunctionCall( m_module.defVoidType(), m_ps.functionId, 0, nullptr); - - if (m_ps.killState != 0) { - DxbcConditional cond; - cond.labelIf = m_module.allocateId(); - cond.labelEnd = m_module.allocateId(); - - uint32_t killTest = m_module.opLoad(m_module.defBoolType(), m_ps.killState); - - m_module.opSelectionMerge(cond.labelEnd, spv::SelectionControlMaskNone); - m_module.opBranchConditional(killTest, cond.labelIf, cond.labelEnd); - - m_module.opLabel(cond.labelIf); - m_module.opKill(); - - m_module.opLabel(cond.labelEnd); - } - + this->emitOutputSetup(); if (m_moduleInfo.options.useDepthClipWorkaround) diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 29d410c70..46afc8062 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -181,9 +181,6 @@ namespace dxvk { uint32_t builtinLayer = 0; uint32_t builtinViewportId = 0; - uint32_t builtinLaneId = 0; - uint32_t killState = 0; - uint32_t pushConstantId = 0; }; @@ -1061,12 +1058,6 @@ namespace dxvk { DxbcSystemValue sv, uint32_t srcArray); - /////////////////////////////// - // Some state checking methods - DxbcConditional emitBeginPsKillTest(); - - void emitEndPsKillTest(const DxbcConditional& cond); - ////////////////////////////////////// // Common function definition methods void emitInit(); diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index f6b111a12..b02351633 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -20,12 +20,6 @@ namespace dxvk { useSubgroupOpsForAtomicCounters = (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_COMPUTE_BIT) && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); - useDemoteToHelperInvocation - = (devFeatures.vk13.shaderDemoteToHelperInvocation); - useSubgroupOpsForEarlyDiscard - = (devInfo.vk11.subgroupSize >= 4) - && (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) - && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); supportsTypedUavLoadR32 = true; supportsTypedUavLoadExtended = true; diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index 3d13ad6a8..336526da0 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -32,13 +32,6 @@ namespace dxvk { /// atomic operations for append/consume buffers. bool useSubgroupOpsForAtomicCounters = false; - /// Use a SPIR-V extension to implement D3D-style discards - bool useDemoteToHelperInvocation = false; - - /// Use subgroup operations to discard fragment - /// shader invocations if derivatives remain valid. - bool useSubgroupOpsForEarlyDiscard = false; - /// Enables NaN fixup for render target outputs bool enableRtOutputNanFixup = false; diff --git a/tests/dxbc/test_dxbc_compiler.cpp b/tests/dxbc/test_dxbc_compiler.cpp index 735604d77..0469c92ea 100644 --- a/tests/dxbc/test_dxbc_compiler.cpp +++ b/tests/dxbc/test_dxbc_compiler.cpp @@ -43,7 +43,6 @@ int WINAPI WinMain(HINSTANCE hInstance, DxbcModuleInfo moduleInfo; moduleInfo.options.useSubgroupOpsForAtomicCounters = true; - moduleInfo.options.useDemoteToHelperInvocation = true; moduleInfo.options.minSsboAlignment = 4; moduleInfo.xfb = nullptr; From 2d92679cd1ef706be05640151222dabe3b5a65ea Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 17 Aug 2022 17:44:10 +0200 Subject: [PATCH 0570/1348] [dxso] Remove fallback path for discards --- src/dxso/dxso_compiler.cpp | 117 +++---------------------------------- src/dxso/dxso_compiler.h | 3 - src/dxso/dxso_options.cpp | 12 ---- src/dxso/dxso_options.h | 7 --- 4 files changed, 9 insertions(+), 130 deletions(-) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index a713648bb..29dfef8f1 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -510,33 +510,11 @@ namespace dxvk { m_module.defVoidType(), 0, nullptr)); this->emitFunctionLabel(); - // We may have to defer kill operations to the end of - // the shader in order to keep derivatives correct. - if (m_analysis->usesKill && m_moduleInfo.options.useDemoteToHelperInvocation) { + if (m_analysis->usesKill) { // This extension basically implements D3D-style discard m_module.enableExtension("SPV_EXT_demote_to_helper_invocation"); m_module.enableCapability(spv::CapabilityDemoteToHelperInvocationEXT); } - else if (m_analysis->usesKill && m_analysis->usesDerivatives) { - m_ps.killState = m_module.newVarInit( - m_module.defPointerType(m_module.defBoolType(), spv::StorageClassPrivate), - spv::StorageClassPrivate, m_module.constBool(false)); - - m_module.setDebugName(m_ps.killState, "ps_kill"); - - if (m_moduleInfo.options.useSubgroupOpsForEarlyDiscard) { - m_module.enableCapability(spv::CapabilityGroupNonUniform); - m_module.enableCapability(spv::CapabilityGroupNonUniformBallot); - - DxsoRegisterInfo laneId; - laneId.type = { DxsoScalarType::Uint32, 1, 0 }; - laneId.sclass = spv::StorageClassInput; - - m_ps.builtinLaneId = emitNewBuiltinVariable( - laneId, spv::BuiltInSubgroupLocalInvocationId, - "fLaneId", 0); - } - } } @@ -3105,79 +3083,17 @@ void DxsoCompiler::emitControlFlowGenericLoop( if (texReg.type.ccount != 1) result = m_module.opAny(m_module.defBoolType(), result); - if (m_ps.killState == 0) { - uint32_t labelIf = m_module.allocateId(); - uint32_t labelEnd = m_module.allocateId(); + uint32_t labelIf = m_module.allocateId(); + uint32_t labelEnd = m_module.allocateId(); - m_module.opSelectionMerge(labelEnd, spv::SelectionControlMaskNone); - m_module.opBranchConditional(result, labelIf, labelEnd); + m_module.opSelectionMerge(labelEnd, spv::SelectionControlMaskNone); + m_module.opBranchConditional(result, labelIf, labelEnd); - m_module.opLabel(labelIf); + m_module.opLabel(labelIf); + m_module.opDemoteToHelperInvocation(); + m_module.opBranch(labelEnd); - if (m_moduleInfo.options.useDemoteToHelperInvocation) { - m_module.opDemoteToHelperInvocation(); - m_module.opBranch(labelEnd); - } else { - // OpKill terminates the block - m_module.opKill(); - } - - m_module.opLabel(labelEnd); - } - else { - uint32_t typeId = m_module.defBoolType(); - - uint32_t killState = m_module.opLoad (typeId, m_ps.killState); - killState = m_module.opLogicalOr(typeId, killState, result); - m_module.opStore(m_ps.killState, killState); - - if (m_moduleInfo.options.useSubgroupOpsForEarlyDiscard) { - uint32_t ballot = m_module.opGroupNonUniformBallot( - getVectorTypeId({ DxsoScalarType::Uint32, 4 }), - m_module.constu32(spv::ScopeSubgroup), - killState); - - uint32_t laneId = m_module.opLoad( - getScalarTypeId(DxsoScalarType::Uint32), - m_ps.builtinLaneId); - - uint32_t laneIdPart = m_module.opShiftRightLogical( - getScalarTypeId(DxsoScalarType::Uint32), - laneId, m_module.constu32(5)); - - uint32_t laneMask = m_module.opVectorExtractDynamic( - getScalarTypeId(DxsoScalarType::Uint32), - ballot, laneIdPart); - - uint32_t laneIdQuad = m_module.opBitwiseAnd( - getScalarTypeId(DxsoScalarType::Uint32), - laneId, m_module.constu32(0x1c)); - - laneMask = m_module.opShiftRightLogical( - getScalarTypeId(DxsoScalarType::Uint32), - laneMask, laneIdQuad); - - laneMask = m_module.opBitwiseAnd( - getScalarTypeId(DxsoScalarType::Uint32), - laneMask, m_module.constu32(0xf)); - - uint32_t killSubgroup = m_module.opIEqual( - m_module.defBoolType(), - laneMask, m_module.constu32(0xf)); - - uint32_t labelIf = m_module.allocateId(); - uint32_t labelEnd = m_module.allocateId(); - - m_module.opSelectionMerge(labelEnd, spv::SelectionControlMaskNone); - m_module.opBranchConditional(killSubgroup, labelIf, labelEnd); - - // OpKill terminates the block - m_module.opLabel(labelIf); - m_module.opKill(); - - m_module.opLabel(labelEnd); - } - } + m_module.opLabel(labelEnd); } void DxsoCompiler::emitTextureDepth(const DxsoInstructionContext& ctx) { @@ -3800,21 +3716,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( m_module.defVoidType(), m_ps.functionId, 0, nullptr); - if (m_ps.killState != 0) { - uint32_t labelIf = m_module.allocateId(); - uint32_t labelEnd = m_module.allocateId(); - - uint32_t killTest = m_module.opLoad(m_module.defBoolType(), m_ps.killState); - - m_module.opSelectionMerge(labelEnd, spv::SelectionControlMaskNone); - m_module.opBranchConditional(killTest, labelIf, labelEnd); - - m_module.opLabel(labelIf); - m_module.opKill(); - - m_module.opLabel(labelEnd); - } - // r0 in PS1 is the colour output register. Move r0 -> cO0 here. if (m_programInfo.majorVersion() == 1 && m_programInfo.type() == DxsoProgramTypes::PixelShader) { diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h index eb16eeee6..9f97fdda6 100644 --- a/src/dxso/dxso_compiler.h +++ b/src/dxso/dxso_compiler.h @@ -173,9 +173,6 @@ namespace dxvk { // Shared State uint32_t sharedState = 0; - uint32_t killState = 0; - uint32_t builtinLaneId = 0; - uint32_t flatShadingMask = 0; }; diff --git a/src/dxso/dxso_options.cpp b/src/dxso/dxso_options.cpp index 6f9dec89b..163c39b96 100644 --- a/src/dxso/dxso_options.cpp +++ b/src/dxso/dxso_options.cpp @@ -14,18 +14,6 @@ namespace dxvk { const DxvkDeviceFeatures& devFeatures = device->features(); const DxvkDeviceInfo& devInfo = adapter->devicePropertiesExt(); - useDemoteToHelperInvocation - = (devFeatures.vk13.shaderDemoteToHelperInvocation); - - useSubgroupOpsForEarlyDiscard - = (devInfo.vk11.subgroupSize >= 4) - && (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) - && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); - - // Disable early discard on Nvidia because it may hurt performance - if (adapter->matchesDriver(VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0)) - useSubgroupOpsForEarlyDiscard = false; - // Apply shader-related options strictConstantCopies = options.strictConstantCopies; diff --git a/src/dxso/dxso_options.h b/src/dxso/dxso_options.h index 85c65ec1b..437f97532 100644 --- a/src/dxso/dxso_options.h +++ b/src/dxso/dxso_options.h @@ -12,13 +12,6 @@ namespace dxvk { DxsoOptions(); DxsoOptions(D3D9DeviceEx* pDevice, const D3D9Options& options); - /// Use a SPIR-V extension to implement D3D-style discards - bool useDemoteToHelperInvocation = false; - - /// Use subgroup operations to discard fragment - /// shader invocations if derivatives remain valid. - bool useSubgroupOpsForEarlyDiscard = false; - /// True: Copy our constant set into UBO if we are relative indexing ever. /// False: Copy our constant set into UBO if we are relative indexing at the start of a defined constant /// Why?: In theory, FXC should never generate code where this would be an issue. From 76ee76d6da6a3d4ec010aab43f1f6ccaaaf491f1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 19 Aug 2022 15:56:25 +0200 Subject: [PATCH 0571/1348] [d3d9,dxso] Use DemoteToHelperInvocation for alpha test May enable additional compiler optimizations. --- src/d3d9/d3d9_fixed_function.cpp | 5 ++++- src/dxso/dxso_compiler.cpp | 8 ++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index cc6628214..344dc7e89 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -323,7 +323,8 @@ namespace dxvk { spvModule.opBranchConditional(atestDiscard, atestDiscardLabel, atestKeepLabel); spvModule.opLabel(atestDiscardLabel); - spvModule.opKill(); + spvModule.opDemoteToHelperInvocation(); + spvModule.opBranch(atestKeepLabel); // end if (do_discard) spvModule.opLabel(atestKeepLabel); @@ -2147,6 +2148,8 @@ namespace dxvk { m_specUbo = SetupSpecUBO(m_module, m_bindings); // PS Caps + m_module.enableExtension("SPV_EXT_demote_to_helper_invocation"); + m_module.enableCapability(spv::CapabilityDemoteToHelperInvocationEXT); m_module.enableCapability(spv::CapabilityDerivativeControl); m_module.setExecutionMode(m_entryPointId, diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 29dfef8f1..67066ec4f 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -488,6 +488,8 @@ namespace dxvk { void DxsoCompiler::emitPsInit() { + m_module.enableExtension("SPV_EXT_demote_to_helper_invocation"); + m_module.enableCapability(spv::CapabilityDemoteToHelperInvocationEXT); m_module.enableCapability(spv::CapabilityDerivativeControl); m_module.setExecutionMode(m_entryPointId, @@ -509,12 +511,6 @@ namespace dxvk { m_module.defFunctionType( m_module.defVoidType(), 0, nullptr)); this->emitFunctionLabel(); - - if (m_analysis->usesKill) { - // This extension basically implements D3D-style discard - m_module.enableExtension("SPV_EXT_demote_to_helper_invocation"); - m_module.enableCapability(spv::CapabilityDemoteToHelperInvocationEXT); - } } From 050e5b327cd99140c63dba7603a7a450a7df94ac Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 12:37:58 +0100 Subject: [PATCH 0572/1348] [wsi] Define wsi interface --- src/wsi/wsi_monitor.h | 127 +++++++++++++++++++++++++++++++++++++++ src/wsi/wsi_window.h | 135 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 262 insertions(+) create mode 100644 src/wsi/wsi_monitor.h create mode 100644 src/wsi/wsi_window.h diff --git a/src/wsi/wsi_monitor.h b/src/wsi/wsi_monitor.h new file mode 100644 index 000000000..c7e33578e --- /dev/null +++ b/src/wsi/wsi_monitor.h @@ -0,0 +1,127 @@ +#pragma once + +#include + +#include +#include + +namespace dxvk::wsi { + + /** + * \brief Rational number. Eg. 2/3 + */ + struct WsiRational { + uint32_t numerator; + uint32_t denominator; + }; + + /** + * \brief Display mode + */ + struct WsiMode { + uint32_t width; + uint32_t height; + WsiRational refreshRate; + uint32_t bitsPerPixel; + bool interlaced; + }; + + /** + * \brief Default monitor + * + * \returns The monitor of given index + */ + HMONITOR getDefaultMonitor(); + + /** + * \brief Enumerators monitors on the system + * + * \returns The monitor of given index + */ + HMONITOR enumMonitors(uint32_t index); + + /** + * \brief Get the GDI name of a HMONITOR + * + * Get the GDI Device Name of a HMONITOR to + * return to the end user. + * + * This typically looks like \.\\DISPLAY1 + * and has a maximum length of 32 chars. + * + * \param [in] hMonitor The monitor + * \param [out] Name The GDI display name + * \returns \c true on success, \c false if an error occured + */ + bool getDisplayName( + HMONITOR hMonitor, + WCHAR (&Name)[32]); + + /** + * \brief Get the encompassing coords of a monitor + */ + bool getDesktopCoordinates( + HMONITOR hMonitor, + RECT* pRect); + + /** + * \brief Get the nth display mode + * + * \param [in] hMonitor The monitor + * \param [in] modeNumber The nth mode + * \param [out] pMode The resultant mode + * \returns \c true on success, \c false if the mode could not be found + */ + bool getDisplayMode( + HMONITOR hMonitor, + uint32_t modeNumber, + WsiMode* pMode); + + /** + * \brief Get the current display mode + * + * This is the display mode right now. + * + * \param [in] hMonitor The monitor + * \param [out] pMode The resultant mode + * \returns \c true on success, \c false on failure + */ + bool getCurrentDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode); + + /** + * \brief Get the current display mode + * + * This is the display mode of the user's + * default desktop. + * + * \param [in] hMonitor The monitor + * \param [out] pMode The resultant mode + * \returns \c true on success, \c false on failure + */ + bool getDesktopDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode); + + /** + * \brief Get the size of a monitor + * + * Helper function to grab the size of a monitor + * using getDesktopCoordinates to mirror the window code. + */ + inline void getMonitorClientSize( + HMONITOR hMonitor, + UINT* pWidth, + UINT* pHeight) { + RECT rect = { }; + getDesktopCoordinates(hMonitor, &rect); + + if (pWidth) + *pWidth = rect.right - rect.left; + + if (pHeight) + *pHeight = rect.bottom - rect.top; + } + +} diff --git a/src/wsi/wsi_window.h b/src/wsi/wsi_window.h new file mode 100644 index 000000000..7471d50cd --- /dev/null +++ b/src/wsi/wsi_window.h @@ -0,0 +1,135 @@ +#pragma once + +#include + +#include "wsi_monitor.h" + +#include "../vulkan/vulkan_loader.h" + +namespace dxvk::wsi { + + /** + * \brief Impl-dependent state + */ + struct DxvkWindowState { +#ifdef DXVK_WSI_WIN32 + LONG style = 0; + LONG exstyle = 0; + RECT rect = { 0, 0, 0, 0 }; +#endif + }; + + /** + * \brief The size of the window + * + * \param [in] hWindow The window + * \param [out] pWidth The width (optional) + * \param [out] pHeight The height (optional) + */ + void getWindowSize( + HWND hWindow, + uint32_t* pWidth, + uint32_t* pWeight); + + /** + * \brief Resize a window + * + * \param [in] hWindow The window + * \param [in] pState The swapchain's window state + * \param [in] width The new width + * \param [in] height The new height + */ + void resizeWindow( + HWND hWindow, + DxvkWindowState* pState, + uint32_t width, + uint32_t weight); + + /** + * \brief Sets the display mode for a window/monitor + * + * \param [in] hMonitor The monitor + * \param [in] hWindow The window (may be unused on some platforms) + * \param [in] mode The mode + * \returns \c true on success, \c false on failure + */ + bool setWindowMode( + HMONITOR hMonitor, + HWND hWindow, + const WsiMode& mode); + + /** + * \brief Enter fullscreen mode for a window & monitor + * + * \param [in] hMonitor The monitor + * \param [in] hWindow The window (may be unused on some platforms) + * \param [in] pState The swapchain's window state + * \param [in] modeSwitch Whether mode switching is allowed + * \returns \c true on success, \c false on failure + */ + bool enterFullscreenMode( + HMONITOR hMonitor, + HWND hWindow, + DxvkWindowState* pState, + [[maybe_unused]] + bool modeSwitch); + + /** + * \brief Exit fullscreen mode for a window + * + * \param [in] hWindow The window + * \param [in] pState The swapchain's window state + * \returns \c true on success, \c false on failure + */ + bool leaveFullscreenMode( + HWND hWindow, + DxvkWindowState* pState); + + /** + * \brief Restores the display mode if necessary + * + * \returns \c true on success, \c false on failure + */ + bool restoreDisplayMode(); + + /** + * \brief The monitor a window is on + * + * \param [in] hWindow The window + * \returns The monitor the window is on + */ + HMONITOR getWindowMonitor(HWND hWindow); + + /** + * \brief Is a HWND a window? + * + * \param [in] hWindow The window + * \returns Is it a window? + */ + bool isWindow(HWND hWindow); + + /** + * \brief Update a fullscreen window's position/size + * + * \param [in] hMonitor The monitor + * \param [in] hWindow The window + * \param [in] forceTopmost Whether to force the window to become topmost again (D3D9 behaviour) + */ + void updateFullscreenWindow( + HMONITOR hMonitor, + HWND hWindow, + bool forceTopmost); + + /** + * \brief Create a surface for a window + * + * \param [in] hWindow The window + * \param [in] vki The instance + * \param [out] pSurface The surface + */ + VkResult createSurface( + HWND hWindow, + const Rc& vki, + VkSurfaceKHR* pSurface); + +} From efa6523e3ee400e7da9f7355e59bd5d52bd2567a Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 12:38:15 +0100 Subject: [PATCH 0573/1348] [wsi] Implement wsi interface for Windows --- src/meson.build | 1 + src/wsi/meson.build | 18 ++ src/wsi/win32/wsi_monitor_win32.cpp | 134 +++++++++++++ src/wsi/win32/wsi_window_win32.cpp | 288 ++++++++++++++++++++++++++++ 4 files changed, 441 insertions(+) create mode 100644 src/wsi/meson.build create mode 100644 src/wsi/win32/wsi_monitor_win32.cpp create mode 100644 src/wsi/win32/wsi_window_win32.cpp diff --git a/src/meson.build b/src/meson.build index c5d2753a5..c2831cf1b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,3 +1,4 @@ +subdir('wsi') subdir('util') subdir('spirv') subdir('vulkan') diff --git a/src/wsi/meson.build b/src/wsi/meson.build new file mode 100644 index 000000000..0e0f9da39 --- /dev/null +++ b/src/wsi/meson.build @@ -0,0 +1,18 @@ +wsi_win32_src = [ + 'win32/wsi_monitor_win32.cpp', + 'win32/wsi_window_win32.cpp', +] + +if dxvk_wsi == 'win32' + wsi_src = wsi_win32_src + wsi_deps = [] +else + error('Unknown wsi') +endif + +wsi_lib = static_library('wsi', wsi_src, + dependencies : wsi_deps, + include_directories : [ dxvk_include_path ]) + +wsi_dep = declare_dependency( + link_with : [ wsi_lib ]) diff --git a/src/wsi/win32/wsi_monitor_win32.cpp b/src/wsi/win32/wsi_monitor_win32.cpp new file mode 100644 index 000000000..be466db58 --- /dev/null +++ b/src/wsi/win32/wsi_monitor_win32.cpp @@ -0,0 +1,134 @@ +#include "../wsi_monitor.h" + +#include "../../util/log/log.h" + +#include + +namespace dxvk::wsi { + + HMONITOR getDefaultMonitor() { + return ::MonitorFromPoint({ 0, 0 }, MONITOR_DEFAULTTOPRIMARY); + } + + struct MonitorEnumInfo { + UINT iMonitorId; + HMONITOR oMonitor; + }; + + static BOOL CALLBACK MonitorEnumProc( + HMONITOR hmon, + HDC hdc, + LPRECT rect, + LPARAM lp) { + auto data = reinterpret_cast(lp); + + if (data->iMonitorId--) + return TRUE; /* continue */ + + data->oMonitor = hmon; + return FALSE; /* stop */ + } + + HMONITOR enumMonitors(uint32_t index) { + MonitorEnumInfo info; + info.iMonitorId = index; + info.oMonitor = nullptr; + + ::EnumDisplayMonitors( + nullptr, nullptr, &MonitorEnumProc, + reinterpret_cast(&info)); + + return info.oMonitor; + } + + + bool getDisplayName( + HMONITOR hMonitor, + WCHAR (&Name)[32]) { + // Query monitor info to get the device name + ::MONITORINFOEXW monInfo; + monInfo.cbSize = sizeof(monInfo); + + if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { + Logger::err("Win32 WSI: getDisplayName: Failed to query monitor info"); + return false; + } + + std::memcpy(Name, monInfo.szDevice, sizeof(Name)); + + return true; + } + + + bool getDesktopCoordinates( + HMONITOR hMonitor, + RECT* pRect) { + ::MONITORINFOEXW monInfo; + monInfo.cbSize = sizeof(monInfo); + + if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { + Logger::err("Win32 WSI: getDisplayName: Failed to query monitor info"); + return false; + } + + *pRect = monInfo.rcMonitor; + + return true; + } + + static inline void convertMode(const DEVMODEW& mode, WsiMode* pMode) { + pMode->width = mode.dmPelsWidth; + pMode->height = mode.dmPelsHeight; + pMode->refreshRate = WsiRational{ mode.dmDisplayFrequency * 1000, 1000 }; + pMode->bitsPerPixel = mode.dmBitsPerPel; + pMode->interlaced = mode.dmDisplayFlags & DM_INTERLACED; + } + + + static inline bool retrieveDisplayMode( + HMONITOR hMonitor, + DWORD modeNumber, + WsiMode* pMode) { + // Query monitor info to get the device name + ::MONITORINFOEXW monInfo; + monInfo.cbSize = sizeof(monInfo); + + if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { + Logger::err("Win32 WSI: retrieveDisplayMode: Failed to query monitor info"); + return false; + } + + DEVMODEW devMode = { }; + devMode.dmSize = sizeof(devMode); + + if (!::EnumDisplaySettingsW(monInfo.szDevice, modeNumber, &devMode)) + return false; + + convertMode(devMode, pMode); + + return true; + } + + + bool getDisplayMode( + HMONITOR hMonitor, + uint32_t modeNumber, + WsiMode* pMode) { + return retrieveDisplayMode(hMonitor, modeNumber, pMode); + } + + + bool getCurrentDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode) { + return retrieveDisplayMode(hMonitor, ENUM_CURRENT_SETTINGS, pMode); + } + + + bool getDesktopDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode) { + return retrieveDisplayMode(hMonitor, ENUM_REGISTRY_SETTINGS, pMode); + } + +} \ No newline at end of file diff --git a/src/wsi/win32/wsi_window_win32.cpp b/src/wsi/win32/wsi_window_win32.cpp new file mode 100644 index 000000000..364c0c0ef --- /dev/null +++ b/src/wsi/win32/wsi_window_win32.cpp @@ -0,0 +1,288 @@ +#include "../wsi_window.h" +#include "../wsi_monitor.h" + +#include "../../util/util_string.h" +#include "../../util/log/log.h" + +namespace dxvk::wsi { + + static bool getMonitorDisplayMode( + HMONITOR hMonitor, + DWORD modeNum, + DEVMODEW* pMode) { + ::MONITORINFOEXW monInfo; + monInfo.cbSize = sizeof(monInfo); + + if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { + Logger::err("Failed to query monitor info"); + return false; + } + + return ::EnumDisplaySettingsW(monInfo.szDevice, modeNum, pMode); + } + + + static bool setMonitorDisplayMode( + HMONITOR hMonitor, + DEVMODEW* pMode) { + ::MONITORINFOEXW monInfo; + monInfo.cbSize = sizeof(monInfo); + + if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { + Logger::err("Failed to query monitor info"); + return E_FAIL; + } + + Logger::info(str::format("Setting display mode: ", + pMode->dmPelsWidth, "x", pMode->dmPelsHeight, "@", + pMode->dmDisplayFrequency)); + + DEVMODEW curMode = { }; + curMode.dmSize = sizeof(curMode); + + if (getMonitorDisplayMode(hMonitor, ENUM_CURRENT_SETTINGS, &curMode)) { + bool eq = curMode.dmPelsWidth == pMode->dmPelsWidth + && curMode.dmPelsHeight == pMode->dmPelsHeight + && curMode.dmBitsPerPel == pMode->dmBitsPerPel; + + if (pMode->dmFields & DM_DISPLAYFREQUENCY) + eq &= curMode.dmDisplayFrequency == pMode->dmDisplayFrequency; + + if (eq) + return true; + } + + LONG status = ::ChangeDisplaySettingsExW(monInfo.szDevice, + pMode, nullptr, CDS_FULLSCREEN, nullptr); + + if (status != DISP_CHANGE_SUCCESSFUL) { + pMode->dmFields &= ~DM_DISPLAYFREQUENCY; + + status = ::ChangeDisplaySettingsExW(monInfo.szDevice, + pMode, nullptr, CDS_FULLSCREEN, nullptr); + } + + return status == DISP_CHANGE_SUCCESSFUL; + } + + + static BOOL CALLBACK restoreDisplayModeCallback( + HMONITOR hMonitor, + HDC hDC, + LPRECT pRect, + LPARAM pUserdata) { + auto success = reinterpret_cast(pUserdata); + + DEVMODEW devMode = { }; + devMode.dmSize = sizeof(devMode); + + if (!getMonitorDisplayMode(hMonitor, ENUM_REGISTRY_SETTINGS, &devMode)) { + *success = false; + return false; + } + + Logger::info(str::format("Restoring display mode: ", + devMode.dmPelsWidth, "x", devMode.dmPelsHeight, "@", + devMode.dmDisplayFrequency)); + + if (!setMonitorDisplayMode(hMonitor, &devMode)) { + *success = false; + return false; + } + + return true; + } + + + void getWindowSize( + HWND hWindow, + uint32_t* pWidth, + uint32_t* pHeight) { + RECT rect = { }; + ::GetClientRect(hWindow, &rect); + + if (pWidth) + *pWidth = rect.right - rect.left; + + if (pHeight) + *pHeight = rect.bottom - rect.top; + } + + + void resizeWindow( + HWND hWindow, + DxvkWindowState* pState, + uint32_t width, + uint32_t height) { + // Adjust window position and size + RECT newRect = { 0, 0, 0, 0 }; + RECT oldRect = { 0, 0, 0, 0 }; + + ::GetWindowRect(hWindow, &oldRect); + ::SetRect(&newRect, 0, 0, width, height); + ::AdjustWindowRectEx(&newRect, + ::GetWindowLongW(hWindow, GWL_STYLE), FALSE, + ::GetWindowLongW(hWindow, GWL_EXSTYLE)); + ::SetRect(&newRect, 0, 0, newRect.right - newRect.left, newRect.bottom - newRect.top); + ::OffsetRect(&newRect, oldRect.left, oldRect.top); + ::MoveWindow(hWindow, newRect.left, newRect.top, + newRect.right - newRect.left, newRect.bottom - newRect.top, TRUE); + } + + + bool setWindowMode( + HMONITOR hMonitor, + HWND hWindow, + const WsiMode& mode) { + ::MONITORINFOEXW monInfo; + monInfo.cbSize = sizeof(monInfo); + + if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { + Logger::err("Win32 WSI: setWindowMode: Failed to query monitor info"); + return false; + } + + DEVMODEW devMode = { }; + devMode.dmSize = sizeof(devMode); + devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; + devMode.dmPelsWidth = mode.width; + devMode.dmPelsHeight = mode.height; + devMode.dmBitsPerPel = mode.bitsPerPixel; + + if (mode.refreshRate.numerator != 0) { + devMode.dmFields |= DM_DISPLAYFREQUENCY; + devMode.dmDisplayFrequency = mode.refreshRate.numerator + / mode.refreshRate.denominator; + } + + Logger::info(str::format("Setting display mode: ", + devMode.dmPelsWidth, "x", devMode.dmPelsHeight, "@", + devMode.dmDisplayFrequency)); + + return setMonitorDisplayMode(hMonitor, &devMode); + } + + + bool enterFullscreenMode( + HMONITOR hMonitor, + HWND hWindow, + DxvkWindowState* pState, + [[maybe_unused]] + bool modeSwitch) { + // Find a display mode that matches what we need + ::GetWindowRect(hWindow, &pState->rect); + + // Change the window flags to remove the decoration etc. + LONG style = ::GetWindowLongW(hWindow, GWL_STYLE); + LONG exstyle = ::GetWindowLongW(hWindow, GWL_EXSTYLE); + + pState->style = style; + pState->exstyle = exstyle; + + style &= ~WS_OVERLAPPEDWINDOW; + exstyle &= ~WS_EX_OVERLAPPEDWINDOW; + + ::SetWindowLongW(hWindow, GWL_STYLE, style); + ::SetWindowLongW(hWindow, GWL_EXSTYLE, exstyle); + + RECT rect = { }; + getDesktopCoordinates(hMonitor, &rect); + + ::SetWindowPos(hWindow, HWND_TOPMOST, + rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, + SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); + + return true; + } + + + bool leaveFullscreenMode( + HWND hWindow, + DxvkWindowState* pState) { + // Only restore the window style if the application hasn't + // changed them. This is in line with what native DXGI does. + LONG curStyle = ::GetWindowLongW(hWindow, GWL_STYLE) & ~WS_VISIBLE; + LONG curExstyle = ::GetWindowLongW(hWindow, GWL_EXSTYLE) & ~WS_EX_TOPMOST; + + if (curStyle == (pState->style & ~(WS_VISIBLE | WS_OVERLAPPEDWINDOW)) + && curExstyle == (pState->exstyle & ~(WS_EX_TOPMOST | WS_EX_OVERLAPPEDWINDOW))) { + ::SetWindowLongW(hWindow, GWL_STYLE, pState->style); + ::SetWindowLongW(hWindow, GWL_EXSTYLE, pState->exstyle); + } + + // Restore window position and apply the style + const RECT rect = pState->rect; + + ::SetWindowPos(hWindow, (pState->exstyle & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_NOTOPMOST, + rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, + SWP_FRAMECHANGED | SWP_NOACTIVATE); + + return true; + } + + + bool restoreDisplayMode() { + bool success = true; + bool result = ::EnumDisplayMonitors(nullptr, nullptr, + &restoreDisplayModeCallback, + reinterpret_cast(&success)); + + return result && success; + } + + + HMONITOR getWindowMonitor(HWND hWindow) { + RECT windowRect = { 0, 0, 0, 0 }; + ::GetWindowRect(hWindow, &windowRect); + + HMONITOR monitor = ::MonitorFromPoint( + { (windowRect.left + windowRect.right) / 2, + (windowRect.top + windowRect.bottom) / 2 }, + MONITOR_DEFAULTTOPRIMARY); + + return monitor; + } + + + bool isWindow(HWND hWindow) { + return ::IsWindow(hWindow); + } + + + void updateFullscreenWindow( + HMONITOR hMonitor, + HWND hWindow, + bool forceTopmost) { + RECT bounds = { }; + wsi::getDesktopCoordinates(hMonitor, &bounds); + + // In D3D9, changing display modes re-forces the window + // to become top most, whereas in DXGI, it does not. + if (forceTopmost) { + ::SetWindowPos(hWindow, HWND_TOPMOST, + bounds.left, bounds.top, + bounds.right - bounds.left, bounds.bottom - bounds.top, + SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); + } else { + ::MoveWindow(hWindow, bounds.left, bounds.top, + bounds.right - bounds.left, bounds.bottom - bounds.top, TRUE); + } + } + + + VkResult createSurface( + HWND hWindow, + const Rc& vki, + VkSurfaceKHR* pSurface) { + HINSTANCE hInstance = reinterpret_cast( + GetWindowLongPtr(hWindow, GWLP_HINSTANCE)); + + VkWin32SurfaceCreateInfoKHR info = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR }; + info.hinstance = hInstance; + info.hwnd = hWindow; + + return vki->vkCreateWin32SurfaceKHR( + vki->instance(), &info, nullptr, pSurface); + } + +} \ No newline at end of file From b875d49c850fb77e9b4fd3ea2470330b5814671f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 14 Aug 2022 16:57:14 +0000 Subject: [PATCH 0574/1348] [wsi] Move DxvkWindowState to wsi platform header --- src/wsi/win32/wsi_platform_win32.h | 16 ++++++++++++++++ src/wsi/wsi_platform.h | 5 +++++ src/wsi/wsi_window.h | 12 +----------- 3 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 src/wsi/win32/wsi_platform_win32.h create mode 100644 src/wsi/wsi_platform.h diff --git a/src/wsi/win32/wsi_platform_win32.h b/src/wsi/win32/wsi_platform_win32.h new file mode 100644 index 000000000..d382f20ad --- /dev/null +++ b/src/wsi/win32/wsi_platform_win32.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +namespace dxvk::wsi { + + /** + * \brief Impl-dependent state + */ + struct DxvkWindowState { + LONG style = 0; + LONG exstyle = 0; + RECT rect = { 0, 0, 0, 0 }; + }; + +} \ No newline at end of file diff --git a/src/wsi/wsi_platform.h b/src/wsi/wsi_platform.h new file mode 100644 index 000000000..5028b20bb --- /dev/null +++ b/src/wsi/wsi_platform.h @@ -0,0 +1,5 @@ +#pragma once + +#ifdef DXVK_WSI_WIN32 +#include "win32/wsi_platform_win32.h" +#endif diff --git a/src/wsi/wsi_window.h b/src/wsi/wsi_window.h index 7471d50cd..9928b43d6 100644 --- a/src/wsi/wsi_window.h +++ b/src/wsi/wsi_window.h @@ -3,22 +3,12 @@ #include #include "wsi_monitor.h" +#include "wsi_platform.h" #include "../vulkan/vulkan_loader.h" namespace dxvk::wsi { - /** - * \brief Impl-dependent state - */ - struct DxvkWindowState { -#ifdef DXVK_WSI_WIN32 - LONG style = 0; - LONG exstyle = 0; - RECT rect = { 0, 0, 0, 0 }; -#endif - }; - /** * \brief The size of the window * From 4b0f13d351327a423837d5de6c641f53daffd3b8 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 13:19:36 +0100 Subject: [PATCH 0575/1348] [build] Set dxvk_wsi and defines for Windows --- meson.build | 3 +++ 1 file changed, 3 insertions(+) diff --git a/meson.build b/meson.build index f044c8f4f..11692c386 100644 --- a/meson.build +++ b/meson.build @@ -92,6 +92,9 @@ if platform == 'windows' endif dxvk_include_path = include_directories('./include') + + dxvk_wsi = 'win32' + compiler_args += ['-DDXVK_WSI_WIN32'] else lib_vulkan = cpp.find_library('vulkan') lib_sdl2 = cpp.find_library('SDL2') From 86b603b8f963358a7bf8de522b6df65c11ef7e5d Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 13:24:48 +0100 Subject: [PATCH 0576/1348] [dxvk] Link against new wsi lib --- src/dxvk/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index b0463108c..cf2822504 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -118,7 +118,7 @@ dxvk_src = files([ thread_dep = dependency('threads') dxvk_lib = static_library('dxvk', dxvk_src, glsl_generator.process(dxvk_shaders), dxvk_version, - link_with : [ util_lib, spirv_lib ], + link_with : [ util_lib, spirv_lib, wsi_lib ], dependencies : [ thread_dep, vkcommon_dep ], include_directories : [ dxvk_include_path ], ) From 4f80ffd830c0619f2058781193620a312758b3f3 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 13:30:31 +0100 Subject: [PATCH 0577/1348] [vulkan] Use surface creation from wsi interface --- src/vulkan/vulkan_presenter.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index b8c2d1225..5725b3644 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -2,6 +2,8 @@ #include "../dxvk/dxvk_format.h" +#include "../wsi/wsi_window.h" + namespace dxvk::vk { Presenter::Presenter( @@ -416,16 +418,8 @@ namespace dxvk::vk { VkResult Presenter::createSurface() { - HINSTANCE instance = reinterpret_cast( - GetWindowLongPtr(m_window, GWLP_HINSTANCE)); - - VkWin32SurfaceCreateInfoKHR info = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR }; - info.hinstance = instance; - info.hwnd = m_window; - - VkResult status = m_vki->vkCreateWin32SurfaceKHR( - m_vki->instance(), &info, nullptr, &m_surface); - + VkResult status = wsi::createSurface(m_window, m_vki, &m_surface); + if (status != VK_SUCCESS) return status; From 9f9c93dcbdb80cf514fd41822c1f89e9dd72f0d6 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 13:06:48 +0100 Subject: [PATCH 0578/1348] [d3d11] Use new wsi interface --- src/d3d11/d3d11_device.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 376f06e69..d05e99cc4 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -24,6 +24,8 @@ #include "d3d11_texture.h" #include "d3d11_video.h" +#include "../wsi/wsi_window.h" + #include "../util/util_shared_res.h" namespace dxvk { @@ -3047,7 +3049,7 @@ namespace dxvk { // Make sure the back buffer size is not zero DXGI_SWAP_CHAIN_DESC1 desc = *pDesc; - GetWindowClientSize(hWnd, + wsi::getWindowSize(hWnd, desc.Width ? nullptr : &desc.Width, desc.Height ? nullptr : &desc.Height); From 71a630801e68ee2c76007cd0de053deae822cbf3 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 13:11:32 +0100 Subject: [PATCH 0579/1348] [dxgi] Add helpers for new wsi interface --- src/dxgi/dxgi_monitor.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/dxgi/dxgi_monitor.h b/src/dxgi/dxgi_monitor.h index 0c70101b2..eee6d47e2 100644 --- a/src/dxgi/dxgi_monitor.h +++ b/src/dxgi/dxgi_monitor.h @@ -5,6 +5,8 @@ #include "dxgi_interfaces.h" +#include "../wsi/wsi_monitor.h" + namespace dxvk { class DxgiSwapChain; @@ -55,4 +57,33 @@ namespace dxvk { uint32_t GetMonitorFormatBpp( DXGI_FORMAT Format); + /** + * \brief Converts a DXVK WSI display mode to a DXGI display mode + */ + inline DXGI_MODE_DESC1 ConvertDisplayMode(const wsi::WsiMode& WsiMode) { + DXGI_MODE_DESC1 dxgiMode = { }; + dxgiMode.Width = WsiMode.width; + dxgiMode.Height = WsiMode.height; + dxgiMode.RefreshRate = DXGI_RATIONAL{ WsiMode.refreshRate.numerator, WsiMode.refreshRate.denominator }; + dxgiMode.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; // FIXME + dxgiMode.ScanlineOrdering = WsiMode.interlaced ? DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST : DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE; + dxgiMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + dxgiMode.Stereo = FALSE; + return dxgiMode; + } + + /** + * \brief Converts a DXGI display mode to a DXVK WSI display mode + */ + inline wsi::WsiMode ConvertDisplayMode(const DXGI_MODE_DESC1& DxgiMode) { + wsi::WsiMode wsiMode = { }; + wsiMode.width = DxgiMode.Width; + wsiMode.height = DxgiMode.Height; + wsiMode.refreshRate = wsi::WsiRational{ DxgiMode.RefreshRate.Numerator, DxgiMode.RefreshRate.Denominator }; + wsiMode.bitsPerPixel = GetMonitorFormatBpp(DxgiMode.Format); + wsiMode.interlaced = DxgiMode.ScanlineOrdering == DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST + || DxgiMode.ScanlineOrdering == DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST; + return wsiMode; + } + } \ No newline at end of file From e13a9f9cf653aaa8f9b8cf2cc8a137866fcf639e Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 13:11:53 +0100 Subject: [PATCH 0580/1348] [dxgi] Make output code use new wsi interface --- src/dxgi/dxgi_output.cpp | 48 +++++++++++++++------------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index ffa5b5dc2..81a4671ea 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -125,16 +125,10 @@ namespace dxvk { DEVMODEW devMode; devMode.dmSize = sizeof(devMode); - if (!GetMonitorDisplayMode(m_monitor, ENUM_CURRENT_SETTINGS, &devMode)) - return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; + wsi::WsiMode activeWsiMode = { }; + wsi::getCurrentDisplayMode(m_monitor, &activeWsiMode); - DXGI_MODE_DESC activeMode = { }; - activeMode.Width = devMode.dmPelsWidth; - activeMode.Height = devMode.dmPelsHeight; - activeMode.RefreshRate = { devMode.dmDisplayFrequency, 1 }; - activeMode.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; // FIXME - activeMode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE; - activeMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + DXGI_MODE_DESC1 activeMode = ConvertDisplayMode(activeWsiMode); DXGI_MODE_DESC1 defaultMode; defaultMode.Width = 0; @@ -222,17 +216,16 @@ namespace dxvk { if (pDesc == nullptr) return DXGI_ERROR_INVALID_CALL; - ::MONITORINFOEXW monInfo; - monInfo.cbSize = sizeof(monInfo); - - if (!::GetMonitorInfoW(m_monitor, reinterpret_cast(&monInfo))) { - Logger::err("DXGI: Failed to query monitor info"); + if (!wsi::getDesktopCoordinates(m_monitor, &pDesc->DesktopCoordinates)) { + Logger::err("DXGI: Failed to query monitor coords"); return E_FAIL; } - std::memcpy(pDesc->DeviceName, monInfo.szDevice, std::size(pDesc->DeviceName)); - - pDesc->DesktopCoordinates = monInfo.rcMonitor; + if (!wsi::getDisplayName(m_monitor, pDesc->DeviceName)) { + Logger::err("DXGI: Failed to query monitor name"); + return E_FAIL; + } + pDesc->AttachedToDesktop = 1; pDesc->Rotation = DXGI_MODE_ROTATION_UNSPECIFIED; pDesc->Monitor = m_monitor; @@ -300,32 +293,27 @@ namespace dxvk { // Walk over all modes that the display supports and // return those that match the requested format etc. - DEVMODEW devMode = { }; - devMode.dmSize = sizeof(DEVMODEW); + wsi::WsiMode devMode = { }; uint32_t srcModeId = 0; uint32_t dstModeId = 0; std::vector modeList; - while (GetMonitorDisplayMode(m_monitor, srcModeId++, &devMode)) { + while (wsi::getDisplayMode(m_monitor, srcModeId++, &devMode)) { // Skip interlaced modes altogether - if (devMode.dmDisplayFlags & DM_INTERLACED) + if (devMode.interlaced) continue; // Skip modes with incompatible formats - if (devMode.dmBitsPerPel != GetMonitorFormatBpp(EnumFormat)) + if (devMode.bitsPerPixel != GetMonitorFormatBpp(EnumFormat)) continue; if (pDesc != nullptr) { - DXGI_MODE_DESC1 mode; - mode.Width = devMode.dmPelsWidth; - mode.Height = devMode.dmPelsHeight; - mode.RefreshRate = { devMode.dmDisplayFrequency * 1000, 1000 }; - mode.Format = EnumFormat; - mode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE; - mode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - mode.Stereo = FALSE; + DXGI_MODE_DESC1 mode = ConvertDisplayMode(devMode); + // Fix up the DXGI_FORMAT to match what we were enumerating. + mode.Format = EnumFormat; + modeList.push_back(mode); } From 21744198e0427824a1e120fdfed57b16d3b2bf1f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 13:25:12 +0100 Subject: [PATCH 0581/1348] [dxgi] Make swapchain use new wsi interface --- src/dxgi/dxgi_swapchain.cpp | 142 +++++++++++------------------------- src/dxgi/dxgi_swapchain.h | 11 +-- 2 files changed, 45 insertions(+), 108 deletions(-) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 09ebd6972..399a99616 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -91,7 +91,7 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiSwapChain::GetContainingOutput(IDXGIOutput** ppOutput) { InitReturnPtr(ppOutput); - if (!IsWindow(m_window)) + if (!wsi::isWindow(m_window)) return DXGI_ERROR_INVALID_CALL; if (m_target != nullptr) { @@ -99,15 +99,7 @@ namespace dxvk { return S_OK; } - RECT windowRect = { 0, 0, 0, 0 }; - ::GetWindowRect(m_window, &windowRect); - - HMONITOR monitor = ::MonitorFromPoint( - { (windowRect.left + windowRect.right) / 2, - (windowRect.top + windowRect.bottom) / 2 }, - MONITOR_DEFAULTTOPRIMARY); - - return GetOutputFromMonitor(monitor, ppOutput); + return GetOutputFromMonitor(wsi::getWindowMonitor(m_window), ppOutput); } @@ -256,7 +248,7 @@ namespace dxvk { UINT PresentFlags, const DXGI_PRESENT_PARAMETERS* pPresentParameters) { - if (!IsWindow(m_window)) + if (!wsi::isWindow(m_window)) return S_OK; if (SyncInterval > 4) @@ -283,7 +275,7 @@ namespace dxvk { UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) { - if (!IsWindow(m_window)) + if (!wsi::isWindow(m_window)) return DXGI_ERROR_INVALID_CALL; constexpr UINT PreserveFlags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; @@ -295,7 +287,7 @@ namespace dxvk { m_desc.Width = Width; m_desc.Height = Height; - GetWindowClientSize(m_window, + wsi::getWindowSize(m_window, m_desc.Width ? nullptr : &m_desc.Width, m_desc.Height ? nullptr : &m_desc.Height); @@ -333,7 +325,7 @@ namespace dxvk { if (pNewTargetParameters == nullptr) return DXGI_ERROR_INVALID_CALL; - if (!IsWindow(m_window)) + if (!wsi::isWindow(m_window)) return DXGI_ERROR_INVALID_CALL; // Update the swap chain description @@ -344,19 +336,10 @@ namespace dxvk { m_descFs.Scaling = pNewTargetParameters->Scaling; if (m_descFs.Windowed) { - // Adjust window position and size - RECT newRect = { 0, 0, 0, 0 }; - RECT oldRect = { 0, 0, 0, 0 }; - - ::GetWindowRect(m_window, &oldRect); - ::SetRect(&newRect, 0, 0, pNewTargetParameters->Width, pNewTargetParameters->Height); - ::AdjustWindowRectEx(&newRect, - ::GetWindowLongW(m_window, GWL_STYLE), FALSE, - ::GetWindowLongW(m_window, GWL_EXSTYLE)); - ::SetRect(&newRect, 0, 0, newRect.right - newRect.left, newRect.bottom - newRect.top); - ::OffsetRect(&newRect, oldRect.left, oldRect.top); - ::MoveWindow(m_window, newRect.left, newRect.top, - newRect.right - newRect.left, newRect.bottom - newRect.top, TRUE); + wsi::resizeWindow( + m_window, &m_windowState, + pNewTargetParameters->Width, + pNewTargetParameters->Height); } else { Com output; @@ -370,15 +353,8 @@ namespace dxvk { ChangeDisplayMode(output.ptr(), pNewTargetParameters); NotifyModeChange(m_monitor, FALSE); } - - // Resize and reposition the window to - DXGI_OUTPUT_DESC desc; - output->GetDesc(&desc); - - RECT newRect = desc.DesktopCoordinates; - - ::MoveWindow(m_window, newRect.left, newRect.top, - newRect.right - newRect.left, newRect.bottom - newRect.top, TRUE); + + wsi::updateFullscreenWindow(m_monitor, m_window, false); } return S_OK; @@ -555,7 +531,7 @@ namespace dxvk { HRESULT DxgiSwapChain::EnterFullscreenMode(IDXGIOutput* pTarget) { Com output = pTarget; - if (!IsWindow(m_window)) + if (!wsi::isWindow(m_window)) return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; if (output == nullptr) { @@ -564,11 +540,10 @@ namespace dxvk { return E_FAIL; } } + + const bool modeSwitch = m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - // Find a display mode that matches what we need - ::GetWindowRect(m_window, &m_windowState.rect); - - if (m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH) { + if (modeSwitch) { DXGI_MODE_DESC displayMode; displayMode.Width = m_desc.Width; displayMode.Height = m_desc.Height; @@ -588,28 +563,14 @@ namespace dxvk { // Update swap chain description m_descFs.Windowed = FALSE; - // Change the window flags to remove the decoration etc. - LONG style = ::GetWindowLongW(m_window, GWL_STYLE); - LONG exstyle = ::GetWindowLongW(m_window, GWL_EXSTYLE); - - m_windowState.style = style; - m_windowState.exstyle = exstyle; - - style &= ~WS_OVERLAPPEDWINDOW; - exstyle &= ~WS_EX_OVERLAPPEDWINDOW; - - ::SetWindowLongW(m_window, GWL_STYLE, style); - ::SetWindowLongW(m_window, GWL_EXSTYLE, exstyle); - // Move the window so that it covers the entire output DXGI_OUTPUT_DESC desc; output->GetDesc(&desc); - - const RECT rect = desc.DesktopCoordinates; - - ::SetWindowPos(m_window, HWND_TOPMOST, - rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, - SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); + + if (!wsi::enterFullscreenMode(desc.Monitor, m_window, &m_windowState, modeSwitch)) { + Logger::err("DXGI: EnterFullscreenMode: Failed to enter fullscreen mode"); + return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; + } m_monitor = desc.Monitor; m_target = std::move(output); @@ -652,27 +613,14 @@ namespace dxvk { m_monitor = nullptr; m_target = nullptr; - if (!IsWindow(m_window)) + if (!wsi::isWindow(m_window)) return S_OK; - // Only restore the window style if the application hasn't - // changed them. This is in line with what native DXGI does. - LONG curStyle = ::GetWindowLongW(m_window, GWL_STYLE) & ~WS_VISIBLE; - LONG curExstyle = ::GetWindowLongW(m_window, GWL_EXSTYLE) & ~WS_EX_TOPMOST; - - if (curStyle == (m_windowState.style & ~(WS_VISIBLE | WS_OVERLAPPEDWINDOW)) - && curExstyle == (m_windowState.exstyle & ~(WS_EX_TOPMOST | WS_EX_OVERLAPPEDWINDOW))) { - ::SetWindowLongW(m_window, GWL_STYLE, m_windowState.style); - ::SetWindowLongW(m_window, GWL_EXSTYLE, m_windowState.exstyle); + if (!wsi::leaveFullscreenMode(m_window, &m_windowState)) { + Logger::err("DXGI: LeaveFullscreenMode: Failed to exit fullscreen mode"); + return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; } - // Restore window position and apply the style - const RECT rect = m_windowState.rect; - - ::SetWindowPos(m_window, (m_windowState.exstyle & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_NOTOPMOST, - rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, - SWP_FRAMECHANGED | SWP_NOACTIVATE); - NotifyModeChange(monitor, TRUE); return S_OK; } @@ -705,23 +653,17 @@ namespace dxvk { "@", preferredMode.RefreshRate.Numerator / preferredMode.RefreshRate.Denominator)); return hr; } - - DEVMODEW devMode = { }; - devMode.dmSize = sizeof(devMode); - devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; - devMode.dmPelsWidth = selectedMode.Width; - devMode.dmPelsHeight = selectedMode.Height; - devMode.dmBitsPerPel = GetMonitorFormatBpp(selectedMode.Format); - - if (selectedMode.RefreshRate.Numerator != 0) { - devMode.dmFields |= DM_DISPLAYFREQUENCY; - devMode.dmDisplayFrequency = selectedMode.RefreshRate.Numerator - / selectedMode.RefreshRate.Denominator; - } - return SetMonitorDisplayMode(outputDesc.Monitor, &devMode) - ? S_OK - : DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; + DXGI_MODE_DESC1 selectedMode1; + selectedMode1.Width = selectedMode.Width; + selectedMode1.Height = selectedMode.Height; + selectedMode1.RefreshRate = selectedMode.RefreshRate; + selectedMode1.Format = selectedMode.Format; + selectedMode1.ScanlineOrdering = selectedMode.ScanlineOrdering; + selectedMode1.Scaling = selectedMode.Scaling; + selectedMode1.Stereo = false; + + return wsi::setWindowMode(outputDesc.Monitor, m_window, ConvertDisplayMode(selectedMode1)); } @@ -729,7 +671,7 @@ namespace dxvk { if (!hMonitor) return DXGI_ERROR_INVALID_CALL; - return RestoreMonitorDisplayMode() + return wsi::restoreDisplayMode() ? S_OK : DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; } @@ -787,15 +729,13 @@ namespace dxvk { void DxgiSwapChain::NotifyModeChange( HMONITOR hMonitor, BOOL Windowed) { - DEVMODEW devMode = { }; - devMode.dmSize = sizeof(devMode); - devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; + wsi::WsiMode mode = { }; - if (GetMonitorDisplayMode(hMonitor, ENUM_CURRENT_SETTINGS, &devMode)) { + if (wsi::getCurrentDisplayMode(hMonitor, &mode)) { DXGI_MODE_DESC displayMode = { }; - displayMode.Width = devMode.dmPelsWidth; - displayMode.Height = devMode.dmPelsHeight; - displayMode.RefreshRate = { devMode.dmDisplayFrequency, 1 }; + displayMode.Width = mode.width; + displayMode.Height = mode.height; + displayMode.RefreshRate = { mode.refreshRate.numerator, mode.refreshRate.denominator }; displayMode.Format = m_desc.Format; displayMode.ScanlineOrdering = m_descFs.ScanlineOrdering; displayMode.Scaling = m_descFs.Scaling; diff --git a/src/dxgi/dxgi_swapchain.h b/src/dxgi/dxgi_swapchain.h index 62adf0e8a..31e49b941 100644 --- a/src/dxgi/dxgi_swapchain.h +++ b/src/dxgi/dxgi_swapchain.h @@ -13,6 +13,9 @@ #include "../util/util_time.h" +#include "../wsi/wsi_window.h" +#include "../wsi/wsi_monitor.h" + namespace dxvk { class DxgiDevice; @@ -169,12 +172,6 @@ namespace dxvk { private: - struct WindowState { - LONG style = 0; - LONG exstyle = 0; - RECT rect = { 0, 0, 0, 0 }; - }; - dxvk::recursive_mutex m_lockWindow; dxvk::mutex m_lockBuffer; @@ -191,7 +188,7 @@ namespace dxvk { Com m_presenter; HMONITOR m_monitor; - WindowState m_windowState; + wsi::DxvkWindowState m_windowState; HRESULT EnterFullscreenMode( IDXGIOutput *pTarget); From 59b943cf125fd86fe233482d60fad8995ed4d246 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 9 Aug 2022 13:25:30 +0100 Subject: [PATCH 0582/1348] [dxgi] Remove unused util_monitor include --- src/dxgi/dxgi_include.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dxgi/dxgi_include.h b/src/dxgi/dxgi_include.h index 14dc138aa..62dbeacfa 100644 --- a/src/dxgi/dxgi_include.h +++ b/src/dxgi/dxgi_include.h @@ -25,7 +25,6 @@ #include "../util/util_flags.h" #include "../util/util_likely.h" #include "../util/util_math.h" -#include "../util/util_monitor.h" #include "../util/util_string.h" #include From bc8e75fdfa9eb0c967eb0cffe0919f7304c05eac Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 14 Aug 2022 17:08:27 +0000 Subject: [PATCH 0583/1348] [dxgi] Make adapter code use new wsi interface --- src/dxgi/dxgi_adapter.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index 7c1de323e..df8c6b541 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -12,6 +12,8 @@ #include "../util/util_luid.h" +#include "../wsi/wsi_monitor.h" + namespace dxvk { DxgiVkAdapter::DxgiVkAdapter(DxgiAdapter* pAdapter) @@ -143,18 +145,12 @@ namespace dxvk { if (ppOutput == nullptr) return E_INVALIDARG; - MonitorEnumInfo info; - info.iMonitorId = Output; - info.oMonitor = nullptr; + HMONITOR monitor = wsi::enumMonitors(Output); - ::EnumDisplayMonitors( - nullptr, nullptr, &MonitorEnumProc, - reinterpret_cast(&info)); - - if (info.oMonitor == nullptr) + if (monitor == nullptr) return DXGI_ERROR_NOT_FOUND; - *ppOutput = ref(new DxgiOutput(m_factory, this, info.oMonitor)); + *ppOutput = ref(new DxgiOutput(m_factory, this, monitor)); return S_OK; } From 654b517057d381903137ededd43c554ed52921a0 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 17 Aug 2022 19:43:12 +0000 Subject: [PATCH 0584/1348] [d3d9] Add helpers for new WSI interface --- src/d3d9/d3d9_monitor.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/d3d9/d3d9_monitor.h b/src/d3d9/d3d9_monitor.h index 0a9d1a89d..b3e7a7b79 100644 --- a/src/d3d9/d3d9_monitor.h +++ b/src/d3d9/d3d9_monitor.h @@ -4,6 +4,9 @@ #include "d3d9_format.h" +#include "../wsi/wsi_window.h" +#include "../wsi/wsi_monitor.h" + namespace dxvk { /** @@ -32,4 +35,27 @@ namespace dxvk { bool IsSupportedBackBufferFormat( D3D9Format BackBufferFormat); + + inline wsi::WsiMode ConvertDisplayMode(const D3DDISPLAYMODEEX& mode) { + wsi::WsiMode wsiMode = { }; + wsiMode.width = mode.Width; + wsiMode.height = mode.Height; + wsiMode.refreshRate = wsi::WsiRational{ mode.RefreshRate, 1 }; + wsiMode.bitsPerPixel = GetMonitorFormatBpp(EnumerateFormat(mode.Format)); + wsiMode.interlaced = mode.ScanLineOrdering == D3DSCANLINEORDERING_INTERLACED; + return wsiMode; + } + + + inline D3DDISPLAYMODEEX ConvertDisplayMode(const wsi::WsiMode& wsiMode) { + D3DDISPLAYMODEEX d3d9Mode = { }; + d3d9Mode.Size = sizeof(D3DDISPLAYMODEEX); + d3d9Mode.Width = wsiMode.width; + d3d9Mode.Height = wsiMode.height; + d3d9Mode.RefreshRate = wsiMode.refreshRate.numerator / wsiMode.refreshRate.denominator; + d3d9Mode.Format = D3DFMT_X8R8G8B8; + d3d9Mode.ScanLineOrdering = wsiMode.interlaced ? D3DSCANLINEORDERING_INTERLACED : D3DSCANLINEORDERING_PROGRESSIVE; + return d3d9Mode; + } + } From dac7e38f4b1de439268ba28a66e11f39ba3a99dd Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 14 Aug 2022 17:36:58 +0000 Subject: [PATCH 0585/1348] [d3d9] Make swapchain use new wsi abstraction --- src/d3d9/d3d9_swapchain.cpp | 98 +++++++++---------------------------- src/d3d9/d3d9_swapchain.h | 12 ++--- 2 files changed, 27 insertions(+), 83 deletions(-) diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 8ffe91765..03ac6e484 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -439,20 +439,14 @@ namespace dxvk { *pRotation = D3DDISPLAYROTATION_IDENTITY; if (pMode != nullptr) { - DEVMODEW devMode = DEVMODEW(); - devMode.dmSize = sizeof(devMode); + wsi::WsiMode devMode = { }; - if (!GetMonitorDisplayMode(GetDefaultMonitor(), ENUM_CURRENT_SETTINGS, &devMode)) { + if (!wsi::getCurrentDisplayMode(wsi::getDefaultMonitor(), &devMode)) { Logger::err("D3D9SwapChainEx::GetDisplayModeEx: Failed to enum display settings"); return D3DERR_INVALIDCALL; } - pMode->Size = sizeof(D3DDISPLAYMODEEX); - pMode->Width = devMode.dmPelsWidth; - pMode->Height = devMode.dmPelsHeight; - pMode->RefreshRate = devMode.dmDisplayFrequency; - pMode->Format = D3DFMT_X8R8G8B8; - pMode->ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE; + *pMode = ConvertDisplayMode(devMode); } return D3D_OK; @@ -487,15 +481,9 @@ namespace dxvk { if (!changeFullscreen) { if (FAILED(ChangeDisplayMode(pPresentParams, pFullscreenDisplayMode))) return D3DERR_INVALIDCALL; - } - // Move the window so that it covers the entire output - RECT rect; - GetMonitorRect(GetDefaultMonitor(), &rect); - - ::SetWindowPos(m_window, HWND_TOPMOST, - rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, - SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); + wsi::updateFullscreenWindow(m_monitor, m_window, true); + } } m_presentParams = *pPresentParams; @@ -634,12 +622,12 @@ namespace dxvk { } if (pPresentParams->Windowed) { - GetWindowClientSize(pPresentParams->hDeviceWindow, + wsi::getWindowSize(pPresentParams->hDeviceWindow, pPresentParams->BackBufferWidth ? nullptr : &pPresentParams->BackBufferWidth, pPresentParams->BackBufferHeight ? nullptr : &pPresentParams->BackBufferHeight); } else { - GetMonitorClientSize(GetDefaultMonitor(), + wsi::getMonitorClientSize(wsi::getDefaultMonitor(), pPresentParams->BackBufferWidth ? nullptr : &pPresentParams->BackBufferWidth, pPresentParams->BackBufferHeight ? nullptr : &pPresentParams->BackBufferHeight); } @@ -1049,28 +1037,13 @@ namespace dxvk { D3D9WindowMessageFilter filter(m_window); - // Change the window flags to remove the decoration etc. - LONG style = ::GetWindowLongW(m_window, GWL_STYLE); - LONG exstyle = ::GetWindowLongW(m_window, GWL_EXSTYLE); + m_monitor = wsi::getDefaultMonitor(); + + if (!wsi::enterFullscreenMode(m_monitor, m_window, &m_windowState, true)) { + Logger::err("D3D9: EnterFullscreenMode: Failed to enter fullscreen mode"); + return D3DERR_INVALIDCALL; + } - m_windowState.style = style; - m_windowState.exstyle = exstyle; - - style &= ~WS_OVERLAPPEDWINDOW; - exstyle &= ~WS_EX_OVERLAPPEDWINDOW; - - ::SetWindowLongW(m_window, GWL_STYLE, style); - ::SetWindowLongW(m_window, GWL_EXSTYLE, exstyle); - - // Move the window so that it covers the entire output - RECT rect; - GetMonitorRect(GetDefaultMonitor(), &rect); - - ::SetWindowPos(m_window, HWND_TOPMOST, - rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, - SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE); - - m_monitor = GetDefaultMonitor(); return D3D_OK; } @@ -1086,24 +1059,11 @@ namespace dxvk { ResetWindowProc(m_window); - // Only restore the window style if the application hasn't - // changed them. This is in line with what native D3D9 does. - LONG curStyle = ::GetWindowLongW(m_window, GWL_STYLE) & ~WS_VISIBLE; - LONG curExstyle = ::GetWindowLongW(m_window, GWL_EXSTYLE) & ~WS_EX_TOPMOST; - - if (curStyle == (m_windowState.style & ~(WS_VISIBLE | WS_OVERLAPPEDWINDOW)) - && curExstyle == (m_windowState.exstyle & ~(WS_EX_TOPMOST | WS_EX_OVERLAPPEDWINDOW))) { - ::SetWindowLongW(m_window, GWL_STYLE, m_windowState.style); - ::SetWindowLongW(m_window, GWL_EXSTYLE, m_windowState.exstyle); + if (!wsi::leaveFullscreenMode(m_window, &m_windowState)) { + Logger::err("D3D9: LeaveFullscreenMode: Failed to exit fullscreen mode"); + return D3DERR_NOTAVAILABLE; } - // Restore window position and apply the style - const RECT rect = m_windowState.rect; - - ::SetWindowPos(m_window, 0, - rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, - SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE); - return D3D_OK; } @@ -1124,27 +1084,15 @@ namespace dxvk { mode.Size = sizeof(D3DDISPLAYMODEEX); } - DEVMODEW devMode = { }; - devMode.dmSize = sizeof(devMode); - devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; - devMode.dmPelsWidth = mode.Width; - devMode.dmPelsHeight = mode.Height; - devMode.dmBitsPerPel = GetMonitorFormatBpp(EnumerateFormat(mode.Format)); + wsi::WsiMode wsiMode = ConvertDisplayMode(mode); - if (mode.RefreshRate != 0) { - devMode.dmFields |= DM_DISPLAYFREQUENCY; - devMode.dmDisplayFrequency = mode.RefreshRate; - } - - HMONITOR monitor = GetDefaultMonitor(); + HMONITOR monitor = wsi::getDefaultMonitor(); - if (!SetMonitorDisplayMode(monitor, &devMode)) + if (!wsi::setWindowMode(monitor, m_window, wsiMode)) return D3DERR_NOTAVAILABLE; - - devMode.dmFields = DM_DISPLAYFREQUENCY; - if (GetMonitorDisplayMode(monitor, ENUM_CURRENT_SETTINGS, &devMode)) - NotifyDisplayRefreshRate(double(devMode.dmDisplayFrequency)); + if (wsi::getCurrentDisplayMode(monitor, &wsiMode)) + NotifyDisplayRefreshRate(double(wsiMode.refreshRate.numerator) / double(wsiMode.refreshRate.denominator)); else NotifyDisplayRefreshRate(0.0); @@ -1156,7 +1104,7 @@ namespace dxvk { if (hMonitor == nullptr) return D3DERR_INVALIDCALL; - if (!RestoreMonitorDisplayMode()) + if (!wsi::restoreDisplayMode()) return D3DERR_NOTAVAILABLE; NotifyDisplayRefreshRate(0.0); @@ -1177,7 +1125,7 @@ namespace dxvk { if (pDestRect == nullptr) { // TODO: Should we hook WM_SIZE message for this? UINT width, height; - GetWindowClientSize(m_window, &width, &height); + wsi::getWindowSize(m_window, &width, &height); dstRect.top = 0; dstRect.left = 0; diff --git a/src/d3d9/d3d9_swapchain.h b/src/d3d9/d3d9_swapchain.h index 150578ca4..9eae6a963 100644 --- a/src/d3d9/d3d9_swapchain.h +++ b/src/d3d9/d3d9_swapchain.h @@ -10,6 +10,9 @@ #include "../util/sync/sync_signal.h" +#include "../wsi/wsi_window.h" +#include "../wsi/wsi_monitor.h" + #include namespace dxvk { @@ -85,13 +88,6 @@ namespace dxvk { Gamma = 1, }; - - struct WindowState { - LONG style = 0; - LONG exstyle = 0; - RECT rect = { 0, 0, 0, 0 }; - }; - D3DPRESENT_PARAMETERS m_presentParams; D3DGAMMARAMP m_ramp; @@ -126,7 +122,7 @@ namespace dxvk { HWND m_window = nullptr; HMONITOR m_monitor = nullptr; - WindowState m_windowState; + wsi::DxvkWindowState m_windowState; double m_displayRefreshRate = 0.0; From 9690b2a9e425636309c12d3f13faff4b1e8a77f1 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 14 Aug 2022 17:39:48 +0000 Subject: [PATCH 0586/1348] [d3d9] Make adapter code use new wsi abstraction --- src/d3d9/d3d9_adapter.cpp | 50 ++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/src/d3d9/d3d9_adapter.cpp b/src/d3d9/d3d9_adapter.cpp index c8e813c8a..d304ff2c9 100644 --- a/src/d3d9/d3d9_adapter.cpp +++ b/src/d3d9/d3d9_adapter.cpp @@ -8,6 +8,9 @@ #include "../util/util_bit.h" #include "../util/util_luid.h" #include "../util/util_ratio.h" +#include "../util/util_string.h" + +#include "../wsi/wsi_monitor.h" #include @@ -59,14 +62,14 @@ namespace dxvk { const auto& props = m_adapter->deviceProperties(); - DISPLAY_DEVICEA device = { }; - device.cb = sizeof(device); - - if (!::EnumDisplayDevicesA(nullptr, m_displayIndex, &device, 0)) { - Logger::err("D3D9Adapter::GetAdapterIdentifier: Failed to query display info"); + WCHAR wideDisplayName[32] = { }; + if (!wsi::getDisplayName(wsi::getDefaultMonitor(), wideDisplayName)) { + Logger::err("D3D9Adapter::GetAdapterIdentifier: Failed to query monitor info"); return D3DERR_INVALIDCALL; } + std::string displayName = str::fromws(wideDisplayName); + GUID guid = bit::cast(m_adapter->devicePropertiesExt().vk11.deviceUUID); uint32_t vendorId = options.customVendorId == -1 ? props.vendorID : uint32_t(options.customVendorId); @@ -75,7 +78,7 @@ namespace dxvk { const char* driver = GetDriverDLL(DxvkGpuVendor(vendorId)); copyToStringArray(pIdentifier->Description, desc); - copyToStringArray(pIdentifier->DeviceName, device.DeviceName); // The GDI device name. Not the actual device name. + copyToStringArray(pIdentifier->DeviceName, displayName.c_str()); // The GDI device name. Not the actual device name. copyToStringArray(pIdentifier->Driver, driver); // This is the driver's dll. pIdentifier->DeviceIdentifier = guid; @@ -621,7 +624,7 @@ namespace dxvk { HMONITOR D3D9Adapter::GetMonitor() { - return GetDefaultMonitor(); + return wsi::getDefaultMonitor(); } @@ -680,20 +683,14 @@ namespace dxvk { if (pRotation != nullptr) *pRotation = D3DDISPLAYROTATION_IDENTITY; - DEVMODEW devMode = DEVMODEW(); - devMode.dmSize = sizeof(devMode); + wsi::WsiMode mode = { }; - if (!GetMonitorDisplayMode(GetDefaultMonitor(), ENUM_CURRENT_SETTINGS, &devMode)) { + if (!wsi::getCurrentDisplayMode(wsi::getDefaultMonitor(), &mode)) { Logger::err("D3D9Adapter::GetAdapterDisplayModeEx: Failed to enum display settings"); return D3DERR_INVALIDCALL; } - pMode->Size = sizeof(D3DDISPLAYMODEEX); - pMode->Width = devMode.dmPelsWidth; - pMode->Height = devMode.dmPelsHeight; - pMode->RefreshRate = devMode.dmDisplayFrequency; - pMode->Format = D3DFMT_X8R8G8B8; - pMode->ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE; + *pMode = ConvertDisplayMode(mode); return D3D_OK; } @@ -768,32 +765,27 @@ namespace dxvk { // Walk over all modes that the display supports and // return those that match the requested format etc. - DEVMODEW devMode = { }; - devMode.dmSize = sizeof(DEVMODEW); + wsi::WsiMode devMode = { }; uint32_t modeIndex = 0; const auto forcedRatio = Ratio(options.forceAspectRatio); - while (GetMonitorDisplayMode(GetDefaultMonitor(), modeIndex++, &devMode)) { + while (wsi::getDisplayMode(wsi::getDefaultMonitor(), modeIndex++, &devMode)) { // Skip interlaced modes altogether - if (devMode.dmDisplayFlags & DM_INTERLACED) + if (devMode.interlaced) continue; // Skip modes with incompatible formats - if (devMode.dmBitsPerPel != GetMonitorFormatBpp(Format)) + if (devMode.bitsPerPixel != GetMonitorFormatBpp(Format)) continue; - if (!forcedRatio.undefined() && Ratio(devMode.dmPelsWidth, devMode.dmPelsHeight) != forcedRatio) + if (!forcedRatio.undefined() && Ratio(devMode.width, devMode.height) != forcedRatio) continue; - D3DDISPLAYMODEEX mode; - mode.Size = sizeof(D3DDISPLAYMODEEX); - mode.Width = devMode.dmPelsWidth; - mode.Height = devMode.dmPelsHeight; - mode.RefreshRate = devMode.dmDisplayFrequency; - mode.Format = static_cast(Format); - mode.ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE; + D3DDISPLAYMODEEX mode = ConvertDisplayMode(devMode); + // Fix up the D3DFORMAT to match what we are enumerating + mode.Format = static_cast(Format); m_modes.push_back(mode); } From 69eba93764f472f26808b07847b7ea45334dc3dd Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 14 Aug 2022 18:50:34 +0000 Subject: [PATCH 0587/1348] [d3d9] Make window proc code use new wsi interface --- src/d3d9/d3d9_window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_window.cpp b/src/d3d9/d3d9_window.cpp index a7fa4a7de..d52607976 100644 --- a/src/d3d9/d3d9_window.cpp +++ b/src/d3d9/d3d9_window.cpp @@ -66,7 +66,7 @@ namespace dxvk D3DPRESENT_PARAMETERS params; RECT rect; - GetMonitorRect(GetDefaultMonitor(), &rect); + wsi::getDesktopCoordinates(wsi::getDefaultMonitor(), &rect); windowData.swapchain->GetPresentParameters(¶ms); SetWindowPos(window, nullptr, rect.left, rect.top, params.BackBufferWidth, params.BackBufferHeight, SWP_NOACTIVATE | SWP_NOZORDER); From f3992658a4f33343fb755556556d3fad3e3a9137 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 14 Aug 2022 18:45:24 +0000 Subject: [PATCH 0588/1348] [d3d9] Remove unused util_monitor include --- src/d3d9/d3d9_include.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/d3d9/d3d9_include.h b/src/d3d9/d3d9_include.h index 8762265ab..2b933aecd 100644 --- a/src/d3d9/d3d9_include.h +++ b/src/d3d9/d3d9_include.h @@ -36,7 +36,6 @@ #include "../util/util_flags.h" #include "../util/util_likely.h" #include "../util/util_math.h" -#include "../util/util_monitor.h" #include "../util/util_string.h" // Missed definitions in Wine/MinGW. From af802fbff8d4266af027b7a7aadeffaccc2b4618 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 14 Aug 2022 18:45:39 +0000 Subject: [PATCH 0589/1348] [util] Delete util_monitor No longer used, replaced by new wsi interface --- src/util/meson.build | 1 - src/util/util_monitor.cpp | 162 -------------------------------------- src/util/util_monitor.h | 78 ------------------ 3 files changed, 241 deletions(-) delete mode 100644 src/util/util_monitor.cpp delete mode 100644 src/util/util_monitor.h diff --git a/src/util/meson.build b/src/util/meson.build index 34da01eeb..50044a00b 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -5,7 +5,6 @@ util_src = files([ 'util_gdi.cpp', 'util_luid.cpp', 'util_matrix.cpp', - 'util_monitor.cpp', 'util_shared_res.cpp', 'thread.cpp', diff --git a/src/util/util_monitor.cpp b/src/util/util_monitor.cpp deleted file mode 100644 index 69f60d165..000000000 --- a/src/util/util_monitor.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include "util_monitor.h" -#include "util_string.h" - -#include "./log/log.h" - -namespace dxvk { - - HMONITOR GetDefaultMonitor() { - return ::MonitorFromPoint({ 0, 0 }, MONITOR_DEFAULTTOPRIMARY); - } - - - BOOL SetMonitorDisplayMode( - HMONITOR hMonitor, - DEVMODEW* pMode) { - ::MONITORINFOEXW monInfo; - monInfo.cbSize = sizeof(monInfo); - - if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { - Logger::err("Failed to query monitor info"); - return E_FAIL; - } - - Logger::info(str::format("Setting display mode: ", - pMode->dmPelsWidth, "x", pMode->dmPelsHeight, "@", - pMode->dmDisplayFrequency)); - - DEVMODEW curMode = { }; - curMode.dmSize = sizeof(curMode); - - if (GetMonitorDisplayMode(hMonitor, ENUM_CURRENT_SETTINGS, &curMode)) { - bool eq = curMode.dmPelsWidth == pMode->dmPelsWidth - && curMode.dmPelsHeight == pMode->dmPelsHeight - && curMode.dmBitsPerPel == pMode->dmBitsPerPel; - - if (pMode->dmFields & DM_DISPLAYFREQUENCY) - eq &= curMode.dmDisplayFrequency == pMode->dmDisplayFrequency; - - if (eq) - return true; - } - - LONG status = ::ChangeDisplaySettingsExW(monInfo.szDevice, - pMode, nullptr, CDS_FULLSCREEN, nullptr); - - if (status != DISP_CHANGE_SUCCESSFUL) { - pMode->dmFields &= ~DM_DISPLAYFREQUENCY; - - status = ::ChangeDisplaySettingsExW(monInfo.szDevice, - pMode, nullptr, CDS_FULLSCREEN, nullptr); - } - - return status == DISP_CHANGE_SUCCESSFUL; - } - - - BOOL GetMonitorDisplayMode( - HMONITOR hMonitor, - DWORD modeNum, - DEVMODEW* pMode) { - ::MONITORINFOEXW monInfo; - monInfo.cbSize = sizeof(monInfo); - - if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { - Logger::err("Failed to query monitor info"); - return false; - } - - return ::EnumDisplaySettingsW(monInfo.szDevice, modeNum, pMode); - } - - - BOOL CALLBACK RestoreMonitorDisplayModeCallback( - HMONITOR hMonitor, - HDC hDC, - LPRECT pRect, - LPARAM pUserdata) { - auto success = reinterpret_cast(pUserdata); - - DEVMODEW devMode = { }; - devMode.dmSize = sizeof(devMode); - - if (!GetMonitorDisplayMode(hMonitor, ENUM_REGISTRY_SETTINGS, &devMode)) { - *success = false; - return false; - } - - Logger::info(str::format("Restoring display mode: ", - devMode.dmPelsWidth, "x", devMode.dmPelsHeight, "@", - devMode.dmDisplayFrequency)); - - if (!SetMonitorDisplayMode(hMonitor, &devMode)) { - *success = false; - return false; - } - - return true; - } - - - BOOL RestoreMonitorDisplayMode() { - bool success = true; - bool result = ::EnumDisplayMonitors(nullptr, nullptr, - &RestoreMonitorDisplayModeCallback, - reinterpret_cast(&success)); - - return result && success; - } - - - void GetWindowClientSize( - HWND hWnd, - UINT* pWidth, - UINT* pHeight) { - RECT rect = { }; - ::GetClientRect(hWnd, &rect); - - if (pWidth) - *pWidth = rect.right - rect.left; - - if (pHeight) - *pHeight = rect.bottom - rect.top; - } - - - void GetMonitorClientSize( - HMONITOR hMonitor, - UINT* pWidth, - UINT* pHeight) { - ::MONITORINFOEXW monInfo; - monInfo.cbSize = sizeof(monInfo); - - if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { - Logger::err("Failed to query monitor info"); - return; - } - - auto rect = monInfo.rcMonitor; - - if (pWidth) - *pWidth = rect.right - rect.left; - - if (pHeight) - *pHeight = rect.bottom - rect.top; - } - - - void GetMonitorRect( - HMONITOR hMonitor, - RECT* pRect) { - ::MONITORINFOEXW monInfo; - monInfo.cbSize = sizeof(monInfo); - - if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { - Logger::err("Failed to query monitor info"); - return; - } - - *pRect = monInfo.rcMonitor; - } - -} diff --git a/src/util/util_monitor.h b/src/util/util_monitor.h deleted file mode 100644 index 41c6ebee8..000000000 --- a/src/util/util_monitor.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include "./com/com_include.h" - -namespace dxvk { - - /** - * \brief Retrieves primary monitor - * \returns The primary monitor - */ - HMONITOR GetDefaultMonitor(); - - /** - * \brief Sets monitor display mode - * - * Note that \c pMode may be altered by this function. - * \param [in] hMonitor The monitor to change - * \param [in] pMode The desired display mode - * \returns \c true on success - */ - BOOL SetMonitorDisplayMode( - HMONITOR hMonitor, - DEVMODEW* pMode); - - /** - * \brief Enumerates monitor display modes - * - * \param [in] hMonitor The monitor to query - * \param [in] modeNum Mode number or enum - * \param [in] pMode The display mode - * \returns \c true on success - */ - BOOL GetMonitorDisplayMode( - HMONITOR hMonitor, - DWORD modeNum, - DEVMODEW* pMode); - - /** - * \brief Change display modes to registry settings - * \returns \c true on success - */ - BOOL RestoreMonitorDisplayMode(); - - /** - * \brief Queries window client size - * - * \param [in] hWnd Window to query - * \param [out] pWidth Client width - * \param [out] pHeight Client height - */ - void GetWindowClientSize( - HWND hWnd, - UINT* pWidth, - UINT* pHeight); - - /** - * \brief Queries monitor size - * - * \param [in] hMonitor Monitor to query - * \param [out] pWidth Client width - * \param [out] pHeight Client height - */ - void GetMonitorClientSize( - HMONITOR hMonitor, - UINT* pWidth, - UINT* pHeight); - - /** - * \brief Queries monitor rect - * - * \param [in] hMonitor Monitor to query - * \param [out] pRect The rect to return - */ - void GetMonitorRect( - HMONITOR hMonitor, - RECT* pRect); - -} From 16ff9b48cdc05fb82f526fdc66fc87e1528a8d71 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 17 Aug 2022 19:37:19 +0000 Subject: [PATCH 0590/1348] [dxgi] Enumerate interlaced modes if requested --- src/dxgi/dxgi_output.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index 81a4671ea..8fb52e82c 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -301,8 +301,8 @@ namespace dxvk { std::vector modeList; while (wsi::getDisplayMode(m_monitor, srcModeId++, &devMode)) { - // Skip interlaced modes altogether - if (devMode.interlaced) + // Only enumerate interlaced modes if requested. + if (devMode.interlaced && !(Flags & DXGI_ENUM_MODES_INTERLACED)) continue; // Skip modes with incompatible formats From f80347d9a90f3eb33900c1d01c2237ebbd8c1232 Mon Sep 17 00:00:00 2001 From: Kassin Dornelles Date: Sat, 20 Aug 2022 17:49:35 -0300 Subject: [PATCH 0591/1348] [util] Remove RE:REV2 and RE5 workarounds There's no real impact, it doesn't fix stuttering (for non-GPL drivers) and since GPL got merged this is not needed anymore --- src/util/config/config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 1636c4017..ea4629b87 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -504,8 +504,8 @@ namespace dxvk { { R"(\\BBCF\.exe$)", {{ { "d3d9.floatEmulation", "Strict" }, }} }, - /* Resident Evil games */ - { R"(\\(rerev|rerev2|re0hd|bhd|re5dx9)\.exe$)", {{ + /* Resident Evil games using MT Framework */ + { R"(\\(rerev|re0hd|bhd)\.exe$)", {{ { "d3d9.allowDirectBufferMapping", "False" }, }} }, /* Limbo */ From 1c35fbb33c424f27253f7e5412358da40fad51b5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 01:50:41 +0200 Subject: [PATCH 0592/1348] [util] Fix strlcpy compiler warning --- src/util/util_string.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/util/util_string.h b/src/util/util_string.h index 114bf63ef..f4810728f 100644 --- a/src/util/util_string.h +++ b/src/util/util_string.h @@ -205,9 +205,10 @@ namespace dxvk::str { } inline void strlcpy(char* dst, const char* src, size_t count) { - std::strncpy(dst, src, count); - if (count > 0) + if (count > 0) { + std::strncpy(dst, src, count - 1); dst[count - 1] = '\0'; + } } } From 92698be09a4e34e6b43edaed180337a7ff2c53a1 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 20 Aug 2022 23:22:17 +0000 Subject: [PATCH 0593/1348] [native] Add substitute Windows headers Adds substutite Windows headers for use when building DXVK natively for Linux. The main one being windows_base.h which has all of the definitions. It supports stuff like __uuidof using some template nonsense too. --- include/native/windows/oaidl.h | 3 + include/native/windows/objbase.h | 3 + include/native/windows/ocidl.h | 3 + include/native/windows/ole2.h | 3 + include/native/windows/poppack.h | 8 + include/native/windows/pshpack4.h | 8 + include/native/windows/rpc.h | 3 + include/native/windows/rpcndr.h | 3 + include/native/windows/unknwn.h | 48 ++++ include/native/windows/windows.h | 4 + include/native/windows/windows_base.h | 314 ++++++++++++++++++++++++++ 11 files changed, 400 insertions(+) create mode 100644 include/native/windows/oaidl.h create mode 100644 include/native/windows/objbase.h create mode 100644 include/native/windows/ocidl.h create mode 100644 include/native/windows/ole2.h create mode 100644 include/native/windows/poppack.h create mode 100644 include/native/windows/pshpack4.h create mode 100644 include/native/windows/rpc.h create mode 100644 include/native/windows/rpcndr.h create mode 100644 include/native/windows/unknwn.h create mode 100644 include/native/windows/windows.h create mode 100644 include/native/windows/windows_base.h diff --git a/include/native/windows/oaidl.h b/include/native/windows/oaidl.h new file mode 100644 index 000000000..549fe36ff --- /dev/null +++ b/include/native/windows/oaidl.h @@ -0,0 +1,3 @@ +#pragma once + +// Don't care. \ No newline at end of file diff --git a/include/native/windows/objbase.h b/include/native/windows/objbase.h new file mode 100644 index 000000000..549fe36ff --- /dev/null +++ b/include/native/windows/objbase.h @@ -0,0 +1,3 @@ +#pragma once + +// Don't care. \ No newline at end of file diff --git a/include/native/windows/ocidl.h b/include/native/windows/ocidl.h new file mode 100644 index 000000000..549fe36ff --- /dev/null +++ b/include/native/windows/ocidl.h @@ -0,0 +1,3 @@ +#pragma once + +// Don't care. \ No newline at end of file diff --git a/include/native/windows/ole2.h b/include/native/windows/ole2.h new file mode 100644 index 000000000..549fe36ff --- /dev/null +++ b/include/native/windows/ole2.h @@ -0,0 +1,3 @@ +#pragma once + +// Don't care. \ No newline at end of file diff --git a/include/native/windows/poppack.h b/include/native/windows/poppack.h new file mode 100644 index 000000000..163af228d --- /dev/null +++ b/include/native/windows/poppack.h @@ -0,0 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#if !(defined(lint) || defined(RC_INVOKED)) +#pragma pack(pop) +#endif diff --git a/include/native/windows/pshpack4.h b/include/native/windows/pshpack4.h new file mode 100644 index 000000000..59fdbbc5f --- /dev/null +++ b/include/native/windows/pshpack4.h @@ -0,0 +1,8 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#if !(defined(lint) || defined(RC_INVOKED)) +#pragma pack(push,4) +#endif diff --git a/include/native/windows/rpc.h b/include/native/windows/rpc.h new file mode 100644 index 000000000..549fe36ff --- /dev/null +++ b/include/native/windows/rpc.h @@ -0,0 +1,3 @@ +#pragma once + +// Don't care. \ No newline at end of file diff --git a/include/native/windows/rpcndr.h b/include/native/windows/rpcndr.h new file mode 100644 index 000000000..549fe36ff --- /dev/null +++ b/include/native/windows/rpcndr.h @@ -0,0 +1,3 @@ +#pragma once + +// Don't care. \ No newline at end of file diff --git a/include/native/windows/unknwn.h b/include/native/windows/unknwn.h new file mode 100644 index 000000000..757226787 --- /dev/null +++ b/include/native/windows/unknwn.h @@ -0,0 +1,48 @@ +#pragma once + +#include "windows_base.h" + +typedef interface IUnknown IUnknown; + +DEFINE_GUID(IID_IUnknown, 0x00000000,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46) + +#ifdef __cplusplus +struct IUnknown { + +public: + + virtual HRESULT QueryInterface(REFIID riid, void** ppvObject) = 0; + + virtual ULONG AddRef() = 0; + virtual ULONG Release() = 0; + +}; +#else +typedef struct IUnknownVtbl +{ +BEGIN_INTERFACE + + HRESULT (STDMETHODCALLTYPE *QueryInterface)( + IUnknown *This, + REFIID riid, + void **ppvObject + ); + ULONG (STDMETHODCALLTYPE *AddRef)(IUnknown *This); + ULONG (STDMETHODCALLTYPE *Release)(IUnknown *This); + +END_INTERFACE +} IUnknownVtbl; + +interface IUnknown +{ + CONST_VTBL struct IUnknownVtbl *lpVtbl; +}; + +#define IUnknown_AddRef(This) ((This)->lpVtbl->AddRef(This)) +#define IUnknown_Release(This) ((This)->lpVtbl->Release(This)) + +#endif // __cplusplus + +DECLARE_UUIDOF_HELPER(IUnknown, 0x00000000,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46) + +#define IID_PPV_ARGS(ppType) __uuidof(decltype(**(ppType))), [](auto** pp) { (void)static_cast(*pp); return reinterpret_cast(pp); }(ppType) diff --git a/include/native/windows/windows.h b/include/native/windows/windows.h new file mode 100644 index 000000000..5ffa7b218 --- /dev/null +++ b/include/native/windows/windows.h @@ -0,0 +1,4 @@ +#pragma once + +#include "windows_base.h" +#include "unknwn.h" \ No newline at end of file diff --git a/include/native/windows/windows_base.h b/include/native/windows/windows_base.h new file mode 100644 index 000000000..747ef303f --- /dev/null +++ b/include/native/windows/windows_base.h @@ -0,0 +1,314 @@ +#pragma once + +#ifdef __cplusplus +#include +#include +#else +#include +#include +#include +#endif // __cplusplus + +// GCC complains about the COM interfaces +// not having virtual destructors + +// and class conversion for C...DESC helper types +#if defined(__GNUC__) && defined(__cplusplus) +#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" +#pragma GCC diagnostic ignored "-Wclass-conversion" +#endif // __GNUC__ && __cplusplus + +typedef int32_t INT; +typedef uint32_t UINT; + +typedef int32_t LONG; +typedef uint32_t ULONG; + +typedef int32_t HRESULT; + +typedef wchar_t WCHAR; + +typedef INT BOOL; +typedef BOOL WINBOOL; + +typedef uint16_t UINT16; +typedef uint32_t UINT32; +typedef uint64_t UINT64; +typedef void VOID; +typedef void* LPVOID; +typedef const void* LPCVOID; + +typedef size_t SIZE_T; + +typedef uint8_t UINT8; +typedef uint8_t BYTE; + +typedef int16_t SHORT; +typedef uint16_t USHORT; + +typedef int64_t LONGLONG; +typedef uint64_t ULONGLONG; + +typedef float FLOAT; + +#ifndef GUID_DEFINED +#define GUID_DEFINED +typedef struct GUID { + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +} GUID; +#endif // GUID_DEFINED + +typedef GUID UUID; +typedef GUID IID; +#ifdef __cplusplus +#define REFIID const IID& +#define REFGUID const GUID& +#else +#define REFIID const IID* +#define REFGUID const GUID* +#endif // __cplusplus + +#ifdef __cplusplus + +template +constexpr GUID __uuidof_helper(); + +#define __uuidof(T) __uuidof_helper() +#define __uuidof_var(T) __uuidof_helper() + +inline bool operator==(const GUID& a, const GUID& b) { return std::memcmp(&a, &b, sizeof(GUID)) == 0; } +inline bool operator!=(const GUID& a, const GUID& b) { return std::memcmp(&a, &b, sizeof(GUID)) != 0; } + +#endif // __cplusplus + +typedef uint32_t DWORD; +typedef uint16_t WORD; + +typedef void* HANDLE; +typedef HANDLE HMONITOR; +typedef HANDLE HDC; +typedef HANDLE HMODULE; +typedef HANDLE HINSTANCE; +typedef HANDLE HWND; +typedef HANDLE HKEY; +typedef DWORD COLORREF; + +typedef char* LPSTR; +typedef const char* LPCSTR; +typedef const wchar_t* LPCWSTR; + +typedef struct LUID { + DWORD LowPart; + LONG HighPart; +} LUID; + +typedef struct POINT { + LONG x; + LONG y; +} POINT; + +typedef POINT* LPPOINT; + +typedef struct RECT { + LONG left; + LONG top; + LONG right; + LONG bottom; +} RECT; + +typedef struct SIZE { + LONG cx; + LONG cy; +} SIZE; + +typedef union { + struct { + DWORD LowPart; + LONG HighPart; + }; + + struct { + DWORD LowPart; + LONG HighPart; + } u; + + LONGLONG QuadPart; +} LARGE_INTEGER; + +typedef struct MEMORYSTATUS { + DWORD dwLength; + SIZE_T dwTotalPhys; +} MEMORYSTATUS; + +typedef struct SECURITY_ATTRIBUTES { + DWORD nLength; + void* lpSecurityDescriptor; + BOOL bInheritHandle; +} SECURITY_ATTRIBUTES; + +typedef struct PALETTEENTRY { + BYTE peRed; + BYTE peGreen; + BYTE peBlue; + BYTE peFlags; +} PALETTEENTRY; + +typedef struct RGNDATAHEADER { + DWORD dwSize; + DWORD iType; + DWORD nCount; + DWORD nRgnSize; + RECT rcBound; +} RGNDATAHEADER; + +typedef struct RGNDATA { + RGNDATAHEADER rdh; + char Buffer[1]; +} RGNDATA; + +// Ignore these. +#define STDMETHODCALLTYPE +#define __stdcall + +#define CONST const +#define CONST_VTBL const + +#define TRUE 1 +#define FALSE 0 + +#define interface struct +#define MIDL_INTERFACE(x) struct + +#ifdef __cplusplus + +#define DEFINE_GUID(iid, a, b, c, d, e, f, g, h, i, j, k) \ + constexpr GUID iid = {a,b,c,{d,e,f,g,h,i,j,k}}; + +#define DECLARE_UUIDOF_HELPER(type, a, b, c, d, e, f, g, h, i, j, k) \ + extern "C++" { template <> constexpr GUID __uuidof_helper() { return GUID{a,b,c,{d,e,f,g,h,i,j,k}}; } } \ + extern "C++" { template <> constexpr GUID __uuidof_helper() { return __uuidof_helper(); } } \ + extern "C++" { template <> constexpr GUID __uuidof_helper() { return __uuidof_helper(); } } \ + extern "C++" { template <> constexpr GUID __uuidof_helper() { return __uuidof_helper(); } } \ + extern "C++" { template <> constexpr GUID __uuidof_helper() { return __uuidof_helper(); } } + +#else +#define DEFINE_GUID(iid, a, b, c, d, e, f, g, h, i, j, k) \ + static const GUID iid = {a,b,c,{d,e,f,g,h,i,j,k}}; +#define DECLARE_UUIDOF_HELPER(type, a, b, c, d, e, f, g, h, i, j, k) +#endif // __cplusplus + +#define __CRT_UUID_DECL(type, a, b, c, d, e, f, g, h, i, j, k) DECLARE_UUIDOF_HELPER(type, a, b, c, d, e, f, g, h, i, j, k) + +#define S_OK 0 +#define S_FALSE 1 + +#define E_INVALIDARG ((HRESULT)0x80070057) +#define E_FAIL ((HRESULT)0x80004005) +#define E_NOINTERFACE ((HRESULT)0x80004002) +#define E_NOTIMPL ((HRESULT)0x80004001) +#define E_OUTOFMEMORY ((HRESULT)0x8007000E) +#define E_POINTER ((HRESULT)0x80004003) + +#define DXGI_STATUS_OCCLUDED ((HRESULT)0x087a0001) +#define DXGI_STATUS_CLIPPED ((HRESULT)0x087a0002) +#define DXGI_STATUS_NO_REDIRECTION ((HRESULT)0x087a0004) +#define DXGI_STATUS_NO_DESKTOP_ACCESS ((HRESULT)0x087a0005) +#define DXGI_STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE ((HRESULT)0x087a0006) +#define DXGI_STATUS_MODE_CHANGED ((HRESULT)0x087a0007) +#define DXGI_STATUS_MODE_CHANGE_IN_PROGRESS ((HRESULT)0x087a0008) +#define DXGI_STATUS_UNOCCLUDED ((HRESULT)0x087a0009) +#define DXGI_STATUS_DDA_WAS_STILL_DRAWING ((HRESULT)0x087a000a) +#define DXGI_STATUS_PRESENT_REQUIRED ((HRESULT)0x087a002f) + +#define DXGI_ERROR_INVALID_CALL ((HRESULT)0x887A0001) +#define DXGI_ERROR_NOT_FOUND ((HRESULT)0x887A0002) +#define DXGI_ERROR_MORE_DATA ((HRESULT)0x887A0003) +#define DXGI_ERROR_UNSUPPORTED ((HRESULT)0x887A0004) +#define DXGI_ERROR_DEVICE_REMOVED ((HRESULT)0x887A0005) +#define DXGI_ERROR_DEVICE_HUNG ((HRESULT)0x887A0006) +#define DXGI_ERROR_DEVICE_RESET ((HRESULT)0x887A0007) +#define DXGI_ERROR_WAS_STILL_DRAWING ((HRESULT)0x887A000A) +#define DXGI_ERROR_FRAME_STATISTICS_DISJOINT ((HRESULT)0x887A000B) +#define DXGI_ERROR_GRAPHICS_VIDPN_SOURCE_IN_USE ((HRESULT)0x887A000C) +#define DXGI_ERROR_DRIVER_INTERNAL_ERROR ((HRESULT)0x887A0020) +#define DXGI_ERROR_NONEXCLUSIVE ((HRESULT)0x887A0021) +#define DXGI_ERROR_NOT_CURRENTLY_AVAILABLE ((HRESULT)0x887A0022) +#define DXGI_ERROR_REMOTE_CLIENT_DISCONNECTED ((HRESULT)0x887A0023) +#define DXGI_ERROR_REMOTE_OUTOFMEMORY ((HRESULT)0x887A0024) +#define DXGI_ERROR_ACCESS_LOST ((HRESULT)0x887A0026) +#define DXGI_ERROR_WAIT_TIMEOUT ((HRESULT)0x887A0027) +#define DXGI_ERROR_SESSION_DISCONNECTED ((HRESULT)0x887A0028) +#define DXGI_ERROR_RESTRICT_TO_OUTPUT_STALE ((HRESULT)0x887A0029) +#define DXGI_ERROR_CANNOT_PROTECT_CONTENT ((HRESULT)0x887A002A) +#define DXGI_ERROR_ACCESS_DENIED ((HRESULT)0x887A002B) +#define DXGI_ERROR_NAME_ALREADY_EXISTS ((HRESULT)0x887A002C) +#define DXGI_ERROR_SDK_COMPONENT_MISSING ((HRESULT)0x887A002D) + +#define WINAPI +#define WINUSERAPI + +#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) + +#define MAKE_HRESULT(sev,fac,code) \ + ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) + +#ifdef __cplusplus +#define STDMETHOD(name) virtual HRESULT name +#define STDMETHOD_(type, name) virtual type name +#else +#define STDMETHOD(name) HRESULT (STDMETHODCALLTYPE *name) +#define STDMETHOD_(type, name) type (STDMETHODCALLTYPE *name) +#endif // __cplusplus + +#define THIS_ +#define THIS + +#define __C89_NAMELESSUNIONNAME +#define __C89_NAMELESSUNIONNAME1 +#define __C89_NAMELESSUNIONNAME2 +#define __C89_NAMELESSUNIONNAME3 +#define __C89_NAMELESSUNIONNAME4 +#define __C89_NAMELESSUNIONNAME5 +#define __C89_NAMELESSUNIONNAME6 +#define __C89_NAMELESSUNIONNAME7 +#define __C89_NAMELESSUNIONNAME8 +#define __C89_NAMELESS +#define DUMMYUNIONNAME +#define DUMMYSTRUCTNAME + +#ifdef __cplusplus +#define DECLARE_INTERFACE(x) struct x +#define DECLARE_INTERFACE_(x, y) struct x : public y +#else +#define DECLARE_INTERFACE(x) \ + typedef interface x { \ + const struct x##Vtbl *lpVtbl; \ + } x; \ + typedef const struct x##Vtbl x##Vtbl; \ + const struct x##Vtbl +#define DECLARE_INTERFACE_(x, y) DECLARE_INTERFACE(x) +#endif // __cplusplus + +#define BEGIN_INTERFACE +#define END_INTERFACE + +#ifdef __cplusplus +#define PURE = 0 +#else +#define PURE +#endif // __cplusplus + +#define DECLSPEC_SELECTANY + +#define __MSABI_LONG(x) x + +#define ENUM_CURRENT_SETTINGS ((DWORD)-1) +#define ENUM_REGISTRY_SETTINGS ((DWORD)-2) + +#define INVALID_HANDLE_VALUE ((HANDLE)-1) + +#define FAILED(hr) ((HRESULT)(hr) < 0) +#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) From e969f49cee2ee4ccf815c5ef8225947f6324b28c Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 17:28:03 +0000 Subject: [PATCH 0594/1348] [native] Add DirectX headers submodule Adds DirectX headers for use when building DXVK natively for Linux. These use the substitute Windows headers I made. These are a minimal set of DirectX specific headers that are compatible with the substitute Windows headers I made. For any license concerns please see the README in the submodule. --- .gitmodules | 3 +++ include/native/directx | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 include/native/directx diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..621f8f23a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "include/native/directx"] + path = include/native/directx + url = https://github.com/Joshua-Ashton/mingw-directx-headers diff --git a/include/native/directx b/include/native/directx new file mode 160000 index 000000000..9ae01457f --- /dev/null +++ b/include/native/directx @@ -0,0 +1 @@ +Subproject commit 9ae01457f3f52b90fcdb472fc8ad86a0c89c15e5 From 91a5123ad0b254a863885fbee35b85151462d3ee Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 20 Aug 2022 23:11:36 +0000 Subject: [PATCH 0595/1348] [native] Add SDL2 native headers Not included by DXVK at all, but used by external applications. --- include/native/wsi/native_sdl2.h | 25 +++++++++++++++++++++++++ include/native/wsi/native_wsi.h | 9 +++++++++ 2 files changed, 34 insertions(+) create mode 100644 include/native/wsi/native_sdl2.h create mode 100644 include/native/wsi/native_wsi.h diff --git a/include/native/wsi/native_sdl2.h b/include/native/wsi/native_sdl2.h new file mode 100644 index 000000000..b197d9527 --- /dev/null +++ b/include/native/wsi/native_sdl2.h @@ -0,0 +1,25 @@ +#include + +#include + +namespace dxvk::wsi { + + inline SDL_Window* fromHwnd(HWND hWindow) { + return reinterpret_cast(hWindow); + } + + inline HWND toHwnd(SDL_Window* pWindow) { + return reinterpret_cast(pWindow); + } + + // Offset so null HMONITORs go to -1 + inline int32_t fromHmonitor(HMONITOR hMonitor) { + return static_cast(reinterpret_cast(hMonitor)) - 1; + } + + // Offset so -1 display id goes to 0 == NULL + inline HMONITOR toHmonitor(int32_t displayId) { + return reinterpret_cast(static_cast(displayId + 1)); + } + +} \ No newline at end of file diff --git a/include/native/wsi/native_wsi.h b/include/native/wsi/native_wsi.h new file mode 100644 index 000000000..00a299060 --- /dev/null +++ b/include/native/wsi/native_wsi.h @@ -0,0 +1,9 @@ +#pragma once + +#ifdef DXVK_WSI_WIN32 +#error You shouldnt be using this code path. +#elif DXVK_WSI_SDL2 +#include "wsi/native_sdl2.h" +#else +#error Unknown wsi! +#endif \ No newline at end of file From 0dc3200951f57b596f56beec7de69de46174e1de Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 20 Aug 2022 23:12:34 +0000 Subject: [PATCH 0596/1348] [vulkan] Re-enable VK_USE_PLATFORM_WIN32_KHR everywhere My initial idea was to if-def out the other extensions, but that's messy, so we just provide the needed types in the native headers now. --- src/vulkan/vulkan_loader.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 841a0f12a..6f469c650 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -3,9 +3,7 @@ #include "../util/rc/util_rc.h" #include "../util/rc/util_rc_ptr.h" -#ifdef _WIN32 #define VK_USE_PLATFORM_WIN32_KHR 1 -#endif #include #define VULKAN_FN(name) \ From 5c2a748d960e3fbbb516aa1f22892f3dde670651 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 20 Aug 2022 23:43:18 +0000 Subject: [PATCH 0597/1348] [util] Rename always_inline to force_inline This conflicts with other libraries using the always_inline attribute in GCC as it defines it with the same name. --- src/util/rc/util_rc.h | 4 ++-- src/util/rc/util_rc_ptr.h | 4 ++-- src/util/util_likely.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/util/rc/util_rc.h b/src/util/rc/util_rc.h index f8e8c2304..b92cf00b4 100644 --- a/src/util/rc/util_rc.h +++ b/src/util/rc/util_rc.h @@ -17,7 +17,7 @@ namespace dxvk { * \brief Increments reference count * \returns New reference count */ - always_inline uint32_t incRef() { + force_inline uint32_t incRef() { return ++m_refCount; } @@ -25,7 +25,7 @@ namespace dxvk { * \brief Decrements reference count * \returns New reference count */ - always_inline uint32_t decRef() { + force_inline uint32_t decRef() { return --m_refCount; } diff --git a/src/util/rc/util_rc_ptr.h b/src/util/rc/util_rc_ptr.h index 55540f603..bc4b4bdd9 100644 --- a/src/util/rc/util_rc_ptr.h +++ b/src/util/rc/util_rc_ptr.h @@ -102,12 +102,12 @@ namespace dxvk { T* m_object = nullptr; - always_inline void incRef() const { + force_inline void incRef() const { if (m_object != nullptr) m_object->incRef(); } - always_inline void decRef() const { + force_inline void decRef() const { if (m_object != nullptr) { if (m_object->decRef() == 0) delete m_object; diff --git a/src/util/util_likely.h b/src/util/util_likely.h index cf6a970d4..df71cee0a 100644 --- a/src/util/util_likely.h +++ b/src/util/util_likely.h @@ -3,9 +3,9 @@ #ifdef __GNUC__ #define likely(x) __builtin_expect((x),1) #define unlikely(x) __builtin_expect((x),0) -#define always_inline inline __attribute__((always_inline)) +#define force_inline inline __attribute__((always_inline)) #else #define likely(x) (x) #define unlikely(x) (x) -#define always_inline inline +#define force_inline inline #endif From eda3ba6372575264d0153b8f2d6c70823a2ca199 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 20 Aug 2022 23:46:58 +0000 Subject: [PATCH 0598/1348] [vulkan] Toss obsolete fullscreen exclusive hack Wine never had support for VK_EXT_exclusive_fullscreen and Proton since dropped support for it now that Doom External does not require it. --- src/vulkan/vulkan_presenter.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index 5725b3644..0938f3ca3 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -13,14 +13,6 @@ namespace dxvk::vk { PresenterDevice device, const PresenterDesc& desc) : m_vki(vki), m_vkd(vkd), m_device(device), m_window(window) { - // As of Wine 5.9, winevulkan provides this extension, but does - // not filter the pNext chain for VkSwapchainCreateInfoKHR properly - // before passing it to the Linux sude, which breaks RenderDoc. - if (m_device.features.fullScreenExclusive && ::GetModuleHandle("winevulkan.dll")) { - Logger::warn("winevulkan detected, disabling exclusive fullscreen support"); - m_device.features.fullScreenExclusive = false; - } - if (createSurface() != VK_SUCCESS) throw DxvkError("Failed to create surface"); From 9509ec114469753c288a34a9097b20053d04211d Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 20 Aug 2022 23:52:30 +0000 Subject: [PATCH 0599/1348] [util] Define platform path_string type --- src/util/util_string.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/util/util_string.h b/src/util/util_string.h index f4810728f..43607378c 100644 --- a/src/util/util_string.h +++ b/src/util/util_string.h @@ -178,9 +178,11 @@ namespace dxvk::str { std::wstring tows(const char* mbs); #ifdef _WIN32 - inline std::wstring topath(const char* mbs) { return tows(mbs); } + using path_string = std::wstring; + inline path_string topath(const char* mbs) { return tows(mbs); } #else - inline std::string topath(const char* mbs) { return std::string(mbs); } + using path_string = std::string; + inline path_string topath(const char* mbs) { return std::string(mbs); } #endif inline void format1(std::stringstream&) { } From 9d64982b230e30e296a84c4c745a87397801170a Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 20 Aug 2022 23:52:54 +0000 Subject: [PATCH 0600/1348] [dxvk] Use path_string for getCacheFileName --- src/dxvk/dxvk_state_cache.cpp | 4 ++-- src/dxvk/dxvk_state_cache.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 92962dacf..fa3322821 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -794,7 +794,7 @@ namespace dxvk { } - std::wstring DxvkStateCache::getCacheFileName() const { + str::path_string DxvkStateCache::getCacheFileName() const { std::string path = getCacheDir(); if (!path.empty() && *path.rbegin() != '/') @@ -802,7 +802,7 @@ namespace dxvk { std::string exeName = env::getExeBaseName(); path += exeName + ".dxvk-cache"; - return str::tows(path.c_str()); + return str::topath(path.c_str()); } diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index 1fae1b097..3df28a4f9 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -159,7 +159,7 @@ namespace dxvk { void createWriter(); - std::wstring getCacheFileName() const; + str::path_string getCacheFileName() const; std::string getCacheDir() const; From 0a203095d69cd353f9109886b0d8ea9c400bbfa0 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:05:42 +0000 Subject: [PATCH 0601/1348] [d3d11] Use topath helper in shader code --- src/d3d11/d3d11_shader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_shader.cpp b/src/d3d11/d3d11_shader.cpp index 800bdea8d..085ad13f2 100644 --- a/src/d3d11/d3d11_shader.cpp +++ b/src/d3d11/d3d11_shader.cpp @@ -27,7 +27,7 @@ namespace dxvk { const std::string dumpPath = env::getEnvVar("DXVK_SHADER_DUMP_PATH"); if (dumpPath.size() != 0) { - reader.store(std::ofstream(str::tows(str::format(dumpPath, "/", name, ".dxbc").c_str()).c_str(), + reader.store(std::ofstream(str::topath(str::format(dumpPath, "/", name, ".dxbc").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc)); } @@ -47,7 +47,7 @@ namespace dxvk { if (dumpPath.size() != 0) { std::ofstream dumpStream( - str::tows(str::format(dumpPath, "/", name, ".spv").c_str()).c_str(), + str::topath(str::format(dumpPath, "/", name, ".spv").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc); m_shader->dump(dumpStream); From 1c679edbfb3267ebde5ba110b73e8866b3307a4d Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:10:05 +0000 Subject: [PATCH 0602/1348] [d3d9] Use topath helpers in shader code --- src/d3d9/d3d9_fixed_function.cpp | 2 +- src/d3d9/d3d9_shader.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 344dc7e89..c54bdc422 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -2441,7 +2441,7 @@ namespace dxvk { if (dumpPath.size() != 0) { std::ofstream dumpStream( - str::tows(str::format(dumpPath, "/", Name, ".spv").c_str()).c_str(), + str::topath(str::format(dumpPath, "/", Name, ".spv").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc); m_shader->dump(dumpStream); diff --git a/src/d3d9/d3d9_shader.cpp b/src/d3d9/d3d9_shader.cpp index 6b22a26e0..650a382e6 100644 --- a/src/d3d9/d3d9_shader.cpp +++ b/src/d3d9/d3d9_shader.cpp @@ -29,7 +29,7 @@ namespace dxvk { DxsoReader reader( reinterpret_cast(pShaderBytecode)); - reader.store(std::ofstream(str::tows(str::format(dumpPath, "/", name, ".dxso").c_str()).c_str(), + reader.store(std::ofstream(str::topath(str::format(dumpPath, "/", name, ".dxso").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc), bytecodeLength); char comment[2048]; @@ -41,7 +41,7 @@ namespace dxvk { &blob); if (SUCCEEDED(hr)) { - std::ofstream disassembledOut(str::tows(str::format(dumpPath, "/", name, ".dxso.dis").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc); + std::ofstream disassembledOut(str::topath(str::format(dumpPath, "/", name, ".dxso.dis").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc); disassembledOut.write( reinterpret_cast(blob->GetBufferPointer()), blob->GetBufferSize()); @@ -75,7 +75,7 @@ namespace dxvk { if (dumpPath.size() != 0) { std::ofstream dumpStream( - str::tows(str::format(dumpPath, "/", name, ".spv").c_str()).c_str(), + str::topath(str::format(dumpPath, "/", name, ".spv").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc); m_shader->dump(dumpStream); From 5f9df1f6e30e76d6e1d3d9573023c40e07fdca6e Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 18:32:45 +0000 Subject: [PATCH 0603/1348] [d3d9] Remove leftover GetWindowRect This is already done for us. --- src/d3d9/d3d9_swapchain.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 03ac6e484..cbe47431a 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -1019,9 +1019,6 @@ namespace dxvk { HRESULT D3D9SwapChainEx::EnterFullscreenMode( D3DPRESENT_PARAMETERS* pPresentParams, const D3DDISPLAYMODEEX* pFullscreenDisplayMode) { - // Find a display mode that matches what we need - ::GetWindowRect(m_window, &m_windowState.rect); - if (FAILED(ChangeDisplayMode(pPresentParams, pFullscreenDisplayMode))) { Logger::err("D3D9: EnterFullscreenMode: Failed to change display mode"); return D3DERR_INVALIDCALL; From c6c8acb000733c13dae28f1f72697f2f90ef192b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 18:33:09 +0000 Subject: [PATCH 0604/1348] [d3d9] Use wsi's isWindow in LeaveFullscreenMode --- src/d3d9/d3d9_swapchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index cbe47431a..fc36547d6 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -1046,7 +1046,7 @@ namespace dxvk { HRESULT D3D9SwapChainEx::LeaveFullscreenMode() { - if (!IsWindow(m_window)) + if (!wsi::isWindow(m_window)) return D3DERR_INVALIDCALL; if (FAILED(RestoreDisplayMode(m_monitor))) From bf99127ee3376b06e8b7ee328ed29ce2d0be16ce Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 18:41:51 +0000 Subject: [PATCH 0605/1348] [d3d9] Stub out cursor code on non-Windows platforms --- src/d3d9/d3d9_cursor.cpp | 19 +++++++++++++++++++ src/d3d9/d3d9_cursor.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/src/d3d9/d3d9_cursor.cpp b/src/d3d9/d3d9_cursor.cpp index 408268c16..798104b3f 100644 --- a/src/d3d9/d3d9_cursor.cpp +++ b/src/d3d9/d3d9_cursor.cpp @@ -5,6 +5,7 @@ namespace dxvk { +#ifdef _WIN32 void D3D9Cursor::UpdateCursor(int X, int Y) { POINT currentPos = { }; if (::GetCursorPos(¤tPos) && currentPos == POINT{ X, Y }) @@ -43,5 +44,23 @@ namespace dxvk { return D3D_OK; } +#else + void D3D9Cursor::UpdateCursor(int X, int Y) { + Logger::warn("D3D9Cursor::UpdateCursor: Not supported on current platform."); + } + + + BOOL D3D9Cursor::ShowCursor(BOOL bShow) { + Logger::warn("D3D9Cursor::ShowCursor: Not supported on current platform."); + return std::exchange(m_visible, bShow); + } + + + HRESULT D3D9Cursor::SetHardwareCursor(UINT XHotSpot, UINT YHotSpot, const CursorBitmap& bitmap) { + Logger::warn("D3D9Cursor::SetHardwareCursor: Not supported on current platform."); + + return D3D_OK; + } +#endif } \ No newline at end of file diff --git a/src/d3d9/d3d9_cursor.h b/src/d3d9/d3d9_cursor.h index 32645d26c..d69e39748 100644 --- a/src/d3d9/d3d9_cursor.h +++ b/src/d3d9/d3d9_cursor.h @@ -26,7 +26,9 @@ namespace dxvk { BOOL m_visible = FALSE; +#ifdef _WIN32 HCURSOR m_hCursor = nullptr; +#endif }; From 0e4e9355cb847a0a758da0c0d55812df464fc4ca Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:10:16 +0000 Subject: [PATCH 0606/1348] [d3d9] Ifdef out code for enumerating adapters by attached displays --- src/d3d9/d3d9_interface.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/d3d9/d3d9_interface.cpp b/src/d3d9/d3d9_interface.cpp index 43f14e896..b729466fd 100644 --- a/src/d3d9/d3d9_interface.cpp +++ b/src/d3d9/d3d9_interface.cpp @@ -20,6 +20,7 @@ namespace dxvk { // If we run out of adapters, then we'll just make repeats of the first one. // We can't match up by names on Linux/Wine as they don't match at all // like on Windows, so this is our best option. +#ifdef _WIN32 if (m_d3d9Options.enumerateByDisplays) { DISPLAY_DEVICEA device = { }; device.cb = sizeof(device); @@ -44,6 +45,7 @@ namespace dxvk { } } else +#endif { const uint32_t adapterCount = m_instance->adapterCount(); m_adapters.reserve(adapterCount); @@ -52,10 +54,12 @@ namespace dxvk { m_adapters.emplace_back(this, m_instance->enumAdapters(i), i, 0); } +#ifdef _WIN32 if (m_d3d9Options.dpiAware) { Logger::info("Process set as DPI aware"); SetProcessDPIAware(); } +#endif } From 38cd2f729051d8565b79c9004b2e089a25048637 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 20 Aug 2022 23:54:36 +0000 Subject: [PATCH 0607/1348] [dxvk] Remove WIN32 check for handle type in DxvkFenceCreateInfo On other platforms we always have a HANDLE and will return through a HANDLE anyway. When we implement this on Linux, we can just add an `int fd` to the union and it can use that, and return it out as a HANDLE. --- src/dxvk/dxvk_fence.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/dxvk/dxvk_fence.h b/src/dxvk/dxvk_fence.h index 797452860..0c6693693 100644 --- a/src/dxvk/dxvk_fence.h +++ b/src/dxvk/dxvk_fence.h @@ -23,12 +23,9 @@ namespace dxvk { uint64_t initialValue; VkExternalSemaphoreHandleTypeFlagBits sharedType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM; union { -#ifdef _WIN32 + // When we want to implement this on non-Windows platforms, + // we could add a `int fd` here, etc. HANDLE sharedHandle = INVALID_HANDLE_VALUE; -#else - // Placeholder for other handle types, such as FD - void *dummy; -#endif }; }; From 915ec4acc26745dbdc5ced43bef56ebfcfbd9f15 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:09:35 +0000 Subject: [PATCH 0608/1348] [dxvk] Remove WIN32 check for handle type in DxvkSharedHandleInfo The initial implementation if-deffed this, but it doesn't need to be. --- src/dxvk/dxvk_memory.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index 795dd74d6..5b8e829dc 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -34,12 +34,9 @@ namespace dxvk { DxvkSharedHandleMode mode = DxvkSharedHandleMode::None; VkExternalMemoryHandleTypeFlagBits type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM; union { -#ifdef _WIN32 - HANDLE handle = INVALID_HANDLE_VALUE; -#else - // Placeholder for other handle types, such as FD - void *dummy; -#endif + // When we want to implement this on non-Windows platforms, + // we could add a `int fd` here, etc. + HANDLE handle = INVALID_HANDLE_VALUE; }; }; From e51c196ee9212db089daab79ba980fc708b0866b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 00:01:28 +0000 Subject: [PATCH 0609/1348] [dxgi] Remove MonitorEnumProc and MonitorEnumInfo Not used anymore, replaced by WSI abstraction. --- src/dxgi/dxgi_adapter.cpp | 15 --------------- src/dxgi/dxgi_adapter.h | 13 +------------ 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index df8c6b541..d947ab447 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -474,19 +474,4 @@ namespace dxvk { } } - - BOOL CALLBACK DxgiAdapter::MonitorEnumProc( - HMONITOR hmon, - HDC hdc, - LPRECT rect, - LPARAM lp) { - auto data = reinterpret_cast(lp); - - if (data->iMonitorId--) - return TRUE; /* continue */ - - data->oMonitor = hmon; - return FALSE; /* stop */ - } - } diff --git a/src/dxgi/dxgi_adapter.h b/src/dxgi/dxgi_adapter.h index a9a0d2dfb..517254d97 100644 --- a/src/dxgi/dxgi_adapter.h +++ b/src/dxgi/dxgi_adapter.h @@ -123,18 +123,7 @@ namespace dxvk { dxvk::thread m_eventThread; void runEventThread(); - - struct MonitorEnumInfo { - UINT iMonitorId; - HMONITOR oMonitor; - }; - - static BOOL CALLBACK MonitorEnumProc( - HMONITOR hmon, - HDC hdc, - LPRECT rect, - LPARAM lp); - + }; } From fad6f764ea8a22e4d9841e846808cae589f06f0b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 17:43:36 +0000 Subject: [PATCH 0610/1348] [dxgi] Remove unused DEVMODE variable --- src/dxgi/dxgi_output.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index 8fb52e82c..570282cfc 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -122,9 +122,6 @@ namespace dxvk { if ((pModeToMatch->Width == 0) ^ (pModeToMatch->Height == 0)) return DXGI_ERROR_INVALID_CALL; - DEVMODEW devMode; - devMode.dmSize = sizeof(devMode); - wsi::WsiMode activeWsiMode = { }; wsi::getCurrentDisplayMode(m_monitor, &activeWsiMode); From 4a113c39d3d89d7b166eb35f3fe1f0362fafedcd Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 17:34:03 +0000 Subject: [PATCH 0611/1348] [d3d11] Remove compat definitions for older MinGW These conflict with native builds, and have existed for a long time now. --- src/d3d11/d3d11_include.h | 41 --------------------------------------- 1 file changed, 41 deletions(-) diff --git a/src/d3d11/d3d11_include.h b/src/d3d11/d3d11_include.h index 1598088af..ef6b135e6 100644 --- a/src/d3d11/d3d11_include.h +++ b/src/d3d11/d3d11_include.h @@ -3,44 +3,3 @@ #include "../dxgi/dxgi_include.h" #include - -// This is not defined in the mingw headers -#ifndef D3D11_1_UAV_SLOT_COUNT -#define D3D11_1_UAV_SLOT_COUNT 64 -#endif - -#ifndef D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL -#define D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL 0xFFFFFFFF -#endif - -#ifndef D3D11_KEEP_UNORDERED_ACCESS_VIEWS -#define D3D11_KEEP_UNORDERED_ACCESS_VIEWS 0xFFFFFFFF -#endif - -#define D3D11_DXVK_USE_REMAINING_LAYERS 0xFFFFFFFF -#define D3D11_DXVK_USE_REMAINING_LEVELS 0xFFFFFFFF - -// Most of these were copied from d3d11.h -// For some strange reason, we cannot use the structures -// directly, although others from the same header work. -// Some structures are missing from the mingw headers. -#ifndef _MSC_VER -#if !defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 9 -typedef enum D3D11_FORMAT_SUPPORT2 { - D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_ADD = 0x1, - D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS = 0x2, - D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE = 0x4, - D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE = 0x8, - D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX = 0x10, - D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX = 0x20, - D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD = 0x40, - D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE = 0x80, - D3D11_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP = 0x100, - D3D11_FORMAT_SUPPORT2_TILED = 0x200, - D3D11_FORMAT_SUPPORT2_SHAREABLE = 0x400, - D3D11_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY = 0x4000 -} D3D11_FORMAT_SUPPORT2; -#define D3D11_RESOURCE_MISC_TILE_POOL (0x20000) -#define D3D11_RESOURCE_MISC_TILED (0x40000) -#endif // !defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 9 -#endif // _MSC_VER From 538b132490967239e2d673659789ea9b76698ee3 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 17:38:38 +0000 Subject: [PATCH 0612/1348] [dxgi] Don't declspec dllexport on MinGW builds Fixes ordinal exporting on MinGW on 32-bit builds. Mirrors this D3D9 commit here: 904d3e6c9014bff7aa0843630b009c51879a1d06 --- src/dxgi/dxgi_include.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/dxgi/dxgi_include.h b/src/dxgi/dxgi_include.h index 62dbeacfa..79ffc6ef0 100644 --- a/src/dxgi/dxgi_include.h +++ b/src/dxgi/dxgi_include.h @@ -2,11 +2,9 @@ //for some reason we need to specify __declspec(dllexport) for MinGW #if defined(__WINE__) - #define DLLEXPORT __attribute__((visibility("default"))) -#elif defined(_MSC_VER) - #define DLLEXPORT +#define DLLEXPORT __attribute__((visibility("default"))) #else - #define DLLEXPORT __declspec(dllexport) +#define DLLEXPORT #endif #include "../util/com/com_guid.h" From f0f4258be360ebe237acf2881e3f73401c689e7c Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 17:39:22 +0000 Subject: [PATCH 0613/1348] [dxgi] Correct DLLEXPORT for native builds --- src/dxgi/dxgi_include.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxgi/dxgi_include.h b/src/dxgi/dxgi_include.h index 79ffc6ef0..0853b1781 100644 --- a/src/dxgi/dxgi_include.h +++ b/src/dxgi/dxgi_include.h @@ -1,7 +1,7 @@ #pragma once //for some reason we need to specify __declspec(dllexport) for MinGW -#if defined(__WINE__) +#if defined(__WINE__) || !defined(_WIN32) #define DLLEXPORT __attribute__((visibility("default"))) #else #define DLLEXPORT From ad386305ff06c75c0fde9cc205f38a5e84c718b7 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 17:37:29 +0000 Subject: [PATCH 0614/1348] [d3d9] Correct DLLEXPORT for native builds --- src/d3d9/d3d9_include.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_include.h b/src/d3d9/d3d9_include.h index 2b933aecd..1f893475a 100644 --- a/src/d3d9/d3d9_include.h +++ b/src/d3d9/d3d9_include.h @@ -11,7 +11,7 @@ #include //for some reason we need to specify __declspec(dllexport) for MinGW -#if defined(__WINE__) +#if defined(__WINE__) || !defined(_WIN32) #define DLLEXPORT __attribute__((visibility("default"))) #else #define DLLEXPORT From ba8868be241fc660b244c8c6509599af799f8ac6 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 18:35:16 +0000 Subject: [PATCH 0615/1348] [util] Add win32 compat header Header of misc. stubs and re-implementations. --- src/util/util_win32_compat.h | 59 ++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/util/util_win32_compat.h diff --git a/src/util/util_win32_compat.h b/src/util/util_win32_compat.h new file mode 100644 index 000000000..41eaf9c61 --- /dev/null +++ b/src/util/util_win32_compat.h @@ -0,0 +1,59 @@ +#pragma once + +#if defined(__linux__) + +#include +#include + +#include "log/log.h" + +inline HMODULE LoadLibraryA(LPCSTR lpLibFileName) { + return dlopen(lpLibFileName, RTLD_NOW); +} + +inline void CloseLibrary(HMODULE module) { + dlclose(module); +} + +inline void* GetProcAddress(HMODULE module, LPCSTR lpProcName) { + return dlsym(module, lpProcName); +} + +inline HANDLE CreateSemaphoreA( + SECURITY_ATTRIBUTES* lpSemaphoreAttributes, + LONG lInitialCount, + LONG lMaximumCount, + LPCSTR lpName) { + dxvk::Logger::warn("CreateSemaphoreA not implemented."); + return nullptr; +} +#define CreateSemaphore CreateSemaphoreA + +inline BOOL ReleaseSemaphore( + HANDLE hSemaphore, + LONG lReleaseCount, + LONG* lpPreviousCount) { + dxvk::Logger::warn("ReleaseSemaphore not implemented."); + return FALSE; +} + +inline BOOL SetEvent(HANDLE hEvent) { + dxvk::Logger::warn("SetEvent not implemented."); + return FALSE; +} + +inline BOOL CloseHandle(HANDLE hObject) { + dxvk::Logger::warn("CloseHandle not implemented."); + return FALSE; +} + +inline HDC CreateCompatibleDC(HDC hdc) { + dxvk::Logger::warn("CreateCompatibleDC not implemented."); + return nullptr; +} + +inline BOOL DeleteDC(HDC hdc) { + return FALSE; +} + +#endif From a554a6d60d3b1bf1f1bc4ae98575e66c428dd864 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:05:27 +0000 Subject: [PATCH 0616/1348] [d3d11] Include win32 compat headers where applicable --- src/d3d11/d3d11_annotation.cpp | 1 + src/d3d11/d3d11_context_imm.cpp | 2 ++ src/d3d11/d3d11_fence.cpp | 1 + src/d3d11/d3d11_gdi.cpp | 1 + src/d3d11/d3d11_swapchain.cpp | 2 ++ src/d3d11/d3d11_texture.cpp | 1 + 6 files changed, 8 insertions(+) diff --git a/src/d3d11/d3d11_annotation.cpp b/src/d3d11/d3d11_annotation.cpp index b46dfe41e..b7c1fdf77 100644 --- a/src/d3d11/d3d11_annotation.cpp +++ b/src/d3d11/d3d11_annotation.cpp @@ -4,6 +4,7 @@ #include "d3d11_device.h" #include "../util/util_misc.h" +#include "../util/util_win32_compat.h" namespace dxvk { diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 6703a661f..b9978d91a 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -4,6 +4,8 @@ #include "d3d11_fence.h" #include "d3d11_texture.h" +#include "../util/util_win32_compat.h" + constexpr static uint32_t MinFlushIntervalUs = 750; constexpr static uint32_t IncFlushIntervalUs = 250; constexpr static uint32_t MaxPendingSubmits = 6; diff --git a/src/d3d11/d3d11_fence.cpp b/src/d3d11/d3d11_fence.cpp index e3c7688b2..3351f4ac8 100644 --- a/src/d3d11/d3d11_fence.cpp +++ b/src/d3d11/d3d11_fence.cpp @@ -1,5 +1,6 @@ #include "d3d11_fence.h" #include "d3d11_device.h" +#include "../util/util_win32_compat.h" namespace dxvk { diff --git a/src/d3d11/d3d11_gdi.cpp b/src/d3d11/d3d11_gdi.cpp index 0958886ec..bd1fa90b8 100644 --- a/src/d3d11/d3d11_gdi.cpp +++ b/src/d3d11/d3d11_gdi.cpp @@ -3,6 +3,7 @@ #include "d3d11_gdi.h" #include "../util/util_gdi.h" +#include "../util/util_win32_compat.h" namespace dxvk { diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 22e006c40..bef53f5a0 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -2,6 +2,8 @@ #include "d3d11_device.h" #include "d3d11_swapchain.h" +#include "../util/util_win32_compat.h" + namespace dxvk { static uint16_t MapGammaControlPoint(float x) { diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 5f8149026..1171b42b6 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -3,6 +3,7 @@ #include "d3d11_texture.h" #include "../util/util_shared_res.h" +#include "../util/util_win32_compat.h" namespace dxvk { From 968bdccbef87b9a425cb8d9a61f6be824ca0d3e6 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:07:10 +0000 Subject: [PATCH 0617/1348] [d3d9] Include win32 compat headers where applicable --- src/d3d9/d3d9_common_texture.cpp | 1 + src/d3d9/d3d9_surface.cpp | 2 ++ src/d3d9/d3d9_util.cpp | 2 ++ 3 files changed, 5 insertions(+) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index e1d675b91..2d1b2317e 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -4,6 +4,7 @@ #include "d3d9_device.h" #include "../util/util_shared_res.h" +#include "../util/util_win32_compat.h" #include diff --git a/src/d3d9/d3d9_surface.cpp b/src/d3d9/d3d9_surface.cpp index 300782e99..1ff2b4e33 100644 --- a/src/d3d9/d3d9_surface.cpp +++ b/src/d3d9/d3d9_surface.cpp @@ -4,6 +4,8 @@ #include "d3d9_device.h" +#include "../util/util_win32_compat.h" + namespace dxvk { D3D9Surface::D3D9Surface( diff --git a/src/d3d9/d3d9_util.cpp b/src/d3d9/d3d9_util.cpp index d740313e7..43f68d3e6 100644 --- a/src/d3d9/d3d9_util.cpp +++ b/src/d3d9/d3d9_util.cpp @@ -1,5 +1,7 @@ #include "d3d9_util.h" +#include "../util/util_win32_compat.h" + namespace dxvk { typedef HRESULT (STDMETHODCALLTYPE *D3DXDisassembleShader) ( From 8b7e0bc2fd721b52d589e5b55855a873c54f751d Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:07:25 +0000 Subject: [PATCH 0618/1348] [dxgi] Include win32 compat headers where applicable --- src/dxgi/dxgi_adapter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index d947ab447..a6395f4b7 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -11,6 +11,7 @@ #include "dxgi_output.h" #include "../util/util_luid.h" +#include "../util/util_win32_compat.h" #include "../wsi/wsi_monitor.h" From a5db9d22f193353c3099284b825e48a0ea495b4a Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 17:54:28 +0000 Subject: [PATCH 0619/1348] [dxvk] Disable VrInstance and DxvkXrProvider on native builds If/when we want to support VR on native builds, we can deal with that then. --- src/dxvk/dxvk_instance.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index 1d56910d9..5efa4cf82 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -20,8 +20,10 @@ namespace dxvk { m_options = DxvkOptions(m_config); m_extProviders.push_back(&DxvkPlatformExts::s_instance); +#ifdef _WIN32 m_extProviders.push_back(&VrInstance::s_instance); m_extProviders.push_back(&DxvkXrProvider::s_instance); +#endif Logger::info("Built-in extension providers:"); for (const auto& provider : m_extProviders) From baa88d8cf1ea9e116bb8ffde07ee82daef731913 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 18:28:01 +0000 Subject: [PATCH 0620/1348] [d3d11] Don't check for apitrace on non-Windows platforms --- src/d3d11/d3d11_options.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index 84d052bf3..4874e114e 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -4,6 +4,14 @@ namespace dxvk { + static bool IsAPITracingDXGI() { +#ifdef _WIN32 + return !!::GetModuleHandle("dxgitrace.dll"); +#else + return false; +#endif + } + D3D11Options::D3D11Options(const Config& config, const Rc& device) { this->dcSingleUseMode = config.getOption("d3d11.dcSingleUseMode", true); this->enableRtOutputNanFixup = config.getOption("d3d11.enableRtOutputNanFixup", false); @@ -39,7 +47,7 @@ namespace dxvk { auto cachedDynamicResources = config.getOption("d3d11.cachedDynamicResources", std::string()); - if (::GetModuleHandle("dxgitrace.dll")) { + if (IsAPITracingDXGI()) { // apitrace reads back all mapped resources on the CPU, so // allocating everything in cached memory is necessary to // achieve acceptable performance From baba2e3c093553797688eb2aea98d934d6e0a60a Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:12:40 +0000 Subject: [PATCH 0621/1348] [d3d11] Use dxgi_dep instead of lib_dxgi Fixes building on native. --- src/d3d11/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 85fe78074..0b99f695f 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -69,7 +69,7 @@ d3d11_shaders = files([ d3d11_dll = shared_library('d3d11'+dll_ext, dxgi_common_src + d3d11_src + d3d10_src, glsl_generator.process(d3d11_shaders), d3d11_res, name_prefix : '', - dependencies : [ lib_dxgi, dxbc_dep, dxvk_dep ], + dependencies : [ dxgi_dep, dxbc_dep, dxvk_dep ], include_directories : dxvk_include_path, install : true, vs_module_defs : 'd3d11'+def_spec_ext, From 191d54e210466a4c8a6ac4b59e0b63585089ebfd Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:14:02 +0000 Subject: [PATCH 0622/1348] [build] Don't build D3D10 on non-Windows platforms Not supported due to d3dcompiler schenanigans --- src/meson.build | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/meson.build b/src/meson.build index c2831cf1b..e7efdbca8 100644 --- a/src/meson.build +++ b/src/meson.build @@ -20,10 +20,14 @@ if get_option('enable_d3d11') endif if get_option('enable_d3d10') - if not get_option('enable_d3d11') - error('D3D11 is required for D3D10.') + if platform == 'windows' + if not get_option('enable_d3d11') + error('D3D11 is required for D3D10.') + endif + subdir('d3d10') + else + warning('Building D3D10 is not supported on non-Windows platforms') endif - subdir('d3d10') endif if get_option('enable_d3d9') From e6fb3e1509e8ab76ccfa2ddf7ff28592288c4005 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:10:28 +0000 Subject: [PATCH 0623/1348] [wsi] Add SDL2 implementation --- src/wsi/meson.build | 8 ++ src/wsi/sdl2/wsi_monitor_sdl2.cpp | 147 ++++++++++++++++++++++++++++ src/wsi/sdl2/wsi_platform_sdl2.h | 21 ++++ src/wsi/sdl2/wsi_window_sdl2.cpp | 155 ++++++++++++++++++++++++++++++ src/wsi/wsi_platform.h | 4 +- 5 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 src/wsi/sdl2/wsi_monitor_sdl2.cpp create mode 100644 src/wsi/sdl2/wsi_platform_sdl2.h create mode 100644 src/wsi/sdl2/wsi_window_sdl2.cpp diff --git a/src/wsi/meson.build b/src/wsi/meson.build index 0e0f9da39..a7442dfb4 100644 --- a/src/wsi/meson.build +++ b/src/wsi/meson.build @@ -3,9 +3,17 @@ wsi_win32_src = [ 'win32/wsi_window_win32.cpp', ] +wsi_sdl2_src = [ + 'sdl2/wsi_monitor_sdl2.cpp', + 'sdl2/wsi_window_sdl2.cpp', +] + if dxvk_wsi == 'win32' wsi_src = wsi_win32_src wsi_deps = [] +elif dxvk_wsi == 'sdl2' + wsi_src = wsi_sdl2_src + wsi_deps = [ lib_sdl2 ] else error('Unknown wsi') endif diff --git a/src/wsi/sdl2/wsi_monitor_sdl2.cpp b/src/wsi/sdl2/wsi_monitor_sdl2.cpp new file mode 100644 index 000000000..1ab82301c --- /dev/null +++ b/src/wsi/sdl2/wsi_monitor_sdl2.cpp @@ -0,0 +1,147 @@ +#include "../wsi_monitor.h" + +#include "wsi/native_wsi.h" +#include "wsi_platform_sdl2.h" + +#include "../../util/util_string.h" +#include "../../util/log/log.h" + +#include +#include + + +namespace dxvk::wsi { + + HMONITOR getDefaultMonitor() { + return enumMonitors(0); + } + + + HMONITOR enumMonitors(uint32_t index) { + return isDisplayValid(int32_t(index)) + ? toHmonitor(index) + : nullptr; + } + + bool getDisplayName( + HMONITOR hMonitor, + WCHAR (&Name)[32]) { + const int32_t displayId = fromHmonitor(hMonitor); + + if (!isDisplayValid(displayId)) + return false; + + std::wstringstream nameStream; + nameStream << LR"(\\.\DISPLAY)" << (displayId + 1); + + std::wstring name = nameStream.str(); + + std::memset(Name, 0, sizeof(Name)); + name.copy(Name, name.length(), 0); + + return true; + } + + + bool getDesktopCoordinates( + HMONITOR hMonitor, + RECT* pRect) { + const int32_t displayId = fromHmonitor(hMonitor); + + if (!isDisplayValid(displayId)) + return false; + + SDL_Rect rect = { }; + SDL_GetDisplayBounds(displayId, &rect); + + pRect->left = rect.x; + pRect->top = rect.y; + pRect->right = rect.x + rect.w; + pRect->bottom = rect.y + rect.h; + + return true; + } + + + static inline uint32_t roundToNextPow2(uint32_t num) { + if (num-- == 0) + return 0; + + num |= num >> 1; num |= num >> 2; + num |= num >> 4; num |= num >> 8; + num |= num >> 16; + + return ++num; + } + + + static inline void convertMode(const SDL_DisplayMode& mode, WsiMode* pMode) { + pMode->width = uint32_t(mode.w); + pMode->height = uint32_t(mode.h); + pMode->refreshRate = WsiRational{ uint32_t(mode.refresh_rate) * 1000, 1000 }; + // BPP should always be a power of two + // to match Windows behaviour of including padding. + pMode->bitsPerPixel = roundToNextPow2(SDL_BITSPERPIXEL(mode.format)); + pMode->interlaced = false; + } + + + bool getDisplayMode( + HMONITOR hMonitor, + uint32_t ModeNumber, + WsiMode* pMode) { + const int32_t displayId = fromHmonitor(hMonitor); + + if (!isDisplayValid(displayId)) + return false; + + SDL_DisplayMode mode = { }; + if (SDL_GetDisplayMode(displayId, ModeNumber, &mode) != 0) + return false; + + convertMode(mode, pMode); + + return true; + } + + + bool getCurrentDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode) { + const int32_t displayId = fromHmonitor(hMonitor); + + if (!isDisplayValid(displayId)) + return false; + + SDL_DisplayMode mode = { }; + if (SDL_GetCurrentDisplayMode(displayId, &mode) != 0) { + Logger::err(str::format("SDL_GetCurrentDisplayMode: ", SDL_GetError())); + return false; + } + + convertMode(mode, pMode); + + return true; + } + + + bool getDesktopDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode) { + const int32_t displayId = fromHmonitor(hMonitor); + + if (!isDisplayValid(displayId)) + return false; + + SDL_DisplayMode mode = { }; + if (SDL_GetDesktopDisplayMode(displayId, &mode) != 0) { + Logger::err(str::format("SDL_GetCurrentDisplayMode: ", SDL_GetError())); + return false; + } + + convertMode(mode, pMode); + + return true; + } + +} \ No newline at end of file diff --git a/src/wsi/sdl2/wsi_platform_sdl2.h b/src/wsi/sdl2/wsi_platform_sdl2.h new file mode 100644 index 000000000..411fe8f6f --- /dev/null +++ b/src/wsi/sdl2/wsi_platform_sdl2.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +#include "../wsi_monitor.h" + +namespace dxvk::wsi { + + /** + * \brief Impl-dependent state + */ + struct DxvkWindowState { + }; + + inline bool isDisplayValid(int32_t displayId) { + const int32_t displayCount = SDL_GetNumVideoDisplays(); + + return displayId < displayCount && displayId >= 0; + } + +} \ No newline at end of file diff --git a/src/wsi/sdl2/wsi_window_sdl2.cpp b/src/wsi/sdl2/wsi_window_sdl2.cpp new file mode 100644 index 000000000..7fbbb0ae2 --- /dev/null +++ b/src/wsi/sdl2/wsi_window_sdl2.cpp @@ -0,0 +1,155 @@ +#include "../wsi_window.h" + +#include "native/wsi/native_wsi.h" +#include "wsi_platform_sdl2.h" + +#include "../../util/util_string.h" +#include "../../util/log/log.h" + +#include +#include + +namespace dxvk::wsi { + + void getWindowSize( + HWND hWindow, + uint32_t* pWidth, + uint32_t* pHeight) { + SDL_Window* window = fromHwnd(hWindow); + + int32_t w, h; + SDL_GetWindowSize(window, &w, &h); + + if (pWidth) + *pWidth = uint32_t(w); + + if (pHeight) + *pHeight = uint32_t(h); + } + + + void resizeWindow( + HWND hWindow, + DxvkWindowState* pState, + uint32_t Width, + uint32_t Height) { + SDL_Window* window = fromHwnd(hWindow); + + SDL_SetWindowSize(window, int32_t(Width), int32_t(Height)); + } + + + bool setWindowMode( + HMONITOR hMonitor, + HWND hWindow, + const WsiMode& pMode) { + const int32_t displayId = fromHmonitor(hMonitor); + SDL_Window* window = fromHwnd(hWindow); + + if (!isDisplayValid(displayId)) + return false; + + SDL_DisplayMode wantedMode = { }; + wantedMode.w = pMode.width; + wantedMode.h = pMode.height; + wantedMode.refresh_rate = pMode.refreshRate.numerator != 0 + ? pMode.refreshRate.numerator / pMode.refreshRate.denominator + : 0; + // TODO: Implement lookup format for bitsPerPixel here. + + SDL_DisplayMode mode = { }; + if (SDL_GetClosestDisplayMode(displayId, &wantedMode, &mode) == nullptr) { + Logger::err(str::format("SDL2 WSI: setWindowMode: SDL_GetClosestDisplayMode: ", SDL_GetError())); + return false; + } + + if (SDL_SetWindowDisplayMode(window, &mode) != 0) { + Logger::err(str::format("SDL2 WSI: setWindowMode: SDL_SetWindowDisplayMode: ", SDL_GetError())); + return false; + } + + return true; + } + + + + bool enterFullscreenMode( + HMONITOR hMonitor, + HWND hWindow, + DxvkWindowState* pState, + bool ModeSwitch) { + const int32_t displayId = fromHmonitor(hMonitor); + SDL_Window* window = fromHwnd(hWindow); + + if (!isDisplayValid(displayId)) + return false; + + uint32_t flags = ModeSwitch + ? SDL_WINDOW_FULLSCREEN + : SDL_WINDOW_FULLSCREEN_DESKTOP; + + // TODO: Set this on the correct monitor. + // Docs aren't clear on this... + if (SDL_SetWindowFullscreen(window, flags) != 0) { + Logger::err(str::format("SDL2 WSI: enterFullscreenMode: SDL_SetWindowFullscreen: ", SDL_GetError())); + return false; + } + + return true; + } + + + bool leaveFullscreenMode( + HWND hWindow, + DxvkWindowState* pState) { + SDL_Window* window = fromHwnd(hWindow); + + if (SDL_SetWindowFullscreen(window, 0) != 0) { + Logger::err(str::format("SDL2 WSI: leaveFullscreenMode: SDL_SetWindowFullscreen: ", SDL_GetError())); + return false; + } + + return true; + } + + + bool restoreDisplayMode() { + // Don't need to do anything with SDL2 here. + return true; + } + + + HMONITOR getWindowMonitor(HWND hWindow) { + SDL_Window* window = fromHwnd(hWindow); + const int32_t displayId = SDL_GetWindowDisplayIndex(window); + + return toHmonitor(displayId); + } + + + bool isWindow(HWND hWindow) { + SDL_Window* window = fromHwnd(hWindow); + return window != nullptr; + } + + + void updateFullscreenWindow( + HMONITOR hMonitor, + HWND hWindow, + bool forceTopmost) { + // Don't need to do anything with SDL2 here. + } + + + VkResult createSurface( + HWND hWindow, + const Rc& vki, + VkSurfaceKHR* pSurface) { + SDL_Window* window = fromHwnd(hWindow); + + return SDL_Vulkan_CreateSurface(window, vki->instance(), pSurface) + ? VK_SUCCESS + : VK_ERROR_OUT_OF_HOST_MEMORY; + } + +} \ No newline at end of file diff --git a/src/wsi/wsi_platform.h b/src/wsi/wsi_platform.h index 5028b20bb..2cbcd2292 100644 --- a/src/wsi/wsi_platform.h +++ b/src/wsi/wsi_platform.h @@ -1,5 +1,7 @@ #pragma once -#ifdef DXVK_WSI_WIN32 +#if defined(DXVK_WSI_WIN32) #include "win32/wsi_platform_win32.h" +#elif defined(DXVK_WSI_SDL2) +#include "sdl2/wsi_platform_sdl2.h" #endif From 5787d9ee048b976f4a6cf80105809fe54b6253b6 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:11:57 +0000 Subject: [PATCH 0624/1348] [dxvk] Check platform before building openvr + openxr cpps --- src/dxvk/meson.build | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index cf2822504..080f4a964 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -60,7 +60,7 @@ dxvk_shaders = files([ 'hud/shaders/hud_text_vert.vert', ]) -dxvk_src = files([ +dxvk_src = [ 'dxvk_adapter.cpp', 'dxvk_barrier.cpp', 'dxvk_buffer.cpp', @@ -89,8 +89,6 @@ dxvk_src = files([ 'dxvk_meta_mipgen.cpp', 'dxvk_meta_pack.cpp', 'dxvk_meta_resolve.cpp', - 'dxvk_openvr.cpp', - 'dxvk_openxr.cpp', 'dxvk_options.cpp', 'dxvk_pipelayout.cpp', 'dxvk_pipemanager.cpp', @@ -113,7 +111,14 @@ dxvk_src = files([ 'hud/dxvk_hud_font.cpp', 'hud/dxvk_hud_item.cpp', 'hud/dxvk_hud_renderer.cpp', -]) +] + +if platform == 'windows' + dxvk_src += [ + 'dxvk_openvr.cpp', + 'dxvk_openxr.cpp', + ] +endif thread_dep = dependency('threads') From 97350d6c35e8382478c4695ca77d5ec9cb37135f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:12:13 +0000 Subject: [PATCH 0625/1348] [dxvk] Support for SDL2 WSI --- src/dxvk/meson.build | 12 +++++- src/dxvk/platform/dxvk_sdl2_exts.cpp | 60 ++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 src/dxvk/platform/dxvk_sdl2_exts.cpp diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 080f4a964..56aa42102 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -105,8 +105,6 @@ dxvk_src = [ 'dxvk_unbound.cpp', 'dxvk_util.cpp', - 'platform/dxvk_win32_exts.cpp', - 'hud/dxvk_hud.cpp', 'hud/dxvk_hud_font.cpp', 'hud/dxvk_hud_item.cpp', @@ -120,6 +118,16 @@ if platform == 'windows' ] endif +if dxvk_wsi == 'win32' + dxvk_src += [ + 'platform/dxvk_win32_exts.cpp' + ] +elif dxvk_wsi == 'sdl2' + dxvk_src += [ + 'platform/dxvk_sdl2_exts.cpp' + ] +endif + thread_dep = dependency('threads') dxvk_lib = static_library('dxvk', dxvk_src, glsl_generator.process(dxvk_shaders), dxvk_version, diff --git a/src/dxvk/platform/dxvk_sdl2_exts.cpp b/src/dxvk/platform/dxvk_sdl2_exts.cpp new file mode 100644 index 000000000..65a3f4993 --- /dev/null +++ b/src/dxvk/platform/dxvk_sdl2_exts.cpp @@ -0,0 +1,60 @@ +#include "../dxvk_platform_exts.h" + +#include +#include + +namespace dxvk { + + DxvkPlatformExts DxvkPlatformExts::s_instance; + + std::string_view DxvkPlatformExts::getName() { + return "SDL2 WSI"; + } + + + DxvkNameSet DxvkPlatformExts::getInstanceExtensions() { + SDL_Window* window = SDL_CreateWindow( + "Dummy Window", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + 1, 1, + SDL_WINDOW_HIDDEN | SDL_WINDOW_VULKAN); + + if (window == nullptr) + throw DxvkError(str::format("SDL2 WSI: Failed to create dummy window. ", SDL_GetError())); + + uint32_t extensionCount = 0; + if (!SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, nullptr)) + throw DxvkError(str::format("SDL2 WSI: Failed to get instance extension count. ", SDL_GetError())); + + auto extensionNames = std::vector(extensionCount); + if (!SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, extensionNames.data())) + throw DxvkError(str::format("SDL2 WSI: Failed to get instance extensions. ", SDL_GetError())); + + DxvkNameSet names; + for (const char* name : extensionNames) + names.add(name); + + SDL_DestroyWindow(window); + + return names; + } + + + DxvkNameSet DxvkPlatformExts::getDeviceExtensions( + uint32_t adapterId) { + return DxvkNameSet(); + } + + + void DxvkPlatformExts::initInstanceExtensions() { + + } + + + void DxvkPlatformExts::initDeviceExtensions( + const DxvkInstance* instance) { + + } + +} From 1c1dba46246b4f98826c2d36f38a046e7f1583b6 Mon Sep 17 00:00:00 2001 From: Joshie Date: Sun, 21 Aug 2022 21:17:33 +0100 Subject: [PATCH 0626/1348] [util] Implement thread set_priority on non-Windows platforms --- src/util/thread.h | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/util/thread.h b/src/util/thread.h index 41750a99c..a0348e688 100644 --- a/src/util/thread.h +++ b/src/util/thread.h @@ -15,18 +15,15 @@ namespace dxvk { -#ifdef _WIN32 /** * \brief Thread priority */ enum class ThreadPriority : int32_t { - Lowest = THREAD_PRIORITY_LOWEST, - Low = THREAD_PRIORITY_BELOW_NORMAL, - Normal = THREAD_PRIORITY_NORMAL, - High = THREAD_PRIORITY_ABOVE_NORMAL, - Highest = THREAD_PRIORITY_HIGHEST, + Normal, + Lowest, }; +#ifdef _WIN32 /** * \brief Thread helper class * @@ -74,7 +71,13 @@ namespace dxvk { } void set_priority(ThreadPriority priority) { - ::SetThreadPriority(m_handle, int32_t(priority)); + int32_t value; + switch (priority) { + default: + case ThreadPriority::Normal: value = THREAD_PRIORITY_NORMAL; break; + case ThreadPriority::Lowest: value = THREAD_PRIORITY_LOWEST; break; + } + ::SetThreadPriority(m_handle, int32_t(value)); } private: @@ -332,8 +335,23 @@ namespace dxvk { }; #else + class thread : public std::thread { + public: + using std::thread::thread; + + void set_priority(ThreadPriority priority) { + ::sched_param param = {}; + int32_t policy; + switch (priority) { + default: + case ThreadPriority::Normal: policy = SCHED_OTHER; break; + case ThreadPriority::Lowest: policy = SCHED_IDLE; break; + } + ::pthread_setschedparam(this->native_handle(), policy, ¶m); + } + }; + using mutex = std::mutex; - using thread = std::thread; using recursive_mutex = std::recursive_mutex; using condition_variable = std::condition_variable; From 8921f625396389b164d1169bbbb19a64c56c8e6b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 20:15:07 +0000 Subject: [PATCH 0627/1348] [util] Rename getFrequency, getCounter -> get_frequency, get_counter To be consistent with STL naming conventions --- src/util/util_time.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/util/util_time.h b/src/util/util_time.h index cbadfa5d0..ee9b7d6fc 100644 --- a/src/util/util_time.h +++ b/src/util/util_time.h @@ -20,8 +20,8 @@ namespace dxvk { static inline time_point now() noexcept { // Keep the frequency static, this doesn't change at all. - static const int64_t freq = getFrequency(); - const int64_t counter = getCounter(); + static const int64_t freq = get_frequency(); + const int64_t counter = get_counter(); const int64_t whole = (counter / freq) * period::den; const int64_t part = (counter % freq) * period::den / freq; @@ -29,14 +29,14 @@ namespace dxvk { return time_point(duration(whole + part)); } - static inline int64_t getFrequency() { + static inline int64_t get_frequency() { LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); return freq.QuadPart; } - static inline int64_t getCounter() { + static inline int64_t get_counter() { LARGE_INTEGER count; QueryPerformanceCounter(&count); From 9610e29a657d182b05c4013370a3ef4a2d142619 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 20:20:25 +0000 Subject: [PATCH 0628/1348] [util] Implement get_frequency + get_counter on non-Windows platforms --- src/util/util_time.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/util/util_time.h b/src/util/util_time.h index ee9b7d6fc..625b2b508 100644 --- a/src/util/util_time.h +++ b/src/util/util_time.h @@ -44,7 +44,15 @@ namespace dxvk { } }; #else - using high_resolution_clock = std::chrono::high_resolution_clock; + struct high_resolution_clock : public std::chrono::high_resolution_clock { + static inline int64_t get_frequency() { + return period::den; + } + + static inline int64_t get_counter() { + return dxvk::high_resolution_clock::now().time_since_epoch().count(); + } + }; #endif } \ No newline at end of file From a4261ddd143e00517025862e2da3cee4dcefcf34 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 20:21:08 +0000 Subject: [PATCH 0629/1348] [dxgi] Use high_resolution_clock get_counter instead of QPC for SyncQPCTime Abstracts this across platforms --- src/dxgi/dxgi_swapchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 399a99616..520700df0 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -171,7 +171,7 @@ namespace dxvk { pStats->PresentCount = m_presentCount; pStats->PresentRefreshCount = 0; pStats->SyncRefreshCount = 0; - QueryPerformanceCounter(&pStats->SyncQPCTime); + pStats->SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter(); pStats->SyncGPUTime.QuadPart = 0; return S_OK; } From be33ccbce992b3f809b43eb7f192e3a58731a99d Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 20:28:40 +0000 Subject: [PATCH 0630/1348] [dxgi] Revert 538b132490967239e2d673659789ea9b76698ee3 This breaks things for 32-bit, but it really shouldn't. My hypothesis currently is that the .lib generated is bogus, but the exports in the actual DLL are correct. --- src/dxgi/dxgi_include.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dxgi/dxgi_include.h b/src/dxgi/dxgi_include.h index 0853b1781..ace26cf21 100644 --- a/src/dxgi/dxgi_include.h +++ b/src/dxgi/dxgi_include.h @@ -2,9 +2,11 @@ //for some reason we need to specify __declspec(dllexport) for MinGW #if defined(__WINE__) || !defined(_WIN32) -#define DLLEXPORT __attribute__((visibility("default"))) + #define DLLEXPORT __attribute__((visibility("default"))) +#elif defined(_MSC_VER) + #define DLLEXPORT #else -#define DLLEXPORT + #define DLLEXPORT __declspec(dllexport) #endif #include "../util/com/com_guid.h" From 801d97806d04e99e8000fb41e495d65b4346d905 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 19:05:59 +0000 Subject: [PATCH 0631/1348] [d3d11] Stub out OpenSharedResourceGeneric on non-Windows --- src/d3d11/d3d11_device.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index d05e99cc4..3f693f84e 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2256,6 +2256,7 @@ namespace dxvk { if (ppResource == nullptr) return S_FALSE; +#ifdef _WIN32 HANDLE ntHandle = IsKmtHandle ? openKmtHandle(hResource) : hResource; if (ntHandle == INVALID_HANDLE_VALUE) { @@ -2298,6 +2299,10 @@ namespace dxvk { Logger::err(e.message()); return E_INVALIDARG; } +#else + Logger::warn("D3D11Device::OpenSharedResourceGeneric: Not supported on this platform."); + return E_INVALIDARG; +#endif } From 9dad1aadbe2490789fbbe95ea94fb87157d7bbae Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 20:34:19 +0000 Subject: [PATCH 0632/1348] [build] Set SDL2 WSI env vars and defines on native builds --- meson.build | 3 +++ 1 file changed, 3 insertions(+) diff --git a/meson.build b/meson.build index 11692c386..5c40b3814 100644 --- a/meson.build +++ b/meson.build @@ -103,6 +103,9 @@ else wrc_generator = generator(wrc, output : [ '@BASENAME@_ignored.h' ], arguments : [ '@OUTPUT@' ] ) dxvk_include_path = include_directories('./include', './include/native', './include/native/windows', './include/native/directx') + + dxvk_wsi = 'sdl2' + compiler_args += ['-DDXVK_WSI_SDL2'] endif add_project_arguments(cpp.get_supported_arguments(compiler_args), language: 'cpp') From c258eb05d28c8f09ae693d7c49794c78878110ff Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 21 Aug 2022 20:35:09 +0000 Subject: [PATCH 0633/1348] [build] Enable building natively for non-Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Yipee 🥳🎉 RIP DXVK Native --- meson.build | 4 ---- 1 file changed, 4 deletions(-) diff --git a/meson.build b/meson.build index 5c40b3814..d2c6a5469 100644 --- a/meson.build +++ b/meson.build @@ -133,10 +133,6 @@ dxvk_version = vcs_tag( output: 'version.h', ) -if platform != 'windows' - error('Non-Windows platforms not supported... yet.') -endif - subdir('src') enable_tests = get_option('enable_tests') From aa554f11667cc236985fa60c378bbf5ef4f3eb49 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 21:08:49 +0200 Subject: [PATCH 0634/1348] [meta] Use Vulkan-Headers repository as a submodule --- .gitmodules | 3 + include/vulkan | 1 + include/vulkan/vk_platform.h | 84 - include/vulkan/vulkan.h | 92 - include/vulkan/vulkan_core.h | 14980 -------------------------------- include/vulkan/vulkan_win32.h | 315 - meson.build | 6 +- 7 files changed, 7 insertions(+), 15474 deletions(-) create mode 160000 include/vulkan delete mode 100644 include/vulkan/vk_platform.h delete mode 100644 include/vulkan/vulkan.h delete mode 100644 include/vulkan/vulkan_core.h delete mode 100644 include/vulkan/vulkan_win32.h diff --git a/.gitmodules b/.gitmodules index 621f8f23a..81d7588ee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "include/native/directx"] path = include/native/directx url = https://github.com/Joshua-Ashton/mingw-directx-headers +[submodule "include/vulkan"] + path = include/vulkan + url = https://github.com/KhronosGroup/Vulkan-Headers diff --git a/include/vulkan b/include/vulkan new file mode 160000 index 000000000..715673702 --- /dev/null +++ b/include/vulkan @@ -0,0 +1 @@ +Subproject commit 715673702f5b18ffb8e5832e67cf731468d32ac6 diff --git a/include/vulkan/vk_platform.h b/include/vulkan/vk_platform.h deleted file mode 100644 index 3ff8c5d14..000000000 --- a/include/vulkan/vk_platform.h +++ /dev/null @@ -1,84 +0,0 @@ -// -// File: vk_platform.h -// -/* -** Copyright 2014-2022 The Khronos Group Inc. -** -** SPDX-License-Identifier: Apache-2.0 -*/ - - -#ifndef VK_PLATFORM_H_ -#define VK_PLATFORM_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif // __cplusplus - -/* -*************************************************************************************************** -* Platform-specific directives and type declarations -*************************************************************************************************** -*/ - -/* Platform-specific calling convention macros. - * - * Platforms should define these so that Vulkan clients call Vulkan commands - * with the same calling conventions that the Vulkan implementation expects. - * - * VKAPI_ATTR - Placed before the return type in function declarations. - * Useful for C++11 and GCC/Clang-style function attribute syntax. - * VKAPI_CALL - Placed after the return type in function declarations. - * Useful for MSVC-style calling convention syntax. - * VKAPI_PTR - Placed between the '(' and '*' in function pointer types. - * - * Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void); - * Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void); - */ -#if defined(_WIN32) - // On Windows, Vulkan commands use the stdcall convention - #define VKAPI_ATTR - #define VKAPI_CALL __stdcall - #define VKAPI_PTR VKAPI_CALL -#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 - #error "Vulkan is not supported for the 'armeabi' NDK ABI" -#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) - // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" - // calling convention, i.e. float parameters are passed in registers. This - // is true even if the rest of the application passes floats on the stack, - // as it does by default when compiling for the armeabi-v7a NDK ABI. - #define VKAPI_ATTR __attribute__((pcs("aapcs-vfp"))) - #define VKAPI_CALL - #define VKAPI_PTR VKAPI_ATTR -#else - // On other platforms, use the default calling convention - #define VKAPI_ATTR - #define VKAPI_CALL - #define VKAPI_PTR -#endif - -#if !defined(VK_NO_STDDEF_H) - #include -#endif // !defined(VK_NO_STDDEF_H) - -#if !defined(VK_NO_STDINT_H) - #if defined(_MSC_VER) && (_MSC_VER < 1600) - typedef signed __int8 int8_t; - typedef unsigned __int8 uint8_t; - typedef signed __int16 int16_t; - typedef unsigned __int16 uint16_t; - typedef signed __int32 int32_t; - typedef unsigned __int32 uint32_t; - typedef signed __int64 int64_t; - typedef unsigned __int64 uint64_t; - #else - #include - #endif -#endif // !defined(VK_NO_STDINT_H) - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - -#endif diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h deleted file mode 100644 index 004fa7095..000000000 --- a/include/vulkan/vulkan.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef VULKAN_H_ -#define VULKAN_H_ 1 - -/* -** Copyright 2015-2022 The Khronos Group Inc. -** -** SPDX-License-Identifier: Apache-2.0 -*/ - -#include "vk_platform.h" -#include "vulkan_core.h" - -#ifdef VK_USE_PLATFORM_ANDROID_KHR -#include "vulkan_android.h" -#endif - -#ifdef VK_USE_PLATFORM_FUCHSIA -#include -#include "vulkan_fuchsia.h" -#endif - -#ifdef VK_USE_PLATFORM_IOS_MVK -#include "vulkan_ios.h" -#endif - - -#ifdef VK_USE_PLATFORM_MACOS_MVK -#include "vulkan_macos.h" -#endif - -#ifdef VK_USE_PLATFORM_METAL_EXT -#include "vulkan_metal.h" -#endif - -#ifdef VK_USE_PLATFORM_VI_NN -#include "vulkan_vi.h" -#endif - - -#ifdef VK_USE_PLATFORM_WAYLAND_KHR -#include -#include "vulkan_wayland.h" -#endif - - -#ifdef VK_USE_PLATFORM_WIN32_KHR -#include -#include "vulkan_win32.h" -#endif - - -#ifdef VK_USE_PLATFORM_XCB_KHR -#include -#include "vulkan_xcb.h" -#endif - - -#ifdef VK_USE_PLATFORM_XLIB_KHR -#include -#include "vulkan_xlib.h" -#endif - - -#ifdef VK_USE_PLATFORM_DIRECTFB_EXT -#include -#include "vulkan_directfb.h" -#endif - - -#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT -#include -#include -#include "vulkan_xlib_xrandr.h" -#endif - - -#ifdef VK_USE_PLATFORM_GGP -#include -#include "vulkan_ggp.h" -#endif - - -#ifdef VK_USE_PLATFORM_SCREEN_QNX -#include -#include "vulkan_screen.h" -#endif - -#ifdef VK_ENABLE_BETA_EXTENSIONS -#include "vulkan_beta.h" -#endif - -#endif // VULKAN_H_ diff --git a/include/vulkan/vulkan_core.h b/include/vulkan/vulkan_core.h deleted file mode 100644 index 9e28ee241..000000000 --- a/include/vulkan/vulkan_core.h +++ /dev/null @@ -1,14980 +0,0 @@ -#ifndef VULKAN_CORE_H_ -#define VULKAN_CORE_H_ 1 - -/* -** Copyright 2015-2022 The Khronos Group Inc. -** -** SPDX-License-Identifier: Apache-2.0 -*/ - -/* -** This header is generated from the Khronos Vulkan XML API Registry. -** -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - - - -#define VK_VERSION_1_0 1 -#include "vk_platform.h" - -#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; - - -#ifndef VK_USE_64_BIT_PTR_DEFINES - #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) - #define VK_USE_64_BIT_PTR_DEFINES 1 - #else - #define VK_USE_64_BIT_PTR_DEFINES 0 - #endif -#endif - - -#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE - #if (VK_USE_64_BIT_PTR_DEFINES==1) - #if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)) - #define VK_NULL_HANDLE nullptr - #else - #define VK_NULL_HANDLE ((void*)0) - #endif - #else - #define VK_NULL_HANDLE 0ULL - #endif -#endif -#ifndef VK_NULL_HANDLE - #define VK_NULL_HANDLE 0 -#endif - - -#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE - #if (VK_USE_64_BIT_PTR_DEFINES==1) - #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; - #else - #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; - #endif -#endif - -// DEPRECATED: This define is deprecated. VK_MAKE_API_VERSION should be used instead. -#define VK_MAKE_VERSION(major, minor, patch) \ - ((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) - -// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead. -//#define VK_API_VERSION VK_MAKE_VERSION(1, 0, 0) // Patch version should always be set to 0 - -#define VK_MAKE_API_VERSION(variant, major, minor, patch) \ - ((((uint32_t)(variant)) << 29) | (((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) - -// Vulkan 1.0 version number -#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 - -// Version of this file -#define VK_HEADER_VERSION 224 - -// Complete version of this file -#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) - -// DEPRECATED: This define is deprecated. VK_API_VERSION_MAJOR should be used instead. -#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22) - -// DEPRECATED: This define is deprecated. VK_API_VERSION_MINOR should be used instead. -#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU) - -// DEPRECATED: This define is deprecated. VK_API_VERSION_PATCH should be used instead. -#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) - -#define VK_API_VERSION_VARIANT(version) ((uint32_t)(version) >> 29) -#define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22) & 0x7FU) -#define VK_API_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3FFU) -#define VK_API_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) -typedef uint32_t VkBool32; -typedef uint64_t VkDeviceAddress; -typedef uint64_t VkDeviceSize; -typedef uint32_t VkFlags; -typedef uint32_t VkSampleMask; -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) -VK_DEFINE_HANDLE(VkInstance) -VK_DEFINE_HANDLE(VkPhysicalDevice) -VK_DEFINE_HANDLE(VkDevice) -VK_DEFINE_HANDLE(VkQueue) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore) -VK_DEFINE_HANDLE(VkCommandBuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) -#define VK_ATTACHMENT_UNUSED (~0U) -#define VK_FALSE 0U -#define VK_LOD_CLAMP_NONE 1000.0F -#define VK_QUEUE_FAMILY_IGNORED (~0U) -#define VK_REMAINING_ARRAY_LAYERS (~0U) -#define VK_REMAINING_MIP_LEVELS (~0U) -#define VK_SUBPASS_EXTERNAL (~0U) -#define VK_TRUE 1U -#define VK_WHOLE_SIZE (~0ULL) -#define VK_MAX_MEMORY_TYPES 32U -#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256U -#define VK_UUID_SIZE 16U -#define VK_MAX_EXTENSION_NAME_SIZE 256U -#define VK_MAX_DESCRIPTION_SIZE 256U -#define VK_MAX_MEMORY_HEAPS 16U - -typedef enum VkResult { - VK_SUCCESS = 0, - VK_NOT_READY = 1, - VK_TIMEOUT = 2, - VK_EVENT_SET = 3, - VK_EVENT_RESET = 4, - VK_INCOMPLETE = 5, - VK_ERROR_OUT_OF_HOST_MEMORY = -1, - VK_ERROR_OUT_OF_DEVICE_MEMORY = -2, - VK_ERROR_INITIALIZATION_FAILED = -3, - VK_ERROR_DEVICE_LOST = -4, - VK_ERROR_MEMORY_MAP_FAILED = -5, - VK_ERROR_LAYER_NOT_PRESENT = -6, - VK_ERROR_EXTENSION_NOT_PRESENT = -7, - VK_ERROR_FEATURE_NOT_PRESENT = -8, - VK_ERROR_INCOMPATIBLE_DRIVER = -9, - VK_ERROR_TOO_MANY_OBJECTS = -10, - VK_ERROR_FORMAT_NOT_SUPPORTED = -11, - VK_ERROR_FRAGMENTED_POOL = -12, - VK_ERROR_UNKNOWN = -13, - VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000, - VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, - VK_ERROR_FRAGMENTATION = -1000161000, - VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, - VK_PIPELINE_COMPILE_REQUIRED = 1000297000, - VK_ERROR_SURFACE_LOST_KHR = -1000000000, - VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, - VK_SUBOPTIMAL_KHR = 1000001003, - VK_ERROR_OUT_OF_DATE_KHR = -1000001004, - VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, - VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, - VK_ERROR_INVALID_SHADER_NV = -1000012000, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR = -1000023000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR = -1000023001, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR = -1000023002, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR = -1000023003, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR = -1000023004, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR = -1000023005, -#endif - VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, - VK_ERROR_NOT_PERMITTED_KHR = -1000174001, - VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, - VK_THREAD_IDLE_KHR = 1000268000, - VK_THREAD_DONE_KHR = 1000268001, - VK_OPERATION_DEFERRED_KHR = 1000268002, - VK_OPERATION_NOT_DEFERRED_KHR = 1000268003, - VK_ERROR_COMPRESSION_EXHAUSTED_EXT = -1000338000, - VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY, - VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE, - VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION, - VK_ERROR_NOT_PERMITTED_EXT = VK_ERROR_NOT_PERMITTED_KHR, - VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - VK_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, - VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, - VK_RESULT_MAX_ENUM = 0x7FFFFFFF -} VkResult; - -typedef enum VkStructureType { - VK_STRUCTURE_TYPE_APPLICATION_INFO = 0, - VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1, - VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2, - VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3, - VK_STRUCTURE_TYPE_SUBMIT_INFO = 4, - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5, - VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6, - VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7, - VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8, - VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9, - VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10, - VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11, - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12, - VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13, - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14, - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15, - VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16, - VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17, - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18, - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19, - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20, - VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21, - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23, - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24, - VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25, - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26, - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27, - VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28, - VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29, - VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30, - VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32, - VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35, - VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36, - VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37, - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38, - VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42, - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45, - VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46, - VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47, - VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000, - VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO = 1000157000, - VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO = 1000157001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000, - VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS = 1000127000, - VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001, - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO = 1000060000, - VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003, - VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004, - VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO = 1000060005, - VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006, - VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013, - VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000, - VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001, - VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002, - VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 = 1000146003, - VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 = 1000059000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001, - VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 = 1000059002, - VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 = 1000059003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2 = 1000059005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006, - VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000, - VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001, - VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002, - VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003, - VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000, - VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO = 1000145000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002, - VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2 = 1000145003, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO = 1000156001, - VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002, - VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005, - VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000, - VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002, - VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES = 1000071003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004, - VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000, - VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001, - VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO = 1000072002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000, - VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES = 1000112001, - VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO = 1000113000, - VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO = 1000077000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000, - VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52, - VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000, - VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000, - VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002, - VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003, - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004, - VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005, - VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, - VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, - VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, - VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, - VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, - VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001, - VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO = 1000207002, - VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003, - VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO = 1000207004, - VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO = 1000207005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000, - VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO = 1000244001, - VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, - VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, - VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES = 53, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES = 54, - VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES = 1000245000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES = 1000295000, - VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO = 1000295001, - VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO = 1000295002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000, - VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 = 1000314000, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 = 1000314001, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 = 1000314002, - VK_STRUCTURE_TYPE_DEPENDENCY_INFO = 1000314003, - VK_STRUCTURE_TYPE_SUBMIT_INFO_2 = 1000314004, - VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO = 1000314005, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO = 1000314006, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES = 1000314007, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000, - VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 = 1000337000, - VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2 = 1000337001, - VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 = 1000337002, - VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2 = 1000337003, - VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 = 1000337004, - VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2 = 1000337005, - VK_STRUCTURE_TYPE_BUFFER_COPY_2 = 1000337006, - VK_STRUCTURE_TYPE_IMAGE_COPY_2 = 1000337007, - VK_STRUCTURE_TYPE_IMAGE_BLIT_2 = 1000337008, - VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 = 1000337009, - VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2 = 1000337010, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES = 1000225000, - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO = 1000225001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES = 1000225002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES = 1000138000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES = 1000138001, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK = 1000138002, - VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO = 1000138003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000, - VK_STRUCTURE_TYPE_RENDERING_INFO = 1000044000, - VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO = 1000044001, - VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO = 1000044002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES = 1000044003, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO = 1000044004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001, - VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 = 1000360000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001, - VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002, - VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003, - VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, - VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, - VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, - VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008, - VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009, - VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010, - VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011, - VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012, - VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR = 1000002000, - VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001, - VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR = 1000003000, - VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000, - VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000, - VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, - VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, - VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, - VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000, - VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000, - VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001, - VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_PROFILE_KHR = 1000023000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR = 1000023001, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_KHR = 1000023002, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_GET_MEMORY_PROPERTIES_KHR = 1000023003, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_BIND_MEMORY_KHR = 1000023004, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR = 1000023005, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000023006, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_UPDATE_INFO_KHR = 1000023007, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR = 1000023008, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR = 1000023009, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR = 1000023010, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_KHR = 1000023011, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_QUEUE_FAMILY_PROPERTIES_2_KHR = 1000023012, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_PROFILES_KHR = 1000023013, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR = 1000023014, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR = 1000023015, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_2_KHR = 1000023016, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR = 1000024000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR = 1000024001, -#endif - VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, - VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, - VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002, - VK_STRUCTURE_TYPE_CU_MODULE_CREATE_INFO_NVX = 1000029000, - VK_STRUCTURE_TYPE_CU_FUNCTION_CREATE_INFO_NVX = 1000029001, - VK_STRUCTURE_TYPE_CU_LAUNCH_INFO_NVX = 1000029002, - VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000, - VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_CAPABILITIES_EXT = 1000038000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000038001, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000038002, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_VCL_FRAME_INFO_EXT = 1000038003, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_EXT = 1000038004, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_EXT = 1000038005, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_EMIT_PICTURE_PARAMETERS_EXT = 1000038006, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_EXT = 1000038007, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_INFO_EXT = 1000038008, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_LAYER_INFO_EXT = 1000038009, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_REFERENCE_LISTS_EXT = 1000038010, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_CAPABILITIES_EXT = 1000039000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000039001, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000039002, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_VCL_FRAME_INFO_EXT = 1000039003, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_EXT = 1000039004, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_NALU_SLICE_SEGMENT_EXT = 1000039005, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_EMIT_PICTURE_PARAMETERS_EXT = 1000039006, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_EXT = 1000039007, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_REFERENCE_LISTS_EXT = 1000039008, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_EXT = 1000039009, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_EXT = 1000039010, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_EXT = 1000040000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_EXT = 1000040001, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_MVC_EXT = 1000040002, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_EXT = 1000040003, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000040004, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_EXT = 1000040005, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_EXT = 1000040006, -#endif - VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, - VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000044006, - VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT = 1000044007, - VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD = 1000044008, - VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_ATTRIBUTES_INFO_NVX = 1000044009, - VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, - VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, - VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001, - VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000, - VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001, - VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, - VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000, - VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000, - VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, - VK_STRUCTURE_TYPE_PIPELINE_ROBUSTNESS_CREATE_INFO_EXT = 1000068000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT = 1000068001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES_EXT = 1000068002, - VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, - VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001, - VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002, - VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003, - VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR = 1000074000, - VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR = 1000074001, - VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR = 1000074002, - VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000, - VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000, - VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001, - VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002, - VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003, - VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000, - VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001, - VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002, - VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000, - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, - VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT = 1000090000, - VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000, - VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT = 1000091001, - VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT = 1000091002, - VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003, - VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000, - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000, - VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, - VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000, - VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000, - VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000, - VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001, - VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002, - VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR = 1000115000, - VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR = 1000115001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR = 1000116000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR = 1000116001, - VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR = 1000116002, - VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR = 1000116003, - VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR = 1000116004, - VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR = 1000116005, - VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_DESCRIPTION_KHR = 1000116006, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000, - VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001, - VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002, - VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR = 1000121000, - VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001, - VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002, - VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR = 1000121003, - VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004, - VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000, - VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, - VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000, - VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT = 1000128001, - VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT = 1000128002, - VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003, - VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004, - VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID = 1000129000, - VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID = 1000129001, - VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID = 1000129002, - VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003, - VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, - VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005, - VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID = 1000129006, - VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000, - VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, - VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003, - VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001, - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, - VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR = 1000150007, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR = 1000150000, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR = 1000150002, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR = 1000150003, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR = 1000150004, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR = 1000150005, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR = 1000150006, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_VERSION_INFO_KHR = 1000150009, - VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR = 1000150010, - VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR = 1000150011, - VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR = 1000150012, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR = 1000150013, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR = 1000150014, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR = 1000150020, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR = 1000347000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR = 1000347001, - VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR = 1000150015, - VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR = 1000150016, - VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR = 1000150018, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR = 1000348013, - VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV = 1000154000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV = 1000154001, - VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002, - VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003, - VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004, - VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005, - VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT = 1000158006, - VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, - VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR = 1000163000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR = 1000163001, -#endif - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002, - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005, - VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001, - VK_STRUCTURE_TYPE_GEOMETRY_NV = 1000165003, - VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV = 1000165004, - VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV = 1000165005, - VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009, - VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV = 1000165012, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000, - VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, - VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, - VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, - VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000, - VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000, - VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_EXT = 1000187000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_EXT = 1000187001, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_EXT = 1000187002, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_EXT = 1000187003, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_EXT = 1000187004, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_EXT = 1000187005, -#endif - VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR = 1000174000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR = 1000388000, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR = 1000388001, - VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002, - VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000, - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002, - VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000, - VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000, - VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001, - VK_STRUCTURE_TYPE_PERFORMANCE_MARKER_INFO_INTEL = 1000210002, - VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003, - VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004, - VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000, - VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000, - VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001, - VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, - VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, - VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, - VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000, - VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR = 1000226003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR = 1000226004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD = 1000227000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD = 1000229000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT = 1000234000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000, - VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001, - VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000, - VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, - VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, - VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV = 1000250000, - VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV = 1000250001, - VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT = 1000254000, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT = 1000254001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT = 1000254002, - VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000, - VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002, - VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001, - VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000, - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT = 1000260000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT = 1000267000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000, - VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR = 1000269001, - VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR = 1000269002, - VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR = 1000269003, - VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, - VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, - VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, - VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, - VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_NV = 1000277003, - VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV = 1000277004, - VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_NV = 1000277005, - VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV = 1000277006, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, - VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000, - VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT = 1000284001, - VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT = 1000284002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001, - VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002, - VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, - VK_STRUCTURE_TYPE_PRESENT_ID_KHR = 1000294000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR = 1000299000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_INFO_KHR = 1000299001, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR = 1000299002, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR = 1000299003, -#endif - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, - VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, - VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECT_CREATE_INFO_EXT = 1000311000, - VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECTS_INFO_EXT = 1000311001, - VK_STRUCTURE_TYPE_EXPORT_METAL_DEVICE_INFO_EXT = 1000311002, - VK_STRUCTURE_TYPE_EXPORT_METAL_COMMAND_QUEUE_INFO_EXT = 1000311003, - VK_STRUCTURE_TYPE_EXPORT_METAL_BUFFER_INFO_EXT = 1000311004, - VK_STRUCTURE_TYPE_IMPORT_METAL_BUFFER_INFO_EXT = 1000311005, - VK_STRUCTURE_TYPE_EXPORT_METAL_TEXTURE_INFO_EXT = 1000311006, - VK_STRUCTURE_TYPE_IMPORT_METAL_TEXTURE_INFO_EXT = 1000311007, - VK_STRUCTURE_TYPE_EXPORT_METAL_IO_SURFACE_INFO_EXT = 1000311008, - VK_STRUCTURE_TYPE_IMPORT_METAL_IO_SURFACE_INFO_EXT = 1000311009, - VK_STRUCTURE_TYPE_EXPORT_METAL_SHARED_EVENT_INFO_EXT = 1000311010, - VK_STRUCTURE_TYPE_IMPORT_METAL_SHARED_EVENT_INFO_EXT = 1000311011, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, - VK_STRUCTURE_TYPE_CHECKPOINT_DATA_2_NV = 1000314009, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT = 1000320000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT = 1000320001, - VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT = 1000320002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD = 1000321000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR = 1000203000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_PROPERTIES_KHR = 1000322000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR = 1000323000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001, - VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_MOTION_TRIANGLES_DATA_NV = 1000327000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV = 1000327001, - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MOTION_INFO_NV = 1000327002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT = 1000330000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001, - VK_STRUCTURE_TYPE_COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR = 1000336000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT = 1000338000, - VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT = 1000338001, - VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_EXT = 1000338002, - VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_EXT = 1000338003, - VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT = 1000338004, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT = 1000339000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM = 1000342000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT = 1000344000, - VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = 1000351000, - VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE = 1000351002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT = 1000352000, - VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001, - VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT = 1000355000, - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT = 1000355001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000, - VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000, - VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001, - VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002, - VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000, - VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001, - VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA = 1000366000, - VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA = 1000366001, - VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA = 1000366002, - VK_STRUCTURE_TYPE_BUFFER_COLLECTION_PROPERTIES_FUCHSIA = 1000366003, - VK_STRUCTURE_TYPE_BUFFER_CONSTRAINTS_INFO_FUCHSIA = 1000366004, - VK_STRUCTURE_TYPE_BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA = 1000366005, - VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA = 1000366006, - VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA = 1000366007, - VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA = 1000366008, - VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA = 1000366009, - VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI = 1000370000, - VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV = 1000371000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001, - VK_STRUCTURE_TYPE_PIPELINE_PROPERTIES_IDENTIFIER_EXT = 1000372000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT = 1000372001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT = 1000376000, - VK_STRUCTURE_TYPE_SUBPASS_RESOLVE_PERFORMANCE_QUERY_EXT = 1000376001, - VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT = 1000376002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000, - VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, - VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT = 1000382000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MAINTENANCE_1_FEATURES_KHR = 1000386000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT = 1000391000, - VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT = 1000391001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT = 1000393000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT = 1000411000, - VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT = 1000411001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE = 1000420000, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_BINDING_REFERENCE_VALVE = 1000420001, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_HOST_MAPPING_INFO_VALVE = 1000420002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT = 1000422000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM = 1000425000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM = 1000425001, - VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM = 1000425002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV = 1000430000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT = 1000437000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM = 1000440000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_PROPERTIES_QCOM = 1000440001, - VK_STRUCTURE_TYPE_IMAGE_VIEW_SAMPLE_WEIGHT_CREATE_INFO_QCOM = 1000440002, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_MERGE_FEEDBACK_FEATURES_EXT = 1000458000, - VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_CONTROL_EXT = 1000458001, - VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000458002, - VK_STRUCTURE_TYPE_RENDER_PASS_SUBPASS_FEEDBACK_CREATE_INFO_EXT = 1000458003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT = 1000462000, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT = 1000462001, - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT = 1000462002, - VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT = 1000462003, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM = 1000484000, - VK_STRUCTURE_TYPE_TILE_PROPERTIES_QCOM = 1000484001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC = 1000485000, - VK_STRUCTURE_TYPE_AMIGO_PROFILING_SUBMIT_INFO_SEC = 1000485001, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, - VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, - VK_STRUCTURE_TYPE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_INFO, - VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO, - VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_NV = VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD, - VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, - VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, - VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, - VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO, - VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO, - VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO, - VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO, - VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO, - VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, - VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES, - VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, - VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO, - VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES, - VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, - VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, - VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, - VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES, - VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, - VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, - VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, - VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, - VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, - VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, - VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, - VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, - VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO, - VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_END_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, - VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES, - VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, - VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, - VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, - VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR, - VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, - VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, - VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES, - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK, - VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, - VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, - VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, - VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2, - VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, - VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, - VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, - VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, - VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, - VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, - VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, - VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, - VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, - VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, - VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, - VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, - VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, - VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES, - VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, - VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT, - VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, - VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES, - VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, - VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, - VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO, - VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, - VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, - VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO, - VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, - VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, - VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, - VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR = VK_STRUCTURE_TYPE_SUBMIT_INFO_2, - VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO, - VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, - VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2, - VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2, - VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2, - VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2, - VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2, - VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2, - VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_COPY_2, - VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_IMAGE_COPY_2, - VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = VK_STRUCTURE_TYPE_IMAGE_BLIT_2, - VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2, - VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, - VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3, - VK_STRUCTURE_TYPE_PIPELINE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, - VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, - VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES, - VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS, - VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS, - VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkStructureType; - -typedef enum VkPipelineCacheHeaderVersion { - VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, - VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCacheHeaderVersion; - -typedef enum VkImageLayout { - VK_IMAGE_LAYOUT_UNDEFINED = 0, - VK_IMAGE_LAYOUT_GENERAL = 1, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, - VK_IMAGE_LAYOUT_PREINITIALIZED = 8, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, - VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, - VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, - VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL = 1000314000, - VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL = 1000314001, - VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR = 1000024000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR = 1000024001, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR = 1000024002, -#endif - VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, - VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, - VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR = 1000164003, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR = 1000299000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR = 1000299001, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR = 1000299002, -#endif - VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT = 1000339000, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, - VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, - VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, - VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL, - VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF -} VkImageLayout; - -typedef enum VkObjectType { - VK_OBJECT_TYPE_UNKNOWN = 0, - VK_OBJECT_TYPE_INSTANCE = 1, - VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2, - VK_OBJECT_TYPE_DEVICE = 3, - VK_OBJECT_TYPE_QUEUE = 4, - VK_OBJECT_TYPE_SEMAPHORE = 5, - VK_OBJECT_TYPE_COMMAND_BUFFER = 6, - VK_OBJECT_TYPE_FENCE = 7, - VK_OBJECT_TYPE_DEVICE_MEMORY = 8, - VK_OBJECT_TYPE_BUFFER = 9, - VK_OBJECT_TYPE_IMAGE = 10, - VK_OBJECT_TYPE_EVENT = 11, - VK_OBJECT_TYPE_QUERY_POOL = 12, - VK_OBJECT_TYPE_BUFFER_VIEW = 13, - VK_OBJECT_TYPE_IMAGE_VIEW = 14, - VK_OBJECT_TYPE_SHADER_MODULE = 15, - VK_OBJECT_TYPE_PIPELINE_CACHE = 16, - VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17, - VK_OBJECT_TYPE_RENDER_PASS = 18, - VK_OBJECT_TYPE_PIPELINE = 19, - VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20, - VK_OBJECT_TYPE_SAMPLER = 21, - VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22, - VK_OBJECT_TYPE_DESCRIPTOR_SET = 23, - VK_OBJECT_TYPE_FRAMEBUFFER = 24, - VK_OBJECT_TYPE_COMMAND_POOL = 25, - VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, - VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, - VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000, - VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, - VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, - VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000, - VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001, - VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_OBJECT_TYPE_VIDEO_SESSION_KHR = 1000023000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR = 1000023001, -#endif - VK_OBJECT_TYPE_CU_MODULE_NVX = 1000029000, - VK_OBJECT_TYPE_CU_FUNCTION_NVX = 1000029001, - VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000, - VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, - VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000, - VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, - VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000, - VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000, - VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV = 1000277000, - VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = 1000366000, - VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, - VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, - VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = VK_OBJECT_TYPE_PRIVATE_DATA_SLOT, - VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkObjectType; - -typedef enum VkVendorId { - VK_VENDOR_ID_VIV = 0x10001, - VK_VENDOR_ID_VSI = 0x10002, - VK_VENDOR_ID_KAZAN = 0x10003, - VK_VENDOR_ID_CODEPLAY = 0x10004, - VK_VENDOR_ID_MESA = 0x10005, - VK_VENDOR_ID_POCL = 0x10006, - VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF -} VkVendorId; - -typedef enum VkSystemAllocationScope { - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1, - VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2, - VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3, - VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4, - VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF -} VkSystemAllocationScope; - -typedef enum VkInternalAllocationType { - VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0, - VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkInternalAllocationType; - -typedef enum VkFormat { - VK_FORMAT_UNDEFINED = 0, - VK_FORMAT_R4G4_UNORM_PACK8 = 1, - VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2, - VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3, - VK_FORMAT_R5G6B5_UNORM_PACK16 = 4, - VK_FORMAT_B5G6R5_UNORM_PACK16 = 5, - VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6, - VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7, - VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8, - VK_FORMAT_R8_UNORM = 9, - VK_FORMAT_R8_SNORM = 10, - VK_FORMAT_R8_USCALED = 11, - VK_FORMAT_R8_SSCALED = 12, - VK_FORMAT_R8_UINT = 13, - VK_FORMAT_R8_SINT = 14, - VK_FORMAT_R8_SRGB = 15, - VK_FORMAT_R8G8_UNORM = 16, - VK_FORMAT_R8G8_SNORM = 17, - VK_FORMAT_R8G8_USCALED = 18, - VK_FORMAT_R8G8_SSCALED = 19, - VK_FORMAT_R8G8_UINT = 20, - VK_FORMAT_R8G8_SINT = 21, - VK_FORMAT_R8G8_SRGB = 22, - VK_FORMAT_R8G8B8_UNORM = 23, - VK_FORMAT_R8G8B8_SNORM = 24, - VK_FORMAT_R8G8B8_USCALED = 25, - VK_FORMAT_R8G8B8_SSCALED = 26, - VK_FORMAT_R8G8B8_UINT = 27, - VK_FORMAT_R8G8B8_SINT = 28, - VK_FORMAT_R8G8B8_SRGB = 29, - VK_FORMAT_B8G8R8_UNORM = 30, - VK_FORMAT_B8G8R8_SNORM = 31, - VK_FORMAT_B8G8R8_USCALED = 32, - VK_FORMAT_B8G8R8_SSCALED = 33, - VK_FORMAT_B8G8R8_UINT = 34, - VK_FORMAT_B8G8R8_SINT = 35, - VK_FORMAT_B8G8R8_SRGB = 36, - VK_FORMAT_R8G8B8A8_UNORM = 37, - VK_FORMAT_R8G8B8A8_SNORM = 38, - VK_FORMAT_R8G8B8A8_USCALED = 39, - VK_FORMAT_R8G8B8A8_SSCALED = 40, - VK_FORMAT_R8G8B8A8_UINT = 41, - VK_FORMAT_R8G8B8A8_SINT = 42, - VK_FORMAT_R8G8B8A8_SRGB = 43, - VK_FORMAT_B8G8R8A8_UNORM = 44, - VK_FORMAT_B8G8R8A8_SNORM = 45, - VK_FORMAT_B8G8R8A8_USCALED = 46, - VK_FORMAT_B8G8R8A8_SSCALED = 47, - VK_FORMAT_B8G8R8A8_UINT = 48, - VK_FORMAT_B8G8R8A8_SINT = 49, - VK_FORMAT_B8G8R8A8_SRGB = 50, - VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51, - VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52, - VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53, - VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54, - VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55, - VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56, - VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57, - VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58, - VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59, - VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60, - VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61, - VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62, - VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63, - VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64, - VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65, - VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66, - VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67, - VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68, - VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69, - VK_FORMAT_R16_UNORM = 70, - VK_FORMAT_R16_SNORM = 71, - VK_FORMAT_R16_USCALED = 72, - VK_FORMAT_R16_SSCALED = 73, - VK_FORMAT_R16_UINT = 74, - VK_FORMAT_R16_SINT = 75, - VK_FORMAT_R16_SFLOAT = 76, - VK_FORMAT_R16G16_UNORM = 77, - VK_FORMAT_R16G16_SNORM = 78, - VK_FORMAT_R16G16_USCALED = 79, - VK_FORMAT_R16G16_SSCALED = 80, - VK_FORMAT_R16G16_UINT = 81, - VK_FORMAT_R16G16_SINT = 82, - VK_FORMAT_R16G16_SFLOAT = 83, - VK_FORMAT_R16G16B16_UNORM = 84, - VK_FORMAT_R16G16B16_SNORM = 85, - VK_FORMAT_R16G16B16_USCALED = 86, - VK_FORMAT_R16G16B16_SSCALED = 87, - VK_FORMAT_R16G16B16_UINT = 88, - VK_FORMAT_R16G16B16_SINT = 89, - VK_FORMAT_R16G16B16_SFLOAT = 90, - VK_FORMAT_R16G16B16A16_UNORM = 91, - VK_FORMAT_R16G16B16A16_SNORM = 92, - VK_FORMAT_R16G16B16A16_USCALED = 93, - VK_FORMAT_R16G16B16A16_SSCALED = 94, - VK_FORMAT_R16G16B16A16_UINT = 95, - VK_FORMAT_R16G16B16A16_SINT = 96, - VK_FORMAT_R16G16B16A16_SFLOAT = 97, - VK_FORMAT_R32_UINT = 98, - VK_FORMAT_R32_SINT = 99, - VK_FORMAT_R32_SFLOAT = 100, - VK_FORMAT_R32G32_UINT = 101, - VK_FORMAT_R32G32_SINT = 102, - VK_FORMAT_R32G32_SFLOAT = 103, - VK_FORMAT_R32G32B32_UINT = 104, - VK_FORMAT_R32G32B32_SINT = 105, - VK_FORMAT_R32G32B32_SFLOAT = 106, - VK_FORMAT_R32G32B32A32_UINT = 107, - VK_FORMAT_R32G32B32A32_SINT = 108, - VK_FORMAT_R32G32B32A32_SFLOAT = 109, - VK_FORMAT_R64_UINT = 110, - VK_FORMAT_R64_SINT = 111, - VK_FORMAT_R64_SFLOAT = 112, - VK_FORMAT_R64G64_UINT = 113, - VK_FORMAT_R64G64_SINT = 114, - VK_FORMAT_R64G64_SFLOAT = 115, - VK_FORMAT_R64G64B64_UINT = 116, - VK_FORMAT_R64G64B64_SINT = 117, - VK_FORMAT_R64G64B64_SFLOAT = 118, - VK_FORMAT_R64G64B64A64_UINT = 119, - VK_FORMAT_R64G64B64A64_SINT = 120, - VK_FORMAT_R64G64B64A64_SFLOAT = 121, - VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122, - VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123, - VK_FORMAT_D16_UNORM = 124, - VK_FORMAT_X8_D24_UNORM_PACK32 = 125, - VK_FORMAT_D32_SFLOAT = 126, - VK_FORMAT_S8_UINT = 127, - VK_FORMAT_D16_UNORM_S8_UINT = 128, - VK_FORMAT_D24_UNORM_S8_UINT = 129, - VK_FORMAT_D32_SFLOAT_S8_UINT = 130, - VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131, - VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132, - VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133, - VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134, - VK_FORMAT_BC2_UNORM_BLOCK = 135, - VK_FORMAT_BC2_SRGB_BLOCK = 136, - VK_FORMAT_BC3_UNORM_BLOCK = 137, - VK_FORMAT_BC3_SRGB_BLOCK = 138, - VK_FORMAT_BC4_UNORM_BLOCK = 139, - VK_FORMAT_BC4_SNORM_BLOCK = 140, - VK_FORMAT_BC5_UNORM_BLOCK = 141, - VK_FORMAT_BC5_SNORM_BLOCK = 142, - VK_FORMAT_BC6H_UFLOAT_BLOCK = 143, - VK_FORMAT_BC6H_SFLOAT_BLOCK = 144, - VK_FORMAT_BC7_UNORM_BLOCK = 145, - VK_FORMAT_BC7_SRGB_BLOCK = 146, - VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147, - VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148, - VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149, - VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150, - VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151, - VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152, - VK_FORMAT_EAC_R11_UNORM_BLOCK = 153, - VK_FORMAT_EAC_R11_SNORM_BLOCK = 154, - VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155, - VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156, - VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157, - VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158, - VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159, - VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160, - VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161, - VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162, - VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163, - VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164, - VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165, - VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166, - VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167, - VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168, - VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169, - VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170, - VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171, - VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172, - VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173, - VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174, - VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175, - VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176, - VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177, - VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178, - VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179, - VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180, - VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181, - VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182, - VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183, - VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184, - VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000, - VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001, - VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002, - VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003, - VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004, - VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005, - VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006, - VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007, - VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008, - VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009, - VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010, - VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016, - VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017, - VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018, - VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019, - VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020, - VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026, - VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027, - VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028, - VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029, - VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030, - VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031, - VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032, - VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033, - VK_FORMAT_G8_B8R8_2PLANE_444_UNORM = 1000330000, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002, - VK_FORMAT_G16_B16R16_2PLANE_444_UNORM = 1000330003, - VK_FORMAT_A4R4G4B4_UNORM_PACK16 = 1000340000, - VK_FORMAT_A4B4G4R4_UNORM_PACK16 = 1000340001, - VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK = 1000066000, - VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK = 1000066001, - VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK = 1000066002, - VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK = 1000066003, - VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK = 1000066004, - VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK = 1000066005, - VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK = 1000066006, - VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK = 1000066007, - VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK = 1000066008, - VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK = 1000066009, - VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK = 1000066010, - VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011, - VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012, - VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013, - VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000, - VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001, - VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002, - VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003, - VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004, - VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, - VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, - VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, - VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK, - VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK, - VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK, - VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK, - VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK, - VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK, - VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK, - VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK, - VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK, - VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK, - VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK, - VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK, - VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK, - VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK, - VK_FORMAT_G8B8G8R8_422_UNORM_KHR = VK_FORMAT_G8B8G8R8_422_UNORM, - VK_FORMAT_B8G8R8G8_422_UNORM_KHR = VK_FORMAT_B8G8R8G8_422_UNORM, - VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, - VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, - VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, - VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM, - VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM, - VK_FORMAT_R10X6_UNORM_PACK16_KHR = VK_FORMAT_R10X6_UNORM_PACK16, - VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR = VK_FORMAT_R10X6G10X6_UNORM_2PACK16, - VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR = VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, - VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, - VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, - VK_FORMAT_R12X4_UNORM_PACK16_KHR = VK_FORMAT_R12X4_UNORM_PACK16, - VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR = VK_FORMAT_R12X4G12X4_UNORM_2PACK16, - VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR = VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16, - VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, - VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, - VK_FORMAT_G16B16G16R16_422_UNORM_KHR = VK_FORMAT_G16B16G16R16_422_UNORM, - VK_FORMAT_B16G16R16G16_422_UNORM_KHR = VK_FORMAT_B16G16R16G16_422_UNORM, - VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, - VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, - VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, - VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, - VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, - VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, - VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM, - VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = VK_FORMAT_A4R4G4B4_UNORM_PACK16, - VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = VK_FORMAT_A4B4G4R4_UNORM_PACK16, - VK_FORMAT_MAX_ENUM = 0x7FFFFFFF -} VkFormat; - -typedef enum VkImageTiling { - VK_IMAGE_TILING_OPTIMAL = 0, - VK_IMAGE_TILING_LINEAR = 1, - VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT = 1000158000, - VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF -} VkImageTiling; - -typedef enum VkImageType { - VK_IMAGE_TYPE_1D = 0, - VK_IMAGE_TYPE_2D = 1, - VK_IMAGE_TYPE_3D = 2, - VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkImageType; - -typedef enum VkPhysicalDeviceType { - VK_PHYSICAL_DEVICE_TYPE_OTHER = 0, - VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1, - VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2, - VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3, - VK_PHYSICAL_DEVICE_TYPE_CPU = 4, - VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkPhysicalDeviceType; - -typedef enum VkQueryType { - VK_QUERY_TYPE_OCCLUSION = 0, - VK_QUERY_TYPE_PIPELINE_STATISTICS = 1, - VK_QUERY_TYPE_TIMESTAMP = 2, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR = 1000023000, -#endif - VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT = 1000028004, - VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR = 1000116000, - VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR = 1000150000, - VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR = 1000150001, - VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000, - VK_QUERY_TYPE_PERFORMANCE_QUERY_INTEL = 1000210000, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_QUERY_TYPE_VIDEO_ENCODE_BITSTREAM_BUFFER_RANGE_KHR = 1000299000, -#endif - VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT = 1000382000, - VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR = 1000386000, - VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR = 1000386001, - VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkQueryType; - -typedef enum VkSharingMode { - VK_SHARING_MODE_EXCLUSIVE = 0, - VK_SHARING_MODE_CONCURRENT = 1, - VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSharingMode; - -typedef enum VkComponentSwizzle { - VK_COMPONENT_SWIZZLE_IDENTITY = 0, - VK_COMPONENT_SWIZZLE_ZERO = 1, - VK_COMPONENT_SWIZZLE_ONE = 2, - VK_COMPONENT_SWIZZLE_R = 3, - VK_COMPONENT_SWIZZLE_G = 4, - VK_COMPONENT_SWIZZLE_B = 5, - VK_COMPONENT_SWIZZLE_A = 6, - VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF -} VkComponentSwizzle; - -typedef enum VkImageViewType { - VK_IMAGE_VIEW_TYPE_1D = 0, - VK_IMAGE_VIEW_TYPE_2D = 1, - VK_IMAGE_VIEW_TYPE_3D = 2, - VK_IMAGE_VIEW_TYPE_CUBE = 3, - VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, - VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, - VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, - VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkImageViewType; - -typedef enum VkBlendFactor { - VK_BLEND_FACTOR_ZERO = 0, - VK_BLEND_FACTOR_ONE = 1, - VK_BLEND_FACTOR_SRC_COLOR = 2, - VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3, - VK_BLEND_FACTOR_DST_COLOR = 4, - VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5, - VK_BLEND_FACTOR_SRC_ALPHA = 6, - VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7, - VK_BLEND_FACTOR_DST_ALPHA = 8, - VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9, - VK_BLEND_FACTOR_CONSTANT_COLOR = 10, - VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11, - VK_BLEND_FACTOR_CONSTANT_ALPHA = 12, - VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13, - VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14, - VK_BLEND_FACTOR_SRC1_COLOR = 15, - VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, - VK_BLEND_FACTOR_SRC1_ALPHA = 17, - VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, - VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF -} VkBlendFactor; - -typedef enum VkBlendOp { - VK_BLEND_OP_ADD = 0, - VK_BLEND_OP_SUBTRACT = 1, - VK_BLEND_OP_REVERSE_SUBTRACT = 2, - VK_BLEND_OP_MIN = 3, - VK_BLEND_OP_MAX = 4, - VK_BLEND_OP_ZERO_EXT = 1000148000, - VK_BLEND_OP_SRC_EXT = 1000148001, - VK_BLEND_OP_DST_EXT = 1000148002, - VK_BLEND_OP_SRC_OVER_EXT = 1000148003, - VK_BLEND_OP_DST_OVER_EXT = 1000148004, - VK_BLEND_OP_SRC_IN_EXT = 1000148005, - VK_BLEND_OP_DST_IN_EXT = 1000148006, - VK_BLEND_OP_SRC_OUT_EXT = 1000148007, - VK_BLEND_OP_DST_OUT_EXT = 1000148008, - VK_BLEND_OP_SRC_ATOP_EXT = 1000148009, - VK_BLEND_OP_DST_ATOP_EXT = 1000148010, - VK_BLEND_OP_XOR_EXT = 1000148011, - VK_BLEND_OP_MULTIPLY_EXT = 1000148012, - VK_BLEND_OP_SCREEN_EXT = 1000148013, - VK_BLEND_OP_OVERLAY_EXT = 1000148014, - VK_BLEND_OP_DARKEN_EXT = 1000148015, - VK_BLEND_OP_LIGHTEN_EXT = 1000148016, - VK_BLEND_OP_COLORDODGE_EXT = 1000148017, - VK_BLEND_OP_COLORBURN_EXT = 1000148018, - VK_BLEND_OP_HARDLIGHT_EXT = 1000148019, - VK_BLEND_OP_SOFTLIGHT_EXT = 1000148020, - VK_BLEND_OP_DIFFERENCE_EXT = 1000148021, - VK_BLEND_OP_EXCLUSION_EXT = 1000148022, - VK_BLEND_OP_INVERT_EXT = 1000148023, - VK_BLEND_OP_INVERT_RGB_EXT = 1000148024, - VK_BLEND_OP_LINEARDODGE_EXT = 1000148025, - VK_BLEND_OP_LINEARBURN_EXT = 1000148026, - VK_BLEND_OP_VIVIDLIGHT_EXT = 1000148027, - VK_BLEND_OP_LINEARLIGHT_EXT = 1000148028, - VK_BLEND_OP_PINLIGHT_EXT = 1000148029, - VK_BLEND_OP_HARDMIX_EXT = 1000148030, - VK_BLEND_OP_HSL_HUE_EXT = 1000148031, - VK_BLEND_OP_HSL_SATURATION_EXT = 1000148032, - VK_BLEND_OP_HSL_COLOR_EXT = 1000148033, - VK_BLEND_OP_HSL_LUMINOSITY_EXT = 1000148034, - VK_BLEND_OP_PLUS_EXT = 1000148035, - VK_BLEND_OP_PLUS_CLAMPED_EXT = 1000148036, - VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT = 1000148037, - VK_BLEND_OP_PLUS_DARKER_EXT = 1000148038, - VK_BLEND_OP_MINUS_EXT = 1000148039, - VK_BLEND_OP_MINUS_CLAMPED_EXT = 1000148040, - VK_BLEND_OP_CONTRAST_EXT = 1000148041, - VK_BLEND_OP_INVERT_OVG_EXT = 1000148042, - VK_BLEND_OP_RED_EXT = 1000148043, - VK_BLEND_OP_GREEN_EXT = 1000148044, - VK_BLEND_OP_BLUE_EXT = 1000148045, - VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF -} VkBlendOp; - -typedef enum VkCompareOp { - VK_COMPARE_OP_NEVER = 0, - VK_COMPARE_OP_LESS = 1, - VK_COMPARE_OP_EQUAL = 2, - VK_COMPARE_OP_LESS_OR_EQUAL = 3, - VK_COMPARE_OP_GREATER = 4, - VK_COMPARE_OP_NOT_EQUAL = 5, - VK_COMPARE_OP_GREATER_OR_EQUAL = 6, - VK_COMPARE_OP_ALWAYS = 7, - VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF -} VkCompareOp; - -typedef enum VkDynamicState { - VK_DYNAMIC_STATE_VIEWPORT = 0, - VK_DYNAMIC_STATE_SCISSOR = 1, - VK_DYNAMIC_STATE_LINE_WIDTH = 2, - VK_DYNAMIC_STATE_DEPTH_BIAS = 3, - VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4, - VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5, - VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, - VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, - VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, - VK_DYNAMIC_STATE_CULL_MODE = 1000267000, - VK_DYNAMIC_STATE_FRONT_FACE = 1000267001, - VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = 1000267002, - VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT = 1000267003, - VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT = 1000267004, - VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE = 1000267005, - VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE = 1000267006, - VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE = 1000267007, - VK_DYNAMIC_STATE_DEPTH_COMPARE_OP = 1000267008, - VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE = 1000267009, - VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE = 1000267010, - VK_DYNAMIC_STATE_STENCIL_OP = 1000267011, - VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE = 1000377001, - VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE = 1000377002, - VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004, - VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000, - VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000, - VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000, - VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR = 1000347000, - VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1000164004, - VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006, - VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001, - VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR = 1000226000, - VK_DYNAMIC_STATE_LINE_STIPPLE_EXT = 1000259000, - VK_DYNAMIC_STATE_VERTEX_INPUT_EXT = 1000352000, - VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT = 1000377000, - VK_DYNAMIC_STATE_LOGIC_OP_EXT = 1000377003, - VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT = 1000381000, - VK_DYNAMIC_STATE_CULL_MODE_EXT = VK_DYNAMIC_STATE_CULL_MODE, - VK_DYNAMIC_STATE_FRONT_FACE_EXT = VK_DYNAMIC_STATE_FRONT_FACE, - VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY, - VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, - VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, - VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE, - VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE, - VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE, - VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP, - VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE, - VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE, - VK_DYNAMIC_STATE_STENCIL_OP_EXT = VK_DYNAMIC_STATE_STENCIL_OP, - VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE, - VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE, - VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE, - VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF -} VkDynamicState; - -typedef enum VkFrontFace { - VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, - VK_FRONT_FACE_CLOCKWISE = 1, - VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF -} VkFrontFace; - -typedef enum VkVertexInputRate { - VK_VERTEX_INPUT_RATE_VERTEX = 0, - VK_VERTEX_INPUT_RATE_INSTANCE = 1, - VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF -} VkVertexInputRate; - -typedef enum VkPrimitiveTopology { - VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, - VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1, - VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5, - VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6, - VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, - VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, - VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF -} VkPrimitiveTopology; - -typedef enum VkPolygonMode { - VK_POLYGON_MODE_FILL = 0, - VK_POLYGON_MODE_LINE = 1, - VK_POLYGON_MODE_POINT = 2, - VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000, - VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF -} VkPolygonMode; - -typedef enum VkStencilOp { - VK_STENCIL_OP_KEEP = 0, - VK_STENCIL_OP_ZERO = 1, - VK_STENCIL_OP_REPLACE = 2, - VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3, - VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4, - VK_STENCIL_OP_INVERT = 5, - VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, - VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, - VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF -} VkStencilOp; - -typedef enum VkLogicOp { - VK_LOGIC_OP_CLEAR = 0, - VK_LOGIC_OP_AND = 1, - VK_LOGIC_OP_AND_REVERSE = 2, - VK_LOGIC_OP_COPY = 3, - VK_LOGIC_OP_AND_INVERTED = 4, - VK_LOGIC_OP_NO_OP = 5, - VK_LOGIC_OP_XOR = 6, - VK_LOGIC_OP_OR = 7, - VK_LOGIC_OP_NOR = 8, - VK_LOGIC_OP_EQUIVALENT = 9, - VK_LOGIC_OP_INVERT = 10, - VK_LOGIC_OP_OR_REVERSE = 11, - VK_LOGIC_OP_COPY_INVERTED = 12, - VK_LOGIC_OP_OR_INVERTED = 13, - VK_LOGIC_OP_NAND = 14, - VK_LOGIC_OP_SET = 15, - VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF -} VkLogicOp; - -typedef enum VkBorderColor { - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0, - VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1, - VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2, - VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3, - VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, - VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5, - VK_BORDER_COLOR_FLOAT_CUSTOM_EXT = 1000287003, - VK_BORDER_COLOR_INT_CUSTOM_EXT = 1000287004, - VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF -} VkBorderColor; - -typedef enum VkFilter { - VK_FILTER_NEAREST = 0, - VK_FILTER_LINEAR = 1, - VK_FILTER_CUBIC_EXT = 1000015000, - VK_FILTER_CUBIC_IMG = VK_FILTER_CUBIC_EXT, - VK_FILTER_MAX_ENUM = 0x7FFFFFFF -} VkFilter; - -typedef enum VkSamplerAddressMode { - VK_SAMPLER_ADDRESS_MODE_REPEAT = 0, - VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, - VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, - VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE_KHR = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, - VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerAddressMode; - -typedef enum VkSamplerMipmapMode { - VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, - VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, - VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerMipmapMode; - -typedef enum VkDescriptorType { - VK_DESCRIPTOR_TYPE_SAMPLER = 0, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, - VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, - VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, - VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, - VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, - VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, - VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK = 1000138000, - VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, - VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, - VK_DESCRIPTOR_TYPE_MUTABLE_VALVE = 1000351000, - VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM = 1000440000, - VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM = 1000440001, - VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, - VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorType; - -typedef enum VkAttachmentLoadOp { - VK_ATTACHMENT_LOAD_OP_LOAD = 0, - VK_ATTACHMENT_LOAD_OP_CLEAR = 1, - VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, - VK_ATTACHMENT_LOAD_OP_NONE_EXT = 1000400000, - VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF -} VkAttachmentLoadOp; - -typedef enum VkAttachmentStoreOp { - VK_ATTACHMENT_STORE_OP_STORE = 0, - VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, - VK_ATTACHMENT_STORE_OP_NONE = 1000301000, - VK_ATTACHMENT_STORE_OP_NONE_KHR = VK_ATTACHMENT_STORE_OP_NONE, - VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE, - VK_ATTACHMENT_STORE_OP_NONE_EXT = VK_ATTACHMENT_STORE_OP_NONE, - VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF -} VkAttachmentStoreOp; - -typedef enum VkPipelineBindPoint { - VK_PIPELINE_BIND_POINT_GRAPHICS = 0, - VK_PIPELINE_BIND_POINT_COMPUTE = 1, - VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR = 1000165000, - VK_PIPELINE_BIND_POINT_SUBPASS_SHADING_HUAWEI = 1000369003, - VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, - VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF -} VkPipelineBindPoint; - -typedef enum VkCommandBufferLevel { - VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, - VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1, - VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferLevel; - -typedef enum VkIndexType { - VK_INDEX_TYPE_UINT16 = 0, - VK_INDEX_TYPE_UINT32 = 1, - VK_INDEX_TYPE_NONE_KHR = 1000165000, - VK_INDEX_TYPE_UINT8_EXT = 1000265000, - VK_INDEX_TYPE_NONE_NV = VK_INDEX_TYPE_NONE_KHR, - VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkIndexType; - -typedef enum VkSubpassContents { - VK_SUBPASS_CONTENTS_INLINE = 0, - VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, - VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF -} VkSubpassContents; - -typedef enum VkAccessFlagBits { - VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001, - VK_ACCESS_INDEX_READ_BIT = 0x00000002, - VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004, - VK_ACCESS_UNIFORM_READ_BIT = 0x00000008, - VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010, - VK_ACCESS_SHADER_READ_BIT = 0x00000020, - VK_ACCESS_SHADER_WRITE_BIT = 0x00000040, - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200, - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400, - VK_ACCESS_TRANSFER_READ_BIT = 0x00000800, - VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000, - VK_ACCESS_HOST_READ_BIT = 0x00002000, - VK_ACCESS_HOST_WRITE_BIT = 0x00004000, - VK_ACCESS_MEMORY_READ_BIT = 0x00008000, - VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, - VK_ACCESS_NONE = 0, - VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, - VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, - VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, - VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000, - VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000, - VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000, - VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000, - VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000, - VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000, - VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000, - VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000, - VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR, - VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, - VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, - VK_ACCESS_NONE_KHR = VK_ACCESS_NONE, - VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkAccessFlagBits; -typedef VkFlags VkAccessFlags; - -typedef enum VkImageAspectFlagBits { - VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001, - VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002, - VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004, - VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008, - VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, - VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, - VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, - VK_IMAGE_ASPECT_NONE = 0, - VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080, - VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100, - VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200, - VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT = 0x00000400, - VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT, - VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT, - VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT, - VK_IMAGE_ASPECT_NONE_KHR = VK_IMAGE_ASPECT_NONE, - VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageAspectFlagBits; -typedef VkFlags VkImageAspectFlags; - -typedef enum VkFormatFeatureFlagBits { - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001, - VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 0x00000002, - VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004, - VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008, - VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 0x00000010, - VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020, - VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 0x00000040, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 0x00000080, - VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200, - VK_FORMAT_FEATURE_BLIT_SRC_BIT = 0x00000400, - VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000, - VK_FORMAT_FEATURE_TRANSFER_SRC_BIT = 0x00004000, - VK_FORMAT_FEATURE_TRANSFER_DST_BIT = 0x00008000, - VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000, - VK_FORMAT_FEATURE_DISJOINT_BIT = 0x00400000, - VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_FORMAT_FEATURE_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_FORMAT_FEATURE_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000, -#endif - VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000, - VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000, - VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_FORMAT_FEATURE_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_FORMAT_FEATURE_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000, -#endif - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT, - VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, - VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, - VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, - VK_FORMAT_FEATURE_DISJOINT_BIT_KHR = VK_FORMAT_FEATURE_DISJOINT_BIT, - VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, - VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkFormatFeatureFlagBits; -typedef VkFlags VkFormatFeatureFlags; - -typedef enum VkImageCreateFlagBits { - VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001, - VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, - VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004, - VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008, - VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010, - VK_IMAGE_CREATE_ALIAS_BIT = 0x00000400, - VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT = 0x00000040, - VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT = 0x00000020, - VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT = 0x00000080, - VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 0x00000100, - VK_IMAGE_CREATE_PROTECTED_BIT = 0x00000800, - VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200, - VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000, - VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, - VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000, - VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT = 0x00040000, - VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT = 0x00020000, - VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM = 0x00008000, - VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, - VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, - VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, - VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, - VK_IMAGE_CREATE_DISJOINT_BIT_KHR = VK_IMAGE_CREATE_DISJOINT_BIT, - VK_IMAGE_CREATE_ALIAS_BIT_KHR = VK_IMAGE_CREATE_ALIAS_BIT, - VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageCreateFlagBits; -typedef VkFlags VkImageCreateFlags; - -typedef enum VkSampleCountFlagBits { - VK_SAMPLE_COUNT_1_BIT = 0x00000001, - VK_SAMPLE_COUNT_2_BIT = 0x00000002, - VK_SAMPLE_COUNT_4_BIT = 0x00000004, - VK_SAMPLE_COUNT_8_BIT = 0x00000008, - VK_SAMPLE_COUNT_16_BIT = 0x00000010, - VK_SAMPLE_COUNT_32_BIT = 0x00000020, - VK_SAMPLE_COUNT_64_BIT = 0x00000040, - VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSampleCountFlagBits; -typedef VkFlags VkSampleCountFlags; - -typedef enum VkImageUsageFlagBits { - VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001, - VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002, - VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004, - VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, - VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR = 0x00000400, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR = 0x00000800, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR = 0x00001000, -#endif - VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200, - VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00000100, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR = 0x00002000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR = 0x00004000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR = 0x00008000, -#endif - VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x00080000, - VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI = 0x00040000, - VK_IMAGE_USAGE_SAMPLE_WEIGHT_BIT_QCOM = 0x00100000, - VK_IMAGE_USAGE_SAMPLE_BLOCK_MATCH_BIT_QCOM = 0x00200000, - VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, - VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageUsageFlagBits; -typedef VkFlags VkImageUsageFlags; - -typedef enum VkInstanceCreateFlagBits { - VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR = 0x00000001, - VK_INSTANCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkInstanceCreateFlagBits; -typedef VkFlags VkInstanceCreateFlags; - -typedef enum VkMemoryHeapFlagBits { - VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001, - VK_MEMORY_HEAP_MULTI_INSTANCE_BIT = 0x00000002, - VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHR = VK_MEMORY_HEAP_MULTI_INSTANCE_BIT, - VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkMemoryHeapFlagBits; -typedef VkFlags VkMemoryHeapFlags; - -typedef enum VkMemoryPropertyFlagBits { - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002, - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004, - VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008, - VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010, - VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020, - VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD = 0x00000040, - VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD = 0x00000080, - VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV = 0x00000100, - VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkMemoryPropertyFlagBits; -typedef VkFlags VkMemoryPropertyFlags; - -typedef enum VkQueueFlagBits { - VK_QUEUE_GRAPHICS_BIT = 0x00000001, - VK_QUEUE_COMPUTE_BIT = 0x00000002, - VK_QUEUE_TRANSFER_BIT = 0x00000004, - VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008, - VK_QUEUE_PROTECTED_BIT = 0x00000010, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_QUEUE_VIDEO_DECODE_BIT_KHR = 0x00000020, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_QUEUE_VIDEO_ENCODE_BIT_KHR = 0x00000040, -#endif - VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueueFlagBits; -typedef VkFlags VkQueueFlags; -typedef VkFlags VkDeviceCreateFlags; - -typedef enum VkDeviceQueueCreateFlagBits { - VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 0x00000001, - VK_DEVICE_QUEUE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDeviceQueueCreateFlagBits; -typedef VkFlags VkDeviceQueueCreateFlags; - -typedef enum VkPipelineStageFlagBits { - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001, - VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002, - VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004, - VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008, - VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010, - VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020, - VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080, - VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100, - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800, - VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000, - VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, - VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, - VK_PIPELINE_STAGE_NONE = 0, - VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000, - VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000, - VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000, - VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR = 0x00200000, - VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = 0x00080000, - VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = 0x00100000, - VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, - VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000, - VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = 0x00020000, - VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, - VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, - VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, - VK_PIPELINE_STAGE_NONE_KHR = VK_PIPELINE_STAGE_NONE, - VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineStageFlagBits; -typedef VkFlags VkPipelineStageFlags; -typedef VkFlags VkMemoryMapFlags; - -typedef enum VkSparseMemoryBindFlagBits { - VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, - VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSparseMemoryBindFlagBits; -typedef VkFlags VkSparseMemoryBindFlags; - -typedef enum VkSparseImageFormatFlagBits { - VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001, - VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 0x00000002, - VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 0x00000004, - VK_SPARSE_IMAGE_FORMAT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSparseImageFormatFlagBits; -typedef VkFlags VkSparseImageFormatFlags; - -typedef enum VkFenceCreateFlagBits { - VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001, - VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkFenceCreateFlagBits; -typedef VkFlags VkFenceCreateFlags; -typedef VkFlags VkSemaphoreCreateFlags; - -typedef enum VkEventCreateFlagBits { - VK_EVENT_CREATE_DEVICE_ONLY_BIT = 0x00000001, - VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = VK_EVENT_CREATE_DEVICE_ONLY_BIT, - VK_EVENT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkEventCreateFlagBits; -typedef VkFlags VkEventCreateFlags; - -typedef enum VkQueryPipelineStatisticFlagBits { - VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 0x00000001, - VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT = 0x00000002, - VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT = 0x00000004, - VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT = 0x00000008, - VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT = 0x00000010, - VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT = 0x00000020, - VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT = 0x00000040, - VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 0x00000080, - VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 0x00000100, - VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 0x00000200, - VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 0x00000400, - VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueryPipelineStatisticFlagBits; -typedef VkFlags VkQueryPipelineStatisticFlags; -typedef VkFlags VkQueryPoolCreateFlags; - -typedef enum VkQueryResultFlagBits { - VK_QUERY_RESULT_64_BIT = 0x00000001, - VK_QUERY_RESULT_WAIT_BIT = 0x00000002, - VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 0x00000004, - VK_QUERY_RESULT_PARTIAL_BIT = 0x00000008, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_QUERY_RESULT_WITH_STATUS_BIT_KHR = 0x00000010, -#endif - VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueryResultFlagBits; -typedef VkFlags VkQueryResultFlags; - -typedef enum VkBufferCreateFlagBits { - VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 0x00000001, - VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, - VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004, - VK_BUFFER_CREATE_PROTECTED_BIT = 0x00000008, - VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000010, - VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, - VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, - VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkBufferCreateFlagBits; -typedef VkFlags VkBufferCreateFlags; - -typedef enum VkBufferUsageFlagBits { - VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 0x00000001, - VK_BUFFER_USAGE_TRANSFER_DST_BIT = 0x00000002, - VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004, - VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 0x00000008, - VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 0x00000010, - VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020, - VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040, - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080, - VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100, - VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT = 0x00020000, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR = 0x00002000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR = 0x00004000, -#endif - VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800, - VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000, - VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200, - VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR = 0x00080000, - VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR = 0x00100000, - VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR = 0x00000400, -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR = 0x00008000, -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS - VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR = 0x00010000, -#endif - VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR, - VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, - VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, - VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkBufferUsageFlagBits; -typedef VkFlags VkBufferUsageFlags; -typedef VkFlags VkBufferViewCreateFlags; - -typedef enum VkImageViewCreateFlagBits { - VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT = 0x00000001, - VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DEFERRED_BIT_EXT = 0x00000002, - VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkImageViewCreateFlagBits; -typedef VkFlags VkImageViewCreateFlags; -typedef VkFlags VkShaderModuleCreateFlags; - -typedef enum VkPipelineCacheCreateFlagBits { - VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001, - VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT, - VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCacheCreateFlagBits; -typedef VkFlags VkPipelineCacheCreateFlags; - -typedef enum VkColorComponentFlagBits { - VK_COLOR_COMPONENT_R_BIT = 0x00000001, - VK_COLOR_COMPONENT_G_BIT = 0x00000002, - VK_COLOR_COMPONENT_B_BIT = 0x00000004, - VK_COLOR_COMPONENT_A_BIT = 0x00000008, - VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkColorComponentFlagBits; -typedef VkFlags VkColorComponentFlags; - -typedef enum VkPipelineCreateFlagBits { - VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001, - VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, - VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, - VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, - VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 0x00000010, - VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT = 0x00000100, - VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT = 0x00000200, - VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000, - VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000, - VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000, - VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000, - VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000, - VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_BIT_KHR = 0x00020000, - VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR = 0x00001000, - VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR = 0x00002000, - VK_PIPELINE_CREATE_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR = 0x00080000, - VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV = 0x00000020, - VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR = 0x00000040, - VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080, - VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV = 0x00040000, - VK_PIPELINE_CREATE_LIBRARY_BIT_KHR = 0x00000800, - VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT = 0x00800000, - VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT = 0x00000400, - VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000, - VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x02000000, - VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x04000000, - VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, - VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, - VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT, - VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT, - VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE, - VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT, - VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT, - VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCreateFlagBits; -typedef VkFlags VkPipelineCreateFlags; - -typedef enum VkPipelineShaderStageCreateFlagBits { - VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT = 0x00000001, - VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT = 0x00000002, - VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT, - VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT, - VK_PIPELINE_SHADER_STAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineShaderStageCreateFlagBits; -typedef VkFlags VkPipelineShaderStageCreateFlags; - -typedef enum VkShaderStageFlagBits { - VK_SHADER_STAGE_VERTEX_BIT = 0x00000001, - VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002, - VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004, - VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, - VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, - VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, - VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, - VK_SHADER_STAGE_ALL = 0x7FFFFFFF, - VK_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, - VK_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, - VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, - VK_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, - VK_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, - VK_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, - VK_SHADER_STAGE_TASK_BIT_NV = 0x00000040, - VK_SHADER_STAGE_MESH_BIT_NV = 0x00000080, - VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI = 0x00004000, - VK_SHADER_STAGE_RAYGEN_BIT_NV = VK_SHADER_STAGE_RAYGEN_BIT_KHR, - VK_SHADER_STAGE_ANY_HIT_BIT_NV = VK_SHADER_STAGE_ANY_HIT_BIT_KHR, - VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, - VK_SHADER_STAGE_MISS_BIT_NV = VK_SHADER_STAGE_MISS_BIT_KHR, - VK_SHADER_STAGE_INTERSECTION_BIT_NV = VK_SHADER_STAGE_INTERSECTION_BIT_KHR, - VK_SHADER_STAGE_CALLABLE_BIT_NV = VK_SHADER_STAGE_CALLABLE_BIT_KHR, - VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkShaderStageFlagBits; - -typedef enum VkCullModeFlagBits { - VK_CULL_MODE_NONE = 0, - VK_CULL_MODE_FRONT_BIT = 0x00000001, - VK_CULL_MODE_BACK_BIT = 0x00000002, - VK_CULL_MODE_FRONT_AND_BACK = 0x00000003, - VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCullModeFlagBits; -typedef VkFlags VkCullModeFlags; -typedef VkFlags VkPipelineVertexInputStateCreateFlags; -typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; -typedef VkFlags VkPipelineTessellationStateCreateFlags; -typedef VkFlags VkPipelineViewportStateCreateFlags; -typedef VkFlags VkPipelineRasterizationStateCreateFlags; -typedef VkFlags VkPipelineMultisampleStateCreateFlags; - -typedef enum VkPipelineDepthStencilStateCreateFlagBits { - VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = 0x00000001, - VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = 0x00000002, - VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineDepthStencilStateCreateFlagBits; -typedef VkFlags VkPipelineDepthStencilStateCreateFlags; - -typedef enum VkPipelineColorBlendStateCreateFlagBits { - VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM = 0x00000001, - VK_PIPELINE_COLOR_BLEND_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineColorBlendStateCreateFlagBits; -typedef VkFlags VkPipelineColorBlendStateCreateFlags; -typedef VkFlags VkPipelineDynamicStateCreateFlags; - -typedef enum VkPipelineLayoutCreateFlagBits { - VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT = 0x00000002, - VK_PIPELINE_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineLayoutCreateFlagBits; -typedef VkFlags VkPipelineLayoutCreateFlags; -typedef VkFlags VkShaderStageFlags; - -typedef enum VkSamplerCreateFlagBits { - VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT = 0x00000001, - VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT = 0x00000002, - VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT = 0x00000004, - VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM = 0x00000010, - VK_SAMPLER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSamplerCreateFlagBits; -typedef VkFlags VkSamplerCreateFlags; - -typedef enum VkDescriptorPoolCreateFlagBits { - VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001, - VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT = 0x00000002, - VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE = 0x00000004, - VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, - VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorPoolCreateFlagBits; -typedef VkFlags VkDescriptorPoolCreateFlags; -typedef VkFlags VkDescriptorPoolResetFlags; - -typedef enum VkDescriptorSetLayoutCreateFlagBits { - VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT = 0x00000002, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE = 0x00000004, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorSetLayoutCreateFlagBits; -typedef VkFlags VkDescriptorSetLayoutCreateFlags; - -typedef enum VkAttachmentDescriptionFlagBits { - VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, - VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkAttachmentDescriptionFlagBits; -typedef VkFlags VkAttachmentDescriptionFlags; - -typedef enum VkDependencyFlagBits { - VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, - VK_DEPENDENCY_DEVICE_GROUP_BIT = 0x00000004, - VK_DEPENDENCY_VIEW_LOCAL_BIT = 0x00000002, - VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT = 0x00000008, - VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR = VK_DEPENDENCY_VIEW_LOCAL_BIT, - VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR = VK_DEPENDENCY_DEVICE_GROUP_BIT, - VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDependencyFlagBits; -typedef VkFlags VkDependencyFlags; - -typedef enum VkFramebufferCreateFlagBits { - VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 0x00000001, - VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, - VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkFramebufferCreateFlagBits; -typedef VkFlags VkFramebufferCreateFlags; - -typedef enum VkRenderPassCreateFlagBits { - VK_RENDER_PASS_CREATE_TRANSFORM_BIT_QCOM = 0x00000002, - VK_RENDER_PASS_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkRenderPassCreateFlagBits; -typedef VkFlags VkRenderPassCreateFlags; - -typedef enum VkSubpassDescriptionFlagBits { - VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX = 0x00000001, - VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002, - VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM = 0x00000004, - VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM = 0x00000008, - VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM = 0x00000010, - VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = 0x00000020, - VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = 0x00000040, - VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSubpassDescriptionFlagBits; -typedef VkFlags VkSubpassDescriptionFlags; - -typedef enum VkCommandPoolCreateFlagBits { - VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001, - VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002, - VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 0x00000004, - VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandPoolCreateFlagBits; -typedef VkFlags VkCommandPoolCreateFlags; - -typedef enum VkCommandPoolResetFlagBits { - VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001, - VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandPoolResetFlagBits; -typedef VkFlags VkCommandPoolResetFlags; - -typedef enum VkCommandBufferUsageFlagBits { - VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001, - VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 0x00000002, - VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 0x00000004, - VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferUsageFlagBits; -typedef VkFlags VkCommandBufferUsageFlags; - -typedef enum VkQueryControlFlagBits { - VK_QUERY_CONTROL_PRECISE_BIT = 0x00000001, - VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkQueryControlFlagBits; -typedef VkFlags VkQueryControlFlags; - -typedef enum VkCommandBufferResetFlagBits { - VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001, - VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkCommandBufferResetFlagBits; -typedef VkFlags VkCommandBufferResetFlags; - -typedef enum VkStencilFaceFlagBits { - VK_STENCIL_FACE_FRONT_BIT = 0x00000001, - VK_STENCIL_FACE_BACK_BIT = 0x00000002, - VK_STENCIL_FACE_FRONT_AND_BACK = 0x00000003, - VK_STENCIL_FRONT_AND_BACK = VK_STENCIL_FACE_FRONT_AND_BACK, - VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkStencilFaceFlagBits; -typedef VkFlags VkStencilFaceFlags; -typedef struct VkExtent2D { - uint32_t width; - uint32_t height; -} VkExtent2D; - -typedef struct VkExtent3D { - uint32_t width; - uint32_t height; - uint32_t depth; -} VkExtent3D; - -typedef struct VkOffset2D { - int32_t x; - int32_t y; -} VkOffset2D; - -typedef struct VkOffset3D { - int32_t x; - int32_t y; - int32_t z; -} VkOffset3D; - -typedef struct VkRect2D { - VkOffset2D offset; - VkExtent2D extent; -} VkRect2D; - -typedef struct VkBaseInStructure { - VkStructureType sType; - const struct VkBaseInStructure* pNext; -} VkBaseInStructure; - -typedef struct VkBaseOutStructure { - VkStructureType sType; - struct VkBaseOutStructure* pNext; -} VkBaseOutStructure; - -typedef struct VkBufferMemoryBarrier { - VkStructureType sType; - const void* pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize size; -} VkBufferMemoryBarrier; - -typedef struct VkDispatchIndirectCommand { - uint32_t x; - uint32_t y; - uint32_t z; -} VkDispatchIndirectCommand; - -typedef struct VkDrawIndexedIndirectCommand { - uint32_t indexCount; - uint32_t instanceCount; - uint32_t firstIndex; - int32_t vertexOffset; - uint32_t firstInstance; -} VkDrawIndexedIndirectCommand; - -typedef struct VkDrawIndirectCommand { - uint32_t vertexCount; - uint32_t instanceCount; - uint32_t firstVertex; - uint32_t firstInstance; -} VkDrawIndirectCommand; - -typedef struct VkImageSubresourceRange { - VkImageAspectFlags aspectMask; - uint32_t baseMipLevel; - uint32_t levelCount; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkImageSubresourceRange; - -typedef struct VkImageMemoryBarrier { - VkStructureType sType; - const void* pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkImageLayout oldLayout; - VkImageLayout newLayout; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkImage image; - VkImageSubresourceRange subresourceRange; -} VkImageMemoryBarrier; - -typedef struct VkMemoryBarrier { - VkStructureType sType; - const void* pNext; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; -} VkMemoryBarrier; - -typedef struct VkPipelineCacheHeaderVersionOne { - uint32_t headerSize; - VkPipelineCacheHeaderVersion headerVersion; - uint32_t vendorID; - uint32_t deviceID; - uint8_t pipelineCacheUUID[VK_UUID_SIZE]; -} VkPipelineCacheHeaderVersionOne; - -typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)( - void* pUserData, - size_t size, - size_t alignment, - VkSystemAllocationScope allocationScope); - -typedef void (VKAPI_PTR *PFN_vkFreeFunction)( - void* pUserData, - void* pMemory); - -typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)( - void* pUserData, - size_t size, - VkInternalAllocationType allocationType, - VkSystemAllocationScope allocationScope); - -typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)( - void* pUserData, - size_t size, - VkInternalAllocationType allocationType, - VkSystemAllocationScope allocationScope); - -typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)( - void* pUserData, - void* pOriginal, - size_t size, - size_t alignment, - VkSystemAllocationScope allocationScope); - -typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void); -typedef struct VkAllocationCallbacks { - void* pUserData; - PFN_vkAllocationFunction pfnAllocation; - PFN_vkReallocationFunction pfnReallocation; - PFN_vkFreeFunction pfnFree; - PFN_vkInternalAllocationNotification pfnInternalAllocation; - PFN_vkInternalFreeNotification pfnInternalFree; -} VkAllocationCallbacks; - -typedef struct VkApplicationInfo { - VkStructureType sType; - const void* pNext; - const char* pApplicationName; - uint32_t applicationVersion; - const char* pEngineName; - uint32_t engineVersion; - uint32_t apiVersion; -} VkApplicationInfo; - -typedef struct VkFormatProperties { - VkFormatFeatureFlags linearTilingFeatures; - VkFormatFeatureFlags optimalTilingFeatures; - VkFormatFeatureFlags bufferFeatures; -} VkFormatProperties; - -typedef struct VkImageFormatProperties { - VkExtent3D maxExtent; - uint32_t maxMipLevels; - uint32_t maxArrayLayers; - VkSampleCountFlags sampleCounts; - VkDeviceSize maxResourceSize; -} VkImageFormatProperties; - -typedef struct VkInstanceCreateInfo { - VkStructureType sType; - const void* pNext; - VkInstanceCreateFlags flags; - const VkApplicationInfo* pApplicationInfo; - uint32_t enabledLayerCount; - const char* const* ppEnabledLayerNames; - uint32_t enabledExtensionCount; - const char* const* ppEnabledExtensionNames; -} VkInstanceCreateInfo; - -typedef struct VkMemoryHeap { - VkDeviceSize size; - VkMemoryHeapFlags flags; -} VkMemoryHeap; - -typedef struct VkMemoryType { - VkMemoryPropertyFlags propertyFlags; - uint32_t heapIndex; -} VkMemoryType; - -typedef struct VkPhysicalDeviceFeatures { - VkBool32 robustBufferAccess; - VkBool32 fullDrawIndexUint32; - VkBool32 imageCubeArray; - VkBool32 independentBlend; - VkBool32 geometryShader; - VkBool32 tessellationShader; - VkBool32 sampleRateShading; - VkBool32 dualSrcBlend; - VkBool32 logicOp; - VkBool32 multiDrawIndirect; - VkBool32 drawIndirectFirstInstance; - VkBool32 depthClamp; - VkBool32 depthBiasClamp; - VkBool32 fillModeNonSolid; - VkBool32 depthBounds; - VkBool32 wideLines; - VkBool32 largePoints; - VkBool32 alphaToOne; - VkBool32 multiViewport; - VkBool32 samplerAnisotropy; - VkBool32 textureCompressionETC2; - VkBool32 textureCompressionASTC_LDR; - VkBool32 textureCompressionBC; - VkBool32 occlusionQueryPrecise; - VkBool32 pipelineStatisticsQuery; - VkBool32 vertexPipelineStoresAndAtomics; - VkBool32 fragmentStoresAndAtomics; - VkBool32 shaderTessellationAndGeometryPointSize; - VkBool32 shaderImageGatherExtended; - VkBool32 shaderStorageImageExtendedFormats; - VkBool32 shaderStorageImageMultisample; - VkBool32 shaderStorageImageReadWithoutFormat; - VkBool32 shaderStorageImageWriteWithoutFormat; - VkBool32 shaderUniformBufferArrayDynamicIndexing; - VkBool32 shaderSampledImageArrayDynamicIndexing; - VkBool32 shaderStorageBufferArrayDynamicIndexing; - VkBool32 shaderStorageImageArrayDynamicIndexing; - VkBool32 shaderClipDistance; - VkBool32 shaderCullDistance; - VkBool32 shaderFloat64; - VkBool32 shaderInt64; - VkBool32 shaderInt16; - VkBool32 shaderResourceResidency; - VkBool32 shaderResourceMinLod; - VkBool32 sparseBinding; - VkBool32 sparseResidencyBuffer; - VkBool32 sparseResidencyImage2D; - VkBool32 sparseResidencyImage3D; - VkBool32 sparseResidency2Samples; - VkBool32 sparseResidency4Samples; - VkBool32 sparseResidency8Samples; - VkBool32 sparseResidency16Samples; - VkBool32 sparseResidencyAliased; - VkBool32 variableMultisampleRate; - VkBool32 inheritedQueries; -} VkPhysicalDeviceFeatures; - -typedef struct VkPhysicalDeviceLimits { - uint32_t maxImageDimension1D; - uint32_t maxImageDimension2D; - uint32_t maxImageDimension3D; - uint32_t maxImageDimensionCube; - uint32_t maxImageArrayLayers; - uint32_t maxTexelBufferElements; - uint32_t maxUniformBufferRange; - uint32_t maxStorageBufferRange; - uint32_t maxPushConstantsSize; - uint32_t maxMemoryAllocationCount; - uint32_t maxSamplerAllocationCount; - VkDeviceSize bufferImageGranularity; - VkDeviceSize sparseAddressSpaceSize; - uint32_t maxBoundDescriptorSets; - uint32_t maxPerStageDescriptorSamplers; - uint32_t maxPerStageDescriptorUniformBuffers; - uint32_t maxPerStageDescriptorStorageBuffers; - uint32_t maxPerStageDescriptorSampledImages; - uint32_t maxPerStageDescriptorStorageImages; - uint32_t maxPerStageDescriptorInputAttachments; - uint32_t maxPerStageResources; - uint32_t maxDescriptorSetSamplers; - uint32_t maxDescriptorSetUniformBuffers; - uint32_t maxDescriptorSetUniformBuffersDynamic; - uint32_t maxDescriptorSetStorageBuffers; - uint32_t maxDescriptorSetStorageBuffersDynamic; - uint32_t maxDescriptorSetSampledImages; - uint32_t maxDescriptorSetStorageImages; - uint32_t maxDescriptorSetInputAttachments; - uint32_t maxVertexInputAttributes; - uint32_t maxVertexInputBindings; - uint32_t maxVertexInputAttributeOffset; - uint32_t maxVertexInputBindingStride; - uint32_t maxVertexOutputComponents; - uint32_t maxTessellationGenerationLevel; - uint32_t maxTessellationPatchSize; - uint32_t maxTessellationControlPerVertexInputComponents; - uint32_t maxTessellationControlPerVertexOutputComponents; - uint32_t maxTessellationControlPerPatchOutputComponents; - uint32_t maxTessellationControlTotalOutputComponents; - uint32_t maxTessellationEvaluationInputComponents; - uint32_t maxTessellationEvaluationOutputComponents; - uint32_t maxGeometryShaderInvocations; - uint32_t maxGeometryInputComponents; - uint32_t maxGeometryOutputComponents; - uint32_t maxGeometryOutputVertices; - uint32_t maxGeometryTotalOutputComponents; - uint32_t maxFragmentInputComponents; - uint32_t maxFragmentOutputAttachments; - uint32_t maxFragmentDualSrcAttachments; - uint32_t maxFragmentCombinedOutputResources; - uint32_t maxComputeSharedMemorySize; - uint32_t maxComputeWorkGroupCount[3]; - uint32_t maxComputeWorkGroupInvocations; - uint32_t maxComputeWorkGroupSize[3]; - uint32_t subPixelPrecisionBits; - uint32_t subTexelPrecisionBits; - uint32_t mipmapPrecisionBits; - uint32_t maxDrawIndexedIndexValue; - uint32_t maxDrawIndirectCount; - float maxSamplerLodBias; - float maxSamplerAnisotropy; - uint32_t maxViewports; - uint32_t maxViewportDimensions[2]; - float viewportBoundsRange[2]; - uint32_t viewportSubPixelBits; - size_t minMemoryMapAlignment; - VkDeviceSize minTexelBufferOffsetAlignment; - VkDeviceSize minUniformBufferOffsetAlignment; - VkDeviceSize minStorageBufferOffsetAlignment; - int32_t minTexelOffset; - uint32_t maxTexelOffset; - int32_t minTexelGatherOffset; - uint32_t maxTexelGatherOffset; - float minInterpolationOffset; - float maxInterpolationOffset; - uint32_t subPixelInterpolationOffsetBits; - uint32_t maxFramebufferWidth; - uint32_t maxFramebufferHeight; - uint32_t maxFramebufferLayers; - VkSampleCountFlags framebufferColorSampleCounts; - VkSampleCountFlags framebufferDepthSampleCounts; - VkSampleCountFlags framebufferStencilSampleCounts; - VkSampleCountFlags framebufferNoAttachmentsSampleCounts; - uint32_t maxColorAttachments; - VkSampleCountFlags sampledImageColorSampleCounts; - VkSampleCountFlags sampledImageIntegerSampleCounts; - VkSampleCountFlags sampledImageDepthSampleCounts; - VkSampleCountFlags sampledImageStencilSampleCounts; - VkSampleCountFlags storageImageSampleCounts; - uint32_t maxSampleMaskWords; - VkBool32 timestampComputeAndGraphics; - float timestampPeriod; - uint32_t maxClipDistances; - uint32_t maxCullDistances; - uint32_t maxCombinedClipAndCullDistances; - uint32_t discreteQueuePriorities; - float pointSizeRange[2]; - float lineWidthRange[2]; - float pointSizeGranularity; - float lineWidthGranularity; - VkBool32 strictLines; - VkBool32 standardSampleLocations; - VkDeviceSize optimalBufferCopyOffsetAlignment; - VkDeviceSize optimalBufferCopyRowPitchAlignment; - VkDeviceSize nonCoherentAtomSize; -} VkPhysicalDeviceLimits; - -typedef struct VkPhysicalDeviceMemoryProperties { - uint32_t memoryTypeCount; - VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; - uint32_t memoryHeapCount; - VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS]; -} VkPhysicalDeviceMemoryProperties; - -typedef struct VkPhysicalDeviceSparseProperties { - VkBool32 residencyStandard2DBlockShape; - VkBool32 residencyStandard2DMultisampleBlockShape; - VkBool32 residencyStandard3DBlockShape; - VkBool32 residencyAlignedMipSize; - VkBool32 residencyNonResidentStrict; -} VkPhysicalDeviceSparseProperties; - -typedef struct VkPhysicalDeviceProperties { - uint32_t apiVersion; - uint32_t driverVersion; - uint32_t vendorID; - uint32_t deviceID; - VkPhysicalDeviceType deviceType; - char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; - uint8_t pipelineCacheUUID[VK_UUID_SIZE]; - VkPhysicalDeviceLimits limits; - VkPhysicalDeviceSparseProperties sparseProperties; -} VkPhysicalDeviceProperties; - -typedef struct VkQueueFamilyProperties { - VkQueueFlags queueFlags; - uint32_t queueCount; - uint32_t timestampValidBits; - VkExtent3D minImageTransferGranularity; -} VkQueueFamilyProperties; - -typedef struct VkDeviceQueueCreateInfo { - VkStructureType sType; - const void* pNext; - VkDeviceQueueCreateFlags flags; - uint32_t queueFamilyIndex; - uint32_t queueCount; - const float* pQueuePriorities; -} VkDeviceQueueCreateInfo; - -typedef struct VkDeviceCreateInfo { - VkStructureType sType; - const void* pNext; - VkDeviceCreateFlags flags; - uint32_t queueCreateInfoCount; - const VkDeviceQueueCreateInfo* pQueueCreateInfos; - uint32_t enabledLayerCount; - const char* const* ppEnabledLayerNames; - uint32_t enabledExtensionCount; - const char* const* ppEnabledExtensionNames; - const VkPhysicalDeviceFeatures* pEnabledFeatures; -} VkDeviceCreateInfo; - -typedef struct VkExtensionProperties { - char extensionName[VK_MAX_EXTENSION_NAME_SIZE]; - uint32_t specVersion; -} VkExtensionProperties; - -typedef struct VkLayerProperties { - char layerName[VK_MAX_EXTENSION_NAME_SIZE]; - uint32_t specVersion; - uint32_t implementationVersion; - char description[VK_MAX_DESCRIPTION_SIZE]; -} VkLayerProperties; - -typedef struct VkSubmitInfo { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreCount; - const VkSemaphore* pWaitSemaphores; - const VkPipelineStageFlags* pWaitDstStageMask; - uint32_t commandBufferCount; - const VkCommandBuffer* pCommandBuffers; - uint32_t signalSemaphoreCount; - const VkSemaphore* pSignalSemaphores; -} VkSubmitInfo; - -typedef struct VkMappedMemoryRange { - VkStructureType sType; - const void* pNext; - VkDeviceMemory memory; - VkDeviceSize offset; - VkDeviceSize size; -} VkMappedMemoryRange; - -typedef struct VkMemoryAllocateInfo { - VkStructureType sType; - const void* pNext; - VkDeviceSize allocationSize; - uint32_t memoryTypeIndex; -} VkMemoryAllocateInfo; - -typedef struct VkMemoryRequirements { - VkDeviceSize size; - VkDeviceSize alignment; - uint32_t memoryTypeBits; -} VkMemoryRequirements; - -typedef struct VkSparseMemoryBind { - VkDeviceSize resourceOffset; - VkDeviceSize size; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; - VkSparseMemoryBindFlags flags; -} VkSparseMemoryBind; - -typedef struct VkSparseBufferMemoryBindInfo { - VkBuffer buffer; - uint32_t bindCount; - const VkSparseMemoryBind* pBinds; -} VkSparseBufferMemoryBindInfo; - -typedef struct VkSparseImageOpaqueMemoryBindInfo { - VkImage image; - uint32_t bindCount; - const VkSparseMemoryBind* pBinds; -} VkSparseImageOpaqueMemoryBindInfo; - -typedef struct VkImageSubresource { - VkImageAspectFlags aspectMask; - uint32_t mipLevel; - uint32_t arrayLayer; -} VkImageSubresource; - -typedef struct VkSparseImageMemoryBind { - VkImageSubresource subresource; - VkOffset3D offset; - VkExtent3D extent; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; - VkSparseMemoryBindFlags flags; -} VkSparseImageMemoryBind; - -typedef struct VkSparseImageMemoryBindInfo { - VkImage image; - uint32_t bindCount; - const VkSparseImageMemoryBind* pBinds; -} VkSparseImageMemoryBindInfo; - -typedef struct VkBindSparseInfo { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreCount; - const VkSemaphore* pWaitSemaphores; - uint32_t bufferBindCount; - const VkSparseBufferMemoryBindInfo* pBufferBinds; - uint32_t imageOpaqueBindCount; - const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds; - uint32_t imageBindCount; - const VkSparseImageMemoryBindInfo* pImageBinds; - uint32_t signalSemaphoreCount; - const VkSemaphore* pSignalSemaphores; -} VkBindSparseInfo; - -typedef struct VkSparseImageFormatProperties { - VkImageAspectFlags aspectMask; - VkExtent3D imageGranularity; - VkSparseImageFormatFlags flags; -} VkSparseImageFormatProperties; - -typedef struct VkSparseImageMemoryRequirements { - VkSparseImageFormatProperties formatProperties; - uint32_t imageMipTailFirstLod; - VkDeviceSize imageMipTailSize; - VkDeviceSize imageMipTailOffset; - VkDeviceSize imageMipTailStride; -} VkSparseImageMemoryRequirements; - -typedef struct VkFenceCreateInfo { - VkStructureType sType; - const void* pNext; - VkFenceCreateFlags flags; -} VkFenceCreateInfo; - -typedef struct VkSemaphoreCreateInfo { - VkStructureType sType; - const void* pNext; - VkSemaphoreCreateFlags flags; -} VkSemaphoreCreateInfo; - -typedef struct VkEventCreateInfo { - VkStructureType sType; - const void* pNext; - VkEventCreateFlags flags; -} VkEventCreateInfo; - -typedef struct VkQueryPoolCreateInfo { - VkStructureType sType; - const void* pNext; - VkQueryPoolCreateFlags flags; - VkQueryType queryType; - uint32_t queryCount; - VkQueryPipelineStatisticFlags pipelineStatistics; -} VkQueryPoolCreateInfo; - -typedef struct VkBufferCreateInfo { - VkStructureType sType; - const void* pNext; - VkBufferCreateFlags flags; - VkDeviceSize size; - VkBufferUsageFlags usage; - VkSharingMode sharingMode; - uint32_t queueFamilyIndexCount; - const uint32_t* pQueueFamilyIndices; -} VkBufferCreateInfo; - -typedef struct VkBufferViewCreateInfo { - VkStructureType sType; - const void* pNext; - VkBufferViewCreateFlags flags; - VkBuffer buffer; - VkFormat format; - VkDeviceSize offset; - VkDeviceSize range; -} VkBufferViewCreateInfo; - -typedef struct VkImageCreateInfo { - VkStructureType sType; - const void* pNext; - VkImageCreateFlags flags; - VkImageType imageType; - VkFormat format; - VkExtent3D extent; - uint32_t mipLevels; - uint32_t arrayLayers; - VkSampleCountFlagBits samples; - VkImageTiling tiling; - VkImageUsageFlags usage; - VkSharingMode sharingMode; - uint32_t queueFamilyIndexCount; - const uint32_t* pQueueFamilyIndices; - VkImageLayout initialLayout; -} VkImageCreateInfo; - -typedef struct VkSubresourceLayout { - VkDeviceSize offset; - VkDeviceSize size; - VkDeviceSize rowPitch; - VkDeviceSize arrayPitch; - VkDeviceSize depthPitch; -} VkSubresourceLayout; - -typedef struct VkComponentMapping { - VkComponentSwizzle r; - VkComponentSwizzle g; - VkComponentSwizzle b; - VkComponentSwizzle a; -} VkComponentMapping; - -typedef struct VkImageViewCreateInfo { - VkStructureType sType; - const void* pNext; - VkImageViewCreateFlags flags; - VkImage image; - VkImageViewType viewType; - VkFormat format; - VkComponentMapping components; - VkImageSubresourceRange subresourceRange; -} VkImageViewCreateInfo; - -typedef struct VkShaderModuleCreateInfo { - VkStructureType sType; - const void* pNext; - VkShaderModuleCreateFlags flags; - size_t codeSize; - const uint32_t* pCode; -} VkShaderModuleCreateInfo; - -typedef struct VkPipelineCacheCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineCacheCreateFlags flags; - size_t initialDataSize; - const void* pInitialData; -} VkPipelineCacheCreateInfo; - -typedef struct VkSpecializationMapEntry { - uint32_t constantID; - uint32_t offset; - size_t size; -} VkSpecializationMapEntry; - -typedef struct VkSpecializationInfo { - uint32_t mapEntryCount; - const VkSpecializationMapEntry* pMapEntries; - size_t dataSize; - const void* pData; -} VkSpecializationInfo; - -typedef struct VkPipelineShaderStageCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineShaderStageCreateFlags flags; - VkShaderStageFlagBits stage; - VkShaderModule module; - const char* pName; - const VkSpecializationInfo* pSpecializationInfo; -} VkPipelineShaderStageCreateInfo; - -typedef struct VkComputePipelineCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineCreateFlags flags; - VkPipelineShaderStageCreateInfo stage; - VkPipelineLayout layout; - VkPipeline basePipelineHandle; - int32_t basePipelineIndex; -} VkComputePipelineCreateInfo; - -typedef struct VkVertexInputBindingDescription { - uint32_t binding; - uint32_t stride; - VkVertexInputRate inputRate; -} VkVertexInputBindingDescription; - -typedef struct VkVertexInputAttributeDescription { - uint32_t location; - uint32_t binding; - VkFormat format; - uint32_t offset; -} VkVertexInputAttributeDescription; - -typedef struct VkPipelineVertexInputStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineVertexInputStateCreateFlags flags; - uint32_t vertexBindingDescriptionCount; - const VkVertexInputBindingDescription* pVertexBindingDescriptions; - uint32_t vertexAttributeDescriptionCount; - const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; -} VkPipelineVertexInputStateCreateInfo; - -typedef struct VkPipelineInputAssemblyStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineInputAssemblyStateCreateFlags flags; - VkPrimitiveTopology topology; - VkBool32 primitiveRestartEnable; -} VkPipelineInputAssemblyStateCreateInfo; - -typedef struct VkPipelineTessellationStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineTessellationStateCreateFlags flags; - uint32_t patchControlPoints; -} VkPipelineTessellationStateCreateInfo; - -typedef struct VkViewport { - float x; - float y; - float width; - float height; - float minDepth; - float maxDepth; -} VkViewport; - -typedef struct VkPipelineViewportStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineViewportStateCreateFlags flags; - uint32_t viewportCount; - const VkViewport* pViewports; - uint32_t scissorCount; - const VkRect2D* pScissors; -} VkPipelineViewportStateCreateInfo; - -typedef struct VkPipelineRasterizationStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineRasterizationStateCreateFlags flags; - VkBool32 depthClampEnable; - VkBool32 rasterizerDiscardEnable; - VkPolygonMode polygonMode; - VkCullModeFlags cullMode; - VkFrontFace frontFace; - VkBool32 depthBiasEnable; - float depthBiasConstantFactor; - float depthBiasClamp; - float depthBiasSlopeFactor; - float lineWidth; -} VkPipelineRasterizationStateCreateInfo; - -typedef struct VkPipelineMultisampleStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineMultisampleStateCreateFlags flags; - VkSampleCountFlagBits rasterizationSamples; - VkBool32 sampleShadingEnable; - float minSampleShading; - const VkSampleMask* pSampleMask; - VkBool32 alphaToCoverageEnable; - VkBool32 alphaToOneEnable; -} VkPipelineMultisampleStateCreateInfo; - -typedef struct VkStencilOpState { - VkStencilOp failOp; - VkStencilOp passOp; - VkStencilOp depthFailOp; - VkCompareOp compareOp; - uint32_t compareMask; - uint32_t writeMask; - uint32_t reference; -} VkStencilOpState; - -typedef struct VkPipelineDepthStencilStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineDepthStencilStateCreateFlags flags; - VkBool32 depthTestEnable; - VkBool32 depthWriteEnable; - VkCompareOp depthCompareOp; - VkBool32 depthBoundsTestEnable; - VkBool32 stencilTestEnable; - VkStencilOpState front; - VkStencilOpState back; - float minDepthBounds; - float maxDepthBounds; -} VkPipelineDepthStencilStateCreateInfo; - -typedef struct VkPipelineColorBlendAttachmentState { - VkBool32 blendEnable; - VkBlendFactor srcColorBlendFactor; - VkBlendFactor dstColorBlendFactor; - VkBlendOp colorBlendOp; - VkBlendFactor srcAlphaBlendFactor; - VkBlendFactor dstAlphaBlendFactor; - VkBlendOp alphaBlendOp; - VkColorComponentFlags colorWriteMask; -} VkPipelineColorBlendAttachmentState; - -typedef struct VkPipelineColorBlendStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineColorBlendStateCreateFlags flags; - VkBool32 logicOpEnable; - VkLogicOp logicOp; - uint32_t attachmentCount; - const VkPipelineColorBlendAttachmentState* pAttachments; - float blendConstants[4]; -} VkPipelineColorBlendStateCreateInfo; - -typedef struct VkPipelineDynamicStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineDynamicStateCreateFlags flags; - uint32_t dynamicStateCount; - const VkDynamicState* pDynamicStates; -} VkPipelineDynamicStateCreateInfo; - -typedef struct VkGraphicsPipelineCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineCreateFlags flags; - uint32_t stageCount; - const VkPipelineShaderStageCreateInfo* pStages; - const VkPipelineVertexInputStateCreateInfo* pVertexInputState; - const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; - const VkPipelineTessellationStateCreateInfo* pTessellationState; - const VkPipelineViewportStateCreateInfo* pViewportState; - const VkPipelineRasterizationStateCreateInfo* pRasterizationState; - const VkPipelineMultisampleStateCreateInfo* pMultisampleState; - const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; - const VkPipelineColorBlendStateCreateInfo* pColorBlendState; - const VkPipelineDynamicStateCreateInfo* pDynamicState; - VkPipelineLayout layout; - VkRenderPass renderPass; - uint32_t subpass; - VkPipeline basePipelineHandle; - int32_t basePipelineIndex; -} VkGraphicsPipelineCreateInfo; - -typedef struct VkPushConstantRange { - VkShaderStageFlags stageFlags; - uint32_t offset; - uint32_t size; -} VkPushConstantRange; - -typedef struct VkPipelineLayoutCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineLayoutCreateFlags flags; - uint32_t setLayoutCount; - const VkDescriptorSetLayout* pSetLayouts; - uint32_t pushConstantRangeCount; - const VkPushConstantRange* pPushConstantRanges; -} VkPipelineLayoutCreateInfo; - -typedef struct VkSamplerCreateInfo { - VkStructureType sType; - const void* pNext; - VkSamplerCreateFlags flags; - VkFilter magFilter; - VkFilter minFilter; - VkSamplerMipmapMode mipmapMode; - VkSamplerAddressMode addressModeU; - VkSamplerAddressMode addressModeV; - VkSamplerAddressMode addressModeW; - float mipLodBias; - VkBool32 anisotropyEnable; - float maxAnisotropy; - VkBool32 compareEnable; - VkCompareOp compareOp; - float minLod; - float maxLod; - VkBorderColor borderColor; - VkBool32 unnormalizedCoordinates; -} VkSamplerCreateInfo; - -typedef struct VkCopyDescriptorSet { - VkStructureType sType; - const void* pNext; - VkDescriptorSet srcSet; - uint32_t srcBinding; - uint32_t srcArrayElement; - VkDescriptorSet dstSet; - uint32_t dstBinding; - uint32_t dstArrayElement; - uint32_t descriptorCount; -} VkCopyDescriptorSet; - -typedef struct VkDescriptorBufferInfo { - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize range; -} VkDescriptorBufferInfo; - -typedef struct VkDescriptorImageInfo { - VkSampler sampler; - VkImageView imageView; - VkImageLayout imageLayout; -} VkDescriptorImageInfo; - -typedef struct VkDescriptorPoolSize { - VkDescriptorType type; - uint32_t descriptorCount; -} VkDescriptorPoolSize; - -typedef struct VkDescriptorPoolCreateInfo { - VkStructureType sType; - const void* pNext; - VkDescriptorPoolCreateFlags flags; - uint32_t maxSets; - uint32_t poolSizeCount; - const VkDescriptorPoolSize* pPoolSizes; -} VkDescriptorPoolCreateInfo; - -typedef struct VkDescriptorSetAllocateInfo { - VkStructureType sType; - const void* pNext; - VkDescriptorPool descriptorPool; - uint32_t descriptorSetCount; - const VkDescriptorSetLayout* pSetLayouts; -} VkDescriptorSetAllocateInfo; - -typedef struct VkDescriptorSetLayoutBinding { - uint32_t binding; - VkDescriptorType descriptorType; - uint32_t descriptorCount; - VkShaderStageFlags stageFlags; - const VkSampler* pImmutableSamplers; -} VkDescriptorSetLayoutBinding; - -typedef struct VkDescriptorSetLayoutCreateInfo { - VkStructureType sType; - const void* pNext; - VkDescriptorSetLayoutCreateFlags flags; - uint32_t bindingCount; - const VkDescriptorSetLayoutBinding* pBindings; -} VkDescriptorSetLayoutCreateInfo; - -typedef struct VkWriteDescriptorSet { - VkStructureType sType; - const void* pNext; - VkDescriptorSet dstSet; - uint32_t dstBinding; - uint32_t dstArrayElement; - uint32_t descriptorCount; - VkDescriptorType descriptorType; - const VkDescriptorImageInfo* pImageInfo; - const VkDescriptorBufferInfo* pBufferInfo; - const VkBufferView* pTexelBufferView; -} VkWriteDescriptorSet; - -typedef struct VkAttachmentDescription { - VkAttachmentDescriptionFlags flags; - VkFormat format; - VkSampleCountFlagBits samples; - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkAttachmentLoadOp stencilLoadOp; - VkAttachmentStoreOp stencilStoreOp; - VkImageLayout initialLayout; - VkImageLayout finalLayout; -} VkAttachmentDescription; - -typedef struct VkAttachmentReference { - uint32_t attachment; - VkImageLayout layout; -} VkAttachmentReference; - -typedef struct VkFramebufferCreateInfo { - VkStructureType sType; - const void* pNext; - VkFramebufferCreateFlags flags; - VkRenderPass renderPass; - uint32_t attachmentCount; - const VkImageView* pAttachments; - uint32_t width; - uint32_t height; - uint32_t layers; -} VkFramebufferCreateInfo; - -typedef struct VkSubpassDescription { - VkSubpassDescriptionFlags flags; - VkPipelineBindPoint pipelineBindPoint; - uint32_t inputAttachmentCount; - const VkAttachmentReference* pInputAttachments; - uint32_t colorAttachmentCount; - const VkAttachmentReference* pColorAttachments; - const VkAttachmentReference* pResolveAttachments; - const VkAttachmentReference* pDepthStencilAttachment; - uint32_t preserveAttachmentCount; - const uint32_t* pPreserveAttachments; -} VkSubpassDescription; - -typedef struct VkSubpassDependency { - uint32_t srcSubpass; - uint32_t dstSubpass; - VkPipelineStageFlags srcStageMask; - VkPipelineStageFlags dstStageMask; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkDependencyFlags dependencyFlags; -} VkSubpassDependency; - -typedef struct VkRenderPassCreateInfo { - VkStructureType sType; - const void* pNext; - VkRenderPassCreateFlags flags; - uint32_t attachmentCount; - const VkAttachmentDescription* pAttachments; - uint32_t subpassCount; - const VkSubpassDescription* pSubpasses; - uint32_t dependencyCount; - const VkSubpassDependency* pDependencies; -} VkRenderPassCreateInfo; - -typedef struct VkCommandPoolCreateInfo { - VkStructureType sType; - const void* pNext; - VkCommandPoolCreateFlags flags; - uint32_t queueFamilyIndex; -} VkCommandPoolCreateInfo; - -typedef struct VkCommandBufferAllocateInfo { - VkStructureType sType; - const void* pNext; - VkCommandPool commandPool; - VkCommandBufferLevel level; - uint32_t commandBufferCount; -} VkCommandBufferAllocateInfo; - -typedef struct VkCommandBufferInheritanceInfo { - VkStructureType sType; - const void* pNext; - VkRenderPass renderPass; - uint32_t subpass; - VkFramebuffer framebuffer; - VkBool32 occlusionQueryEnable; - VkQueryControlFlags queryFlags; - VkQueryPipelineStatisticFlags pipelineStatistics; -} VkCommandBufferInheritanceInfo; - -typedef struct VkCommandBufferBeginInfo { - VkStructureType sType; - const void* pNext; - VkCommandBufferUsageFlags flags; - const VkCommandBufferInheritanceInfo* pInheritanceInfo; -} VkCommandBufferBeginInfo; - -typedef struct VkBufferCopy { - VkDeviceSize srcOffset; - VkDeviceSize dstOffset; - VkDeviceSize size; -} VkBufferCopy; - -typedef struct VkImageSubresourceLayers { - VkImageAspectFlags aspectMask; - uint32_t mipLevel; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkImageSubresourceLayers; - -typedef struct VkBufferImageCopy { - VkDeviceSize bufferOffset; - uint32_t bufferRowLength; - uint32_t bufferImageHeight; - VkImageSubresourceLayers imageSubresource; - VkOffset3D imageOffset; - VkExtent3D imageExtent; -} VkBufferImageCopy; - -typedef union VkClearColorValue { - float float32[4]; - int32_t int32[4]; - uint32_t uint32[4]; -} VkClearColorValue; - -typedef struct VkClearDepthStencilValue { - float depth; - uint32_t stencil; -} VkClearDepthStencilValue; - -typedef union VkClearValue { - VkClearColorValue color; - VkClearDepthStencilValue depthStencil; -} VkClearValue; - -typedef struct VkClearAttachment { - VkImageAspectFlags aspectMask; - uint32_t colorAttachment; - VkClearValue clearValue; -} VkClearAttachment; - -typedef struct VkClearRect { - VkRect2D rect; - uint32_t baseArrayLayer; - uint32_t layerCount; -} VkClearRect; - -typedef struct VkImageBlit { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffsets[2]; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffsets[2]; -} VkImageBlit; - -typedef struct VkImageCopy { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageCopy; - -typedef struct VkImageResolve { - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageResolve; - -typedef struct VkRenderPassBeginInfo { - VkStructureType sType; - const void* pNext; - VkRenderPass renderPass; - VkFramebuffer framebuffer; - VkRect2D renderArea; - uint32_t clearValueCount; - const VkClearValue* pClearValues; -} VkRenderPassBeginInfo; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance); -typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties); -typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName); -typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetDeviceProcAddr)(VkDevice device, const char* pName); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice); -typedef void (VKAPI_PTR *PFN_vkDestroyDevice)(VkDevice device, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t* pPropertyCount, VkLayerProperties* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties); -typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue); -typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence); -typedef VkResult (VKAPI_PTR *PFN_vkQueueWaitIdle)(VkQueue queue); -typedef VkResult (VKAPI_PTR *PFN_vkDeviceWaitIdle)(VkDevice device); -typedef VkResult (VKAPI_PTR *PFN_vkAllocateMemory)(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory); -typedef void (VKAPI_PTR *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData); -typedef void (VKAPI_PTR *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory memory); -typedef VkResult (VKAPI_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); -typedef VkResult (VKAPI_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); -typedef void (VKAPI_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes); -typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset); -typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset); -typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkQueueBindSparse)(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence); -typedef VkResult (VKAPI_PTR *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); -typedef void (VKAPI_PTR *PFN_vkDestroyFence)(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences); -typedef VkResult (VKAPI_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence); -typedef VkResult (VKAPI_PTR *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout); -typedef VkResult (VKAPI_PTR *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore); -typedef void (VKAPI_PTR *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent); -typedef void (VKAPI_PTR *PFN_vkDestroyEvent)(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkGetEventStatus)(VkDevice device, VkEvent event); -typedef VkResult (VKAPI_PTR *PFN_vkSetEvent)(VkDevice device, VkEvent event); -typedef VkResult (VKAPI_PTR *PFN_vkResetEvent)(VkDevice device, VkEvent event); -typedef VkResult (VKAPI_PTR *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool); -typedef void (VKAPI_PTR *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags); -typedef VkResult (VKAPI_PTR *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer); -typedef void (VKAPI_PTR *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView); -typedef void (VKAPI_PTR *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage); -typedef void (VKAPI_PTR *PFN_vkDestroyImage)(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout); -typedef VkResult (VKAPI_PTR *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView); -typedef void (VKAPI_PTR *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule); -typedef void (VKAPI_PTR *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache); -typedef void (VKAPI_PTR *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData); -typedef VkResult (VKAPI_PTR *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches); -typedef VkResult (VKAPI_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); -typedef VkResult (VKAPI_PTR *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); -typedef void (VKAPI_PTR *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout); -typedef void (VKAPI_PTR *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler); -typedef void (VKAPI_PTR *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout); -typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool); -typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags); -typedef VkResult (VKAPI_PTR *PFN_vkAllocateDescriptorSets)(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets); -typedef VkResult (VKAPI_PTR *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets); -typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies); -typedef VkResult (VKAPI_PTR *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer); -typedef void (VKAPI_PTR *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); -typedef void (VKAPI_PTR *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity); -typedef VkResult (VKAPI_PTR *PFN_vkCreateCommandPool)(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool); -typedef void (VKAPI_PTR *PFN_vkDestroyCommandPool)(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkResetCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags); -typedef VkResult (VKAPI_PTR *PFN_vkAllocateCommandBuffers)(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers); -typedef void (VKAPI_PTR *PFN_vkFreeCommandBuffers)(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); -typedef VkResult (VKAPI_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo); -typedef VkResult (VKAPI_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer commandBuffer); -typedef VkResult (VKAPI_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); -typedef void (VKAPI_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); -typedef void (VKAPI_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports); -typedef void (VKAPI_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors); -typedef void (VKAPI_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer commandBuffer, float lineWidth); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); -typedef void (VKAPI_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer commandBuffer, const float blendConstants[4]); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds); -typedef void (VKAPI_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask); -typedef void (VKAPI_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask); -typedef void (VKAPI_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference); -typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets); -typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); -typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets); -typedef void (VKAPI_PTR *PFN_vkCmdDraw)(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); -typedef void (VKAPI_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); -typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions); -typedef void (VKAPI_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter); -typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions); -typedef void (VKAPI_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData); -typedef void (VKAPI_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); -typedef void (VKAPI_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); -typedef void (VKAPI_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); -typedef void (VKAPI_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects); -typedef void (VKAPI_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve* pRegions); -typedef void (VKAPI_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); -typedef void (VKAPI_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); -typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); -typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); -typedef void (VKAPI_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); -typedef void (VKAPI_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query); -typedef void (VKAPI_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); -typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query); -typedef void (VKAPI_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); -typedef void (VKAPI_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues); -typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents); -typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer commandBuffer, VkSubpassContents contents); -typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer commandBuffer); -typedef void (VKAPI_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( - const VkInstanceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkInstance* pInstance); - -VKAPI_ATTR void VKAPI_CALL vkDestroyInstance( - VkInstance instance, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices( - VkInstance instance, - uint32_t* pPhysicalDeviceCount, - VkPhysicalDevice* pPhysicalDevices); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceFeatures* pFeatures); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkFormatProperties* pFormatProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkImageType type, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkImageCreateFlags flags, - VkImageFormatProperties* pImageFormatProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceProperties* pProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties( - VkPhysicalDevice physicalDevice, - uint32_t* pQueueFamilyPropertyCount, - VkQueueFamilyProperties* pQueueFamilyProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceMemoryProperties* pMemoryProperties); - -VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr( - VkInstance instance, - const char* pName); - -VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( - VkDevice device, - const char* pName); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( - VkPhysicalDevice physicalDevice, - const VkDeviceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDevice* pDevice); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDevice( - VkDevice device, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties( - const char* pLayerName, - uint32_t* pPropertyCount, - VkExtensionProperties* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties( - VkPhysicalDevice physicalDevice, - const char* pLayerName, - uint32_t* pPropertyCount, - VkExtensionProperties* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties( - uint32_t* pPropertyCount, - VkLayerProperties* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkLayerProperties* pProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue( - VkDevice device, - uint32_t queueFamilyIndex, - uint32_t queueIndex, - VkQueue* pQueue); - -VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit( - VkQueue queue, - uint32_t submitCount, - const VkSubmitInfo* pSubmits, - VkFence fence); - -VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle( - VkQueue queue); - -VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle( - VkDevice device); - -VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory( - VkDevice device, - const VkMemoryAllocateInfo* pAllocateInfo, - const VkAllocationCallbacks* pAllocator, - VkDeviceMemory* pMemory); - -VKAPI_ATTR void VKAPI_CALL vkFreeMemory( - VkDevice device, - VkDeviceMemory memory, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory( - VkDevice device, - VkDeviceMemory memory, - VkDeviceSize offset, - VkDeviceSize size, - VkMemoryMapFlags flags, - void** ppData); - -VKAPI_ATTR void VKAPI_CALL vkUnmapMemory( - VkDevice device, - VkDeviceMemory memory); - -VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges( - VkDevice device, - uint32_t memoryRangeCount, - const VkMappedMemoryRange* pMemoryRanges); - -VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges( - VkDevice device, - uint32_t memoryRangeCount, - const VkMappedMemoryRange* pMemoryRanges); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment( - VkDevice device, - VkDeviceMemory memory, - VkDeviceSize* pCommittedMemoryInBytes); - -VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory( - VkDevice device, - VkBuffer buffer, - VkDeviceMemory memory, - VkDeviceSize memoryOffset); - -VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory( - VkDevice device, - VkImage image, - VkDeviceMemory memory, - VkDeviceSize memoryOffset); - -VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements( - VkDevice device, - VkBuffer buffer, - VkMemoryRequirements* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements( - VkDevice device, - VkImage image, - VkMemoryRequirements* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements( - VkDevice device, - VkImage image, - uint32_t* pSparseMemoryRequirementCount, - VkSparseImageMemoryRequirements* pSparseMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkImageType type, - VkSampleCountFlagBits samples, - VkImageUsageFlags usage, - VkImageTiling tiling, - uint32_t* pPropertyCount, - VkSparseImageFormatProperties* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse( - VkQueue queue, - uint32_t bindInfoCount, - const VkBindSparseInfo* pBindInfo, - VkFence fence); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence( - VkDevice device, - const VkFenceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkFence* pFence); - -VKAPI_ATTR void VKAPI_CALL vkDestroyFence( - VkDevice device, - VkFence fence, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkResetFences( - VkDevice device, - uint32_t fenceCount, - const VkFence* pFences); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus( - VkDevice device, - VkFence fence); - -VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences( - VkDevice device, - uint32_t fenceCount, - const VkFence* pFences, - VkBool32 waitAll, - uint64_t timeout); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore( - VkDevice device, - const VkSemaphoreCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSemaphore* pSemaphore); - -VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore( - VkDevice device, - VkSemaphore semaphore, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent( - VkDevice device, - const VkEventCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkEvent* pEvent); - -VKAPI_ATTR void VKAPI_CALL vkDestroyEvent( - VkDevice device, - VkEvent event, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus( - VkDevice device, - VkEvent event); - -VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent( - VkDevice device, - VkEvent event); - -VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent( - VkDevice device, - VkEvent event); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool( - VkDevice device, - const VkQueryPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkQueryPool* pQueryPool); - -VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool( - VkDevice device, - VkQueryPool queryPool, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults( - VkDevice device, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - size_t dataSize, - void* pData, - VkDeviceSize stride, - VkQueryResultFlags flags); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer( - VkDevice device, - const VkBufferCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkBuffer* pBuffer); - -VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer( - VkDevice device, - VkBuffer buffer, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView( - VkDevice device, - const VkBufferViewCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkBufferView* pView); - -VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView( - VkDevice device, - VkBufferView bufferView, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage( - VkDevice device, - const VkImageCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImage* pImage); - -VKAPI_ATTR void VKAPI_CALL vkDestroyImage( - VkDevice device, - VkImage image, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout( - VkDevice device, - VkImage image, - const VkImageSubresource* pSubresource, - VkSubresourceLayout* pLayout); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView( - VkDevice device, - const VkImageViewCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImageView* pView); - -VKAPI_ATTR void VKAPI_CALL vkDestroyImageView( - VkDevice device, - VkImageView imageView, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule( - VkDevice device, - const VkShaderModuleCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkShaderModule* pShaderModule); - -VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule( - VkDevice device, - VkShaderModule shaderModule, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache( - VkDevice device, - const VkPipelineCacheCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPipelineCache* pPipelineCache); - -VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache( - VkDevice device, - VkPipelineCache pipelineCache, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData( - VkDevice device, - VkPipelineCache pipelineCache, - size_t* pDataSize, - void* pData); - -VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches( - VkDevice device, - VkPipelineCache dstCache, - uint32_t srcCacheCount, - const VkPipelineCache* pSrcCaches); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines( - VkDevice device, - VkPipelineCache pipelineCache, - uint32_t createInfoCount, - const VkGraphicsPipelineCreateInfo* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines( - VkDevice device, - VkPipelineCache pipelineCache, - uint32_t createInfoCount, - const VkComputePipelineCreateInfo* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines); - -VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline( - VkDevice device, - VkPipeline pipeline, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout( - VkDevice device, - const VkPipelineLayoutCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPipelineLayout* pPipelineLayout); - -VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout( - VkDevice device, - VkPipelineLayout pipelineLayout, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler( - VkDevice device, - const VkSamplerCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSampler* pSampler); - -VKAPI_ATTR void VKAPI_CALL vkDestroySampler( - VkDevice device, - VkSampler sampler, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout( - VkDevice device, - const VkDescriptorSetLayoutCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorSetLayout* pSetLayout); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout( - VkDevice device, - VkDescriptorSetLayout descriptorSetLayout, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool( - VkDevice device, - const VkDescriptorPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorPool* pDescriptorPool); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool( - VkDevice device, - VkDescriptorPool descriptorPool, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool( - VkDevice device, - VkDescriptorPool descriptorPool, - VkDescriptorPoolResetFlags flags); - -VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets( - VkDevice device, - const VkDescriptorSetAllocateInfo* pAllocateInfo, - VkDescriptorSet* pDescriptorSets); - -VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets( - VkDevice device, - VkDescriptorPool descriptorPool, - uint32_t descriptorSetCount, - const VkDescriptorSet* pDescriptorSets); - -VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets( - VkDevice device, - uint32_t descriptorWriteCount, - const VkWriteDescriptorSet* pDescriptorWrites, - uint32_t descriptorCopyCount, - const VkCopyDescriptorSet* pDescriptorCopies); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer( - VkDevice device, - const VkFramebufferCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkFramebuffer* pFramebuffer); - -VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer( - VkDevice device, - VkFramebuffer framebuffer, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass( - VkDevice device, - const VkRenderPassCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkRenderPass* pRenderPass); - -VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass( - VkDevice device, - VkRenderPass renderPass, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity( - VkDevice device, - VkRenderPass renderPass, - VkExtent2D* pGranularity); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool( - VkDevice device, - const VkCommandPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkCommandPool* pCommandPool); - -VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool( - VkDevice device, - VkCommandPool commandPool, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool( - VkDevice device, - VkCommandPool commandPool, - VkCommandPoolResetFlags flags); - -VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers( - VkDevice device, - const VkCommandBufferAllocateInfo* pAllocateInfo, - VkCommandBuffer* pCommandBuffers); - -VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers( - VkDevice device, - VkCommandPool commandPool, - uint32_t commandBufferCount, - const VkCommandBuffer* pCommandBuffers); - -VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer( - VkCommandBuffer commandBuffer, - const VkCommandBufferBeginInfo* pBeginInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer( - VkCommandBuffer commandBuffer); - -VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer( - VkCommandBuffer commandBuffer, - VkCommandBufferResetFlags flags); - -VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline( - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipeline pipeline); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport( - VkCommandBuffer commandBuffer, - uint32_t firstViewport, - uint32_t viewportCount, - const VkViewport* pViewports); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor( - VkCommandBuffer commandBuffer, - uint32_t firstScissor, - uint32_t scissorCount, - const VkRect2D* pScissors); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth( - VkCommandBuffer commandBuffer, - float lineWidth); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias( - VkCommandBuffer commandBuffer, - float depthBiasConstantFactor, - float depthBiasClamp, - float depthBiasSlopeFactor); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants( - VkCommandBuffer commandBuffer, - const float blendConstants[4]); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds( - VkCommandBuffer commandBuffer, - float minDepthBounds, - float maxDepthBounds); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask( - VkCommandBuffer commandBuffer, - VkStencilFaceFlags faceMask, - uint32_t compareMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask( - VkCommandBuffer commandBuffer, - VkStencilFaceFlags faceMask, - uint32_t writeMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference( - VkCommandBuffer commandBuffer, - VkStencilFaceFlags faceMask, - uint32_t reference); - -VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets( - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipelineLayout layout, - uint32_t firstSet, - uint32_t descriptorSetCount, - const VkDescriptorSet* pDescriptorSets, - uint32_t dynamicOffsetCount, - const uint32_t* pDynamicOffsets); - -VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkIndexType indexType); - -VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers( - VkCommandBuffer commandBuffer, - uint32_t firstBinding, - uint32_t bindingCount, - const VkBuffer* pBuffers, - const VkDeviceSize* pOffsets); - -VKAPI_ATTR void VKAPI_CALL vkCmdDraw( - VkCommandBuffer commandBuffer, - uint32_t vertexCount, - uint32_t instanceCount, - uint32_t firstVertex, - uint32_t firstInstance); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed( - VkCommandBuffer commandBuffer, - uint32_t indexCount, - uint32_t instanceCount, - uint32_t firstIndex, - int32_t vertexOffset, - uint32_t firstInstance); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - uint32_t drawCount, - uint32_t stride); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - uint32_t drawCount, - uint32_t stride); - -VKAPI_ATTR void VKAPI_CALL vkCmdDispatch( - VkCommandBuffer commandBuffer, - uint32_t groupCountX, - uint32_t groupCountY, - uint32_t groupCountZ); - -VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer( - VkCommandBuffer commandBuffer, - VkBuffer srcBuffer, - VkBuffer dstBuffer, - uint32_t regionCount, - const VkBufferCopy* pRegions); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageCopy* pRegions); - -VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageBlit* pRegions, - VkFilter filter); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage( - VkCommandBuffer commandBuffer, - VkBuffer srcBuffer, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkBufferImageCopy* pRegions); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkBuffer dstBuffer, - uint32_t regionCount, - const VkBufferImageCopy* pRegions); - -VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer( - VkCommandBuffer commandBuffer, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - VkDeviceSize dataSize, - const void* pData); - -VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer( - VkCommandBuffer commandBuffer, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - VkDeviceSize size, - uint32_t data); - -VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage( - VkCommandBuffer commandBuffer, - VkImage image, - VkImageLayout imageLayout, - const VkClearColorValue* pColor, - uint32_t rangeCount, - const VkImageSubresourceRange* pRanges); - -VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage( - VkCommandBuffer commandBuffer, - VkImage image, - VkImageLayout imageLayout, - const VkClearDepthStencilValue* pDepthStencil, - uint32_t rangeCount, - const VkImageSubresourceRange* pRanges); - -VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments( - VkCommandBuffer commandBuffer, - uint32_t attachmentCount, - const VkClearAttachment* pAttachments, - uint32_t rectCount, - const VkClearRect* pRects); - -VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageResolve* pRegions); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent( - VkCommandBuffer commandBuffer, - VkEvent event, - VkPipelineStageFlags stageMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent( - VkCommandBuffer commandBuffer, - VkEvent event, - VkPipelineStageFlags stageMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents( - VkCommandBuffer commandBuffer, - uint32_t eventCount, - const VkEvent* pEvents, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - uint32_t memoryBarrierCount, - const VkMemoryBarrier* pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier* pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier* pImageMemoryBarriers); - -VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier( - VkCommandBuffer commandBuffer, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - VkDependencyFlags dependencyFlags, - uint32_t memoryBarrierCount, - const VkMemoryBarrier* pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier* pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier* pImageMemoryBarriers); - -VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query, - VkQueryControlFlags flags); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query); - -VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount); - -VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp( - VkCommandBuffer commandBuffer, - VkPipelineStageFlagBits pipelineStage, - VkQueryPool queryPool, - uint32_t query); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - VkDeviceSize stride, - VkQueryResultFlags flags); - -VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants( - VkCommandBuffer commandBuffer, - VkPipelineLayout layout, - VkShaderStageFlags stageFlags, - uint32_t offset, - uint32_t size, - const void* pValues); - -VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass( - VkCommandBuffer commandBuffer, - const VkRenderPassBeginInfo* pRenderPassBegin, - VkSubpassContents contents); - -VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass( - VkCommandBuffer commandBuffer, - VkSubpassContents contents); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass( - VkCommandBuffer commandBuffer); - -VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands( - VkCommandBuffer commandBuffer, - uint32_t commandBufferCount, - const VkCommandBuffer* pCommandBuffers); -#endif - - -#define VK_VERSION_1_1 1 -// Vulkan 1.1 version number -#define VK_API_VERSION_1_1 VK_MAKE_API_VERSION(0, 1, 1, 0)// Patch version should always be set to 0 - -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversion) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplate) -#define VK_MAX_DEVICE_GROUP_SIZE 32U -#define VK_LUID_SIZE 8U -#define VK_QUEUE_FAMILY_EXTERNAL (~1U) - -typedef enum VkPointClippingBehavior { - VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES = 0, - VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY = 1, - VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES, - VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY, - VK_POINT_CLIPPING_BEHAVIOR_MAX_ENUM = 0x7FFFFFFF -} VkPointClippingBehavior; - -typedef enum VkTessellationDomainOrigin { - VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT = 0, - VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1, - VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT, - VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT, - VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM = 0x7FFFFFFF -} VkTessellationDomainOrigin; - -typedef enum VkSamplerYcbcrModelConversion { - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY = 1, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 = 2, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 = 3, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 = 4, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020, - VK_SAMPLER_YCBCR_MODEL_CONVERSION_MAX_ENUM = 0x7FFFFFFF -} VkSamplerYcbcrModelConversion; - -typedef enum VkSamplerYcbcrRange { - VK_SAMPLER_YCBCR_RANGE_ITU_FULL = 0, - VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1, - VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_FULL, - VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, - VK_SAMPLER_YCBCR_RANGE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerYcbcrRange; - -typedef enum VkChromaLocation { - VK_CHROMA_LOCATION_COSITED_EVEN = 0, - VK_CHROMA_LOCATION_MIDPOINT = 1, - VK_CHROMA_LOCATION_COSITED_EVEN_KHR = VK_CHROMA_LOCATION_COSITED_EVEN, - VK_CHROMA_LOCATION_MIDPOINT_KHR = VK_CHROMA_LOCATION_MIDPOINT, - VK_CHROMA_LOCATION_MAX_ENUM = 0x7FFFFFFF -} VkChromaLocation; - -typedef enum VkDescriptorUpdateTemplateType { - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, - VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorUpdateTemplateType; - -typedef enum VkSubgroupFeatureFlagBits { - VK_SUBGROUP_FEATURE_BASIC_BIT = 0x00000001, - VK_SUBGROUP_FEATURE_VOTE_BIT = 0x00000002, - VK_SUBGROUP_FEATURE_ARITHMETIC_BIT = 0x00000004, - VK_SUBGROUP_FEATURE_BALLOT_BIT = 0x00000008, - VK_SUBGROUP_FEATURE_SHUFFLE_BIT = 0x00000010, - VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 0x00000020, - VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 0x00000040, - VK_SUBGROUP_FEATURE_QUAD_BIT = 0x00000080, - VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV = 0x00000100, - VK_SUBGROUP_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSubgroupFeatureFlagBits; -typedef VkFlags VkSubgroupFeatureFlags; - -typedef enum VkPeerMemoryFeatureFlagBits { - VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT = 0x00000001, - VK_PEER_MEMORY_FEATURE_COPY_DST_BIT = 0x00000002, - VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT = 0x00000004, - VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT = 0x00000008, - VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT_KHR = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT, - VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHR = VK_PEER_MEMORY_FEATURE_COPY_DST_BIT, - VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT_KHR = VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT, - VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT_KHR = VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT, - VK_PEER_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPeerMemoryFeatureFlagBits; -typedef VkFlags VkPeerMemoryFeatureFlags; - -typedef enum VkMemoryAllocateFlagBits { - VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 0x00000001, - VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT = 0x00000002, - VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000004, - VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT, - VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, - VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, - VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkMemoryAllocateFlagBits; -typedef VkFlags VkMemoryAllocateFlags; -typedef VkFlags VkCommandPoolTrimFlags; -typedef VkFlags VkDescriptorUpdateTemplateCreateFlags; - -typedef enum VkExternalMemoryHandleTypeFlagBits { - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT = 0x00000008, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT = 0x00000010, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT = 0x00000020, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT = 0x00000040, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT = 0x00000200, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID = 0x00000400, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT = 0x00000080, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA = 0x00000800, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV = 0x00001000, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalMemoryHandleTypeFlagBits; -typedef VkFlags VkExternalMemoryHandleTypeFlags; - -typedef enum VkExternalMemoryFeatureFlagBits { - VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT = 0x00000001, - VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT = 0x00000002, - VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT = 0x00000004, - VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT, - VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT, - VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, - VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalMemoryFeatureFlagBits; -typedef VkFlags VkExternalMemoryFeatureFlags; - -typedef enum VkExternalFenceHandleTypeFlagBits { - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, - VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000008, - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT, - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT, - VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, - VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT, - VK_EXTERNAL_FENCE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalFenceHandleTypeFlagBits; -typedef VkFlags VkExternalFenceHandleTypeFlags; - -typedef enum VkExternalFenceFeatureFlagBits { - VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT = 0x00000001, - VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT = 0x00000002, - VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT, - VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT, - VK_EXTERNAL_FENCE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalFenceFeatureFlagBits; -typedef VkFlags VkExternalFenceFeatureFlags; - -typedef enum VkFenceImportFlagBits { - VK_FENCE_IMPORT_TEMPORARY_BIT = 0x00000001, - VK_FENCE_IMPORT_TEMPORARY_BIT_KHR = VK_FENCE_IMPORT_TEMPORARY_BIT, - VK_FENCE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkFenceImportFlagBits; -typedef VkFlags VkFenceImportFlags; - -typedef enum VkSemaphoreImportFlagBits { - VK_SEMAPHORE_IMPORT_TEMPORARY_BIT = 0x00000001, - VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT, - VK_SEMAPHORE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSemaphoreImportFlagBits; -typedef VkFlags VkSemaphoreImportFlags; - -typedef enum VkExternalSemaphoreHandleTypeFlagBits { - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT = 0x00000008, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000010, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA = 0x00000080, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE_BIT = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, - VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalSemaphoreHandleTypeFlagBits; -typedef VkFlags VkExternalSemaphoreHandleTypeFlags; - -typedef enum VkExternalSemaphoreFeatureFlagBits { - VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT = 0x00000001, - VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT = 0x00000002, - VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT, - VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT, - VK_EXTERNAL_SEMAPHORE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkExternalSemaphoreFeatureFlagBits; -typedef VkFlags VkExternalSemaphoreFeatureFlags; -typedef struct VkPhysicalDeviceSubgroupProperties { - VkStructureType sType; - void* pNext; - uint32_t subgroupSize; - VkShaderStageFlags supportedStages; - VkSubgroupFeatureFlags supportedOperations; - VkBool32 quadOperationsInAllStages; -} VkPhysicalDeviceSubgroupProperties; - -typedef struct VkBindBufferMemoryInfo { - VkStructureType sType; - const void* pNext; - VkBuffer buffer; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; -} VkBindBufferMemoryInfo; - -typedef struct VkBindImageMemoryInfo { - VkStructureType sType; - const void* pNext; - VkImage image; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; -} VkBindImageMemoryInfo; - -typedef struct VkPhysicalDevice16BitStorageFeatures { - VkStructureType sType; - void* pNext; - VkBool32 storageBuffer16BitAccess; - VkBool32 uniformAndStorageBuffer16BitAccess; - VkBool32 storagePushConstant16; - VkBool32 storageInputOutput16; -} VkPhysicalDevice16BitStorageFeatures; - -typedef struct VkMemoryDedicatedRequirements { - VkStructureType sType; - void* pNext; - VkBool32 prefersDedicatedAllocation; - VkBool32 requiresDedicatedAllocation; -} VkMemoryDedicatedRequirements; - -typedef struct VkMemoryDedicatedAllocateInfo { - VkStructureType sType; - const void* pNext; - VkImage image; - VkBuffer buffer; -} VkMemoryDedicatedAllocateInfo; - -typedef struct VkMemoryAllocateFlagsInfo { - VkStructureType sType; - const void* pNext; - VkMemoryAllocateFlags flags; - uint32_t deviceMask; -} VkMemoryAllocateFlagsInfo; - -typedef struct VkDeviceGroupRenderPassBeginInfo { - VkStructureType sType; - const void* pNext; - uint32_t deviceMask; - uint32_t deviceRenderAreaCount; - const VkRect2D* pDeviceRenderAreas; -} VkDeviceGroupRenderPassBeginInfo; - -typedef struct VkDeviceGroupCommandBufferBeginInfo { - VkStructureType sType; - const void* pNext; - uint32_t deviceMask; -} VkDeviceGroupCommandBufferBeginInfo; - -typedef struct VkDeviceGroupSubmitInfo { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreCount; - const uint32_t* pWaitSemaphoreDeviceIndices; - uint32_t commandBufferCount; - const uint32_t* pCommandBufferDeviceMasks; - uint32_t signalSemaphoreCount; - const uint32_t* pSignalSemaphoreDeviceIndices; -} VkDeviceGroupSubmitInfo; - -typedef struct VkDeviceGroupBindSparseInfo { - VkStructureType sType; - const void* pNext; - uint32_t resourceDeviceIndex; - uint32_t memoryDeviceIndex; -} VkDeviceGroupBindSparseInfo; - -typedef struct VkBindBufferMemoryDeviceGroupInfo { - VkStructureType sType; - const void* pNext; - uint32_t deviceIndexCount; - const uint32_t* pDeviceIndices; -} VkBindBufferMemoryDeviceGroupInfo; - -typedef struct VkBindImageMemoryDeviceGroupInfo { - VkStructureType sType; - const void* pNext; - uint32_t deviceIndexCount; - const uint32_t* pDeviceIndices; - uint32_t splitInstanceBindRegionCount; - const VkRect2D* pSplitInstanceBindRegions; -} VkBindImageMemoryDeviceGroupInfo; - -typedef struct VkPhysicalDeviceGroupProperties { - VkStructureType sType; - void* pNext; - uint32_t physicalDeviceCount; - VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE]; - VkBool32 subsetAllocation; -} VkPhysicalDeviceGroupProperties; - -typedef struct VkDeviceGroupDeviceCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t physicalDeviceCount; - const VkPhysicalDevice* pPhysicalDevices; -} VkDeviceGroupDeviceCreateInfo; - -typedef struct VkBufferMemoryRequirementsInfo2 { - VkStructureType sType; - const void* pNext; - VkBuffer buffer; -} VkBufferMemoryRequirementsInfo2; - -typedef struct VkImageMemoryRequirementsInfo2 { - VkStructureType sType; - const void* pNext; - VkImage image; -} VkImageMemoryRequirementsInfo2; - -typedef struct VkImageSparseMemoryRequirementsInfo2 { - VkStructureType sType; - const void* pNext; - VkImage image; -} VkImageSparseMemoryRequirementsInfo2; - -typedef struct VkMemoryRequirements2 { - VkStructureType sType; - void* pNext; - VkMemoryRequirements memoryRequirements; -} VkMemoryRequirements2; - -typedef struct VkSparseImageMemoryRequirements2 { - VkStructureType sType; - void* pNext; - VkSparseImageMemoryRequirements memoryRequirements; -} VkSparseImageMemoryRequirements2; - -typedef struct VkPhysicalDeviceFeatures2 { - VkStructureType sType; - void* pNext; - VkPhysicalDeviceFeatures features; -} VkPhysicalDeviceFeatures2; - -typedef struct VkPhysicalDeviceProperties2 { - VkStructureType sType; - void* pNext; - VkPhysicalDeviceProperties properties; -} VkPhysicalDeviceProperties2; - -typedef struct VkFormatProperties2 { - VkStructureType sType; - void* pNext; - VkFormatProperties formatProperties; -} VkFormatProperties2; - -typedef struct VkImageFormatProperties2 { - VkStructureType sType; - void* pNext; - VkImageFormatProperties imageFormatProperties; -} VkImageFormatProperties2; - -typedef struct VkPhysicalDeviceImageFormatInfo2 { - VkStructureType sType; - const void* pNext; - VkFormat format; - VkImageType type; - VkImageTiling tiling; - VkImageUsageFlags usage; - VkImageCreateFlags flags; -} VkPhysicalDeviceImageFormatInfo2; - -typedef struct VkQueueFamilyProperties2 { - VkStructureType sType; - void* pNext; - VkQueueFamilyProperties queueFamilyProperties; -} VkQueueFamilyProperties2; - -typedef struct VkPhysicalDeviceMemoryProperties2 { - VkStructureType sType; - void* pNext; - VkPhysicalDeviceMemoryProperties memoryProperties; -} VkPhysicalDeviceMemoryProperties2; - -typedef struct VkSparseImageFormatProperties2 { - VkStructureType sType; - void* pNext; - VkSparseImageFormatProperties properties; -} VkSparseImageFormatProperties2; - -typedef struct VkPhysicalDeviceSparseImageFormatInfo2 { - VkStructureType sType; - const void* pNext; - VkFormat format; - VkImageType type; - VkSampleCountFlagBits samples; - VkImageUsageFlags usage; - VkImageTiling tiling; -} VkPhysicalDeviceSparseImageFormatInfo2; - -typedef struct VkPhysicalDevicePointClippingProperties { - VkStructureType sType; - void* pNext; - VkPointClippingBehavior pointClippingBehavior; -} VkPhysicalDevicePointClippingProperties; - -typedef struct VkInputAttachmentAspectReference { - uint32_t subpass; - uint32_t inputAttachmentIndex; - VkImageAspectFlags aspectMask; -} VkInputAttachmentAspectReference; - -typedef struct VkRenderPassInputAttachmentAspectCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t aspectReferenceCount; - const VkInputAttachmentAspectReference* pAspectReferences; -} VkRenderPassInputAttachmentAspectCreateInfo; - -typedef struct VkImageViewUsageCreateInfo { - VkStructureType sType; - const void* pNext; - VkImageUsageFlags usage; -} VkImageViewUsageCreateInfo; - -typedef struct VkPipelineTessellationDomainOriginStateCreateInfo { - VkStructureType sType; - const void* pNext; - VkTessellationDomainOrigin domainOrigin; -} VkPipelineTessellationDomainOriginStateCreateInfo; - -typedef struct VkRenderPassMultiviewCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t subpassCount; - const uint32_t* pViewMasks; - uint32_t dependencyCount; - const int32_t* pViewOffsets; - uint32_t correlationMaskCount; - const uint32_t* pCorrelationMasks; -} VkRenderPassMultiviewCreateInfo; - -typedef struct VkPhysicalDeviceMultiviewFeatures { - VkStructureType sType; - void* pNext; - VkBool32 multiview; - VkBool32 multiviewGeometryShader; - VkBool32 multiviewTessellationShader; -} VkPhysicalDeviceMultiviewFeatures; - -typedef struct VkPhysicalDeviceMultiviewProperties { - VkStructureType sType; - void* pNext; - uint32_t maxMultiviewViewCount; - uint32_t maxMultiviewInstanceIndex; -} VkPhysicalDeviceMultiviewProperties; - -typedef struct VkPhysicalDeviceVariablePointersFeatures { - VkStructureType sType; - void* pNext; - VkBool32 variablePointersStorageBuffer; - VkBool32 variablePointers; -} VkPhysicalDeviceVariablePointersFeatures; - -typedef VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointerFeatures; - -typedef struct VkPhysicalDeviceProtectedMemoryFeatures { - VkStructureType sType; - void* pNext; - VkBool32 protectedMemory; -} VkPhysicalDeviceProtectedMemoryFeatures; - -typedef struct VkPhysicalDeviceProtectedMemoryProperties { - VkStructureType sType; - void* pNext; - VkBool32 protectedNoFault; -} VkPhysicalDeviceProtectedMemoryProperties; - -typedef struct VkDeviceQueueInfo2 { - VkStructureType sType; - const void* pNext; - VkDeviceQueueCreateFlags flags; - uint32_t queueFamilyIndex; - uint32_t queueIndex; -} VkDeviceQueueInfo2; - -typedef struct VkProtectedSubmitInfo { - VkStructureType sType; - const void* pNext; - VkBool32 protectedSubmit; -} VkProtectedSubmitInfo; - -typedef struct VkSamplerYcbcrConversionCreateInfo { - VkStructureType sType; - const void* pNext; - VkFormat format; - VkSamplerYcbcrModelConversion ycbcrModel; - VkSamplerYcbcrRange ycbcrRange; - VkComponentMapping components; - VkChromaLocation xChromaOffset; - VkChromaLocation yChromaOffset; - VkFilter chromaFilter; - VkBool32 forceExplicitReconstruction; -} VkSamplerYcbcrConversionCreateInfo; - -typedef struct VkSamplerYcbcrConversionInfo { - VkStructureType sType; - const void* pNext; - VkSamplerYcbcrConversion conversion; -} VkSamplerYcbcrConversionInfo; - -typedef struct VkBindImagePlaneMemoryInfo { - VkStructureType sType; - const void* pNext; - VkImageAspectFlagBits planeAspect; -} VkBindImagePlaneMemoryInfo; - -typedef struct VkImagePlaneMemoryRequirementsInfo { - VkStructureType sType; - const void* pNext; - VkImageAspectFlagBits planeAspect; -} VkImagePlaneMemoryRequirementsInfo; - -typedef struct VkPhysicalDeviceSamplerYcbcrConversionFeatures { - VkStructureType sType; - void* pNext; - VkBool32 samplerYcbcrConversion; -} VkPhysicalDeviceSamplerYcbcrConversionFeatures; - -typedef struct VkSamplerYcbcrConversionImageFormatProperties { - VkStructureType sType; - void* pNext; - uint32_t combinedImageSamplerDescriptorCount; -} VkSamplerYcbcrConversionImageFormatProperties; - -typedef struct VkDescriptorUpdateTemplateEntry { - uint32_t dstBinding; - uint32_t dstArrayElement; - uint32_t descriptorCount; - VkDescriptorType descriptorType; - size_t offset; - size_t stride; -} VkDescriptorUpdateTemplateEntry; - -typedef struct VkDescriptorUpdateTemplateCreateInfo { - VkStructureType sType; - const void* pNext; - VkDescriptorUpdateTemplateCreateFlags flags; - uint32_t descriptorUpdateEntryCount; - const VkDescriptorUpdateTemplateEntry* pDescriptorUpdateEntries; - VkDescriptorUpdateTemplateType templateType; - VkDescriptorSetLayout descriptorSetLayout; - VkPipelineBindPoint pipelineBindPoint; - VkPipelineLayout pipelineLayout; - uint32_t set; -} VkDescriptorUpdateTemplateCreateInfo; - -typedef struct VkExternalMemoryProperties { - VkExternalMemoryFeatureFlags externalMemoryFeatures; - VkExternalMemoryHandleTypeFlags exportFromImportedHandleTypes; - VkExternalMemoryHandleTypeFlags compatibleHandleTypes; -} VkExternalMemoryProperties; - -typedef struct VkPhysicalDeviceExternalImageFormatInfo { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagBits handleType; -} VkPhysicalDeviceExternalImageFormatInfo; - -typedef struct VkExternalImageFormatProperties { - VkStructureType sType; - void* pNext; - VkExternalMemoryProperties externalMemoryProperties; -} VkExternalImageFormatProperties; - -typedef struct VkPhysicalDeviceExternalBufferInfo { - VkStructureType sType; - const void* pNext; - VkBufferCreateFlags flags; - VkBufferUsageFlags usage; - VkExternalMemoryHandleTypeFlagBits handleType; -} VkPhysicalDeviceExternalBufferInfo; - -typedef struct VkExternalBufferProperties { - VkStructureType sType; - void* pNext; - VkExternalMemoryProperties externalMemoryProperties; -} VkExternalBufferProperties; - -typedef struct VkPhysicalDeviceIDProperties { - VkStructureType sType; - void* pNext; - uint8_t deviceUUID[VK_UUID_SIZE]; - uint8_t driverUUID[VK_UUID_SIZE]; - uint8_t deviceLUID[VK_LUID_SIZE]; - uint32_t deviceNodeMask; - VkBool32 deviceLUIDValid; -} VkPhysicalDeviceIDProperties; - -typedef struct VkExternalMemoryImageCreateInfo { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlags handleTypes; -} VkExternalMemoryImageCreateInfo; - -typedef struct VkExternalMemoryBufferCreateInfo { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlags handleTypes; -} VkExternalMemoryBufferCreateInfo; - -typedef struct VkExportMemoryAllocateInfo { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlags handleTypes; -} VkExportMemoryAllocateInfo; - -typedef struct VkPhysicalDeviceExternalFenceInfo { - VkStructureType sType; - const void* pNext; - VkExternalFenceHandleTypeFlagBits handleType; -} VkPhysicalDeviceExternalFenceInfo; - -typedef struct VkExternalFenceProperties { - VkStructureType sType; - void* pNext; - VkExternalFenceHandleTypeFlags exportFromImportedHandleTypes; - VkExternalFenceHandleTypeFlags compatibleHandleTypes; - VkExternalFenceFeatureFlags externalFenceFeatures; -} VkExternalFenceProperties; - -typedef struct VkExportFenceCreateInfo { - VkStructureType sType; - const void* pNext; - VkExternalFenceHandleTypeFlags handleTypes; -} VkExportFenceCreateInfo; - -typedef struct VkExportSemaphoreCreateInfo { - VkStructureType sType; - const void* pNext; - VkExternalSemaphoreHandleTypeFlags handleTypes; -} VkExportSemaphoreCreateInfo; - -typedef struct VkPhysicalDeviceExternalSemaphoreInfo { - VkStructureType sType; - const void* pNext; - VkExternalSemaphoreHandleTypeFlagBits handleType; -} VkPhysicalDeviceExternalSemaphoreInfo; - -typedef struct VkExternalSemaphoreProperties { - VkStructureType sType; - void* pNext; - VkExternalSemaphoreHandleTypeFlags exportFromImportedHandleTypes; - VkExternalSemaphoreHandleTypeFlags compatibleHandleTypes; - VkExternalSemaphoreFeatureFlags externalSemaphoreFeatures; -} VkExternalSemaphoreProperties; - -typedef struct VkPhysicalDeviceMaintenance3Properties { - VkStructureType sType; - void* pNext; - uint32_t maxPerSetDescriptors; - VkDeviceSize maxMemoryAllocationSize; -} VkPhysicalDeviceMaintenance3Properties; - -typedef struct VkDescriptorSetLayoutSupport { - VkStructureType sType; - void* pNext; - VkBool32 supported; -} VkDescriptorSetLayoutSupport; - -typedef struct VkPhysicalDeviceShaderDrawParametersFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderDrawParameters; -} VkPhysicalDeviceShaderDrawParametersFeatures; - -typedef VkPhysicalDeviceShaderDrawParametersFeatures VkPhysicalDeviceShaderDrawParameterFeatures; - -typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t* pApiVersion); -typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos); -typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos); -typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeatures)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); -typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMask)(VkCommandBuffer commandBuffer, uint32_t deviceMask); -typedef void (VKAPI_PTR *PFN_vkCmdDispatchBase)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); -typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroups)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); -typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2)(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2)(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties); -typedef void (VKAPI_PTR *PFN_vkTrimCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); -typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue2)(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue); -typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversion)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion); -typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversion)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplate)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); -typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplate)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplate)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFenceProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties); -typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupport)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion( - uint32_t* pApiVersion); - -VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2( - VkDevice device, - uint32_t bindInfoCount, - const VkBindBufferMemoryInfo* pBindInfos); - -VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2( - VkDevice device, - uint32_t bindInfoCount, - const VkBindImageMemoryInfo* pBindInfos); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeatures( - VkDevice device, - uint32_t heapIndex, - uint32_t localDeviceIndex, - uint32_t remoteDeviceIndex, - VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMask( - VkCommandBuffer commandBuffer, - uint32_t deviceMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBase( - VkCommandBuffer commandBuffer, - uint32_t baseGroupX, - uint32_t baseGroupY, - uint32_t baseGroupZ, - uint32_t groupCountX, - uint32_t groupCountY, - uint32_t groupCountZ); - -VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups( - VkInstance instance, - uint32_t* pPhysicalDeviceGroupCount, - VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2( - VkDevice device, - const VkImageMemoryRequirementsInfo2* pInfo, - VkMemoryRequirements2* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2( - VkDevice device, - const VkBufferMemoryRequirementsInfo2* pInfo, - VkMemoryRequirements2* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2( - VkDevice device, - const VkImageSparseMemoryRequirementsInfo2* pInfo, - uint32_t* pSparseMemoryRequirementCount, - VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceFeatures2* pFeatures); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceProperties2* pProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkFormatProperties2* pFormatProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, - VkImageFormatProperties2* pImageFormatProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2( - VkPhysicalDevice physicalDevice, - uint32_t* pQueueFamilyPropertyCount, - VkQueueFamilyProperties2* pQueueFamilyProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceMemoryProperties2* pMemoryProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, - uint32_t* pPropertyCount, - VkSparseImageFormatProperties2* pProperties); - -VKAPI_ATTR void VKAPI_CALL vkTrimCommandPool( - VkDevice device, - VkCommandPool commandPool, - VkCommandPoolTrimFlags flags); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue2( - VkDevice device, - const VkDeviceQueueInfo2* pQueueInfo, - VkQueue* pQueue); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion( - VkDevice device, - const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSamplerYcbcrConversion* pYcbcrConversion); - -VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion( - VkDevice device, - VkSamplerYcbcrConversion ycbcrConversion, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplate( - VkDevice device, - const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplate( - VkDevice device, - VkDescriptorUpdateTemplate descriptorUpdateTemplate, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplate( - VkDevice device, - VkDescriptorSet descriptorSet, - VkDescriptorUpdateTemplate descriptorUpdateTemplate, - const void* pData); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, - VkExternalBufferProperties* pExternalBufferProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFenceProperties( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, - VkExternalFenceProperties* pExternalFenceProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphoreProperties( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, - VkExternalSemaphoreProperties* pExternalSemaphoreProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport( - VkDevice device, - const VkDescriptorSetLayoutCreateInfo* pCreateInfo, - VkDescriptorSetLayoutSupport* pSupport); -#endif - - -#define VK_VERSION_1_2 1 -// Vulkan 1.2 version number -#define VK_API_VERSION_1_2 VK_MAKE_API_VERSION(0, 1, 2, 0)// Patch version should always be set to 0 - -#define VK_MAX_DRIVER_NAME_SIZE 256U -#define VK_MAX_DRIVER_INFO_SIZE 256U - -typedef enum VkDriverId { - VK_DRIVER_ID_AMD_PROPRIETARY = 1, - VK_DRIVER_ID_AMD_OPEN_SOURCE = 2, - VK_DRIVER_ID_MESA_RADV = 3, - VK_DRIVER_ID_NVIDIA_PROPRIETARY = 4, - VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS = 5, - VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA = 6, - VK_DRIVER_ID_IMAGINATION_PROPRIETARY = 7, - VK_DRIVER_ID_QUALCOMM_PROPRIETARY = 8, - VK_DRIVER_ID_ARM_PROPRIETARY = 9, - VK_DRIVER_ID_GOOGLE_SWIFTSHADER = 10, - VK_DRIVER_ID_GGP_PROPRIETARY = 11, - VK_DRIVER_ID_BROADCOM_PROPRIETARY = 12, - VK_DRIVER_ID_MESA_LLVMPIPE = 13, - VK_DRIVER_ID_MOLTENVK = 14, - VK_DRIVER_ID_COREAVI_PROPRIETARY = 15, - VK_DRIVER_ID_JUICE_PROPRIETARY = 16, - VK_DRIVER_ID_VERISILICON_PROPRIETARY = 17, - VK_DRIVER_ID_MESA_TURNIP = 18, - VK_DRIVER_ID_MESA_V3DV = 19, - VK_DRIVER_ID_MESA_PANVK = 20, - VK_DRIVER_ID_SAMSUNG_PROPRIETARY = 21, - VK_DRIVER_ID_MESA_VENUS = 22, - VK_DRIVER_ID_MESA_DOZEN = 23, - VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY, - VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE, - VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV, - VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = VK_DRIVER_ID_NVIDIA_PROPRIETARY, - VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS, - VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA, - VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = VK_DRIVER_ID_IMAGINATION_PROPRIETARY, - VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = VK_DRIVER_ID_QUALCOMM_PROPRIETARY, - VK_DRIVER_ID_ARM_PROPRIETARY_KHR = VK_DRIVER_ID_ARM_PROPRIETARY, - VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = VK_DRIVER_ID_GOOGLE_SWIFTSHADER, - VK_DRIVER_ID_GGP_PROPRIETARY_KHR = VK_DRIVER_ID_GGP_PROPRIETARY, - VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY, - VK_DRIVER_ID_MAX_ENUM = 0x7FFFFFFF -} VkDriverId; - -typedef enum VkShaderFloatControlsIndependence { - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY = 0, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL = 1, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE = 2, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE, - VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM = 0x7FFFFFFF -} VkShaderFloatControlsIndependence; - -typedef enum VkSamplerReductionMode { - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE = 0, - VK_SAMPLER_REDUCTION_MODE_MIN = 1, - VK_SAMPLER_REDUCTION_MODE_MAX = 2, - VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE, - VK_SAMPLER_REDUCTION_MODE_MIN_EXT = VK_SAMPLER_REDUCTION_MODE_MIN, - VK_SAMPLER_REDUCTION_MODE_MAX_EXT = VK_SAMPLER_REDUCTION_MODE_MAX, - VK_SAMPLER_REDUCTION_MODE_MAX_ENUM = 0x7FFFFFFF -} VkSamplerReductionMode; - -typedef enum VkSemaphoreType { - VK_SEMAPHORE_TYPE_BINARY = 0, - VK_SEMAPHORE_TYPE_TIMELINE = 1, - VK_SEMAPHORE_TYPE_BINARY_KHR = VK_SEMAPHORE_TYPE_BINARY, - VK_SEMAPHORE_TYPE_TIMELINE_KHR = VK_SEMAPHORE_TYPE_TIMELINE, - VK_SEMAPHORE_TYPE_MAX_ENUM = 0x7FFFFFFF -} VkSemaphoreType; - -typedef enum VkResolveModeFlagBits { - VK_RESOLVE_MODE_NONE = 0, - VK_RESOLVE_MODE_SAMPLE_ZERO_BIT = 0x00000001, - VK_RESOLVE_MODE_AVERAGE_BIT = 0x00000002, - VK_RESOLVE_MODE_MIN_BIT = 0x00000004, - VK_RESOLVE_MODE_MAX_BIT = 0x00000008, - VK_RESOLVE_MODE_NONE_KHR = VK_RESOLVE_MODE_NONE, - VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, - VK_RESOLVE_MODE_AVERAGE_BIT_KHR = VK_RESOLVE_MODE_AVERAGE_BIT, - VK_RESOLVE_MODE_MIN_BIT_KHR = VK_RESOLVE_MODE_MIN_BIT, - VK_RESOLVE_MODE_MAX_BIT_KHR = VK_RESOLVE_MODE_MAX_BIT, - VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkResolveModeFlagBits; -typedef VkFlags VkResolveModeFlags; - -typedef enum VkDescriptorBindingFlagBits { - VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 0x00000001, - VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002, - VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004, - VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008, - VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, - VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, - VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT, - VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT, - VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkDescriptorBindingFlagBits; -typedef VkFlags VkDescriptorBindingFlags; - -typedef enum VkSemaphoreWaitFlagBits { - VK_SEMAPHORE_WAIT_ANY_BIT = 0x00000001, - VK_SEMAPHORE_WAIT_ANY_BIT_KHR = VK_SEMAPHORE_WAIT_ANY_BIT, - VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSemaphoreWaitFlagBits; -typedef VkFlags VkSemaphoreWaitFlags; -typedef struct VkPhysicalDeviceVulkan11Features { - VkStructureType sType; - void* pNext; - VkBool32 storageBuffer16BitAccess; - VkBool32 uniformAndStorageBuffer16BitAccess; - VkBool32 storagePushConstant16; - VkBool32 storageInputOutput16; - VkBool32 multiview; - VkBool32 multiviewGeometryShader; - VkBool32 multiviewTessellationShader; - VkBool32 variablePointersStorageBuffer; - VkBool32 variablePointers; - VkBool32 protectedMemory; - VkBool32 samplerYcbcrConversion; - VkBool32 shaderDrawParameters; -} VkPhysicalDeviceVulkan11Features; - -typedef struct VkPhysicalDeviceVulkan11Properties { - VkStructureType sType; - void* pNext; - uint8_t deviceUUID[VK_UUID_SIZE]; - uint8_t driverUUID[VK_UUID_SIZE]; - uint8_t deviceLUID[VK_LUID_SIZE]; - uint32_t deviceNodeMask; - VkBool32 deviceLUIDValid; - uint32_t subgroupSize; - VkShaderStageFlags subgroupSupportedStages; - VkSubgroupFeatureFlags subgroupSupportedOperations; - VkBool32 subgroupQuadOperationsInAllStages; - VkPointClippingBehavior pointClippingBehavior; - uint32_t maxMultiviewViewCount; - uint32_t maxMultiviewInstanceIndex; - VkBool32 protectedNoFault; - uint32_t maxPerSetDescriptors; - VkDeviceSize maxMemoryAllocationSize; -} VkPhysicalDeviceVulkan11Properties; - -typedef struct VkPhysicalDeviceVulkan12Features { - VkStructureType sType; - void* pNext; - VkBool32 samplerMirrorClampToEdge; - VkBool32 drawIndirectCount; - VkBool32 storageBuffer8BitAccess; - VkBool32 uniformAndStorageBuffer8BitAccess; - VkBool32 storagePushConstant8; - VkBool32 shaderBufferInt64Atomics; - VkBool32 shaderSharedInt64Atomics; - VkBool32 shaderFloat16; - VkBool32 shaderInt8; - VkBool32 descriptorIndexing; - VkBool32 shaderInputAttachmentArrayDynamicIndexing; - VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; - VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; - VkBool32 shaderUniformBufferArrayNonUniformIndexing; - VkBool32 shaderSampledImageArrayNonUniformIndexing; - VkBool32 shaderStorageBufferArrayNonUniformIndexing; - VkBool32 shaderStorageImageArrayNonUniformIndexing; - VkBool32 shaderInputAttachmentArrayNonUniformIndexing; - VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; - VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; - VkBool32 descriptorBindingUniformBufferUpdateAfterBind; - VkBool32 descriptorBindingSampledImageUpdateAfterBind; - VkBool32 descriptorBindingStorageImageUpdateAfterBind; - VkBool32 descriptorBindingStorageBufferUpdateAfterBind; - VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingUpdateUnusedWhilePending; - VkBool32 descriptorBindingPartiallyBound; - VkBool32 descriptorBindingVariableDescriptorCount; - VkBool32 runtimeDescriptorArray; - VkBool32 samplerFilterMinmax; - VkBool32 scalarBlockLayout; - VkBool32 imagelessFramebuffer; - VkBool32 uniformBufferStandardLayout; - VkBool32 shaderSubgroupExtendedTypes; - VkBool32 separateDepthStencilLayouts; - VkBool32 hostQueryReset; - VkBool32 timelineSemaphore; - VkBool32 bufferDeviceAddress; - VkBool32 bufferDeviceAddressCaptureReplay; - VkBool32 bufferDeviceAddressMultiDevice; - VkBool32 vulkanMemoryModel; - VkBool32 vulkanMemoryModelDeviceScope; - VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; - VkBool32 shaderOutputViewportIndex; - VkBool32 shaderOutputLayer; - VkBool32 subgroupBroadcastDynamicId; -} VkPhysicalDeviceVulkan12Features; - -typedef struct VkConformanceVersion { - uint8_t major; - uint8_t minor; - uint8_t subminor; - uint8_t patch; -} VkConformanceVersion; - -typedef struct VkPhysicalDeviceVulkan12Properties { - VkStructureType sType; - void* pNext; - VkDriverId driverID; - char driverName[VK_MAX_DRIVER_NAME_SIZE]; - char driverInfo[VK_MAX_DRIVER_INFO_SIZE]; - VkConformanceVersion conformanceVersion; - VkShaderFloatControlsIndependence denormBehaviorIndependence; - VkShaderFloatControlsIndependence roundingModeIndependence; - VkBool32 shaderSignedZeroInfNanPreserveFloat16; - VkBool32 shaderSignedZeroInfNanPreserveFloat32; - VkBool32 shaderSignedZeroInfNanPreserveFloat64; - VkBool32 shaderDenormPreserveFloat16; - VkBool32 shaderDenormPreserveFloat32; - VkBool32 shaderDenormPreserveFloat64; - VkBool32 shaderDenormFlushToZeroFloat16; - VkBool32 shaderDenormFlushToZeroFloat32; - VkBool32 shaderDenormFlushToZeroFloat64; - VkBool32 shaderRoundingModeRTEFloat16; - VkBool32 shaderRoundingModeRTEFloat32; - VkBool32 shaderRoundingModeRTEFloat64; - VkBool32 shaderRoundingModeRTZFloat16; - VkBool32 shaderRoundingModeRTZFloat32; - VkBool32 shaderRoundingModeRTZFloat64; - uint32_t maxUpdateAfterBindDescriptorsInAllPools; - VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; - VkBool32 shaderSampledImageArrayNonUniformIndexingNative; - VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; - VkBool32 shaderStorageImageArrayNonUniformIndexingNative; - VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; - VkBool32 robustBufferAccessUpdateAfterBind; - VkBool32 quadDivergentImplicitLod; - uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; - uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; - uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; - uint32_t maxPerStageUpdateAfterBindResources; - uint32_t maxDescriptorSetUpdateAfterBindSamplers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindSampledImages; - uint32_t maxDescriptorSetUpdateAfterBindStorageImages; - uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; - VkResolveModeFlags supportedDepthResolveModes; - VkResolveModeFlags supportedStencilResolveModes; - VkBool32 independentResolveNone; - VkBool32 independentResolve; - VkBool32 filterMinmaxSingleComponentFormats; - VkBool32 filterMinmaxImageComponentMapping; - uint64_t maxTimelineSemaphoreValueDifference; - VkSampleCountFlags framebufferIntegerColorSampleCounts; -} VkPhysicalDeviceVulkan12Properties; - -typedef struct VkImageFormatListCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t viewFormatCount; - const VkFormat* pViewFormats; -} VkImageFormatListCreateInfo; - -typedef struct VkAttachmentDescription2 { - VkStructureType sType; - const void* pNext; - VkAttachmentDescriptionFlags flags; - VkFormat format; - VkSampleCountFlagBits samples; - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkAttachmentLoadOp stencilLoadOp; - VkAttachmentStoreOp stencilStoreOp; - VkImageLayout initialLayout; - VkImageLayout finalLayout; -} VkAttachmentDescription2; - -typedef struct VkAttachmentReference2 { - VkStructureType sType; - const void* pNext; - uint32_t attachment; - VkImageLayout layout; - VkImageAspectFlags aspectMask; -} VkAttachmentReference2; - -typedef struct VkSubpassDescription2 { - VkStructureType sType; - const void* pNext; - VkSubpassDescriptionFlags flags; - VkPipelineBindPoint pipelineBindPoint; - uint32_t viewMask; - uint32_t inputAttachmentCount; - const VkAttachmentReference2* pInputAttachments; - uint32_t colorAttachmentCount; - const VkAttachmentReference2* pColorAttachments; - const VkAttachmentReference2* pResolveAttachments; - const VkAttachmentReference2* pDepthStencilAttachment; - uint32_t preserveAttachmentCount; - const uint32_t* pPreserveAttachments; -} VkSubpassDescription2; - -typedef struct VkSubpassDependency2 { - VkStructureType sType; - const void* pNext; - uint32_t srcSubpass; - uint32_t dstSubpass; - VkPipelineStageFlags srcStageMask; - VkPipelineStageFlags dstStageMask; - VkAccessFlags srcAccessMask; - VkAccessFlags dstAccessMask; - VkDependencyFlags dependencyFlags; - int32_t viewOffset; -} VkSubpassDependency2; - -typedef struct VkRenderPassCreateInfo2 { - VkStructureType sType; - const void* pNext; - VkRenderPassCreateFlags flags; - uint32_t attachmentCount; - const VkAttachmentDescription2* pAttachments; - uint32_t subpassCount; - const VkSubpassDescription2* pSubpasses; - uint32_t dependencyCount; - const VkSubpassDependency2* pDependencies; - uint32_t correlatedViewMaskCount; - const uint32_t* pCorrelatedViewMasks; -} VkRenderPassCreateInfo2; - -typedef struct VkSubpassBeginInfo { - VkStructureType sType; - const void* pNext; - VkSubpassContents contents; -} VkSubpassBeginInfo; - -typedef struct VkSubpassEndInfo { - VkStructureType sType; - const void* pNext; -} VkSubpassEndInfo; - -typedef struct VkPhysicalDevice8BitStorageFeatures { - VkStructureType sType; - void* pNext; - VkBool32 storageBuffer8BitAccess; - VkBool32 uniformAndStorageBuffer8BitAccess; - VkBool32 storagePushConstant8; -} VkPhysicalDevice8BitStorageFeatures; - -typedef struct VkPhysicalDeviceDriverProperties { - VkStructureType sType; - void* pNext; - VkDriverId driverID; - char driverName[VK_MAX_DRIVER_NAME_SIZE]; - char driverInfo[VK_MAX_DRIVER_INFO_SIZE]; - VkConformanceVersion conformanceVersion; -} VkPhysicalDeviceDriverProperties; - -typedef struct VkPhysicalDeviceShaderAtomicInt64Features { - VkStructureType sType; - void* pNext; - VkBool32 shaderBufferInt64Atomics; - VkBool32 shaderSharedInt64Atomics; -} VkPhysicalDeviceShaderAtomicInt64Features; - -typedef struct VkPhysicalDeviceShaderFloat16Int8Features { - VkStructureType sType; - void* pNext; - VkBool32 shaderFloat16; - VkBool32 shaderInt8; -} VkPhysicalDeviceShaderFloat16Int8Features; - -typedef struct VkPhysicalDeviceFloatControlsProperties { - VkStructureType sType; - void* pNext; - VkShaderFloatControlsIndependence denormBehaviorIndependence; - VkShaderFloatControlsIndependence roundingModeIndependence; - VkBool32 shaderSignedZeroInfNanPreserveFloat16; - VkBool32 shaderSignedZeroInfNanPreserveFloat32; - VkBool32 shaderSignedZeroInfNanPreserveFloat64; - VkBool32 shaderDenormPreserveFloat16; - VkBool32 shaderDenormPreserveFloat32; - VkBool32 shaderDenormPreserveFloat64; - VkBool32 shaderDenormFlushToZeroFloat16; - VkBool32 shaderDenormFlushToZeroFloat32; - VkBool32 shaderDenormFlushToZeroFloat64; - VkBool32 shaderRoundingModeRTEFloat16; - VkBool32 shaderRoundingModeRTEFloat32; - VkBool32 shaderRoundingModeRTEFloat64; - VkBool32 shaderRoundingModeRTZFloat16; - VkBool32 shaderRoundingModeRTZFloat32; - VkBool32 shaderRoundingModeRTZFloat64; -} VkPhysicalDeviceFloatControlsProperties; - -typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t bindingCount; - const VkDescriptorBindingFlags* pBindingFlags; -} VkDescriptorSetLayoutBindingFlagsCreateInfo; - -typedef struct VkPhysicalDeviceDescriptorIndexingFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderInputAttachmentArrayDynamicIndexing; - VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; - VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; - VkBool32 shaderUniformBufferArrayNonUniformIndexing; - VkBool32 shaderSampledImageArrayNonUniformIndexing; - VkBool32 shaderStorageBufferArrayNonUniformIndexing; - VkBool32 shaderStorageImageArrayNonUniformIndexing; - VkBool32 shaderInputAttachmentArrayNonUniformIndexing; - VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; - VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; - VkBool32 descriptorBindingUniformBufferUpdateAfterBind; - VkBool32 descriptorBindingSampledImageUpdateAfterBind; - VkBool32 descriptorBindingStorageImageUpdateAfterBind; - VkBool32 descriptorBindingStorageBufferUpdateAfterBind; - VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; - VkBool32 descriptorBindingUpdateUnusedWhilePending; - VkBool32 descriptorBindingPartiallyBound; - VkBool32 descriptorBindingVariableDescriptorCount; - VkBool32 runtimeDescriptorArray; -} VkPhysicalDeviceDescriptorIndexingFeatures; - -typedef struct VkPhysicalDeviceDescriptorIndexingProperties { - VkStructureType sType; - void* pNext; - uint32_t maxUpdateAfterBindDescriptorsInAllPools; - VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; - VkBool32 shaderSampledImageArrayNonUniformIndexingNative; - VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; - VkBool32 shaderStorageImageArrayNonUniformIndexingNative; - VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; - VkBool32 robustBufferAccessUpdateAfterBind; - VkBool32 quadDivergentImplicitLod; - uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; - uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; - uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; - uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; - uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; - uint32_t maxPerStageUpdateAfterBindResources; - uint32_t maxDescriptorSetUpdateAfterBindSamplers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; - uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; - uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; - uint32_t maxDescriptorSetUpdateAfterBindSampledImages; - uint32_t maxDescriptorSetUpdateAfterBindStorageImages; - uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; -} VkPhysicalDeviceDescriptorIndexingProperties; - -typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfo { - VkStructureType sType; - const void* pNext; - uint32_t descriptorSetCount; - const uint32_t* pDescriptorCounts; -} VkDescriptorSetVariableDescriptorCountAllocateInfo; - -typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupport { - VkStructureType sType; - void* pNext; - uint32_t maxVariableDescriptorCount; -} VkDescriptorSetVariableDescriptorCountLayoutSupport; - -typedef struct VkSubpassDescriptionDepthStencilResolve { - VkStructureType sType; - const void* pNext; - VkResolveModeFlagBits depthResolveMode; - VkResolveModeFlagBits stencilResolveMode; - const VkAttachmentReference2* pDepthStencilResolveAttachment; -} VkSubpassDescriptionDepthStencilResolve; - -typedef struct VkPhysicalDeviceDepthStencilResolveProperties { - VkStructureType sType; - void* pNext; - VkResolveModeFlags supportedDepthResolveModes; - VkResolveModeFlags supportedStencilResolveModes; - VkBool32 independentResolveNone; - VkBool32 independentResolve; -} VkPhysicalDeviceDepthStencilResolveProperties; - -typedef struct VkPhysicalDeviceScalarBlockLayoutFeatures { - VkStructureType sType; - void* pNext; - VkBool32 scalarBlockLayout; -} VkPhysicalDeviceScalarBlockLayoutFeatures; - -typedef struct VkImageStencilUsageCreateInfo { - VkStructureType sType; - const void* pNext; - VkImageUsageFlags stencilUsage; -} VkImageStencilUsageCreateInfo; - -typedef struct VkSamplerReductionModeCreateInfo { - VkStructureType sType; - const void* pNext; - VkSamplerReductionMode reductionMode; -} VkSamplerReductionModeCreateInfo; - -typedef struct VkPhysicalDeviceSamplerFilterMinmaxProperties { - VkStructureType sType; - void* pNext; - VkBool32 filterMinmaxSingleComponentFormats; - VkBool32 filterMinmaxImageComponentMapping; -} VkPhysicalDeviceSamplerFilterMinmaxProperties; - -typedef struct VkPhysicalDeviceVulkanMemoryModelFeatures { - VkStructureType sType; - void* pNext; - VkBool32 vulkanMemoryModel; - VkBool32 vulkanMemoryModelDeviceScope; - VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; -} VkPhysicalDeviceVulkanMemoryModelFeatures; - -typedef struct VkPhysicalDeviceImagelessFramebufferFeatures { - VkStructureType sType; - void* pNext; - VkBool32 imagelessFramebuffer; -} VkPhysicalDeviceImagelessFramebufferFeatures; - -typedef struct VkFramebufferAttachmentImageInfo { - VkStructureType sType; - const void* pNext; - VkImageCreateFlags flags; - VkImageUsageFlags usage; - uint32_t width; - uint32_t height; - uint32_t layerCount; - uint32_t viewFormatCount; - const VkFormat* pViewFormats; -} VkFramebufferAttachmentImageInfo; - -typedef struct VkFramebufferAttachmentsCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t attachmentImageInfoCount; - const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos; -} VkFramebufferAttachmentsCreateInfo; - -typedef struct VkRenderPassAttachmentBeginInfo { - VkStructureType sType; - const void* pNext; - uint32_t attachmentCount; - const VkImageView* pAttachments; -} VkRenderPassAttachmentBeginInfo; - -typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures { - VkStructureType sType; - void* pNext; - VkBool32 uniformBufferStandardLayout; -} VkPhysicalDeviceUniformBufferStandardLayoutFeatures; - -typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderSubgroupExtendedTypes; -} VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures; - -typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures { - VkStructureType sType; - void* pNext; - VkBool32 separateDepthStencilLayouts; -} VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures; - -typedef struct VkAttachmentReferenceStencilLayout { - VkStructureType sType; - void* pNext; - VkImageLayout stencilLayout; -} VkAttachmentReferenceStencilLayout; - -typedef struct VkAttachmentDescriptionStencilLayout { - VkStructureType sType; - void* pNext; - VkImageLayout stencilInitialLayout; - VkImageLayout stencilFinalLayout; -} VkAttachmentDescriptionStencilLayout; - -typedef struct VkPhysicalDeviceHostQueryResetFeatures { - VkStructureType sType; - void* pNext; - VkBool32 hostQueryReset; -} VkPhysicalDeviceHostQueryResetFeatures; - -typedef struct VkPhysicalDeviceTimelineSemaphoreFeatures { - VkStructureType sType; - void* pNext; - VkBool32 timelineSemaphore; -} VkPhysicalDeviceTimelineSemaphoreFeatures; - -typedef struct VkPhysicalDeviceTimelineSemaphoreProperties { - VkStructureType sType; - void* pNext; - uint64_t maxTimelineSemaphoreValueDifference; -} VkPhysicalDeviceTimelineSemaphoreProperties; - -typedef struct VkSemaphoreTypeCreateInfo { - VkStructureType sType; - const void* pNext; - VkSemaphoreType semaphoreType; - uint64_t initialValue; -} VkSemaphoreTypeCreateInfo; - -typedef struct VkTimelineSemaphoreSubmitInfo { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreValueCount; - const uint64_t* pWaitSemaphoreValues; - uint32_t signalSemaphoreValueCount; - const uint64_t* pSignalSemaphoreValues; -} VkTimelineSemaphoreSubmitInfo; - -typedef struct VkSemaphoreWaitInfo { - VkStructureType sType; - const void* pNext; - VkSemaphoreWaitFlags flags; - uint32_t semaphoreCount; - const VkSemaphore* pSemaphores; - const uint64_t* pValues; -} VkSemaphoreWaitInfo; - -typedef struct VkSemaphoreSignalInfo { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - uint64_t value; -} VkSemaphoreSignalInfo; - -typedef struct VkPhysicalDeviceBufferDeviceAddressFeatures { - VkStructureType sType; - void* pNext; - VkBool32 bufferDeviceAddress; - VkBool32 bufferDeviceAddressCaptureReplay; - VkBool32 bufferDeviceAddressMultiDevice; -} VkPhysicalDeviceBufferDeviceAddressFeatures; - -typedef struct VkBufferDeviceAddressInfo { - VkStructureType sType; - const void* pNext; - VkBuffer buffer; -} VkBufferDeviceAddressInfo; - -typedef struct VkBufferOpaqueCaptureAddressCreateInfo { - VkStructureType sType; - const void* pNext; - uint64_t opaqueCaptureAddress; -} VkBufferOpaqueCaptureAddressCreateInfo; - -typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo { - VkStructureType sType; - const void* pNext; - uint64_t opaqueCaptureAddress; -} VkMemoryOpaqueCaptureAddressAllocateInfo; - -typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo { - VkStructureType sType; - const void* pNext; - VkDeviceMemory memory; -} VkDeviceMemoryOpaqueCaptureAddressInfo; - -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); -typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); -typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo); -typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo); -typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); -typedef void (VKAPI_PTR *PFN_vkResetQueryPool)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); -typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValue)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue); -typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphores)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout); -typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphore)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo); -typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); -typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); -typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddress)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCount( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkBuffer countBuffer, - VkDeviceSize countBufferOffset, - uint32_t maxDrawCount, - uint32_t stride); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCount( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkBuffer countBuffer, - VkDeviceSize countBufferOffset, - uint32_t maxDrawCount, - uint32_t stride); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2( - VkDevice device, - const VkRenderPassCreateInfo2* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkRenderPass* pRenderPass); - -VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2( - VkCommandBuffer commandBuffer, - const VkRenderPassBeginInfo* pRenderPassBegin, - const VkSubpassBeginInfo* pSubpassBeginInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2( - VkCommandBuffer commandBuffer, - const VkSubpassBeginInfo* pSubpassBeginInfo, - const VkSubpassEndInfo* pSubpassEndInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2( - VkCommandBuffer commandBuffer, - const VkSubpassEndInfo* pSubpassEndInfo); - -VKAPI_ATTR void VKAPI_CALL vkResetQueryPool( - VkDevice device, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValue( - VkDevice device, - VkSemaphore semaphore, - uint64_t* pValue); - -VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphores( - VkDevice device, - const VkSemaphoreWaitInfo* pWaitInfo, - uint64_t timeout); - -VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphore( - VkDevice device, - const VkSemaphoreSignalInfo* pSignalInfo); - -VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddress( - VkDevice device, - const VkBufferDeviceAddressInfo* pInfo); - -VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddress( - VkDevice device, - const VkBufferDeviceAddressInfo* pInfo); - -VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress( - VkDevice device, - const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); -#endif - - -#define VK_VERSION_1_3 1 -// Vulkan 1.3 version number -#define VK_API_VERSION_1_3 VK_MAKE_API_VERSION(0, 1, 3, 0)// Patch version should always be set to 0 - -typedef uint64_t VkFlags64; -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlot) - -typedef enum VkPipelineCreationFeedbackFlagBits { - VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT = 0x00000001, - VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT = 0x00000002, - VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT = 0x00000004, - VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT, - VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT, - VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT, - VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkPipelineCreationFeedbackFlagBits; -typedef VkFlags VkPipelineCreationFeedbackFlags; - -typedef enum VkToolPurposeFlagBits { - VK_TOOL_PURPOSE_VALIDATION_BIT = 0x00000001, - VK_TOOL_PURPOSE_PROFILING_BIT = 0x00000002, - VK_TOOL_PURPOSE_TRACING_BIT = 0x00000004, - VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT = 0x00000008, - VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT = 0x00000010, - VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020, - VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040, - VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = VK_TOOL_PURPOSE_VALIDATION_BIT, - VK_TOOL_PURPOSE_PROFILING_BIT_EXT = VK_TOOL_PURPOSE_PROFILING_BIT, - VK_TOOL_PURPOSE_TRACING_BIT_EXT = VK_TOOL_PURPOSE_TRACING_BIT, - VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT, - VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT, - VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkToolPurposeFlagBits; -typedef VkFlags VkToolPurposeFlags; -typedef VkFlags VkPrivateDataSlotCreateFlags; -typedef VkFlags64 VkPipelineStageFlags2; - -// Flag bits for VkPipelineStageFlagBits2 -typedef VkFlags64 VkPipelineStageFlagBits2; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE = 0ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT = 0x00000001ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT = 0x00000002ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT = 0x00000004ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT = 0x00000008ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT = 0x00000040ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT = 0x00000080ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT = 0x00000100ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT = 0x00000200ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT = 0x00000800ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT = 0x00001000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT = 0x00001000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT = 0x00002000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT = 0x00004000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT = 0x00008000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT = 0x00010000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT = 0x100000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT = 0x200000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT = 0x400000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT = 0x800000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT = 0x1000000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT = 0x2000000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT = 0x4000000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR = 0x04000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR = 0x08000000ULL; -#endif -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL; -static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR = 0x10000000ULL; - -typedef VkFlags64 VkAccessFlags2; - -// Flag bits for VkAccessFlagBits2 -typedef VkFlags64 VkAccessFlagBits2; -static const VkAccessFlagBits2 VK_ACCESS_2_NONE = 0ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_NONE_KHR = 0ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT = 0x00000001ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT = 0x00000002ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT = 0x00000008ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT = 0x00000010ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT = 0x00000020ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT = 0x00000040ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT = 0x00000080ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT = 0x00000800ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT = 0x00001000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT = 0x00002000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT = 0x00004000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT = 0x00008000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT = 0x00010000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT = 0x100000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT = 0x200000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT = 0x400000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR = 0x800000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR = 0x1000000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR = 0x2000000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR = 0x4000000000ULL; -#endif -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL; -static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_BINDING_TABLE_READ_BIT_KHR = 0x10000000000ULL; - - -typedef enum VkSubmitFlagBits { - VK_SUBMIT_PROTECTED_BIT = 0x00000001, - VK_SUBMIT_PROTECTED_BIT_KHR = VK_SUBMIT_PROTECTED_BIT, - VK_SUBMIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkSubmitFlagBits; -typedef VkFlags VkSubmitFlags; - -typedef enum VkRenderingFlagBits { - VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 0x00000001, - VK_RENDERING_SUSPENDING_BIT = 0x00000002, - VK_RENDERING_RESUMING_BIT = 0x00000004, - VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, - VK_RENDERING_SUSPENDING_BIT_KHR = VK_RENDERING_SUSPENDING_BIT, - VK_RENDERING_RESUMING_BIT_KHR = VK_RENDERING_RESUMING_BIT, - VK_RENDERING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VkRenderingFlagBits; -typedef VkFlags VkRenderingFlags; -typedef VkFlags64 VkFormatFeatureFlags2; - -// Flag bits for VkFormatFeatureFlagBits2 -typedef VkFlags64 VkFormatFeatureFlagBits2; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT = 0x00000001ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR = 0x00000001ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT = 0x00000002ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR = 0x00000002ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR = 0x00000004ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT = 0x00000010ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000010ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR = 0x00000020ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT = 0x00000040ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR = 0x00000040ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT = 0x00000080ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR = 0x00000080ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR = 0x00000100ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 0x00000200ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT = 0x00000400ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR = 0x00000400ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT = 0x00000800ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR = 0x00000800ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR = 0x00001000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT = 0x00002000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT = 0x00004000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR = 0x00004000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT = 0x00008000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR = 0x00008000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR = 0x00010000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 0x00020000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 0x00040000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 0x00080000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 0x00100000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 0x00200000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT = 0x00400000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR = 0x00400000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT = 0x00800000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR = 0x00800000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT = 0x80000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR = 0x80000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT = 0x100000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR = 0x100000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT = 0x200000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR = 0x200000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000ULL; -#endif -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000ULL; -#endif -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV = 0x4000000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_WEIGHT_IMAGE_BIT_QCOM = 0x400000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_WEIGHT_SAMPLED_IMAGE_BIT_QCOM = 0x800000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM = 0x1000000000ULL; -static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BOX_FILTER_SAMPLED_BIT_QCOM = 0x2000000000ULL; - -typedef struct VkPhysicalDeviceVulkan13Features { - VkStructureType sType; - void* pNext; - VkBool32 robustImageAccess; - VkBool32 inlineUniformBlock; - VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; - VkBool32 pipelineCreationCacheControl; - VkBool32 privateData; - VkBool32 shaderDemoteToHelperInvocation; - VkBool32 shaderTerminateInvocation; - VkBool32 subgroupSizeControl; - VkBool32 computeFullSubgroups; - VkBool32 synchronization2; - VkBool32 textureCompressionASTC_HDR; - VkBool32 shaderZeroInitializeWorkgroupMemory; - VkBool32 dynamicRendering; - VkBool32 shaderIntegerDotProduct; - VkBool32 maintenance4; -} VkPhysicalDeviceVulkan13Features; - -typedef struct VkPhysicalDeviceVulkan13Properties { - VkStructureType sType; - void* pNext; - uint32_t minSubgroupSize; - uint32_t maxSubgroupSize; - uint32_t maxComputeWorkgroupSubgroups; - VkShaderStageFlags requiredSubgroupSizeStages; - uint32_t maxInlineUniformBlockSize; - uint32_t maxPerStageDescriptorInlineUniformBlocks; - uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; - uint32_t maxDescriptorSetInlineUniformBlocks; - uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; - uint32_t maxInlineUniformTotalSize; - VkBool32 integerDotProduct8BitUnsignedAccelerated; - VkBool32 integerDotProduct8BitSignedAccelerated; - VkBool32 integerDotProduct8BitMixedSignednessAccelerated; - VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProduct16BitUnsignedAccelerated; - VkBool32 integerDotProduct16BitSignedAccelerated; - VkBool32 integerDotProduct16BitMixedSignednessAccelerated; - VkBool32 integerDotProduct32BitUnsignedAccelerated; - VkBool32 integerDotProduct32BitSignedAccelerated; - VkBool32 integerDotProduct32BitMixedSignednessAccelerated; - VkBool32 integerDotProduct64BitUnsignedAccelerated; - VkBool32 integerDotProduct64BitSignedAccelerated; - VkBool32 integerDotProduct64BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; - VkDeviceSize storageTexelBufferOffsetAlignmentBytes; - VkBool32 storageTexelBufferOffsetSingleTexelAlignment; - VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; - VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; - VkDeviceSize maxBufferSize; -} VkPhysicalDeviceVulkan13Properties; - -typedef struct VkPipelineCreationFeedback { - VkPipelineCreationFeedbackFlags flags; - uint64_t duration; -} VkPipelineCreationFeedback; - -typedef struct VkPipelineCreationFeedbackCreateInfo { - VkStructureType sType; - const void* pNext; - VkPipelineCreationFeedback* pPipelineCreationFeedback; - uint32_t pipelineStageCreationFeedbackCount; - VkPipelineCreationFeedback* pPipelineStageCreationFeedbacks; -} VkPipelineCreationFeedbackCreateInfo; - -typedef struct VkPhysicalDeviceShaderTerminateInvocationFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderTerminateInvocation; -} VkPhysicalDeviceShaderTerminateInvocationFeatures; - -typedef struct VkPhysicalDeviceToolProperties { - VkStructureType sType; - void* pNext; - char name[VK_MAX_EXTENSION_NAME_SIZE]; - char version[VK_MAX_EXTENSION_NAME_SIZE]; - VkToolPurposeFlags purposes; - char description[VK_MAX_DESCRIPTION_SIZE]; - char layer[VK_MAX_EXTENSION_NAME_SIZE]; -} VkPhysicalDeviceToolProperties; - -typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderDemoteToHelperInvocation; -} VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures; - -typedef struct VkPhysicalDevicePrivateDataFeatures { - VkStructureType sType; - void* pNext; - VkBool32 privateData; -} VkPhysicalDevicePrivateDataFeatures; - -typedef struct VkDevicePrivateDataCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t privateDataSlotRequestCount; -} VkDevicePrivateDataCreateInfo; - -typedef struct VkPrivateDataSlotCreateInfo { - VkStructureType sType; - const void* pNext; - VkPrivateDataSlotCreateFlags flags; -} VkPrivateDataSlotCreateInfo; - -typedef struct VkPhysicalDevicePipelineCreationCacheControlFeatures { - VkStructureType sType; - void* pNext; - VkBool32 pipelineCreationCacheControl; -} VkPhysicalDevicePipelineCreationCacheControlFeatures; - -typedef struct VkMemoryBarrier2 { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2 srcStageMask; - VkAccessFlags2 srcAccessMask; - VkPipelineStageFlags2 dstStageMask; - VkAccessFlags2 dstAccessMask; -} VkMemoryBarrier2; - -typedef struct VkBufferMemoryBarrier2 { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2 srcStageMask; - VkAccessFlags2 srcAccessMask; - VkPipelineStageFlags2 dstStageMask; - VkAccessFlags2 dstAccessMask; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize size; -} VkBufferMemoryBarrier2; - -typedef struct VkImageMemoryBarrier2 { - VkStructureType sType; - const void* pNext; - VkPipelineStageFlags2 srcStageMask; - VkAccessFlags2 srcAccessMask; - VkPipelineStageFlags2 dstStageMask; - VkAccessFlags2 dstAccessMask; - VkImageLayout oldLayout; - VkImageLayout newLayout; - uint32_t srcQueueFamilyIndex; - uint32_t dstQueueFamilyIndex; - VkImage image; - VkImageSubresourceRange subresourceRange; -} VkImageMemoryBarrier2; - -typedef struct VkDependencyInfo { - VkStructureType sType; - const void* pNext; - VkDependencyFlags dependencyFlags; - uint32_t memoryBarrierCount; - const VkMemoryBarrier2* pMemoryBarriers; - uint32_t bufferMemoryBarrierCount; - const VkBufferMemoryBarrier2* pBufferMemoryBarriers; - uint32_t imageMemoryBarrierCount; - const VkImageMemoryBarrier2* pImageMemoryBarriers; -} VkDependencyInfo; - -typedef struct VkSemaphoreSubmitInfo { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - uint64_t value; - VkPipelineStageFlags2 stageMask; - uint32_t deviceIndex; -} VkSemaphoreSubmitInfo; - -typedef struct VkCommandBufferSubmitInfo { - VkStructureType sType; - const void* pNext; - VkCommandBuffer commandBuffer; - uint32_t deviceMask; -} VkCommandBufferSubmitInfo; - -typedef struct VkSubmitInfo2 { - VkStructureType sType; - const void* pNext; - VkSubmitFlags flags; - uint32_t waitSemaphoreInfoCount; - const VkSemaphoreSubmitInfo* pWaitSemaphoreInfos; - uint32_t commandBufferInfoCount; - const VkCommandBufferSubmitInfo* pCommandBufferInfos; - uint32_t signalSemaphoreInfoCount; - const VkSemaphoreSubmitInfo* pSignalSemaphoreInfos; -} VkSubmitInfo2; - -typedef struct VkPhysicalDeviceSynchronization2Features { - VkStructureType sType; - void* pNext; - VkBool32 synchronization2; -} VkPhysicalDeviceSynchronization2Features; - -typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderZeroInitializeWorkgroupMemory; -} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures; - -typedef struct VkPhysicalDeviceImageRobustnessFeatures { - VkStructureType sType; - void* pNext; - VkBool32 robustImageAccess; -} VkPhysicalDeviceImageRobustnessFeatures; - -typedef struct VkBufferCopy2 { - VkStructureType sType; - const void* pNext; - VkDeviceSize srcOffset; - VkDeviceSize dstOffset; - VkDeviceSize size; -} VkBufferCopy2; - -typedef struct VkCopyBufferInfo2 { - VkStructureType sType; - const void* pNext; - VkBuffer srcBuffer; - VkBuffer dstBuffer; - uint32_t regionCount; - const VkBufferCopy2* pRegions; -} VkCopyBufferInfo2; - -typedef struct VkImageCopy2 { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageCopy2; - -typedef struct VkCopyImageInfo2 { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageCopy2* pRegions; -} VkCopyImageInfo2; - -typedef struct VkBufferImageCopy2 { - VkStructureType sType; - const void* pNext; - VkDeviceSize bufferOffset; - uint32_t bufferRowLength; - uint32_t bufferImageHeight; - VkImageSubresourceLayers imageSubresource; - VkOffset3D imageOffset; - VkExtent3D imageExtent; -} VkBufferImageCopy2; - -typedef struct VkCopyBufferToImageInfo2 { - VkStructureType sType; - const void* pNext; - VkBuffer srcBuffer; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkBufferImageCopy2* pRegions; -} VkCopyBufferToImageInfo2; - -typedef struct VkCopyImageToBufferInfo2 { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkBuffer dstBuffer; - uint32_t regionCount; - const VkBufferImageCopy2* pRegions; -} VkCopyImageToBufferInfo2; - -typedef struct VkImageBlit2 { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffsets[2]; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffsets[2]; -} VkImageBlit2; - -typedef struct VkBlitImageInfo2 { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageBlit2* pRegions; - VkFilter filter; -} VkBlitImageInfo2; - -typedef struct VkImageResolve2 { - VkStructureType sType; - const void* pNext; - VkImageSubresourceLayers srcSubresource; - VkOffset3D srcOffset; - VkImageSubresourceLayers dstSubresource; - VkOffset3D dstOffset; - VkExtent3D extent; -} VkImageResolve2; - -typedef struct VkResolveImageInfo2 { - VkStructureType sType; - const void* pNext; - VkImage srcImage; - VkImageLayout srcImageLayout; - VkImage dstImage; - VkImageLayout dstImageLayout; - uint32_t regionCount; - const VkImageResolve2* pRegions; -} VkResolveImageInfo2; - -typedef struct VkPhysicalDeviceSubgroupSizeControlFeatures { - VkStructureType sType; - void* pNext; - VkBool32 subgroupSizeControl; - VkBool32 computeFullSubgroups; -} VkPhysicalDeviceSubgroupSizeControlFeatures; - -typedef struct VkPhysicalDeviceSubgroupSizeControlProperties { - VkStructureType sType; - void* pNext; - uint32_t minSubgroupSize; - uint32_t maxSubgroupSize; - uint32_t maxComputeWorkgroupSubgroups; - VkShaderStageFlags requiredSubgroupSizeStages; -} VkPhysicalDeviceSubgroupSizeControlProperties; - -typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfo { - VkStructureType sType; - void* pNext; - uint32_t requiredSubgroupSize; -} VkPipelineShaderStageRequiredSubgroupSizeCreateInfo; - -typedef struct VkPhysicalDeviceInlineUniformBlockFeatures { - VkStructureType sType; - void* pNext; - VkBool32 inlineUniformBlock; - VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; -} VkPhysicalDeviceInlineUniformBlockFeatures; - -typedef struct VkPhysicalDeviceInlineUniformBlockProperties { - VkStructureType sType; - void* pNext; - uint32_t maxInlineUniformBlockSize; - uint32_t maxPerStageDescriptorInlineUniformBlocks; - uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; - uint32_t maxDescriptorSetInlineUniformBlocks; - uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; -} VkPhysicalDeviceInlineUniformBlockProperties; - -typedef struct VkWriteDescriptorSetInlineUniformBlock { - VkStructureType sType; - const void* pNext; - uint32_t dataSize; - const void* pData; -} VkWriteDescriptorSetInlineUniformBlock; - -typedef struct VkDescriptorPoolInlineUniformBlockCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t maxInlineUniformBlockBindings; -} VkDescriptorPoolInlineUniformBlockCreateInfo; - -typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeatures { - VkStructureType sType; - void* pNext; - VkBool32 textureCompressionASTC_HDR; -} VkPhysicalDeviceTextureCompressionASTCHDRFeatures; - -typedef struct VkRenderingAttachmentInfo { - VkStructureType sType; - const void* pNext; - VkImageView imageView; - VkImageLayout imageLayout; - VkResolveModeFlagBits resolveMode; - VkImageView resolveImageView; - VkImageLayout resolveImageLayout; - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkClearValue clearValue; -} VkRenderingAttachmentInfo; - -typedef struct VkRenderingInfo { - VkStructureType sType; - const void* pNext; - VkRenderingFlags flags; - VkRect2D renderArea; - uint32_t layerCount; - uint32_t viewMask; - uint32_t colorAttachmentCount; - const VkRenderingAttachmentInfo* pColorAttachments; - const VkRenderingAttachmentInfo* pDepthAttachment; - const VkRenderingAttachmentInfo* pStencilAttachment; -} VkRenderingInfo; - -typedef struct VkPipelineRenderingCreateInfo { - VkStructureType sType; - const void* pNext; - uint32_t viewMask; - uint32_t colorAttachmentCount; - const VkFormat* pColorAttachmentFormats; - VkFormat depthAttachmentFormat; - VkFormat stencilAttachmentFormat; -} VkPipelineRenderingCreateInfo; - -typedef struct VkPhysicalDeviceDynamicRenderingFeatures { - VkStructureType sType; - void* pNext; - VkBool32 dynamicRendering; -} VkPhysicalDeviceDynamicRenderingFeatures; - -typedef struct VkCommandBufferInheritanceRenderingInfo { - VkStructureType sType; - const void* pNext; - VkRenderingFlags flags; - uint32_t viewMask; - uint32_t colorAttachmentCount; - const VkFormat* pColorAttachmentFormats; - VkFormat depthAttachmentFormat; - VkFormat stencilAttachmentFormat; - VkSampleCountFlagBits rasterizationSamples; -} VkCommandBufferInheritanceRenderingInfo; - -typedef struct VkPhysicalDeviceShaderIntegerDotProductFeatures { - VkStructureType sType; - void* pNext; - VkBool32 shaderIntegerDotProduct; -} VkPhysicalDeviceShaderIntegerDotProductFeatures; - -typedef struct VkPhysicalDeviceShaderIntegerDotProductProperties { - VkStructureType sType; - void* pNext; - VkBool32 integerDotProduct8BitUnsignedAccelerated; - VkBool32 integerDotProduct8BitSignedAccelerated; - VkBool32 integerDotProduct8BitMixedSignednessAccelerated; - VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; - VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProduct16BitUnsignedAccelerated; - VkBool32 integerDotProduct16BitSignedAccelerated; - VkBool32 integerDotProduct16BitMixedSignednessAccelerated; - VkBool32 integerDotProduct32BitUnsignedAccelerated; - VkBool32 integerDotProduct32BitSignedAccelerated; - VkBool32 integerDotProduct32BitMixedSignednessAccelerated; - VkBool32 integerDotProduct64BitUnsignedAccelerated; - VkBool32 integerDotProduct64BitSignedAccelerated; - VkBool32 integerDotProduct64BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; - VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; -} VkPhysicalDeviceShaderIntegerDotProductProperties; - -typedef struct VkPhysicalDeviceTexelBufferAlignmentProperties { - VkStructureType sType; - void* pNext; - VkDeviceSize storageTexelBufferOffsetAlignmentBytes; - VkBool32 storageTexelBufferOffsetSingleTexelAlignment; - VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; - VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; -} VkPhysicalDeviceTexelBufferAlignmentProperties; - -typedef struct VkFormatProperties3 { - VkStructureType sType; - void* pNext; - VkFormatFeatureFlags2 linearTilingFeatures; - VkFormatFeatureFlags2 optimalTilingFeatures; - VkFormatFeatureFlags2 bufferFeatures; -} VkFormatProperties3; - -typedef struct VkPhysicalDeviceMaintenance4Features { - VkStructureType sType; - void* pNext; - VkBool32 maintenance4; -} VkPhysicalDeviceMaintenance4Features; - -typedef struct VkPhysicalDeviceMaintenance4Properties { - VkStructureType sType; - void* pNext; - VkDeviceSize maxBufferSize; -} VkPhysicalDeviceMaintenance4Properties; - -typedef struct VkDeviceBufferMemoryRequirements { - VkStructureType sType; - const void* pNext; - const VkBufferCreateInfo* pCreateInfo; -} VkDeviceBufferMemoryRequirements; - -typedef struct VkDeviceImageMemoryRequirements { - VkStructureType sType; - const void* pNext; - const VkImageCreateInfo* pCreateInfo; - VkImageAspectFlagBits planeAspect; -} VkDeviceImageMemoryRequirements; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolProperties)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); -typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlot)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); -typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlot)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); -typedef void (VKAPI_PTR *PFN_vkGetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); -typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); -typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); -typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); -typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); -typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); -typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); -typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); -typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdBeginRendering)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); -typedef void (VKAPI_PTR *PFN_vkCmdEndRendering)(VkCommandBuffer commandBuffer); -typedef void (VKAPI_PTR *PFN_vkCmdSetCullMode)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode); -typedef void (VKAPI_PTR *PFN_vkCmdSetFrontFace)(VkCommandBuffer commandBuffer, VkFrontFace frontFace); -typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveTopology)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology); -typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWithCount)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport* pViewports); -typedef void (VKAPI_PTR *PFN_vkCmdSetScissorWithCount)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors); -typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers2)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthWriteEnable)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthCompareOp)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBoundsTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetStencilTestEnable)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOp)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); -typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizerDiscardEnable)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBiasEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnable)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); -typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirements)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolProperties( - VkPhysicalDevice physicalDevice, - uint32_t* pToolCount, - VkPhysicalDeviceToolProperties* pToolProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlot( - VkDevice device, - const VkPrivateDataSlotCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPrivateDataSlot* pPrivateDataSlot); - -VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlot( - VkDevice device, - VkPrivateDataSlot privateDataSlot, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateData( - VkDevice device, - VkObjectType objectType, - uint64_t objectHandle, - VkPrivateDataSlot privateDataSlot, - uint64_t data); - -VKAPI_ATTR void VKAPI_CALL vkGetPrivateData( - VkDevice device, - VkObjectType objectType, - uint64_t objectHandle, - VkPrivateDataSlot privateDataSlot, - uint64_t* pData); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2( - VkCommandBuffer commandBuffer, - VkEvent event, - const VkDependencyInfo* pDependencyInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2( - VkCommandBuffer commandBuffer, - VkEvent event, - VkPipelineStageFlags2 stageMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2( - VkCommandBuffer commandBuffer, - uint32_t eventCount, - const VkEvent* pEvents, - const VkDependencyInfo* pDependencyInfos); - -VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2( - VkCommandBuffer commandBuffer, - const VkDependencyInfo* pDependencyInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2( - VkCommandBuffer commandBuffer, - VkPipelineStageFlags2 stage, - VkQueryPool queryPool, - uint32_t query); - -VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2( - VkQueue queue, - uint32_t submitCount, - const VkSubmitInfo2* pSubmits, - VkFence fence); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2( - VkCommandBuffer commandBuffer, - const VkCopyBufferInfo2* pCopyBufferInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2( - VkCommandBuffer commandBuffer, - const VkCopyImageInfo2* pCopyImageInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2( - VkCommandBuffer commandBuffer, - const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2( - VkCommandBuffer commandBuffer, - const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2( - VkCommandBuffer commandBuffer, - const VkBlitImageInfo2* pBlitImageInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2( - VkCommandBuffer commandBuffer, - const VkResolveImageInfo2* pResolveImageInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdBeginRendering( - VkCommandBuffer commandBuffer, - const VkRenderingInfo* pRenderingInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndRendering( - VkCommandBuffer commandBuffer); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetCullMode( - VkCommandBuffer commandBuffer, - VkCullModeFlags cullMode); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFace( - VkCommandBuffer commandBuffer, - VkFrontFace frontFace); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopology( - VkCommandBuffer commandBuffer, - VkPrimitiveTopology primitiveTopology); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCount( - VkCommandBuffer commandBuffer, - uint32_t viewportCount, - const VkViewport* pViewports); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCount( - VkCommandBuffer commandBuffer, - uint32_t scissorCount, - const VkRect2D* pScissors); - -VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2( - VkCommandBuffer commandBuffer, - uint32_t firstBinding, - uint32_t bindingCount, - const VkBuffer* pBuffers, - const VkDeviceSize* pOffsets, - const VkDeviceSize* pSizes, - const VkDeviceSize* pStrides); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnable( - VkCommandBuffer commandBuffer, - VkBool32 depthTestEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnable( - VkCommandBuffer commandBuffer, - VkBool32 depthWriteEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOp( - VkCommandBuffer commandBuffer, - VkCompareOp depthCompareOp); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnable( - VkCommandBuffer commandBuffer, - VkBool32 depthBoundsTestEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnable( - VkCommandBuffer commandBuffer, - VkBool32 stencilTestEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOp( - VkCommandBuffer commandBuffer, - VkStencilFaceFlags faceMask, - VkStencilOp failOp, - VkStencilOp passOp, - VkStencilOp depthFailOp, - VkCompareOp compareOp); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnable( - VkCommandBuffer commandBuffer, - VkBool32 rasterizerDiscardEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnable( - VkCommandBuffer commandBuffer, - VkBool32 depthBiasEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnable( - VkCommandBuffer commandBuffer, - VkBool32 primitiveRestartEnable); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirements( - VkDevice device, - const VkDeviceBufferMemoryRequirements* pInfo, - VkMemoryRequirements2* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirements( - VkDevice device, - const VkDeviceImageMemoryRequirements* pInfo, - VkMemoryRequirements2* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirements( - VkDevice device, - const VkDeviceImageMemoryRequirements* pInfo, - uint32_t* pSparseMemoryRequirementCount, - VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); -#endif - - -#define VK_KHR_surface 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) -#define VK_KHR_SURFACE_SPEC_VERSION 25 -#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface" - -typedef enum VkPresentModeKHR { - VK_PRESENT_MODE_IMMEDIATE_KHR = 0, - VK_PRESENT_MODE_MAILBOX_KHR = 1, - VK_PRESENT_MODE_FIFO_KHR = 2, - VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, - VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000, - VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001, - VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkPresentModeKHR; - -typedef enum VkColorSpaceKHR { - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0, - VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001, - VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT = 1000104002, - VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT = 1000104003, - VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104004, - VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104005, - VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006, - VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007, - VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008, - VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009, - VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010, - VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011, - VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012, - VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013, - VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014, - VK_COLOR_SPACE_DISPLAY_NATIVE_AMD = 1000213000, - VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, - VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkColorSpaceKHR; - -typedef enum VkSurfaceTransformFlagBitsKHR { - VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001, - VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002, - VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004, - VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040, - VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080, - VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100, - VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSurfaceTransformFlagBitsKHR; - -typedef enum VkCompositeAlphaFlagBitsKHR { - VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, - VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002, - VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004, - VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008, - VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkCompositeAlphaFlagBitsKHR; -typedef VkFlags VkCompositeAlphaFlagsKHR; -typedef VkFlags VkSurfaceTransformFlagsKHR; -typedef struct VkSurfaceCapabilitiesKHR { - uint32_t minImageCount; - uint32_t maxImageCount; - VkExtent2D currentExtent; - VkExtent2D minImageExtent; - VkExtent2D maxImageExtent; - uint32_t maxImageArrayLayers; - VkSurfaceTransformFlagsKHR supportedTransforms; - VkSurfaceTransformFlagBitsKHR currentTransform; - VkCompositeAlphaFlagsKHR supportedCompositeAlpha; - VkImageUsageFlags supportedUsageFlags; -} VkSurfaceCapabilitiesKHR; - -typedef struct VkSurfaceFormatKHR { - VkFormat format; - VkColorSpaceKHR colorSpace; -} VkSurfaceFormatKHR; - -typedef void (VKAPI_PTR *PFN_vkDestroySurfaceKHR)(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR( - VkInstance instance, - VkSurfaceKHR surface, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - VkSurfaceKHR surface, - VkBool32* pSupported); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - uint32_t* pSurfaceFormatCount, - VkSurfaceFormatKHR* pSurfaceFormats); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - uint32_t* pPresentModeCount, - VkPresentModeKHR* pPresentModes); -#endif - - -#define VK_KHR_swapchain 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) -#define VK_KHR_SWAPCHAIN_SPEC_VERSION 70 -#define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain" - -typedef enum VkSwapchainCreateFlagBitsKHR { - VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000001, - VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 0x00000002, - VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR = 0x00000004, - VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkSwapchainCreateFlagBitsKHR; -typedef VkFlags VkSwapchainCreateFlagsKHR; - -typedef enum VkDeviceGroupPresentModeFlagBitsKHR { - VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR = 0x00000001, - VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR = 0x00000002, - VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR = 0x00000004, - VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR = 0x00000008, - VK_DEVICE_GROUP_PRESENT_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkDeviceGroupPresentModeFlagBitsKHR; -typedef VkFlags VkDeviceGroupPresentModeFlagsKHR; -typedef struct VkSwapchainCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkSwapchainCreateFlagsKHR flags; - VkSurfaceKHR surface; - uint32_t minImageCount; - VkFormat imageFormat; - VkColorSpaceKHR imageColorSpace; - VkExtent2D imageExtent; - uint32_t imageArrayLayers; - VkImageUsageFlags imageUsage; - VkSharingMode imageSharingMode; - uint32_t queueFamilyIndexCount; - const uint32_t* pQueueFamilyIndices; - VkSurfaceTransformFlagBitsKHR preTransform; - VkCompositeAlphaFlagBitsKHR compositeAlpha; - VkPresentModeKHR presentMode; - VkBool32 clipped; - VkSwapchainKHR oldSwapchain; -} VkSwapchainCreateInfoKHR; - -typedef struct VkPresentInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreCount; - const VkSemaphore* pWaitSemaphores; - uint32_t swapchainCount; - const VkSwapchainKHR* pSwapchains; - const uint32_t* pImageIndices; - VkResult* pResults; -} VkPresentInfoKHR; - -typedef struct VkImageSwapchainCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkSwapchainKHR swapchain; -} VkImageSwapchainCreateInfoKHR; - -typedef struct VkBindImageMemorySwapchainInfoKHR { - VkStructureType sType; - const void* pNext; - VkSwapchainKHR swapchain; - uint32_t imageIndex; -} VkBindImageMemorySwapchainInfoKHR; - -typedef struct VkAcquireNextImageInfoKHR { - VkStructureType sType; - const void* pNext; - VkSwapchainKHR swapchain; - uint64_t timeout; - VkSemaphore semaphore; - VkFence fence; - uint32_t deviceMask; -} VkAcquireNextImageInfoKHR; - -typedef struct VkDeviceGroupPresentCapabilitiesKHR { - VkStructureType sType; - void* pNext; - uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE]; - VkDeviceGroupPresentModeFlagsKHR modes; -} VkDeviceGroupPresentCapabilitiesKHR; - -typedef struct VkDeviceGroupPresentInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t swapchainCount; - const uint32_t* pDeviceMasks; - VkDeviceGroupPresentModeFlagBitsKHR mode; -} VkDeviceGroupPresentInfoKHR; - -typedef struct VkDeviceGroupSwapchainCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkDeviceGroupPresentModeFlagsKHR modes; -} VkDeviceGroupSwapchainCreateInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain); -typedef void (VKAPI_PTR *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages); -typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex); -typedef VkResult (VKAPI_PTR *PFN_vkQueuePresentKHR)(VkQueue queue, const VkPresentInfoKHR* pPresentInfo); -typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupPresentCapabilitiesKHR)(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities); -typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModesKHR)(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR* pModes); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDevicePresentRectanglesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects); -typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImage2KHR)(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( - VkDevice device, - const VkSwapchainCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSwapchainKHR* pSwapchain); - -VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR( - VkDevice device, - VkSwapchainKHR swapchain, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR( - VkDevice device, - VkSwapchainKHR swapchain, - uint32_t* pSwapchainImageCount, - VkImage* pSwapchainImages); - -VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR( - VkDevice device, - VkSwapchainKHR swapchain, - uint64_t timeout, - VkSemaphore semaphore, - VkFence fence, - uint32_t* pImageIndex); - -VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( - VkQueue queue, - const VkPresentInfoKHR* pPresentInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupPresentCapabilitiesKHR( - VkDevice device, - VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHR( - VkDevice device, - VkSurfaceKHR surface, - VkDeviceGroupPresentModeFlagsKHR* pModes); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - uint32_t* pRectCount, - VkRect2D* pRects); - -VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHR( - VkDevice device, - const VkAcquireNextImageInfoKHR* pAcquireInfo, - uint32_t* pImageIndex); -#endif - - -#define VK_KHR_display 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayModeKHR) -#define VK_KHR_DISPLAY_SPEC_VERSION 23 -#define VK_KHR_DISPLAY_EXTENSION_NAME "VK_KHR_display" -typedef VkFlags VkDisplayModeCreateFlagsKHR; - -typedef enum VkDisplayPlaneAlphaFlagBitsKHR { - VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, - VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR = 0x00000002, - VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR = 0x00000004, - VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR = 0x00000008, - VK_DISPLAY_PLANE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkDisplayPlaneAlphaFlagBitsKHR; -typedef VkFlags VkDisplayPlaneAlphaFlagsKHR; -typedef VkFlags VkDisplaySurfaceCreateFlagsKHR; -typedef struct VkDisplayModeParametersKHR { - VkExtent2D visibleRegion; - uint32_t refreshRate; -} VkDisplayModeParametersKHR; - -typedef struct VkDisplayModeCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkDisplayModeCreateFlagsKHR flags; - VkDisplayModeParametersKHR parameters; -} VkDisplayModeCreateInfoKHR; - -typedef struct VkDisplayModePropertiesKHR { - VkDisplayModeKHR displayMode; - VkDisplayModeParametersKHR parameters; -} VkDisplayModePropertiesKHR; - -typedef struct VkDisplayPlaneCapabilitiesKHR { - VkDisplayPlaneAlphaFlagsKHR supportedAlpha; - VkOffset2D minSrcPosition; - VkOffset2D maxSrcPosition; - VkExtent2D minSrcExtent; - VkExtent2D maxSrcExtent; - VkOffset2D minDstPosition; - VkOffset2D maxDstPosition; - VkExtent2D minDstExtent; - VkExtent2D maxDstExtent; -} VkDisplayPlaneCapabilitiesKHR; - -typedef struct VkDisplayPlanePropertiesKHR { - VkDisplayKHR currentDisplay; - uint32_t currentStackIndex; -} VkDisplayPlanePropertiesKHR; - -typedef struct VkDisplayPropertiesKHR { - VkDisplayKHR display; - const char* displayName; - VkExtent2D physicalDimensions; - VkExtent2D physicalResolution; - VkSurfaceTransformFlagsKHR supportedTransforms; - VkBool32 planeReorderPossible; - VkBool32 persistentContent; -} VkDisplayPropertiesKHR; - -typedef struct VkDisplaySurfaceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkDisplaySurfaceCreateFlagsKHR flags; - VkDisplayModeKHR displayMode; - uint32_t planeIndex; - uint32_t planeStackIndex; - VkSurfaceTransformFlagBitsKHR transform; - float globalAlpha; - VkDisplayPlaneAlphaFlagBitsKHR alphaMode; - VkExtent2D imageExtent; -} VkDisplaySurfaceCreateInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlanePropertiesKHR* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneSupportedDisplaysKHR)(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays); -typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModePropertiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayModeKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode); -typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayPlaneSurfaceKHR)(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkDisplayPropertiesKHR* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkDisplayPlanePropertiesKHR* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR( - VkPhysicalDevice physicalDevice, - uint32_t planeIndex, - uint32_t* pDisplayCount, - VkDisplayKHR* pDisplays); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR( - VkPhysicalDevice physicalDevice, - VkDisplayKHR display, - uint32_t* pPropertyCount, - VkDisplayModePropertiesKHR* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR( - VkPhysicalDevice physicalDevice, - VkDisplayKHR display, - const VkDisplayModeCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDisplayModeKHR* pMode); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR( - VkPhysicalDevice physicalDevice, - VkDisplayModeKHR mode, - uint32_t planeIndex, - VkDisplayPlaneCapabilitiesKHR* pCapabilities); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR( - VkInstance instance, - const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); -#endif - - -#define VK_KHR_display_swapchain 1 -#define VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION 10 -#define VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME "VK_KHR_display_swapchain" -typedef struct VkDisplayPresentInfoKHR { - VkStructureType sType; - const void* pNext; - VkRect2D srcRect; - VkRect2D dstRect; - VkBool32 persistent; -} VkDisplayPresentInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateSharedSwapchainsKHR)(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( - VkDevice device, - uint32_t swapchainCount, - const VkSwapchainCreateInfoKHR* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkSwapchainKHR* pSwapchains); -#endif - - -#define VK_KHR_sampler_mirror_clamp_to_edge 1 -#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 3 -#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge" - - -#define VK_KHR_dynamic_rendering 1 -#define VK_KHR_DYNAMIC_RENDERING_SPEC_VERSION 1 -#define VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME "VK_KHR_dynamic_rendering" -typedef VkRenderingFlags VkRenderingFlagsKHR; - -typedef VkRenderingFlagBits VkRenderingFlagBitsKHR; - -typedef VkRenderingInfo VkRenderingInfoKHR; - -typedef VkRenderingAttachmentInfo VkRenderingAttachmentInfoKHR; - -typedef VkPipelineRenderingCreateInfo VkPipelineRenderingCreateInfoKHR; - -typedef VkPhysicalDeviceDynamicRenderingFeatures VkPhysicalDeviceDynamicRenderingFeaturesKHR; - -typedef VkCommandBufferInheritanceRenderingInfo VkCommandBufferInheritanceRenderingInfoKHR; - -typedef struct VkRenderingFragmentShadingRateAttachmentInfoKHR { - VkStructureType sType; - const void* pNext; - VkImageView imageView; - VkImageLayout imageLayout; - VkExtent2D shadingRateAttachmentTexelSize; -} VkRenderingFragmentShadingRateAttachmentInfoKHR; - -typedef struct VkRenderingFragmentDensityMapAttachmentInfoEXT { - VkStructureType sType; - const void* pNext; - VkImageView imageView; - VkImageLayout imageLayout; -} VkRenderingFragmentDensityMapAttachmentInfoEXT; - -typedef struct VkAttachmentSampleCountInfoAMD { - VkStructureType sType; - const void* pNext; - uint32_t colorAttachmentCount; - const VkSampleCountFlagBits* pColorAttachmentSamples; - VkSampleCountFlagBits depthStencilAttachmentSamples; -} VkAttachmentSampleCountInfoAMD; - -typedef VkAttachmentSampleCountInfoAMD VkAttachmentSampleCountInfoNV; - -typedef struct VkMultiviewPerViewAttributesInfoNVX { - VkStructureType sType; - const void* pNext; - VkBool32 perViewAttributes; - VkBool32 perViewAttributesPositionXOnly; -} VkMultiviewPerViewAttributesInfoNVX; - -typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderingKHR)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); -typedef void (VKAPI_PTR *PFN_vkCmdEndRenderingKHR)(VkCommandBuffer commandBuffer); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderingKHR( - VkCommandBuffer commandBuffer, - const VkRenderingInfo* pRenderingInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderingKHR( - VkCommandBuffer commandBuffer); -#endif - - -#define VK_KHR_multiview 1 -#define VK_KHR_MULTIVIEW_SPEC_VERSION 1 -#define VK_KHR_MULTIVIEW_EXTENSION_NAME "VK_KHR_multiview" -typedef VkRenderPassMultiviewCreateInfo VkRenderPassMultiviewCreateInfoKHR; - -typedef VkPhysicalDeviceMultiviewFeatures VkPhysicalDeviceMultiviewFeaturesKHR; - -typedef VkPhysicalDeviceMultiviewProperties VkPhysicalDeviceMultiviewPropertiesKHR; - - - -#define VK_KHR_get_physical_device_properties2 1 -#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION 2 -#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_physical_device_properties2" -typedef VkPhysicalDeviceFeatures2 VkPhysicalDeviceFeatures2KHR; - -typedef VkPhysicalDeviceProperties2 VkPhysicalDeviceProperties2KHR; - -typedef VkFormatProperties2 VkFormatProperties2KHR; - -typedef VkImageFormatProperties2 VkImageFormatProperties2KHR; - -typedef VkPhysicalDeviceImageFormatInfo2 VkPhysicalDeviceImageFormatInfo2KHR; - -typedef VkQueueFamilyProperties2 VkQueueFamilyProperties2KHR; - -typedef VkPhysicalDeviceMemoryProperties2 VkPhysicalDeviceMemoryProperties2KHR; - -typedef VkSparseImageFormatProperties2 VkSparseImageFormatProperties2KHR; - -typedef VkPhysicalDeviceSparseImageFormatInfo2 VkPhysicalDeviceSparseImageFormatInfo2KHR; - -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2KHR)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceFeatures2* pFeatures); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2KHR( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceProperties2* pProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2KHR( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkFormatProperties2* pFormatProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2KHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, - VkImageFormatProperties2* pImageFormatProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2KHR( - VkPhysicalDevice physicalDevice, - uint32_t* pQueueFamilyPropertyCount, - VkQueueFamilyProperties2* pQueueFamilyProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2KHR( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceMemoryProperties2* pMemoryProperties); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2KHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, - uint32_t* pPropertyCount, - VkSparseImageFormatProperties2* pProperties); -#endif - - -#define VK_KHR_device_group 1 -#define VK_KHR_DEVICE_GROUP_SPEC_VERSION 4 -#define VK_KHR_DEVICE_GROUP_EXTENSION_NAME "VK_KHR_device_group" -typedef VkPeerMemoryFeatureFlags VkPeerMemoryFeatureFlagsKHR; - -typedef VkPeerMemoryFeatureFlagBits VkPeerMemoryFeatureFlagBitsKHR; - -typedef VkMemoryAllocateFlags VkMemoryAllocateFlagsKHR; - -typedef VkMemoryAllocateFlagBits VkMemoryAllocateFlagBitsKHR; - -typedef VkMemoryAllocateFlagsInfo VkMemoryAllocateFlagsInfoKHR; - -typedef VkDeviceGroupRenderPassBeginInfo VkDeviceGroupRenderPassBeginInfoKHR; - -typedef VkDeviceGroupCommandBufferBeginInfo VkDeviceGroupCommandBufferBeginInfoKHR; - -typedef VkDeviceGroupSubmitInfo VkDeviceGroupSubmitInfoKHR; - -typedef VkDeviceGroupBindSparseInfo VkDeviceGroupBindSparseInfoKHR; - -typedef VkBindBufferMemoryDeviceGroupInfo VkBindBufferMemoryDeviceGroupInfoKHR; - -typedef VkBindImageMemoryDeviceGroupInfo VkBindImageMemoryDeviceGroupInfoKHR; - -typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); -typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMaskKHR)(VkCommandBuffer commandBuffer, uint32_t deviceMask); -typedef void (VKAPI_PTR *PFN_vkCmdDispatchBaseKHR)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeaturesKHR( - VkDevice device, - uint32_t heapIndex, - uint32_t localDeviceIndex, - uint32_t remoteDeviceIndex, - VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMaskKHR( - VkCommandBuffer commandBuffer, - uint32_t deviceMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHR( - VkCommandBuffer commandBuffer, - uint32_t baseGroupX, - uint32_t baseGroupY, - uint32_t baseGroupZ, - uint32_t groupCountX, - uint32_t groupCountY, - uint32_t groupCountZ); -#endif - - -#define VK_KHR_shader_draw_parameters 1 -#define VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION 1 -#define VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME "VK_KHR_shader_draw_parameters" - - -#define VK_KHR_maintenance1 1 -#define VK_KHR_MAINTENANCE_1_SPEC_VERSION 2 -#define VK_KHR_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_maintenance1" -#define VK_KHR_MAINTENANCE1_SPEC_VERSION VK_KHR_MAINTENANCE_1_SPEC_VERSION -#define VK_KHR_MAINTENANCE1_EXTENSION_NAME VK_KHR_MAINTENANCE_1_EXTENSION_NAME -typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR; - -typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkTrimCommandPoolKHR( - VkDevice device, - VkCommandPool commandPool, - VkCommandPoolTrimFlags flags); -#endif - - -#define VK_KHR_device_group_creation 1 -#define VK_KHR_DEVICE_GROUP_CREATION_SPEC_VERSION 1 -#define VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME "VK_KHR_device_group_creation" -#define VK_MAX_DEVICE_GROUP_SIZE_KHR VK_MAX_DEVICE_GROUP_SIZE -typedef VkPhysicalDeviceGroupProperties VkPhysicalDeviceGroupPropertiesKHR; - -typedef VkDeviceGroupDeviceCreateInfo VkDeviceGroupDeviceCreateInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroupsKHR)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroupsKHR( - VkInstance instance, - uint32_t* pPhysicalDeviceGroupCount, - VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); -#endif - - -#define VK_KHR_external_memory_capabilities 1 -#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_memory_capabilities" -#define VK_LUID_SIZE_KHR VK_LUID_SIZE -typedef VkExternalMemoryHandleTypeFlags VkExternalMemoryHandleTypeFlagsKHR; - -typedef VkExternalMemoryHandleTypeFlagBits VkExternalMemoryHandleTypeFlagBitsKHR; - -typedef VkExternalMemoryFeatureFlags VkExternalMemoryFeatureFlagsKHR; - -typedef VkExternalMemoryFeatureFlagBits VkExternalMemoryFeatureFlagBitsKHR; - -typedef VkExternalMemoryProperties VkExternalMemoryPropertiesKHR; - -typedef VkPhysicalDeviceExternalImageFormatInfo VkPhysicalDeviceExternalImageFormatInfoKHR; - -typedef VkExternalImageFormatProperties VkExternalImageFormatPropertiesKHR; - -typedef VkPhysicalDeviceExternalBufferInfo VkPhysicalDeviceExternalBufferInfoKHR; - -typedef VkExternalBufferProperties VkExternalBufferPropertiesKHR; - -typedef VkPhysicalDeviceIDProperties VkPhysicalDeviceIDPropertiesKHR; - -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferPropertiesKHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, - VkExternalBufferProperties* pExternalBufferProperties); -#endif - - -#define VK_KHR_external_memory 1 -#define VK_KHR_EXTERNAL_MEMORY_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME "VK_KHR_external_memory" -#define VK_QUEUE_FAMILY_EXTERNAL_KHR VK_QUEUE_FAMILY_EXTERNAL -typedef VkExternalMemoryImageCreateInfo VkExternalMemoryImageCreateInfoKHR; - -typedef VkExternalMemoryBufferCreateInfo VkExternalMemoryBufferCreateInfoKHR; - -typedef VkExportMemoryAllocateInfo VkExportMemoryAllocateInfoKHR; - - - -#define VK_KHR_external_memory_fd 1 -#define VK_KHR_EXTERNAL_MEMORY_FD_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME "VK_KHR_external_memory_fd" -typedef struct VkImportMemoryFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagBits handleType; - int fd; -} VkImportMemoryFdInfoKHR; - -typedef struct VkMemoryFdPropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t memoryTypeBits; -} VkMemoryFdPropertiesKHR; - -typedef struct VkMemoryGetFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkDeviceMemory memory; - VkExternalMemoryHandleTypeFlagBits handleType; -} VkMemoryGetFdInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdKHR)(VkDevice device, const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd); -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdPropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, int fd, VkMemoryFdPropertiesKHR* pMemoryFdProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdKHR( - VkDevice device, - const VkMemoryGetFdInfoKHR* pGetFdInfo, - int* pFd); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdPropertiesKHR( - VkDevice device, - VkExternalMemoryHandleTypeFlagBits handleType, - int fd, - VkMemoryFdPropertiesKHR* pMemoryFdProperties); -#endif - - -#define VK_KHR_external_semaphore_capabilities 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_semaphore_capabilities" -typedef VkExternalSemaphoreHandleTypeFlags VkExternalSemaphoreHandleTypeFlagsKHR; - -typedef VkExternalSemaphoreHandleTypeFlagBits VkExternalSemaphoreHandleTypeFlagBitsKHR; - -typedef VkExternalSemaphoreFeatureFlags VkExternalSemaphoreFeatureFlagsKHR; - -typedef VkExternalSemaphoreFeatureFlagBits VkExternalSemaphoreFeatureFlagBitsKHR; - -typedef VkPhysicalDeviceExternalSemaphoreInfo VkPhysicalDeviceExternalSemaphoreInfoKHR; - -typedef VkExternalSemaphoreProperties VkExternalSemaphorePropertiesKHR; - -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphorePropertiesKHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, - VkExternalSemaphoreProperties* pExternalSemaphoreProperties); -#endif - - -#define VK_KHR_external_semaphore 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_KHR_external_semaphore" -typedef VkSemaphoreImportFlags VkSemaphoreImportFlagsKHR; - -typedef VkSemaphoreImportFlagBits VkSemaphoreImportFlagBitsKHR; - -typedef VkExportSemaphoreCreateInfo VkExportSemaphoreCreateInfoKHR; - - - -#define VK_KHR_external_semaphore_fd 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME "VK_KHR_external_semaphore_fd" -typedef struct VkImportSemaphoreFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - VkSemaphoreImportFlags flags; - VkExternalSemaphoreHandleTypeFlagBits handleType; - int fd; -} VkImportSemaphoreFdInfoKHR; - -typedef struct VkSemaphoreGetFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - VkExternalSemaphoreHandleTypeFlagBits handleType; -} VkSemaphoreGetFdInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreFdKHR)(VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo); -typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreFdKHR)(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreFdKHR( - VkDevice device, - const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreFdKHR( - VkDevice device, - const VkSemaphoreGetFdInfoKHR* pGetFdInfo, - int* pFd); -#endif - - -#define VK_KHR_push_descriptor 1 -#define VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION 2 -#define VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME "VK_KHR_push_descriptor" -typedef struct VkPhysicalDevicePushDescriptorPropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t maxPushDescriptors; -} VkPhysicalDevicePushDescriptorPropertiesKHR; - -typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetKHR)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites); -typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplateKHR)(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkPipelineLayout layout, uint32_t set, const void* pData); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetKHR( - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipelineLayout layout, - uint32_t set, - uint32_t descriptorWriteCount, - const VkWriteDescriptorSet* pDescriptorWrites); - -VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR( - VkCommandBuffer commandBuffer, - VkDescriptorUpdateTemplate descriptorUpdateTemplate, - VkPipelineLayout layout, - uint32_t set, - const void* pData); -#endif - - -#define VK_KHR_shader_float16_int8 1 -#define VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION 1 -#define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8" -typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceShaderFloat16Int8FeaturesKHR; - -typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceFloat16Int8FeaturesKHR; - - - -#define VK_KHR_16bit_storage 1 -#define VK_KHR_16BIT_STORAGE_SPEC_VERSION 1 -#define VK_KHR_16BIT_STORAGE_EXTENSION_NAME "VK_KHR_16bit_storage" -typedef VkPhysicalDevice16BitStorageFeatures VkPhysicalDevice16BitStorageFeaturesKHR; - - - -#define VK_KHR_incremental_present 1 -#define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 2 -#define VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME "VK_KHR_incremental_present" -typedef struct VkRectLayerKHR { - VkOffset2D offset; - VkExtent2D extent; - uint32_t layer; -} VkRectLayerKHR; - -typedef struct VkPresentRegionKHR { - uint32_t rectangleCount; - const VkRectLayerKHR* pRectangles; -} VkPresentRegionKHR; - -typedef struct VkPresentRegionsKHR { - VkStructureType sType; - const void* pNext; - uint32_t swapchainCount; - const VkPresentRegionKHR* pRegions; -} VkPresentRegionsKHR; - - - -#define VK_KHR_descriptor_update_template 1 -typedef VkDescriptorUpdateTemplate VkDescriptorUpdateTemplateKHR; - -#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION 1 -#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME "VK_KHR_descriptor_update_template" -typedef VkDescriptorUpdateTemplateType VkDescriptorUpdateTemplateTypeKHR; - -typedef VkDescriptorUpdateTemplateCreateFlags VkDescriptorUpdateTemplateCreateFlagsKHR; - -typedef VkDescriptorUpdateTemplateEntry VkDescriptorUpdateTemplateEntryKHR; - -typedef VkDescriptorUpdateTemplateCreateInfo VkDescriptorUpdateTemplateCreateInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplateKHR)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); -typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplateKHR)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplateKHR)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplateKHR( - VkDevice device, - const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplateKHR( - VkDevice device, - VkDescriptorUpdateTemplate descriptorUpdateTemplate, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR( - VkDevice device, - VkDescriptorSet descriptorSet, - VkDescriptorUpdateTemplate descriptorUpdateTemplate, - const void* pData); -#endif - - -#define VK_KHR_imageless_framebuffer 1 -#define VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION 1 -#define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME "VK_KHR_imageless_framebuffer" -typedef VkPhysicalDeviceImagelessFramebufferFeatures VkPhysicalDeviceImagelessFramebufferFeaturesKHR; - -typedef VkFramebufferAttachmentsCreateInfo VkFramebufferAttachmentsCreateInfoKHR; - -typedef VkFramebufferAttachmentImageInfo VkFramebufferAttachmentImageInfoKHR; - -typedef VkRenderPassAttachmentBeginInfo VkRenderPassAttachmentBeginInfoKHR; - - - -#define VK_KHR_create_renderpass2 1 -#define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1 -#define VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME "VK_KHR_create_renderpass2" -typedef VkRenderPassCreateInfo2 VkRenderPassCreateInfo2KHR; - -typedef VkAttachmentDescription2 VkAttachmentDescription2KHR; - -typedef VkAttachmentReference2 VkAttachmentReference2KHR; - -typedef VkSubpassDescription2 VkSubpassDescription2KHR; - -typedef VkSubpassDependency2 VkSubpassDependency2KHR; - -typedef VkSubpassBeginInfo VkSubpassBeginInfoKHR; - -typedef VkSubpassEndInfo VkSubpassEndInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); -typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo); -typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo); -typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR( - VkDevice device, - const VkRenderPassCreateInfo2* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkRenderPass* pRenderPass); - -VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2KHR( - VkCommandBuffer commandBuffer, - const VkRenderPassBeginInfo* pRenderPassBegin, - const VkSubpassBeginInfo* pSubpassBeginInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2KHR( - VkCommandBuffer commandBuffer, - const VkSubpassBeginInfo* pSubpassBeginInfo, - const VkSubpassEndInfo* pSubpassEndInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2KHR( - VkCommandBuffer commandBuffer, - const VkSubpassEndInfo* pSubpassEndInfo); -#endif - - -#define VK_KHR_shared_presentable_image 1 -#define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1 -#define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image" -typedef struct VkSharedPresentSurfaceCapabilitiesKHR { - VkStructureType sType; - void* pNext; - VkImageUsageFlags sharedPresentSupportedUsageFlags; -} VkSharedPresentSurfaceCapabilitiesKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainStatusKHR)(VkDevice device, VkSwapchainKHR swapchain); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainStatusKHR( - VkDevice device, - VkSwapchainKHR swapchain); -#endif - - -#define VK_KHR_external_fence_capabilities 1 -#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_fence_capabilities" -typedef VkExternalFenceHandleTypeFlags VkExternalFenceHandleTypeFlagsKHR; - -typedef VkExternalFenceHandleTypeFlagBits VkExternalFenceHandleTypeFlagBitsKHR; - -typedef VkExternalFenceFeatureFlags VkExternalFenceFeatureFlagsKHR; - -typedef VkExternalFenceFeatureFlagBits VkExternalFenceFeatureFlagBitsKHR; - -typedef VkPhysicalDeviceExternalFenceInfo VkPhysicalDeviceExternalFenceInfoKHR; - -typedef VkExternalFenceProperties VkExternalFencePropertiesKHR; - -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFencePropertiesKHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, - VkExternalFenceProperties* pExternalFenceProperties); -#endif - - -#define VK_KHR_external_fence 1 -#define VK_KHR_EXTERNAL_FENCE_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME "VK_KHR_external_fence" -typedef VkFenceImportFlags VkFenceImportFlagsKHR; - -typedef VkFenceImportFlagBits VkFenceImportFlagBitsKHR; - -typedef VkExportFenceCreateInfo VkExportFenceCreateInfoKHR; - - - -#define VK_KHR_external_fence_fd 1 -#define VK_KHR_EXTERNAL_FENCE_FD_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME "VK_KHR_external_fence_fd" -typedef struct VkImportFenceFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkFence fence; - VkFenceImportFlags flags; - VkExternalFenceHandleTypeFlagBits handleType; - int fd; -} VkImportFenceFdInfoKHR; - -typedef struct VkFenceGetFdInfoKHR { - VkStructureType sType; - const void* pNext; - VkFence fence; - VkExternalFenceHandleTypeFlagBits handleType; -} VkFenceGetFdInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkImportFenceFdKHR)(VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo); -typedef VkResult (VKAPI_PTR *PFN_vkGetFenceFdKHR)(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceFdKHR( - VkDevice device, - const VkImportFenceFdInfoKHR* pImportFenceFdInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceFdKHR( - VkDevice device, - const VkFenceGetFdInfoKHR* pGetFdInfo, - int* pFd); -#endif - - -#define VK_KHR_performance_query 1 -#define VK_KHR_PERFORMANCE_QUERY_SPEC_VERSION 1 -#define VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME "VK_KHR_performance_query" - -typedef enum VkPerformanceCounterUnitKHR { - VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR = 0, - VK_PERFORMANCE_COUNTER_UNIT_PERCENTAGE_KHR = 1, - VK_PERFORMANCE_COUNTER_UNIT_NANOSECONDS_KHR = 2, - VK_PERFORMANCE_COUNTER_UNIT_BYTES_KHR = 3, - VK_PERFORMANCE_COUNTER_UNIT_BYTES_PER_SECOND_KHR = 4, - VK_PERFORMANCE_COUNTER_UNIT_KELVIN_KHR = 5, - VK_PERFORMANCE_COUNTER_UNIT_WATTS_KHR = 6, - VK_PERFORMANCE_COUNTER_UNIT_VOLTS_KHR = 7, - VK_PERFORMANCE_COUNTER_UNIT_AMPS_KHR = 8, - VK_PERFORMANCE_COUNTER_UNIT_HERTZ_KHR = 9, - VK_PERFORMANCE_COUNTER_UNIT_CYCLES_KHR = 10, - VK_PERFORMANCE_COUNTER_UNIT_MAX_ENUM_KHR = 0x7FFFFFFF -} VkPerformanceCounterUnitKHR; - -typedef enum VkPerformanceCounterScopeKHR { - VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR = 0, - VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR = 1, - VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR = 2, - VK_QUERY_SCOPE_COMMAND_BUFFER_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR, - VK_QUERY_SCOPE_RENDER_PASS_KHR = VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR, - VK_QUERY_SCOPE_COMMAND_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR, - VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkPerformanceCounterScopeKHR; - -typedef enum VkPerformanceCounterStorageKHR { - VK_PERFORMANCE_COUNTER_STORAGE_INT32_KHR = 0, - VK_PERFORMANCE_COUNTER_STORAGE_INT64_KHR = 1, - VK_PERFORMANCE_COUNTER_STORAGE_UINT32_KHR = 2, - VK_PERFORMANCE_COUNTER_STORAGE_UINT64_KHR = 3, - VK_PERFORMANCE_COUNTER_STORAGE_FLOAT32_KHR = 4, - VK_PERFORMANCE_COUNTER_STORAGE_FLOAT64_KHR = 5, - VK_PERFORMANCE_COUNTER_STORAGE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkPerformanceCounterStorageKHR; - -typedef enum VkPerformanceCounterDescriptionFlagBitsKHR { - VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_BIT_KHR = 0x00000001, - VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_BIT_KHR = 0x00000002, - VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_KHR = VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_BIT_KHR, - VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_KHR = VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_BIT_KHR, - VK_PERFORMANCE_COUNTER_DESCRIPTION_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkPerformanceCounterDescriptionFlagBitsKHR; -typedef VkFlags VkPerformanceCounterDescriptionFlagsKHR; - -typedef enum VkAcquireProfilingLockFlagBitsKHR { - VK_ACQUIRE_PROFILING_LOCK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkAcquireProfilingLockFlagBitsKHR; -typedef VkFlags VkAcquireProfilingLockFlagsKHR; -typedef struct VkPhysicalDevicePerformanceQueryFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 performanceCounterQueryPools; - VkBool32 performanceCounterMultipleQueryPools; -} VkPhysicalDevicePerformanceQueryFeaturesKHR; - -typedef struct VkPhysicalDevicePerformanceQueryPropertiesKHR { - VkStructureType sType; - void* pNext; - VkBool32 allowCommandBufferQueryCopies; -} VkPhysicalDevicePerformanceQueryPropertiesKHR; - -typedef struct VkPerformanceCounterKHR { - VkStructureType sType; - void* pNext; - VkPerformanceCounterUnitKHR unit; - VkPerformanceCounterScopeKHR scope; - VkPerformanceCounterStorageKHR storage; - uint8_t uuid[VK_UUID_SIZE]; -} VkPerformanceCounterKHR; - -typedef struct VkPerformanceCounterDescriptionKHR { - VkStructureType sType; - void* pNext; - VkPerformanceCounterDescriptionFlagsKHR flags; - char name[VK_MAX_DESCRIPTION_SIZE]; - char category[VK_MAX_DESCRIPTION_SIZE]; - char description[VK_MAX_DESCRIPTION_SIZE]; -} VkPerformanceCounterDescriptionKHR; - -typedef struct VkQueryPoolPerformanceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t queueFamilyIndex; - uint32_t counterIndexCount; - const uint32_t* pCounterIndices; -} VkQueryPoolPerformanceCreateInfoKHR; - -typedef union VkPerformanceCounterResultKHR { - int32_t int32; - int64_t int64; - uint32_t uint32; - uint64_t uint64; - float float32; - double float64; -} VkPerformanceCounterResultKHR; - -typedef struct VkAcquireProfilingLockInfoKHR { - VkStructureType sType; - const void* pNext; - VkAcquireProfilingLockFlagsKHR flags; - uint64_t timeout; -} VkAcquireProfilingLockInfoKHR; - -typedef struct VkPerformanceQuerySubmitInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t counterPassIndex; -} VkPerformanceQuerySubmitInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t* pCounterCount, VkPerformanceCounterKHR* pCounters, VkPerformanceCounterDescriptionKHR* pCounterDescriptions); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR)(VkPhysicalDevice physicalDevice, const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo, uint32_t* pNumPasses); -typedef VkResult (VKAPI_PTR *PFN_vkAcquireProfilingLockKHR)(VkDevice device, const VkAcquireProfilingLockInfoKHR* pInfo); -typedef void (VKAPI_PTR *PFN_vkReleaseProfilingLockKHR)(VkDevice device); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - uint32_t* pCounterCount, - VkPerformanceCounterKHR* pCounters, - VkPerformanceCounterDescriptionKHR* pCounterDescriptions); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR( - VkPhysicalDevice physicalDevice, - const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo, - uint32_t* pNumPasses); - -VKAPI_ATTR VkResult VKAPI_CALL vkAcquireProfilingLockKHR( - VkDevice device, - const VkAcquireProfilingLockInfoKHR* pInfo); - -VKAPI_ATTR void VKAPI_CALL vkReleaseProfilingLockKHR( - VkDevice device); -#endif - - -#define VK_KHR_maintenance2 1 -#define VK_KHR_MAINTENANCE_2_SPEC_VERSION 1 -#define VK_KHR_MAINTENANCE_2_EXTENSION_NAME "VK_KHR_maintenance2" -#define VK_KHR_MAINTENANCE2_SPEC_VERSION VK_KHR_MAINTENANCE_2_SPEC_VERSION -#define VK_KHR_MAINTENANCE2_EXTENSION_NAME VK_KHR_MAINTENANCE_2_EXTENSION_NAME -typedef VkPointClippingBehavior VkPointClippingBehaviorKHR; - -typedef VkTessellationDomainOrigin VkTessellationDomainOriginKHR; - -typedef VkPhysicalDevicePointClippingProperties VkPhysicalDevicePointClippingPropertiesKHR; - -typedef VkRenderPassInputAttachmentAspectCreateInfo VkRenderPassInputAttachmentAspectCreateInfoKHR; - -typedef VkInputAttachmentAspectReference VkInputAttachmentAspectReferenceKHR; - -typedef VkImageViewUsageCreateInfo VkImageViewUsageCreateInfoKHR; - -typedef VkPipelineTessellationDomainOriginStateCreateInfo VkPipelineTessellationDomainOriginStateCreateInfoKHR; - - - -#define VK_KHR_get_surface_capabilities2 1 -#define VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION 1 -#define VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME "VK_KHR_get_surface_capabilities2" -typedef struct VkPhysicalDeviceSurfaceInfo2KHR { - VkStructureType sType; - const void* pNext; - VkSurfaceKHR surface; -} VkPhysicalDeviceSurfaceInfo2KHR; - -typedef struct VkSurfaceCapabilities2KHR { - VkStructureType sType; - void* pNext; - VkSurfaceCapabilitiesKHR surfaceCapabilities; -} VkSurfaceCapabilities2KHR; - -typedef struct VkSurfaceFormat2KHR { - VkStructureType sType; - void* pNext; - VkSurfaceFormatKHR surfaceFormat; -} VkSurfaceFormat2KHR; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2KHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, - VkSurfaceCapabilities2KHR* pSurfaceCapabilities); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats2KHR( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, - uint32_t* pSurfaceFormatCount, - VkSurfaceFormat2KHR* pSurfaceFormats); -#endif - - -#define VK_KHR_variable_pointers 1 -#define VK_KHR_VARIABLE_POINTERS_SPEC_VERSION 1 -#define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME "VK_KHR_variable_pointers" -typedef VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointerFeaturesKHR; - -typedef VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointersFeaturesKHR; - - - -#define VK_KHR_get_display_properties2 1 -#define VK_KHR_GET_DISPLAY_PROPERTIES_2_SPEC_VERSION 1 -#define VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_display_properties2" -typedef struct VkDisplayProperties2KHR { - VkStructureType sType; - void* pNext; - VkDisplayPropertiesKHR displayProperties; -} VkDisplayProperties2KHR; - -typedef struct VkDisplayPlaneProperties2KHR { - VkStructureType sType; - void* pNext; - VkDisplayPlanePropertiesKHR displayPlaneProperties; -} VkDisplayPlaneProperties2KHR; - -typedef struct VkDisplayModeProperties2KHR { - VkStructureType sType; - void* pNext; - VkDisplayModePropertiesKHR displayModeProperties; -} VkDisplayModeProperties2KHR; - -typedef struct VkDisplayPlaneInfo2KHR { - VkStructureType sType; - const void* pNext; - VkDisplayModeKHR mode; - uint32_t planeIndex; -} VkDisplayPlaneInfo2KHR; - -typedef struct VkDisplayPlaneCapabilities2KHR { - VkStructureType sType; - void* pNext; - VkDisplayPlaneCapabilitiesKHR capabilities; -} VkDisplayPlaneCapabilities2KHR; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayProperties2KHR* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlaneProperties2KHR* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModeProperties2KHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModeProperties2KHR* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR* pCapabilities); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayProperties2KHR( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkDisplayProperties2KHR* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlaneProperties2KHR( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkDisplayPlaneProperties2KHR* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModeProperties2KHR( - VkPhysicalDevice physicalDevice, - VkDisplayKHR display, - uint32_t* pPropertyCount, - VkDisplayModeProperties2KHR* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilities2KHR( - VkPhysicalDevice physicalDevice, - const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo, - VkDisplayPlaneCapabilities2KHR* pCapabilities); -#endif - - -#define VK_KHR_dedicated_allocation 1 -#define VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION 3 -#define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_KHR_dedicated_allocation" -typedef VkMemoryDedicatedRequirements VkMemoryDedicatedRequirementsKHR; - -typedef VkMemoryDedicatedAllocateInfo VkMemoryDedicatedAllocateInfoKHR; - - - -#define VK_KHR_storage_buffer_storage_class 1 -#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION 1 -#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME "VK_KHR_storage_buffer_storage_class" - - -#define VK_KHR_relaxed_block_layout 1 -#define VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION 1 -#define VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME "VK_KHR_relaxed_block_layout" - - -#define VK_KHR_get_memory_requirements2 1 -#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION 1 -#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME "VK_KHR_get_memory_requirements2" -typedef VkBufferMemoryRequirementsInfo2 VkBufferMemoryRequirementsInfo2KHR; - -typedef VkImageMemoryRequirementsInfo2 VkImageMemoryRequirementsInfo2KHR; - -typedef VkImageSparseMemoryRequirementsInfo2 VkImageSparseMemoryRequirementsInfo2KHR; - -typedef VkMemoryRequirements2 VkMemoryRequirements2KHR; - -typedef VkSparseImageMemoryRequirements2 VkSparseImageMemoryRequirements2KHR; - -typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2KHR)(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2KHR)(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2KHR)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2KHR( - VkDevice device, - const VkImageMemoryRequirementsInfo2* pInfo, - VkMemoryRequirements2* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2KHR( - VkDevice device, - const VkBufferMemoryRequirementsInfo2* pInfo, - VkMemoryRequirements2* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2KHR( - VkDevice device, - const VkImageSparseMemoryRequirementsInfo2* pInfo, - uint32_t* pSparseMemoryRequirementCount, - VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); -#endif - - -#define VK_KHR_image_format_list 1 -#define VK_KHR_IMAGE_FORMAT_LIST_SPEC_VERSION 1 -#define VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME "VK_KHR_image_format_list" -typedef VkImageFormatListCreateInfo VkImageFormatListCreateInfoKHR; - - - -#define VK_KHR_sampler_ycbcr_conversion 1 -typedef VkSamplerYcbcrConversion VkSamplerYcbcrConversionKHR; - -#define VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION 14 -#define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME "VK_KHR_sampler_ycbcr_conversion" -typedef VkSamplerYcbcrModelConversion VkSamplerYcbcrModelConversionKHR; - -typedef VkSamplerYcbcrRange VkSamplerYcbcrRangeKHR; - -typedef VkChromaLocation VkChromaLocationKHR; - -typedef VkSamplerYcbcrConversionCreateInfo VkSamplerYcbcrConversionCreateInfoKHR; - -typedef VkSamplerYcbcrConversionInfo VkSamplerYcbcrConversionInfoKHR; - -typedef VkBindImagePlaneMemoryInfo VkBindImagePlaneMemoryInfoKHR; - -typedef VkImagePlaneMemoryRequirementsInfo VkImagePlaneMemoryRequirementsInfoKHR; - -typedef VkPhysicalDeviceSamplerYcbcrConversionFeatures VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR; - -typedef VkSamplerYcbcrConversionImageFormatProperties VkSamplerYcbcrConversionImageFormatPropertiesKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversionKHR)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion); -typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversionKHR)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversionKHR( - VkDevice device, - const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSamplerYcbcrConversion* pYcbcrConversion); - -VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversionKHR( - VkDevice device, - VkSamplerYcbcrConversion ycbcrConversion, - const VkAllocationCallbacks* pAllocator); -#endif - - -#define VK_KHR_bind_memory2 1 -#define VK_KHR_BIND_MEMORY_2_SPEC_VERSION 1 -#define VK_KHR_BIND_MEMORY_2_EXTENSION_NAME "VK_KHR_bind_memory2" -typedef VkBindBufferMemoryInfo VkBindBufferMemoryInfoKHR; - -typedef VkBindImageMemoryInfo VkBindImageMemoryInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2KHR)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos); -typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2KHR)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2KHR( - VkDevice device, - uint32_t bindInfoCount, - const VkBindBufferMemoryInfo* pBindInfos); - -VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2KHR( - VkDevice device, - uint32_t bindInfoCount, - const VkBindImageMemoryInfo* pBindInfos); -#endif - - -#define VK_KHR_maintenance3 1 -#define VK_KHR_MAINTENANCE_3_SPEC_VERSION 1 -#define VK_KHR_MAINTENANCE_3_EXTENSION_NAME "VK_KHR_maintenance3" -#define VK_KHR_MAINTENANCE3_SPEC_VERSION VK_KHR_MAINTENANCE_3_SPEC_VERSION -#define VK_KHR_MAINTENANCE3_EXTENSION_NAME VK_KHR_MAINTENANCE_3_EXTENSION_NAME -typedef VkPhysicalDeviceMaintenance3Properties VkPhysicalDeviceMaintenance3PropertiesKHR; - -typedef VkDescriptorSetLayoutSupport VkDescriptorSetLayoutSupportKHR; - -typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupportKHR)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupportKHR( - VkDevice device, - const VkDescriptorSetLayoutCreateInfo* pCreateInfo, - VkDescriptorSetLayoutSupport* pSupport); -#endif - - -#define VK_KHR_draw_indirect_count 1 -#define VK_KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION 1 -#define VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_KHR_draw_indirect_count" -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountKHR( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkBuffer countBuffer, - VkDeviceSize countBufferOffset, - uint32_t maxDrawCount, - uint32_t stride); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountKHR( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkBuffer countBuffer, - VkDeviceSize countBufferOffset, - uint32_t maxDrawCount, - uint32_t stride); -#endif - - -#define VK_KHR_shader_subgroup_extended_types 1 -#define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION 1 -#define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME "VK_KHR_shader_subgroup_extended_types" -typedef VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR; - - - -#define VK_KHR_8bit_storage 1 -#define VK_KHR_8BIT_STORAGE_SPEC_VERSION 1 -#define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage" -typedef VkPhysicalDevice8BitStorageFeatures VkPhysicalDevice8BitStorageFeaturesKHR; - - - -#define VK_KHR_shader_atomic_int64 1 -#define VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION 1 -#define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME "VK_KHR_shader_atomic_int64" -typedef VkPhysicalDeviceShaderAtomicInt64Features VkPhysicalDeviceShaderAtomicInt64FeaturesKHR; - - - -#define VK_KHR_shader_clock 1 -#define VK_KHR_SHADER_CLOCK_SPEC_VERSION 1 -#define VK_KHR_SHADER_CLOCK_EXTENSION_NAME "VK_KHR_shader_clock" -typedef struct VkPhysicalDeviceShaderClockFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderSubgroupClock; - VkBool32 shaderDeviceClock; -} VkPhysicalDeviceShaderClockFeaturesKHR; - - - -#define VK_KHR_global_priority 1 -#define VK_MAX_GLOBAL_PRIORITY_SIZE_KHR 16U -#define VK_KHR_GLOBAL_PRIORITY_SPEC_VERSION 1 -#define VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME "VK_KHR_global_priority" - -typedef enum VkQueueGlobalPriorityKHR { - VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR = 128, - VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR = 256, - VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR = 512, - VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR = 1024, - VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR, - VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR, - VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR, - VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR, - VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_KHR = 0x7FFFFFFF -} VkQueueGlobalPriorityKHR; -typedef struct VkDeviceQueueGlobalPriorityCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkQueueGlobalPriorityKHR globalPriority; -} VkDeviceQueueGlobalPriorityCreateInfoKHR; - -typedef struct VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 globalPriorityQuery; -} VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR; - -typedef struct VkQueueFamilyGlobalPriorityPropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t priorityCount; - VkQueueGlobalPriorityKHR priorities[VK_MAX_GLOBAL_PRIORITY_SIZE_KHR]; -} VkQueueFamilyGlobalPriorityPropertiesKHR; - - - -#define VK_KHR_driver_properties 1 -#define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1 -#define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties" -#define VK_MAX_DRIVER_NAME_SIZE_KHR VK_MAX_DRIVER_NAME_SIZE -#define VK_MAX_DRIVER_INFO_SIZE_KHR VK_MAX_DRIVER_INFO_SIZE -typedef VkDriverId VkDriverIdKHR; - -typedef VkConformanceVersion VkConformanceVersionKHR; - -typedef VkPhysicalDeviceDriverProperties VkPhysicalDeviceDriverPropertiesKHR; - - - -#define VK_KHR_shader_float_controls 1 -#define VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION 4 -#define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME "VK_KHR_shader_float_controls" -typedef VkShaderFloatControlsIndependence VkShaderFloatControlsIndependenceKHR; - -typedef VkPhysicalDeviceFloatControlsProperties VkPhysicalDeviceFloatControlsPropertiesKHR; - - - -#define VK_KHR_depth_stencil_resolve 1 -#define VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION 1 -#define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME "VK_KHR_depth_stencil_resolve" -typedef VkResolveModeFlagBits VkResolveModeFlagBitsKHR; - -typedef VkResolveModeFlags VkResolveModeFlagsKHR; - -typedef VkSubpassDescriptionDepthStencilResolve VkSubpassDescriptionDepthStencilResolveKHR; - -typedef VkPhysicalDeviceDepthStencilResolveProperties VkPhysicalDeviceDepthStencilResolvePropertiesKHR; - - - -#define VK_KHR_swapchain_mutable_format 1 -#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION 1 -#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME "VK_KHR_swapchain_mutable_format" - - -#define VK_KHR_timeline_semaphore 1 -#define VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION 2 -#define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME "VK_KHR_timeline_semaphore" -typedef VkSemaphoreType VkSemaphoreTypeKHR; - -typedef VkSemaphoreWaitFlagBits VkSemaphoreWaitFlagBitsKHR; - -typedef VkSemaphoreWaitFlags VkSemaphoreWaitFlagsKHR; - -typedef VkPhysicalDeviceTimelineSemaphoreFeatures VkPhysicalDeviceTimelineSemaphoreFeaturesKHR; - -typedef VkPhysicalDeviceTimelineSemaphoreProperties VkPhysicalDeviceTimelineSemaphorePropertiesKHR; - -typedef VkSemaphoreTypeCreateInfo VkSemaphoreTypeCreateInfoKHR; - -typedef VkTimelineSemaphoreSubmitInfo VkTimelineSemaphoreSubmitInfoKHR; - -typedef VkSemaphoreWaitInfo VkSemaphoreWaitInfoKHR; - -typedef VkSemaphoreSignalInfo VkSemaphoreSignalInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValueKHR)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue); -typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphoresKHR)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout); -typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphoreKHR)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValueKHR( - VkDevice device, - VkSemaphore semaphore, - uint64_t* pValue); - -VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphoresKHR( - VkDevice device, - const VkSemaphoreWaitInfo* pWaitInfo, - uint64_t timeout); - -VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphoreKHR( - VkDevice device, - const VkSemaphoreSignalInfo* pSignalInfo); -#endif - - -#define VK_KHR_vulkan_memory_model 1 -#define VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION 3 -#define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model" -typedef VkPhysicalDeviceVulkanMemoryModelFeatures VkPhysicalDeviceVulkanMemoryModelFeaturesKHR; - - - -#define VK_KHR_shader_terminate_invocation 1 -#define VK_KHR_SHADER_TERMINATE_INVOCATION_SPEC_VERSION 1 -#define VK_KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME "VK_KHR_shader_terminate_invocation" -typedef VkPhysicalDeviceShaderTerminateInvocationFeatures VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR; - - - -#define VK_KHR_fragment_shading_rate 1 -#define VK_KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION 2 -#define VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME "VK_KHR_fragment_shading_rate" - -typedef enum VkFragmentShadingRateCombinerOpKHR { - VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR = 0, - VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR = 1, - VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR = 2, - VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR = 3, - VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR = 4, - VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_ENUM_KHR = 0x7FFFFFFF -} VkFragmentShadingRateCombinerOpKHR; -typedef struct VkFragmentShadingRateAttachmentInfoKHR { - VkStructureType sType; - const void* pNext; - const VkAttachmentReference2* pFragmentShadingRateAttachment; - VkExtent2D shadingRateAttachmentTexelSize; -} VkFragmentShadingRateAttachmentInfoKHR; - -typedef struct VkPipelineFragmentShadingRateStateCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkExtent2D fragmentSize; - VkFragmentShadingRateCombinerOpKHR combinerOps[2]; -} VkPipelineFragmentShadingRateStateCreateInfoKHR; - -typedef struct VkPhysicalDeviceFragmentShadingRateFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 pipelineFragmentShadingRate; - VkBool32 primitiveFragmentShadingRate; - VkBool32 attachmentFragmentShadingRate; -} VkPhysicalDeviceFragmentShadingRateFeaturesKHR; - -typedef struct VkPhysicalDeviceFragmentShadingRatePropertiesKHR { - VkStructureType sType; - void* pNext; - VkExtent2D minFragmentShadingRateAttachmentTexelSize; - VkExtent2D maxFragmentShadingRateAttachmentTexelSize; - uint32_t maxFragmentShadingRateAttachmentTexelSizeAspectRatio; - VkBool32 primitiveFragmentShadingRateWithMultipleViewports; - VkBool32 layeredShadingRateAttachments; - VkBool32 fragmentShadingRateNonTrivialCombinerOps; - VkExtent2D maxFragmentSize; - uint32_t maxFragmentSizeAspectRatio; - uint32_t maxFragmentShadingRateCoverageSamples; - VkSampleCountFlagBits maxFragmentShadingRateRasterizationSamples; - VkBool32 fragmentShadingRateWithShaderDepthStencilWrites; - VkBool32 fragmentShadingRateWithSampleMask; - VkBool32 fragmentShadingRateWithShaderSampleMask; - VkBool32 fragmentShadingRateWithConservativeRasterization; - VkBool32 fragmentShadingRateWithFragmentShaderInterlock; - VkBool32 fragmentShadingRateWithCustomSampleLocations; - VkBool32 fragmentShadingRateStrictMultiplyCombiner; -} VkPhysicalDeviceFragmentShadingRatePropertiesKHR; - -typedef struct VkPhysicalDeviceFragmentShadingRateKHR { - VkStructureType sType; - void* pNext; - VkSampleCountFlags sampleCounts; - VkExtent2D fragmentSize; -} VkPhysicalDeviceFragmentShadingRateKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pFragmentShadingRateCount, VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates); -typedef void (VKAPI_PTR *PFN_vkCmdSetFragmentShadingRateKHR)(VkCommandBuffer commandBuffer, const VkExtent2D* pFragmentSize, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceFragmentShadingRatesKHR( - VkPhysicalDevice physicalDevice, - uint32_t* pFragmentShadingRateCount, - VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetFragmentShadingRateKHR( - VkCommandBuffer commandBuffer, - const VkExtent2D* pFragmentSize, - const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); -#endif - - -#define VK_KHR_spirv_1_4 1 -#define VK_KHR_SPIRV_1_4_SPEC_VERSION 1 -#define VK_KHR_SPIRV_1_4_EXTENSION_NAME "VK_KHR_spirv_1_4" - - -#define VK_KHR_surface_protected_capabilities 1 -#define VK_KHR_SURFACE_PROTECTED_CAPABILITIES_SPEC_VERSION 1 -#define VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME "VK_KHR_surface_protected_capabilities" -typedef struct VkSurfaceProtectedCapabilitiesKHR { - VkStructureType sType; - const void* pNext; - VkBool32 supportsProtected; -} VkSurfaceProtectedCapabilitiesKHR; - - - -#define VK_KHR_separate_depth_stencil_layouts 1 -#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION 1 -#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME "VK_KHR_separate_depth_stencil_layouts" -typedef VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR; - -typedef VkAttachmentReferenceStencilLayout VkAttachmentReferenceStencilLayoutKHR; - -typedef VkAttachmentDescriptionStencilLayout VkAttachmentDescriptionStencilLayoutKHR; - - - -#define VK_KHR_present_wait 1 -#define VK_KHR_PRESENT_WAIT_SPEC_VERSION 1 -#define VK_KHR_PRESENT_WAIT_EXTENSION_NAME "VK_KHR_present_wait" -typedef struct VkPhysicalDevicePresentWaitFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 presentWait; -} VkPhysicalDevicePresentWaitFeaturesKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkWaitForPresentKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t presentId, uint64_t timeout); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkWaitForPresentKHR( - VkDevice device, - VkSwapchainKHR swapchain, - uint64_t presentId, - uint64_t timeout); -#endif - - -#define VK_KHR_uniform_buffer_standard_layout 1 -#define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION 1 -#define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME "VK_KHR_uniform_buffer_standard_layout" -typedef VkPhysicalDeviceUniformBufferStandardLayoutFeatures VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR; - - - -#define VK_KHR_buffer_device_address 1 -#define VK_KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 1 -#define VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_KHR_buffer_device_address" -typedef VkPhysicalDeviceBufferDeviceAddressFeatures VkPhysicalDeviceBufferDeviceAddressFeaturesKHR; - -typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoKHR; - -typedef VkBufferOpaqueCaptureAddressCreateInfo VkBufferOpaqueCaptureAddressCreateInfoKHR; - -typedef VkMemoryOpaqueCaptureAddressAllocateInfo VkMemoryOpaqueCaptureAddressAllocateInfoKHR; - -typedef VkDeviceMemoryOpaqueCaptureAddressInfo VkDeviceMemoryOpaqueCaptureAddressInfoKHR; - -typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); -typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); -typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressKHR( - VkDevice device, - const VkBufferDeviceAddressInfo* pInfo); - -VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddressKHR( - VkDevice device, - const VkBufferDeviceAddressInfo* pInfo); - -VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddressKHR( - VkDevice device, - const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); -#endif - - -#define VK_KHR_deferred_host_operations 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeferredOperationKHR) -#define VK_KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION 4 -#define VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME "VK_KHR_deferred_host_operations" -typedef VkResult (VKAPI_PTR *PFN_vkCreateDeferredOperationKHR)(VkDevice device, const VkAllocationCallbacks* pAllocator, VkDeferredOperationKHR* pDeferredOperation); -typedef void (VKAPI_PTR *PFN_vkDestroyDeferredOperationKHR)(VkDevice device, VkDeferredOperationKHR operation, const VkAllocationCallbacks* pAllocator); -typedef uint32_t (VKAPI_PTR *PFN_vkGetDeferredOperationMaxConcurrencyKHR)(VkDevice device, VkDeferredOperationKHR operation); -typedef VkResult (VKAPI_PTR *PFN_vkGetDeferredOperationResultKHR)(VkDevice device, VkDeferredOperationKHR operation); -typedef VkResult (VKAPI_PTR *PFN_vkDeferredOperationJoinKHR)(VkDevice device, VkDeferredOperationKHR operation); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDeferredOperationKHR( - VkDevice device, - const VkAllocationCallbacks* pAllocator, - VkDeferredOperationKHR* pDeferredOperation); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDeferredOperationKHR( - VkDevice device, - VkDeferredOperationKHR operation, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR uint32_t VKAPI_CALL vkGetDeferredOperationMaxConcurrencyKHR( - VkDevice device, - VkDeferredOperationKHR operation); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDeferredOperationResultKHR( - VkDevice device, - VkDeferredOperationKHR operation); - -VKAPI_ATTR VkResult VKAPI_CALL vkDeferredOperationJoinKHR( - VkDevice device, - VkDeferredOperationKHR operation); -#endif - - -#define VK_KHR_pipeline_executable_properties 1 -#define VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_SPEC_VERSION 1 -#define VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME "VK_KHR_pipeline_executable_properties" - -typedef enum VkPipelineExecutableStatisticFormatKHR { - VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR = 0, - VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR = 1, - VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR = 2, - VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR = 3, - VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_MAX_ENUM_KHR = 0x7FFFFFFF -} VkPipelineExecutableStatisticFormatKHR; -typedef struct VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 pipelineExecutableInfo; -} VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR; - -typedef struct VkPipelineInfoKHR { - VkStructureType sType; - const void* pNext; - VkPipeline pipeline; -} VkPipelineInfoKHR; - -typedef struct VkPipelineExecutablePropertiesKHR { - VkStructureType sType; - void* pNext; - VkShaderStageFlags stages; - char name[VK_MAX_DESCRIPTION_SIZE]; - char description[VK_MAX_DESCRIPTION_SIZE]; - uint32_t subgroupSize; -} VkPipelineExecutablePropertiesKHR; - -typedef struct VkPipelineExecutableInfoKHR { - VkStructureType sType; - const void* pNext; - VkPipeline pipeline; - uint32_t executableIndex; -} VkPipelineExecutableInfoKHR; - -typedef union VkPipelineExecutableStatisticValueKHR { - VkBool32 b32; - int64_t i64; - uint64_t u64; - double f64; -} VkPipelineExecutableStatisticValueKHR; - -typedef struct VkPipelineExecutableStatisticKHR { - VkStructureType sType; - void* pNext; - char name[VK_MAX_DESCRIPTION_SIZE]; - char description[VK_MAX_DESCRIPTION_SIZE]; - VkPipelineExecutableStatisticFormatKHR format; - VkPipelineExecutableStatisticValueKHR value; -} VkPipelineExecutableStatisticKHR; - -typedef struct VkPipelineExecutableInternalRepresentationKHR { - VkStructureType sType; - void* pNext; - char name[VK_MAX_DESCRIPTION_SIZE]; - char description[VK_MAX_DESCRIPTION_SIZE]; - VkBool32 isText; - size_t dataSize; - void* pData; -} VkPipelineExecutableInternalRepresentationKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutablePropertiesKHR)(VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, uint32_t* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutableStatisticsKHR)(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics); -typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutableInternalRepresentationsKHR)(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutablePropertiesKHR( - VkDevice device, - const VkPipelineInfoKHR* pPipelineInfo, - uint32_t* pExecutableCount, - VkPipelineExecutablePropertiesKHR* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableStatisticsKHR( - VkDevice device, - const VkPipelineExecutableInfoKHR* pExecutableInfo, - uint32_t* pStatisticCount, - VkPipelineExecutableStatisticKHR* pStatistics); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR( - VkDevice device, - const VkPipelineExecutableInfoKHR* pExecutableInfo, - uint32_t* pInternalRepresentationCount, - VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations); -#endif - - -#define VK_KHR_shader_integer_dot_product 1 -#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION 1 -#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME "VK_KHR_shader_integer_dot_product" -typedef VkPhysicalDeviceShaderIntegerDotProductFeatures VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR; - -typedef VkPhysicalDeviceShaderIntegerDotProductProperties VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR; - - - -#define VK_KHR_pipeline_library 1 -#define VK_KHR_PIPELINE_LIBRARY_SPEC_VERSION 1 -#define VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME "VK_KHR_pipeline_library" -typedef struct VkPipelineLibraryCreateInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t libraryCount; - const VkPipeline* pLibraries; -} VkPipelineLibraryCreateInfoKHR; - - - -#define VK_KHR_shader_non_semantic_info 1 -#define VK_KHR_SHADER_NON_SEMANTIC_INFO_SPEC_VERSION 1 -#define VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME "VK_KHR_shader_non_semantic_info" - - -#define VK_KHR_present_id 1 -#define VK_KHR_PRESENT_ID_SPEC_VERSION 1 -#define VK_KHR_PRESENT_ID_EXTENSION_NAME "VK_KHR_present_id" -typedef struct VkPresentIdKHR { - VkStructureType sType; - const void* pNext; - uint32_t swapchainCount; - const uint64_t* pPresentIds; -} VkPresentIdKHR; - -typedef struct VkPhysicalDevicePresentIdFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 presentId; -} VkPhysicalDevicePresentIdFeaturesKHR; - - - -#define VK_KHR_synchronization2 1 -#define VK_KHR_SYNCHRONIZATION_2_SPEC_VERSION 1 -#define VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME "VK_KHR_synchronization2" -typedef VkPipelineStageFlags2 VkPipelineStageFlags2KHR; - -typedef VkPipelineStageFlagBits2 VkPipelineStageFlagBits2KHR; - -typedef VkAccessFlags2 VkAccessFlags2KHR; - -typedef VkAccessFlagBits2 VkAccessFlagBits2KHR; - -typedef VkSubmitFlagBits VkSubmitFlagBitsKHR; - -typedef VkSubmitFlags VkSubmitFlagsKHR; - -typedef VkMemoryBarrier2 VkMemoryBarrier2KHR; - -typedef VkBufferMemoryBarrier2 VkBufferMemoryBarrier2KHR; - -typedef VkImageMemoryBarrier2 VkImageMemoryBarrier2KHR; - -typedef VkDependencyInfo VkDependencyInfoKHR; - -typedef VkSubmitInfo2 VkSubmitInfo2KHR; - -typedef VkSemaphoreSubmitInfo VkSemaphoreSubmitInfoKHR; - -typedef VkCommandBufferSubmitInfo VkCommandBufferSubmitInfoKHR; - -typedef VkPhysicalDeviceSynchronization2Features VkPhysicalDeviceSynchronization2FeaturesKHR; - -typedef struct VkQueueFamilyCheckpointProperties2NV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlags2 checkpointExecutionStageMask; -} VkQueueFamilyCheckpointProperties2NV; - -typedef struct VkCheckpointData2NV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlags2 stage; - void* pCheckpointMarker; -} VkCheckpointData2NV; - -typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); -typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); -typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2KHR)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); -typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2KHR)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); -typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2KHR)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); -typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); -typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); -typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointData2NV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointData2NV* pCheckpointData); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2KHR( - VkCommandBuffer commandBuffer, - VkEvent event, - const VkDependencyInfo* pDependencyInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2KHR( - VkCommandBuffer commandBuffer, - VkEvent event, - VkPipelineStageFlags2 stageMask); - -VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2KHR( - VkCommandBuffer commandBuffer, - uint32_t eventCount, - const VkEvent* pEvents, - const VkDependencyInfo* pDependencyInfos); - -VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2KHR( - VkCommandBuffer commandBuffer, - const VkDependencyInfo* pDependencyInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2KHR( - VkCommandBuffer commandBuffer, - VkPipelineStageFlags2 stage, - VkQueryPool queryPool, - uint32_t query); - -VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2KHR( - VkQueue queue, - uint32_t submitCount, - const VkSubmitInfo2* pSubmits, - VkFence fence); - -VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarker2AMD( - VkCommandBuffer commandBuffer, - VkPipelineStageFlags2 stage, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - uint32_t marker); - -VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointData2NV( - VkQueue queue, - uint32_t* pCheckpointDataCount, - VkCheckpointData2NV* pCheckpointData); -#endif - - -#define VK_KHR_fragment_shader_barycentric 1 -#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1 -#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_KHR_fragment_shader_barycentric" -typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 fragmentShaderBarycentric; -} VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR; - -typedef struct VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR { - VkStructureType sType; - void* pNext; - VkBool32 triStripVertexOrderIndependentOfProvokingVertex; -} VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR; - - - -#define VK_KHR_shader_subgroup_uniform_control_flow 1 -#define VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_SPEC_VERSION 1 -#define VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_EXTENSION_NAME "VK_KHR_shader_subgroup_uniform_control_flow" -typedef struct VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 shaderSubgroupUniformControlFlow; -} VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR; - - - -#define VK_KHR_zero_initialize_workgroup_memory 1 -#define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_SPEC_VERSION 1 -#define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_EXTENSION_NAME "VK_KHR_zero_initialize_workgroup_memory" -typedef VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR; - - - -#define VK_KHR_workgroup_memory_explicit_layout 1 -#define VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_SPEC_VERSION 1 -#define VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME "VK_KHR_workgroup_memory_explicit_layout" -typedef struct VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 workgroupMemoryExplicitLayout; - VkBool32 workgroupMemoryExplicitLayoutScalarBlockLayout; - VkBool32 workgroupMemoryExplicitLayout8BitAccess; - VkBool32 workgroupMemoryExplicitLayout16BitAccess; -} VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR; - - - -#define VK_KHR_copy_commands2 1 -#define VK_KHR_COPY_COMMANDS_2_SPEC_VERSION 1 -#define VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME "VK_KHR_copy_commands2" -typedef VkCopyBufferInfo2 VkCopyBufferInfo2KHR; - -typedef VkCopyImageInfo2 VkCopyImageInfo2KHR; - -typedef VkCopyBufferToImageInfo2 VkCopyBufferToImageInfo2KHR; - -typedef VkCopyImageToBufferInfo2 VkCopyImageToBufferInfo2KHR; - -typedef VkBlitImageInfo2 VkBlitImageInfo2KHR; - -typedef VkResolveImageInfo2 VkResolveImageInfo2KHR; - -typedef VkBufferCopy2 VkBufferCopy2KHR; - -typedef VkImageCopy2 VkImageCopy2KHR; - -typedef VkImageBlit2 VkImageBlit2KHR; - -typedef VkBufferImageCopy2 VkBufferImageCopy2KHR; - -typedef VkImageResolve2 VkImageResolve2KHR; - -typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); -typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2KHR)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); -typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2KHR)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2KHR( - VkCommandBuffer commandBuffer, - const VkCopyBufferInfo2* pCopyBufferInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2KHR( - VkCommandBuffer commandBuffer, - const VkCopyImageInfo2* pCopyImageInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2KHR( - VkCommandBuffer commandBuffer, - const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2KHR( - VkCommandBuffer commandBuffer, - const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2KHR( - VkCommandBuffer commandBuffer, - const VkBlitImageInfo2* pBlitImageInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2KHR( - VkCommandBuffer commandBuffer, - const VkResolveImageInfo2* pResolveImageInfo); -#endif - - -#define VK_KHR_format_feature_flags2 1 -#define VK_KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION 1 -#define VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME "VK_KHR_format_feature_flags2" -typedef VkFormatFeatureFlags2 VkFormatFeatureFlags2KHR; - -typedef VkFormatFeatureFlagBits2 VkFormatFeatureFlagBits2KHR; - -typedef VkFormatProperties3 VkFormatProperties3KHR; - - - -#define VK_KHR_ray_tracing_maintenance1 1 -#define VK_KHR_RAY_TRACING_MAINTENANCE_1_SPEC_VERSION 1 -#define VK_KHR_RAY_TRACING_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_ray_tracing_maintenance1" -typedef struct VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 rayTracingMaintenance1; - VkBool32 rayTracingPipelineTraceRaysIndirect2; -} VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR; - -typedef struct VkTraceRaysIndirectCommand2KHR { - VkDeviceAddress raygenShaderRecordAddress; - VkDeviceSize raygenShaderRecordSize; - VkDeviceAddress missShaderBindingTableAddress; - VkDeviceSize missShaderBindingTableSize; - VkDeviceSize missShaderBindingTableStride; - VkDeviceAddress hitShaderBindingTableAddress; - VkDeviceSize hitShaderBindingTableSize; - VkDeviceSize hitShaderBindingTableStride; - VkDeviceAddress callableShaderBindingTableAddress; - VkDeviceSize callableShaderBindingTableSize; - VkDeviceSize callableShaderBindingTableStride; - uint32_t width; - uint32_t height; - uint32_t depth; -} VkTraceRaysIndirectCommand2KHR; - -typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysIndirect2KHR)(VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirect2KHR( - VkCommandBuffer commandBuffer, - VkDeviceAddress indirectDeviceAddress); -#endif - - -#define VK_KHR_portability_enumeration 1 -#define VK_KHR_PORTABILITY_ENUMERATION_SPEC_VERSION 1 -#define VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME "VK_KHR_portability_enumeration" - - -#define VK_KHR_maintenance4 1 -#define VK_KHR_MAINTENANCE_4_SPEC_VERSION 2 -#define VK_KHR_MAINTENANCE_4_EXTENSION_NAME "VK_KHR_maintenance4" -typedef VkPhysicalDeviceMaintenance4Features VkPhysicalDeviceMaintenance4FeaturesKHR; - -typedef VkPhysicalDeviceMaintenance4Properties VkPhysicalDeviceMaintenance4PropertiesKHR; - -typedef VkDeviceBufferMemoryRequirements VkDeviceBufferMemoryRequirementsKHR; - -typedef VkDeviceImageMemoryRequirements VkDeviceImageMemoryRequirementsKHR; - -typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirementsKHR)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirementsKHR( - VkDevice device, - const VkDeviceBufferMemoryRequirements* pInfo, - VkMemoryRequirements2* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirementsKHR( - VkDevice device, - const VkDeviceImageMemoryRequirements* pInfo, - VkMemoryRequirements2* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirementsKHR( - VkDevice device, - const VkDeviceImageMemoryRequirements* pInfo, - uint32_t* pSparseMemoryRequirementCount, - VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); -#endif - - -#define VK_EXT_debug_report 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) -#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 10 -#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report" - -typedef enum VkDebugReportObjectTypeEXT { - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0, - VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1, - VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2, - VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3, - VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4, - VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5, - VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6, - VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7, - VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8, - VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9, - VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10, - VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11, - VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12, - VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13, - VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14, - VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15, - VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16, - VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17, - VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18, - VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20, - VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23, - VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24, - VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25, - VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26, - VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27, - VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT = 28, - VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29, - VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30, - VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33, - VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000, - VK_DEBUG_REPORT_OBJECT_TYPE_CU_MODULE_NVX_EXT = 1000029000, - VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT = 1000029001, - VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT = 1000150000, - VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT = 1000165000, - VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT = 1000366000, - VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT, - VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDebugReportObjectTypeEXT; - -typedef enum VkDebugReportFlagBitsEXT { - VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 0x00000001, - VK_DEBUG_REPORT_WARNING_BIT_EXT = 0x00000002, - VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 0x00000004, - VK_DEBUG_REPORT_ERROR_BIT_EXT = 0x00000008, - VK_DEBUG_REPORT_DEBUG_BIT_EXT = 0x00000010, - VK_DEBUG_REPORT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDebugReportFlagBitsEXT; -typedef VkFlags VkDebugReportFlagsEXT; -typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)( - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage, - void* pUserData); - -typedef struct VkDebugReportCallbackCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkDebugReportFlagsEXT flags; - PFN_vkDebugReportCallbackEXT pfnCallback; - void* pUserData; -} VkDebugReportCallbackCreateInfoEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); -typedef void (VKAPI_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkDebugReportMessageEXT)(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT( - VkInstance instance, - const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDebugReportCallbackEXT* pCallback); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT( - VkInstance instance, - VkDebugReportCallbackEXT callback, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( - VkInstance instance, - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage); -#endif - - -#define VK_NV_glsl_shader 1 -#define VK_NV_GLSL_SHADER_SPEC_VERSION 1 -#define VK_NV_GLSL_SHADER_EXTENSION_NAME "VK_NV_glsl_shader" - - -#define VK_EXT_depth_range_unrestricted 1 -#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_SPEC_VERSION 1 -#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME "VK_EXT_depth_range_unrestricted" - - -#define VK_IMG_filter_cubic 1 -#define VK_IMG_FILTER_CUBIC_SPEC_VERSION 1 -#define VK_IMG_FILTER_CUBIC_EXTENSION_NAME "VK_IMG_filter_cubic" - - -#define VK_AMD_rasterization_order 1 -#define VK_AMD_RASTERIZATION_ORDER_SPEC_VERSION 1 -#define VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME "VK_AMD_rasterization_order" - -typedef enum VkRasterizationOrderAMD { - VK_RASTERIZATION_ORDER_STRICT_AMD = 0, - VK_RASTERIZATION_ORDER_RELAXED_AMD = 1, - VK_RASTERIZATION_ORDER_MAX_ENUM_AMD = 0x7FFFFFFF -} VkRasterizationOrderAMD; -typedef struct VkPipelineRasterizationStateRasterizationOrderAMD { - VkStructureType sType; - const void* pNext; - VkRasterizationOrderAMD rasterizationOrder; -} VkPipelineRasterizationStateRasterizationOrderAMD; - - - -#define VK_AMD_shader_trinary_minmax 1 -#define VK_AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION 1 -#define VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME "VK_AMD_shader_trinary_minmax" - - -#define VK_AMD_shader_explicit_vertex_parameter 1 -#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION 1 -#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME "VK_AMD_shader_explicit_vertex_parameter" - - -#define VK_EXT_debug_marker 1 -#define VK_EXT_DEBUG_MARKER_SPEC_VERSION 4 -#define VK_EXT_DEBUG_MARKER_EXTENSION_NAME "VK_EXT_debug_marker" -typedef struct VkDebugMarkerObjectNameInfoEXT { - VkStructureType sType; - const void* pNext; - VkDebugReportObjectTypeEXT objectType; - uint64_t object; - const char* pObjectName; -} VkDebugMarkerObjectNameInfoEXT; - -typedef struct VkDebugMarkerObjectTagInfoEXT { - VkStructureType sType; - const void* pNext; - VkDebugReportObjectTypeEXT objectType; - uint64_t object; - uint64_t tagName; - size_t tagSize; - const void* pTag; -} VkDebugMarkerObjectTagInfoEXT; - -typedef struct VkDebugMarkerMarkerInfoEXT { - VkStructureType sType; - const void* pNext; - const char* pMarkerName; - float color[4]; -} VkDebugMarkerMarkerInfoEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectTagEXT)(VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo); -typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectNameEXT)(VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo); -typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerBeginEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); -typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerEndEXT)(VkCommandBuffer commandBuffer); -typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerInsertEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectTagEXT( - VkDevice device, - const VkDebugMarkerObjectTagInfoEXT* pTagInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectNameEXT( - VkDevice device, - const VkDebugMarkerObjectNameInfoEXT* pNameInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerBeginEXT( - VkCommandBuffer commandBuffer, - const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerEndEXT( - VkCommandBuffer commandBuffer); - -VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerInsertEXT( - VkCommandBuffer commandBuffer, - const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); -#endif - - -#define VK_AMD_gcn_shader 1 -#define VK_AMD_GCN_SHADER_SPEC_VERSION 1 -#define VK_AMD_GCN_SHADER_EXTENSION_NAME "VK_AMD_gcn_shader" - - -#define VK_NV_dedicated_allocation 1 -#define VK_NV_DEDICATED_ALLOCATION_SPEC_VERSION 1 -#define VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_NV_dedicated_allocation" -typedef struct VkDedicatedAllocationImageCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkBool32 dedicatedAllocation; -} VkDedicatedAllocationImageCreateInfoNV; - -typedef struct VkDedicatedAllocationBufferCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkBool32 dedicatedAllocation; -} VkDedicatedAllocationBufferCreateInfoNV; - -typedef struct VkDedicatedAllocationMemoryAllocateInfoNV { - VkStructureType sType; - const void* pNext; - VkImage image; - VkBuffer buffer; -} VkDedicatedAllocationMemoryAllocateInfoNV; - - - -#define VK_EXT_transform_feedback 1 -#define VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION 1 -#define VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME "VK_EXT_transform_feedback" -typedef VkFlags VkPipelineRasterizationStateStreamCreateFlagsEXT; -typedef struct VkPhysicalDeviceTransformFeedbackFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 transformFeedback; - VkBool32 geometryStreams; -} VkPhysicalDeviceTransformFeedbackFeaturesEXT; - -typedef struct VkPhysicalDeviceTransformFeedbackPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t maxTransformFeedbackStreams; - uint32_t maxTransformFeedbackBuffers; - VkDeviceSize maxTransformFeedbackBufferSize; - uint32_t maxTransformFeedbackStreamDataSize; - uint32_t maxTransformFeedbackBufferDataSize; - uint32_t maxTransformFeedbackBufferDataStride; - VkBool32 transformFeedbackQueries; - VkBool32 transformFeedbackStreamsLinesTriangles; - VkBool32 transformFeedbackRasterizationStreamSelect; - VkBool32 transformFeedbackDraw; -} VkPhysicalDeviceTransformFeedbackPropertiesEXT; - -typedef struct VkPipelineRasterizationStateStreamCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPipelineRasterizationStateStreamCreateFlagsEXT flags; - uint32_t rasterizationStream; -} VkPipelineRasterizationStateStreamCreateInfoEXT; - -typedef void (VKAPI_PTR *PFN_vkCmdBindTransformFeedbackBuffersEXT)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes); -typedef void (VKAPI_PTR *PFN_vkCmdBeginTransformFeedbackEXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets); -typedef void (VKAPI_PTR *PFN_vkCmdEndTransformFeedbackEXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets); -typedef void (VKAPI_PTR *PFN_vkCmdBeginQueryIndexedEXT)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags, uint32_t index); -typedef void (VKAPI_PTR *PFN_vkCmdEndQueryIndexedEXT)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, uint32_t index); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectByteCountEXT)(VkCommandBuffer commandBuffer, uint32_t instanceCount, uint32_t firstInstance, VkBuffer counterBuffer, VkDeviceSize counterBufferOffset, uint32_t counterOffset, uint32_t vertexStride); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdBindTransformFeedbackBuffersEXT( - VkCommandBuffer commandBuffer, - uint32_t firstBinding, - uint32_t bindingCount, - const VkBuffer* pBuffers, - const VkDeviceSize* pOffsets, - const VkDeviceSize* pSizes); - -VKAPI_ATTR void VKAPI_CALL vkCmdBeginTransformFeedbackEXT( - VkCommandBuffer commandBuffer, - uint32_t firstCounterBuffer, - uint32_t counterBufferCount, - const VkBuffer* pCounterBuffers, - const VkDeviceSize* pCounterBufferOffsets); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndTransformFeedbackEXT( - VkCommandBuffer commandBuffer, - uint32_t firstCounterBuffer, - uint32_t counterBufferCount, - const VkBuffer* pCounterBuffers, - const VkDeviceSize* pCounterBufferOffsets); - -VKAPI_ATTR void VKAPI_CALL vkCmdBeginQueryIndexedEXT( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query, - VkQueryControlFlags flags, - uint32_t index); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndQueryIndexedEXT( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query, - uint32_t index); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectByteCountEXT( - VkCommandBuffer commandBuffer, - uint32_t instanceCount, - uint32_t firstInstance, - VkBuffer counterBuffer, - VkDeviceSize counterBufferOffset, - uint32_t counterOffset, - uint32_t vertexStride); -#endif - - -#define VK_NVX_binary_import 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuModuleNVX) -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuFunctionNVX) -#define VK_NVX_BINARY_IMPORT_SPEC_VERSION 1 -#define VK_NVX_BINARY_IMPORT_EXTENSION_NAME "VK_NVX_binary_import" -typedef struct VkCuModuleCreateInfoNVX { - VkStructureType sType; - const void* pNext; - size_t dataSize; - const void* pData; -} VkCuModuleCreateInfoNVX; - -typedef struct VkCuFunctionCreateInfoNVX { - VkStructureType sType; - const void* pNext; - VkCuModuleNVX module; - const char* pName; -} VkCuFunctionCreateInfoNVX; - -typedef struct VkCuLaunchInfoNVX { - VkStructureType sType; - const void* pNext; - VkCuFunctionNVX function; - uint32_t gridDimX; - uint32_t gridDimY; - uint32_t gridDimZ; - uint32_t blockDimX; - uint32_t blockDimY; - uint32_t blockDimZ; - uint32_t sharedMemBytes; - size_t paramCount; - const void* const * pParams; - size_t extraCount; - const void* const * pExtras; -} VkCuLaunchInfoNVX; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateCuModuleNVX)(VkDevice device, const VkCuModuleCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCuModuleNVX* pModule); -typedef VkResult (VKAPI_PTR *PFN_vkCreateCuFunctionNVX)(VkDevice device, const VkCuFunctionCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCuFunctionNVX* pFunction); -typedef void (VKAPI_PTR *PFN_vkDestroyCuModuleNVX)(VkDevice device, VkCuModuleNVX module, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkDestroyCuFunctionNVX)(VkDevice device, VkCuFunctionNVX function, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkCmdCuLaunchKernelNVX)(VkCommandBuffer commandBuffer, const VkCuLaunchInfoNVX* pLaunchInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateCuModuleNVX( - VkDevice device, - const VkCuModuleCreateInfoNVX* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkCuModuleNVX* pModule); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateCuFunctionNVX( - VkDevice device, - const VkCuFunctionCreateInfoNVX* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkCuFunctionNVX* pFunction); - -VKAPI_ATTR void VKAPI_CALL vkDestroyCuModuleNVX( - VkDevice device, - VkCuModuleNVX module, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkDestroyCuFunctionNVX( - VkDevice device, - VkCuFunctionNVX function, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkCmdCuLaunchKernelNVX( - VkCommandBuffer commandBuffer, - const VkCuLaunchInfoNVX* pLaunchInfo); -#endif - - -#define VK_NVX_image_view_handle 1 -#define VK_NVX_IMAGE_VIEW_HANDLE_SPEC_VERSION 2 -#define VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME "VK_NVX_image_view_handle" -typedef struct VkImageViewHandleInfoNVX { - VkStructureType sType; - const void* pNext; - VkImageView imageView; - VkDescriptorType descriptorType; - VkSampler sampler; -} VkImageViewHandleInfoNVX; - -typedef struct VkImageViewAddressPropertiesNVX { - VkStructureType sType; - void* pNext; - VkDeviceAddress deviceAddress; - VkDeviceSize size; -} VkImageViewAddressPropertiesNVX; - -typedef uint32_t (VKAPI_PTR *PFN_vkGetImageViewHandleNVX)(VkDevice device, const VkImageViewHandleInfoNVX* pInfo); -typedef VkResult (VKAPI_PTR *PFN_vkGetImageViewAddressNVX)(VkDevice device, VkImageView imageView, VkImageViewAddressPropertiesNVX* pProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR uint32_t VKAPI_CALL vkGetImageViewHandleNVX( - VkDevice device, - const VkImageViewHandleInfoNVX* pInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetImageViewAddressNVX( - VkDevice device, - VkImageView imageView, - VkImageViewAddressPropertiesNVX* pProperties); -#endif - - -#define VK_AMD_draw_indirect_count 1 -#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 2 -#define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count" -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountAMD( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkBuffer countBuffer, - VkDeviceSize countBufferOffset, - uint32_t maxDrawCount, - uint32_t stride); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkBuffer countBuffer, - VkDeviceSize countBufferOffset, - uint32_t maxDrawCount, - uint32_t stride); -#endif - - -#define VK_AMD_negative_viewport_height 1 -#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION 1 -#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME "VK_AMD_negative_viewport_height" - - -#define VK_AMD_gpu_shader_half_float 1 -#define VK_AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION 2 -#define VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME "VK_AMD_gpu_shader_half_float" - - -#define VK_AMD_shader_ballot 1 -#define VK_AMD_SHADER_BALLOT_SPEC_VERSION 1 -#define VK_AMD_SHADER_BALLOT_EXTENSION_NAME "VK_AMD_shader_ballot" - - -#define VK_AMD_texture_gather_bias_lod 1 -#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_SPEC_VERSION 1 -#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_EXTENSION_NAME "VK_AMD_texture_gather_bias_lod" -typedef struct VkTextureLODGatherFormatPropertiesAMD { - VkStructureType sType; - void* pNext; - VkBool32 supportsTextureGatherLODBiasAMD; -} VkTextureLODGatherFormatPropertiesAMD; - - - -#define VK_AMD_shader_info 1 -#define VK_AMD_SHADER_INFO_SPEC_VERSION 1 -#define VK_AMD_SHADER_INFO_EXTENSION_NAME "VK_AMD_shader_info" - -typedef enum VkShaderInfoTypeAMD { - VK_SHADER_INFO_TYPE_STATISTICS_AMD = 0, - VK_SHADER_INFO_TYPE_BINARY_AMD = 1, - VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD = 2, - VK_SHADER_INFO_TYPE_MAX_ENUM_AMD = 0x7FFFFFFF -} VkShaderInfoTypeAMD; -typedef struct VkShaderResourceUsageAMD { - uint32_t numUsedVgprs; - uint32_t numUsedSgprs; - uint32_t ldsSizePerLocalWorkGroup; - size_t ldsUsageSizeInBytes; - size_t scratchMemUsageInBytes; -} VkShaderResourceUsageAMD; - -typedef struct VkShaderStatisticsInfoAMD { - VkShaderStageFlags shaderStageMask; - VkShaderResourceUsageAMD resourceUsage; - uint32_t numPhysicalVgprs; - uint32_t numPhysicalSgprs; - uint32_t numAvailableVgprs; - uint32_t numAvailableSgprs; - uint32_t computeWorkGroupSize[3]; -} VkShaderStatisticsInfoAMD; - -typedef VkResult (VKAPI_PTR *PFN_vkGetShaderInfoAMD)(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits shaderStage, VkShaderInfoTypeAMD infoType, size_t* pInfoSize, void* pInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderInfoAMD( - VkDevice device, - VkPipeline pipeline, - VkShaderStageFlagBits shaderStage, - VkShaderInfoTypeAMD infoType, - size_t* pInfoSize, - void* pInfo); -#endif - - -#define VK_AMD_shader_image_load_store_lod 1 -#define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_SPEC_VERSION 1 -#define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME "VK_AMD_shader_image_load_store_lod" - - -#define VK_NV_corner_sampled_image 1 -#define VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION 2 -#define VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME "VK_NV_corner_sampled_image" -typedef struct VkPhysicalDeviceCornerSampledImageFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 cornerSampledImage; -} VkPhysicalDeviceCornerSampledImageFeaturesNV; - - - -#define VK_IMG_format_pvrtc 1 -#define VK_IMG_FORMAT_PVRTC_SPEC_VERSION 1 -#define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc" - - -#define VK_NV_external_memory_capabilities 1 -#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1 -#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_NV_external_memory_capabilities" - -typedef enum VkExternalMemoryHandleTypeFlagBitsNV { - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV = 0x00000001, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV = 0x00000002, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV = 0x00000004, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV = 0x00000008, - VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkExternalMemoryHandleTypeFlagBitsNV; -typedef VkFlags VkExternalMemoryHandleTypeFlagsNV; - -typedef enum VkExternalMemoryFeatureFlagBitsNV { - VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV = 0x00000001, - VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV = 0x00000002, - VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV = 0x00000004, - VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkExternalMemoryFeatureFlagBitsNV; -typedef VkFlags VkExternalMemoryFeatureFlagsNV; -typedef struct VkExternalImageFormatPropertiesNV { - VkImageFormatProperties imageFormatProperties; - VkExternalMemoryFeatureFlagsNV externalMemoryFeatures; - VkExternalMemoryHandleTypeFlagsNV exportFromImportedHandleTypes; - VkExternalMemoryHandleTypeFlagsNV compatibleHandleTypes; -} VkExternalImageFormatPropertiesNV; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType, VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceExternalImageFormatPropertiesNV( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkImageType type, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkImageCreateFlags flags, - VkExternalMemoryHandleTypeFlagsNV externalHandleType, - VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties); -#endif - - -#define VK_NV_external_memory 1 -#define VK_NV_EXTERNAL_MEMORY_SPEC_VERSION 1 -#define VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME "VK_NV_external_memory" -typedef struct VkExternalMemoryImageCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagsNV handleTypes; -} VkExternalMemoryImageCreateInfoNV; - -typedef struct VkExportMemoryAllocateInfoNV { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagsNV handleTypes; -} VkExportMemoryAllocateInfoNV; - - - -#define VK_EXT_validation_flags 1 -#define VK_EXT_VALIDATION_FLAGS_SPEC_VERSION 2 -#define VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME "VK_EXT_validation_flags" - -typedef enum VkValidationCheckEXT { - VK_VALIDATION_CHECK_ALL_EXT = 0, - VK_VALIDATION_CHECK_SHADERS_EXT = 1, - VK_VALIDATION_CHECK_MAX_ENUM_EXT = 0x7FFFFFFF -} VkValidationCheckEXT; -typedef struct VkValidationFlagsEXT { - VkStructureType sType; - const void* pNext; - uint32_t disabledValidationCheckCount; - const VkValidationCheckEXT* pDisabledValidationChecks; -} VkValidationFlagsEXT; - - - -#define VK_EXT_shader_subgroup_ballot 1 -#define VK_EXT_SHADER_SUBGROUP_BALLOT_SPEC_VERSION 1 -#define VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME "VK_EXT_shader_subgroup_ballot" - - -#define VK_EXT_shader_subgroup_vote 1 -#define VK_EXT_SHADER_SUBGROUP_VOTE_SPEC_VERSION 1 -#define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote" - - -#define VK_EXT_texture_compression_astc_hdr 1 -#define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_SPEC_VERSION 1 -#define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME "VK_EXT_texture_compression_astc_hdr" -typedef VkPhysicalDeviceTextureCompressionASTCHDRFeatures VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT; - - - -#define VK_EXT_astc_decode_mode 1 -#define VK_EXT_ASTC_DECODE_MODE_SPEC_VERSION 1 -#define VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME "VK_EXT_astc_decode_mode" -typedef struct VkImageViewASTCDecodeModeEXT { - VkStructureType sType; - const void* pNext; - VkFormat decodeMode; -} VkImageViewASTCDecodeModeEXT; - -typedef struct VkPhysicalDeviceASTCDecodeFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 decodeModeSharedExponent; -} VkPhysicalDeviceASTCDecodeFeaturesEXT; - - - -#define VK_EXT_pipeline_robustness 1 -#define VK_EXT_PIPELINE_ROBUSTNESS_SPEC_VERSION 1 -#define VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_pipeline_robustness" - -typedef enum VkPipelineRobustnessBufferBehaviorEXT { - VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT = 0, - VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT = 1, - VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT = 2, - VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT = 3, - VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPipelineRobustnessBufferBehaviorEXT; - -typedef enum VkPipelineRobustnessImageBehaviorEXT { - VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT_EXT = 0, - VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT = 1, - VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_EXT = 2, - VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2_EXT = 3, - VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_MAX_ENUM_EXT = 0x7FFFFFFF -} VkPipelineRobustnessImageBehaviorEXT; -typedef struct VkPhysicalDevicePipelineRobustnessFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 pipelineRobustness; -} VkPhysicalDevicePipelineRobustnessFeaturesEXT; - -typedef struct VkPhysicalDevicePipelineRobustnessPropertiesEXT { - VkStructureType sType; - void* pNext; - VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessStorageBuffers; - VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessUniformBuffers; - VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessVertexInputs; - VkPipelineRobustnessImageBehaviorEXT defaultRobustnessImages; -} VkPhysicalDevicePipelineRobustnessPropertiesEXT; - -typedef struct VkPipelineRobustnessCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPipelineRobustnessBufferBehaviorEXT storageBuffers; - VkPipelineRobustnessBufferBehaviorEXT uniformBuffers; - VkPipelineRobustnessBufferBehaviorEXT vertexInputs; - VkPipelineRobustnessImageBehaviorEXT images; -} VkPipelineRobustnessCreateInfoEXT; - - - -#define VK_EXT_conditional_rendering 1 -#define VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION 2 -#define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering" - -typedef enum VkConditionalRenderingFlagBitsEXT { - VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT = 0x00000001, - VK_CONDITIONAL_RENDERING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkConditionalRenderingFlagBitsEXT; -typedef VkFlags VkConditionalRenderingFlagsEXT; -typedef struct VkConditionalRenderingBeginInfoEXT { - VkStructureType sType; - const void* pNext; - VkBuffer buffer; - VkDeviceSize offset; - VkConditionalRenderingFlagsEXT flags; -} VkConditionalRenderingBeginInfoEXT; - -typedef struct VkPhysicalDeviceConditionalRenderingFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 conditionalRendering; - VkBool32 inheritedConditionalRendering; -} VkPhysicalDeviceConditionalRenderingFeaturesEXT; - -typedef struct VkCommandBufferInheritanceConditionalRenderingInfoEXT { - VkStructureType sType; - const void* pNext; - VkBool32 conditionalRenderingEnable; -} VkCommandBufferInheritanceConditionalRenderingInfoEXT; - -typedef void (VKAPI_PTR *PFN_vkCmdBeginConditionalRenderingEXT)(VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin); -typedef void (VKAPI_PTR *PFN_vkCmdEndConditionalRenderingEXT)(VkCommandBuffer commandBuffer); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdBeginConditionalRenderingEXT( - VkCommandBuffer commandBuffer, - const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndConditionalRenderingEXT( - VkCommandBuffer commandBuffer); -#endif - - -#define VK_NV_clip_space_w_scaling 1 -#define VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION 1 -#define VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME "VK_NV_clip_space_w_scaling" -typedef struct VkViewportWScalingNV { - float xcoeff; - float ycoeff; -} VkViewportWScalingNV; - -typedef struct VkPipelineViewportWScalingStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkBool32 viewportWScalingEnable; - uint32_t viewportCount; - const VkViewportWScalingNV* pViewportWScalings; -} VkPipelineViewportWScalingStateCreateInfoNV; - -typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWScalingNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportWScalingNV* pViewportWScalings); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWScalingNV( - VkCommandBuffer commandBuffer, - uint32_t firstViewport, - uint32_t viewportCount, - const VkViewportWScalingNV* pViewportWScalings); -#endif - - -#define VK_EXT_direct_mode_display 1 -#define VK_EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION 1 -#define VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME "VK_EXT_direct_mode_display" -typedef VkResult (VKAPI_PTR *PFN_vkReleaseDisplayEXT)(VkPhysicalDevice physicalDevice, VkDisplayKHR display); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkReleaseDisplayEXT( - VkPhysicalDevice physicalDevice, - VkDisplayKHR display); -#endif - - -#define VK_EXT_display_surface_counter 1 -#define VK_EXT_DISPLAY_SURFACE_COUNTER_SPEC_VERSION 1 -#define VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME "VK_EXT_display_surface_counter" - -typedef enum VkSurfaceCounterFlagBitsEXT { - VK_SURFACE_COUNTER_VBLANK_BIT_EXT = 0x00000001, - VK_SURFACE_COUNTER_VBLANK_EXT = VK_SURFACE_COUNTER_VBLANK_BIT_EXT, - VK_SURFACE_COUNTER_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkSurfaceCounterFlagBitsEXT; -typedef VkFlags VkSurfaceCounterFlagsEXT; -typedef struct VkSurfaceCapabilities2EXT { - VkStructureType sType; - void* pNext; - uint32_t minImageCount; - uint32_t maxImageCount; - VkExtent2D currentExtent; - VkExtent2D minImageExtent; - VkExtent2D maxImageExtent; - uint32_t maxImageArrayLayers; - VkSurfaceTransformFlagsKHR supportedTransforms; - VkSurfaceTransformFlagBitsKHR currentTransform; - VkCompositeAlphaFlagsKHR supportedCompositeAlpha; - VkImageUsageFlags supportedUsageFlags; - VkSurfaceCounterFlagsEXT supportedSurfaceCounters; -} VkSurfaceCapabilities2EXT; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT* pSurfaceCapabilities); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2EXT( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - VkSurfaceCapabilities2EXT* pSurfaceCapabilities); -#endif - - -#define VK_EXT_display_control 1 -#define VK_EXT_DISPLAY_CONTROL_SPEC_VERSION 1 -#define VK_EXT_DISPLAY_CONTROL_EXTENSION_NAME "VK_EXT_display_control" - -typedef enum VkDisplayPowerStateEXT { - VK_DISPLAY_POWER_STATE_OFF_EXT = 0, - VK_DISPLAY_POWER_STATE_SUSPEND_EXT = 1, - VK_DISPLAY_POWER_STATE_ON_EXT = 2, - VK_DISPLAY_POWER_STATE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDisplayPowerStateEXT; - -typedef enum VkDeviceEventTypeEXT { - VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT = 0, - VK_DEVICE_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDeviceEventTypeEXT; - -typedef enum VkDisplayEventTypeEXT { - VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT = 0, - VK_DISPLAY_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDisplayEventTypeEXT; -typedef struct VkDisplayPowerInfoEXT { - VkStructureType sType; - const void* pNext; - VkDisplayPowerStateEXT powerState; -} VkDisplayPowerInfoEXT; - -typedef struct VkDeviceEventInfoEXT { - VkStructureType sType; - const void* pNext; - VkDeviceEventTypeEXT deviceEvent; -} VkDeviceEventInfoEXT; - -typedef struct VkDisplayEventInfoEXT { - VkStructureType sType; - const void* pNext; - VkDisplayEventTypeEXT displayEvent; -} VkDisplayEventInfoEXT; - -typedef struct VkSwapchainCounterCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkSurfaceCounterFlagsEXT surfaceCounters; -} VkSwapchainCounterCreateInfoEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkDisplayPowerControlEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayPowerInfoEXT* pDisplayPowerInfo); -typedef VkResult (VKAPI_PTR *PFN_vkRegisterDeviceEventEXT)(VkDevice device, const VkDeviceEventInfoEXT* pDeviceEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); -typedef VkResult (VKAPI_PTR *PFN_vkRegisterDisplayEventEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayEventInfoEXT* pDisplayEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); -typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainCounterEXT)(VkDevice device, VkSwapchainKHR swapchain, VkSurfaceCounterFlagBitsEXT counter, uint64_t* pCounterValue); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkDisplayPowerControlEXT( - VkDevice device, - VkDisplayKHR display, - const VkDisplayPowerInfoEXT* pDisplayPowerInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDeviceEventEXT( - VkDevice device, - const VkDeviceEventInfoEXT* pDeviceEventInfo, - const VkAllocationCallbacks* pAllocator, - VkFence* pFence); - -VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDisplayEventEXT( - VkDevice device, - VkDisplayKHR display, - const VkDisplayEventInfoEXT* pDisplayEventInfo, - const VkAllocationCallbacks* pAllocator, - VkFence* pFence); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainCounterEXT( - VkDevice device, - VkSwapchainKHR swapchain, - VkSurfaceCounterFlagBitsEXT counter, - uint64_t* pCounterValue); -#endif - - -#define VK_GOOGLE_display_timing 1 -#define VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION 1 -#define VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME "VK_GOOGLE_display_timing" -typedef struct VkRefreshCycleDurationGOOGLE { - uint64_t refreshDuration; -} VkRefreshCycleDurationGOOGLE; - -typedef struct VkPastPresentationTimingGOOGLE { - uint32_t presentID; - uint64_t desiredPresentTime; - uint64_t actualPresentTime; - uint64_t earliestPresentTime; - uint64_t presentMargin; -} VkPastPresentationTimingGOOGLE; - -typedef struct VkPresentTimeGOOGLE { - uint32_t presentID; - uint64_t desiredPresentTime; -} VkPresentTimeGOOGLE; - -typedef struct VkPresentTimesInfoGOOGLE { - VkStructureType sType; - const void* pNext; - uint32_t swapchainCount; - const VkPresentTimeGOOGLE* pTimes; -} VkPresentTimesInfoGOOGLE; - -typedef VkResult (VKAPI_PTR *PFN_vkGetRefreshCycleDurationGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetPastPresentationTimingGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetRefreshCycleDurationGOOGLE( - VkDevice device, - VkSwapchainKHR swapchain, - VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE( - VkDevice device, - VkSwapchainKHR swapchain, - uint32_t* pPresentationTimingCount, - VkPastPresentationTimingGOOGLE* pPresentationTimings); -#endif - - -#define VK_NV_sample_mask_override_coverage 1 -#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_SPEC_VERSION 1 -#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME "VK_NV_sample_mask_override_coverage" - - -#define VK_NV_geometry_shader_passthrough 1 -#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_SPEC_VERSION 1 -#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME "VK_NV_geometry_shader_passthrough" - - -#define VK_NV_viewport_array2 1 -#define VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION 1 -#define VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME "VK_NV_viewport_array2" -#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION -#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME - - -#define VK_NVX_multiview_per_view_attributes 1 -#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION 1 -#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME "VK_NVX_multiview_per_view_attributes" -typedef struct VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX { - VkStructureType sType; - void* pNext; - VkBool32 perViewPositionAllComponents; -} VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX; - - - -#define VK_NV_viewport_swizzle 1 -#define VK_NV_VIEWPORT_SWIZZLE_SPEC_VERSION 1 -#define VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME "VK_NV_viewport_swizzle" - -typedef enum VkViewportCoordinateSwizzleNV { - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV = 0, - VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV = 1, - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV = 2, - VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV = 3, - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV = 4, - VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV = 5, - VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV = 6, - VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV = 7, - VK_VIEWPORT_COORDINATE_SWIZZLE_MAX_ENUM_NV = 0x7FFFFFFF -} VkViewportCoordinateSwizzleNV; -typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV; -typedef struct VkViewportSwizzleNV { - VkViewportCoordinateSwizzleNV x; - VkViewportCoordinateSwizzleNV y; - VkViewportCoordinateSwizzleNV z; - VkViewportCoordinateSwizzleNV w; -} VkViewportSwizzleNV; - -typedef struct VkPipelineViewportSwizzleStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkPipelineViewportSwizzleStateCreateFlagsNV flags; - uint32_t viewportCount; - const VkViewportSwizzleNV* pViewportSwizzles; -} VkPipelineViewportSwizzleStateCreateInfoNV; - - - -#define VK_EXT_discard_rectangles 1 -#define VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION 1 -#define VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME "VK_EXT_discard_rectangles" - -typedef enum VkDiscardRectangleModeEXT { - VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT = 0, - VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT = 1, - VK_DISCARD_RECTANGLE_MODE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDiscardRectangleModeEXT; -typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT; -typedef struct VkPhysicalDeviceDiscardRectanglePropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t maxDiscardRectangles; -} VkPhysicalDeviceDiscardRectanglePropertiesEXT; - -typedef struct VkPipelineDiscardRectangleStateCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPipelineDiscardRectangleStateCreateFlagsEXT flags; - VkDiscardRectangleModeEXT discardRectangleMode; - uint32_t discardRectangleCount; - const VkRect2D* pDiscardRectangles; -} VkPipelineDiscardRectangleStateCreateInfoEXT; - -typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleEXT)(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle, uint32_t discardRectangleCount, const VkRect2D* pDiscardRectangles); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEXT( - VkCommandBuffer commandBuffer, - uint32_t firstDiscardRectangle, - uint32_t discardRectangleCount, - const VkRect2D* pDiscardRectangles); -#endif - - -#define VK_EXT_conservative_rasterization 1 -#define VK_EXT_CONSERVATIVE_RASTERIZATION_SPEC_VERSION 1 -#define VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME "VK_EXT_conservative_rasterization" - -typedef enum VkConservativeRasterizationModeEXT { - VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT = 0, - VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT = 1, - VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT = 2, - VK_CONSERVATIVE_RASTERIZATION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkConservativeRasterizationModeEXT; -typedef VkFlags VkPipelineRasterizationConservativeStateCreateFlagsEXT; -typedef struct VkPhysicalDeviceConservativeRasterizationPropertiesEXT { - VkStructureType sType; - void* pNext; - float primitiveOverestimationSize; - float maxExtraPrimitiveOverestimationSize; - float extraPrimitiveOverestimationSizeGranularity; - VkBool32 primitiveUnderestimation; - VkBool32 conservativePointAndLineRasterization; - VkBool32 degenerateTrianglesRasterized; - VkBool32 degenerateLinesRasterized; - VkBool32 fullyCoveredFragmentShaderInputVariable; - VkBool32 conservativeRasterizationPostDepthCoverage; -} VkPhysicalDeviceConservativeRasterizationPropertiesEXT; - -typedef struct VkPipelineRasterizationConservativeStateCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPipelineRasterizationConservativeStateCreateFlagsEXT flags; - VkConservativeRasterizationModeEXT conservativeRasterizationMode; - float extraPrimitiveOverestimationSize; -} VkPipelineRasterizationConservativeStateCreateInfoEXT; - - - -#define VK_EXT_depth_clip_enable 1 -#define VK_EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION 1 -#define VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME "VK_EXT_depth_clip_enable" -typedef VkFlags VkPipelineRasterizationDepthClipStateCreateFlagsEXT; -typedef struct VkPhysicalDeviceDepthClipEnableFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 depthClipEnable; -} VkPhysicalDeviceDepthClipEnableFeaturesEXT; - -typedef struct VkPipelineRasterizationDepthClipStateCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkPipelineRasterizationDepthClipStateCreateFlagsEXT flags; - VkBool32 depthClipEnable; -} VkPipelineRasterizationDepthClipStateCreateInfoEXT; - - - -#define VK_EXT_swapchain_colorspace 1 -#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 4 -#define VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace" - - -#define VK_EXT_hdr_metadata 1 -#define VK_EXT_HDR_METADATA_SPEC_VERSION 2 -#define VK_EXT_HDR_METADATA_EXTENSION_NAME "VK_EXT_hdr_metadata" -typedef struct VkXYColorEXT { - float x; - float y; -} VkXYColorEXT; - -typedef struct VkHdrMetadataEXT { - VkStructureType sType; - const void* pNext; - VkXYColorEXT displayPrimaryRed; - VkXYColorEXT displayPrimaryGreen; - VkXYColorEXT displayPrimaryBlue; - VkXYColorEXT whitePoint; - float maxLuminance; - float minLuminance; - float maxContentLightLevel; - float maxFrameAverageLightLevel; -} VkHdrMetadataEXT; - -typedef void (VKAPI_PTR *PFN_vkSetHdrMetadataEXT)(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkSetHdrMetadataEXT( - VkDevice device, - uint32_t swapchainCount, - const VkSwapchainKHR* pSwapchains, - const VkHdrMetadataEXT* pMetadata); -#endif - - -#define VK_EXT_external_memory_dma_buf 1 -#define VK_EXT_EXTERNAL_MEMORY_DMA_BUF_SPEC_VERSION 1 -#define VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME "VK_EXT_external_memory_dma_buf" - - -#define VK_EXT_queue_family_foreign 1 -#define VK_EXT_QUEUE_FAMILY_FOREIGN_SPEC_VERSION 1 -#define VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME "VK_EXT_queue_family_foreign" -#define VK_QUEUE_FAMILY_FOREIGN_EXT (~2U) - - -#define VK_EXT_debug_utils 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugUtilsMessengerEXT) -#define VK_EXT_DEBUG_UTILS_SPEC_VERSION 2 -#define VK_EXT_DEBUG_UTILS_EXTENSION_NAME "VK_EXT_debug_utils" -typedef VkFlags VkDebugUtilsMessengerCallbackDataFlagsEXT; - -typedef enum VkDebugUtilsMessageSeverityFlagBitsEXT { - VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT = 0x00000001, - VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT = 0x00000010, - VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT = 0x00000100, - VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT = 0x00001000, - VK_DEBUG_UTILS_MESSAGE_SEVERITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDebugUtilsMessageSeverityFlagBitsEXT; - -typedef enum VkDebugUtilsMessageTypeFlagBitsEXT { - VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT = 0x00000001, - VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT = 0x00000002, - VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT = 0x00000004, - VK_DEBUG_UTILS_MESSAGE_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDebugUtilsMessageTypeFlagBitsEXT; -typedef VkFlags VkDebugUtilsMessageTypeFlagsEXT; -typedef VkFlags VkDebugUtilsMessageSeverityFlagsEXT; -typedef VkFlags VkDebugUtilsMessengerCreateFlagsEXT; -typedef struct VkDebugUtilsLabelEXT { - VkStructureType sType; - const void* pNext; - const char* pLabelName; - float color[4]; -} VkDebugUtilsLabelEXT; - -typedef struct VkDebugUtilsObjectNameInfoEXT { - VkStructureType sType; - const void* pNext; - VkObjectType objectType; - uint64_t objectHandle; - const char* pObjectName; -} VkDebugUtilsObjectNameInfoEXT; - -typedef struct VkDebugUtilsMessengerCallbackDataEXT { - VkStructureType sType; - const void* pNext; - VkDebugUtilsMessengerCallbackDataFlagsEXT flags; - const char* pMessageIdName; - int32_t messageIdNumber; - const char* pMessage; - uint32_t queueLabelCount; - const VkDebugUtilsLabelEXT* pQueueLabels; - uint32_t cmdBufLabelCount; - const VkDebugUtilsLabelEXT* pCmdBufLabels; - uint32_t objectCount; - const VkDebugUtilsObjectNameInfoEXT* pObjects; -} VkDebugUtilsMessengerCallbackDataEXT; - -typedef VkBool32 (VKAPI_PTR *PFN_vkDebugUtilsMessengerCallbackEXT)( - VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - VkDebugUtilsMessageTypeFlagsEXT messageTypes, - const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, - void* pUserData); - -typedef struct VkDebugUtilsMessengerCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkDebugUtilsMessengerCreateFlagsEXT flags; - VkDebugUtilsMessageSeverityFlagsEXT messageSeverity; - VkDebugUtilsMessageTypeFlagsEXT messageType; - PFN_vkDebugUtilsMessengerCallbackEXT pfnUserCallback; - void* pUserData; -} VkDebugUtilsMessengerCreateInfoEXT; - -typedef struct VkDebugUtilsObjectTagInfoEXT { - VkStructureType sType; - const void* pNext; - VkObjectType objectType; - uint64_t objectHandle; - uint64_t tagName; - size_t tagSize; - const void* pTag; -} VkDebugUtilsObjectTagInfoEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkSetDebugUtilsObjectNameEXT)(VkDevice device, const VkDebugUtilsObjectNameInfoEXT* pNameInfo); -typedef VkResult (VKAPI_PTR *PFN_vkSetDebugUtilsObjectTagEXT)(VkDevice device, const VkDebugUtilsObjectTagInfoEXT* pTagInfo); -typedef void (VKAPI_PTR *PFN_vkQueueBeginDebugUtilsLabelEXT)(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo); -typedef void (VKAPI_PTR *PFN_vkQueueEndDebugUtilsLabelEXT)(VkQueue queue); -typedef void (VKAPI_PTR *PFN_vkQueueInsertDebugUtilsLabelEXT)(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo); -typedef void (VKAPI_PTR *PFN_vkCmdBeginDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo); -typedef void (VKAPI_PTR *PFN_vkCmdEndDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer); -typedef void (VKAPI_PTR *PFN_vkCmdInsertDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugUtilsMessengerEXT)(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger); -typedef void (VKAPI_PTR *PFN_vkDestroyDebugUtilsMessengerEXT)(VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkSubmitDebugUtilsMessageEXT)(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkSetDebugUtilsObjectNameEXT( - VkDevice device, - const VkDebugUtilsObjectNameInfoEXT* pNameInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkSetDebugUtilsObjectTagEXT( - VkDevice device, - const VkDebugUtilsObjectTagInfoEXT* pTagInfo); - -VKAPI_ATTR void VKAPI_CALL vkQueueBeginDebugUtilsLabelEXT( - VkQueue queue, - const VkDebugUtilsLabelEXT* pLabelInfo); - -VKAPI_ATTR void VKAPI_CALL vkQueueEndDebugUtilsLabelEXT( - VkQueue queue); - -VKAPI_ATTR void VKAPI_CALL vkQueueInsertDebugUtilsLabelEXT( - VkQueue queue, - const VkDebugUtilsLabelEXT* pLabelInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdBeginDebugUtilsLabelEXT( - VkCommandBuffer commandBuffer, - const VkDebugUtilsLabelEXT* pLabelInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdEndDebugUtilsLabelEXT( - VkCommandBuffer commandBuffer); - -VKAPI_ATTR void VKAPI_CALL vkCmdInsertDebugUtilsLabelEXT( - VkCommandBuffer commandBuffer, - const VkDebugUtilsLabelEXT* pLabelInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT( - VkInstance instance, - const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDebugUtilsMessengerEXT* pMessenger); - -VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT( - VkInstance instance, - VkDebugUtilsMessengerEXT messenger, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkSubmitDebugUtilsMessageEXT( - VkInstance instance, - VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, - VkDebugUtilsMessageTypeFlagsEXT messageTypes, - const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData); -#endif - - -#define VK_EXT_sampler_filter_minmax 1 -#define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 2 -#define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax" -typedef VkSamplerReductionMode VkSamplerReductionModeEXT; - -typedef VkSamplerReductionModeCreateInfo VkSamplerReductionModeCreateInfoEXT; - -typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT; - - - -#define VK_AMD_gpu_shader_int16 1 -#define VK_AMD_GPU_SHADER_INT16_SPEC_VERSION 2 -#define VK_AMD_GPU_SHADER_INT16_EXTENSION_NAME "VK_AMD_gpu_shader_int16" - - -#define VK_AMD_mixed_attachment_samples 1 -#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_SPEC_VERSION 1 -#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME "VK_AMD_mixed_attachment_samples" - - -#define VK_AMD_shader_fragment_mask 1 -#define VK_AMD_SHADER_FRAGMENT_MASK_SPEC_VERSION 1 -#define VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME "VK_AMD_shader_fragment_mask" - - -#define VK_EXT_inline_uniform_block 1 -#define VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION 1 -#define VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME "VK_EXT_inline_uniform_block" -typedef VkPhysicalDeviceInlineUniformBlockFeatures VkPhysicalDeviceInlineUniformBlockFeaturesEXT; - -typedef VkPhysicalDeviceInlineUniformBlockProperties VkPhysicalDeviceInlineUniformBlockPropertiesEXT; - -typedef VkWriteDescriptorSetInlineUniformBlock VkWriteDescriptorSetInlineUniformBlockEXT; - -typedef VkDescriptorPoolInlineUniformBlockCreateInfo VkDescriptorPoolInlineUniformBlockCreateInfoEXT; - - - -#define VK_EXT_shader_stencil_export 1 -#define VK_EXT_SHADER_STENCIL_EXPORT_SPEC_VERSION 1 -#define VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME "VK_EXT_shader_stencil_export" - - -#define VK_EXT_sample_locations 1 -#define VK_EXT_SAMPLE_LOCATIONS_SPEC_VERSION 1 -#define VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME "VK_EXT_sample_locations" -typedef struct VkSampleLocationEXT { - float x; - float y; -} VkSampleLocationEXT; - -typedef struct VkSampleLocationsInfoEXT { - VkStructureType sType; - const void* pNext; - VkSampleCountFlagBits sampleLocationsPerPixel; - VkExtent2D sampleLocationGridSize; - uint32_t sampleLocationsCount; - const VkSampleLocationEXT* pSampleLocations; -} VkSampleLocationsInfoEXT; - -typedef struct VkAttachmentSampleLocationsEXT { - uint32_t attachmentIndex; - VkSampleLocationsInfoEXT sampleLocationsInfo; -} VkAttachmentSampleLocationsEXT; - -typedef struct VkSubpassSampleLocationsEXT { - uint32_t subpassIndex; - VkSampleLocationsInfoEXT sampleLocationsInfo; -} VkSubpassSampleLocationsEXT; - -typedef struct VkRenderPassSampleLocationsBeginInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t attachmentInitialSampleLocationsCount; - const VkAttachmentSampleLocationsEXT* pAttachmentInitialSampleLocations; - uint32_t postSubpassSampleLocationsCount; - const VkSubpassSampleLocationsEXT* pPostSubpassSampleLocations; -} VkRenderPassSampleLocationsBeginInfoEXT; - -typedef struct VkPipelineSampleLocationsStateCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkBool32 sampleLocationsEnable; - VkSampleLocationsInfoEXT sampleLocationsInfo; -} VkPipelineSampleLocationsStateCreateInfoEXT; - -typedef struct VkPhysicalDeviceSampleLocationsPropertiesEXT { - VkStructureType sType; - void* pNext; - VkSampleCountFlags sampleLocationSampleCounts; - VkExtent2D maxSampleLocationGridSize; - float sampleLocationCoordinateRange[2]; - uint32_t sampleLocationSubPixelBits; - VkBool32 variableSampleLocations; -} VkPhysicalDeviceSampleLocationsPropertiesEXT; - -typedef struct VkMultisamplePropertiesEXT { - VkStructureType sType; - void* pNext; - VkExtent2D maxSampleLocationGridSize; -} VkMultisamplePropertiesEXT; - -typedef void (VKAPI_PTR *PFN_vkCmdSetSampleLocationsEXT)(VkCommandBuffer commandBuffer, const VkSampleLocationsInfoEXT* pSampleLocationsInfo); -typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)(VkPhysicalDevice physicalDevice, VkSampleCountFlagBits samples, VkMultisamplePropertiesEXT* pMultisampleProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleLocationsEXT( - VkCommandBuffer commandBuffer, - const VkSampleLocationsInfoEXT* pSampleLocationsInfo); - -VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMultisamplePropertiesEXT( - VkPhysicalDevice physicalDevice, - VkSampleCountFlagBits samples, - VkMultisamplePropertiesEXT* pMultisampleProperties); -#endif - - -#define VK_EXT_blend_operation_advanced 1 -#define VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION 2 -#define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME "VK_EXT_blend_operation_advanced" - -typedef enum VkBlendOverlapEXT { - VK_BLEND_OVERLAP_UNCORRELATED_EXT = 0, - VK_BLEND_OVERLAP_DISJOINT_EXT = 1, - VK_BLEND_OVERLAP_CONJOINT_EXT = 2, - VK_BLEND_OVERLAP_MAX_ENUM_EXT = 0x7FFFFFFF -} VkBlendOverlapEXT; -typedef struct VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 advancedBlendCoherentOperations; -} VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT; - -typedef struct VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t advancedBlendMaxColorAttachments; - VkBool32 advancedBlendIndependentBlend; - VkBool32 advancedBlendNonPremultipliedSrcColor; - VkBool32 advancedBlendNonPremultipliedDstColor; - VkBool32 advancedBlendCorrelatedOverlap; - VkBool32 advancedBlendAllOperations; -} VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT; - -typedef struct VkPipelineColorBlendAdvancedStateCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkBool32 srcPremultiplied; - VkBool32 dstPremultiplied; - VkBlendOverlapEXT blendOverlap; -} VkPipelineColorBlendAdvancedStateCreateInfoEXT; - - - -#define VK_NV_fragment_coverage_to_color 1 -#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_SPEC_VERSION 1 -#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME "VK_NV_fragment_coverage_to_color" -typedef VkFlags VkPipelineCoverageToColorStateCreateFlagsNV; -typedef struct VkPipelineCoverageToColorStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkPipelineCoverageToColorStateCreateFlagsNV flags; - VkBool32 coverageToColorEnable; - uint32_t coverageToColorLocation; -} VkPipelineCoverageToColorStateCreateInfoNV; - - - -#define VK_NV_framebuffer_mixed_samples 1 -#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_SPEC_VERSION 1 -#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME "VK_NV_framebuffer_mixed_samples" - -typedef enum VkCoverageModulationModeNV { - VK_COVERAGE_MODULATION_MODE_NONE_NV = 0, - VK_COVERAGE_MODULATION_MODE_RGB_NV = 1, - VK_COVERAGE_MODULATION_MODE_ALPHA_NV = 2, - VK_COVERAGE_MODULATION_MODE_RGBA_NV = 3, - VK_COVERAGE_MODULATION_MODE_MAX_ENUM_NV = 0x7FFFFFFF -} VkCoverageModulationModeNV; -typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV; -typedef struct VkPipelineCoverageModulationStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkPipelineCoverageModulationStateCreateFlagsNV flags; - VkCoverageModulationModeNV coverageModulationMode; - VkBool32 coverageModulationTableEnable; - uint32_t coverageModulationTableCount; - const float* pCoverageModulationTable; -} VkPipelineCoverageModulationStateCreateInfoNV; - - - -#define VK_NV_fill_rectangle 1 -#define VK_NV_FILL_RECTANGLE_SPEC_VERSION 1 -#define VK_NV_FILL_RECTANGLE_EXTENSION_NAME "VK_NV_fill_rectangle" - - -#define VK_NV_shader_sm_builtins 1 -#define VK_NV_SHADER_SM_BUILTINS_SPEC_VERSION 1 -#define VK_NV_SHADER_SM_BUILTINS_EXTENSION_NAME "VK_NV_shader_sm_builtins" -typedef struct VkPhysicalDeviceShaderSMBuiltinsPropertiesNV { - VkStructureType sType; - void* pNext; - uint32_t shaderSMCount; - uint32_t shaderWarpsPerSM; -} VkPhysicalDeviceShaderSMBuiltinsPropertiesNV; - -typedef struct VkPhysicalDeviceShaderSMBuiltinsFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 shaderSMBuiltins; -} VkPhysicalDeviceShaderSMBuiltinsFeaturesNV; - - - -#define VK_EXT_post_depth_coverage 1 -#define VK_EXT_POST_DEPTH_COVERAGE_SPEC_VERSION 1 -#define VK_EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME "VK_EXT_post_depth_coverage" - - -#define VK_EXT_image_drm_format_modifier 1 -#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION 2 -#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME "VK_EXT_image_drm_format_modifier" -typedef struct VkDrmFormatModifierPropertiesEXT { - uint64_t drmFormatModifier; - uint32_t drmFormatModifierPlaneCount; - VkFormatFeatureFlags drmFormatModifierTilingFeatures; -} VkDrmFormatModifierPropertiesEXT; - -typedef struct VkDrmFormatModifierPropertiesListEXT { - VkStructureType sType; - void* pNext; - uint32_t drmFormatModifierCount; - VkDrmFormatModifierPropertiesEXT* pDrmFormatModifierProperties; -} VkDrmFormatModifierPropertiesListEXT; - -typedef struct VkPhysicalDeviceImageDrmFormatModifierInfoEXT { - VkStructureType sType; - const void* pNext; - uint64_t drmFormatModifier; - VkSharingMode sharingMode; - uint32_t queueFamilyIndexCount; - const uint32_t* pQueueFamilyIndices; -} VkPhysicalDeviceImageDrmFormatModifierInfoEXT; - -typedef struct VkImageDrmFormatModifierListCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t drmFormatModifierCount; - const uint64_t* pDrmFormatModifiers; -} VkImageDrmFormatModifierListCreateInfoEXT; - -typedef struct VkImageDrmFormatModifierExplicitCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint64_t drmFormatModifier; - uint32_t drmFormatModifierPlaneCount; - const VkSubresourceLayout* pPlaneLayouts; -} VkImageDrmFormatModifierExplicitCreateInfoEXT; - -typedef struct VkImageDrmFormatModifierPropertiesEXT { - VkStructureType sType; - void* pNext; - uint64_t drmFormatModifier; -} VkImageDrmFormatModifierPropertiesEXT; - -typedef struct VkDrmFormatModifierProperties2EXT { - uint64_t drmFormatModifier; - uint32_t drmFormatModifierPlaneCount; - VkFormatFeatureFlags2 drmFormatModifierTilingFeatures; -} VkDrmFormatModifierProperties2EXT; - -typedef struct VkDrmFormatModifierPropertiesList2EXT { - VkStructureType sType; - void* pNext; - uint32_t drmFormatModifierCount; - VkDrmFormatModifierProperties2EXT* pDrmFormatModifierProperties; -} VkDrmFormatModifierPropertiesList2EXT; - -typedef VkResult (VKAPI_PTR *PFN_vkGetImageDrmFormatModifierPropertiesEXT)(VkDevice device, VkImage image, VkImageDrmFormatModifierPropertiesEXT* pProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetImageDrmFormatModifierPropertiesEXT( - VkDevice device, - VkImage image, - VkImageDrmFormatModifierPropertiesEXT* pProperties); -#endif - - -#define VK_EXT_validation_cache 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkValidationCacheEXT) -#define VK_EXT_VALIDATION_CACHE_SPEC_VERSION 1 -#define VK_EXT_VALIDATION_CACHE_EXTENSION_NAME "VK_EXT_validation_cache" - -typedef enum VkValidationCacheHeaderVersionEXT { - VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT = 1, - VK_VALIDATION_CACHE_HEADER_VERSION_MAX_ENUM_EXT = 0x7FFFFFFF -} VkValidationCacheHeaderVersionEXT; -typedef VkFlags VkValidationCacheCreateFlagsEXT; -typedef struct VkValidationCacheCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkValidationCacheCreateFlagsEXT flags; - size_t initialDataSize; - const void* pInitialData; -} VkValidationCacheCreateInfoEXT; - -typedef struct VkShaderModuleValidationCacheCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkValidationCacheEXT validationCache; -} VkShaderModuleValidationCacheCreateInfoEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateValidationCacheEXT)(VkDevice device, const VkValidationCacheCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkValidationCacheEXT* pValidationCache); -typedef void (VKAPI_PTR *PFN_vkDestroyValidationCacheEXT)(VkDevice device, VkValidationCacheEXT validationCache, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkMergeValidationCachesEXT)(VkDevice device, VkValidationCacheEXT dstCache, uint32_t srcCacheCount, const VkValidationCacheEXT* pSrcCaches); -typedef VkResult (VKAPI_PTR *PFN_vkGetValidationCacheDataEXT)(VkDevice device, VkValidationCacheEXT validationCache, size_t* pDataSize, void* pData); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateValidationCacheEXT( - VkDevice device, - const VkValidationCacheCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkValidationCacheEXT* pValidationCache); - -VKAPI_ATTR void VKAPI_CALL vkDestroyValidationCacheEXT( - VkDevice device, - VkValidationCacheEXT validationCache, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkMergeValidationCachesEXT( - VkDevice device, - VkValidationCacheEXT dstCache, - uint32_t srcCacheCount, - const VkValidationCacheEXT* pSrcCaches); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetValidationCacheDataEXT( - VkDevice device, - VkValidationCacheEXT validationCache, - size_t* pDataSize, - void* pData); -#endif - - -#define VK_EXT_descriptor_indexing 1 -#define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2 -#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing" -typedef VkDescriptorBindingFlagBits VkDescriptorBindingFlagBitsEXT; - -typedef VkDescriptorBindingFlags VkDescriptorBindingFlagsEXT; - -typedef VkDescriptorSetLayoutBindingFlagsCreateInfo VkDescriptorSetLayoutBindingFlagsCreateInfoEXT; - -typedef VkPhysicalDeviceDescriptorIndexingFeatures VkPhysicalDeviceDescriptorIndexingFeaturesEXT; - -typedef VkPhysicalDeviceDescriptorIndexingProperties VkPhysicalDeviceDescriptorIndexingPropertiesEXT; - -typedef VkDescriptorSetVariableDescriptorCountAllocateInfo VkDescriptorSetVariableDescriptorCountAllocateInfoEXT; - -typedef VkDescriptorSetVariableDescriptorCountLayoutSupport VkDescriptorSetVariableDescriptorCountLayoutSupportEXT; - - - -#define VK_EXT_shader_viewport_index_layer 1 -#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1 -#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer" - - -#define VK_NV_shading_rate_image 1 -#define VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION 3 -#define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image" - -typedef enum VkShadingRatePaletteEntryNV { - VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV = 0, - VK_SHADING_RATE_PALETTE_ENTRY_16_INVOCATIONS_PER_PIXEL_NV = 1, - VK_SHADING_RATE_PALETTE_ENTRY_8_INVOCATIONS_PER_PIXEL_NV = 2, - VK_SHADING_RATE_PALETTE_ENTRY_4_INVOCATIONS_PER_PIXEL_NV = 3, - VK_SHADING_RATE_PALETTE_ENTRY_2_INVOCATIONS_PER_PIXEL_NV = 4, - VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV = 5, - VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV = 6, - VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV = 7, - VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV = 8, - VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV = 9, - VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV = 10, - VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV = 11, - VK_SHADING_RATE_PALETTE_ENTRY_MAX_ENUM_NV = 0x7FFFFFFF -} VkShadingRatePaletteEntryNV; - -typedef enum VkCoarseSampleOrderTypeNV { - VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV = 0, - VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV = 1, - VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV = 2, - VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV = 3, - VK_COARSE_SAMPLE_ORDER_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkCoarseSampleOrderTypeNV; -typedef struct VkShadingRatePaletteNV { - uint32_t shadingRatePaletteEntryCount; - const VkShadingRatePaletteEntryNV* pShadingRatePaletteEntries; -} VkShadingRatePaletteNV; - -typedef struct VkPipelineViewportShadingRateImageStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkBool32 shadingRateImageEnable; - uint32_t viewportCount; - const VkShadingRatePaletteNV* pShadingRatePalettes; -} VkPipelineViewportShadingRateImageStateCreateInfoNV; - -typedef struct VkPhysicalDeviceShadingRateImageFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 shadingRateImage; - VkBool32 shadingRateCoarseSampleOrder; -} VkPhysicalDeviceShadingRateImageFeaturesNV; - -typedef struct VkPhysicalDeviceShadingRateImagePropertiesNV { - VkStructureType sType; - void* pNext; - VkExtent2D shadingRateTexelSize; - uint32_t shadingRatePaletteSize; - uint32_t shadingRateMaxCoarseSamples; -} VkPhysicalDeviceShadingRateImagePropertiesNV; - -typedef struct VkCoarseSampleLocationNV { - uint32_t pixelX; - uint32_t pixelY; - uint32_t sample; -} VkCoarseSampleLocationNV; - -typedef struct VkCoarseSampleOrderCustomNV { - VkShadingRatePaletteEntryNV shadingRate; - uint32_t sampleCount; - uint32_t sampleLocationCount; - const VkCoarseSampleLocationNV* pSampleLocations; -} VkCoarseSampleOrderCustomNV; - -typedef struct VkPipelineViewportCoarseSampleOrderStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkCoarseSampleOrderTypeNV sampleOrderType; - uint32_t customSampleOrderCount; - const VkCoarseSampleOrderCustomNV* pCustomSampleOrders; -} VkPipelineViewportCoarseSampleOrderStateCreateInfoNV; - -typedef void (VKAPI_PTR *PFN_vkCmdBindShadingRateImageNV)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout); -typedef void (VKAPI_PTR *PFN_vkCmdSetViewportShadingRatePaletteNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkShadingRatePaletteNV* pShadingRatePalettes); -typedef void (VKAPI_PTR *PFN_vkCmdSetCoarseSampleOrderNV)(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, uint32_t customSampleOrderCount, const VkCoarseSampleOrderCustomNV* pCustomSampleOrders); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdBindShadingRateImageNV( - VkCommandBuffer commandBuffer, - VkImageView imageView, - VkImageLayout imageLayout); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportShadingRatePaletteNV( - VkCommandBuffer commandBuffer, - uint32_t firstViewport, - uint32_t viewportCount, - const VkShadingRatePaletteNV* pShadingRatePalettes); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetCoarseSampleOrderNV( - VkCommandBuffer commandBuffer, - VkCoarseSampleOrderTypeNV sampleOrderType, - uint32_t customSampleOrderCount, - const VkCoarseSampleOrderCustomNV* pCustomSampleOrders); -#endif - - -#define VK_NV_ray_tracing 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNV) -#define VK_NV_RAY_TRACING_SPEC_VERSION 3 -#define VK_NV_RAY_TRACING_EXTENSION_NAME "VK_NV_ray_tracing" -#define VK_SHADER_UNUSED_KHR (~0U) -#define VK_SHADER_UNUSED_NV VK_SHADER_UNUSED_KHR - -typedef enum VkRayTracingShaderGroupTypeKHR { - VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR = 0, - VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR = 1, - VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR = 2, - VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, - VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR, - VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR, - VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkRayTracingShaderGroupTypeKHR; -typedef VkRayTracingShaderGroupTypeKHR VkRayTracingShaderGroupTypeNV; - - -typedef enum VkGeometryTypeKHR { - VK_GEOMETRY_TYPE_TRIANGLES_KHR = 0, - VK_GEOMETRY_TYPE_AABBS_KHR = 1, - VK_GEOMETRY_TYPE_INSTANCES_KHR = 2, - VK_GEOMETRY_TYPE_TRIANGLES_NV = VK_GEOMETRY_TYPE_TRIANGLES_KHR, - VK_GEOMETRY_TYPE_AABBS_NV = VK_GEOMETRY_TYPE_AABBS_KHR, - VK_GEOMETRY_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkGeometryTypeKHR; -typedef VkGeometryTypeKHR VkGeometryTypeNV; - - -typedef enum VkAccelerationStructureTypeKHR { - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR = 0, - VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR = 1, - VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR = 2, - VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, - VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, - VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkAccelerationStructureTypeKHR; -typedef VkAccelerationStructureTypeKHR VkAccelerationStructureTypeNV; - - -typedef enum VkCopyAccelerationStructureModeKHR { - VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR = 0, - VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR = 1, - VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR = 2, - VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR = 3, - VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR, - VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR, - VK_COPY_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkCopyAccelerationStructureModeKHR; -typedef VkCopyAccelerationStructureModeKHR VkCopyAccelerationStructureModeNV; - - -typedef enum VkAccelerationStructureMemoryRequirementsTypeNV { - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV = 0, - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV = 1, - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV = 2, - VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkAccelerationStructureMemoryRequirementsTypeNV; - -typedef enum VkGeometryFlagBitsKHR { - VK_GEOMETRY_OPAQUE_BIT_KHR = 0x00000001, - VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR = 0x00000002, - VK_GEOMETRY_OPAQUE_BIT_NV = VK_GEOMETRY_OPAQUE_BIT_KHR, - VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NV = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, - VK_GEOMETRY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkGeometryFlagBitsKHR; -typedef VkFlags VkGeometryFlagsKHR; -typedef VkGeometryFlagsKHR VkGeometryFlagsNV; - -typedef VkGeometryFlagBitsKHR VkGeometryFlagBitsNV; - - -typedef enum VkGeometryInstanceFlagBitsKHR { - VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR = 0x00000001, - VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR = 0x00000002, - VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR = 0x00000004, - VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR = 0x00000008, - VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR, - VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR, - VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR, - VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR, - VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR, - VK_GEOMETRY_INSTANCE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkGeometryInstanceFlagBitsKHR; -typedef VkFlags VkGeometryInstanceFlagsKHR; -typedef VkGeometryInstanceFlagsKHR VkGeometryInstanceFlagsNV; - -typedef VkGeometryInstanceFlagBitsKHR VkGeometryInstanceFlagBitsNV; - - -typedef enum VkBuildAccelerationStructureFlagBitsKHR { - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR = 0x00000001, - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR = 0x00000002, - VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR = 0x00000004, - VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR = 0x00000008, - VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR = 0x00000010, - VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV = 0x00000020, - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR, - VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR, - VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, - VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR, - VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR, - VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkBuildAccelerationStructureFlagBitsKHR; -typedef VkFlags VkBuildAccelerationStructureFlagsKHR; -typedef VkBuildAccelerationStructureFlagsKHR VkBuildAccelerationStructureFlagsNV; - -typedef VkBuildAccelerationStructureFlagBitsKHR VkBuildAccelerationStructureFlagBitsNV; - -typedef struct VkRayTracingShaderGroupCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkRayTracingShaderGroupTypeKHR type; - uint32_t generalShader; - uint32_t closestHitShader; - uint32_t anyHitShader; - uint32_t intersectionShader; -} VkRayTracingShaderGroupCreateInfoNV; - -typedef struct VkRayTracingPipelineCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkPipelineCreateFlags flags; - uint32_t stageCount; - const VkPipelineShaderStageCreateInfo* pStages; - uint32_t groupCount; - const VkRayTracingShaderGroupCreateInfoNV* pGroups; - uint32_t maxRecursionDepth; - VkPipelineLayout layout; - VkPipeline basePipelineHandle; - int32_t basePipelineIndex; -} VkRayTracingPipelineCreateInfoNV; - -typedef struct VkGeometryTrianglesNV { - VkStructureType sType; - const void* pNext; - VkBuffer vertexData; - VkDeviceSize vertexOffset; - uint32_t vertexCount; - VkDeviceSize vertexStride; - VkFormat vertexFormat; - VkBuffer indexData; - VkDeviceSize indexOffset; - uint32_t indexCount; - VkIndexType indexType; - VkBuffer transformData; - VkDeviceSize transformOffset; -} VkGeometryTrianglesNV; - -typedef struct VkGeometryAABBNV { - VkStructureType sType; - const void* pNext; - VkBuffer aabbData; - uint32_t numAABBs; - uint32_t stride; - VkDeviceSize offset; -} VkGeometryAABBNV; - -typedef struct VkGeometryDataNV { - VkGeometryTrianglesNV triangles; - VkGeometryAABBNV aabbs; -} VkGeometryDataNV; - -typedef struct VkGeometryNV { - VkStructureType sType; - const void* pNext; - VkGeometryTypeKHR geometryType; - VkGeometryDataNV geometry; - VkGeometryFlagsKHR flags; -} VkGeometryNV; - -typedef struct VkAccelerationStructureInfoNV { - VkStructureType sType; - const void* pNext; - VkAccelerationStructureTypeNV type; - VkBuildAccelerationStructureFlagsNV flags; - uint32_t instanceCount; - uint32_t geometryCount; - const VkGeometryNV* pGeometries; -} VkAccelerationStructureInfoNV; - -typedef struct VkAccelerationStructureCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkDeviceSize compactedSize; - VkAccelerationStructureInfoNV info; -} VkAccelerationStructureCreateInfoNV; - -typedef struct VkBindAccelerationStructureMemoryInfoNV { - VkStructureType sType; - const void* pNext; - VkAccelerationStructureNV accelerationStructure; - VkDeviceMemory memory; - VkDeviceSize memoryOffset; - uint32_t deviceIndexCount; - const uint32_t* pDeviceIndices; -} VkBindAccelerationStructureMemoryInfoNV; - -typedef struct VkWriteDescriptorSetAccelerationStructureNV { - VkStructureType sType; - const void* pNext; - uint32_t accelerationStructureCount; - const VkAccelerationStructureNV* pAccelerationStructures; -} VkWriteDescriptorSetAccelerationStructureNV; - -typedef struct VkAccelerationStructureMemoryRequirementsInfoNV { - VkStructureType sType; - const void* pNext; - VkAccelerationStructureMemoryRequirementsTypeNV type; - VkAccelerationStructureNV accelerationStructure; -} VkAccelerationStructureMemoryRequirementsInfoNV; - -typedef struct VkPhysicalDeviceRayTracingPropertiesNV { - VkStructureType sType; - void* pNext; - uint32_t shaderGroupHandleSize; - uint32_t maxRecursionDepth; - uint32_t maxShaderGroupStride; - uint32_t shaderGroupBaseAlignment; - uint64_t maxGeometryCount; - uint64_t maxInstanceCount; - uint64_t maxTriangleCount; - uint32_t maxDescriptorSetAccelerationStructures; -} VkPhysicalDeviceRayTracingPropertiesNV; - -typedef struct VkTransformMatrixKHR { - float matrix[3][4]; -} VkTransformMatrixKHR; - -typedef VkTransformMatrixKHR VkTransformMatrixNV; - -typedef struct VkAabbPositionsKHR { - float minX; - float minY; - float minZ; - float maxX; - float maxY; - float maxZ; -} VkAabbPositionsKHR; - -typedef VkAabbPositionsKHR VkAabbPositionsNV; - -typedef struct VkAccelerationStructureInstanceKHR { - VkTransformMatrixKHR transform; - uint32_t instanceCustomIndex:24; - uint32_t mask:8; - uint32_t instanceShaderBindingTableRecordOffset:24; - VkGeometryInstanceFlagsKHR flags:8; - uint64_t accelerationStructureReference; -} VkAccelerationStructureInstanceKHR; - -typedef VkAccelerationStructureInstanceKHR VkAccelerationStructureInstanceNV; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureNV)(VkDevice device, const VkAccelerationStructureCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNV* pAccelerationStructure); -typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsNV)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements); -typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryNV)(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV* pBindInfos); -typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureNV)(VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV* pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset, VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset); -typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNV)(VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkCopyAccelerationStructureModeKHR mode); -typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysNV)(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer, VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer, VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride, VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset, VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer, VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride, uint32_t width, uint32_t height, uint32_t depth); -typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesNV)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoNV* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); -typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesKHR)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); -typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesNV)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); -typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureHandleNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, size_t dataSize, void* pData); -typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesNV)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureNV* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); -typedef VkResult (VKAPI_PTR *PFN_vkCompileDeferredNV)(VkDevice device, VkPipeline pipeline, uint32_t shader); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureNV( - VkDevice device, - const VkAccelerationStructureCreateInfoNV* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkAccelerationStructureNV* pAccelerationStructure); - -VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureNV( - VkDevice device, - VkAccelerationStructureNV accelerationStructure, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureMemoryRequirementsNV( - VkDevice device, - const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, - VkMemoryRequirements2KHR* pMemoryRequirements); - -VKAPI_ATTR VkResult VKAPI_CALL vkBindAccelerationStructureMemoryNV( - VkDevice device, - uint32_t bindInfoCount, - const VkBindAccelerationStructureMemoryInfoNV* pBindInfos); - -VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureNV( - VkCommandBuffer commandBuffer, - const VkAccelerationStructureInfoNV* pInfo, - VkBuffer instanceData, - VkDeviceSize instanceOffset, - VkBool32 update, - VkAccelerationStructureNV dst, - VkAccelerationStructureNV src, - VkBuffer scratch, - VkDeviceSize scratchOffset); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureNV( - VkCommandBuffer commandBuffer, - VkAccelerationStructureNV dst, - VkAccelerationStructureNV src, - VkCopyAccelerationStructureModeKHR mode); - -VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysNV( - VkCommandBuffer commandBuffer, - VkBuffer raygenShaderBindingTableBuffer, - VkDeviceSize raygenShaderBindingOffset, - VkBuffer missShaderBindingTableBuffer, - VkDeviceSize missShaderBindingOffset, - VkDeviceSize missShaderBindingStride, - VkBuffer hitShaderBindingTableBuffer, - VkDeviceSize hitShaderBindingOffset, - VkDeviceSize hitShaderBindingStride, - VkBuffer callableShaderBindingTableBuffer, - VkDeviceSize callableShaderBindingOffset, - VkDeviceSize callableShaderBindingStride, - uint32_t width, - uint32_t height, - uint32_t depth); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesNV( - VkDevice device, - VkPipelineCache pipelineCache, - uint32_t createInfoCount, - const VkRayTracingPipelineCreateInfoNV* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesKHR( - VkDevice device, - VkPipeline pipeline, - uint32_t firstGroup, - uint32_t groupCount, - size_t dataSize, - void* pData); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesNV( - VkDevice device, - VkPipeline pipeline, - uint32_t firstGroup, - uint32_t groupCount, - size_t dataSize, - void* pData); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetAccelerationStructureHandleNV( - VkDevice device, - VkAccelerationStructureNV accelerationStructure, - size_t dataSize, - void* pData); - -VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesNV( - VkCommandBuffer commandBuffer, - uint32_t accelerationStructureCount, - const VkAccelerationStructureNV* pAccelerationStructures, - VkQueryType queryType, - VkQueryPool queryPool, - uint32_t firstQuery); - -VKAPI_ATTR VkResult VKAPI_CALL vkCompileDeferredNV( - VkDevice device, - VkPipeline pipeline, - uint32_t shader); -#endif - - -#define VK_NV_representative_fragment_test 1 -#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 2 -#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME "VK_NV_representative_fragment_test" -typedef struct VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 representativeFragmentTest; -} VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV; - -typedef struct VkPipelineRepresentativeFragmentTestStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkBool32 representativeFragmentTestEnable; -} VkPipelineRepresentativeFragmentTestStateCreateInfoNV; - - - -#define VK_EXT_filter_cubic 1 -#define VK_EXT_FILTER_CUBIC_SPEC_VERSION 3 -#define VK_EXT_FILTER_CUBIC_EXTENSION_NAME "VK_EXT_filter_cubic" -typedef struct VkPhysicalDeviceImageViewImageFormatInfoEXT { - VkStructureType sType; - void* pNext; - VkImageViewType imageViewType; -} VkPhysicalDeviceImageViewImageFormatInfoEXT; - -typedef struct VkFilterCubicImageViewImageFormatPropertiesEXT { - VkStructureType sType; - void* pNext; - VkBool32 filterCubic; - VkBool32 filterCubicMinmax; -} VkFilterCubicImageViewImageFormatPropertiesEXT; - - - -#define VK_QCOM_render_pass_shader_resolve 1 -#define VK_QCOM_RENDER_PASS_SHADER_RESOLVE_SPEC_VERSION 4 -#define VK_QCOM_RENDER_PASS_SHADER_RESOLVE_EXTENSION_NAME "VK_QCOM_render_pass_shader_resolve" - - -#define VK_EXT_global_priority 1 -#define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2 -#define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority" -typedef VkQueueGlobalPriorityKHR VkQueueGlobalPriorityEXT; - -typedef VkDeviceQueueGlobalPriorityCreateInfoKHR VkDeviceQueueGlobalPriorityCreateInfoEXT; - - - -#define VK_EXT_external_memory_host 1 -#define VK_EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION 1 -#define VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME "VK_EXT_external_memory_host" -typedef struct VkImportMemoryHostPointerInfoEXT { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagBits handleType; - void* pHostPointer; -} VkImportMemoryHostPointerInfoEXT; - -typedef struct VkMemoryHostPointerPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t memoryTypeBits; -} VkMemoryHostPointerPropertiesEXT; - -typedef struct VkPhysicalDeviceExternalMemoryHostPropertiesEXT { - VkStructureType sType; - void* pNext; - VkDeviceSize minImportedHostPointerAlignment; -} VkPhysicalDeviceExternalMemoryHostPropertiesEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryHostPointerPropertiesEXT)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, const void* pHostPointer, VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT( - VkDevice device, - VkExternalMemoryHandleTypeFlagBits handleType, - const void* pHostPointer, - VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties); -#endif - - -#define VK_AMD_buffer_marker 1 -#define VK_AMD_BUFFER_MARKER_SPEC_VERSION 1 -#define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_AMD_buffer_marker" -typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarkerAMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarkerAMD( - VkCommandBuffer commandBuffer, - VkPipelineStageFlagBits pipelineStage, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - uint32_t marker); -#endif - - -#define VK_AMD_pipeline_compiler_control 1 -#define VK_AMD_PIPELINE_COMPILER_CONTROL_SPEC_VERSION 1 -#define VK_AMD_PIPELINE_COMPILER_CONTROL_EXTENSION_NAME "VK_AMD_pipeline_compiler_control" - -typedef enum VkPipelineCompilerControlFlagBitsAMD { - VK_PIPELINE_COMPILER_CONTROL_FLAG_BITS_MAX_ENUM_AMD = 0x7FFFFFFF -} VkPipelineCompilerControlFlagBitsAMD; -typedef VkFlags VkPipelineCompilerControlFlagsAMD; -typedef struct VkPipelineCompilerControlCreateInfoAMD { - VkStructureType sType; - const void* pNext; - VkPipelineCompilerControlFlagsAMD compilerControlFlags; -} VkPipelineCompilerControlCreateInfoAMD; - - - -#define VK_EXT_calibrated_timestamps 1 -#define VK_EXT_CALIBRATED_TIMESTAMPS_SPEC_VERSION 2 -#define VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME "VK_EXT_calibrated_timestamps" - -typedef enum VkTimeDomainEXT { - VK_TIME_DOMAIN_DEVICE_EXT = 0, - VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT = 1, - VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT = 2, - VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT = 3, - VK_TIME_DOMAIN_MAX_ENUM_EXT = 0x7FFFFFFF -} VkTimeDomainEXT; -typedef struct VkCalibratedTimestampInfoEXT { - VkStructureType sType; - const void* pNext; - VkTimeDomainEXT timeDomain; -} VkCalibratedTimestampInfoEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)(VkPhysicalDevice physicalDevice, uint32_t* pTimeDomainCount, VkTimeDomainEXT* pTimeDomains); -typedef VkResult (VKAPI_PTR *PFN_vkGetCalibratedTimestampsEXT)(VkDevice device, uint32_t timestampCount, const VkCalibratedTimestampInfoEXT* pTimestampInfos, uint64_t* pTimestamps, uint64_t* pMaxDeviation); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( - VkPhysicalDevice physicalDevice, - uint32_t* pTimeDomainCount, - VkTimeDomainEXT* pTimeDomains); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetCalibratedTimestampsEXT( - VkDevice device, - uint32_t timestampCount, - const VkCalibratedTimestampInfoEXT* pTimestampInfos, - uint64_t* pTimestamps, - uint64_t* pMaxDeviation); -#endif - - -#define VK_AMD_shader_core_properties 1 -#define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 2 -#define VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_AMD_shader_core_properties" -typedef struct VkPhysicalDeviceShaderCorePropertiesAMD { - VkStructureType sType; - void* pNext; - uint32_t shaderEngineCount; - uint32_t shaderArraysPerEngineCount; - uint32_t computeUnitsPerShaderArray; - uint32_t simdPerComputeUnit; - uint32_t wavefrontsPerSimd; - uint32_t wavefrontSize; - uint32_t sgprsPerSimd; - uint32_t minSgprAllocation; - uint32_t maxSgprAllocation; - uint32_t sgprAllocationGranularity; - uint32_t vgprsPerSimd; - uint32_t minVgprAllocation; - uint32_t maxVgprAllocation; - uint32_t vgprAllocationGranularity; -} VkPhysicalDeviceShaderCorePropertiesAMD; - - - -#define VK_AMD_memory_overallocation_behavior 1 -#define VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_SPEC_VERSION 1 -#define VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_EXTENSION_NAME "VK_AMD_memory_overallocation_behavior" - -typedef enum VkMemoryOverallocationBehaviorAMD { - VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD = 0, - VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD = 1, - VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD = 2, - VK_MEMORY_OVERALLOCATION_BEHAVIOR_MAX_ENUM_AMD = 0x7FFFFFFF -} VkMemoryOverallocationBehaviorAMD; -typedef struct VkDeviceMemoryOverallocationCreateInfoAMD { - VkStructureType sType; - const void* pNext; - VkMemoryOverallocationBehaviorAMD overallocationBehavior; -} VkDeviceMemoryOverallocationCreateInfoAMD; - - - -#define VK_EXT_vertex_attribute_divisor 1 -#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION 3 -#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME "VK_EXT_vertex_attribute_divisor" -typedef struct VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t maxVertexAttribDivisor; -} VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT; - -typedef struct VkVertexInputBindingDivisorDescriptionEXT { - uint32_t binding; - uint32_t divisor; -} VkVertexInputBindingDivisorDescriptionEXT; - -typedef struct VkPipelineVertexInputDivisorStateCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t vertexBindingDivisorCount; - const VkVertexInputBindingDivisorDescriptionEXT* pVertexBindingDivisors; -} VkPipelineVertexInputDivisorStateCreateInfoEXT; - -typedef struct VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 vertexAttributeInstanceRateDivisor; - VkBool32 vertexAttributeInstanceRateZeroDivisor; -} VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT; - - - -#define VK_EXT_pipeline_creation_feedback 1 -#define VK_EXT_PIPELINE_CREATION_FEEDBACK_SPEC_VERSION 1 -#define VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME "VK_EXT_pipeline_creation_feedback" -typedef VkPipelineCreationFeedbackFlagBits VkPipelineCreationFeedbackFlagBitsEXT; - -typedef VkPipelineCreationFeedbackFlags VkPipelineCreationFeedbackFlagsEXT; - -typedef VkPipelineCreationFeedbackCreateInfo VkPipelineCreationFeedbackCreateInfoEXT; - -typedef VkPipelineCreationFeedback VkPipelineCreationFeedbackEXT; - - - -#define VK_NV_shader_subgroup_partitioned 1 -#define VK_NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1 -#define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned" - - -#define VK_NV_compute_shader_derivatives 1 -#define VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION 1 -#define VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_NV_compute_shader_derivatives" -typedef struct VkPhysicalDeviceComputeShaderDerivativesFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 computeDerivativeGroupQuads; - VkBool32 computeDerivativeGroupLinear; -} VkPhysicalDeviceComputeShaderDerivativesFeaturesNV; - - - -#define VK_NV_mesh_shader 1 -#define VK_NV_MESH_SHADER_SPEC_VERSION 1 -#define VK_NV_MESH_SHADER_EXTENSION_NAME "VK_NV_mesh_shader" -typedef struct VkPhysicalDeviceMeshShaderFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 taskShader; - VkBool32 meshShader; -} VkPhysicalDeviceMeshShaderFeaturesNV; - -typedef struct VkPhysicalDeviceMeshShaderPropertiesNV { - VkStructureType sType; - void* pNext; - uint32_t maxDrawMeshTasksCount; - uint32_t maxTaskWorkGroupInvocations; - uint32_t maxTaskWorkGroupSize[3]; - uint32_t maxTaskTotalMemorySize; - uint32_t maxTaskOutputCount; - uint32_t maxMeshWorkGroupInvocations; - uint32_t maxMeshWorkGroupSize[3]; - uint32_t maxMeshTotalMemorySize; - uint32_t maxMeshOutputVertices; - uint32_t maxMeshOutputPrimitives; - uint32_t maxMeshMultiviewViewCount; - uint32_t meshOutputPerVertexGranularity; - uint32_t meshOutputPerPrimitiveGranularity; -} VkPhysicalDeviceMeshShaderPropertiesNV; - -typedef struct VkDrawMeshTasksIndirectCommandNV { - uint32_t taskCount; - uint32_t firstTask; -} VkDrawMeshTasksIndirectCommandNV; - -typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksNV)(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask); -typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCountNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksNV( - VkCommandBuffer commandBuffer, - uint32_t taskCount, - uint32_t firstTask); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectNV( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - uint32_t drawCount, - uint32_t stride); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountNV( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkBuffer countBuffer, - VkDeviceSize countBufferOffset, - uint32_t maxDrawCount, - uint32_t stride); -#endif - - -#define VK_NV_fragment_shader_barycentric 1 -#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1 -#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_NV_fragment_shader_barycentric" -typedef VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV; - - - -#define VK_NV_shader_image_footprint 1 -#define VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION 2 -#define VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME "VK_NV_shader_image_footprint" -typedef struct VkPhysicalDeviceShaderImageFootprintFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 imageFootprint; -} VkPhysicalDeviceShaderImageFootprintFeaturesNV; - - - -#define VK_NV_scissor_exclusive 1 -#define VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION 1 -#define VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME "VK_NV_scissor_exclusive" -typedef struct VkPipelineViewportExclusiveScissorStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - uint32_t exclusiveScissorCount; - const VkRect2D* pExclusiveScissors; -} VkPipelineViewportExclusiveScissorStateCreateInfoNV; - -typedef struct VkPhysicalDeviceExclusiveScissorFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 exclusiveScissor; -} VkPhysicalDeviceExclusiveScissorFeaturesNV; - -typedef void (VKAPI_PTR *PFN_vkCmdSetExclusiveScissorNV)(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkRect2D* pExclusiveScissors); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetExclusiveScissorNV( - VkCommandBuffer commandBuffer, - uint32_t firstExclusiveScissor, - uint32_t exclusiveScissorCount, - const VkRect2D* pExclusiveScissors); -#endif - - -#define VK_NV_device_diagnostic_checkpoints 1 -#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION 2 -#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME "VK_NV_device_diagnostic_checkpoints" -typedef struct VkQueueFamilyCheckpointPropertiesNV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlags checkpointExecutionStageMask; -} VkQueueFamilyCheckpointPropertiesNV; - -typedef struct VkCheckpointDataNV { - VkStructureType sType; - void* pNext; - VkPipelineStageFlagBits stage; - void* pCheckpointMarker; -} VkCheckpointDataNV; - -typedef void (VKAPI_PTR *PFN_vkCmdSetCheckpointNV)(VkCommandBuffer commandBuffer, const void* pCheckpointMarker); -typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointDataNV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointDataNV* pCheckpointData); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetCheckpointNV( - VkCommandBuffer commandBuffer, - const void* pCheckpointMarker); - -VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointDataNV( - VkQueue queue, - uint32_t* pCheckpointDataCount, - VkCheckpointDataNV* pCheckpointData); -#endif - - -#define VK_INTEL_shader_integer_functions2 1 -#define VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_SPEC_VERSION 1 -#define VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_EXTENSION_NAME "VK_INTEL_shader_integer_functions2" -typedef struct VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL { - VkStructureType sType; - void* pNext; - VkBool32 shaderIntegerFunctions2; -} VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL; - - - -#define VK_INTEL_performance_query 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPerformanceConfigurationINTEL) -#define VK_INTEL_PERFORMANCE_QUERY_SPEC_VERSION 2 -#define VK_INTEL_PERFORMANCE_QUERY_EXTENSION_NAME "VK_INTEL_performance_query" - -typedef enum VkPerformanceConfigurationTypeINTEL { - VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL = 0, - VK_PERFORMANCE_CONFIGURATION_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF -} VkPerformanceConfigurationTypeINTEL; - -typedef enum VkQueryPoolSamplingModeINTEL { - VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL = 0, - VK_QUERY_POOL_SAMPLING_MODE_MAX_ENUM_INTEL = 0x7FFFFFFF -} VkQueryPoolSamplingModeINTEL; - -typedef enum VkPerformanceOverrideTypeINTEL { - VK_PERFORMANCE_OVERRIDE_TYPE_NULL_HARDWARE_INTEL = 0, - VK_PERFORMANCE_OVERRIDE_TYPE_FLUSH_GPU_CACHES_INTEL = 1, - VK_PERFORMANCE_OVERRIDE_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF -} VkPerformanceOverrideTypeINTEL; - -typedef enum VkPerformanceParameterTypeINTEL { - VK_PERFORMANCE_PARAMETER_TYPE_HW_COUNTERS_SUPPORTED_INTEL = 0, - VK_PERFORMANCE_PARAMETER_TYPE_STREAM_MARKER_VALID_BITS_INTEL = 1, - VK_PERFORMANCE_PARAMETER_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF -} VkPerformanceParameterTypeINTEL; - -typedef enum VkPerformanceValueTypeINTEL { - VK_PERFORMANCE_VALUE_TYPE_UINT32_INTEL = 0, - VK_PERFORMANCE_VALUE_TYPE_UINT64_INTEL = 1, - VK_PERFORMANCE_VALUE_TYPE_FLOAT_INTEL = 2, - VK_PERFORMANCE_VALUE_TYPE_BOOL_INTEL = 3, - VK_PERFORMANCE_VALUE_TYPE_STRING_INTEL = 4, - VK_PERFORMANCE_VALUE_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF -} VkPerformanceValueTypeINTEL; -typedef union VkPerformanceValueDataINTEL { - uint32_t value32; - uint64_t value64; - float valueFloat; - VkBool32 valueBool; - const char* valueString; -} VkPerformanceValueDataINTEL; - -typedef struct VkPerformanceValueINTEL { - VkPerformanceValueTypeINTEL type; - VkPerformanceValueDataINTEL data; -} VkPerformanceValueINTEL; - -typedef struct VkInitializePerformanceApiInfoINTEL { - VkStructureType sType; - const void* pNext; - void* pUserData; -} VkInitializePerformanceApiInfoINTEL; - -typedef struct VkQueryPoolPerformanceQueryCreateInfoINTEL { - VkStructureType sType; - const void* pNext; - VkQueryPoolSamplingModeINTEL performanceCountersSampling; -} VkQueryPoolPerformanceQueryCreateInfoINTEL; - -typedef VkQueryPoolPerformanceQueryCreateInfoINTEL VkQueryPoolCreateInfoINTEL; - -typedef struct VkPerformanceMarkerInfoINTEL { - VkStructureType sType; - const void* pNext; - uint64_t marker; -} VkPerformanceMarkerInfoINTEL; - -typedef struct VkPerformanceStreamMarkerInfoINTEL { - VkStructureType sType; - const void* pNext; - uint32_t marker; -} VkPerformanceStreamMarkerInfoINTEL; - -typedef struct VkPerformanceOverrideInfoINTEL { - VkStructureType sType; - const void* pNext; - VkPerformanceOverrideTypeINTEL type; - VkBool32 enable; - uint64_t parameter; -} VkPerformanceOverrideInfoINTEL; - -typedef struct VkPerformanceConfigurationAcquireInfoINTEL { - VkStructureType sType; - const void* pNext; - VkPerformanceConfigurationTypeINTEL type; -} VkPerformanceConfigurationAcquireInfoINTEL; - -typedef VkResult (VKAPI_PTR *PFN_vkInitializePerformanceApiINTEL)(VkDevice device, const VkInitializePerformanceApiInfoINTEL* pInitializeInfo); -typedef void (VKAPI_PTR *PFN_vkUninitializePerformanceApiINTEL)(VkDevice device); -typedef VkResult (VKAPI_PTR *PFN_vkCmdSetPerformanceMarkerINTEL)(VkCommandBuffer commandBuffer, const VkPerformanceMarkerInfoINTEL* pMarkerInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCmdSetPerformanceStreamMarkerINTEL)(VkCommandBuffer commandBuffer, const VkPerformanceStreamMarkerInfoINTEL* pMarkerInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCmdSetPerformanceOverrideINTEL)(VkCommandBuffer commandBuffer, const VkPerformanceOverrideInfoINTEL* pOverrideInfo); -typedef VkResult (VKAPI_PTR *PFN_vkAcquirePerformanceConfigurationINTEL)(VkDevice device, const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo, VkPerformanceConfigurationINTEL* pConfiguration); -typedef VkResult (VKAPI_PTR *PFN_vkReleasePerformanceConfigurationINTEL)(VkDevice device, VkPerformanceConfigurationINTEL configuration); -typedef VkResult (VKAPI_PTR *PFN_vkQueueSetPerformanceConfigurationINTEL)(VkQueue queue, VkPerformanceConfigurationINTEL configuration); -typedef VkResult (VKAPI_PTR *PFN_vkGetPerformanceParameterINTEL)(VkDevice device, VkPerformanceParameterTypeINTEL parameter, VkPerformanceValueINTEL* pValue); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkInitializePerformanceApiINTEL( - VkDevice device, - const VkInitializePerformanceApiInfoINTEL* pInitializeInfo); - -VKAPI_ATTR void VKAPI_CALL vkUninitializePerformanceApiINTEL( - VkDevice device); - -VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceMarkerINTEL( - VkCommandBuffer commandBuffer, - const VkPerformanceMarkerInfoINTEL* pMarkerInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceStreamMarkerINTEL( - VkCommandBuffer commandBuffer, - const VkPerformanceStreamMarkerInfoINTEL* pMarkerInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceOverrideINTEL( - VkCommandBuffer commandBuffer, - const VkPerformanceOverrideInfoINTEL* pOverrideInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkAcquirePerformanceConfigurationINTEL( - VkDevice device, - const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo, - VkPerformanceConfigurationINTEL* pConfiguration); - -VKAPI_ATTR VkResult VKAPI_CALL vkReleasePerformanceConfigurationINTEL( - VkDevice device, - VkPerformanceConfigurationINTEL configuration); - -VKAPI_ATTR VkResult VKAPI_CALL vkQueueSetPerformanceConfigurationINTEL( - VkQueue queue, - VkPerformanceConfigurationINTEL configuration); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetPerformanceParameterINTEL( - VkDevice device, - VkPerformanceParameterTypeINTEL parameter, - VkPerformanceValueINTEL* pValue); -#endif - - -#define VK_EXT_pci_bus_info 1 -#define VK_EXT_PCI_BUS_INFO_SPEC_VERSION 2 -#define VK_EXT_PCI_BUS_INFO_EXTENSION_NAME "VK_EXT_pci_bus_info" -typedef struct VkPhysicalDevicePCIBusInfoPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t pciDomain; - uint32_t pciBus; - uint32_t pciDevice; - uint32_t pciFunction; -} VkPhysicalDevicePCIBusInfoPropertiesEXT; - - - -#define VK_AMD_display_native_hdr 1 -#define VK_AMD_DISPLAY_NATIVE_HDR_SPEC_VERSION 1 -#define VK_AMD_DISPLAY_NATIVE_HDR_EXTENSION_NAME "VK_AMD_display_native_hdr" -typedef struct VkDisplayNativeHdrSurfaceCapabilitiesAMD { - VkStructureType sType; - void* pNext; - VkBool32 localDimmingSupport; -} VkDisplayNativeHdrSurfaceCapabilitiesAMD; - -typedef struct VkSwapchainDisplayNativeHdrCreateInfoAMD { - VkStructureType sType; - const void* pNext; - VkBool32 localDimmingEnable; -} VkSwapchainDisplayNativeHdrCreateInfoAMD; - -typedef void (VKAPI_PTR *PFN_vkSetLocalDimmingAMD)(VkDevice device, VkSwapchainKHR swapChain, VkBool32 localDimmingEnable); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkSetLocalDimmingAMD( - VkDevice device, - VkSwapchainKHR swapChain, - VkBool32 localDimmingEnable); -#endif - - -#define VK_EXT_fragment_density_map 1 -#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 2 -#define VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME "VK_EXT_fragment_density_map" -typedef struct VkPhysicalDeviceFragmentDensityMapFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 fragmentDensityMap; - VkBool32 fragmentDensityMapDynamic; - VkBool32 fragmentDensityMapNonSubsampledImages; -} VkPhysicalDeviceFragmentDensityMapFeaturesEXT; - -typedef struct VkPhysicalDeviceFragmentDensityMapPropertiesEXT { - VkStructureType sType; - void* pNext; - VkExtent2D minFragmentDensityTexelSize; - VkExtent2D maxFragmentDensityTexelSize; - VkBool32 fragmentDensityInvocations; -} VkPhysicalDeviceFragmentDensityMapPropertiesEXT; - -typedef struct VkRenderPassFragmentDensityMapCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkAttachmentReference fragmentDensityMapAttachment; -} VkRenderPassFragmentDensityMapCreateInfoEXT; - - - -#define VK_EXT_scalar_block_layout 1 -#define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1 -#define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout" -typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLayoutFeaturesEXT; - - - -#define VK_GOOGLE_hlsl_functionality1 1 -#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION 1 -#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1" -#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION -#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME - - -#define VK_GOOGLE_decorate_string 1 -#define VK_GOOGLE_DECORATE_STRING_SPEC_VERSION 1 -#define VK_GOOGLE_DECORATE_STRING_EXTENSION_NAME "VK_GOOGLE_decorate_string" - - -#define VK_EXT_subgroup_size_control 1 -#define VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION 2 -#define VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME "VK_EXT_subgroup_size_control" -typedef VkPhysicalDeviceSubgroupSizeControlFeatures VkPhysicalDeviceSubgroupSizeControlFeaturesEXT; - -typedef VkPhysicalDeviceSubgroupSizeControlProperties VkPhysicalDeviceSubgroupSizeControlPropertiesEXT; - -typedef VkPipelineShaderStageRequiredSubgroupSizeCreateInfo VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT; - - - -#define VK_AMD_shader_core_properties2 1 -#define VK_AMD_SHADER_CORE_PROPERTIES_2_SPEC_VERSION 1 -#define VK_AMD_SHADER_CORE_PROPERTIES_2_EXTENSION_NAME "VK_AMD_shader_core_properties2" - -typedef enum VkShaderCorePropertiesFlagBitsAMD { - VK_SHADER_CORE_PROPERTIES_FLAG_BITS_MAX_ENUM_AMD = 0x7FFFFFFF -} VkShaderCorePropertiesFlagBitsAMD; -typedef VkFlags VkShaderCorePropertiesFlagsAMD; -typedef struct VkPhysicalDeviceShaderCoreProperties2AMD { - VkStructureType sType; - void* pNext; - VkShaderCorePropertiesFlagsAMD shaderCoreFeatures; - uint32_t activeComputeUnitCount; -} VkPhysicalDeviceShaderCoreProperties2AMD; - - - -#define VK_AMD_device_coherent_memory 1 -#define VK_AMD_DEVICE_COHERENT_MEMORY_SPEC_VERSION 1 -#define VK_AMD_DEVICE_COHERENT_MEMORY_EXTENSION_NAME "VK_AMD_device_coherent_memory" -typedef struct VkPhysicalDeviceCoherentMemoryFeaturesAMD { - VkStructureType sType; - void* pNext; - VkBool32 deviceCoherentMemory; -} VkPhysicalDeviceCoherentMemoryFeaturesAMD; - - - -#define VK_EXT_shader_image_atomic_int64 1 -#define VK_EXT_SHADER_IMAGE_ATOMIC_INT64_SPEC_VERSION 1 -#define VK_EXT_SHADER_IMAGE_ATOMIC_INT64_EXTENSION_NAME "VK_EXT_shader_image_atomic_int64" -typedef struct VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 shaderImageInt64Atomics; - VkBool32 sparseImageInt64Atomics; -} VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT; - - - -#define VK_EXT_memory_budget 1 -#define VK_EXT_MEMORY_BUDGET_SPEC_VERSION 1 -#define VK_EXT_MEMORY_BUDGET_EXTENSION_NAME "VK_EXT_memory_budget" -typedef struct VkPhysicalDeviceMemoryBudgetPropertiesEXT { - VkStructureType sType; - void* pNext; - VkDeviceSize heapBudget[VK_MAX_MEMORY_HEAPS]; - VkDeviceSize heapUsage[VK_MAX_MEMORY_HEAPS]; -} VkPhysicalDeviceMemoryBudgetPropertiesEXT; - - - -#define VK_EXT_memory_priority 1 -#define VK_EXT_MEMORY_PRIORITY_SPEC_VERSION 1 -#define VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME "VK_EXT_memory_priority" -typedef struct VkPhysicalDeviceMemoryPriorityFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 memoryPriority; -} VkPhysicalDeviceMemoryPriorityFeaturesEXT; - -typedef struct VkMemoryPriorityAllocateInfoEXT { - VkStructureType sType; - const void* pNext; - float priority; -} VkMemoryPriorityAllocateInfoEXT; - - - -#define VK_NV_dedicated_allocation_image_aliasing 1 -#define VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_SPEC_VERSION 1 -#define VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_EXTENSION_NAME "VK_NV_dedicated_allocation_image_aliasing" -typedef struct VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 dedicatedAllocationImageAliasing; -} VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV; - - - -#define VK_EXT_buffer_device_address 1 -#define VK_EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 2 -#define VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_EXT_buffer_device_address" -typedef struct VkPhysicalDeviceBufferDeviceAddressFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 bufferDeviceAddress; - VkBool32 bufferDeviceAddressCaptureReplay; - VkBool32 bufferDeviceAddressMultiDevice; -} VkPhysicalDeviceBufferDeviceAddressFeaturesEXT; - -typedef VkPhysicalDeviceBufferDeviceAddressFeaturesEXT VkPhysicalDeviceBufferAddressFeaturesEXT; - -typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoEXT; - -typedef struct VkBufferDeviceAddressCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkDeviceAddress deviceAddress; -} VkBufferDeviceAddressCreateInfoEXT; - -typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT( - VkDevice device, - const VkBufferDeviceAddressInfo* pInfo); -#endif - - -#define VK_EXT_tooling_info 1 -#define VK_EXT_TOOLING_INFO_SPEC_VERSION 1 -#define VK_EXT_TOOLING_INFO_EXTENSION_NAME "VK_EXT_tooling_info" -typedef VkToolPurposeFlagBits VkToolPurposeFlagBitsEXT; - -typedef VkToolPurposeFlags VkToolPurposeFlagsEXT; - -typedef VkPhysicalDeviceToolProperties VkPhysicalDeviceToolPropertiesEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolPropertiesEXT( - VkPhysicalDevice physicalDevice, - uint32_t* pToolCount, - VkPhysicalDeviceToolProperties* pToolProperties); -#endif - - -#define VK_EXT_separate_stencil_usage 1 -#define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1 -#define VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME "VK_EXT_separate_stencil_usage" -typedef VkImageStencilUsageCreateInfo VkImageStencilUsageCreateInfoEXT; - - - -#define VK_EXT_validation_features 1 -#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 5 -#define VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME "VK_EXT_validation_features" - -typedef enum VkValidationFeatureEnableEXT { - VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT = 0, - VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT = 1, - VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT = 2, - VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT = 3, - VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT = 4, - VK_VALIDATION_FEATURE_ENABLE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkValidationFeatureEnableEXT; - -typedef enum VkValidationFeatureDisableEXT { - VK_VALIDATION_FEATURE_DISABLE_ALL_EXT = 0, - VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT = 1, - VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT = 2, - VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT = 3, - VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT = 4, - VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT = 5, - VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT = 6, - VK_VALIDATION_FEATURE_DISABLE_SHADER_VALIDATION_CACHE_EXT = 7, - VK_VALIDATION_FEATURE_DISABLE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkValidationFeatureDisableEXT; -typedef struct VkValidationFeaturesEXT { - VkStructureType sType; - const void* pNext; - uint32_t enabledValidationFeatureCount; - const VkValidationFeatureEnableEXT* pEnabledValidationFeatures; - uint32_t disabledValidationFeatureCount; - const VkValidationFeatureDisableEXT* pDisabledValidationFeatures; -} VkValidationFeaturesEXT; - - - -#define VK_NV_cooperative_matrix 1 -#define VK_NV_COOPERATIVE_MATRIX_SPEC_VERSION 1 -#define VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME "VK_NV_cooperative_matrix" - -typedef enum VkComponentTypeNV { - VK_COMPONENT_TYPE_FLOAT16_NV = 0, - VK_COMPONENT_TYPE_FLOAT32_NV = 1, - VK_COMPONENT_TYPE_FLOAT64_NV = 2, - VK_COMPONENT_TYPE_SINT8_NV = 3, - VK_COMPONENT_TYPE_SINT16_NV = 4, - VK_COMPONENT_TYPE_SINT32_NV = 5, - VK_COMPONENT_TYPE_SINT64_NV = 6, - VK_COMPONENT_TYPE_UINT8_NV = 7, - VK_COMPONENT_TYPE_UINT16_NV = 8, - VK_COMPONENT_TYPE_UINT32_NV = 9, - VK_COMPONENT_TYPE_UINT64_NV = 10, - VK_COMPONENT_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkComponentTypeNV; - -typedef enum VkScopeNV { - VK_SCOPE_DEVICE_NV = 1, - VK_SCOPE_WORKGROUP_NV = 2, - VK_SCOPE_SUBGROUP_NV = 3, - VK_SCOPE_QUEUE_FAMILY_NV = 5, - VK_SCOPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkScopeNV; -typedef struct VkCooperativeMatrixPropertiesNV { - VkStructureType sType; - void* pNext; - uint32_t MSize; - uint32_t NSize; - uint32_t KSize; - VkComponentTypeNV AType; - VkComponentTypeNV BType; - VkComponentTypeNV CType; - VkComponentTypeNV DType; - VkScopeNV scope; -} VkCooperativeMatrixPropertiesNV; - -typedef struct VkPhysicalDeviceCooperativeMatrixFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 cooperativeMatrix; - VkBool32 cooperativeMatrixRobustBufferAccess; -} VkPhysicalDeviceCooperativeMatrixFeaturesNV; - -typedef struct VkPhysicalDeviceCooperativeMatrixPropertiesNV { - VkStructureType sType; - void* pNext; - VkShaderStageFlags cooperativeMatrixSupportedStages; -} VkPhysicalDeviceCooperativeMatrixPropertiesNV; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkCooperativeMatrixPropertiesNV* pProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCooperativeMatrixPropertiesNV( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkCooperativeMatrixPropertiesNV* pProperties); -#endif - - -#define VK_NV_coverage_reduction_mode 1 -#define VK_NV_COVERAGE_REDUCTION_MODE_SPEC_VERSION 1 -#define VK_NV_COVERAGE_REDUCTION_MODE_EXTENSION_NAME "VK_NV_coverage_reduction_mode" - -typedef enum VkCoverageReductionModeNV { - VK_COVERAGE_REDUCTION_MODE_MERGE_NV = 0, - VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV = 1, - VK_COVERAGE_REDUCTION_MODE_MAX_ENUM_NV = 0x7FFFFFFF -} VkCoverageReductionModeNV; -typedef VkFlags VkPipelineCoverageReductionStateCreateFlagsNV; -typedef struct VkPhysicalDeviceCoverageReductionModeFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 coverageReductionMode; -} VkPhysicalDeviceCoverageReductionModeFeaturesNV; - -typedef struct VkPipelineCoverageReductionStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkPipelineCoverageReductionStateCreateFlagsNV flags; - VkCoverageReductionModeNV coverageReductionMode; -} VkPipelineCoverageReductionStateCreateInfoNV; - -typedef struct VkFramebufferMixedSamplesCombinationNV { - VkStructureType sType; - void* pNext; - VkCoverageReductionModeNV coverageReductionMode; - VkSampleCountFlagBits rasterizationSamples; - VkSampleCountFlags depthStencilSamples; - VkSampleCountFlags colorSamples; -} VkFramebufferMixedSamplesCombinationNV; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV)(VkPhysicalDevice physicalDevice, uint32_t* pCombinationCount, VkFramebufferMixedSamplesCombinationNV* pCombinations); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV( - VkPhysicalDevice physicalDevice, - uint32_t* pCombinationCount, - VkFramebufferMixedSamplesCombinationNV* pCombinations); -#endif - - -#define VK_EXT_fragment_shader_interlock 1 -#define VK_EXT_FRAGMENT_SHADER_INTERLOCK_SPEC_VERSION 1 -#define VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME "VK_EXT_fragment_shader_interlock" -typedef struct VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 fragmentShaderSampleInterlock; - VkBool32 fragmentShaderPixelInterlock; - VkBool32 fragmentShaderShadingRateInterlock; -} VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT; - - - -#define VK_EXT_ycbcr_image_arrays 1 -#define VK_EXT_YCBCR_IMAGE_ARRAYS_SPEC_VERSION 1 -#define VK_EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME "VK_EXT_ycbcr_image_arrays" -typedef struct VkPhysicalDeviceYcbcrImageArraysFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 ycbcrImageArrays; -} VkPhysicalDeviceYcbcrImageArraysFeaturesEXT; - - - -#define VK_EXT_provoking_vertex 1 -#define VK_EXT_PROVOKING_VERTEX_SPEC_VERSION 1 -#define VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME "VK_EXT_provoking_vertex" - -typedef enum VkProvokingVertexModeEXT { - VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT = 0, - VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT = 1, - VK_PROVOKING_VERTEX_MODE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkProvokingVertexModeEXT; -typedef struct VkPhysicalDeviceProvokingVertexFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 provokingVertexLast; - VkBool32 transformFeedbackPreservesProvokingVertex; -} VkPhysicalDeviceProvokingVertexFeaturesEXT; - -typedef struct VkPhysicalDeviceProvokingVertexPropertiesEXT { - VkStructureType sType; - void* pNext; - VkBool32 provokingVertexModePerPipeline; - VkBool32 transformFeedbackPreservesTriangleFanProvokingVertex; -} VkPhysicalDeviceProvokingVertexPropertiesEXT; - -typedef struct VkPipelineRasterizationProvokingVertexStateCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkProvokingVertexModeEXT provokingVertexMode; -} VkPipelineRasterizationProvokingVertexStateCreateInfoEXT; - - - -#define VK_EXT_headless_surface 1 -#define VK_EXT_HEADLESS_SURFACE_SPEC_VERSION 1 -#define VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME "VK_EXT_headless_surface" -typedef VkFlags VkHeadlessSurfaceCreateFlagsEXT; -typedef struct VkHeadlessSurfaceCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkHeadlessSurfaceCreateFlagsEXT flags; -} VkHeadlessSurfaceCreateInfoEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateHeadlessSurfaceEXT)(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateHeadlessSurfaceEXT( - VkInstance instance, - const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); -#endif - - -#define VK_EXT_line_rasterization 1 -#define VK_EXT_LINE_RASTERIZATION_SPEC_VERSION 1 -#define VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME "VK_EXT_line_rasterization" - -typedef enum VkLineRasterizationModeEXT { - VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT = 0, - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT = 1, - VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT = 2, - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT = 3, - VK_LINE_RASTERIZATION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkLineRasterizationModeEXT; -typedef struct VkPhysicalDeviceLineRasterizationFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 rectangularLines; - VkBool32 bresenhamLines; - VkBool32 smoothLines; - VkBool32 stippledRectangularLines; - VkBool32 stippledBresenhamLines; - VkBool32 stippledSmoothLines; -} VkPhysicalDeviceLineRasterizationFeaturesEXT; - -typedef struct VkPhysicalDeviceLineRasterizationPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t lineSubPixelPrecisionBits; -} VkPhysicalDeviceLineRasterizationPropertiesEXT; - -typedef struct VkPipelineRasterizationLineStateCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkLineRasterizationModeEXT lineRasterizationMode; - VkBool32 stippledLineEnable; - uint32_t lineStippleFactor; - uint16_t lineStipplePattern; -} VkPipelineRasterizationLineStateCreateInfoEXT; - -typedef void (VKAPI_PTR *PFN_vkCmdSetLineStippleEXT)(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStippleEXT( - VkCommandBuffer commandBuffer, - uint32_t lineStippleFactor, - uint16_t lineStipplePattern); -#endif - - -#define VK_EXT_shader_atomic_float 1 -#define VK_EXT_SHADER_ATOMIC_FLOAT_SPEC_VERSION 1 -#define VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME "VK_EXT_shader_atomic_float" -typedef struct VkPhysicalDeviceShaderAtomicFloatFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 shaderBufferFloat32Atomics; - VkBool32 shaderBufferFloat32AtomicAdd; - VkBool32 shaderBufferFloat64Atomics; - VkBool32 shaderBufferFloat64AtomicAdd; - VkBool32 shaderSharedFloat32Atomics; - VkBool32 shaderSharedFloat32AtomicAdd; - VkBool32 shaderSharedFloat64Atomics; - VkBool32 shaderSharedFloat64AtomicAdd; - VkBool32 shaderImageFloat32Atomics; - VkBool32 shaderImageFloat32AtomicAdd; - VkBool32 sparseImageFloat32Atomics; - VkBool32 sparseImageFloat32AtomicAdd; -} VkPhysicalDeviceShaderAtomicFloatFeaturesEXT; - - - -#define VK_EXT_host_query_reset 1 -#define VK_EXT_HOST_QUERY_RESET_SPEC_VERSION 1 -#define VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME "VK_EXT_host_query_reset" -typedef VkPhysicalDeviceHostQueryResetFeatures VkPhysicalDeviceHostQueryResetFeaturesEXT; - -typedef void (VKAPI_PTR *PFN_vkResetQueryPoolEXT)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkResetQueryPoolEXT( - VkDevice device, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount); -#endif - - -#define VK_EXT_index_type_uint8 1 -#define VK_EXT_INDEX_TYPE_UINT8_SPEC_VERSION 1 -#define VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME "VK_EXT_index_type_uint8" -typedef struct VkPhysicalDeviceIndexTypeUint8FeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 indexTypeUint8; -} VkPhysicalDeviceIndexTypeUint8FeaturesEXT; - - - -#define VK_EXT_extended_dynamic_state 1 -#define VK_EXT_EXTENDED_DYNAMIC_STATE_SPEC_VERSION 1 -#define VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME "VK_EXT_extended_dynamic_state" -typedef struct VkPhysicalDeviceExtendedDynamicStateFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 extendedDynamicState; -} VkPhysicalDeviceExtendedDynamicStateFeaturesEXT; - -typedef void (VKAPI_PTR *PFN_vkCmdSetCullModeEXT)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode); -typedef void (VKAPI_PTR *PFN_vkCmdSetFrontFaceEXT)(VkCommandBuffer commandBuffer, VkFrontFace frontFace); -typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveTopologyEXT)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology); -typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWithCountEXT)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport* pViewports); -typedef void (VKAPI_PTR *PFN_vkCmdSetScissorWithCountEXT)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors); -typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers2EXT)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthWriteEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthCompareOpEXT)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBoundsTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetStencilTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOpEXT)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetCullModeEXT( - VkCommandBuffer commandBuffer, - VkCullModeFlags cullMode); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFaceEXT( - VkCommandBuffer commandBuffer, - VkFrontFace frontFace); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopologyEXT( - VkCommandBuffer commandBuffer, - VkPrimitiveTopology primitiveTopology); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCountEXT( - VkCommandBuffer commandBuffer, - uint32_t viewportCount, - const VkViewport* pViewports); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCountEXT( - VkCommandBuffer commandBuffer, - uint32_t scissorCount, - const VkRect2D* pScissors); - -VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2EXT( - VkCommandBuffer commandBuffer, - uint32_t firstBinding, - uint32_t bindingCount, - const VkBuffer* pBuffers, - const VkDeviceSize* pOffsets, - const VkDeviceSize* pSizes, - const VkDeviceSize* pStrides); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnableEXT( - VkCommandBuffer commandBuffer, - VkBool32 depthTestEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnableEXT( - VkCommandBuffer commandBuffer, - VkBool32 depthWriteEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOpEXT( - VkCommandBuffer commandBuffer, - VkCompareOp depthCompareOp); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnableEXT( - VkCommandBuffer commandBuffer, - VkBool32 depthBoundsTestEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnableEXT( - VkCommandBuffer commandBuffer, - VkBool32 stencilTestEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOpEXT( - VkCommandBuffer commandBuffer, - VkStencilFaceFlags faceMask, - VkStencilOp failOp, - VkStencilOp passOp, - VkStencilOp depthFailOp, - VkCompareOp compareOp); -#endif - - -#define VK_EXT_shader_atomic_float2 1 -#define VK_EXT_SHADER_ATOMIC_FLOAT_2_SPEC_VERSION 1 -#define VK_EXT_SHADER_ATOMIC_FLOAT_2_EXTENSION_NAME "VK_EXT_shader_atomic_float2" -typedef struct VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 shaderBufferFloat16Atomics; - VkBool32 shaderBufferFloat16AtomicAdd; - VkBool32 shaderBufferFloat16AtomicMinMax; - VkBool32 shaderBufferFloat32AtomicMinMax; - VkBool32 shaderBufferFloat64AtomicMinMax; - VkBool32 shaderSharedFloat16Atomics; - VkBool32 shaderSharedFloat16AtomicAdd; - VkBool32 shaderSharedFloat16AtomicMinMax; - VkBool32 shaderSharedFloat32AtomicMinMax; - VkBool32 shaderSharedFloat64AtomicMinMax; - VkBool32 shaderImageFloat32AtomicMinMax; - VkBool32 sparseImageFloat32AtomicMinMax; -} VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT; - - - -#define VK_EXT_shader_demote_to_helper_invocation 1 -#define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION 1 -#define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME "VK_EXT_shader_demote_to_helper_invocation" -typedef VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT; - - - -#define VK_NV_device_generated_commands 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNV) -#define VK_NV_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 3 -#define VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_NV_device_generated_commands" - -typedef enum VkIndirectCommandsTokenTypeNV { - VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV = 0, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV = 1, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV = 2, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV = 3, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV = 4, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV = 5, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV = 6, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_TASKS_NV = 7, - VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkIndirectCommandsTokenTypeNV; - -typedef enum VkIndirectStateFlagBitsNV { - VK_INDIRECT_STATE_FLAG_FRONTFACE_BIT_NV = 0x00000001, - VK_INDIRECT_STATE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkIndirectStateFlagBitsNV; -typedef VkFlags VkIndirectStateFlagsNV; - -typedef enum VkIndirectCommandsLayoutUsageFlagBitsNV { - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EXPLICIT_PREPROCESS_BIT_NV = 0x00000001, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NV = 0x00000002, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NV = 0x00000004, - VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkIndirectCommandsLayoutUsageFlagBitsNV; -typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNV; -typedef struct VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV { - VkStructureType sType; - void* pNext; - uint32_t maxGraphicsShaderGroupCount; - uint32_t maxIndirectSequenceCount; - uint32_t maxIndirectCommandsTokenCount; - uint32_t maxIndirectCommandsStreamCount; - uint32_t maxIndirectCommandsTokenOffset; - uint32_t maxIndirectCommandsStreamStride; - uint32_t minSequencesCountBufferOffsetAlignment; - uint32_t minSequencesIndexBufferOffsetAlignment; - uint32_t minIndirectCommandsBufferOffsetAlignment; -} VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV; - -typedef struct VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 deviceGeneratedCommands; -} VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV; - -typedef struct VkGraphicsShaderGroupCreateInfoNV { - VkStructureType sType; - const void* pNext; - uint32_t stageCount; - const VkPipelineShaderStageCreateInfo* pStages; - const VkPipelineVertexInputStateCreateInfo* pVertexInputState; - const VkPipelineTessellationStateCreateInfo* pTessellationState; -} VkGraphicsShaderGroupCreateInfoNV; - -typedef struct VkGraphicsPipelineShaderGroupsCreateInfoNV { - VkStructureType sType; - const void* pNext; - uint32_t groupCount; - const VkGraphicsShaderGroupCreateInfoNV* pGroups; - uint32_t pipelineCount; - const VkPipeline* pPipelines; -} VkGraphicsPipelineShaderGroupsCreateInfoNV; - -typedef struct VkBindShaderGroupIndirectCommandNV { - uint32_t groupIndex; -} VkBindShaderGroupIndirectCommandNV; - -typedef struct VkBindIndexBufferIndirectCommandNV { - VkDeviceAddress bufferAddress; - uint32_t size; - VkIndexType indexType; -} VkBindIndexBufferIndirectCommandNV; - -typedef struct VkBindVertexBufferIndirectCommandNV { - VkDeviceAddress bufferAddress; - uint32_t size; - uint32_t stride; -} VkBindVertexBufferIndirectCommandNV; - -typedef struct VkSetStateFlagsIndirectCommandNV { - uint32_t data; -} VkSetStateFlagsIndirectCommandNV; - -typedef struct VkIndirectCommandsStreamNV { - VkBuffer buffer; - VkDeviceSize offset; -} VkIndirectCommandsStreamNV; - -typedef struct VkIndirectCommandsLayoutTokenNV { - VkStructureType sType; - const void* pNext; - VkIndirectCommandsTokenTypeNV tokenType; - uint32_t stream; - uint32_t offset; - uint32_t vertexBindingUnit; - VkBool32 vertexDynamicStride; - VkPipelineLayout pushconstantPipelineLayout; - VkShaderStageFlags pushconstantShaderStageFlags; - uint32_t pushconstantOffset; - uint32_t pushconstantSize; - VkIndirectStateFlagsNV indirectStateFlags; - uint32_t indexTypeCount; - const VkIndexType* pIndexTypes; - const uint32_t* pIndexTypeValues; -} VkIndirectCommandsLayoutTokenNV; - -typedef struct VkIndirectCommandsLayoutCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkIndirectCommandsLayoutUsageFlagsNV flags; - VkPipelineBindPoint pipelineBindPoint; - uint32_t tokenCount; - const VkIndirectCommandsLayoutTokenNV* pTokens; - uint32_t streamCount; - const uint32_t* pStreamStrides; -} VkIndirectCommandsLayoutCreateInfoNV; - -typedef struct VkGeneratedCommandsInfoNV { - VkStructureType sType; - const void* pNext; - VkPipelineBindPoint pipelineBindPoint; - VkPipeline pipeline; - VkIndirectCommandsLayoutNV indirectCommandsLayout; - uint32_t streamCount; - const VkIndirectCommandsStreamNV* pStreams; - uint32_t sequencesCount; - VkBuffer preprocessBuffer; - VkDeviceSize preprocessOffset; - VkDeviceSize preprocessSize; - VkBuffer sequencesCountBuffer; - VkDeviceSize sequencesCountOffset; - VkBuffer sequencesIndexBuffer; - VkDeviceSize sequencesIndexOffset; -} VkGeneratedCommandsInfoNV; - -typedef struct VkGeneratedCommandsMemoryRequirementsInfoNV { - VkStructureType sType; - const void* pNext; - VkPipelineBindPoint pipelineBindPoint; - VkPipeline pipeline; - VkIndirectCommandsLayoutNV indirectCommandsLayout; - uint32_t maxSequencesCount; -} VkGeneratedCommandsMemoryRequirementsInfoNV; - -typedef void (VKAPI_PTR *PFN_vkGetGeneratedCommandsMemoryRequirementsNV)(VkDevice device, const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2* pMemoryRequirements); -typedef void (VKAPI_PTR *PFN_vkCmdPreprocessGeneratedCommandsNV)(VkCommandBuffer commandBuffer, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); -typedef void (VKAPI_PTR *PFN_vkCmdExecuteGeneratedCommandsNV)(VkCommandBuffer commandBuffer, VkBool32 isPreprocessed, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); -typedef void (VKAPI_PTR *PFN_vkCmdBindPipelineShaderGroupNV)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline, uint32_t groupIndex); -typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNV)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNV* pIndirectCommandsLayout); -typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNV)(VkDevice device, VkIndirectCommandsLayoutNV indirectCommandsLayout, const VkAllocationCallbacks* pAllocator); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetGeneratedCommandsMemoryRequirementsNV( - VkDevice device, - const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo, - VkMemoryRequirements2* pMemoryRequirements); - -VKAPI_ATTR void VKAPI_CALL vkCmdPreprocessGeneratedCommandsNV( - VkCommandBuffer commandBuffer, - const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdExecuteGeneratedCommandsNV( - VkCommandBuffer commandBuffer, - VkBool32 isPreprocessed, - const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdBindPipelineShaderGroupNV( - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipeline pipeline, - uint32_t groupIndex); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNV( - VkDevice device, - const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkIndirectCommandsLayoutNV* pIndirectCommandsLayout); - -VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNV( - VkDevice device, - VkIndirectCommandsLayoutNV indirectCommandsLayout, - const VkAllocationCallbacks* pAllocator); -#endif - - -#define VK_NV_inherited_viewport_scissor 1 -#define VK_NV_INHERITED_VIEWPORT_SCISSOR_SPEC_VERSION 1 -#define VK_NV_INHERITED_VIEWPORT_SCISSOR_EXTENSION_NAME "VK_NV_inherited_viewport_scissor" -typedef struct VkPhysicalDeviceInheritedViewportScissorFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 inheritedViewportScissor2D; -} VkPhysicalDeviceInheritedViewportScissorFeaturesNV; - -typedef struct VkCommandBufferInheritanceViewportScissorInfoNV { - VkStructureType sType; - const void* pNext; - VkBool32 viewportScissor2D; - uint32_t viewportDepthCount; - const VkViewport* pViewportDepths; -} VkCommandBufferInheritanceViewportScissorInfoNV; - - - -#define VK_EXT_texel_buffer_alignment 1 -#define VK_EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION 1 -#define VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME "VK_EXT_texel_buffer_alignment" -typedef struct VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 texelBufferAlignment; -} VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT; - -typedef VkPhysicalDeviceTexelBufferAlignmentProperties VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT; - - - -#define VK_QCOM_render_pass_transform 1 -#define VK_QCOM_RENDER_PASS_TRANSFORM_SPEC_VERSION 3 -#define VK_QCOM_RENDER_PASS_TRANSFORM_EXTENSION_NAME "VK_QCOM_render_pass_transform" -typedef struct VkRenderPassTransformBeginInfoQCOM { - VkStructureType sType; - void* pNext; - VkSurfaceTransformFlagBitsKHR transform; -} VkRenderPassTransformBeginInfoQCOM; - -typedef struct VkCommandBufferInheritanceRenderPassTransformInfoQCOM { - VkStructureType sType; - void* pNext; - VkSurfaceTransformFlagBitsKHR transform; - VkRect2D renderArea; -} VkCommandBufferInheritanceRenderPassTransformInfoQCOM; - - - -#define VK_EXT_device_memory_report 1 -#define VK_EXT_DEVICE_MEMORY_REPORT_SPEC_VERSION 2 -#define VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME "VK_EXT_device_memory_report" - -typedef enum VkDeviceMemoryReportEventTypeEXT { - VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT = 0, - VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT = 1, - VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT = 2, - VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT = 3, - VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATION_FAILED_EXT = 4, - VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkDeviceMemoryReportEventTypeEXT; -typedef VkFlags VkDeviceMemoryReportFlagsEXT; -typedef struct VkPhysicalDeviceDeviceMemoryReportFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 deviceMemoryReport; -} VkPhysicalDeviceDeviceMemoryReportFeaturesEXT; - -typedef struct VkDeviceMemoryReportCallbackDataEXT { - VkStructureType sType; - void* pNext; - VkDeviceMemoryReportFlagsEXT flags; - VkDeviceMemoryReportEventTypeEXT type; - uint64_t memoryObjectId; - VkDeviceSize size; - VkObjectType objectType; - uint64_t objectHandle; - uint32_t heapIndex; -} VkDeviceMemoryReportCallbackDataEXT; - -typedef void (VKAPI_PTR *PFN_vkDeviceMemoryReportCallbackEXT)( - const VkDeviceMemoryReportCallbackDataEXT* pCallbackData, - void* pUserData); - -typedef struct VkDeviceDeviceMemoryReportCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkDeviceMemoryReportFlagsEXT flags; - PFN_vkDeviceMemoryReportCallbackEXT pfnUserCallback; - void* pUserData; -} VkDeviceDeviceMemoryReportCreateInfoEXT; - - - -#define VK_EXT_acquire_drm_display 1 -#define VK_EXT_ACQUIRE_DRM_DISPLAY_SPEC_VERSION 1 -#define VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_drm_display" -typedef VkResult (VKAPI_PTR *PFN_vkAcquireDrmDisplayEXT)(VkPhysicalDevice physicalDevice, int32_t drmFd, VkDisplayKHR display); -typedef VkResult (VKAPI_PTR *PFN_vkGetDrmDisplayEXT)(VkPhysicalDevice physicalDevice, int32_t drmFd, uint32_t connectorId, VkDisplayKHR* display); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkAcquireDrmDisplayEXT( - VkPhysicalDevice physicalDevice, - int32_t drmFd, - VkDisplayKHR display); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDrmDisplayEXT( - VkPhysicalDevice physicalDevice, - int32_t drmFd, - uint32_t connectorId, - VkDisplayKHR* display); -#endif - - -#define VK_EXT_robustness2 1 -#define VK_EXT_ROBUSTNESS_2_SPEC_VERSION 1 -#define VK_EXT_ROBUSTNESS_2_EXTENSION_NAME "VK_EXT_robustness2" -typedef struct VkPhysicalDeviceRobustness2FeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 robustBufferAccess2; - VkBool32 robustImageAccess2; - VkBool32 nullDescriptor; -} VkPhysicalDeviceRobustness2FeaturesEXT; - -typedef struct VkPhysicalDeviceRobustness2PropertiesEXT { - VkStructureType sType; - void* pNext; - VkDeviceSize robustStorageBufferAccessSizeAlignment; - VkDeviceSize robustUniformBufferAccessSizeAlignment; -} VkPhysicalDeviceRobustness2PropertiesEXT; - - - -#define VK_EXT_custom_border_color 1 -#define VK_EXT_CUSTOM_BORDER_COLOR_SPEC_VERSION 12 -#define VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME "VK_EXT_custom_border_color" -typedef struct VkSamplerCustomBorderColorCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkClearColorValue customBorderColor; - VkFormat format; -} VkSamplerCustomBorderColorCreateInfoEXT; - -typedef struct VkPhysicalDeviceCustomBorderColorPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t maxCustomBorderColorSamplers; -} VkPhysicalDeviceCustomBorderColorPropertiesEXT; - -typedef struct VkPhysicalDeviceCustomBorderColorFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 customBorderColors; - VkBool32 customBorderColorWithoutFormat; -} VkPhysicalDeviceCustomBorderColorFeaturesEXT; - - - -#define VK_GOOGLE_user_type 1 -#define VK_GOOGLE_USER_TYPE_SPEC_VERSION 1 -#define VK_GOOGLE_USER_TYPE_EXTENSION_NAME "VK_GOOGLE_user_type" - - -#define VK_EXT_private_data 1 -typedef VkPrivateDataSlot VkPrivateDataSlotEXT; - -#define VK_EXT_PRIVATE_DATA_SPEC_VERSION 1 -#define VK_EXT_PRIVATE_DATA_EXTENSION_NAME "VK_EXT_private_data" -typedef VkPrivateDataSlotCreateFlags VkPrivateDataSlotCreateFlagsEXT; - -typedef VkPhysicalDevicePrivateDataFeatures VkPhysicalDevicePrivateDataFeaturesEXT; - -typedef VkDevicePrivateDataCreateInfo VkDevicePrivateDataCreateInfoEXT; - -typedef VkPrivateDataSlotCreateInfo VkPrivateDataSlotCreateInfoEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlotEXT)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); -typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlotEXT)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); -typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); -typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlotEXT( - VkDevice device, - const VkPrivateDataSlotCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPrivateDataSlot* pPrivateDataSlot); - -VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlotEXT( - VkDevice device, - VkPrivateDataSlot privateDataSlot, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateDataEXT( - VkDevice device, - VkObjectType objectType, - uint64_t objectHandle, - VkPrivateDataSlot privateDataSlot, - uint64_t data); - -VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( - VkDevice device, - VkObjectType objectType, - uint64_t objectHandle, - VkPrivateDataSlot privateDataSlot, - uint64_t* pData); -#endif - - -#define VK_EXT_pipeline_creation_cache_control 1 -#define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_SPEC_VERSION 3 -#define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME "VK_EXT_pipeline_creation_cache_control" -typedef VkPhysicalDevicePipelineCreationCacheControlFeatures VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT; - - - -#define VK_NV_device_diagnostics_config 1 -#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_SPEC_VERSION 2 -#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME "VK_NV_device_diagnostics_config" - -typedef enum VkDeviceDiagnosticsConfigFlagBitsNV { - VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV = 0x00000001, - VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV = 0x00000002, - VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV = 0x00000004, - VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_ERROR_REPORTING_BIT_NV = 0x00000008, - VK_DEVICE_DIAGNOSTICS_CONFIG_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF -} VkDeviceDiagnosticsConfigFlagBitsNV; -typedef VkFlags VkDeviceDiagnosticsConfigFlagsNV; -typedef struct VkPhysicalDeviceDiagnosticsConfigFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 diagnosticsConfig; -} VkPhysicalDeviceDiagnosticsConfigFeaturesNV; - -typedef struct VkDeviceDiagnosticsConfigCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkDeviceDiagnosticsConfigFlagsNV flags; -} VkDeviceDiagnosticsConfigCreateInfoNV; - - - -#define VK_QCOM_render_pass_store_ops 1 -#define VK_QCOM_RENDER_PASS_STORE_OPS_SPEC_VERSION 2 -#define VK_QCOM_RENDER_PASS_STORE_OPS_EXTENSION_NAME "VK_QCOM_render_pass_store_ops" - - -#define VK_EXT_graphics_pipeline_library 1 -#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_SPEC_VERSION 1 -#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME "VK_EXT_graphics_pipeline_library" - -typedef enum VkGraphicsPipelineLibraryFlagBitsEXT { - VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT = 0x00000001, - VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT = 0x00000002, - VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT = 0x00000004, - VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT = 0x00000008, - VK_GRAPHICS_PIPELINE_LIBRARY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkGraphicsPipelineLibraryFlagBitsEXT; -typedef VkFlags VkGraphicsPipelineLibraryFlagsEXT; -typedef struct VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 graphicsPipelineLibrary; -} VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT; - -typedef struct VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT { - VkStructureType sType; - void* pNext; - VkBool32 graphicsPipelineLibraryFastLinking; - VkBool32 graphicsPipelineLibraryIndependentInterpolationDecoration; -} VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT; - -typedef struct VkGraphicsPipelineLibraryCreateInfoEXT { - VkStructureType sType; - void* pNext; - VkGraphicsPipelineLibraryFlagsEXT flags; -} VkGraphicsPipelineLibraryCreateInfoEXT; - - - -#define VK_AMD_shader_early_and_late_fragment_tests 1 -#define VK_AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_SPEC_VERSION 1 -#define VK_AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_EXTENSION_NAME "VK_AMD_shader_early_and_late_fragment_tests" -typedef struct VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD { - VkStructureType sType; - void* pNext; - VkBool32 shaderEarlyAndLateFragmentTests; -} VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD; - - - -#define VK_NV_fragment_shading_rate_enums 1 -#define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_SPEC_VERSION 1 -#define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME "VK_NV_fragment_shading_rate_enums" - -typedef enum VkFragmentShadingRateTypeNV { - VK_FRAGMENT_SHADING_RATE_TYPE_FRAGMENT_SIZE_NV = 0, - VK_FRAGMENT_SHADING_RATE_TYPE_ENUMS_NV = 1, - VK_FRAGMENT_SHADING_RATE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkFragmentShadingRateTypeNV; - -typedef enum VkFragmentShadingRateNV { - VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV = 0, - VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV = 1, - VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV = 4, - VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV = 5, - VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV = 6, - VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV = 9, - VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV = 10, - VK_FRAGMENT_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV = 11, - VK_FRAGMENT_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV = 12, - VK_FRAGMENT_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV = 13, - VK_FRAGMENT_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV = 14, - VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV = 15, - VK_FRAGMENT_SHADING_RATE_MAX_ENUM_NV = 0x7FFFFFFF -} VkFragmentShadingRateNV; -typedef struct VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 fragmentShadingRateEnums; - VkBool32 supersampleFragmentShadingRates; - VkBool32 noInvocationFragmentShadingRates; -} VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV; - -typedef struct VkPhysicalDeviceFragmentShadingRateEnumsPropertiesNV { - VkStructureType sType; - void* pNext; - VkSampleCountFlagBits maxFragmentShadingRateInvocationCount; -} VkPhysicalDeviceFragmentShadingRateEnumsPropertiesNV; - -typedef struct VkPipelineFragmentShadingRateEnumStateCreateInfoNV { - VkStructureType sType; - const void* pNext; - VkFragmentShadingRateTypeNV shadingRateType; - VkFragmentShadingRateNV shadingRate; - VkFragmentShadingRateCombinerOpKHR combinerOps[2]; -} VkPipelineFragmentShadingRateEnumStateCreateInfoNV; - -typedef void (VKAPI_PTR *PFN_vkCmdSetFragmentShadingRateEnumNV)(VkCommandBuffer commandBuffer, VkFragmentShadingRateNV shadingRate, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetFragmentShadingRateEnumNV( - VkCommandBuffer commandBuffer, - VkFragmentShadingRateNV shadingRate, - const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); -#endif - - -#define VK_NV_ray_tracing_motion_blur 1 -#define VK_NV_RAY_TRACING_MOTION_BLUR_SPEC_VERSION 1 -#define VK_NV_RAY_TRACING_MOTION_BLUR_EXTENSION_NAME "VK_NV_ray_tracing_motion_blur" - -typedef enum VkAccelerationStructureMotionInstanceTypeNV { - VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_STATIC_NV = 0, - VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_MATRIX_MOTION_NV = 1, - VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_SRT_MOTION_NV = 2, - VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF -} VkAccelerationStructureMotionInstanceTypeNV; -typedef VkFlags VkAccelerationStructureMotionInfoFlagsNV; -typedef VkFlags VkAccelerationStructureMotionInstanceFlagsNV; -typedef union VkDeviceOrHostAddressConstKHR { - VkDeviceAddress deviceAddress; - const void* hostAddress; -} VkDeviceOrHostAddressConstKHR; - -typedef struct VkAccelerationStructureGeometryMotionTrianglesDataNV { - VkStructureType sType; - const void* pNext; - VkDeviceOrHostAddressConstKHR vertexData; -} VkAccelerationStructureGeometryMotionTrianglesDataNV; - -typedef struct VkAccelerationStructureMotionInfoNV { - VkStructureType sType; - const void* pNext; - uint32_t maxInstances; - VkAccelerationStructureMotionInfoFlagsNV flags; -} VkAccelerationStructureMotionInfoNV; - -typedef struct VkAccelerationStructureMatrixMotionInstanceNV { - VkTransformMatrixKHR transformT0; - VkTransformMatrixKHR transformT1; - uint32_t instanceCustomIndex:24; - uint32_t mask:8; - uint32_t instanceShaderBindingTableRecordOffset:24; - VkGeometryInstanceFlagsKHR flags:8; - uint64_t accelerationStructureReference; -} VkAccelerationStructureMatrixMotionInstanceNV; - -typedef struct VkSRTDataNV { - float sx; - float a; - float b; - float pvx; - float sy; - float c; - float pvy; - float sz; - float pvz; - float qx; - float qy; - float qz; - float qw; - float tx; - float ty; - float tz; -} VkSRTDataNV; - -typedef struct VkAccelerationStructureSRTMotionInstanceNV { - VkSRTDataNV transformT0; - VkSRTDataNV transformT1; - uint32_t instanceCustomIndex:24; - uint32_t mask:8; - uint32_t instanceShaderBindingTableRecordOffset:24; - VkGeometryInstanceFlagsKHR flags:8; - uint64_t accelerationStructureReference; -} VkAccelerationStructureSRTMotionInstanceNV; - -typedef union VkAccelerationStructureMotionInstanceDataNV { - VkAccelerationStructureInstanceKHR staticInstance; - VkAccelerationStructureMatrixMotionInstanceNV matrixMotionInstance; - VkAccelerationStructureSRTMotionInstanceNV srtMotionInstance; -} VkAccelerationStructureMotionInstanceDataNV; - -typedef struct VkAccelerationStructureMotionInstanceNV { - VkAccelerationStructureMotionInstanceTypeNV type; - VkAccelerationStructureMotionInstanceFlagsNV flags; - VkAccelerationStructureMotionInstanceDataNV data; -} VkAccelerationStructureMotionInstanceNV; - -typedef struct VkPhysicalDeviceRayTracingMotionBlurFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 rayTracingMotionBlur; - VkBool32 rayTracingMotionBlurPipelineTraceRaysIndirect; -} VkPhysicalDeviceRayTracingMotionBlurFeaturesNV; - - - -#define VK_EXT_ycbcr_2plane_444_formats 1 -#define VK_EXT_YCBCR_2PLANE_444_FORMATS_SPEC_VERSION 1 -#define VK_EXT_YCBCR_2PLANE_444_FORMATS_EXTENSION_NAME "VK_EXT_ycbcr_2plane_444_formats" -typedef struct VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 ycbcr2plane444Formats; -} VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT; - - - -#define VK_EXT_fragment_density_map2 1 -#define VK_EXT_FRAGMENT_DENSITY_MAP_2_SPEC_VERSION 1 -#define VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME "VK_EXT_fragment_density_map2" -typedef struct VkPhysicalDeviceFragmentDensityMap2FeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 fragmentDensityMapDeferred; -} VkPhysicalDeviceFragmentDensityMap2FeaturesEXT; - -typedef struct VkPhysicalDeviceFragmentDensityMap2PropertiesEXT { - VkStructureType sType; - void* pNext; - VkBool32 subsampledLoads; - VkBool32 subsampledCoarseReconstructionEarlyAccess; - uint32_t maxSubsampledArrayLayers; - uint32_t maxDescriptorSetSubsampledSamplers; -} VkPhysicalDeviceFragmentDensityMap2PropertiesEXT; - - - -#define VK_QCOM_rotated_copy_commands 1 -#define VK_QCOM_ROTATED_COPY_COMMANDS_SPEC_VERSION 1 -#define VK_QCOM_ROTATED_COPY_COMMANDS_EXTENSION_NAME "VK_QCOM_rotated_copy_commands" -typedef struct VkCopyCommandTransformInfoQCOM { - VkStructureType sType; - const void* pNext; - VkSurfaceTransformFlagBitsKHR transform; -} VkCopyCommandTransformInfoQCOM; - - - -#define VK_EXT_image_robustness 1 -#define VK_EXT_IMAGE_ROBUSTNESS_SPEC_VERSION 1 -#define VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_image_robustness" -typedef VkPhysicalDeviceImageRobustnessFeatures VkPhysicalDeviceImageRobustnessFeaturesEXT; - - - -#define VK_EXT_image_compression_control 1 -#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SPEC_VERSION 1 -#define VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME "VK_EXT_image_compression_control" - -typedef enum VkImageCompressionFlagBitsEXT { - VK_IMAGE_COMPRESSION_DEFAULT_EXT = 0, - VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT = 0x00000001, - VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT = 0x00000002, - VK_IMAGE_COMPRESSION_DISABLED_EXT = 0x00000004, - VK_IMAGE_COMPRESSION_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkImageCompressionFlagBitsEXT; -typedef VkFlags VkImageCompressionFlagsEXT; - -typedef enum VkImageCompressionFixedRateFlagBitsEXT { - VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT = 0, - VK_IMAGE_COMPRESSION_FIXED_RATE_1BPC_BIT_EXT = 0x00000001, - VK_IMAGE_COMPRESSION_FIXED_RATE_2BPC_BIT_EXT = 0x00000002, - VK_IMAGE_COMPRESSION_FIXED_RATE_3BPC_BIT_EXT = 0x00000004, - VK_IMAGE_COMPRESSION_FIXED_RATE_4BPC_BIT_EXT = 0x00000008, - VK_IMAGE_COMPRESSION_FIXED_RATE_5BPC_BIT_EXT = 0x00000010, - VK_IMAGE_COMPRESSION_FIXED_RATE_6BPC_BIT_EXT = 0x00000020, - VK_IMAGE_COMPRESSION_FIXED_RATE_7BPC_BIT_EXT = 0x00000040, - VK_IMAGE_COMPRESSION_FIXED_RATE_8BPC_BIT_EXT = 0x00000080, - VK_IMAGE_COMPRESSION_FIXED_RATE_9BPC_BIT_EXT = 0x00000100, - VK_IMAGE_COMPRESSION_FIXED_RATE_10BPC_BIT_EXT = 0x00000200, - VK_IMAGE_COMPRESSION_FIXED_RATE_11BPC_BIT_EXT = 0x00000400, - VK_IMAGE_COMPRESSION_FIXED_RATE_12BPC_BIT_EXT = 0x00000800, - VK_IMAGE_COMPRESSION_FIXED_RATE_13BPC_BIT_EXT = 0x00001000, - VK_IMAGE_COMPRESSION_FIXED_RATE_14BPC_BIT_EXT = 0x00002000, - VK_IMAGE_COMPRESSION_FIXED_RATE_15BPC_BIT_EXT = 0x00004000, - VK_IMAGE_COMPRESSION_FIXED_RATE_16BPC_BIT_EXT = 0x00008000, - VK_IMAGE_COMPRESSION_FIXED_RATE_17BPC_BIT_EXT = 0x00010000, - VK_IMAGE_COMPRESSION_FIXED_RATE_18BPC_BIT_EXT = 0x00020000, - VK_IMAGE_COMPRESSION_FIXED_RATE_19BPC_BIT_EXT = 0x00040000, - VK_IMAGE_COMPRESSION_FIXED_RATE_20BPC_BIT_EXT = 0x00080000, - VK_IMAGE_COMPRESSION_FIXED_RATE_21BPC_BIT_EXT = 0x00100000, - VK_IMAGE_COMPRESSION_FIXED_RATE_22BPC_BIT_EXT = 0x00200000, - VK_IMAGE_COMPRESSION_FIXED_RATE_23BPC_BIT_EXT = 0x00400000, - VK_IMAGE_COMPRESSION_FIXED_RATE_24BPC_BIT_EXT = 0x00800000, - VK_IMAGE_COMPRESSION_FIXED_RATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkImageCompressionFixedRateFlagBitsEXT; -typedef VkFlags VkImageCompressionFixedRateFlagsEXT; -typedef struct VkPhysicalDeviceImageCompressionControlFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 imageCompressionControl; -} VkPhysicalDeviceImageCompressionControlFeaturesEXT; - -typedef struct VkImageCompressionControlEXT { - VkStructureType sType; - const void* pNext; - VkImageCompressionFlagsEXT flags; - uint32_t compressionControlPlaneCount; - VkImageCompressionFixedRateFlagsEXT* pFixedRateFlags; -} VkImageCompressionControlEXT; - -typedef struct VkSubresourceLayout2EXT { - VkStructureType sType; - void* pNext; - VkSubresourceLayout subresourceLayout; -} VkSubresourceLayout2EXT; - -typedef struct VkImageSubresource2EXT { - VkStructureType sType; - void* pNext; - VkImageSubresource imageSubresource; -} VkImageSubresource2EXT; - -typedef struct VkImageCompressionPropertiesEXT { - VkStructureType sType; - void* pNext; - VkImageCompressionFlagsEXT imageCompressionFlags; - VkImageCompressionFixedRateFlagsEXT imageCompressionFixedRateFlags; -} VkImageCompressionPropertiesEXT; - -typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout2EXT)(VkDevice device, VkImage image, const VkImageSubresource2EXT* pSubresource, VkSubresourceLayout2EXT* pLayout); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout2EXT( - VkDevice device, - VkImage image, - const VkImageSubresource2EXT* pSubresource, - VkSubresourceLayout2EXT* pLayout); -#endif - - -#define VK_EXT_attachment_feedback_loop_layout 1 -#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_SPEC_VERSION 2 -#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME "VK_EXT_attachment_feedback_loop_layout" -typedef struct VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 attachmentFeedbackLoopLayout; -} VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT; - - - -#define VK_EXT_4444_formats 1 -#define VK_EXT_4444_FORMATS_SPEC_VERSION 1 -#define VK_EXT_4444_FORMATS_EXTENSION_NAME "VK_EXT_4444_formats" -typedef struct VkPhysicalDevice4444FormatsFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 formatA4R4G4B4; - VkBool32 formatA4B4G4R4; -} VkPhysicalDevice4444FormatsFeaturesEXT; - - - -#define VK_ARM_rasterization_order_attachment_access 1 -#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_SPEC_VERSION 1 -#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME "VK_ARM_rasterization_order_attachment_access" -typedef struct VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM { - VkStructureType sType; - void* pNext; - VkBool32 rasterizationOrderColorAttachmentAccess; - VkBool32 rasterizationOrderDepthAttachmentAccess; - VkBool32 rasterizationOrderStencilAttachmentAccess; -} VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM; - - - -#define VK_EXT_rgba10x6_formats 1 -#define VK_EXT_RGBA10X6_FORMATS_SPEC_VERSION 1 -#define VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME "VK_EXT_rgba10x6_formats" -typedef struct VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 formatRgba10x6WithoutYCbCrSampler; -} VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT; - - - -#define VK_NV_acquire_winrt_display 1 -#define VK_NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION 1 -#define VK_NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME "VK_NV_acquire_winrt_display" -typedef VkResult (VKAPI_PTR *PFN_vkAcquireWinrtDisplayNV)(VkPhysicalDevice physicalDevice, VkDisplayKHR display); -typedef VkResult (VKAPI_PTR *PFN_vkGetWinrtDisplayNV)(VkPhysicalDevice physicalDevice, uint32_t deviceRelativeId, VkDisplayKHR* pDisplay); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkAcquireWinrtDisplayNV( - VkPhysicalDevice physicalDevice, - VkDisplayKHR display); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetWinrtDisplayNV( - VkPhysicalDevice physicalDevice, - uint32_t deviceRelativeId, - VkDisplayKHR* pDisplay); -#endif - - -#define VK_VALVE_mutable_descriptor_type 1 -#define VK_VALVE_MUTABLE_DESCRIPTOR_TYPE_SPEC_VERSION 1 -#define VK_VALVE_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME "VK_VALVE_mutable_descriptor_type" -typedef struct VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE { - VkStructureType sType; - void* pNext; - VkBool32 mutableDescriptorType; -} VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE; - -typedef struct VkMutableDescriptorTypeListVALVE { - uint32_t descriptorTypeCount; - const VkDescriptorType* pDescriptorTypes; -} VkMutableDescriptorTypeListVALVE; - -typedef struct VkMutableDescriptorTypeCreateInfoVALVE { - VkStructureType sType; - const void* pNext; - uint32_t mutableDescriptorTypeListCount; - const VkMutableDescriptorTypeListVALVE* pMutableDescriptorTypeLists; -} VkMutableDescriptorTypeCreateInfoVALVE; - - - -#define VK_EXT_vertex_input_dynamic_state 1 -#define VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_SPEC_VERSION 2 -#define VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME "VK_EXT_vertex_input_dynamic_state" -typedef struct VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 vertexInputDynamicState; -} VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT; - -typedef struct VkVertexInputBindingDescription2EXT { - VkStructureType sType; - void* pNext; - uint32_t binding; - uint32_t stride; - VkVertexInputRate inputRate; - uint32_t divisor; -} VkVertexInputBindingDescription2EXT; - -typedef struct VkVertexInputAttributeDescription2EXT { - VkStructureType sType; - void* pNext; - uint32_t location; - uint32_t binding; - VkFormat format; - uint32_t offset; -} VkVertexInputAttributeDescription2EXT; - -typedef void (VKAPI_PTR *PFN_vkCmdSetVertexInputEXT)(VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount, const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions, uint32_t vertexAttributeDescriptionCount, const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetVertexInputEXT( - VkCommandBuffer commandBuffer, - uint32_t vertexBindingDescriptionCount, - const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions, - uint32_t vertexAttributeDescriptionCount, - const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions); -#endif - - -#define VK_EXT_physical_device_drm 1 -#define VK_EXT_PHYSICAL_DEVICE_DRM_SPEC_VERSION 1 -#define VK_EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME "VK_EXT_physical_device_drm" -typedef struct VkPhysicalDeviceDrmPropertiesEXT { - VkStructureType sType; - void* pNext; - VkBool32 hasPrimary; - VkBool32 hasRender; - int64_t primaryMajor; - int64_t primaryMinor; - int64_t renderMajor; - int64_t renderMinor; -} VkPhysicalDeviceDrmPropertiesEXT; - - - -#define VK_EXT_depth_clip_control 1 -#define VK_EXT_DEPTH_CLIP_CONTROL_SPEC_VERSION 1 -#define VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME "VK_EXT_depth_clip_control" -typedef struct VkPhysicalDeviceDepthClipControlFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 depthClipControl; -} VkPhysicalDeviceDepthClipControlFeaturesEXT; - -typedef struct VkPipelineViewportDepthClipControlCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkBool32 negativeOneToOne; -} VkPipelineViewportDepthClipControlCreateInfoEXT; - - - -#define VK_EXT_primitive_topology_list_restart 1 -#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION 1 -#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME "VK_EXT_primitive_topology_list_restart" -typedef struct VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 primitiveTopologyListRestart; - VkBool32 primitiveTopologyPatchListRestart; -} VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT; - - - -#define VK_HUAWEI_subpass_shading 1 -#define VK_HUAWEI_SUBPASS_SHADING_SPEC_VERSION 2 -#define VK_HUAWEI_SUBPASS_SHADING_EXTENSION_NAME "VK_HUAWEI_subpass_shading" -typedef struct VkSubpassShadingPipelineCreateInfoHUAWEI { - VkStructureType sType; - void* pNext; - VkRenderPass renderPass; - uint32_t subpass; -} VkSubpassShadingPipelineCreateInfoHUAWEI; - -typedef struct VkPhysicalDeviceSubpassShadingFeaturesHUAWEI { - VkStructureType sType; - void* pNext; - VkBool32 subpassShading; -} VkPhysicalDeviceSubpassShadingFeaturesHUAWEI; - -typedef struct VkPhysicalDeviceSubpassShadingPropertiesHUAWEI { - VkStructureType sType; - void* pNext; - uint32_t maxSubpassShadingWorkgroupSizeAspectRatio; -} VkPhysicalDeviceSubpassShadingPropertiesHUAWEI; - -typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)(VkDevice device, VkRenderPass renderpass, VkExtent2D* pMaxWorkgroupSize); -typedef void (VKAPI_PTR *PFN_vkCmdSubpassShadingHUAWEI)(VkCommandBuffer commandBuffer); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI( - VkDevice device, - VkRenderPass renderpass, - VkExtent2D* pMaxWorkgroupSize); - -VKAPI_ATTR void VKAPI_CALL vkCmdSubpassShadingHUAWEI( - VkCommandBuffer commandBuffer); -#endif - - -#define VK_HUAWEI_invocation_mask 1 -#define VK_HUAWEI_INVOCATION_MASK_SPEC_VERSION 1 -#define VK_HUAWEI_INVOCATION_MASK_EXTENSION_NAME "VK_HUAWEI_invocation_mask" -typedef struct VkPhysicalDeviceInvocationMaskFeaturesHUAWEI { - VkStructureType sType; - void* pNext; - VkBool32 invocationMask; -} VkPhysicalDeviceInvocationMaskFeaturesHUAWEI; - -typedef void (VKAPI_PTR *PFN_vkCmdBindInvocationMaskHUAWEI)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdBindInvocationMaskHUAWEI( - VkCommandBuffer commandBuffer, - VkImageView imageView, - VkImageLayout imageLayout); -#endif - - -#define VK_NV_external_memory_rdma 1 -typedef void* VkRemoteAddressNV; -#define VK_NV_EXTERNAL_MEMORY_RDMA_SPEC_VERSION 1 -#define VK_NV_EXTERNAL_MEMORY_RDMA_EXTENSION_NAME "VK_NV_external_memory_rdma" -typedef struct VkMemoryGetRemoteAddressInfoNV { - VkStructureType sType; - const void* pNext; - VkDeviceMemory memory; - VkExternalMemoryHandleTypeFlagBits handleType; -} VkMemoryGetRemoteAddressInfoNV; - -typedef struct VkPhysicalDeviceExternalMemoryRDMAFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 externalMemoryRDMA; -} VkPhysicalDeviceExternalMemoryRDMAFeaturesNV; - -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryRemoteAddressNV)(VkDevice device, const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo, VkRemoteAddressNV* pAddress); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryRemoteAddressNV( - VkDevice device, - const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo, - VkRemoteAddressNV* pAddress); -#endif - - -#define VK_EXT_pipeline_properties 1 -#define VK_EXT_PIPELINE_PROPERTIES_SPEC_VERSION 1 -#define VK_EXT_PIPELINE_PROPERTIES_EXTENSION_NAME "VK_EXT_pipeline_properties" -typedef VkPipelineInfoKHR VkPipelineInfoEXT; - -typedef struct VkPipelinePropertiesIdentifierEXT { - VkStructureType sType; - void* pNext; - uint8_t pipelineIdentifier[VK_UUID_SIZE]; -} VkPipelinePropertiesIdentifierEXT; - -typedef struct VkPhysicalDevicePipelinePropertiesFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 pipelinePropertiesIdentifier; -} VkPhysicalDevicePipelinePropertiesFeaturesEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPipelinePropertiesEXT)(VkDevice device, const VkPipelineInfoEXT* pPipelineInfo, VkBaseOutStructure* pPipelineProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelinePropertiesEXT( - VkDevice device, - const VkPipelineInfoEXT* pPipelineInfo, - VkBaseOutStructure* pPipelineProperties); -#endif - - -#define VK_EXT_multisampled_render_to_single_sampled 1 -#define VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_SPEC_VERSION 1 -#define VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME "VK_EXT_multisampled_render_to_single_sampled" -typedef struct VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 multisampledRenderToSingleSampled; -} VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT; - -typedef struct VkSubpassResolvePerformanceQueryEXT { - VkStructureType sType; - void* pNext; - VkBool32 optimal; -} VkSubpassResolvePerformanceQueryEXT; - -typedef struct VkMultisampledRenderToSingleSampledInfoEXT { - VkStructureType sType; - const void* pNext; - VkBool32 multisampledRenderToSingleSampledEnable; - VkSampleCountFlagBits rasterizationSamples; -} VkMultisampledRenderToSingleSampledInfoEXT; - - - -#define VK_EXT_extended_dynamic_state2 1 -#define VK_EXT_EXTENDED_DYNAMIC_STATE_2_SPEC_VERSION 1 -#define VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME "VK_EXT_extended_dynamic_state2" -typedef struct VkPhysicalDeviceExtendedDynamicState2FeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 extendedDynamicState2; - VkBool32 extendedDynamicState2LogicOp; - VkBool32 extendedDynamicState2PatchControlPoints; -} VkPhysicalDeviceExtendedDynamicState2FeaturesEXT; - -typedef void (VKAPI_PTR *PFN_vkCmdSetPatchControlPointsEXT)(VkCommandBuffer commandBuffer, uint32_t patchControlPoints); -typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizerDiscardEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBiasEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); -typedef void (VKAPI_PTR *PFN_vkCmdSetLogicOpEXT)(VkCommandBuffer commandBuffer, VkLogicOp logicOp); -typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetPatchControlPointsEXT( - VkCommandBuffer commandBuffer, - uint32_t patchControlPoints); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnableEXT( - VkCommandBuffer commandBuffer, - VkBool32 rasterizerDiscardEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnableEXT( - VkCommandBuffer commandBuffer, - VkBool32 depthBiasEnable); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetLogicOpEXT( - VkCommandBuffer commandBuffer, - VkLogicOp logicOp); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnableEXT( - VkCommandBuffer commandBuffer, - VkBool32 primitiveRestartEnable); -#endif - - -#define VK_EXT_color_write_enable 1 -#define VK_EXT_COLOR_WRITE_ENABLE_SPEC_VERSION 1 -#define VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME "VK_EXT_color_write_enable" -typedef struct VkPhysicalDeviceColorWriteEnableFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 colorWriteEnable; -} VkPhysicalDeviceColorWriteEnableFeaturesEXT; - -typedef struct VkPipelineColorWriteCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t attachmentCount; - const VkBool32* pColorWriteEnables; -} VkPipelineColorWriteCreateInfoEXT; - -typedef void (VKAPI_PTR *PFN_vkCmdSetColorWriteEnableEXT)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkBool32* pColorWriteEnables); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWriteEnableEXT( - VkCommandBuffer commandBuffer, - uint32_t attachmentCount, - const VkBool32* pColorWriteEnables); -#endif - - -#define VK_EXT_primitives_generated_query 1 -#define VK_EXT_PRIMITIVES_GENERATED_QUERY_SPEC_VERSION 1 -#define VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME "VK_EXT_primitives_generated_query" -typedef struct VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 primitivesGeneratedQuery; - VkBool32 primitivesGeneratedQueryWithRasterizerDiscard; - VkBool32 primitivesGeneratedQueryWithNonZeroStreams; -} VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT; - - - -#define VK_EXT_global_priority_query 1 -#define VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION 1 -#define VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME "VK_EXT_global_priority_query" -#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT VK_MAX_GLOBAL_PRIORITY_SIZE_KHR -typedef VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; - -typedef VkQueueFamilyGlobalPriorityPropertiesKHR VkQueueFamilyGlobalPriorityPropertiesEXT; - - - -#define VK_EXT_image_view_min_lod 1 -#define VK_EXT_IMAGE_VIEW_MIN_LOD_SPEC_VERSION 1 -#define VK_EXT_IMAGE_VIEW_MIN_LOD_EXTENSION_NAME "VK_EXT_image_view_min_lod" -typedef struct VkPhysicalDeviceImageViewMinLodFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 minLod; -} VkPhysicalDeviceImageViewMinLodFeaturesEXT; - -typedef struct VkImageViewMinLodCreateInfoEXT { - VkStructureType sType; - const void* pNext; - float minLod; -} VkImageViewMinLodCreateInfoEXT; - - - -#define VK_EXT_multi_draw 1 -#define VK_EXT_MULTI_DRAW_SPEC_VERSION 1 -#define VK_EXT_MULTI_DRAW_EXTENSION_NAME "VK_EXT_multi_draw" -typedef struct VkPhysicalDeviceMultiDrawFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 multiDraw; -} VkPhysicalDeviceMultiDrawFeaturesEXT; - -typedef struct VkPhysicalDeviceMultiDrawPropertiesEXT { - VkStructureType sType; - void* pNext; - uint32_t maxMultiDrawCount; -} VkPhysicalDeviceMultiDrawPropertiesEXT; - -typedef struct VkMultiDrawInfoEXT { - uint32_t firstVertex; - uint32_t vertexCount; -} VkMultiDrawInfoEXT; - -typedef struct VkMultiDrawIndexedInfoEXT { - uint32_t firstIndex; - uint32_t indexCount; - int32_t vertexOffset; -} VkMultiDrawIndexedInfoEXT; - -typedef void (VKAPI_PTR *PFN_vkCmdDrawMultiEXT)(VkCommandBuffer commandBuffer, uint32_t drawCount, const VkMultiDrawInfoEXT* pVertexInfo, uint32_t instanceCount, uint32_t firstInstance, uint32_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdDrawMultiIndexedEXT)(VkCommandBuffer commandBuffer, uint32_t drawCount, const VkMultiDrawIndexedInfoEXT* pIndexInfo, uint32_t instanceCount, uint32_t firstInstance, uint32_t stride, const int32_t* pVertexOffset); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiEXT( - VkCommandBuffer commandBuffer, - uint32_t drawCount, - const VkMultiDrawInfoEXT* pVertexInfo, - uint32_t instanceCount, - uint32_t firstInstance, - uint32_t stride); - -VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT( - VkCommandBuffer commandBuffer, - uint32_t drawCount, - const VkMultiDrawIndexedInfoEXT* pIndexInfo, - uint32_t instanceCount, - uint32_t firstInstance, - uint32_t stride, - const int32_t* pVertexOffset); -#endif - - -#define VK_EXT_image_2d_view_of_3d 1 -#define VK_EXT_IMAGE_2D_VIEW_OF_3D_SPEC_VERSION 1 -#define VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME "VK_EXT_image_2d_view_of_3d" -typedef struct VkPhysicalDeviceImage2DViewOf3DFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 image2DViewOf3D; - VkBool32 sampler2DViewOf3D; -} VkPhysicalDeviceImage2DViewOf3DFeaturesEXT; - - - -#define VK_EXT_load_store_op_none 1 -#define VK_EXT_LOAD_STORE_OP_NONE_SPEC_VERSION 1 -#define VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_EXT_load_store_op_none" - - -#define VK_EXT_border_color_swizzle 1 -#define VK_EXT_BORDER_COLOR_SWIZZLE_SPEC_VERSION 1 -#define VK_EXT_BORDER_COLOR_SWIZZLE_EXTENSION_NAME "VK_EXT_border_color_swizzle" -typedef struct VkPhysicalDeviceBorderColorSwizzleFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 borderColorSwizzle; - VkBool32 borderColorSwizzleFromImage; -} VkPhysicalDeviceBorderColorSwizzleFeaturesEXT; - -typedef struct VkSamplerBorderColorComponentMappingCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkComponentMapping components; - VkBool32 srgb; -} VkSamplerBorderColorComponentMappingCreateInfoEXT; - - - -#define VK_EXT_pageable_device_local_memory 1 -#define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_SPEC_VERSION 1 -#define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME "VK_EXT_pageable_device_local_memory" -typedef struct VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 pageableDeviceLocalMemory; -} VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT; - -typedef void (VKAPI_PTR *PFN_vkSetDeviceMemoryPriorityEXT)(VkDevice device, VkDeviceMemory memory, float priority); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkSetDeviceMemoryPriorityEXT( - VkDevice device, - VkDeviceMemory memory, - float priority); -#endif - - -#define VK_VALVE_descriptor_set_host_mapping 1 -#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_SPEC_VERSION 1 -#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_EXTENSION_NAME "VK_VALVE_descriptor_set_host_mapping" -typedef struct VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE { - VkStructureType sType; - void* pNext; - VkBool32 descriptorSetHostMapping; -} VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE; - -typedef struct VkDescriptorSetBindingReferenceVALVE { - VkStructureType sType; - const void* pNext; - VkDescriptorSetLayout descriptorSetLayout; - uint32_t binding; -} VkDescriptorSetBindingReferenceVALVE; - -typedef struct VkDescriptorSetLayoutHostMappingInfoVALVE { - VkStructureType sType; - void* pNext; - size_t descriptorOffset; - uint32_t descriptorSize; -} VkDescriptorSetLayoutHostMappingInfoVALVE; - -typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE)(VkDevice device, const VkDescriptorSetBindingReferenceVALVE* pBindingReference, VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping); -typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetHostMappingVALVE)(VkDevice device, VkDescriptorSet descriptorSet, void** ppData); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutHostMappingInfoVALVE( - VkDevice device, - const VkDescriptorSetBindingReferenceVALVE* pBindingReference, - VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping); - -VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetHostMappingVALVE( - VkDevice device, - VkDescriptorSet descriptorSet, - void** ppData); -#endif - - -#define VK_EXT_non_seamless_cube_map 1 -#define VK_EXT_NON_SEAMLESS_CUBE_MAP_SPEC_VERSION 1 -#define VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME "VK_EXT_non_seamless_cube_map" -typedef struct VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 nonSeamlessCubeMap; -} VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT; - - - -#define VK_QCOM_fragment_density_map_offset 1 -#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION 1 -#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME "VK_QCOM_fragment_density_map_offset" -typedef struct VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM { - VkStructureType sType; - void* pNext; - VkBool32 fragmentDensityMapOffset; -} VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM; - -typedef struct VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM { - VkStructureType sType; - void* pNext; - VkExtent2D fragmentDensityOffsetGranularity; -} VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM; - -typedef struct VkSubpassFragmentDensityMapOffsetEndInfoQCOM { - VkStructureType sType; - const void* pNext; - uint32_t fragmentDensityOffsetCount; - const VkOffset2D* pFragmentDensityOffsets; -} VkSubpassFragmentDensityMapOffsetEndInfoQCOM; - - - -#define VK_NV_linear_color_attachment 1 -#define VK_NV_LINEAR_COLOR_ATTACHMENT_SPEC_VERSION 1 -#define VK_NV_LINEAR_COLOR_ATTACHMENT_EXTENSION_NAME "VK_NV_linear_color_attachment" -typedef struct VkPhysicalDeviceLinearColorAttachmentFeaturesNV { - VkStructureType sType; - void* pNext; - VkBool32 linearColorAttachment; -} VkPhysicalDeviceLinearColorAttachmentFeaturesNV; - - - -#define VK_GOOGLE_surfaceless_query 1 -#define VK_GOOGLE_SURFACELESS_QUERY_SPEC_VERSION 1 -#define VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME "VK_GOOGLE_surfaceless_query" - - -#define VK_EXT_image_compression_control_swapchain 1 -#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_SPEC_VERSION 1 -#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME "VK_EXT_image_compression_control_swapchain" -typedef struct VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 imageCompressionControlSwapchain; -} VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT; - - - -#define VK_QCOM_image_processing 1 -#define VK_QCOM_IMAGE_PROCESSING_SPEC_VERSION 1 -#define VK_QCOM_IMAGE_PROCESSING_EXTENSION_NAME "VK_QCOM_image_processing" -typedef struct VkImageViewSampleWeightCreateInfoQCOM { - VkStructureType sType; - const void* pNext; - VkOffset2D filterCenter; - VkExtent2D filterSize; - uint32_t numPhases; -} VkImageViewSampleWeightCreateInfoQCOM; - -typedef struct VkPhysicalDeviceImageProcessingFeaturesQCOM { - VkStructureType sType; - void* pNext; - VkBool32 textureSampleWeighted; - VkBool32 textureBoxFilter; - VkBool32 textureBlockMatch; -} VkPhysicalDeviceImageProcessingFeaturesQCOM; - -typedef struct VkPhysicalDeviceImageProcessingPropertiesQCOM { - VkStructureType sType; - void* pNext; - uint32_t maxWeightFilterPhases; - VkExtent2D maxWeightFilterDimension; - VkExtent2D maxBlockMatchRegion; - VkExtent2D maxBoxFilterBlockSize; -} VkPhysicalDeviceImageProcessingPropertiesQCOM; - - - -#define VK_EXT_subpass_merge_feedback 1 -#define VK_EXT_SUBPASS_MERGE_FEEDBACK_SPEC_VERSION 2 -#define VK_EXT_SUBPASS_MERGE_FEEDBACK_EXTENSION_NAME "VK_EXT_subpass_merge_feedback" - -typedef enum VkSubpassMergeStatusEXT { - VK_SUBPASS_MERGE_STATUS_MERGED_EXT = 0, - VK_SUBPASS_MERGE_STATUS_DISALLOWED_EXT = 1, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SIDE_EFFECTS_EXT = 2, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SAMPLES_MISMATCH_EXT = 3, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_VIEWS_MISMATCH_EXT = 4, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_ALIASING_EXT = 5, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPENDENCIES_EXT = 6, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INCOMPATIBLE_INPUT_ATTACHMENT_EXT = 7, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_TOO_MANY_ATTACHMENTS_EXT = 8, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INSUFFICIENT_STORAGE_EXT = 9, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPTH_STENCIL_COUNT_EXT = 10, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_RESOLVE_ATTACHMENT_REUSE_EXT = 11, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SINGLE_SUBPASS_EXT = 12, - VK_SUBPASS_MERGE_STATUS_NOT_MERGED_UNSPECIFIED_EXT = 13, - VK_SUBPASS_MERGE_STATUS_MAX_ENUM_EXT = 0x7FFFFFFF -} VkSubpassMergeStatusEXT; -typedef struct VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 subpassMergeFeedback; -} VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT; - -typedef struct VkRenderPassCreationControlEXT { - VkStructureType sType; - const void* pNext; - VkBool32 disallowMerging; -} VkRenderPassCreationControlEXT; - -typedef struct VkRenderPassCreationFeedbackInfoEXT { - uint32_t postMergeSubpassCount; -} VkRenderPassCreationFeedbackInfoEXT; - -typedef struct VkRenderPassCreationFeedbackCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkRenderPassCreationFeedbackInfoEXT* pRenderPassFeedback; -} VkRenderPassCreationFeedbackCreateInfoEXT; - -typedef struct VkRenderPassSubpassFeedbackInfoEXT { - VkSubpassMergeStatusEXT subpassMergeStatus; - char description[VK_MAX_DESCRIPTION_SIZE]; - uint32_t postMergeIndex; -} VkRenderPassSubpassFeedbackInfoEXT; - -typedef struct VkRenderPassSubpassFeedbackCreateInfoEXT { - VkStructureType sType; - const void* pNext; - VkRenderPassSubpassFeedbackInfoEXT* pSubpassFeedback; -} VkRenderPassSubpassFeedbackCreateInfoEXT; - - - -#define VK_EXT_shader_module_identifier 1 -#define VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT 32U -#define VK_EXT_SHADER_MODULE_IDENTIFIER_SPEC_VERSION 1 -#define VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME "VK_EXT_shader_module_identifier" -typedef struct VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT { - VkStructureType sType; - void* pNext; - VkBool32 shaderModuleIdentifier; -} VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT; - -typedef struct VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT { - VkStructureType sType; - void* pNext; - uint8_t shaderModuleIdentifierAlgorithmUUID[VK_UUID_SIZE]; -} VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT; - -typedef struct VkPipelineShaderStageModuleIdentifierCreateInfoEXT { - VkStructureType sType; - const void* pNext; - uint32_t identifierSize; - const uint8_t* pIdentifier; -} VkPipelineShaderStageModuleIdentifierCreateInfoEXT; - -typedef struct VkShaderModuleIdentifierEXT { - VkStructureType sType; - void* pNext; - uint32_t identifierSize; - uint8_t identifier[VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT]; -} VkShaderModuleIdentifierEXT; - -typedef void (VKAPI_PTR *PFN_vkGetShaderModuleIdentifierEXT)(VkDevice device, VkShaderModule shaderModule, VkShaderModuleIdentifierEXT* pIdentifier); -typedef void (VKAPI_PTR *PFN_vkGetShaderModuleCreateInfoIdentifierEXT)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, VkShaderModuleIdentifierEXT* pIdentifier); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkGetShaderModuleIdentifierEXT( - VkDevice device, - VkShaderModule shaderModule, - VkShaderModuleIdentifierEXT* pIdentifier); - -VKAPI_ATTR void VKAPI_CALL vkGetShaderModuleCreateInfoIdentifierEXT( - VkDevice device, - const VkShaderModuleCreateInfo* pCreateInfo, - VkShaderModuleIdentifierEXT* pIdentifier); -#endif - - -#define VK_QCOM_tile_properties 1 -#define VK_QCOM_TILE_PROPERTIES_SPEC_VERSION 1 -#define VK_QCOM_TILE_PROPERTIES_EXTENSION_NAME "VK_QCOM_tile_properties" -typedef struct VkPhysicalDeviceTilePropertiesFeaturesQCOM { - VkStructureType sType; - void* pNext; - VkBool32 tileProperties; -} VkPhysicalDeviceTilePropertiesFeaturesQCOM; - -typedef struct VkTilePropertiesQCOM { - VkStructureType sType; - void* pNext; - VkExtent3D tileSize; - VkExtent2D apronSize; - VkOffset2D origin; -} VkTilePropertiesQCOM; - -typedef VkResult (VKAPI_PTR *PFN_vkGetFramebufferTilePropertiesQCOM)(VkDevice device, VkFramebuffer framebuffer, uint32_t* pPropertiesCount, VkTilePropertiesQCOM* pProperties); -typedef VkResult (VKAPI_PTR *PFN_vkGetDynamicRenderingTilePropertiesQCOM)(VkDevice device, const VkRenderingInfo* pRenderingInfo, VkTilePropertiesQCOM* pProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetFramebufferTilePropertiesQCOM( - VkDevice device, - VkFramebuffer framebuffer, - uint32_t* pPropertiesCount, - VkTilePropertiesQCOM* pProperties); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDynamicRenderingTilePropertiesQCOM( - VkDevice device, - const VkRenderingInfo* pRenderingInfo, - VkTilePropertiesQCOM* pProperties); -#endif - - -#define VK_SEC_amigo_profiling 1 -#define VK_SEC_AMIGO_PROFILING_SPEC_VERSION 1 -#define VK_SEC_AMIGO_PROFILING_EXTENSION_NAME "VK_SEC_amigo_profiling" -typedef struct VkPhysicalDeviceAmigoProfilingFeaturesSEC { - VkStructureType sType; - void* pNext; - VkBool32 amigoProfiling; -} VkPhysicalDeviceAmigoProfilingFeaturesSEC; - -typedef struct VkAmigoProfilingSubmitInfoSEC { - VkStructureType sType; - const void* pNext; - uint64_t firstDrawTimestamp; - uint64_t swapBufferTimestamp; -} VkAmigoProfilingSubmitInfoSEC; - - - -#define VK_KHR_acceleration_structure 1 -VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) -#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 -#define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure" - -typedef enum VkBuildAccelerationStructureModeKHR { - VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR = 0, - VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR = 1, - VK_BUILD_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkBuildAccelerationStructureModeKHR; - -typedef enum VkAccelerationStructureBuildTypeKHR { - VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR = 0, - VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR = 1, - VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_OR_DEVICE_KHR = 2, - VK_ACCELERATION_STRUCTURE_BUILD_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF -} VkAccelerationStructureBuildTypeKHR; - -typedef enum VkAccelerationStructureCompatibilityKHR { - VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR = 0, - VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR = 1, - VK_ACCELERATION_STRUCTURE_COMPATIBILITY_MAX_ENUM_KHR = 0x7FFFFFFF -} VkAccelerationStructureCompatibilityKHR; - -typedef enum VkAccelerationStructureCreateFlagBitsKHR { - VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 0x00000001, - VK_ACCELERATION_STRUCTURE_CREATE_MOTION_BIT_NV = 0x00000004, - VK_ACCELERATION_STRUCTURE_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF -} VkAccelerationStructureCreateFlagBitsKHR; -typedef VkFlags VkAccelerationStructureCreateFlagsKHR; -typedef union VkDeviceOrHostAddressKHR { - VkDeviceAddress deviceAddress; - void* hostAddress; -} VkDeviceOrHostAddressKHR; - -typedef struct VkAccelerationStructureBuildRangeInfoKHR { - uint32_t primitiveCount; - uint32_t primitiveOffset; - uint32_t firstVertex; - uint32_t transformOffset; -} VkAccelerationStructureBuildRangeInfoKHR; - -typedef struct VkAccelerationStructureGeometryTrianglesDataKHR { - VkStructureType sType; - const void* pNext; - VkFormat vertexFormat; - VkDeviceOrHostAddressConstKHR vertexData; - VkDeviceSize vertexStride; - uint32_t maxVertex; - VkIndexType indexType; - VkDeviceOrHostAddressConstKHR indexData; - VkDeviceOrHostAddressConstKHR transformData; -} VkAccelerationStructureGeometryTrianglesDataKHR; - -typedef struct VkAccelerationStructureGeometryAabbsDataKHR { - VkStructureType sType; - const void* pNext; - VkDeviceOrHostAddressConstKHR data; - VkDeviceSize stride; -} VkAccelerationStructureGeometryAabbsDataKHR; - -typedef struct VkAccelerationStructureGeometryInstancesDataKHR { - VkStructureType sType; - const void* pNext; - VkBool32 arrayOfPointers; - VkDeviceOrHostAddressConstKHR data; -} VkAccelerationStructureGeometryInstancesDataKHR; - -typedef union VkAccelerationStructureGeometryDataKHR { - VkAccelerationStructureGeometryTrianglesDataKHR triangles; - VkAccelerationStructureGeometryAabbsDataKHR aabbs; - VkAccelerationStructureGeometryInstancesDataKHR instances; -} VkAccelerationStructureGeometryDataKHR; - -typedef struct VkAccelerationStructureGeometryKHR { - VkStructureType sType; - const void* pNext; - VkGeometryTypeKHR geometryType; - VkAccelerationStructureGeometryDataKHR geometry; - VkGeometryFlagsKHR flags; -} VkAccelerationStructureGeometryKHR; - -typedef struct VkAccelerationStructureBuildGeometryInfoKHR { - VkStructureType sType; - const void* pNext; - VkAccelerationStructureTypeKHR type; - VkBuildAccelerationStructureFlagsKHR flags; - VkBuildAccelerationStructureModeKHR mode; - VkAccelerationStructureKHR srcAccelerationStructure; - VkAccelerationStructureKHR dstAccelerationStructure; - uint32_t geometryCount; - const VkAccelerationStructureGeometryKHR* pGeometries; - const VkAccelerationStructureGeometryKHR* const* ppGeometries; - VkDeviceOrHostAddressKHR scratchData; -} VkAccelerationStructureBuildGeometryInfoKHR; - -typedef struct VkAccelerationStructureCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkAccelerationStructureCreateFlagsKHR createFlags; - VkBuffer buffer; - VkDeviceSize offset; - VkDeviceSize size; - VkAccelerationStructureTypeKHR type; - VkDeviceAddress deviceAddress; -} VkAccelerationStructureCreateInfoKHR; - -typedef struct VkWriteDescriptorSetAccelerationStructureKHR { - VkStructureType sType; - const void* pNext; - uint32_t accelerationStructureCount; - const VkAccelerationStructureKHR* pAccelerationStructures; -} VkWriteDescriptorSetAccelerationStructureKHR; - -typedef struct VkPhysicalDeviceAccelerationStructureFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 accelerationStructure; - VkBool32 accelerationStructureCaptureReplay; - VkBool32 accelerationStructureIndirectBuild; - VkBool32 accelerationStructureHostCommands; - VkBool32 descriptorBindingAccelerationStructureUpdateAfterBind; -} VkPhysicalDeviceAccelerationStructureFeaturesKHR; - -typedef struct VkPhysicalDeviceAccelerationStructurePropertiesKHR { - VkStructureType sType; - void* pNext; - uint64_t maxGeometryCount; - uint64_t maxInstanceCount; - uint64_t maxPrimitiveCount; - uint32_t maxPerStageDescriptorAccelerationStructures; - uint32_t maxPerStageDescriptorUpdateAfterBindAccelerationStructures; - uint32_t maxDescriptorSetAccelerationStructures; - uint32_t maxDescriptorSetUpdateAfterBindAccelerationStructures; - uint32_t minAccelerationStructureScratchOffsetAlignment; -} VkPhysicalDeviceAccelerationStructurePropertiesKHR; - -typedef struct VkAccelerationStructureDeviceAddressInfoKHR { - VkStructureType sType; - const void* pNext; - VkAccelerationStructureKHR accelerationStructure; -} VkAccelerationStructureDeviceAddressInfoKHR; - -typedef struct VkAccelerationStructureVersionInfoKHR { - VkStructureType sType; - const void* pNext; - const uint8_t* pVersionData; -} VkAccelerationStructureVersionInfoKHR; - -typedef struct VkCopyAccelerationStructureToMemoryInfoKHR { - VkStructureType sType; - const void* pNext; - VkAccelerationStructureKHR src; - VkDeviceOrHostAddressKHR dst; - VkCopyAccelerationStructureModeKHR mode; -} VkCopyAccelerationStructureToMemoryInfoKHR; - -typedef struct VkCopyMemoryToAccelerationStructureInfoKHR { - VkStructureType sType; - const void* pNext; - VkDeviceOrHostAddressConstKHR src; - VkAccelerationStructureKHR dst; - VkCopyAccelerationStructureModeKHR mode; -} VkCopyMemoryToAccelerationStructureInfoKHR; - -typedef struct VkCopyAccelerationStructureInfoKHR { - VkStructureType sType; - const void* pNext; - VkAccelerationStructureKHR src; - VkAccelerationStructureKHR dst; - VkCopyAccelerationStructureModeKHR mode; -} VkCopyAccelerationStructureInfoKHR; - -typedef struct VkAccelerationStructureBuildSizesInfoKHR { - VkStructureType sType; - const void* pNext; - VkDeviceSize accelerationStructureSize; - VkDeviceSize updateScratchSize; - VkDeviceSize buildScratchSize; -} VkAccelerationStructureBuildSizesInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureKHR)(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure); -typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureKHR)(VkDevice device, VkAccelerationStructureKHR accelerationStructure, const VkAllocationCallbacks* pAllocator); -typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructuresKHR)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); -typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructuresIndirectKHR)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkDeviceAddress* pIndirectDeviceAddresses, const uint32_t* pIndirectStrides, const uint32_t* const* ppMaxPrimitiveCounts); -typedef VkResult (VKAPI_PTR *PFN_vkBuildAccelerationStructuresKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); -typedef VkResult (VKAPI_PTR *PFN_vkCopyAccelerationStructureKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyAccelerationStructureInfoKHR* pInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCopyAccelerationStructureToMemoryKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); -typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToAccelerationStructureKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); -typedef VkResult (VKAPI_PTR *PFN_vkWriteAccelerationStructuresPropertiesKHR)(VkDevice device, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, size_t dataSize, void* pData, size_t stride); -typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureKHR)(VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureInfoKHR* pInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureToMemoryKHR)(VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); -typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToAccelerationStructureKHR)(VkCommandBuffer commandBuffer, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); -typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetAccelerationStructureDeviceAddressKHR)(VkDevice device, const VkAccelerationStructureDeviceAddressInfoKHR* pInfo); -typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesKHR)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); -typedef void (VKAPI_PTR *PFN_vkGetDeviceAccelerationStructureCompatibilityKHR)(VkDevice device, const VkAccelerationStructureVersionInfoKHR* pVersionInfo, VkAccelerationStructureCompatibilityKHR* pCompatibility); -typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureBuildSizesKHR)(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType, const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo, const uint32_t* pMaxPrimitiveCounts, VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureKHR( - VkDevice device, - const VkAccelerationStructureCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkAccelerationStructureKHR* pAccelerationStructure); - -VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureKHR( - VkDevice device, - VkAccelerationStructureKHR accelerationStructure, - const VkAllocationCallbacks* pAllocator); - -VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructuresKHR( - VkCommandBuffer commandBuffer, - uint32_t infoCount, - const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, - const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); - -VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructuresIndirectKHR( - VkCommandBuffer commandBuffer, - uint32_t infoCount, - const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, - const VkDeviceAddress* pIndirectDeviceAddresses, - const uint32_t* pIndirectStrides, - const uint32_t* const* ppMaxPrimitiveCounts); - -VKAPI_ATTR VkResult VKAPI_CALL vkBuildAccelerationStructuresKHR( - VkDevice device, - VkDeferredOperationKHR deferredOperation, - uint32_t infoCount, - const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, - const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); - -VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureKHR( - VkDevice device, - VkDeferredOperationKHR deferredOperation, - const VkCopyAccelerationStructureInfoKHR* pInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureToMemoryKHR( - VkDevice device, - VkDeferredOperationKHR deferredOperation, - const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToAccelerationStructureKHR( - VkDevice device, - VkDeferredOperationKHR deferredOperation, - const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkWriteAccelerationStructuresPropertiesKHR( - VkDevice device, - uint32_t accelerationStructureCount, - const VkAccelerationStructureKHR* pAccelerationStructures, - VkQueryType queryType, - size_t dataSize, - void* pData, - size_t stride); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureKHR( - VkCommandBuffer commandBuffer, - const VkCopyAccelerationStructureInfoKHR* pInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureToMemoryKHR( - VkCommandBuffer commandBuffer, - const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToAccelerationStructureKHR( - VkCommandBuffer commandBuffer, - const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); - -VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetAccelerationStructureDeviceAddressKHR( - VkDevice device, - const VkAccelerationStructureDeviceAddressInfoKHR* pInfo); - -VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesKHR( - VkCommandBuffer commandBuffer, - uint32_t accelerationStructureCount, - const VkAccelerationStructureKHR* pAccelerationStructures, - VkQueryType queryType, - VkQueryPool queryPool, - uint32_t firstQuery); - -VKAPI_ATTR void VKAPI_CALL vkGetDeviceAccelerationStructureCompatibilityKHR( - VkDevice device, - const VkAccelerationStructureVersionInfoKHR* pVersionInfo, - VkAccelerationStructureCompatibilityKHR* pCompatibility); - -VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureBuildSizesKHR( - VkDevice device, - VkAccelerationStructureBuildTypeKHR buildType, - const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo, - const uint32_t* pMaxPrimitiveCounts, - VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); -#endif - - -#define VK_KHR_ray_tracing_pipeline 1 -#define VK_KHR_RAY_TRACING_PIPELINE_SPEC_VERSION 1 -#define VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME "VK_KHR_ray_tracing_pipeline" - -typedef enum VkShaderGroupShaderKHR { - VK_SHADER_GROUP_SHADER_GENERAL_KHR = 0, - VK_SHADER_GROUP_SHADER_CLOSEST_HIT_KHR = 1, - VK_SHADER_GROUP_SHADER_ANY_HIT_KHR = 2, - VK_SHADER_GROUP_SHADER_INTERSECTION_KHR = 3, - VK_SHADER_GROUP_SHADER_MAX_ENUM_KHR = 0x7FFFFFFF -} VkShaderGroupShaderKHR; -typedef struct VkRayTracingShaderGroupCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkRayTracingShaderGroupTypeKHR type; - uint32_t generalShader; - uint32_t closestHitShader; - uint32_t anyHitShader; - uint32_t intersectionShader; - const void* pShaderGroupCaptureReplayHandle; -} VkRayTracingShaderGroupCreateInfoKHR; - -typedef struct VkRayTracingPipelineInterfaceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t maxPipelineRayPayloadSize; - uint32_t maxPipelineRayHitAttributeSize; -} VkRayTracingPipelineInterfaceCreateInfoKHR; - -typedef struct VkRayTracingPipelineCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkPipelineCreateFlags flags; - uint32_t stageCount; - const VkPipelineShaderStageCreateInfo* pStages; - uint32_t groupCount; - const VkRayTracingShaderGroupCreateInfoKHR* pGroups; - uint32_t maxPipelineRayRecursionDepth; - const VkPipelineLibraryCreateInfoKHR* pLibraryInfo; - const VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface; - const VkPipelineDynamicStateCreateInfo* pDynamicState; - VkPipelineLayout layout; - VkPipeline basePipelineHandle; - int32_t basePipelineIndex; -} VkRayTracingPipelineCreateInfoKHR; - -typedef struct VkPhysicalDeviceRayTracingPipelineFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 rayTracingPipeline; - VkBool32 rayTracingPipelineShaderGroupHandleCaptureReplay; - VkBool32 rayTracingPipelineShaderGroupHandleCaptureReplayMixed; - VkBool32 rayTracingPipelineTraceRaysIndirect; - VkBool32 rayTraversalPrimitiveCulling; -} VkPhysicalDeviceRayTracingPipelineFeaturesKHR; - -typedef struct VkPhysicalDeviceRayTracingPipelinePropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t shaderGroupHandleSize; - uint32_t maxRayRecursionDepth; - uint32_t maxShaderGroupStride; - uint32_t shaderGroupBaseAlignment; - uint32_t shaderGroupHandleCaptureReplaySize; - uint32_t maxRayDispatchInvocationCount; - uint32_t shaderGroupHandleAlignment; - uint32_t maxRayHitAttributeSize; -} VkPhysicalDeviceRayTracingPipelinePropertiesKHR; - -typedef struct VkStridedDeviceAddressRegionKHR { - VkDeviceAddress deviceAddress; - VkDeviceSize stride; - VkDeviceSize size; -} VkStridedDeviceAddressRegionKHR; - -typedef struct VkTraceRaysIndirectCommandKHR { - uint32_t width; - uint32_t height; - uint32_t depth; -} VkTraceRaysIndirectCommandKHR; - -typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysKHR)(VkCommandBuffer commandBuffer, const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, uint32_t width, uint32_t height, uint32_t depth); -typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); -typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); -typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysIndirectKHR)(VkCommandBuffer commandBuffer, const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, VkDeviceAddress indirectDeviceAddress); -typedef VkDeviceSize (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupStackSizeKHR)(VkDevice device, VkPipeline pipeline, uint32_t group, VkShaderGroupShaderKHR groupShader); -typedef void (VKAPI_PTR *PFN_vkCmdSetRayTracingPipelineStackSizeKHR)(VkCommandBuffer commandBuffer, uint32_t pipelineStackSize); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysKHR( - VkCommandBuffer commandBuffer, - const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, - const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, - const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, - const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, - uint32_t width, - uint32_t height, - uint32_t depth); - -VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesKHR( - VkDevice device, - VkDeferredOperationKHR deferredOperation, - VkPipelineCache pipelineCache, - uint32_t createInfoCount, - const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingCaptureReplayShaderGroupHandlesKHR( - VkDevice device, - VkPipeline pipeline, - uint32_t firstGroup, - uint32_t groupCount, - size_t dataSize, - void* pData); - -VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirectKHR( - VkCommandBuffer commandBuffer, - const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, - const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, - const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, - const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, - VkDeviceAddress indirectDeviceAddress); - -VKAPI_ATTR VkDeviceSize VKAPI_CALL vkGetRayTracingShaderGroupStackSizeKHR( - VkDevice device, - VkPipeline pipeline, - uint32_t group, - VkShaderGroupShaderKHR groupShader); - -VKAPI_ATTR void VKAPI_CALL vkCmdSetRayTracingPipelineStackSizeKHR( - VkCommandBuffer commandBuffer, - uint32_t pipelineStackSize); -#endif - - -#define VK_KHR_ray_query 1 -#define VK_KHR_RAY_QUERY_SPEC_VERSION 1 -#define VK_KHR_RAY_QUERY_EXTENSION_NAME "VK_KHR_ray_query" -typedef struct VkPhysicalDeviceRayQueryFeaturesKHR { - VkStructureType sType; - void* pNext; - VkBool32 rayQuery; -} VkPhysicalDeviceRayQueryFeaturesKHR; - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/vulkan/vulkan_win32.h b/include/vulkan/vulkan_win32.h deleted file mode 100644 index affe0c02a..000000000 --- a/include/vulkan/vulkan_win32.h +++ /dev/null @@ -1,315 +0,0 @@ -#ifndef VULKAN_WIN32_H_ -#define VULKAN_WIN32_H_ 1 - -/* -** Copyright 2015-2022 The Khronos Group Inc. -** -** SPDX-License-Identifier: Apache-2.0 -*/ - -/* -** This header is generated from the Khronos Vulkan XML API Registry. -** -*/ - - -#ifdef __cplusplus -extern "C" { -#endif - - - -#define VK_KHR_win32_surface 1 -#define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6 -#define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface" -typedef VkFlags VkWin32SurfaceCreateFlagsKHR; -typedef struct VkWin32SurfaceCreateInfoKHR { - VkStructureType sType; - const void* pNext; - VkWin32SurfaceCreateFlagsKHR flags; - HINSTANCE hinstance; - HWND hwnd; -} VkWin32SurfaceCreateInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); -typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkCreateWin32SurfaceKHR( - VkInstance instance, - const VkWin32SurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); - -VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex); -#endif - - -#define VK_KHR_external_memory_win32 1 -#define VK_KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_KHR_external_memory_win32" -typedef struct VkImportMemoryWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagBits handleType; - HANDLE handle; - LPCWSTR name; -} VkImportMemoryWin32HandleInfoKHR; - -typedef struct VkExportMemoryWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - const SECURITY_ATTRIBUTES* pAttributes; - DWORD dwAccess; - LPCWSTR name; -} VkExportMemoryWin32HandleInfoKHR; - -typedef struct VkMemoryWin32HandlePropertiesKHR { - VkStructureType sType; - void* pNext; - uint32_t memoryTypeBits; -} VkMemoryWin32HandlePropertiesKHR; - -typedef struct VkMemoryGetWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkDeviceMemory memory; - VkExternalMemoryHandleTypeFlagBits handleType; -} VkMemoryGetWin32HandleInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleKHR)(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandlePropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleKHR( - VkDevice device, - const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, - HANDLE* pHandle); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR( - VkDevice device, - VkExternalMemoryHandleTypeFlagBits handleType, - HANDLE handle, - VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties); -#endif - - -#define VK_KHR_win32_keyed_mutex 1 -#define VK_KHR_WIN32_KEYED_MUTEX_SPEC_VERSION 1 -#define VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_KHR_win32_keyed_mutex" -typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t acquireCount; - const VkDeviceMemory* pAcquireSyncs; - const uint64_t* pAcquireKeys; - const uint32_t* pAcquireTimeouts; - uint32_t releaseCount; - const VkDeviceMemory* pReleaseSyncs; - const uint64_t* pReleaseKeys; -} VkWin32KeyedMutexAcquireReleaseInfoKHR; - - - -#define VK_KHR_external_semaphore_win32 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME "VK_KHR_external_semaphore_win32" -typedef struct VkImportSemaphoreWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - VkSemaphoreImportFlags flags; - VkExternalSemaphoreHandleTypeFlagBits handleType; - HANDLE handle; - LPCWSTR name; -} VkImportSemaphoreWin32HandleInfoKHR; - -typedef struct VkExportSemaphoreWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - const SECURITY_ATTRIBUTES* pAttributes; - DWORD dwAccess; - LPCWSTR name; -} VkExportSemaphoreWin32HandleInfoKHR; - -typedef struct VkD3D12FenceSubmitInfoKHR { - VkStructureType sType; - const void* pNext; - uint32_t waitSemaphoreValuesCount; - const uint64_t* pWaitSemaphoreValues; - uint32_t signalSemaphoreValuesCount; - const uint64_t* pSignalSemaphoreValues; -} VkD3D12FenceSubmitInfoKHR; - -typedef struct VkSemaphoreGetWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkSemaphore semaphore; - VkExternalSemaphoreHandleTypeFlagBits handleType; -} VkSemaphoreGetWin32HandleInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreWin32HandleKHR)(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo); -typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreWin32HandleKHR)(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreWin32HandleKHR( - VkDevice device, - const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR( - VkDevice device, - const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, - HANDLE* pHandle); -#endif - - -#define VK_KHR_external_fence_win32 1 -#define VK_KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION 1 -#define VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME "VK_KHR_external_fence_win32" -typedef struct VkImportFenceWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkFence fence; - VkFenceImportFlags flags; - VkExternalFenceHandleTypeFlagBits handleType; - HANDLE handle; - LPCWSTR name; -} VkImportFenceWin32HandleInfoKHR; - -typedef struct VkExportFenceWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - const SECURITY_ATTRIBUTES* pAttributes; - DWORD dwAccess; - LPCWSTR name; -} VkExportFenceWin32HandleInfoKHR; - -typedef struct VkFenceGetWin32HandleInfoKHR { - VkStructureType sType; - const void* pNext; - VkFence fence; - VkExternalFenceHandleTypeFlagBits handleType; -} VkFenceGetWin32HandleInfoKHR; - -typedef VkResult (VKAPI_PTR *PFN_vkImportFenceWin32HandleKHR)(VkDevice device, const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo); -typedef VkResult (VKAPI_PTR *PFN_vkGetFenceWin32HandleKHR)(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceWin32HandleKHR( - VkDevice device, - const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR( - VkDevice device, - const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, - HANDLE* pHandle); -#endif - - -#define VK_NV_external_memory_win32 1 -#define VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1 -#define VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_NV_external_memory_win32" -typedef struct VkImportMemoryWin32HandleInfoNV { - VkStructureType sType; - const void* pNext; - VkExternalMemoryHandleTypeFlagsNV handleType; - HANDLE handle; -} VkImportMemoryWin32HandleInfoNV; - -typedef struct VkExportMemoryWin32HandleInfoNV { - VkStructureType sType; - const void* pNext; - const SECURITY_ATTRIBUTES* pAttributes; - DWORD dwAccess; -} VkExportMemoryWin32HandleInfoNV; - -typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleNV)(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV( - VkDevice device, - VkDeviceMemory memory, - VkExternalMemoryHandleTypeFlagsNV handleType, - HANDLE* pHandle); -#endif - - -#define VK_NV_win32_keyed_mutex 1 -#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 2 -#define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex" -typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV { - VkStructureType sType; - const void* pNext; - uint32_t acquireCount; - const VkDeviceMemory* pAcquireSyncs; - const uint64_t* pAcquireKeys; - const uint32_t* pAcquireTimeoutMilliseconds; - uint32_t releaseCount; - const VkDeviceMemory* pReleaseSyncs; - const uint64_t* pReleaseKeys; -} VkWin32KeyedMutexAcquireReleaseInfoNV; - - - -#define VK_EXT_full_screen_exclusive 1 -#define VK_EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION 4 -#define VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME "VK_EXT_full_screen_exclusive" - -typedef enum VkFullScreenExclusiveEXT { - VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT = 0, - VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT = 1, - VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT = 2, - VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT = 3, - VK_FULL_SCREEN_EXCLUSIVE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkFullScreenExclusiveEXT; -typedef struct VkSurfaceFullScreenExclusiveInfoEXT { - VkStructureType sType; - void* pNext; - VkFullScreenExclusiveEXT fullScreenExclusive; -} VkSurfaceFullScreenExclusiveInfoEXT; - -typedef struct VkSurfaceCapabilitiesFullScreenExclusiveEXT { - VkStructureType sType; - void* pNext; - VkBool32 fullScreenExclusiveSupported; -} VkSurfaceCapabilitiesFullScreenExclusiveEXT; - -typedef struct VkSurfaceFullScreenExclusiveWin32InfoEXT { - VkStructureType sType; - const void* pNext; - HMONITOR hmonitor; -} VkSurfaceFullScreenExclusiveWin32InfoEXT; - -typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); -typedef VkResult (VKAPI_PTR *PFN_vkAcquireFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain); -typedef VkResult (VKAPI_PTR *PFN_vkReleaseFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain); -typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModes2EXT)(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR* pModes); - -#ifndef VK_NO_PROTOTYPES -VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModes2EXT( - VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, - uint32_t* pPresentModeCount, - VkPresentModeKHR* pPresentModes); - -VKAPI_ATTR VkResult VKAPI_CALL vkAcquireFullScreenExclusiveModeEXT( - VkDevice device, - VkSwapchainKHR swapchain); - -VKAPI_ATTR VkResult VKAPI_CALL vkReleaseFullScreenExclusiveModeEXT( - VkDevice device, - VkSwapchainKHR swapchain); - -VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModes2EXT( - VkDevice device, - const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, - VkDeviceGroupPresentModeFlagsKHR* pModes); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/meson.build b/meson.build index d2c6a5469..385776352 100644 --- a/meson.build +++ b/meson.build @@ -26,6 +26,8 @@ if get_option('build_id') ] endif +dxvk_include_path = include_directories('./include', './include/vulkan/include') + if platform == 'windows' compiler_args += [ '-DNOMINMAX', @@ -91,8 +93,6 @@ if platform == 'windows' ) endif - dxvk_include_path = include_directories('./include') - dxvk_wsi = 'win32' compiler_args += ['-DDXVK_WSI_WIN32'] else @@ -102,7 +102,7 @@ else wrc = find_program('touch') wrc_generator = generator(wrc, output : [ '@BASENAME@_ignored.h' ], arguments : [ '@OUTPUT@' ] ) - dxvk_include_path = include_directories('./include', './include/native', './include/native/windows', './include/native/directx') + dxvk_include_path += include_directories('./include/native', './include/native/windows', './include/native/directx') dxvk_wsi = 'sdl2' compiler_args += ['-DDXVK_WSI_SDL2'] From c1448d31fa6322d9a948c498feb4e763ab930d04 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 22:21:57 +0200 Subject: [PATCH 0635/1348] [meta] Use SPIRV-Headers repository as a submodule --- .gitmodules | 3 + include/spirv | 1 + include/spirv/GLSL.std.450.h | 131 -- include/spirv/GLSL.std.450.hpp | 135 -- include/spirv/spirv.hpp | 2562 -------------------------------- meson.build | 2 +- src/spirv/spirv_code_buffer.h | 2 - src/spirv/spirv_include.h | 3 + src/spirv/spirv_instruction.h | 3 - src/spirv/spirv_module.cpp | 84 +- 10 files changed, 50 insertions(+), 2876 deletions(-) create mode 160000 include/spirv delete mode 100644 include/spirv/GLSL.std.450.h delete mode 100644 include/spirv/GLSL.std.450.hpp delete mode 100644 include/spirv/spirv.hpp diff --git a/.gitmodules b/.gitmodules index 81d7588ee..91895ae2e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "include/vulkan"] path = include/vulkan url = https://github.com/KhronosGroup/Vulkan-Headers +[submodule "include/spirv"] + path = include/spirv + url = https://github.com/KhronosGroup/SPIRV-Headers.git diff --git a/include/spirv b/include/spirv new file mode 160000 index 000000000..0bcc62492 --- /dev/null +++ b/include/spirv @@ -0,0 +1 @@ +Subproject commit 0bcc624926a25a2a273d07877fd25a6ff5ba1cfb diff --git a/include/spirv/GLSL.std.450.h b/include/spirv/GLSL.std.450.h deleted file mode 100644 index 54cc00e9a..000000000 --- a/include/spirv/GLSL.std.450.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -** Copyright (c) 2014-2016 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and/or associated documentation files (the "Materials"), -** to deal in the Materials without restriction, including without limitation -** the rights to use, copy, modify, merge, publish, distribute, sublicense, -** and/or sell copies of the Materials, and to permit persons to whom the -** Materials are furnished to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in -** all copies or substantial portions of the Materials. -** -** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS -** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS -** IN THE MATERIALS. -*/ - -#ifndef GLSLstd450_H -#define GLSLstd450_H - -static const int GLSLstd450Version = 100; -static const int GLSLstd450Revision = 3; - -enum GLSLstd450 { - GLSLstd450Bad = 0, // Don't use - - GLSLstd450Round = 1, - GLSLstd450RoundEven = 2, - GLSLstd450Trunc = 3, - GLSLstd450FAbs = 4, - GLSLstd450SAbs = 5, - GLSLstd450FSign = 6, - GLSLstd450SSign = 7, - GLSLstd450Floor = 8, - GLSLstd450Ceil = 9, - GLSLstd450Fract = 10, - - GLSLstd450Radians = 11, - GLSLstd450Degrees = 12, - GLSLstd450Sin = 13, - GLSLstd450Cos = 14, - GLSLstd450Tan = 15, - GLSLstd450Asin = 16, - GLSLstd450Acos = 17, - GLSLstd450Atan = 18, - GLSLstd450Sinh = 19, - GLSLstd450Cosh = 20, - GLSLstd450Tanh = 21, - GLSLstd450Asinh = 22, - GLSLstd450Acosh = 23, - GLSLstd450Atanh = 24, - GLSLstd450Atan2 = 25, - - GLSLstd450Pow = 26, - GLSLstd450Exp = 27, - GLSLstd450Log = 28, - GLSLstd450Exp2 = 29, - GLSLstd450Log2 = 30, - GLSLstd450Sqrt = 31, - GLSLstd450InverseSqrt = 32, - - GLSLstd450Determinant = 33, - GLSLstd450MatrixInverse = 34, - - GLSLstd450Modf = 35, // second operand needs an OpVariable to write to - GLSLstd450ModfStruct = 36, // no OpVariable operand - GLSLstd450FMin = 37, - GLSLstd450UMin = 38, - GLSLstd450SMin = 39, - GLSLstd450FMax = 40, - GLSLstd450UMax = 41, - GLSLstd450SMax = 42, - GLSLstd450FClamp = 43, - GLSLstd450UClamp = 44, - GLSLstd450SClamp = 45, - GLSLstd450FMix = 46, - GLSLstd450IMix = 47, // Reserved - GLSLstd450Step = 48, - GLSLstd450SmoothStep = 49, - - GLSLstd450Fma = 50, - GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to - GLSLstd450FrexpStruct = 52, // no OpVariable operand - GLSLstd450Ldexp = 53, - - GLSLstd450PackSnorm4x8 = 54, - GLSLstd450PackUnorm4x8 = 55, - GLSLstd450PackSnorm2x16 = 56, - GLSLstd450PackUnorm2x16 = 57, - GLSLstd450PackHalf2x16 = 58, - GLSLstd450PackDouble2x32 = 59, - GLSLstd450UnpackSnorm2x16 = 60, - GLSLstd450UnpackUnorm2x16 = 61, - GLSLstd450UnpackHalf2x16 = 62, - GLSLstd450UnpackSnorm4x8 = 63, - GLSLstd450UnpackUnorm4x8 = 64, - GLSLstd450UnpackDouble2x32 = 65, - - GLSLstd450Length = 66, - GLSLstd450Distance = 67, - GLSLstd450Cross = 68, - GLSLstd450Normalize = 69, - GLSLstd450FaceForward = 70, - GLSLstd450Reflect = 71, - GLSLstd450Refract = 72, - - GLSLstd450FindILsb = 73, - GLSLstd450FindSMsb = 74, - GLSLstd450FindUMsb = 75, - - GLSLstd450InterpolateAtCentroid = 76, - GLSLstd450InterpolateAtSample = 77, - GLSLstd450InterpolateAtOffset = 78, - - GLSLstd450NMin = 79, - GLSLstd450NMax = 80, - GLSLstd450NClamp = 81, - - GLSLstd450Count -}; - -#endif // #ifndef GLSLstd450_H diff --git a/include/spirv/GLSL.std.450.hpp b/include/spirv/GLSL.std.450.hpp deleted file mode 100644 index 186436680..000000000 --- a/include/spirv/GLSL.std.450.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* -** Copyright (c) 2014-2016 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and/or associated documentation files (the "Materials"), -** to deal in the Materials without restriction, including without limitation -** the rights to use, copy, modify, merge, publish, distribute, sublicense, -** and/or sell copies of the Materials, and to permit persons to whom the -** Materials are furnished to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in -** all copies or substantial portions of the Materials. -** -** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS -** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS -** IN THE MATERIALS. -*/ - -#ifndef GLSLstd450_HPP -#define GLSLstd450_HPP - -namespace spv { - -static const int GLSLstd450Version = 100; -static const int GLSLstd450Revision = 3; - -enum GLSLstd450 { - GLSLstd450Bad = 0, // Don't use - - GLSLstd450Round = 1, - GLSLstd450RoundEven = 2, - GLSLstd450Trunc = 3, - GLSLstd450FAbs = 4, - GLSLstd450SAbs = 5, - GLSLstd450FSign = 6, - GLSLstd450SSign = 7, - GLSLstd450Floor = 8, - GLSLstd450Ceil = 9, - GLSLstd450Fract = 10, - - GLSLstd450Radians = 11, - GLSLstd450Degrees = 12, - GLSLstd450Sin = 13, - GLSLstd450Cos = 14, - GLSLstd450Tan = 15, - GLSLstd450Asin = 16, - GLSLstd450Acos = 17, - GLSLstd450Atan = 18, - GLSLstd450Sinh = 19, - GLSLstd450Cosh = 20, - GLSLstd450Tanh = 21, - GLSLstd450Asinh = 22, - GLSLstd450Acosh = 23, - GLSLstd450Atanh = 24, - GLSLstd450Atan2 = 25, - - GLSLstd450Pow = 26, - GLSLstd450Exp = 27, - GLSLstd450Log = 28, - GLSLstd450Exp2 = 29, - GLSLstd450Log2 = 30, - GLSLstd450Sqrt = 31, - GLSLstd450InverseSqrt = 32, - - GLSLstd450Determinant = 33, - GLSLstd450MatrixInverse = 34, - - GLSLstd450Modf = 35, // second operand needs an OpVariable to write to - GLSLstd450ModfStruct = 36, // no OpVariable operand - GLSLstd450FMin = 37, - GLSLstd450UMin = 38, - GLSLstd450SMin = 39, - GLSLstd450FMax = 40, - GLSLstd450UMax = 41, - GLSLstd450SMax = 42, - GLSLstd450FClamp = 43, - GLSLstd450UClamp = 44, - GLSLstd450SClamp = 45, - GLSLstd450FMix = 46, - GLSLstd450IMix = 47, // Reserved - GLSLstd450Step = 48, - GLSLstd450SmoothStep = 49, - - GLSLstd450Fma = 50, - GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to - GLSLstd450FrexpStruct = 52, // no OpVariable operand - GLSLstd450Ldexp = 53, - - GLSLstd450PackSnorm4x8 = 54, - GLSLstd450PackUnorm4x8 = 55, - GLSLstd450PackSnorm2x16 = 56, - GLSLstd450PackUnorm2x16 = 57, - GLSLstd450PackHalf2x16 = 58, - GLSLstd450PackDouble2x32 = 59, - GLSLstd450UnpackSnorm2x16 = 60, - GLSLstd450UnpackUnorm2x16 = 61, - GLSLstd450UnpackHalf2x16 = 62, - GLSLstd450UnpackSnorm4x8 = 63, - GLSLstd450UnpackUnorm4x8 = 64, - GLSLstd450UnpackDouble2x32 = 65, - - GLSLstd450Length = 66, - GLSLstd450Distance = 67, - GLSLstd450Cross = 68, - GLSLstd450Normalize = 69, - GLSLstd450FaceForward = 70, - GLSLstd450Reflect = 71, - GLSLstd450Refract = 72, - - GLSLstd450FindILsb = 73, - GLSLstd450FindSMsb = 74, - GLSLstd450FindUMsb = 75, - - GLSLstd450InterpolateAtCentroid = 76, - GLSLstd450InterpolateAtSample = 77, - GLSLstd450InterpolateAtOffset = 78, - - GLSLstd450NMin = 79, - GLSLstd450NMax = 80, - GLSLstd450NClamp = 81, - - GLSLstd450Count -}; - -} - -#endif // #ifndef GLSLstd450_HPP \ No newline at end of file diff --git a/include/spirv/spirv.hpp b/include/spirv/spirv.hpp deleted file mode 100644 index 5947d6f7e..000000000 --- a/include/spirv/spirv.hpp +++ /dev/null @@ -1,2562 +0,0 @@ -// Copyright (c) 2014-2020 The Khronos Group Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and/or associated documentation files (the "Materials"), -// to deal in the Materials without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Materials, and to permit persons to whom the -// Materials are furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Materials. -// -// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS -// STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -// HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ -// -// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS -// IN THE MATERIALS. - -// This header is automatically generated by the same tool that creates -// the Binary Section of the SPIR-V specification. - -// Enumeration tokens for SPIR-V, in various styles: -// C, C++, C++11, JSON, Lua, Python, C#, D, Beef -// -// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] -// - C# will use enum classes in the Specification class located in the "Spv" namespace, -// e.g.: Spv.Specification.SourceLanguage.GLSL -// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL -// - Beef will use enum classes in the Specification class located in the "Spv" namespace, -// e.g.: Spv.Specification.SourceLanguage.GLSL -// -// Some tokens act like mask values, which can be OR'd together, -// while others are mutually exclusive. The mask-like ones have -// "Mask" in their name, and a parallel enum that has the shift -// amount (1 << x) for each corresponding enumerant. - -#ifndef spirv_HPP -#define spirv_HPP - -namespace spv { - -typedef unsigned int Id; - -#define SPV_VERSION 0x10600 -#define SPV_REVISION 1 - -static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010600; -static const unsigned int Revision = 1; -static const unsigned int OpCodeMask = 0xffff; -static const unsigned int WordCountShift = 16; - -enum SourceLanguage { - SourceLanguageUnknown = 0, - SourceLanguageESSL = 1, - SourceLanguageGLSL = 2, - SourceLanguageOpenCL_C = 3, - SourceLanguageOpenCL_CPP = 4, - SourceLanguageHLSL = 5, - SourceLanguageCPP_for_OpenCL = 6, - SourceLanguageSYCL = 7, - SourceLanguageMax = 0x7fffffff, -}; - -enum ExecutionModel { - ExecutionModelVertex = 0, - ExecutionModelTessellationControl = 1, - ExecutionModelTessellationEvaluation = 2, - ExecutionModelGeometry = 3, - ExecutionModelFragment = 4, - ExecutionModelGLCompute = 5, - ExecutionModelKernel = 6, - ExecutionModelTaskNV = 5267, - ExecutionModelMeshNV = 5268, - ExecutionModelRayGenerationKHR = 5313, - ExecutionModelRayGenerationNV = 5313, - ExecutionModelIntersectionKHR = 5314, - ExecutionModelIntersectionNV = 5314, - ExecutionModelAnyHitKHR = 5315, - ExecutionModelAnyHitNV = 5315, - ExecutionModelClosestHitKHR = 5316, - ExecutionModelClosestHitNV = 5316, - ExecutionModelMissKHR = 5317, - ExecutionModelMissNV = 5317, - ExecutionModelCallableKHR = 5318, - ExecutionModelCallableNV = 5318, - ExecutionModelMax = 0x7fffffff, -}; - -enum AddressingModel { - AddressingModelLogical = 0, - AddressingModelPhysical32 = 1, - AddressingModelPhysical64 = 2, - AddressingModelPhysicalStorageBuffer64 = 5348, - AddressingModelPhysicalStorageBuffer64EXT = 5348, - AddressingModelMax = 0x7fffffff, -}; - -enum MemoryModel { - MemoryModelSimple = 0, - MemoryModelGLSL450 = 1, - MemoryModelOpenCL = 2, - MemoryModelVulkan = 3, - MemoryModelVulkanKHR = 3, - MemoryModelMax = 0x7fffffff, -}; - -enum ExecutionMode { - ExecutionModeInvocations = 0, - ExecutionModeSpacingEqual = 1, - ExecutionModeSpacingFractionalEven = 2, - ExecutionModeSpacingFractionalOdd = 3, - ExecutionModeVertexOrderCw = 4, - ExecutionModeVertexOrderCcw = 5, - ExecutionModePixelCenterInteger = 6, - ExecutionModeOriginUpperLeft = 7, - ExecutionModeOriginLowerLeft = 8, - ExecutionModeEarlyFragmentTests = 9, - ExecutionModePointMode = 10, - ExecutionModeXfb = 11, - ExecutionModeDepthReplacing = 12, - ExecutionModeDepthGreater = 14, - ExecutionModeDepthLess = 15, - ExecutionModeDepthUnchanged = 16, - ExecutionModeLocalSize = 17, - ExecutionModeLocalSizeHint = 18, - ExecutionModeInputPoints = 19, - ExecutionModeInputLines = 20, - ExecutionModeInputLinesAdjacency = 21, - ExecutionModeTriangles = 22, - ExecutionModeInputTrianglesAdjacency = 23, - ExecutionModeQuads = 24, - ExecutionModeIsolines = 25, - ExecutionModeOutputVertices = 26, - ExecutionModeOutputPoints = 27, - ExecutionModeOutputLineStrip = 28, - ExecutionModeOutputTriangleStrip = 29, - ExecutionModeVecTypeHint = 30, - ExecutionModeContractionOff = 31, - ExecutionModeInitializer = 33, - ExecutionModeFinalizer = 34, - ExecutionModeSubgroupSize = 35, - ExecutionModeSubgroupsPerWorkgroup = 36, - ExecutionModeSubgroupsPerWorkgroupId = 37, - ExecutionModeLocalSizeId = 38, - ExecutionModeLocalSizeHintId = 39, - ExecutionModeSubgroupUniformControlFlowKHR = 4421, - ExecutionModePostDepthCoverage = 4446, - ExecutionModeDenormPreserve = 4459, - ExecutionModeDenormFlushToZero = 4460, - ExecutionModeSignedZeroInfNanPreserve = 4461, - ExecutionModeRoundingModeRTE = 4462, - ExecutionModeRoundingModeRTZ = 4463, - ExecutionModeEarlyAndLateFragmentTestsAMD = 5017, - ExecutionModeStencilRefReplacingEXT = 5027, - ExecutionModeStencilRefUnchangedFrontAMD = 5079, - ExecutionModeStencilRefGreaterFrontAMD = 5080, - ExecutionModeStencilRefLessFrontAMD = 5081, - ExecutionModeStencilRefUnchangedBackAMD = 5082, - ExecutionModeStencilRefGreaterBackAMD = 5083, - ExecutionModeStencilRefLessBackAMD = 5084, - ExecutionModeOutputLinesNV = 5269, - ExecutionModeOutputPrimitivesNV = 5270, - ExecutionModeDerivativeGroupQuadsNV = 5289, - ExecutionModeDerivativeGroupLinearNV = 5290, - ExecutionModeOutputTrianglesNV = 5298, - ExecutionModePixelInterlockOrderedEXT = 5366, - ExecutionModePixelInterlockUnorderedEXT = 5367, - ExecutionModeSampleInterlockOrderedEXT = 5368, - ExecutionModeSampleInterlockUnorderedEXT = 5369, - ExecutionModeShadingRateInterlockOrderedEXT = 5370, - ExecutionModeShadingRateInterlockUnorderedEXT = 5371, - ExecutionModeSharedLocalMemorySizeINTEL = 5618, - ExecutionModeRoundingModeRTPINTEL = 5620, - ExecutionModeRoundingModeRTNINTEL = 5621, - ExecutionModeFloatingPointModeALTINTEL = 5622, - ExecutionModeFloatingPointModeIEEEINTEL = 5623, - ExecutionModeMaxWorkgroupSizeINTEL = 5893, - ExecutionModeMaxWorkDimINTEL = 5894, - ExecutionModeNoGlobalOffsetINTEL = 5895, - ExecutionModeNumSIMDWorkitemsINTEL = 5896, - ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, - ExecutionModeNamedBarrierCountINTEL = 6417, - ExecutionModeMax = 0x7fffffff, -}; - -enum StorageClass { - StorageClassUniformConstant = 0, - StorageClassInput = 1, - StorageClassUniform = 2, - StorageClassOutput = 3, - StorageClassWorkgroup = 4, - StorageClassCrossWorkgroup = 5, - StorageClassPrivate = 6, - StorageClassFunction = 7, - StorageClassGeneric = 8, - StorageClassPushConstant = 9, - StorageClassAtomicCounter = 10, - StorageClassImage = 11, - StorageClassStorageBuffer = 12, - StorageClassCallableDataKHR = 5328, - StorageClassCallableDataNV = 5328, - StorageClassIncomingCallableDataKHR = 5329, - StorageClassIncomingCallableDataNV = 5329, - StorageClassRayPayloadKHR = 5338, - StorageClassRayPayloadNV = 5338, - StorageClassHitAttributeKHR = 5339, - StorageClassHitAttributeNV = 5339, - StorageClassIncomingRayPayloadKHR = 5342, - StorageClassIncomingRayPayloadNV = 5342, - StorageClassShaderRecordBufferKHR = 5343, - StorageClassShaderRecordBufferNV = 5343, - StorageClassPhysicalStorageBuffer = 5349, - StorageClassPhysicalStorageBufferEXT = 5349, - StorageClassCodeSectionINTEL = 5605, - StorageClassDeviceOnlyINTEL = 5936, - StorageClassHostOnlyINTEL = 5937, - StorageClassMax = 0x7fffffff, -}; - -enum Dim { - Dim1D = 0, - Dim2D = 1, - Dim3D = 2, - DimCube = 3, - DimRect = 4, - DimBuffer = 5, - DimSubpassData = 6, - DimMax = 0x7fffffff, -}; - -enum SamplerAddressingMode { - SamplerAddressingModeNone = 0, - SamplerAddressingModeClampToEdge = 1, - SamplerAddressingModeClamp = 2, - SamplerAddressingModeRepeat = 3, - SamplerAddressingModeRepeatMirrored = 4, - SamplerAddressingModeMax = 0x7fffffff, -}; - -enum SamplerFilterMode { - SamplerFilterModeNearest = 0, - SamplerFilterModeLinear = 1, - SamplerFilterModeMax = 0x7fffffff, -}; - -enum ImageFormat { - ImageFormatUnknown = 0, - ImageFormatRgba32f = 1, - ImageFormatRgba16f = 2, - ImageFormatR32f = 3, - ImageFormatRgba8 = 4, - ImageFormatRgba8Snorm = 5, - ImageFormatRg32f = 6, - ImageFormatRg16f = 7, - ImageFormatR11fG11fB10f = 8, - ImageFormatR16f = 9, - ImageFormatRgba16 = 10, - ImageFormatRgb10A2 = 11, - ImageFormatRg16 = 12, - ImageFormatRg8 = 13, - ImageFormatR16 = 14, - ImageFormatR8 = 15, - ImageFormatRgba16Snorm = 16, - ImageFormatRg16Snorm = 17, - ImageFormatRg8Snorm = 18, - ImageFormatR16Snorm = 19, - ImageFormatR8Snorm = 20, - ImageFormatRgba32i = 21, - ImageFormatRgba16i = 22, - ImageFormatRgba8i = 23, - ImageFormatR32i = 24, - ImageFormatRg32i = 25, - ImageFormatRg16i = 26, - ImageFormatRg8i = 27, - ImageFormatR16i = 28, - ImageFormatR8i = 29, - ImageFormatRgba32ui = 30, - ImageFormatRgba16ui = 31, - ImageFormatRgba8ui = 32, - ImageFormatR32ui = 33, - ImageFormatRgb10a2ui = 34, - ImageFormatRg32ui = 35, - ImageFormatRg16ui = 36, - ImageFormatRg8ui = 37, - ImageFormatR16ui = 38, - ImageFormatR8ui = 39, - ImageFormatR64ui = 40, - ImageFormatR64i = 41, - ImageFormatMax = 0x7fffffff, -}; - -enum ImageChannelOrder { - ImageChannelOrderR = 0, - ImageChannelOrderA = 1, - ImageChannelOrderRG = 2, - ImageChannelOrderRA = 3, - ImageChannelOrderRGB = 4, - ImageChannelOrderRGBA = 5, - ImageChannelOrderBGRA = 6, - ImageChannelOrderARGB = 7, - ImageChannelOrderIntensity = 8, - ImageChannelOrderLuminance = 9, - ImageChannelOrderRx = 10, - ImageChannelOrderRGx = 11, - ImageChannelOrderRGBx = 12, - ImageChannelOrderDepth = 13, - ImageChannelOrderDepthStencil = 14, - ImageChannelOrdersRGB = 15, - ImageChannelOrdersRGBx = 16, - ImageChannelOrdersRGBA = 17, - ImageChannelOrdersBGRA = 18, - ImageChannelOrderABGR = 19, - ImageChannelOrderMax = 0x7fffffff, -}; - -enum ImageChannelDataType { - ImageChannelDataTypeSnormInt8 = 0, - ImageChannelDataTypeSnormInt16 = 1, - ImageChannelDataTypeUnormInt8 = 2, - ImageChannelDataTypeUnormInt16 = 3, - ImageChannelDataTypeUnormShort565 = 4, - ImageChannelDataTypeUnormShort555 = 5, - ImageChannelDataTypeUnormInt101010 = 6, - ImageChannelDataTypeSignedInt8 = 7, - ImageChannelDataTypeSignedInt16 = 8, - ImageChannelDataTypeSignedInt32 = 9, - ImageChannelDataTypeUnsignedInt8 = 10, - ImageChannelDataTypeUnsignedInt16 = 11, - ImageChannelDataTypeUnsignedInt32 = 12, - ImageChannelDataTypeHalfFloat = 13, - ImageChannelDataTypeFloat = 14, - ImageChannelDataTypeUnormInt24 = 15, - ImageChannelDataTypeUnormInt101010_2 = 16, - ImageChannelDataTypeMax = 0x7fffffff, -}; - -enum ImageOperandsShift { - ImageOperandsBiasShift = 0, - ImageOperandsLodShift = 1, - ImageOperandsGradShift = 2, - ImageOperandsConstOffsetShift = 3, - ImageOperandsOffsetShift = 4, - ImageOperandsConstOffsetsShift = 5, - ImageOperandsSampleShift = 6, - ImageOperandsMinLodShift = 7, - ImageOperandsMakeTexelAvailableShift = 8, - ImageOperandsMakeTexelAvailableKHRShift = 8, - ImageOperandsMakeTexelVisibleShift = 9, - ImageOperandsMakeTexelVisibleKHRShift = 9, - ImageOperandsNonPrivateTexelShift = 10, - ImageOperandsNonPrivateTexelKHRShift = 10, - ImageOperandsVolatileTexelShift = 11, - ImageOperandsVolatileTexelKHRShift = 11, - ImageOperandsSignExtendShift = 12, - ImageOperandsZeroExtendShift = 13, - ImageOperandsNontemporalShift = 14, - ImageOperandsOffsetsShift = 16, - ImageOperandsMax = 0x7fffffff, -}; - -enum ImageOperandsMask { - ImageOperandsMaskNone = 0, - ImageOperandsBiasMask = 0x00000001, - ImageOperandsLodMask = 0x00000002, - ImageOperandsGradMask = 0x00000004, - ImageOperandsConstOffsetMask = 0x00000008, - ImageOperandsOffsetMask = 0x00000010, - ImageOperandsConstOffsetsMask = 0x00000020, - ImageOperandsSampleMask = 0x00000040, - ImageOperandsMinLodMask = 0x00000080, - ImageOperandsMakeTexelAvailableMask = 0x00000100, - ImageOperandsMakeTexelAvailableKHRMask = 0x00000100, - ImageOperandsMakeTexelVisibleMask = 0x00000200, - ImageOperandsMakeTexelVisibleKHRMask = 0x00000200, - ImageOperandsNonPrivateTexelMask = 0x00000400, - ImageOperandsNonPrivateTexelKHRMask = 0x00000400, - ImageOperandsVolatileTexelMask = 0x00000800, - ImageOperandsVolatileTexelKHRMask = 0x00000800, - ImageOperandsSignExtendMask = 0x00001000, - ImageOperandsZeroExtendMask = 0x00002000, - ImageOperandsNontemporalMask = 0x00004000, - ImageOperandsOffsetsMask = 0x00010000, -}; - -enum FPFastMathModeShift { - FPFastMathModeNotNaNShift = 0, - FPFastMathModeNotInfShift = 1, - FPFastMathModeNSZShift = 2, - FPFastMathModeAllowRecipShift = 3, - FPFastMathModeFastShift = 4, - FPFastMathModeAllowContractFastINTELShift = 16, - FPFastMathModeAllowReassocINTELShift = 17, - FPFastMathModeMax = 0x7fffffff, -}; - -enum FPFastMathModeMask { - FPFastMathModeMaskNone = 0, - FPFastMathModeNotNaNMask = 0x00000001, - FPFastMathModeNotInfMask = 0x00000002, - FPFastMathModeNSZMask = 0x00000004, - FPFastMathModeAllowRecipMask = 0x00000008, - FPFastMathModeFastMask = 0x00000010, - FPFastMathModeAllowContractFastINTELMask = 0x00010000, - FPFastMathModeAllowReassocINTELMask = 0x00020000, -}; - -enum FPRoundingMode { - FPRoundingModeRTE = 0, - FPRoundingModeRTZ = 1, - FPRoundingModeRTP = 2, - FPRoundingModeRTN = 3, - FPRoundingModeMax = 0x7fffffff, -}; - -enum LinkageType { - LinkageTypeExport = 0, - LinkageTypeImport = 1, - LinkageTypeLinkOnceODR = 2, - LinkageTypeMax = 0x7fffffff, -}; - -enum AccessQualifier { - AccessQualifierReadOnly = 0, - AccessQualifierWriteOnly = 1, - AccessQualifierReadWrite = 2, - AccessQualifierMax = 0x7fffffff, -}; - -enum FunctionParameterAttribute { - FunctionParameterAttributeZext = 0, - FunctionParameterAttributeSext = 1, - FunctionParameterAttributeByVal = 2, - FunctionParameterAttributeSret = 3, - FunctionParameterAttributeNoAlias = 4, - FunctionParameterAttributeNoCapture = 5, - FunctionParameterAttributeNoWrite = 6, - FunctionParameterAttributeNoReadWrite = 7, - FunctionParameterAttributeMax = 0x7fffffff, -}; - -enum Decoration { - DecorationRelaxedPrecision = 0, - DecorationSpecId = 1, - DecorationBlock = 2, - DecorationBufferBlock = 3, - DecorationRowMajor = 4, - DecorationColMajor = 5, - DecorationArrayStride = 6, - DecorationMatrixStride = 7, - DecorationGLSLShared = 8, - DecorationGLSLPacked = 9, - DecorationCPacked = 10, - DecorationBuiltIn = 11, - DecorationNoPerspective = 13, - DecorationFlat = 14, - DecorationPatch = 15, - DecorationCentroid = 16, - DecorationSample = 17, - DecorationInvariant = 18, - DecorationRestrict = 19, - DecorationAliased = 20, - DecorationVolatile = 21, - DecorationConstant = 22, - DecorationCoherent = 23, - DecorationNonWritable = 24, - DecorationNonReadable = 25, - DecorationUniform = 26, - DecorationUniformId = 27, - DecorationSaturatedConversion = 28, - DecorationStream = 29, - DecorationLocation = 30, - DecorationComponent = 31, - DecorationIndex = 32, - DecorationBinding = 33, - DecorationDescriptorSet = 34, - DecorationOffset = 35, - DecorationXfbBuffer = 36, - DecorationXfbStride = 37, - DecorationFuncParamAttr = 38, - DecorationFPRoundingMode = 39, - DecorationFPFastMathMode = 40, - DecorationLinkageAttributes = 41, - DecorationNoContraction = 42, - DecorationInputAttachmentIndex = 43, - DecorationAlignment = 44, - DecorationMaxByteOffset = 45, - DecorationAlignmentId = 46, - DecorationMaxByteOffsetId = 47, - DecorationNoSignedWrap = 4469, - DecorationNoUnsignedWrap = 4470, - DecorationExplicitInterpAMD = 4999, - DecorationOverrideCoverageNV = 5248, - DecorationPassthroughNV = 5250, - DecorationViewportRelativeNV = 5252, - DecorationSecondaryViewportRelativeNV = 5256, - DecorationPerPrimitiveNV = 5271, - DecorationPerViewNV = 5272, - DecorationPerTaskNV = 5273, - DecorationPerVertexKHR = 5285, - DecorationPerVertexNV = 5285, - DecorationNonUniform = 5300, - DecorationNonUniformEXT = 5300, - DecorationRestrictPointer = 5355, - DecorationRestrictPointerEXT = 5355, - DecorationAliasedPointer = 5356, - DecorationAliasedPointerEXT = 5356, - DecorationBindlessSamplerNV = 5398, - DecorationBindlessImageNV = 5399, - DecorationBoundSamplerNV = 5400, - DecorationBoundImageNV = 5401, - DecorationSIMTCallINTEL = 5599, - DecorationReferencedIndirectlyINTEL = 5602, - DecorationClobberINTEL = 5607, - DecorationSideEffectsINTEL = 5608, - DecorationVectorComputeVariableINTEL = 5624, - DecorationFuncParamIOKindINTEL = 5625, - DecorationVectorComputeFunctionINTEL = 5626, - DecorationStackCallINTEL = 5627, - DecorationGlobalVariableOffsetINTEL = 5628, - DecorationCounterBuffer = 5634, - DecorationHlslCounterBufferGOOGLE = 5634, - DecorationHlslSemanticGOOGLE = 5635, - DecorationUserSemantic = 5635, - DecorationUserTypeGOOGLE = 5636, - DecorationFunctionRoundingModeINTEL = 5822, - DecorationFunctionDenormModeINTEL = 5823, - DecorationRegisterINTEL = 5825, - DecorationMemoryINTEL = 5826, - DecorationNumbanksINTEL = 5827, - DecorationBankwidthINTEL = 5828, - DecorationMaxPrivateCopiesINTEL = 5829, - DecorationSinglepumpINTEL = 5830, - DecorationDoublepumpINTEL = 5831, - DecorationMaxReplicatesINTEL = 5832, - DecorationSimpleDualPortINTEL = 5833, - DecorationMergeINTEL = 5834, - DecorationBankBitsINTEL = 5835, - DecorationForcePow2DepthINTEL = 5836, - DecorationBurstCoalesceINTEL = 5899, - DecorationCacheSizeINTEL = 5900, - DecorationDontStaticallyCoalesceINTEL = 5901, - DecorationPrefetchINTEL = 5902, - DecorationStallEnableINTEL = 5905, - DecorationFuseLoopsInFunctionINTEL = 5907, - DecorationAliasScopeINTEL = 5914, - DecorationNoAliasINTEL = 5915, - DecorationBufferLocationINTEL = 5921, - DecorationIOPipeStorageINTEL = 5944, - DecorationFunctionFloatingPointModeINTEL = 6080, - DecorationSingleElementVectorINTEL = 6085, - DecorationVectorComputeCallableFunctionINTEL = 6087, - DecorationMediaBlockIOINTEL = 6140, - DecorationMax = 0x7fffffff, -}; - -enum BuiltIn { - BuiltInPosition = 0, - BuiltInPointSize = 1, - BuiltInClipDistance = 3, - BuiltInCullDistance = 4, - BuiltInVertexId = 5, - BuiltInInstanceId = 6, - BuiltInPrimitiveId = 7, - BuiltInInvocationId = 8, - BuiltInLayer = 9, - BuiltInViewportIndex = 10, - BuiltInTessLevelOuter = 11, - BuiltInTessLevelInner = 12, - BuiltInTessCoord = 13, - BuiltInPatchVertices = 14, - BuiltInFragCoord = 15, - BuiltInPointCoord = 16, - BuiltInFrontFacing = 17, - BuiltInSampleId = 18, - BuiltInSamplePosition = 19, - BuiltInSampleMask = 20, - BuiltInFragDepth = 22, - BuiltInHelperInvocation = 23, - BuiltInNumWorkgroups = 24, - BuiltInWorkgroupSize = 25, - BuiltInWorkgroupId = 26, - BuiltInLocalInvocationId = 27, - BuiltInGlobalInvocationId = 28, - BuiltInLocalInvocationIndex = 29, - BuiltInWorkDim = 30, - BuiltInGlobalSize = 31, - BuiltInEnqueuedWorkgroupSize = 32, - BuiltInGlobalOffset = 33, - BuiltInGlobalLinearId = 34, - BuiltInSubgroupSize = 36, - BuiltInSubgroupMaxSize = 37, - BuiltInNumSubgroups = 38, - BuiltInNumEnqueuedSubgroups = 39, - BuiltInSubgroupId = 40, - BuiltInSubgroupLocalInvocationId = 41, - BuiltInVertexIndex = 42, - BuiltInInstanceIndex = 43, - BuiltInSubgroupEqMask = 4416, - BuiltInSubgroupEqMaskKHR = 4416, - BuiltInSubgroupGeMask = 4417, - BuiltInSubgroupGeMaskKHR = 4417, - BuiltInSubgroupGtMask = 4418, - BuiltInSubgroupGtMaskKHR = 4418, - BuiltInSubgroupLeMask = 4419, - BuiltInSubgroupLeMaskKHR = 4419, - BuiltInSubgroupLtMask = 4420, - BuiltInSubgroupLtMaskKHR = 4420, - BuiltInBaseVertex = 4424, - BuiltInBaseInstance = 4425, - BuiltInDrawIndex = 4426, - BuiltInPrimitiveShadingRateKHR = 4432, - BuiltInDeviceIndex = 4438, - BuiltInViewIndex = 4440, - BuiltInShadingRateKHR = 4444, - BuiltInBaryCoordNoPerspAMD = 4992, - BuiltInBaryCoordNoPerspCentroidAMD = 4993, - BuiltInBaryCoordNoPerspSampleAMD = 4994, - BuiltInBaryCoordSmoothAMD = 4995, - BuiltInBaryCoordSmoothCentroidAMD = 4996, - BuiltInBaryCoordSmoothSampleAMD = 4997, - BuiltInBaryCoordPullModelAMD = 4998, - BuiltInFragStencilRefEXT = 5014, - BuiltInViewportMaskNV = 5253, - BuiltInSecondaryPositionNV = 5257, - BuiltInSecondaryViewportMaskNV = 5258, - BuiltInPositionPerViewNV = 5261, - BuiltInViewportMaskPerViewNV = 5262, - BuiltInFullyCoveredEXT = 5264, - BuiltInTaskCountNV = 5274, - BuiltInPrimitiveCountNV = 5275, - BuiltInPrimitiveIndicesNV = 5276, - BuiltInClipDistancePerViewNV = 5277, - BuiltInCullDistancePerViewNV = 5278, - BuiltInLayerPerViewNV = 5279, - BuiltInMeshViewCountNV = 5280, - BuiltInMeshViewIndicesNV = 5281, - BuiltInBaryCoordKHR = 5286, - BuiltInBaryCoordNV = 5286, - BuiltInBaryCoordNoPerspKHR = 5287, - BuiltInBaryCoordNoPerspNV = 5287, - BuiltInFragSizeEXT = 5292, - BuiltInFragmentSizeNV = 5292, - BuiltInFragInvocationCountEXT = 5293, - BuiltInInvocationsPerPixelNV = 5293, - BuiltInLaunchIdKHR = 5319, - BuiltInLaunchIdNV = 5319, - BuiltInLaunchSizeKHR = 5320, - BuiltInLaunchSizeNV = 5320, - BuiltInWorldRayOriginKHR = 5321, - BuiltInWorldRayOriginNV = 5321, - BuiltInWorldRayDirectionKHR = 5322, - BuiltInWorldRayDirectionNV = 5322, - BuiltInObjectRayOriginKHR = 5323, - BuiltInObjectRayOriginNV = 5323, - BuiltInObjectRayDirectionKHR = 5324, - BuiltInObjectRayDirectionNV = 5324, - BuiltInRayTminKHR = 5325, - BuiltInRayTminNV = 5325, - BuiltInRayTmaxKHR = 5326, - BuiltInRayTmaxNV = 5326, - BuiltInInstanceCustomIndexKHR = 5327, - BuiltInInstanceCustomIndexNV = 5327, - BuiltInObjectToWorldKHR = 5330, - BuiltInObjectToWorldNV = 5330, - BuiltInWorldToObjectKHR = 5331, - BuiltInWorldToObjectNV = 5331, - BuiltInHitTNV = 5332, - BuiltInHitKindKHR = 5333, - BuiltInHitKindNV = 5333, - BuiltInCurrentRayTimeNV = 5334, - BuiltInIncomingRayFlagsKHR = 5351, - BuiltInIncomingRayFlagsNV = 5351, - BuiltInRayGeometryIndexKHR = 5352, - BuiltInWarpsPerSMNV = 5374, - BuiltInSMCountNV = 5375, - BuiltInWarpIDNV = 5376, - BuiltInSMIDNV = 5377, - BuiltInCullMaskKHR = 6021, - BuiltInMax = 0x7fffffff, -}; - -enum SelectionControlShift { - SelectionControlFlattenShift = 0, - SelectionControlDontFlattenShift = 1, - SelectionControlMax = 0x7fffffff, -}; - -enum SelectionControlMask { - SelectionControlMaskNone = 0, - SelectionControlFlattenMask = 0x00000001, - SelectionControlDontFlattenMask = 0x00000002, -}; - -enum LoopControlShift { - LoopControlUnrollShift = 0, - LoopControlDontUnrollShift = 1, - LoopControlDependencyInfiniteShift = 2, - LoopControlDependencyLengthShift = 3, - LoopControlMinIterationsShift = 4, - LoopControlMaxIterationsShift = 5, - LoopControlIterationMultipleShift = 6, - LoopControlPeelCountShift = 7, - LoopControlPartialCountShift = 8, - LoopControlInitiationIntervalINTELShift = 16, - LoopControlMaxConcurrencyINTELShift = 17, - LoopControlDependencyArrayINTELShift = 18, - LoopControlPipelineEnableINTELShift = 19, - LoopControlLoopCoalesceINTELShift = 20, - LoopControlMaxInterleavingINTELShift = 21, - LoopControlSpeculatedIterationsINTELShift = 22, - LoopControlNoFusionINTELShift = 23, - LoopControlMax = 0x7fffffff, -}; - -enum LoopControlMask { - LoopControlMaskNone = 0, - LoopControlUnrollMask = 0x00000001, - LoopControlDontUnrollMask = 0x00000002, - LoopControlDependencyInfiniteMask = 0x00000004, - LoopControlDependencyLengthMask = 0x00000008, - LoopControlMinIterationsMask = 0x00000010, - LoopControlMaxIterationsMask = 0x00000020, - LoopControlIterationMultipleMask = 0x00000040, - LoopControlPeelCountMask = 0x00000080, - LoopControlPartialCountMask = 0x00000100, - LoopControlInitiationIntervalINTELMask = 0x00010000, - LoopControlMaxConcurrencyINTELMask = 0x00020000, - LoopControlDependencyArrayINTELMask = 0x00040000, - LoopControlPipelineEnableINTELMask = 0x00080000, - LoopControlLoopCoalesceINTELMask = 0x00100000, - LoopControlMaxInterleavingINTELMask = 0x00200000, - LoopControlSpeculatedIterationsINTELMask = 0x00400000, - LoopControlNoFusionINTELMask = 0x00800000, -}; - -enum FunctionControlShift { - FunctionControlInlineShift = 0, - FunctionControlDontInlineShift = 1, - FunctionControlPureShift = 2, - FunctionControlConstShift = 3, - FunctionControlOptNoneINTELShift = 16, - FunctionControlMax = 0x7fffffff, -}; - -enum FunctionControlMask { - FunctionControlMaskNone = 0, - FunctionControlInlineMask = 0x00000001, - FunctionControlDontInlineMask = 0x00000002, - FunctionControlPureMask = 0x00000004, - FunctionControlConstMask = 0x00000008, - FunctionControlOptNoneINTELMask = 0x00010000, -}; - -enum MemorySemanticsShift { - MemorySemanticsAcquireShift = 1, - MemorySemanticsReleaseShift = 2, - MemorySemanticsAcquireReleaseShift = 3, - MemorySemanticsSequentiallyConsistentShift = 4, - MemorySemanticsUniformMemoryShift = 6, - MemorySemanticsSubgroupMemoryShift = 7, - MemorySemanticsWorkgroupMemoryShift = 8, - MemorySemanticsCrossWorkgroupMemoryShift = 9, - MemorySemanticsAtomicCounterMemoryShift = 10, - MemorySemanticsImageMemoryShift = 11, - MemorySemanticsOutputMemoryShift = 12, - MemorySemanticsOutputMemoryKHRShift = 12, - MemorySemanticsMakeAvailableShift = 13, - MemorySemanticsMakeAvailableKHRShift = 13, - MemorySemanticsMakeVisibleShift = 14, - MemorySemanticsMakeVisibleKHRShift = 14, - MemorySemanticsVolatileShift = 15, - MemorySemanticsMax = 0x7fffffff, -}; - -enum MemorySemanticsMask { - MemorySemanticsMaskNone = 0, - MemorySemanticsAcquireMask = 0x00000002, - MemorySemanticsReleaseMask = 0x00000004, - MemorySemanticsAcquireReleaseMask = 0x00000008, - MemorySemanticsSequentiallyConsistentMask = 0x00000010, - MemorySemanticsUniformMemoryMask = 0x00000040, - MemorySemanticsSubgroupMemoryMask = 0x00000080, - MemorySemanticsWorkgroupMemoryMask = 0x00000100, - MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, - MemorySemanticsAtomicCounterMemoryMask = 0x00000400, - MemorySemanticsImageMemoryMask = 0x00000800, - MemorySemanticsOutputMemoryMask = 0x00001000, - MemorySemanticsOutputMemoryKHRMask = 0x00001000, - MemorySemanticsMakeAvailableMask = 0x00002000, - MemorySemanticsMakeAvailableKHRMask = 0x00002000, - MemorySemanticsMakeVisibleMask = 0x00004000, - MemorySemanticsMakeVisibleKHRMask = 0x00004000, - MemorySemanticsVolatileMask = 0x00008000, -}; - -enum MemoryAccessShift { - MemoryAccessVolatileShift = 0, - MemoryAccessAlignedShift = 1, - MemoryAccessNontemporalShift = 2, - MemoryAccessMakePointerAvailableShift = 3, - MemoryAccessMakePointerAvailableKHRShift = 3, - MemoryAccessMakePointerVisibleShift = 4, - MemoryAccessMakePointerVisibleKHRShift = 4, - MemoryAccessNonPrivatePointerShift = 5, - MemoryAccessNonPrivatePointerKHRShift = 5, - MemoryAccessAliasScopeINTELMaskShift = 16, - MemoryAccessNoAliasINTELMaskShift = 17, - MemoryAccessMax = 0x7fffffff, -}; - -enum MemoryAccessMask { - MemoryAccessMaskNone = 0, - MemoryAccessVolatileMask = 0x00000001, - MemoryAccessAlignedMask = 0x00000002, - MemoryAccessNontemporalMask = 0x00000004, - MemoryAccessMakePointerAvailableMask = 0x00000008, - MemoryAccessMakePointerAvailableKHRMask = 0x00000008, - MemoryAccessMakePointerVisibleMask = 0x00000010, - MemoryAccessMakePointerVisibleKHRMask = 0x00000010, - MemoryAccessNonPrivatePointerMask = 0x00000020, - MemoryAccessNonPrivatePointerKHRMask = 0x00000020, - MemoryAccessAliasScopeINTELMaskMask = 0x00010000, - MemoryAccessNoAliasINTELMaskMask = 0x00020000, -}; - -enum Scope { - ScopeCrossDevice = 0, - ScopeDevice = 1, - ScopeWorkgroup = 2, - ScopeSubgroup = 3, - ScopeInvocation = 4, - ScopeQueueFamily = 5, - ScopeQueueFamilyKHR = 5, - ScopeShaderCallKHR = 6, - ScopeMax = 0x7fffffff, -}; - -enum GroupOperation { - GroupOperationReduce = 0, - GroupOperationInclusiveScan = 1, - GroupOperationExclusiveScan = 2, - GroupOperationClusteredReduce = 3, - GroupOperationPartitionedReduceNV = 6, - GroupOperationPartitionedInclusiveScanNV = 7, - GroupOperationPartitionedExclusiveScanNV = 8, - GroupOperationMax = 0x7fffffff, -}; - -enum KernelEnqueueFlags { - KernelEnqueueFlagsNoWait = 0, - KernelEnqueueFlagsWaitKernel = 1, - KernelEnqueueFlagsWaitWorkGroup = 2, - KernelEnqueueFlagsMax = 0x7fffffff, -}; - -enum KernelProfilingInfoShift { - KernelProfilingInfoCmdExecTimeShift = 0, - KernelProfilingInfoMax = 0x7fffffff, -}; - -enum KernelProfilingInfoMask { - KernelProfilingInfoMaskNone = 0, - KernelProfilingInfoCmdExecTimeMask = 0x00000001, -}; - -enum Capability { - CapabilityMatrix = 0, - CapabilityShader = 1, - CapabilityGeometry = 2, - CapabilityTessellation = 3, - CapabilityAddresses = 4, - CapabilityLinkage = 5, - CapabilityKernel = 6, - CapabilityVector16 = 7, - CapabilityFloat16Buffer = 8, - CapabilityFloat16 = 9, - CapabilityFloat64 = 10, - CapabilityInt64 = 11, - CapabilityInt64Atomics = 12, - CapabilityImageBasic = 13, - CapabilityImageReadWrite = 14, - CapabilityImageMipmap = 15, - CapabilityPipes = 17, - CapabilityGroups = 18, - CapabilityDeviceEnqueue = 19, - CapabilityLiteralSampler = 20, - CapabilityAtomicStorage = 21, - CapabilityInt16 = 22, - CapabilityTessellationPointSize = 23, - CapabilityGeometryPointSize = 24, - CapabilityImageGatherExtended = 25, - CapabilityStorageImageMultisample = 27, - CapabilityUniformBufferArrayDynamicIndexing = 28, - CapabilitySampledImageArrayDynamicIndexing = 29, - CapabilityStorageBufferArrayDynamicIndexing = 30, - CapabilityStorageImageArrayDynamicIndexing = 31, - CapabilityClipDistance = 32, - CapabilityCullDistance = 33, - CapabilityImageCubeArray = 34, - CapabilitySampleRateShading = 35, - CapabilityImageRect = 36, - CapabilitySampledRect = 37, - CapabilityGenericPointer = 38, - CapabilityInt8 = 39, - CapabilityInputAttachment = 40, - CapabilitySparseResidency = 41, - CapabilityMinLod = 42, - CapabilitySampled1D = 43, - CapabilityImage1D = 44, - CapabilitySampledCubeArray = 45, - CapabilitySampledBuffer = 46, - CapabilityImageBuffer = 47, - CapabilityImageMSArray = 48, - CapabilityStorageImageExtendedFormats = 49, - CapabilityImageQuery = 50, - CapabilityDerivativeControl = 51, - CapabilityInterpolationFunction = 52, - CapabilityTransformFeedback = 53, - CapabilityGeometryStreams = 54, - CapabilityStorageImageReadWithoutFormat = 55, - CapabilityStorageImageWriteWithoutFormat = 56, - CapabilityMultiViewport = 57, - CapabilitySubgroupDispatch = 58, - CapabilityNamedBarrier = 59, - CapabilityPipeStorage = 60, - CapabilityGroupNonUniform = 61, - CapabilityGroupNonUniformVote = 62, - CapabilityGroupNonUniformArithmetic = 63, - CapabilityGroupNonUniformBallot = 64, - CapabilityGroupNonUniformShuffle = 65, - CapabilityGroupNonUniformShuffleRelative = 66, - CapabilityGroupNonUniformClustered = 67, - CapabilityGroupNonUniformQuad = 68, - CapabilityShaderLayer = 69, - CapabilityShaderViewportIndex = 70, - CapabilityUniformDecoration = 71, - CapabilityFragmentShadingRateKHR = 4422, - CapabilitySubgroupBallotKHR = 4423, - CapabilityDrawParameters = 4427, - CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, - CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, - CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, - CapabilitySubgroupVoteKHR = 4431, - CapabilityStorageBuffer16BitAccess = 4433, - CapabilityStorageUniformBufferBlock16 = 4433, - CapabilityStorageUniform16 = 4434, - CapabilityUniformAndStorageBuffer16BitAccess = 4434, - CapabilityStoragePushConstant16 = 4435, - CapabilityStorageInputOutput16 = 4436, - CapabilityDeviceGroup = 4437, - CapabilityMultiView = 4439, - CapabilityVariablePointersStorageBuffer = 4441, - CapabilityVariablePointers = 4442, - CapabilityAtomicStorageOps = 4445, - CapabilitySampleMaskPostDepthCoverage = 4447, - CapabilityStorageBuffer8BitAccess = 4448, - CapabilityUniformAndStorageBuffer8BitAccess = 4449, - CapabilityStoragePushConstant8 = 4450, - CapabilityDenormPreserve = 4464, - CapabilityDenormFlushToZero = 4465, - CapabilitySignedZeroInfNanPreserve = 4466, - CapabilityRoundingModeRTE = 4467, - CapabilityRoundingModeRTZ = 4468, - CapabilityRayQueryProvisionalKHR = 4471, - CapabilityRayQueryKHR = 4472, - CapabilityRayTraversalPrimitiveCullingKHR = 4478, - CapabilityRayTracingKHR = 4479, - CapabilityFloat16ImageAMD = 5008, - CapabilityImageGatherBiasLodAMD = 5009, - CapabilityFragmentMaskAMD = 5010, - CapabilityStencilExportEXT = 5013, - CapabilityImageReadWriteLodAMD = 5015, - CapabilityInt64ImageEXT = 5016, - CapabilityShaderClockKHR = 5055, - CapabilitySampleMaskOverrideCoverageNV = 5249, - CapabilityGeometryShaderPassthroughNV = 5251, - CapabilityShaderViewportIndexLayerEXT = 5254, - CapabilityShaderViewportIndexLayerNV = 5254, - CapabilityShaderViewportMaskNV = 5255, - CapabilityShaderStereoViewNV = 5259, - CapabilityPerViewAttributesNV = 5260, - CapabilityFragmentFullyCoveredEXT = 5265, - CapabilityMeshShadingNV = 5266, - CapabilityImageFootprintNV = 5282, - CapabilityFragmentBarycentricKHR = 5284, - CapabilityFragmentBarycentricNV = 5284, - CapabilityComputeDerivativeGroupQuadsNV = 5288, - CapabilityFragmentDensityEXT = 5291, - CapabilityShadingRateNV = 5291, - CapabilityGroupNonUniformPartitionedNV = 5297, - CapabilityShaderNonUniform = 5301, - CapabilityShaderNonUniformEXT = 5301, - CapabilityRuntimeDescriptorArray = 5302, - CapabilityRuntimeDescriptorArrayEXT = 5302, - CapabilityInputAttachmentArrayDynamicIndexing = 5303, - CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, - CapabilityUniformTexelBufferArrayDynamicIndexing = 5304, - CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, - CapabilityStorageTexelBufferArrayDynamicIndexing = 5305, - CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, - CapabilityUniformBufferArrayNonUniformIndexing = 5306, - CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, - CapabilitySampledImageArrayNonUniformIndexing = 5307, - CapabilitySampledImageArrayNonUniformIndexingEXT = 5307, - CapabilityStorageBufferArrayNonUniformIndexing = 5308, - CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, - CapabilityStorageImageArrayNonUniformIndexing = 5309, - CapabilityStorageImageArrayNonUniformIndexingEXT = 5309, - CapabilityInputAttachmentArrayNonUniformIndexing = 5310, - CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, - CapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, - CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, - CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, - CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, - CapabilityRayTracingNV = 5340, - CapabilityRayTracingMotionBlurNV = 5341, - CapabilityVulkanMemoryModel = 5345, - CapabilityVulkanMemoryModelKHR = 5345, - CapabilityVulkanMemoryModelDeviceScope = 5346, - CapabilityVulkanMemoryModelDeviceScopeKHR = 5346, - CapabilityPhysicalStorageBufferAddresses = 5347, - CapabilityPhysicalStorageBufferAddressesEXT = 5347, - CapabilityComputeDerivativeGroupLinearNV = 5350, - CapabilityRayTracingProvisionalKHR = 5353, - CapabilityCooperativeMatrixNV = 5357, - CapabilityFragmentShaderSampleInterlockEXT = 5363, - CapabilityFragmentShaderShadingRateInterlockEXT = 5372, - CapabilityShaderSMBuiltinsNV = 5373, - CapabilityFragmentShaderPixelInterlockEXT = 5378, - CapabilityDemoteToHelperInvocation = 5379, - CapabilityDemoteToHelperInvocationEXT = 5379, - CapabilityBindlessTextureNV = 5390, - CapabilitySubgroupShuffleINTEL = 5568, - CapabilitySubgroupBufferBlockIOINTEL = 5569, - CapabilitySubgroupImageBlockIOINTEL = 5570, - CapabilitySubgroupImageMediaBlockIOINTEL = 5579, - CapabilityRoundToInfinityINTEL = 5582, - CapabilityFloatingPointModeINTEL = 5583, - CapabilityIntegerFunctions2INTEL = 5584, - CapabilityFunctionPointersINTEL = 5603, - CapabilityIndirectReferencesINTEL = 5604, - CapabilityAsmINTEL = 5606, - CapabilityAtomicFloat32MinMaxEXT = 5612, - CapabilityAtomicFloat64MinMaxEXT = 5613, - CapabilityAtomicFloat16MinMaxEXT = 5616, - CapabilityVectorComputeINTEL = 5617, - CapabilityVectorAnyINTEL = 5619, - CapabilityExpectAssumeKHR = 5629, - CapabilitySubgroupAvcMotionEstimationINTEL = 5696, - CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, - CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, - CapabilityVariableLengthArrayINTEL = 5817, - CapabilityFunctionFloatControlINTEL = 5821, - CapabilityFPGAMemoryAttributesINTEL = 5824, - CapabilityFPFastMathModeINTEL = 5837, - CapabilityArbitraryPrecisionIntegersINTEL = 5844, - CapabilityArbitraryPrecisionFloatingPointINTEL = 5845, - CapabilityUnstructuredLoopControlsINTEL = 5886, - CapabilityFPGALoopControlsINTEL = 5888, - CapabilityKernelAttributesINTEL = 5892, - CapabilityFPGAKernelAttributesINTEL = 5897, - CapabilityFPGAMemoryAccessesINTEL = 5898, - CapabilityFPGAClusterAttributesINTEL = 5904, - CapabilityLoopFuseINTEL = 5906, - CapabilityMemoryAccessAliasingINTEL = 5910, - CapabilityFPGABufferLocationINTEL = 5920, - CapabilityArbitraryPrecisionFixedPointINTEL = 5922, - CapabilityUSMStorageClassesINTEL = 5935, - CapabilityIOPipesINTEL = 5943, - CapabilityBlockingPipesINTEL = 5945, - CapabilityFPGARegINTEL = 5948, - CapabilityDotProductInputAll = 6016, - CapabilityDotProductInputAllKHR = 6016, - CapabilityDotProductInput4x8Bit = 6017, - CapabilityDotProductInput4x8BitKHR = 6017, - CapabilityDotProductInput4x8BitPacked = 6018, - CapabilityDotProductInput4x8BitPackedKHR = 6018, - CapabilityDotProduct = 6019, - CapabilityDotProductKHR = 6019, - CapabilityRayCullMaskKHR = 6020, - CapabilityBitInstructions = 6025, - CapabilityGroupNonUniformRotateKHR = 6026, - CapabilityAtomicFloat32AddEXT = 6033, - CapabilityAtomicFloat64AddEXT = 6034, - CapabilityLongConstantCompositeINTEL = 6089, - CapabilityOptNoneINTEL = 6094, - CapabilityAtomicFloat16AddEXT = 6095, - CapabilityDebugInfoModuleINTEL = 6114, - CapabilitySplitBarrierINTEL = 6141, - CapabilityGroupUniformArithmeticKHR = 6400, - CapabilityMax = 0x7fffffff, -}; - -enum RayFlagsShift { - RayFlagsOpaqueKHRShift = 0, - RayFlagsNoOpaqueKHRShift = 1, - RayFlagsTerminateOnFirstHitKHRShift = 2, - RayFlagsSkipClosestHitShaderKHRShift = 3, - RayFlagsCullBackFacingTrianglesKHRShift = 4, - RayFlagsCullFrontFacingTrianglesKHRShift = 5, - RayFlagsCullOpaqueKHRShift = 6, - RayFlagsCullNoOpaqueKHRShift = 7, - RayFlagsSkipTrianglesKHRShift = 8, - RayFlagsSkipAABBsKHRShift = 9, - RayFlagsMax = 0x7fffffff, -}; - -enum RayFlagsMask { - RayFlagsMaskNone = 0, - RayFlagsOpaqueKHRMask = 0x00000001, - RayFlagsNoOpaqueKHRMask = 0x00000002, - RayFlagsTerminateOnFirstHitKHRMask = 0x00000004, - RayFlagsSkipClosestHitShaderKHRMask = 0x00000008, - RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, - RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, - RayFlagsCullOpaqueKHRMask = 0x00000040, - RayFlagsCullNoOpaqueKHRMask = 0x00000080, - RayFlagsSkipTrianglesKHRMask = 0x00000100, - RayFlagsSkipAABBsKHRMask = 0x00000200, -}; - -enum RayQueryIntersection { - RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, - RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, - RayQueryIntersectionMax = 0x7fffffff, -}; - -enum RayQueryCommittedIntersectionType { - RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, - RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, - RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, - RayQueryCommittedIntersectionTypeMax = 0x7fffffff, -}; - -enum RayQueryCandidateIntersectionType { - RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, - RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, - RayQueryCandidateIntersectionTypeMax = 0x7fffffff, -}; - -enum FragmentShadingRateShift { - FragmentShadingRateVertical2PixelsShift = 0, - FragmentShadingRateVertical4PixelsShift = 1, - FragmentShadingRateHorizontal2PixelsShift = 2, - FragmentShadingRateHorizontal4PixelsShift = 3, - FragmentShadingRateMax = 0x7fffffff, -}; - -enum FragmentShadingRateMask { - FragmentShadingRateMaskNone = 0, - FragmentShadingRateVertical2PixelsMask = 0x00000001, - FragmentShadingRateVertical4PixelsMask = 0x00000002, - FragmentShadingRateHorizontal2PixelsMask = 0x00000004, - FragmentShadingRateHorizontal4PixelsMask = 0x00000008, -}; - -enum FPDenormMode { - FPDenormModePreserve = 0, - FPDenormModeFlushToZero = 1, - FPDenormModeMax = 0x7fffffff, -}; - -enum FPOperationMode { - FPOperationModeIEEE = 0, - FPOperationModeALT = 1, - FPOperationModeMax = 0x7fffffff, -}; - -enum QuantizationModes { - QuantizationModesTRN = 0, - QuantizationModesTRN_ZERO = 1, - QuantizationModesRND = 2, - QuantizationModesRND_ZERO = 3, - QuantizationModesRND_INF = 4, - QuantizationModesRND_MIN_INF = 5, - QuantizationModesRND_CONV = 6, - QuantizationModesRND_CONV_ODD = 7, - QuantizationModesMax = 0x7fffffff, -}; - -enum OverflowModes { - OverflowModesWRAP = 0, - OverflowModesSAT = 1, - OverflowModesSAT_ZERO = 2, - OverflowModesSAT_SYM = 3, - OverflowModesMax = 0x7fffffff, -}; - -enum PackedVectorFormat { - PackedVectorFormatPackedVectorFormat4x8Bit = 0, - PackedVectorFormatPackedVectorFormat4x8BitKHR = 0, - PackedVectorFormatMax = 0x7fffffff, -}; - -enum Op { - OpNop = 0, - OpUndef = 1, - OpSourceContinued = 2, - OpSource = 3, - OpSourceExtension = 4, - OpName = 5, - OpMemberName = 6, - OpString = 7, - OpLine = 8, - OpExtension = 10, - OpExtInstImport = 11, - OpExtInst = 12, - OpMemoryModel = 14, - OpEntryPoint = 15, - OpExecutionMode = 16, - OpCapability = 17, - OpTypeVoid = 19, - OpTypeBool = 20, - OpTypeInt = 21, - OpTypeFloat = 22, - OpTypeVector = 23, - OpTypeMatrix = 24, - OpTypeImage = 25, - OpTypeSampler = 26, - OpTypeSampledImage = 27, - OpTypeArray = 28, - OpTypeRuntimeArray = 29, - OpTypeStruct = 30, - OpTypeOpaque = 31, - OpTypePointer = 32, - OpTypeFunction = 33, - OpTypeEvent = 34, - OpTypeDeviceEvent = 35, - OpTypeReserveId = 36, - OpTypeQueue = 37, - OpTypePipe = 38, - OpTypeForwardPointer = 39, - OpConstantTrue = 41, - OpConstantFalse = 42, - OpConstant = 43, - OpConstantComposite = 44, - OpConstantSampler = 45, - OpConstantNull = 46, - OpSpecConstantTrue = 48, - OpSpecConstantFalse = 49, - OpSpecConstant = 50, - OpSpecConstantComposite = 51, - OpSpecConstantOp = 52, - OpFunction = 54, - OpFunctionParameter = 55, - OpFunctionEnd = 56, - OpFunctionCall = 57, - OpVariable = 59, - OpImageTexelPointer = 60, - OpLoad = 61, - OpStore = 62, - OpCopyMemory = 63, - OpCopyMemorySized = 64, - OpAccessChain = 65, - OpInBoundsAccessChain = 66, - OpPtrAccessChain = 67, - OpArrayLength = 68, - OpGenericPtrMemSemantics = 69, - OpInBoundsPtrAccessChain = 70, - OpDecorate = 71, - OpMemberDecorate = 72, - OpDecorationGroup = 73, - OpGroupDecorate = 74, - OpGroupMemberDecorate = 75, - OpVectorExtractDynamic = 77, - OpVectorInsertDynamic = 78, - OpVectorShuffle = 79, - OpCompositeConstruct = 80, - OpCompositeExtract = 81, - OpCompositeInsert = 82, - OpCopyObject = 83, - OpTranspose = 84, - OpSampledImage = 86, - OpImageSampleImplicitLod = 87, - OpImageSampleExplicitLod = 88, - OpImageSampleDrefImplicitLod = 89, - OpImageSampleDrefExplicitLod = 90, - OpImageSampleProjImplicitLod = 91, - OpImageSampleProjExplicitLod = 92, - OpImageSampleProjDrefImplicitLod = 93, - OpImageSampleProjDrefExplicitLod = 94, - OpImageFetch = 95, - OpImageGather = 96, - OpImageDrefGather = 97, - OpImageRead = 98, - OpImageWrite = 99, - OpImage = 100, - OpImageQueryFormat = 101, - OpImageQueryOrder = 102, - OpImageQuerySizeLod = 103, - OpImageQuerySize = 104, - OpImageQueryLod = 105, - OpImageQueryLevels = 106, - OpImageQuerySamples = 107, - OpConvertFToU = 109, - OpConvertFToS = 110, - OpConvertSToF = 111, - OpConvertUToF = 112, - OpUConvert = 113, - OpSConvert = 114, - OpFConvert = 115, - OpQuantizeToF16 = 116, - OpConvertPtrToU = 117, - OpSatConvertSToU = 118, - OpSatConvertUToS = 119, - OpConvertUToPtr = 120, - OpPtrCastToGeneric = 121, - OpGenericCastToPtr = 122, - OpGenericCastToPtrExplicit = 123, - OpBitcast = 124, - OpSNegate = 126, - OpFNegate = 127, - OpIAdd = 128, - OpFAdd = 129, - OpISub = 130, - OpFSub = 131, - OpIMul = 132, - OpFMul = 133, - OpUDiv = 134, - OpSDiv = 135, - OpFDiv = 136, - OpUMod = 137, - OpSRem = 138, - OpSMod = 139, - OpFRem = 140, - OpFMod = 141, - OpVectorTimesScalar = 142, - OpMatrixTimesScalar = 143, - OpVectorTimesMatrix = 144, - OpMatrixTimesVector = 145, - OpMatrixTimesMatrix = 146, - OpOuterProduct = 147, - OpDot = 148, - OpIAddCarry = 149, - OpISubBorrow = 150, - OpUMulExtended = 151, - OpSMulExtended = 152, - OpAny = 154, - OpAll = 155, - OpIsNan = 156, - OpIsInf = 157, - OpIsFinite = 158, - OpIsNormal = 159, - OpSignBitSet = 160, - OpLessOrGreater = 161, - OpOrdered = 162, - OpUnordered = 163, - OpLogicalEqual = 164, - OpLogicalNotEqual = 165, - OpLogicalOr = 166, - OpLogicalAnd = 167, - OpLogicalNot = 168, - OpSelect = 169, - OpIEqual = 170, - OpINotEqual = 171, - OpUGreaterThan = 172, - OpSGreaterThan = 173, - OpUGreaterThanEqual = 174, - OpSGreaterThanEqual = 175, - OpULessThan = 176, - OpSLessThan = 177, - OpULessThanEqual = 178, - OpSLessThanEqual = 179, - OpFOrdEqual = 180, - OpFUnordEqual = 181, - OpFOrdNotEqual = 182, - OpFUnordNotEqual = 183, - OpFOrdLessThan = 184, - OpFUnordLessThan = 185, - OpFOrdGreaterThan = 186, - OpFUnordGreaterThan = 187, - OpFOrdLessThanEqual = 188, - OpFUnordLessThanEqual = 189, - OpFOrdGreaterThanEqual = 190, - OpFUnordGreaterThanEqual = 191, - OpShiftRightLogical = 194, - OpShiftRightArithmetic = 195, - OpShiftLeftLogical = 196, - OpBitwiseOr = 197, - OpBitwiseXor = 198, - OpBitwiseAnd = 199, - OpNot = 200, - OpBitFieldInsert = 201, - OpBitFieldSExtract = 202, - OpBitFieldUExtract = 203, - OpBitReverse = 204, - OpBitCount = 205, - OpDPdx = 207, - OpDPdy = 208, - OpFwidth = 209, - OpDPdxFine = 210, - OpDPdyFine = 211, - OpFwidthFine = 212, - OpDPdxCoarse = 213, - OpDPdyCoarse = 214, - OpFwidthCoarse = 215, - OpEmitVertex = 218, - OpEndPrimitive = 219, - OpEmitStreamVertex = 220, - OpEndStreamPrimitive = 221, - OpControlBarrier = 224, - OpMemoryBarrier = 225, - OpAtomicLoad = 227, - OpAtomicStore = 228, - OpAtomicExchange = 229, - OpAtomicCompareExchange = 230, - OpAtomicCompareExchangeWeak = 231, - OpAtomicIIncrement = 232, - OpAtomicIDecrement = 233, - OpAtomicIAdd = 234, - OpAtomicISub = 235, - OpAtomicSMin = 236, - OpAtomicUMin = 237, - OpAtomicSMax = 238, - OpAtomicUMax = 239, - OpAtomicAnd = 240, - OpAtomicOr = 241, - OpAtomicXor = 242, - OpPhi = 245, - OpLoopMerge = 246, - OpSelectionMerge = 247, - OpLabel = 248, - OpBranch = 249, - OpBranchConditional = 250, - OpSwitch = 251, - OpKill = 252, - OpReturn = 253, - OpReturnValue = 254, - OpUnreachable = 255, - OpLifetimeStart = 256, - OpLifetimeStop = 257, - OpGroupAsyncCopy = 259, - OpGroupWaitEvents = 260, - OpGroupAll = 261, - OpGroupAny = 262, - OpGroupBroadcast = 263, - OpGroupIAdd = 264, - OpGroupFAdd = 265, - OpGroupFMin = 266, - OpGroupUMin = 267, - OpGroupSMin = 268, - OpGroupFMax = 269, - OpGroupUMax = 270, - OpGroupSMax = 271, - OpReadPipe = 274, - OpWritePipe = 275, - OpReservedReadPipe = 276, - OpReservedWritePipe = 277, - OpReserveReadPipePackets = 278, - OpReserveWritePipePackets = 279, - OpCommitReadPipe = 280, - OpCommitWritePipe = 281, - OpIsValidReserveId = 282, - OpGetNumPipePackets = 283, - OpGetMaxPipePackets = 284, - OpGroupReserveReadPipePackets = 285, - OpGroupReserveWritePipePackets = 286, - OpGroupCommitReadPipe = 287, - OpGroupCommitWritePipe = 288, - OpEnqueueMarker = 291, - OpEnqueueKernel = 292, - OpGetKernelNDrangeSubGroupCount = 293, - OpGetKernelNDrangeMaxSubGroupSize = 294, - OpGetKernelWorkGroupSize = 295, - OpGetKernelPreferredWorkGroupSizeMultiple = 296, - OpRetainEvent = 297, - OpReleaseEvent = 298, - OpCreateUserEvent = 299, - OpIsValidEvent = 300, - OpSetUserEventStatus = 301, - OpCaptureEventProfilingInfo = 302, - OpGetDefaultQueue = 303, - OpBuildNDRange = 304, - OpImageSparseSampleImplicitLod = 305, - OpImageSparseSampleExplicitLod = 306, - OpImageSparseSampleDrefImplicitLod = 307, - OpImageSparseSampleDrefExplicitLod = 308, - OpImageSparseSampleProjImplicitLod = 309, - OpImageSparseSampleProjExplicitLod = 310, - OpImageSparseSampleProjDrefImplicitLod = 311, - OpImageSparseSampleProjDrefExplicitLod = 312, - OpImageSparseFetch = 313, - OpImageSparseGather = 314, - OpImageSparseDrefGather = 315, - OpImageSparseTexelsResident = 316, - OpNoLine = 317, - OpAtomicFlagTestAndSet = 318, - OpAtomicFlagClear = 319, - OpImageSparseRead = 320, - OpSizeOf = 321, - OpTypePipeStorage = 322, - OpConstantPipeStorage = 323, - OpCreatePipeFromPipeStorage = 324, - OpGetKernelLocalSizeForSubgroupCount = 325, - OpGetKernelMaxNumSubgroups = 326, - OpTypeNamedBarrier = 327, - OpNamedBarrierInitialize = 328, - OpMemoryNamedBarrier = 329, - OpModuleProcessed = 330, - OpExecutionModeId = 331, - OpDecorateId = 332, - OpGroupNonUniformElect = 333, - OpGroupNonUniformAll = 334, - OpGroupNonUniformAny = 335, - OpGroupNonUniformAllEqual = 336, - OpGroupNonUniformBroadcast = 337, - OpGroupNonUniformBroadcastFirst = 338, - OpGroupNonUniformBallot = 339, - OpGroupNonUniformInverseBallot = 340, - OpGroupNonUniformBallotBitExtract = 341, - OpGroupNonUniformBallotBitCount = 342, - OpGroupNonUniformBallotFindLSB = 343, - OpGroupNonUniformBallotFindMSB = 344, - OpGroupNonUniformShuffle = 345, - OpGroupNonUniformShuffleXor = 346, - OpGroupNonUniformShuffleUp = 347, - OpGroupNonUniformShuffleDown = 348, - OpGroupNonUniformIAdd = 349, - OpGroupNonUniformFAdd = 350, - OpGroupNonUniformIMul = 351, - OpGroupNonUniformFMul = 352, - OpGroupNonUniformSMin = 353, - OpGroupNonUniformUMin = 354, - OpGroupNonUniformFMin = 355, - OpGroupNonUniformSMax = 356, - OpGroupNonUniformUMax = 357, - OpGroupNonUniformFMax = 358, - OpGroupNonUniformBitwiseAnd = 359, - OpGroupNonUniformBitwiseOr = 360, - OpGroupNonUniformBitwiseXor = 361, - OpGroupNonUniformLogicalAnd = 362, - OpGroupNonUniformLogicalOr = 363, - OpGroupNonUniformLogicalXor = 364, - OpGroupNonUniformQuadBroadcast = 365, - OpGroupNonUniformQuadSwap = 366, - OpCopyLogical = 400, - OpPtrEqual = 401, - OpPtrNotEqual = 402, - OpPtrDiff = 403, - OpTerminateInvocation = 4416, - OpSubgroupBallotKHR = 4421, - OpSubgroupFirstInvocationKHR = 4422, - OpSubgroupAllKHR = 4428, - OpSubgroupAnyKHR = 4429, - OpSubgroupAllEqualKHR = 4430, - OpGroupNonUniformRotateKHR = 4431, - OpSubgroupReadInvocationKHR = 4432, - OpTraceRayKHR = 4445, - OpExecuteCallableKHR = 4446, - OpConvertUToAccelerationStructureKHR = 4447, - OpIgnoreIntersectionKHR = 4448, - OpTerminateRayKHR = 4449, - OpSDot = 4450, - OpSDotKHR = 4450, - OpUDot = 4451, - OpUDotKHR = 4451, - OpSUDot = 4452, - OpSUDotKHR = 4452, - OpSDotAccSat = 4453, - OpSDotAccSatKHR = 4453, - OpUDotAccSat = 4454, - OpUDotAccSatKHR = 4454, - OpSUDotAccSat = 4455, - OpSUDotAccSatKHR = 4455, - OpTypeRayQueryKHR = 4472, - OpRayQueryInitializeKHR = 4473, - OpRayQueryTerminateKHR = 4474, - OpRayQueryGenerateIntersectionKHR = 4475, - OpRayQueryConfirmIntersectionKHR = 4476, - OpRayQueryProceedKHR = 4477, - OpRayQueryGetIntersectionTypeKHR = 4479, - OpGroupIAddNonUniformAMD = 5000, - OpGroupFAddNonUniformAMD = 5001, - OpGroupFMinNonUniformAMD = 5002, - OpGroupUMinNonUniformAMD = 5003, - OpGroupSMinNonUniformAMD = 5004, - OpGroupFMaxNonUniformAMD = 5005, - OpGroupUMaxNonUniformAMD = 5006, - OpGroupSMaxNonUniformAMD = 5007, - OpFragmentMaskFetchAMD = 5011, - OpFragmentFetchAMD = 5012, - OpReadClockKHR = 5056, - OpImageSampleFootprintNV = 5283, - OpGroupNonUniformPartitionNV = 5296, - OpWritePackedPrimitiveIndices4x8NV = 5299, - OpReportIntersectionKHR = 5334, - OpReportIntersectionNV = 5334, - OpIgnoreIntersectionNV = 5335, - OpTerminateRayNV = 5336, - OpTraceNV = 5337, - OpTraceMotionNV = 5338, - OpTraceRayMotionNV = 5339, - OpTypeAccelerationStructureKHR = 5341, - OpTypeAccelerationStructureNV = 5341, - OpExecuteCallableNV = 5344, - OpTypeCooperativeMatrixNV = 5358, - OpCooperativeMatrixLoadNV = 5359, - OpCooperativeMatrixStoreNV = 5360, - OpCooperativeMatrixMulAddNV = 5361, - OpCooperativeMatrixLengthNV = 5362, - OpBeginInvocationInterlockEXT = 5364, - OpEndInvocationInterlockEXT = 5365, - OpDemoteToHelperInvocation = 5380, - OpDemoteToHelperInvocationEXT = 5380, - OpIsHelperInvocationEXT = 5381, - OpConvertUToImageNV = 5391, - OpConvertUToSamplerNV = 5392, - OpConvertImageToUNV = 5393, - OpConvertSamplerToUNV = 5394, - OpConvertUToSampledImageNV = 5395, - OpConvertSampledImageToUNV = 5396, - OpSamplerImageAddressingModeNV = 5397, - OpSubgroupShuffleINTEL = 5571, - OpSubgroupShuffleDownINTEL = 5572, - OpSubgroupShuffleUpINTEL = 5573, - OpSubgroupShuffleXorINTEL = 5574, - OpSubgroupBlockReadINTEL = 5575, - OpSubgroupBlockWriteINTEL = 5576, - OpSubgroupImageBlockReadINTEL = 5577, - OpSubgroupImageBlockWriteINTEL = 5578, - OpSubgroupImageMediaBlockReadINTEL = 5580, - OpSubgroupImageMediaBlockWriteINTEL = 5581, - OpUCountLeadingZerosINTEL = 5585, - OpUCountTrailingZerosINTEL = 5586, - OpAbsISubINTEL = 5587, - OpAbsUSubINTEL = 5588, - OpIAddSatINTEL = 5589, - OpUAddSatINTEL = 5590, - OpIAverageINTEL = 5591, - OpUAverageINTEL = 5592, - OpIAverageRoundedINTEL = 5593, - OpUAverageRoundedINTEL = 5594, - OpISubSatINTEL = 5595, - OpUSubSatINTEL = 5596, - OpIMul32x16INTEL = 5597, - OpUMul32x16INTEL = 5598, - OpConstantFunctionPointerINTEL = 5600, - OpFunctionPointerCallINTEL = 5601, - OpAsmTargetINTEL = 5609, - OpAsmINTEL = 5610, - OpAsmCallINTEL = 5611, - OpAtomicFMinEXT = 5614, - OpAtomicFMaxEXT = 5615, - OpAssumeTrueKHR = 5630, - OpExpectKHR = 5631, - OpDecorateString = 5632, - OpDecorateStringGOOGLE = 5632, - OpMemberDecorateString = 5633, - OpMemberDecorateStringGOOGLE = 5633, - OpVmeImageINTEL = 5699, - OpTypeVmeImageINTEL = 5700, - OpTypeAvcImePayloadINTEL = 5701, - OpTypeAvcRefPayloadINTEL = 5702, - OpTypeAvcSicPayloadINTEL = 5703, - OpTypeAvcMcePayloadINTEL = 5704, - OpTypeAvcMceResultINTEL = 5705, - OpTypeAvcImeResultINTEL = 5706, - OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, - OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, - OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, - OpTypeAvcImeDualReferenceStreaminINTEL = 5710, - OpTypeAvcRefResultINTEL = 5711, - OpTypeAvcSicResultINTEL = 5712, - OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, - OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, - OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, - OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, - OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, - OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, - OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, - OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, - OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, - OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, - OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, - OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, - OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, - OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, - OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, - OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, - OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, - OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, - OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, - OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, - OpSubgroupAvcMceConvertToImeResultINTEL = 5733, - OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, - OpSubgroupAvcMceConvertToRefResultINTEL = 5735, - OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, - OpSubgroupAvcMceConvertToSicResultINTEL = 5737, - OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, - OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, - OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, - OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, - OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, - OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, - OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, - OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, - OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, - OpSubgroupAvcImeInitializeINTEL = 5747, - OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, - OpSubgroupAvcImeSetDualReferenceINTEL = 5749, - OpSubgroupAvcImeRefWindowSizeINTEL = 5750, - OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, - OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, - OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, - OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, - OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, - OpSubgroupAvcImeSetWeightedSadINTEL = 5756, - OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, - OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, - OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, - OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, - OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, - OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, - OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, - OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, - OpSubgroupAvcImeConvertToMceResultINTEL = 5765, - OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, - OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, - OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, - OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, - OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, - OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, - OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, - OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, - OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, - OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, - OpSubgroupAvcImeGetBorderReachedINTEL = 5776, - OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, - OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, - OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, - OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, - OpSubgroupAvcFmeInitializeINTEL = 5781, - OpSubgroupAvcBmeInitializeINTEL = 5782, - OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, - OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, - OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, - OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, - OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, - OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, - OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, - OpSubgroupAvcRefConvertToMceResultINTEL = 5790, - OpSubgroupAvcSicInitializeINTEL = 5791, - OpSubgroupAvcSicConfigureSkcINTEL = 5792, - OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, - OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, - OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, - OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, - OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, - OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, - OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, - OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, - OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, - OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, - OpSubgroupAvcSicEvaluateIpeINTEL = 5803, - OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, - OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, - OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, - OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, - OpSubgroupAvcSicConvertToMceResultINTEL = 5808, - OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, - OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, - OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, - OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, - OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, - OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, - OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, - OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, - OpVariableLengthArrayINTEL = 5818, - OpSaveMemoryINTEL = 5819, - OpRestoreMemoryINTEL = 5820, - OpArbitraryFloatSinCosPiINTEL = 5840, - OpArbitraryFloatCastINTEL = 5841, - OpArbitraryFloatCastFromIntINTEL = 5842, - OpArbitraryFloatCastToIntINTEL = 5843, - OpArbitraryFloatAddINTEL = 5846, - OpArbitraryFloatSubINTEL = 5847, - OpArbitraryFloatMulINTEL = 5848, - OpArbitraryFloatDivINTEL = 5849, - OpArbitraryFloatGTINTEL = 5850, - OpArbitraryFloatGEINTEL = 5851, - OpArbitraryFloatLTINTEL = 5852, - OpArbitraryFloatLEINTEL = 5853, - OpArbitraryFloatEQINTEL = 5854, - OpArbitraryFloatRecipINTEL = 5855, - OpArbitraryFloatRSqrtINTEL = 5856, - OpArbitraryFloatCbrtINTEL = 5857, - OpArbitraryFloatHypotINTEL = 5858, - OpArbitraryFloatSqrtINTEL = 5859, - OpArbitraryFloatLogINTEL = 5860, - OpArbitraryFloatLog2INTEL = 5861, - OpArbitraryFloatLog10INTEL = 5862, - OpArbitraryFloatLog1pINTEL = 5863, - OpArbitraryFloatExpINTEL = 5864, - OpArbitraryFloatExp2INTEL = 5865, - OpArbitraryFloatExp10INTEL = 5866, - OpArbitraryFloatExpm1INTEL = 5867, - OpArbitraryFloatSinINTEL = 5868, - OpArbitraryFloatCosINTEL = 5869, - OpArbitraryFloatSinCosINTEL = 5870, - OpArbitraryFloatSinPiINTEL = 5871, - OpArbitraryFloatCosPiINTEL = 5872, - OpArbitraryFloatASinINTEL = 5873, - OpArbitraryFloatASinPiINTEL = 5874, - OpArbitraryFloatACosINTEL = 5875, - OpArbitraryFloatACosPiINTEL = 5876, - OpArbitraryFloatATanINTEL = 5877, - OpArbitraryFloatATanPiINTEL = 5878, - OpArbitraryFloatATan2INTEL = 5879, - OpArbitraryFloatPowINTEL = 5880, - OpArbitraryFloatPowRINTEL = 5881, - OpArbitraryFloatPowNINTEL = 5882, - OpLoopControlINTEL = 5887, - OpAliasDomainDeclINTEL = 5911, - OpAliasScopeDeclINTEL = 5912, - OpAliasScopeListDeclINTEL = 5913, - OpFixedSqrtINTEL = 5923, - OpFixedRecipINTEL = 5924, - OpFixedRsqrtINTEL = 5925, - OpFixedSinINTEL = 5926, - OpFixedCosINTEL = 5927, - OpFixedSinCosINTEL = 5928, - OpFixedSinPiINTEL = 5929, - OpFixedCosPiINTEL = 5930, - OpFixedSinCosPiINTEL = 5931, - OpFixedLogINTEL = 5932, - OpFixedExpINTEL = 5933, - OpPtrCastToCrossWorkgroupINTEL = 5934, - OpCrossWorkgroupCastToPtrINTEL = 5938, - OpReadPipeBlockingINTEL = 5946, - OpWritePipeBlockingINTEL = 5947, - OpFPGARegINTEL = 5949, - OpRayQueryGetRayTMinKHR = 6016, - OpRayQueryGetRayFlagsKHR = 6017, - OpRayQueryGetIntersectionTKHR = 6018, - OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, - OpRayQueryGetIntersectionInstanceIdKHR = 6020, - OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, - OpRayQueryGetIntersectionGeometryIndexKHR = 6022, - OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, - OpRayQueryGetIntersectionBarycentricsKHR = 6024, - OpRayQueryGetIntersectionFrontFaceKHR = 6025, - OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, - OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, - OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, - OpRayQueryGetWorldRayDirectionKHR = 6029, - OpRayQueryGetWorldRayOriginKHR = 6030, - OpRayQueryGetIntersectionObjectToWorldKHR = 6031, - OpRayQueryGetIntersectionWorldToObjectKHR = 6032, - OpAtomicFAddEXT = 6035, - OpTypeBufferSurfaceINTEL = 6086, - OpTypeStructContinuedINTEL = 6090, - OpConstantCompositeContinuedINTEL = 6091, - OpSpecConstantCompositeContinuedINTEL = 6092, - OpControlBarrierArriveINTEL = 6142, - OpControlBarrierWaitINTEL = 6143, - OpGroupIMulKHR = 6401, - OpGroupFMulKHR = 6402, - OpGroupBitwiseAndKHR = 6403, - OpGroupBitwiseOrKHR = 6404, - OpGroupBitwiseXorKHR = 6405, - OpGroupLogicalAndKHR = 6406, - OpGroupLogicalOrKHR = 6407, - OpGroupLogicalXorKHR = 6408, - OpMax = 0x7fffffff, -}; - -#ifdef SPV_ENABLE_UTILITY_CODE -#ifndef __cplusplus -#include -#endif -inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { - *hasResult = *hasResultType = false; - switch (opcode) { - default: /* unknown opcode */ break; - case OpNop: *hasResult = false; *hasResultType = false; break; - case OpUndef: *hasResult = true; *hasResultType = true; break; - case OpSourceContinued: *hasResult = false; *hasResultType = false; break; - case OpSource: *hasResult = false; *hasResultType = false; break; - case OpSourceExtension: *hasResult = false; *hasResultType = false; break; - case OpName: *hasResult = false; *hasResultType = false; break; - case OpMemberName: *hasResult = false; *hasResultType = false; break; - case OpString: *hasResult = true; *hasResultType = false; break; - case OpLine: *hasResult = false; *hasResultType = false; break; - case OpExtension: *hasResult = false; *hasResultType = false; break; - case OpExtInstImport: *hasResult = true; *hasResultType = false; break; - case OpExtInst: *hasResult = true; *hasResultType = true; break; - case OpMemoryModel: *hasResult = false; *hasResultType = false; break; - case OpEntryPoint: *hasResult = false; *hasResultType = false; break; - case OpExecutionMode: *hasResult = false; *hasResultType = false; break; - case OpCapability: *hasResult = false; *hasResultType = false; break; - case OpTypeVoid: *hasResult = true; *hasResultType = false; break; - case OpTypeBool: *hasResult = true; *hasResultType = false; break; - case OpTypeInt: *hasResult = true; *hasResultType = false; break; - case OpTypeFloat: *hasResult = true; *hasResultType = false; break; - case OpTypeVector: *hasResult = true; *hasResultType = false; break; - case OpTypeMatrix: *hasResult = true; *hasResultType = false; break; - case OpTypeImage: *hasResult = true; *hasResultType = false; break; - case OpTypeSampler: *hasResult = true; *hasResultType = false; break; - case OpTypeSampledImage: *hasResult = true; *hasResultType = false; break; - case OpTypeArray: *hasResult = true; *hasResultType = false; break; - case OpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; - case OpTypeStruct: *hasResult = true; *hasResultType = false; break; - case OpTypeOpaque: *hasResult = true; *hasResultType = false; break; - case OpTypePointer: *hasResult = true; *hasResultType = false; break; - case OpTypeFunction: *hasResult = true; *hasResultType = false; break; - case OpTypeEvent: *hasResult = true; *hasResultType = false; break; - case OpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; - case OpTypeReserveId: *hasResult = true; *hasResultType = false; break; - case OpTypeQueue: *hasResult = true; *hasResultType = false; break; - case OpTypePipe: *hasResult = true; *hasResultType = false; break; - case OpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; - case OpConstantTrue: *hasResult = true; *hasResultType = true; break; - case OpConstantFalse: *hasResult = true; *hasResultType = true; break; - case OpConstant: *hasResult = true; *hasResultType = true; break; - case OpConstantComposite: *hasResult = true; *hasResultType = true; break; - case OpConstantSampler: *hasResult = true; *hasResultType = true; break; - case OpConstantNull: *hasResult = true; *hasResultType = true; break; - case OpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; - case OpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; - case OpSpecConstant: *hasResult = true; *hasResultType = true; break; - case OpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; - case OpSpecConstantOp: *hasResult = true; *hasResultType = true; break; - case OpFunction: *hasResult = true; *hasResultType = true; break; - case OpFunctionParameter: *hasResult = true; *hasResultType = true; break; - case OpFunctionEnd: *hasResult = false; *hasResultType = false; break; - case OpFunctionCall: *hasResult = true; *hasResultType = true; break; - case OpVariable: *hasResult = true; *hasResultType = true; break; - case OpImageTexelPointer: *hasResult = true; *hasResultType = true; break; - case OpLoad: *hasResult = true; *hasResultType = true; break; - case OpStore: *hasResult = false; *hasResultType = false; break; - case OpCopyMemory: *hasResult = false; *hasResultType = false; break; - case OpCopyMemorySized: *hasResult = false; *hasResultType = false; break; - case OpAccessChain: *hasResult = true; *hasResultType = true; break; - case OpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; - case OpPtrAccessChain: *hasResult = true; *hasResultType = true; break; - case OpArrayLength: *hasResult = true; *hasResultType = true; break; - case OpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; - case OpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; - case OpDecorate: *hasResult = false; *hasResultType = false; break; - case OpMemberDecorate: *hasResult = false; *hasResultType = false; break; - case OpDecorationGroup: *hasResult = true; *hasResultType = false; break; - case OpGroupDecorate: *hasResult = false; *hasResultType = false; break; - case OpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; - case OpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; - case OpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; - case OpVectorShuffle: *hasResult = true; *hasResultType = true; break; - case OpCompositeConstruct: *hasResult = true; *hasResultType = true; break; - case OpCompositeExtract: *hasResult = true; *hasResultType = true; break; - case OpCompositeInsert: *hasResult = true; *hasResultType = true; break; - case OpCopyObject: *hasResult = true; *hasResultType = true; break; - case OpTranspose: *hasResult = true; *hasResultType = true; break; - case OpSampledImage: *hasResult = true; *hasResultType = true; break; - case OpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageFetch: *hasResult = true; *hasResultType = true; break; - case OpImageGather: *hasResult = true; *hasResultType = true; break; - case OpImageDrefGather: *hasResult = true; *hasResultType = true; break; - case OpImageRead: *hasResult = true; *hasResultType = true; break; - case OpImageWrite: *hasResult = false; *hasResultType = false; break; - case OpImage: *hasResult = true; *hasResultType = true; break; - case OpImageQueryFormat: *hasResult = true; *hasResultType = true; break; - case OpImageQueryOrder: *hasResult = true; *hasResultType = true; break; - case OpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; - case OpImageQuerySize: *hasResult = true; *hasResultType = true; break; - case OpImageQueryLod: *hasResult = true; *hasResultType = true; break; - case OpImageQueryLevels: *hasResult = true; *hasResultType = true; break; - case OpImageQuerySamples: *hasResult = true; *hasResultType = true; break; - case OpConvertFToU: *hasResult = true; *hasResultType = true; break; - case OpConvertFToS: *hasResult = true; *hasResultType = true; break; - case OpConvertSToF: *hasResult = true; *hasResultType = true; break; - case OpConvertUToF: *hasResult = true; *hasResultType = true; break; - case OpUConvert: *hasResult = true; *hasResultType = true; break; - case OpSConvert: *hasResult = true; *hasResultType = true; break; - case OpFConvert: *hasResult = true; *hasResultType = true; break; - case OpQuantizeToF16: *hasResult = true; *hasResultType = true; break; - case OpConvertPtrToU: *hasResult = true; *hasResultType = true; break; - case OpSatConvertSToU: *hasResult = true; *hasResultType = true; break; - case OpSatConvertUToS: *hasResult = true; *hasResultType = true; break; - case OpConvertUToPtr: *hasResult = true; *hasResultType = true; break; - case OpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; - case OpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; - case OpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; - case OpBitcast: *hasResult = true; *hasResultType = true; break; - case OpSNegate: *hasResult = true; *hasResultType = true; break; - case OpFNegate: *hasResult = true; *hasResultType = true; break; - case OpIAdd: *hasResult = true; *hasResultType = true; break; - case OpFAdd: *hasResult = true; *hasResultType = true; break; - case OpISub: *hasResult = true; *hasResultType = true; break; - case OpFSub: *hasResult = true; *hasResultType = true; break; - case OpIMul: *hasResult = true; *hasResultType = true; break; - case OpFMul: *hasResult = true; *hasResultType = true; break; - case OpUDiv: *hasResult = true; *hasResultType = true; break; - case OpSDiv: *hasResult = true; *hasResultType = true; break; - case OpFDiv: *hasResult = true; *hasResultType = true; break; - case OpUMod: *hasResult = true; *hasResultType = true; break; - case OpSRem: *hasResult = true; *hasResultType = true; break; - case OpSMod: *hasResult = true; *hasResultType = true; break; - case OpFRem: *hasResult = true; *hasResultType = true; break; - case OpFMod: *hasResult = true; *hasResultType = true; break; - case OpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; - case OpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; - case OpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; - case OpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; - case OpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; - case OpOuterProduct: *hasResult = true; *hasResultType = true; break; - case OpDot: *hasResult = true; *hasResultType = true; break; - case OpIAddCarry: *hasResult = true; *hasResultType = true; break; - case OpISubBorrow: *hasResult = true; *hasResultType = true; break; - case OpUMulExtended: *hasResult = true; *hasResultType = true; break; - case OpSMulExtended: *hasResult = true; *hasResultType = true; break; - case OpAny: *hasResult = true; *hasResultType = true; break; - case OpAll: *hasResult = true; *hasResultType = true; break; - case OpIsNan: *hasResult = true; *hasResultType = true; break; - case OpIsInf: *hasResult = true; *hasResultType = true; break; - case OpIsFinite: *hasResult = true; *hasResultType = true; break; - case OpIsNormal: *hasResult = true; *hasResultType = true; break; - case OpSignBitSet: *hasResult = true; *hasResultType = true; break; - case OpLessOrGreater: *hasResult = true; *hasResultType = true; break; - case OpOrdered: *hasResult = true; *hasResultType = true; break; - case OpUnordered: *hasResult = true; *hasResultType = true; break; - case OpLogicalEqual: *hasResult = true; *hasResultType = true; break; - case OpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; - case OpLogicalOr: *hasResult = true; *hasResultType = true; break; - case OpLogicalAnd: *hasResult = true; *hasResultType = true; break; - case OpLogicalNot: *hasResult = true; *hasResultType = true; break; - case OpSelect: *hasResult = true; *hasResultType = true; break; - case OpIEqual: *hasResult = true; *hasResultType = true; break; - case OpINotEqual: *hasResult = true; *hasResultType = true; break; - case OpUGreaterThan: *hasResult = true; *hasResultType = true; break; - case OpSGreaterThan: *hasResult = true; *hasResultType = true; break; - case OpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case OpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case OpULessThan: *hasResult = true; *hasResultType = true; break; - case OpSLessThan: *hasResult = true; *hasResultType = true; break; - case OpULessThanEqual: *hasResult = true; *hasResultType = true; break; - case OpSLessThanEqual: *hasResult = true; *hasResultType = true; break; - case OpFOrdEqual: *hasResult = true; *hasResultType = true; break; - case OpFUnordEqual: *hasResult = true; *hasResultType = true; break; - case OpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; - case OpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; - case OpFOrdLessThan: *hasResult = true; *hasResultType = true; break; - case OpFUnordLessThan: *hasResult = true; *hasResultType = true; break; - case OpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; - case OpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; - case OpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; - case OpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; - case OpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case OpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case OpShiftRightLogical: *hasResult = true; *hasResultType = true; break; - case OpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; - case OpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; - case OpBitwiseOr: *hasResult = true; *hasResultType = true; break; - case OpBitwiseXor: *hasResult = true; *hasResultType = true; break; - case OpBitwiseAnd: *hasResult = true; *hasResultType = true; break; - case OpNot: *hasResult = true; *hasResultType = true; break; - case OpBitFieldInsert: *hasResult = true; *hasResultType = true; break; - case OpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; - case OpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; - case OpBitReverse: *hasResult = true; *hasResultType = true; break; - case OpBitCount: *hasResult = true; *hasResultType = true; break; - case OpDPdx: *hasResult = true; *hasResultType = true; break; - case OpDPdy: *hasResult = true; *hasResultType = true; break; - case OpFwidth: *hasResult = true; *hasResultType = true; break; - case OpDPdxFine: *hasResult = true; *hasResultType = true; break; - case OpDPdyFine: *hasResult = true; *hasResultType = true; break; - case OpFwidthFine: *hasResult = true; *hasResultType = true; break; - case OpDPdxCoarse: *hasResult = true; *hasResultType = true; break; - case OpDPdyCoarse: *hasResult = true; *hasResultType = true; break; - case OpFwidthCoarse: *hasResult = true; *hasResultType = true; break; - case OpEmitVertex: *hasResult = false; *hasResultType = false; break; - case OpEndPrimitive: *hasResult = false; *hasResultType = false; break; - case OpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; - case OpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; - case OpControlBarrier: *hasResult = false; *hasResultType = false; break; - case OpMemoryBarrier: *hasResult = false; *hasResultType = false; break; - case OpAtomicLoad: *hasResult = true; *hasResultType = true; break; - case OpAtomicStore: *hasResult = false; *hasResultType = false; break; - case OpAtomicExchange: *hasResult = true; *hasResultType = true; break; - case OpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; - case OpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; - case OpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; - case OpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; - case OpAtomicIAdd: *hasResult = true; *hasResultType = true; break; - case OpAtomicISub: *hasResult = true; *hasResultType = true; break; - case OpAtomicSMin: *hasResult = true; *hasResultType = true; break; - case OpAtomicUMin: *hasResult = true; *hasResultType = true; break; - case OpAtomicSMax: *hasResult = true; *hasResultType = true; break; - case OpAtomicUMax: *hasResult = true; *hasResultType = true; break; - case OpAtomicAnd: *hasResult = true; *hasResultType = true; break; - case OpAtomicOr: *hasResult = true; *hasResultType = true; break; - case OpAtomicXor: *hasResult = true; *hasResultType = true; break; - case OpPhi: *hasResult = true; *hasResultType = true; break; - case OpLoopMerge: *hasResult = false; *hasResultType = false; break; - case OpSelectionMerge: *hasResult = false; *hasResultType = false; break; - case OpLabel: *hasResult = true; *hasResultType = false; break; - case OpBranch: *hasResult = false; *hasResultType = false; break; - case OpBranchConditional: *hasResult = false; *hasResultType = false; break; - case OpSwitch: *hasResult = false; *hasResultType = false; break; - case OpKill: *hasResult = false; *hasResultType = false; break; - case OpReturn: *hasResult = false; *hasResultType = false; break; - case OpReturnValue: *hasResult = false; *hasResultType = false; break; - case OpUnreachable: *hasResult = false; *hasResultType = false; break; - case OpLifetimeStart: *hasResult = false; *hasResultType = false; break; - case OpLifetimeStop: *hasResult = false; *hasResultType = false; break; - case OpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; - case OpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; - case OpGroupAll: *hasResult = true; *hasResultType = true; break; - case OpGroupAny: *hasResult = true; *hasResultType = true; break; - case OpGroupBroadcast: *hasResult = true; *hasResultType = true; break; - case OpGroupIAdd: *hasResult = true; *hasResultType = true; break; - case OpGroupFAdd: *hasResult = true; *hasResultType = true; break; - case OpGroupFMin: *hasResult = true; *hasResultType = true; break; - case OpGroupUMin: *hasResult = true; *hasResultType = true; break; - case OpGroupSMin: *hasResult = true; *hasResultType = true; break; - case OpGroupFMax: *hasResult = true; *hasResultType = true; break; - case OpGroupUMax: *hasResult = true; *hasResultType = true; break; - case OpGroupSMax: *hasResult = true; *hasResultType = true; break; - case OpReadPipe: *hasResult = true; *hasResultType = true; break; - case OpWritePipe: *hasResult = true; *hasResultType = true; break; - case OpReservedReadPipe: *hasResult = true; *hasResultType = true; break; - case OpReservedWritePipe: *hasResult = true; *hasResultType = true; break; - case OpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; - case OpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; - case OpCommitReadPipe: *hasResult = false; *hasResultType = false; break; - case OpCommitWritePipe: *hasResult = false; *hasResultType = false; break; - case OpIsValidReserveId: *hasResult = true; *hasResultType = true; break; - case OpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; - case OpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; - case OpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; - case OpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; - case OpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; - case OpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; - case OpEnqueueMarker: *hasResult = true; *hasResultType = true; break; - case OpEnqueueKernel: *hasResult = true; *hasResultType = true; break; - case OpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; - case OpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; - case OpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; - case OpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; - case OpRetainEvent: *hasResult = false; *hasResultType = false; break; - case OpReleaseEvent: *hasResult = false; *hasResultType = false; break; - case OpCreateUserEvent: *hasResult = true; *hasResultType = true; break; - case OpIsValidEvent: *hasResult = true; *hasResultType = true; break; - case OpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; - case OpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; - case OpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; - case OpBuildNDRange: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseFetch: *hasResult = true; *hasResultType = true; break; - case OpImageSparseGather: *hasResult = true; *hasResultType = true; break; - case OpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; - case OpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; - case OpNoLine: *hasResult = false; *hasResultType = false; break; - case OpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; - case OpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; - case OpImageSparseRead: *hasResult = true; *hasResultType = true; break; - case OpSizeOf: *hasResult = true; *hasResultType = true; break; - case OpTypePipeStorage: *hasResult = true; *hasResultType = false; break; - case OpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; - case OpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; - case OpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; - case OpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; - case OpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; - case OpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; - case OpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; - case OpModuleProcessed: *hasResult = false; *hasResultType = false; break; - case OpExecutionModeId: *hasResult = false; *hasResultType = false; break; - case OpDecorateId: *hasResult = false; *hasResultType = false; break; - case OpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; - case OpCopyLogical: *hasResult = true; *hasResultType = true; break; - case OpPtrEqual: *hasResult = true; *hasResultType = true; break; - case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; - case OpPtrDiff: *hasResult = true; *hasResultType = true; break; - case OpTerminateInvocation: *hasResult = false; *hasResultType = false; break; - case OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; - case OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; - case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; - case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; - case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; - case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; - case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; - case OpSDot: *hasResult = true; *hasResultType = true; break; - case OpUDot: *hasResult = true; *hasResultType = true; break; - case OpSUDot: *hasResult = true; *hasResultType = true; break; - case OpSDotAccSat: *hasResult = true; *hasResultType = true; break; - case OpUDotAccSat: *hasResult = true; *hasResultType = true; break; - case OpSUDotAccSat: *hasResult = true; *hasResultType = true; break; - case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; - case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; - case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; - case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; - case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; - case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; - case OpReadClockKHR: *hasResult = true; *hasResultType = true; break; - case OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; - case OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; - case OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; - case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; - case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; - case OpTraceNV: *hasResult = false; *hasResultType = false; break; - case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break; - case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; - case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; - case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; - case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; - case OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; - case OpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; - case OpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; - case OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; - case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; - case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; - case OpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; - case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; - case OpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; - case OpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; - case OpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; - case OpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; - case OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; - case OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; - case OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; - case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case OpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; - case OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; - case OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; - case OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; - case OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; - case OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; - case OpIAverageINTEL: *hasResult = true; *hasResultType = true; break; - case OpUAverageINTEL: *hasResult = true; *hasResultType = true; break; - case OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; - case OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; - case OpISubSatINTEL: *hasResult = true; *hasResultType = true; break; - case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; - case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; - case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; - case OpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; - case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; - case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; - case OpAsmINTEL: *hasResult = true; *hasResultType = true; break; - case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; - case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; - case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; - case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; - case OpExpectKHR: *hasResult = true; *hasResultType = true; break; - case OpDecorateString: *hasResult = false; *hasResultType = false; break; - case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; - case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; - case OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; - case OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; - case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; - case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; - case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; - case OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; - case OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; - case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; - case OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; - case OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; - case OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; - case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; - case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; - case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; - case OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; - case OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; - case OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; - case OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; - case OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; - case OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; - case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; - case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; - case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; - case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; - case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; - case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; - case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; - case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; - case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; - case OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; - case OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; - case OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; - case OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; - case OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; - case OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; - case OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; - case OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; - case OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; - case OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; - } -} -#endif /* SPV_ENABLE_UTILITY_CODE */ - -// Overload operator| for mask bit combining - -inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } -inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } -inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } -inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } -inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } -inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } -inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } -inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } -inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); } -inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); } - -} // end namespace spv - -#endif // #ifndef spirv_HPP diff --git a/meson.build b/meson.build index 385776352..27d73d7ca 100644 --- a/meson.build +++ b/meson.build @@ -26,7 +26,7 @@ if get_option('build_id') ] endif -dxvk_include_path = include_directories('./include', './include/vulkan/include') +dxvk_include_path = include_directories('./include', './include/vulkan/include', './include/spirv/include') if platform == 'windows' compiler_args += [ diff --git a/src/spirv/spirv_code_buffer.h b/src/spirv/spirv_code_buffer.h index a0ed22727..e919bf4cb 100644 --- a/src/spirv/spirv_code_buffer.h +++ b/src/spirv/spirv_code_buffer.h @@ -1,7 +1,5 @@ #pragma once -#include - #include #include #include diff --git a/src/spirv/spirv_include.h b/src/spirv/spirv_include.h index fca941816..9d281d86d 100644 --- a/src/spirv/spirv_include.h +++ b/src/spirv/spirv_include.h @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "../util/log/log.h" #include "../util/log/log_debug.h" diff --git a/src/spirv/spirv_instruction.h b/src/spirv/spirv_instruction.h index ada816e72..1f9314157 100644 --- a/src/spirv/spirv_instruction.h +++ b/src/spirv/spirv_instruction.h @@ -1,8 +1,5 @@ #pragma once -#include -#include - #include "spirv_include.h" namespace dxvk { diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 7e9efe71f..d59f87f08 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -1330,7 +1330,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450FindILsb); + m_code.putWord(GLSLstd450FindILsb); m_code.putWord(operand); return resultId; } @@ -1345,7 +1345,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450FindUMsb); + m_code.putWord(GLSLstd450FindUMsb); m_code.putWord(operand); return resultId; } @@ -1360,7 +1360,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450FindSMsb); + m_code.putWord(GLSLstd450FindSMsb); m_code.putWord(operand); return resultId; } @@ -1776,7 +1776,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450SAbs); + m_code.putWord(GLSLstd450SAbs); m_code.putWord(operand); return resultId; } @@ -1791,7 +1791,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450FAbs); + m_code.putWord(GLSLstd450FAbs); m_code.putWord(operand); return resultId; } @@ -1806,7 +1806,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450FSign); + m_code.putWord(GLSLstd450FSign); m_code.putWord(operand); return resultId; } @@ -1823,7 +1823,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450FMix); + m_code.putWord(GLSLstd450FMix); m_code.putWord(x); m_code.putWord(y); m_code.putWord(a); @@ -1841,7 +1841,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Cross); + m_code.putWord(GLSLstd450Cross); m_code.putWord(x); m_code.putWord(y); return resultId; @@ -2095,7 +2095,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450MatrixInverse); + m_code.putWord(GLSLstd450MatrixInverse); m_code.putWord(matrix); return resultId; } @@ -2112,7 +2112,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Fma); + m_code.putWord(GLSLstd450Fma); m_code.putWord(a); m_code.putWord(b); m_code.putWord(c); @@ -2130,7 +2130,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450FMax); + m_code.putWord(GLSLstd450FMax); m_code.putWord(a); m_code.putWord(b); return resultId; @@ -2147,7 +2147,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450FMin); + m_code.putWord(GLSLstd450FMin); m_code.putWord(a); m_code.putWord(b); return resultId; @@ -2164,7 +2164,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450NMax); + m_code.putWord(GLSLstd450NMax); m_code.putWord(a); m_code.putWord(b); return resultId; @@ -2181,7 +2181,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450NMin); + m_code.putWord(GLSLstd450NMin); m_code.putWord(a); m_code.putWord(b); return resultId; @@ -2198,7 +2198,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450SMax); + m_code.putWord(GLSLstd450SMax); m_code.putWord(a); m_code.putWord(b); return resultId; @@ -2215,7 +2215,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450SMin); + m_code.putWord(GLSLstd450SMin); m_code.putWord(a); m_code.putWord(b); return resultId; @@ -2232,7 +2232,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450UMax); + m_code.putWord(GLSLstd450UMax); m_code.putWord(a); m_code.putWord(b); return resultId; @@ -2249,7 +2249,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450UMin); + m_code.putWord(GLSLstd450UMin); m_code.putWord(a); m_code.putWord(b); return resultId; @@ -2267,7 +2267,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450FClamp); + m_code.putWord(GLSLstd450FClamp); m_code.putWord(x); m_code.putWord(minVal); m_code.putWord(maxVal); @@ -2286,7 +2286,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450NClamp); + m_code.putWord(GLSLstd450NClamp); m_code.putWord(x); m_code.putWord(minVal); m_code.putWord(maxVal); @@ -2631,7 +2631,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Sin); + m_code.putWord(GLSLstd450Sin); m_code.putWord(vector); return resultId; } @@ -2646,7 +2646,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Cos); + m_code.putWord(GLSLstd450Cos); m_code.putWord(vector); return resultId; } @@ -2661,7 +2661,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Sqrt); + m_code.putWord(GLSLstd450Sqrt); m_code.putWord(operand); return resultId; } @@ -2676,7 +2676,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450InverseSqrt); + m_code.putWord(GLSLstd450InverseSqrt); m_code.putWord(operand); return resultId; } @@ -2691,7 +2691,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Normalize); + m_code.putWord(GLSLstd450Normalize); m_code.putWord(operand); return resultId; } @@ -2707,7 +2707,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Reflect); + m_code.putWord(GLSLstd450Reflect); m_code.putWord(incident); m_code.putWord(normal); return resultId; @@ -2723,7 +2723,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Length); + m_code.putWord(GLSLstd450Length); m_code.putWord(operand); return resultId; } @@ -2738,7 +2738,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Exp2); + m_code.putWord(GLSLstd450Exp2); m_code.putWord(operand); return resultId; } @@ -2753,7 +2753,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Exp); + m_code.putWord(GLSLstd450Exp); m_code.putWord(operand); return resultId; } @@ -2768,7 +2768,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Log2); + m_code.putWord(GLSLstd450Log2); m_code.putWord(operand); return resultId; } @@ -2783,7 +2783,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Pow); + m_code.putWord(GLSLstd450Pow); m_code.putWord(base); m_code.putWord(exponent); return resultId; @@ -2798,7 +2798,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Fract); + m_code.putWord(GLSLstd450Fract); m_code.putWord(operand); return resultId; } @@ -2813,7 +2813,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Ceil); + m_code.putWord(GLSLstd450Ceil); m_code.putWord(operand); return resultId; } @@ -2828,7 +2828,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Floor); + m_code.putWord(GLSLstd450Floor); m_code.putWord(operand); return resultId; } @@ -2843,7 +2843,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Round); + m_code.putWord(GLSLstd450Round); m_code.putWord(operand); return resultId; } @@ -2858,7 +2858,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450RoundEven); + m_code.putWord(GLSLstd450RoundEven); m_code.putWord(operand); return resultId; } @@ -2873,7 +2873,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450Trunc); + m_code.putWord(GLSLstd450Trunc); m_code.putWord(operand); return resultId; } @@ -2901,7 +2901,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450PackHalf2x16); + m_code.putWord(GLSLstd450PackHalf2x16); m_code.putWord(operand); return resultId; } @@ -2916,7 +2916,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450UnpackHalf2x16); + m_code.putWord(GLSLstd450UnpackHalf2x16); m_code.putWord(operand); return resultId; } @@ -3022,7 +3022,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450InterpolateAtCentroid); + m_code.putWord(GLSLstd450InterpolateAtCentroid); m_code.putWord(interpolant); return resultId; } @@ -3038,7 +3038,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450InterpolateAtSample); + m_code.putWord(GLSLstd450InterpolateAtSample); m_code.putWord(interpolant); m_code.putWord(sample); return resultId; @@ -3055,7 +3055,7 @@ namespace dxvk { m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); - m_code.putWord(spv::GLSLstd450InterpolateAtOffset); + m_code.putWord(GLSLstd450InterpolateAtOffset); m_code.putWord(interpolant); m_code.putWord(offset); return resultId; From 9feed43abf9ceffb7036d144b40681c8bfea96d5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 21:24:23 +0200 Subject: [PATCH 0636/1348] [meta] Add README entry about submodules --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index db344e378..12260af61 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,13 @@ export WINEPREFIX=/path/to/.wine-prefix ## Build instructions +In order to pull in all submodules that are needed for building, clone the repository using the following command: +``` +git clone --recursive https://github.com/doitsujin/dxvk.git +``` + + + ### Requirements: - [wine 3.10](https://www.winehq.org/) or newer - [Meson](https://mesonbuild.com/) build system (at least version 0.49) From 85aa0a0ecba8ab5144b932c74084246f4b10ca04 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 23:22:43 +0200 Subject: [PATCH 0637/1348] [dxvk] Fix meson issue for native builds --- meson.build | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 27d73d7ca..e8b15fa96 100644 --- a/meson.build +++ b/meson.build @@ -26,7 +26,11 @@ if get_option('build_id') ] endif -dxvk_include_path = include_directories('./include', './include/vulkan/include', './include/spirv/include') +dxvk_include_dirs = [ + './include', + './include/vulkan/include', + './include/spirv/include' +] if platform == 'windows' compiler_args += [ @@ -102,12 +106,18 @@ else wrc = find_program('touch') wrc_generator = generator(wrc, output : [ '@BASENAME@_ignored.h' ], arguments : [ '@OUTPUT@' ] ) - dxvk_include_path += include_directories('./include/native', './include/native/windows', './include/native/directx') + dxvk_include_dirs += [ + './include/native', + './include/native/windows', + './include/native/directx' + ] dxvk_wsi = 'sdl2' compiler_args += ['-DDXVK_WSI_SDL2'] endif +dxvk_include_path = include_directories(dxvk_include_dirs) + add_project_arguments(cpp.get_supported_arguments(compiler_args), language: 'cpp') add_project_arguments(cc.get_supported_arguments(compiler_args), language: 'c') add_project_link_arguments(cpp.get_supported_link_arguments(link_args), language: 'cpp') From 23c3960f6589685c92ae1b991a8bd7d0fb8aae02 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 00:06:57 +0200 Subject: [PATCH 0638/1348] [dxvk] Store WSI semaphore pair directly with the command list --- src/d3d11/d3d11_swapchain.cpp | 8 +++----- src/d3d9/d3d9_swapchain.cpp | 8 +++----- src/dxvk/dxvk_cmdlist.cpp | 14 +++++++------- src/dxvk/dxvk_cmdlist.h | 22 ++++++++++++++++------ src/dxvk/dxvk_context.cpp | 4 +--- src/dxvk/dxvk_device.cpp | 6 +----- src/dxvk/dxvk_device.h | 6 +----- src/dxvk/dxvk_queue.cpp | 4 +--- src/dxvk/dxvk_queue.h | 2 -- 9 files changed, 33 insertions(+), 41 deletions(-) diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index bef53f5a0..8e007e7d5 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -332,8 +332,8 @@ namespace dxvk { cHud = m_hud, cCommandList = m_context->endRecording() ] (DxvkContext* ctx) { - m_device->submitCommandList(cCommandList, - cSync.acquire, cSync.present); + cCommandList->setWsiSemaphores(cSync); + m_device->submitCommandList(cCommandList); if (cHud != nullptr && !cFrameId) cHud->update(); @@ -526,9 +526,7 @@ namespace dxvk { subresources, VK_IMAGE_LAYOUT_UNDEFINED); m_device->submitCommandList( - m_context->endRecording(), - VK_NULL_HANDLE, - VK_NULL_HANDLE); + m_context->endRecording()); } diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index fc36547d6..8268e8002 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -715,8 +715,8 @@ namespace dxvk { cHud = m_hud, cCommandList = m_context->endRecording() ] (DxvkContext* ctx) { - m_device->submitCommandList(cCommandList, - cSync.acquire, cSync.present); + cCommandList->setWsiSemaphores(cSync); + m_device->submitCommandList(cCommandList); if (cHud != nullptr && !cFrameId) cHud->update(); @@ -890,9 +890,7 @@ namespace dxvk { } m_device->submitCommandList( - m_context->endRecording(), - VK_NULL_HANDLE, - VK_NULL_HANDLE); + m_context->endRecording()); } diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index adff122d3..e24c4ea03 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -78,9 +78,7 @@ namespace dxvk { } - VkResult DxvkCommandList::submit( - VkSemaphore waitSemaphore, - VkSemaphore wakeSemaphore) { + VkResult DxvkCommandList::submit() { const auto& graphics = m_device->queues().graphics; const auto& transfer = m_device->queues().transfer; @@ -123,16 +121,16 @@ namespace dxvk { m_submission.cmdBuffers.push_back(cmdInfo); } - if (waitSemaphore) { + if (m_wsiSemaphores.acquire) { VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - waitInfo.semaphore = waitSemaphore; + waitInfo.semaphore = m_wsiSemaphores.acquire; waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; m_submission.waitSync.push_back(waitInfo); } - if (wakeSemaphore) { + if (m_wsiSemaphores.present) { VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - signalInfo.semaphore = wakeSemaphore; + signalInfo.semaphore = m_wsiSemaphores.present; signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; m_submission.wakeSync.push_back(signalInfo); } @@ -233,6 +231,8 @@ namespace dxvk { m_waitSemaphores.clear(); m_signalSemaphores.clear(); + + m_wsiSemaphores = vk::PresenterSync(); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index f4492a063..366bac3fe 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -2,6 +2,8 @@ #include +#include "../vulkan/vulkan_presenter.h" + #include "dxvk_bind_mask.h" #include "dxvk_buffer.h" #include "dxvk_descriptor.h" @@ -71,13 +73,9 @@ namespace dxvk { * \brief Submits command list * * \param [in] queue Device queue - * \param [in] waitSemaphore Semaphore to wait on - * \param [in] wakeSemaphore Semaphore to signal * \returns Submission status */ - VkResult submit( - VkSemaphore waitSemaphore, - VkSemaphore wakeSemaphore); + VkResult submit(); /** * \brief Synchronizes command buffer execution @@ -225,7 +223,17 @@ namespace dxvk { void signalFence(Rc fence, uint64_t value) { m_signalSemaphores.emplace_back(std::move(fence), value); } - + + /** + * \brief Sets WSI semaphores to synchronize with + * + * The given semaphores must be binary semaphores. + * \param [in] wsiSemaphores Pair of WSI semaphores + */ + void setWsiSemaphores(const vk::PresenterSync& wsiSemaphores) { + m_wsiSemaphores = wsiSemaphores; + } + /** * \brief Resets the command list * @@ -816,6 +824,8 @@ namespace dxvk { VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE; + vk::PresenterSync m_wsiSemaphores = { }; + DxvkCmdBufferFlags m_cmdBuffersUsed; DxvkLifetimeTracker m_resources; DxvkSignalTracker m_signalTracker; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index f493e0ce4..c304bfc8e 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -135,9 +135,7 @@ namespace dxvk { void DxvkContext::flushCommandList() { m_device->submitCommandList( - this->endRecording(), - VK_NULL_HANDLE, - VK_NULL_HANDLE); + this->endRecording()); this->beginRecording( m_device->createCommandList()); diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 5f3f08774..08d6e6997 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -267,13 +267,9 @@ namespace dxvk { void DxvkDevice::submitCommandList( - const Rc& commandList, - VkSemaphore waitSync, - VkSemaphore wakeSync) { + const Rc& commandList) { DxvkSubmitInfo submitInfo; submitInfo.cmdList = commandList; - submitInfo.waitSync = waitSync; - submitInfo.wakeSync = wakeSync; m_submissionQueue.submit(submitInfo); std::lock_guard statLock(m_statLock); diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 7918c7b33..2899f8137 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -435,13 +435,9 @@ namespace dxvk { * Submits the given command list to the device using * the given set of optional synchronization primitives. * \param [in] commandList The command list to submit - * \param [in] waitSync (Optional) Semaphore to wait on - * \param [in] wakeSync (Optional) Semaphore to notify */ void submitCommandList( - const Rc& commandList, - VkSemaphore waitSync, - VkSemaphore wakeSync); + const Rc& commandList); /** * \brief Locks submission queue diff --git a/src/dxvk/dxvk_queue.cpp b/src/dxvk/dxvk_queue.cpp index 86f0b4e35..57c2be1a3 100644 --- a/src/dxvk/dxvk_queue.cpp +++ b/src/dxvk/dxvk_queue.cpp @@ -104,9 +104,7 @@ namespace dxvk { std::lock_guard lock(m_mutexQueue); if (entry.submit.cmdList != nullptr) { - status = entry.submit.cmdList->submit( - entry.submit.waitSync, - entry.submit.wakeSync); + status = entry.submit.cmdList->submit(); } else if (entry.present.presenter != nullptr) { status = entry.present.presenter->presentImage(); } diff --git a/src/dxvk/dxvk_queue.h b/src/dxvk/dxvk_queue.h index 374da55ed..5f1785b2f 100644 --- a/src/dxvk/dxvk_queue.h +++ b/src/dxvk/dxvk_queue.h @@ -33,8 +33,6 @@ namespace dxvk { */ struct DxvkSubmitInfo { Rc cmdList; - VkSemaphore waitSync; - VkSemaphore wakeSync; }; From 11ef1084d026aac075851a57eb26e0bee74d5b12 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 00:08:42 +0200 Subject: [PATCH 0639/1348] [dxvk] Rename semaphore stuff in command list code --- src/dxvk/dxvk_cmdlist.cpp | 20 ++++++++++---------- src/dxvk/dxvk_cmdlist.h | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index e24c4ea03..756a53cfd 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -93,7 +93,7 @@ namespace dxvk { VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; signalInfo.semaphore = m_sdmaSemaphore; signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; - m_submission.wakeSync.push_back(signalInfo); + m_submission.signalInfos.push_back(signalInfo); VkResult status = submitToQueue(transfer.queueHandle, VK_NULL_HANDLE, m_submission); @@ -105,7 +105,7 @@ namespace dxvk { VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; waitInfo.semaphore = m_sdmaSemaphore; waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; - m_submission.waitSync.push_back(waitInfo); + m_submission.waitInfos.push_back(waitInfo); } } @@ -125,14 +125,14 @@ namespace dxvk { VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; waitInfo.semaphore = m_wsiSemaphores.acquire; waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; - m_submission.waitSync.push_back(waitInfo); + m_submission.waitInfos.push_back(waitInfo); } if (m_wsiSemaphores.present) { VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; signalInfo.semaphore = m_wsiSemaphores.present; signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; - m_submission.wakeSync.push_back(signalInfo); + m_submission.signalInfos.push_back(signalInfo); } for (const auto& entry : m_waitSemaphores) { @@ -140,7 +140,7 @@ namespace dxvk { waitInfo.semaphore = entry.fence->handle(); waitInfo.value = entry.value; waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; - m_submission.waitSync.push_back(waitInfo); + m_submission.waitInfos.push_back(waitInfo); } for (const auto& entry : m_signalSemaphores) { @@ -148,7 +148,7 @@ namespace dxvk { signalInfo.semaphore = entry.fence->handle(); signalInfo.value = entry.value; signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; - m_submission.wakeSync.push_back(signalInfo); + m_submission.signalInfos.push_back(signalInfo); } return submitToQueue(graphics.queueHandle, m_fence, m_submission); @@ -241,12 +241,12 @@ namespace dxvk { VkFence fence, const DxvkQueueSubmission& info) { VkSubmitInfo2 submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO_2 }; - submitInfo.waitSemaphoreInfoCount = info.waitSync.size(); - submitInfo.pWaitSemaphoreInfos = info.waitSync.data(); + submitInfo.waitSemaphoreInfoCount = info.waitInfos.size(); + submitInfo.pWaitSemaphoreInfos = info.waitInfos.data(); submitInfo.commandBufferInfoCount = info.cmdBuffers.size(); submitInfo.pCommandBufferInfos = info.cmdBuffers.data(); - submitInfo.signalSemaphoreInfoCount = info.wakeSync.size(); - submitInfo.pSignalSemaphoreInfos = info.wakeSync.data(); + submitInfo.signalSemaphoreInfoCount = info.signalInfos.size(); + submitInfo.pSignalSemaphoreInfos = info.signalInfos.data(); return m_vkd->vkQueueSubmit2(queue, 1, &submitInfo, fence); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 366bac3fe..96edb66ed 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -42,13 +42,13 @@ namespace dxvk { * only, array sizes are based on need. */ struct DxvkQueueSubmission { - std::vector waitSync; - std::vector wakeSync; + std::vector waitInfos; + std::vector signalInfos; std::vector cmdBuffers; void reset() { - waitSync.clear(); - wakeSync.clear(); + waitInfos.clear(); + signalInfos.clear(); cmdBuffers.clear(); } }; From cff9056915c659ee543a40bee4ae3ff3ef34f35b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 00:39:50 +0200 Subject: [PATCH 0640/1348] [dxvk] Always enable timeline semaphore feature --- src/d3d11/d3d11_device.cpp | 1 - src/dxvk/dxvk_adapter.cpp | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 3f693f84e..0df056825 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1918,7 +1918,6 @@ namespace dxvk { enabled.vk11.shaderDrawParameters = VK_TRUE; enabled.vk12.samplerMirrorClampToEdge = VK_TRUE; - enabled.vk12.timelineSemaphore = VK_TRUE; enabled.vk13.shaderDemoteToHelperInvocation = VK_TRUE; diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 3e5187129..1c7adbbed 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -344,6 +344,9 @@ namespace dxvk { enabledFeatures.vk12.shaderOutputLayer = m_deviceFeatures.vk12.shaderOutputLayer; + // Required for proper GPU synchronization + enabledFeatures.vk12.timelineSemaphore = VK_TRUE; + // Only enable the base image robustness feature if robustness 2 isn't // supported, since this is only a subset of what we actually want. enabledFeatures.vk13.robustImageAccess = From f385b4bb47dbb9081760edb762b2dd3f6491f6ad Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 00:32:49 +0200 Subject: [PATCH 0641/1348] [dxvk] Use global timeline semaphore for command list synchronization Replaces the old fence mechanism and also makes it easier to synchronize across queues. --- src/dxvk/dxvk_cmdlist.cpp | 62 +++++++++++---------------------------- src/dxvk/dxvk_cmdlist.h | 25 ++++++---------- src/dxvk/dxvk_queue.cpp | 39 ++++++++++++++++++++++-- src/dxvk/dxvk_queue.h | 18 +++++++----- 4 files changed, 73 insertions(+), 71 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 756a53cfd..fd185b387 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -11,14 +11,6 @@ namespace dxvk { const auto& graphicsQueue = m_device->queues().graphics; const auto& transferQueue = m_device->queues().transfer; - VkFenceCreateInfo fenceInfo; - fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fenceInfo.pNext = nullptr; - fenceInfo.flags = 0; - - if (m_vkd->vkCreateFence(m_vkd->device(), &fenceInfo, nullptr, &m_fence) != VK_SUCCESS) - throw DxvkError("DxvkCommandList: Failed to create fence"); - VkCommandPoolCreateInfo poolInfo; poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolInfo.pNext = nullptr; @@ -53,32 +45,20 @@ namespace dxvk { || m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoGfx, &m_initBuffer) != VK_SUCCESS || m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoDma, &m_sdmaBuffer) != VK_SUCCESS) throw DxvkError("DxvkCommandList: Failed to allocate command buffer"); - - if (m_device->hasDedicatedTransferQueue()) { - VkSemaphoreCreateInfo semInfo; - semInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - semInfo.pNext = nullptr; - semInfo.flags = 0; - - if (m_vkd->vkCreateSemaphore(m_vkd->device(), &semInfo, nullptr, &m_sdmaSemaphore) != VK_SUCCESS) - throw DxvkError("DxvkCommandList: Failed to create semaphore"); - } } DxvkCommandList::~DxvkCommandList() { this->reset(); - m_vkd->vkDestroySemaphore(m_vkd->device(), m_sdmaSemaphore, nullptr); - m_vkd->vkDestroyCommandPool(m_vkd->device(), m_graphicsPool, nullptr); m_vkd->vkDestroyCommandPool(m_vkd->device(), m_transferPool, nullptr); - - m_vkd->vkDestroyFence(m_vkd->device(), m_fence, nullptr); } - VkResult DxvkCommandList::submit() { + VkResult DxvkCommandList::submit( + VkSemaphore semaphore, + uint64_t& semaphoreValue) { const auto& graphics = m_device->queues().graphics; const auto& transfer = m_device->queues().transfer; @@ -91,11 +71,12 @@ namespace dxvk { if (m_device->hasDedicatedTransferQueue()) { VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - signalInfo.semaphore = m_sdmaSemaphore; + signalInfo.semaphore = semaphore; + signalInfo.value = ++semaphoreValue; signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; m_submission.signalInfos.push_back(signalInfo); - VkResult status = submitToQueue(transfer.queueHandle, VK_NULL_HANDLE, m_submission); + VkResult status = submitToQueue(transfer.queueHandle, m_submission); if (status != VK_SUCCESS) return status; @@ -103,7 +84,8 @@ namespace dxvk { m_submission.reset(); VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - waitInfo.semaphore = m_sdmaSemaphore; + waitInfo.semaphore = semaphore; + waitInfo.value = semaphoreValue; waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; m_submission.waitInfos.push_back(waitInfo); } @@ -151,20 +133,14 @@ namespace dxvk { m_submission.signalInfos.push_back(signalInfo); } - return submitToQueue(graphics.queueHandle, m_fence, m_submission); - } - - - VkResult DxvkCommandList::synchronize() { - VkResult status = VK_TIMEOUT; - - while (status == VK_TIMEOUT) { - status = m_vkd->vkWaitForFences( - m_vkd->device(), 1, &m_fence, VK_FALSE, - 1'000'000'000ull); - } - - return status; + // Signal global timeline semaphore + VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + signalInfo.semaphore = semaphore; + signalInfo.value = ++semaphoreValue; + signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; + m_submission.signalInfos.push_back(signalInfo); + + return submitToQueue(graphics.queueHandle, m_submission); } @@ -184,9 +160,6 @@ namespace dxvk { || m_vkd->vkBeginCommandBuffer(m_sdmaBuffer, &info) != VK_SUCCESS) Logger::err("DxvkCommandList: Failed to begin command buffer"); - if (m_vkd->vkResetFences(m_vkd->device(), 1, &m_fence) != VK_SUCCESS) - Logger::err("DxvkCommandList: Failed to reset fence"); - // Unconditionally mark the exec buffer as used. There // is virtually no use case where this isn't correct. m_cmdBuffersUsed = DxvkCmdBuffer::ExecBuffer; @@ -238,7 +211,6 @@ namespace dxvk { VkResult DxvkCommandList::submitToQueue( VkQueue queue, - VkFence fence, const DxvkQueueSubmission& info) { VkSubmitInfo2 submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO_2 }; submitInfo.waitSemaphoreInfoCount = info.waitInfos.size(); @@ -248,7 +220,7 @@ namespace dxvk { submitInfo.signalSemaphoreInfoCount = info.signalInfos.size(); submitInfo.pSignalSemaphoreInfos = info.signalInfos.data(); - return m_vkd->vkQueueSubmit2(queue, 1, &submitInfo, fence); + return m_vkd->vkQueueSubmit2(queue, 1, &submitInfo, VK_NULL_HANDLE); } void DxvkCommandList::cmdBeginDebugUtilsLabel(VkDebugUtilsLabelEXT *pLabelInfo) { diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 96edb66ed..297b2be67 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -72,19 +72,17 @@ namespace dxvk { /** * \brief Submits command list * - * \param [in] queue Device queue + * \param [in] semaphore Global timeline semaphore + * \param [in,out] semaphoreValue Semaphore value. On input, + * this is the last signaled value of the semaphore so that + * synchronization can take place as needed. On ouput, this + * will contain the new value the semaphore gets signaled + * to by this submission. * \returns Submission status */ - VkResult submit(); - - /** - * \brief Synchronizes command buffer execution - * - * Waits for the fence associated with - * this command buffer to get signaled. - * \returns Synchronization status - */ - VkResult synchronize(); + VkResult submit( + VkSemaphore semaphore, + uint64_t& semaphoreValue); /** * \brief Stat counters @@ -813,8 +811,6 @@ namespace dxvk { Rc m_vkd; Rc m_vki; - VkFence m_fence; - VkCommandPool m_graphicsPool = VK_NULL_HANDLE; VkCommandPool m_transferPool = VK_NULL_HANDLE; @@ -822,8 +818,6 @@ namespace dxvk { VkCommandBuffer m_initBuffer = VK_NULL_HANDLE; VkCommandBuffer m_sdmaBuffer = VK_NULL_HANDLE; - VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE; - vk::PresenterSync m_wsiSemaphores = { }; DxvkCmdBufferFlags m_cmdBuffersUsed; @@ -853,7 +847,6 @@ namespace dxvk { VkResult submitToQueue( VkQueue queue, - VkFence fence, const DxvkQueueSubmission& info); }; diff --git a/src/dxvk/dxvk_queue.cpp b/src/dxvk/dxvk_queue.cpp index 57c2be1a3..02671a096 100644 --- a/src/dxvk/dxvk_queue.cpp +++ b/src/dxvk/dxvk_queue.cpp @@ -7,20 +7,34 @@ namespace dxvk { : m_device(device), m_submitThread([this] () { submitCmdLists(); }), m_finishThread([this] () { finishCmdLists(); }) { + auto vk = m_device->vkd(); + VkSemaphoreTypeCreateInfo typeInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO }; + typeInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; + + VkSemaphoreCreateInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &typeInfo }; + + if (vk->vkCreateSemaphore(vk->device(), &info, nullptr, &m_semaphore)) + throw DxvkError("Failed to create global timeline semaphore"); } DxvkSubmissionQueue::~DxvkSubmissionQueue() { + auto vk = m_device->vkd(); + { std::unique_lock lock(m_mutex); m_stopped.store(true); } - + m_appendCond.notify_all(); m_submitCond.notify_all(); m_submitThread.join(); m_finishThread.join(); + + synchronizeSemaphore(m_semaphoreValue); + + vk->vkDestroySemaphore(vk->device(), m_semaphore, nullptr); } @@ -81,6 +95,24 @@ namespace dxvk { } + VkResult DxvkSubmissionQueue::synchronizeSemaphore( + uint64_t semaphoreValue) { + auto vk = m_device->vkd(); + + VkSemaphoreWaitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO }; + waitInfo.semaphoreCount = 1; + waitInfo.pSemaphores = &m_semaphore; + waitInfo.pValues = &semaphoreValue; + + VkResult vr = vk->vkWaitSemaphores(vk->device(), &waitInfo, ~0ull); + + if (vr) + Logger::err(str::format("Failed to synchronize with global timeline semaphore: ", vr)); + + return vr; + } + + void DxvkSubmissionQueue::submitCmdLists() { env::setThreadName("dxvk-submit"); @@ -104,7 +136,8 @@ namespace dxvk { std::lock_guard lock(m_mutexQueue); if (entry.submit.cmdList != nullptr) { - status = entry.submit.cmdList->submit(); + status = entry.submit.cmdList->submit(m_semaphore, m_semaphoreValue); + entry.submit.semaphoreValue = m_semaphoreValue; } else if (entry.present.presenter != nullptr) { status = entry.present.presenter->presentImage(); } @@ -161,7 +194,7 @@ namespace dxvk { VkResult status = m_lastError.load(); if (status != VK_ERROR_DEVICE_LOST) - status = entry.submit.cmdList->synchronize(); + status = synchronizeSemaphore(entry.submit.semaphoreValue); if (status != VK_SUCCESS) { Logger::err(str::format("DxvkSubmissionQueue: Failed to sync fence: ", status)); diff --git a/src/dxvk/dxvk_queue.h b/src/dxvk/dxvk_queue.h index 5f1785b2f..370c763b1 100644 --- a/src/dxvk/dxvk_queue.h +++ b/src/dxvk/dxvk_queue.h @@ -33,6 +33,7 @@ namespace dxvk { */ struct DxvkSubmitInfo { Rc cmdList; + uint64_t semaphoreValue; }; @@ -175,13 +176,16 @@ namespace dxvk { private: - DxvkDevice* m_device; + DxvkDevice* m_device; - std::atomic m_lastError = { VK_SUCCESS }; + std::atomic m_lastError = { VK_SUCCESS }; - std::atomic m_stopped = { false }; - std::atomic m_pending = { 0u }; - std::atomic m_gpuIdle = { 0ull }; + std::atomic m_stopped = { false }; + std::atomic m_pending = { 0u }; + std::atomic m_gpuIdle = { 0ull }; + + VkSemaphore m_semaphore = VK_NULL_HANDLE; + uint64_t m_semaphoreValue = 0ull; dxvk::mutex m_mutex; dxvk::mutex m_mutexQueue; @@ -196,8 +200,8 @@ namespace dxvk { dxvk::thread m_submitThread; dxvk::thread m_finishThread; - VkResult submitToQueue( - const DxvkSubmitInfo& submission); + VkResult synchronizeSemaphore( + uint64_t semaphoreValue); void submitCmdLists(); From 3c38bdbd0e7cdc753eaa094db8b7fa69a1940993 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 01:59:14 +0200 Subject: [PATCH 0642/1348] [dxvk] Initialize DxvkSubmitInfo properly We don't use the semaphore value here, but it shouldn't contain undefined data. --- src/dxvk/dxvk_device.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 08d6e6997..49ef7158e 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -268,8 +268,8 @@ namespace dxvk { void DxvkDevice::submitCommandList( const Rc& commandList) { - DxvkSubmitInfo submitInfo; - submitInfo.cmdList = commandList; + DxvkSubmitInfo submitInfo = { }; + submitInfo.cmdList = commandList; m_submissionQueue.submit(submitInfo); std::lock_guard statLock(m_statLock); From a8b578b2a21b4ccbec1898a0cc798a7d5d7ec7e8 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Fri, 19 Aug 2022 21:59:54 +0200 Subject: [PATCH 0643/1348] [d3d9] Fix crash when auto generating mip maps for unmappable textures --- src/d3d9/d3d9_common_texture.cpp | 32 ++++++++++++++++---------------- src/d3d9/d3d9_common_texture.h | 20 ++++++++++---------- src/d3d9/d3d9_device.cpp | 20 +++++++++++--------- src/d3d9/d3d9_swapchain.cpp | 3 ++- 4 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 2d1b2317e..cdcd469f1 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -180,7 +180,11 @@ namespace dxvk { return memory.Ptr(); } - void D3D9CommonTexture::CreateBufferSubresource(UINT Subresource) { + void D3D9CommonTexture::CreateBufferSubresource(UINT Subresource, bool Initialize) { + if (likely(m_buffers[Subresource] != nullptr)) { + return; + } + DxvkBufferCreateInfo info; info.size = GetMipSize(Subresource); info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT @@ -201,6 +205,16 @@ namespace dxvk { m_buffers[Subresource] = m_device->GetDXVKDevice()->createBuffer(info, memType); m_mappedSlices[Subresource] = m_buffers[Subresource]->getSliceHandle(); + + if (Initialize) { + if (m_data[Subresource]) { + m_data[Subresource].Map(); + memcpy(m_mappedSlices[Subresource].mapPtr, m_data[Subresource].Ptr(), info.size); + } else { + memset(m_mappedSlices[Subresource].mapPtr, 0, info.size); + } + } + m_data[Subresource] = {}; } @@ -642,21 +656,7 @@ namespace dxvk { } } - const Rc& D3D9CommonTexture::GetBuffer(UINT Subresource, bool Initialize) { - if (unlikely(m_buffers[Subresource] == nullptr)) { - CreateBufferSubresource(Subresource); - - if (Initialize) { - if (m_data[Subresource]) { - m_data[Subresource].Map(); - memcpy(m_mappedSlices[Subresource].mapPtr, m_data[Subresource].Ptr(), GetMipSize(Subresource)); - } else { - memset(m_mappedSlices[Subresource].mapPtr, 0, GetMipSize(Subresource)); - } - } - m_data[Subresource] = {}; - } - + const Rc& D3D9CommonTexture::GetBuffer(UINT Subresource) { return m_buffers[Subresource]; } diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index 667d3f9d7..58c0827ba 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -153,7 +153,7 @@ namespace dxvk { */ void* GetData(UINT Subresource); - const Rc& GetBuffer(UINT Subresource, bool Initialize); + const Rc& GetBuffer(UINT Subresource); DxvkBufferSliceHandle GetMappedSlice(UINT Subresource) { @@ -466,6 +466,14 @@ namespace dxvk { */ VkDeviceSize GetMipSize(UINT Subresource) const; + /** + * \brief Creates a buffer + * Creates mapping and staging buffers for a given subresource + * allocates new buffers if necessary + * \returns Whether an allocation happened + */ + void CreateBufferSubresource(UINT Subresource, bool Initialize); + private: D3D9DeviceEx* m_device; @@ -542,14 +550,6 @@ namespace dxvk { D3DRESOURCETYPE Dimension, UINT Layer); - /** - * \brief Creates a buffer - * Creates mapping and staging buffers for a given subresource - * allocates new buffers if necessary - * \returns Whether an allocation happened - */ - void CreateBufferSubresource(UINT Subresource); - /** * \brief Creates buffers * Creates mapping and staging buffers for all subresources @@ -559,7 +559,7 @@ namespace dxvk { // D3D9Initializer will handle clearing the buffers const uint32_t count = CountSubresources(); for (uint32_t i = 0; i < count; i++) - CreateBufferSubresource(i); + CreateBufferSubresource(i, false); } void AllocData(); diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index a55b0bad0..2592e7858 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -889,7 +889,8 @@ namespace dxvk { VkExtent3D dstTexExtent = dstTexInfo->GetExtentMip(dst->GetMipLevel()); VkExtent3D srcTexExtent = srcTexInfo->GetExtentMip(src->GetMipLevel()); - Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height); + dstTexInfo->CreateBufferSubresource(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height); + Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource()); Rc srcImage = srcTexInfo->GetImage(); const DxvkFormatInfo* srcFormatInfo = lookupFormatInfo(srcImage->info().format); @@ -4260,12 +4261,17 @@ namespace dxvk { bool needsReadback = pResource->NeedsReadback(Subresource) || renderable; pResource->SetNeedsReadback(Subresource, false); + if (unlikely(pResource->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED || needsReadback)) { + // Create mapping buffer if it doesn't exist yet. (POOL_DEFAULT) + pResource->CreateBufferSubresource(Subresource, !needsReadback); + } + void* mapPtr; if ((Flags & D3DLOCK_DISCARD) && needsReadback) { // We do not have to preserve the contents of the // buffer if the entire image gets discarded. - const Rc mappedBuffer = pResource->GetBuffer(Subresource, false); + const Rc mappedBuffer = pResource->GetBuffer(Subresource); DxvkBufferSliceHandle physSlice = pResource->DiscardMapSlice(Subresource); mapPtr = physSlice.mapPtr; @@ -4276,16 +4282,11 @@ namespace dxvk { ctx->invalidateBuffer(cImageBuffer, cBufferSlice); }); } else { - if (unlikely(pResource->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED)) { - // Create mapping buffer if it doesn't exist yet. (POOL_DEFAULT) - pResource->GetBuffer(Subresource, !needsReadback); - } - // Don't use MapTexture here to keep the mapped list small while the resource is still locked. mapPtr = pResource->GetData(Subresource); if (needsReadback) { - const Rc mappedBuffer = pResource->GetBuffer(Subresource, false); + const Rc mappedBuffer = pResource->GetBuffer(Subresource); if (unlikely(needsReadback) && pResource->GetImage() != nullptr) { Rc resourceImage = pResource->GetImage(); @@ -4523,7 +4524,8 @@ namespace dxvk { auto convertFormat = pDestTexture->GetFormatMapping().ConversionFormatInfo; if (unlikely(pSrcTexture->NeedsReadback(SrcSubresource))) { - const Rc& buffer = pSrcTexture->GetBuffer(SrcSubresource, false); + pSrcTexture->CreateBufferSubresource(SrcSubresource, true); + const Rc& buffer = pSrcTexture->GetBuffer(SrcSubresource); WaitForResource(buffer, pSrcTexture->GetMappingBufferSequenceNumber(SrcSubresource), 0); pSrcTexture->SetNeedsReadback(SrcSubresource, false); } diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 8268e8002..634567d80 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -180,7 +180,8 @@ namespace dxvk { VkExtent3D dstTexExtent = dstTexInfo->GetExtentMip(dst->GetMipLevel()); VkExtent3D srcTexExtent = srcTexInfo->GetExtentMip(0); - Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height); + dstTexInfo->CreateBufferSubresource(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height); + Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource()); Rc srcImage = srcTexInfo->GetImage(); if (srcImage->info().sampleCount != VK_SAMPLE_COUNT_1_BIT) { From 3d6b687e4164e412c2062295e62512cc5a547c83 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 05:20:49 +0200 Subject: [PATCH 0644/1348] [dxbc] Remove useless lambda --- src/dxbc/dxbc_compiler.cpp | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 3cf2da356..927114a9e 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -7449,23 +7449,19 @@ namespace dxvk { bool isUav) const { uint32_t ms = m_moduleInfo.options.disableMsaa ? 0 : 1; - DxbcImageInfo typeInfo = [resourceType, isUav, ms] () -> DxbcImageInfo { - switch (resourceType) { - case DxbcResourceDim::Buffer: return { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_MAX_ENUM }; - case DxbcResourceDim::Texture1D: return { spv::Dim1D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_1D }; - case DxbcResourceDim::Texture1DArr: return { spv::Dim1D, 1, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_1D_ARRAY }; - case DxbcResourceDim::Texture2D: return { spv::Dim2D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D }; - case DxbcResourceDim::Texture2DArr: return { spv::Dim2D, 1, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY }; - case DxbcResourceDim::Texture2DMs: return { spv::Dim2D, 0, ms,isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D }; - case DxbcResourceDim::Texture2DMsArr: return { spv::Dim2D, 1, ms,isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY }; - case DxbcResourceDim::Texture3D: return { spv::Dim3D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_3D }; - case DxbcResourceDim::TextureCube: return { spv::DimCube, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_CUBE }; - case DxbcResourceDim::TextureCubeArr: return { spv::DimCube, 1, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY }; - default: throw DxvkError(str::format("DxbcCompiler: Unsupported resource type: ", resourceType)); - } - }(); - - return typeInfo; + switch (resourceType) { + case DxbcResourceDim::Buffer: return { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_MAX_ENUM }; + case DxbcResourceDim::Texture1D: return { spv::Dim1D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_1D }; + case DxbcResourceDim::Texture1DArr: return { spv::Dim1D, 1, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_1D_ARRAY }; + case DxbcResourceDim::Texture2D: return { spv::Dim2D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D }; + case DxbcResourceDim::Texture2DArr: return { spv::Dim2D, 1, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY }; + case DxbcResourceDim::Texture2DMs: return { spv::Dim2D, 0, ms,isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D }; + case DxbcResourceDim::Texture2DMsArr: return { spv::Dim2D, 1, ms,isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY }; + case DxbcResourceDim::Texture3D: return { spv::Dim3D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_3D }; + case DxbcResourceDim::TextureCube: return { spv::DimCube, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_CUBE }; + case DxbcResourceDim::TextureCubeArr: return { spv::DimCube, 1, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY }; + default: throw DxvkError(str::format("DxbcCompiler: Unsupported resource type: ", resourceType)); + } } From dd0d611d4d88daae7f3cab2dc34bd9b6e36e6c36 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 05:52:28 +0200 Subject: [PATCH 0645/1348] [dxvk] Reintroduce binary semaphore for transfer <-> graphics sync The global timeline semaphore does not work here since we could be signaling it from two different queues at the same time, or out of order. --- src/dxvk/dxvk_cmdlist.cpp | 11 +++++++---- src/dxvk/dxvk_cmdlist.h | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index fd185b387..0d63dd5c6 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -11,6 +11,9 @@ namespace dxvk { const auto& graphicsQueue = m_device->queues().graphics; const auto& transferQueue = m_device->queues().transfer; + VkSemaphoreCreateInfo semaphoreInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; + m_vkd->vkCreateSemaphore(m_vkd->device(), &semaphoreInfo, nullptr, &m_sdmaSemaphore); + VkCommandPoolCreateInfo poolInfo; poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolInfo.pNext = nullptr; @@ -53,6 +56,8 @@ namespace dxvk { m_vkd->vkDestroyCommandPool(m_vkd->device(), m_graphicsPool, nullptr); m_vkd->vkDestroyCommandPool(m_vkd->device(), m_transferPool, nullptr); + + m_vkd->vkDestroySemaphore(m_vkd->device(), m_sdmaSemaphore, nullptr); } @@ -71,8 +76,7 @@ namespace dxvk { if (m_device->hasDedicatedTransferQueue()) { VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - signalInfo.semaphore = semaphore; - signalInfo.value = ++semaphoreValue; + signalInfo.semaphore = m_sdmaSemaphore; signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; m_submission.signalInfos.push_back(signalInfo); @@ -84,8 +88,7 @@ namespace dxvk { m_submission.reset(); VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - waitInfo.semaphore = semaphore; - waitInfo.value = semaphoreValue; + waitInfo.semaphore = m_sdmaSemaphore; waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; m_submission.waitInfos.push_back(waitInfo); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 297b2be67..ca04d13f1 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -818,6 +818,8 @@ namespace dxvk { VkCommandBuffer m_initBuffer = VK_NULL_HANDLE; VkCommandBuffer m_sdmaBuffer = VK_NULL_HANDLE; + VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE; + vk::PresenterSync m_wsiSemaphores = { }; DxvkCmdBufferFlags m_cmdBuffersUsed; From f88239719cbdf89b7442c08437dca7abf1b28993 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 20:44:57 +0200 Subject: [PATCH 0646/1348] [dxvk] Explicitly mark execution command buffer as used We can omit the execution command buffer in some circumstances, and for the sparse resource changes we need to track this in order to be able to merge consecutive sparse binding calls. We only need to do this on action commands with observable side effects as long as the backend still properly resets those command buffers. All draw commands are implcitly covered by cmdBeginRendering. --- src/dxvk/dxvk_cmdlist.cpp | 11 ------- src/dxvk/dxvk_cmdlist.h | 65 +++++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 27 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 0d63dd5c6..50ea433cc 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -226,15 +226,4 @@ namespace dxvk { return m_vkd->vkQueueSubmit2(queue, 1, &submitInfo, VK_NULL_HANDLE); } - void DxvkCommandList::cmdBeginDebugUtilsLabel(VkDebugUtilsLabelEXT *pLabelInfo) { - m_vki->vkCmdBeginDebugUtilsLabelEXT(m_execBuffer, pLabelInfo); - } - - void DxvkCommandList::cmdEndDebugUtilsLabel() { - m_vki->vkCmdEndDebugUtilsLabelEXT(m_execBuffer); - } - - void DxvkCommandList::cmdInsertDebugUtilsLabel(VkDebugUtilsLabelEXT *pLabelInfo) { - m_vki->vkCmdInsertDebugUtilsLabelEXT(m_execBuffer, pLabelInfo); - } } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index ca04d13f1..6f5d6a8f7 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -260,23 +260,12 @@ namespace dxvk { } - void cmdBeginConditionalRendering( - const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin) { - m_vkd->vkCmdBeginConditionalRenderingEXT( - m_execBuffer, pConditionalRenderingBegin); - } - - - void cmdEndConditionalRendering() { - m_vkd->vkCmdEndConditionalRenderingEXT(m_execBuffer); - } - - - void cmdBeginQuery( VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdBeginQuery(m_execBuffer, queryPool, query, flags); } @@ -287,6 +276,8 @@ namespace dxvk { uint32_t query, VkQueryControlFlags flags, uint32_t index) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdBeginQueryIndexedEXT( m_execBuffer, queryPool, query, flags, index); } @@ -294,6 +285,8 @@ namespace dxvk { void cmdBeginRendering( const VkRenderingInfo* pRenderingInfo) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdBeginRendering(m_execBuffer, pRenderingInfo); } @@ -375,11 +368,16 @@ namespace dxvk { } void cmdLaunchCuKernel(VkCuLaunchInfoNVX launchInfo) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdCuLaunchKernelNVX(m_execBuffer, &launchInfo); } + void cmdBlitImage( const VkBlitImageInfo2* pBlitInfo) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdBlitImage2(m_execBuffer, pBlitInfo); } @@ -401,6 +399,8 @@ namespace dxvk { const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdClearColorImage(m_execBuffer, image, imageLayout, pColor, rangeCount, pRanges); @@ -413,6 +413,8 @@ namespace dxvk { const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdClearDepthStencilImage(m_execBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges); @@ -463,6 +465,8 @@ namespace dxvk { VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdCopyQueryPoolResults(m_execBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags); @@ -473,6 +477,8 @@ namespace dxvk { uint32_t x, uint32_t y, uint32_t z) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdDispatch(m_execBuffer, x, y, z); } @@ -480,6 +486,8 @@ namespace dxvk { void cmdDispatchIndirect( VkBuffer buffer, VkDeviceSize offset) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdDispatchIndirect( m_execBuffer, buffer, offset); } @@ -632,6 +640,8 @@ namespace dxvk { void cmdResolveImage( const VkResolveImageInfo2* resolveInfo) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdResolveImage2(m_execBuffer, resolveInfo); } @@ -705,6 +715,8 @@ namespace dxvk { void cmdSetEvent( VkEvent event, const VkDependencyInfo* dependencyInfo) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdSetEvent2(m_execBuffer, event, dependencyInfo); } @@ -781,15 +793,35 @@ namespace dxvk { VkPipelineStageFlagBits2 pipelineStage, VkQueryPool queryPool, uint32_t query) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_vkd->vkCmdWriteTimestamp2(m_execBuffer, pipelineStage, queryPool, query); } - void cmdBeginDebugUtilsLabel(VkDebugUtilsLabelEXT *pLabelInfo); - void cmdEndDebugUtilsLabel(); + void cmdBeginDebugUtilsLabel( + VkDebugUtilsLabelEXT* pLabelInfo) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + + m_vki->vkCmdBeginDebugUtilsLabelEXT(m_execBuffer, pLabelInfo); + } + + + void cmdEndDebugUtilsLabel() { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + + m_vki->vkCmdEndDebugUtilsLabelEXT(m_execBuffer); + } + + + void cmdInsertDebugUtilsLabel( + VkDebugUtilsLabelEXT* pLabelInfo) { + m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + + m_vki->vkCmdInsertDebugUtilsLabelEXT(m_execBuffer, pLabelInfo); + } - void cmdInsertDebugUtilsLabel(VkDebugUtilsLabelEXT *pLabelInfo); void resetQuery( VkQueryPool queryPool, @@ -798,6 +830,7 @@ namespace dxvk { m_vkd->device(), queryPool, queryId, 1); } + void trackDescriptorPool( const Rc& pool, const Rc& manager) { From d367fac64e413cca26d1e37a7f9b70b19b543748 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 13:36:23 +0200 Subject: [PATCH 0647/1348] [dxvk] Rework queue submission helper We want this to be less verbose and smarter about when to perform submissions for when we introduce the ability to split a command list into multiple submissions. --- src/dxvk/dxvk_cmdlist.cpp | 189 +++++++++++++++++++++++--------------- src/dxvk/dxvk_cmdlist.h | 82 +++++++++++++---- 2 files changed, 180 insertions(+), 91 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 50ea433cc..80454d111 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -2,7 +2,91 @@ #include "dxvk_device.h" namespace dxvk { - + + DxvkCommandSubmission::DxvkCommandSubmission() { + + } + + + DxvkCommandSubmission::~DxvkCommandSubmission() { + + } + + + void DxvkCommandSubmission::waitSemaphore( + VkSemaphore semaphore, + uint64_t value, + VkPipelineStageFlags2 stageMask) { + VkSemaphoreSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + submitInfo.semaphore = semaphore; + submitInfo.value = value; + submitInfo.stageMask = stageMask; + + m_semaphoreWaits.push_back(submitInfo); + } + + + void DxvkCommandSubmission::signalSemaphore( + VkSemaphore semaphore, + uint64_t value, + VkPipelineStageFlags2 stageMask) { + VkSemaphoreSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; + submitInfo.semaphore = semaphore; + submitInfo.value = value; + submitInfo.stageMask = stageMask; + + m_semaphoreSignals.push_back(submitInfo); + } + + + void DxvkCommandSubmission::executeCommandBuffer( + VkCommandBuffer commandBuffer) { + VkCommandBufferSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; + submitInfo.commandBuffer = commandBuffer; + + m_commandBuffers.push_back(submitInfo); + } + + + VkResult DxvkCommandSubmission::submit( + DxvkDevice* device, + VkQueue queue) { + auto vk = device->vkd(); + + VkSubmitInfo2 submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO_2 }; + + if (!m_semaphoreWaits.empty()) { + submitInfo.waitSemaphoreInfoCount = m_semaphoreWaits.size(); + submitInfo.pWaitSemaphoreInfos = m_semaphoreWaits.data(); + } + + if (!m_commandBuffers.empty()) { + submitInfo.commandBufferInfoCount = m_commandBuffers.size(); + submitInfo.pCommandBufferInfos = m_commandBuffers.data(); + } + + if (!m_semaphoreSignals.empty()) { + submitInfo.signalSemaphoreInfoCount = m_semaphoreSignals.size(); + submitInfo.pSignalSemaphoreInfos = m_semaphoreSignals.data(); + } + + VkResult vr = VK_SUCCESS; + + if (submitInfo.waitSemaphoreInfoCount || submitInfo.commandBufferInfoCount || submitInfo.signalSemaphoreInfoCount) + vr = vk->vkQueueSubmit2(queue, 1, &submitInfo, VK_NULL_HANDLE); + + this->reset(); + return vr; + } + + + void DxvkCommandSubmission::reset() { + m_semaphoreWaits.clear(); + m_semaphoreSignals.clear(); + m_commandBuffers.clear(); + } + + DxvkCommandList::DxvkCommandList(DxvkDevice* device) : m_device (device), m_vkd (device->vkd()), @@ -12,7 +96,9 @@ namespace dxvk { const auto& transferQueue = m_device->queues().transfer; VkSemaphoreCreateInfo semaphoreInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; - m_vkd->vkCreateSemaphore(m_vkd->device(), &semaphoreInfo, nullptr, &m_sdmaSemaphore); + + if (m_vkd->vkCreateSemaphore(m_vkd->device(), &semaphoreInfo, nullptr, &m_sdmaSemaphore)) + throw DxvkError("DxvkCommandList: Failed to create semaphore"); VkCommandPoolCreateInfo poolInfo; poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; @@ -64,86 +150,58 @@ namespace dxvk { VkResult DxvkCommandList::submit( VkSemaphore semaphore, uint64_t& semaphoreValue) { + VkResult status = VK_SUCCESS; + const auto& graphics = m_device->queues().graphics; const auto& transfer = m_device->queues().transfer; - m_submission.reset(); + m_commandSubmission.reset(); if (m_cmdBuffersUsed.test(DxvkCmdBuffer::SdmaBuffer)) { - VkCommandBufferSubmitInfo cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; - cmdInfo.commandBuffer = m_sdmaBuffer; - m_submission.cmdBuffers.push_back(cmdInfo); + m_commandSubmission.executeCommandBuffer(m_sdmaBuffer); if (m_device->hasDedicatedTransferQueue()) { - VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - signalInfo.semaphore = m_sdmaSemaphore; - signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; - m_submission.signalInfos.push_back(signalInfo); + m_commandSubmission.signalSemaphore(m_sdmaSemaphore, 0, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); - VkResult status = submitToQueue(transfer.queueHandle, m_submission); - - if (status != VK_SUCCESS) + if ((status = m_commandSubmission.submit(m_device, transfer.queueHandle))) return status; - m_submission.reset(); - - VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - waitInfo.semaphore = m_sdmaSemaphore; - waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; - m_submission.waitInfos.push_back(waitInfo); + m_commandSubmission.waitSemaphore(m_sdmaSemaphore, 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); } } - if (m_cmdBuffersUsed.test(DxvkCmdBuffer::InitBuffer)) { - VkCommandBufferSubmitInfo cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; - cmdInfo.commandBuffer = m_initBuffer; - m_submission.cmdBuffers.push_back(cmdInfo); - } + if (m_cmdBuffersUsed.test(DxvkCmdBuffer::InitBuffer)) + m_commandSubmission.executeCommandBuffer(m_initBuffer); + + if (m_cmdBuffersUsed.test(DxvkCmdBuffer::ExecBuffer)) + m_commandSubmission.executeCommandBuffer(m_execBuffer); - if (m_cmdBuffersUsed.test(DxvkCmdBuffer::ExecBuffer)) { - VkCommandBufferSubmitInfo cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; - cmdInfo.commandBuffer = m_execBuffer; - m_submission.cmdBuffers.push_back(cmdInfo); - } - if (m_wsiSemaphores.acquire) { - VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - waitInfo.semaphore = m_wsiSemaphores.acquire; - waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; - m_submission.waitInfos.push_back(waitInfo); + m_commandSubmission.waitSemaphore(m_wsiSemaphores.acquire, + 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); } if (m_wsiSemaphores.present) { - VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - signalInfo.semaphore = m_wsiSemaphores.present; - signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; - m_submission.signalInfos.push_back(signalInfo); + m_commandSubmission.signalSemaphore(m_wsiSemaphores.present, + 0, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); } - + for (const auto& entry : m_waitSemaphores) { - VkSemaphoreSubmitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - waitInfo.semaphore = entry.fence->handle(); - waitInfo.value = entry.value; - waitInfo.stageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; - m_submission.waitInfos.push_back(waitInfo); + m_commandSubmission.waitSemaphore( + entry.fence->handle(), + entry.value, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); } - for (const auto& entry : m_signalSemaphores) { - VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - signalInfo.semaphore = entry.fence->handle(); - signalInfo.value = entry.value; - signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; - m_submission.signalInfos.push_back(signalInfo); - } + for (const auto& entry : m_signalSemaphores) + m_commandSubmission.signalSemaphore(entry.fence->handle(), entry.value, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); - // Signal global timeline semaphore - VkSemaphoreSubmitInfo signalInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO }; - signalInfo.semaphore = semaphore; - signalInfo.value = ++semaphoreValue; - signalInfo.stageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; - m_submission.signalInfos.push_back(signalInfo); + m_commandSubmission.signalSemaphore(semaphore, + ++semaphoreValue, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); - return submitToQueue(graphics.queueHandle, m_submission); + if ((status = m_commandSubmission.submit(m_device, graphics.queueHandle))) + return status; + + return VK_SUCCESS; } @@ -211,19 +269,4 @@ namespace dxvk { m_wsiSemaphores = vk::PresenterSync(); } - - VkResult DxvkCommandList::submitToQueue( - VkQueue queue, - const DxvkQueueSubmission& info) { - VkSubmitInfo2 submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO_2 }; - submitInfo.waitSemaphoreInfoCount = info.waitInfos.size(); - submitInfo.pWaitSemaphoreInfos = info.waitInfos.data(); - submitInfo.commandBufferInfoCount = info.cmdBuffers.size(); - submitInfo.pCommandBufferInfos = info.cmdBuffers.data(); - submitInfo.signalSemaphoreInfoCount = info.signalInfos.size(); - submitInfo.pSignalSemaphoreInfos = info.signalInfos.data(); - - return m_vkd->vkQueueSubmit2(queue, 1, &submitInfo, VK_NULL_HANDLE); - } - } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 6f5d6a8f7..e844556e6 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -35,22 +35,71 @@ namespace dxvk { using DxvkCmdBufferFlags = Flags; /** - * \brief Queue submission info + * \brief Queue command submission * - * Convenience struct that holds data for - * actual command submissions. Internal use - * only, array sizes are based on need. + * Convenience class that holds data for a single + * command submission, which then easily be executed. */ - struct DxvkQueueSubmission { - std::vector waitInfos; - std::vector signalInfos; - std::vector cmdBuffers; + class DxvkCommandSubmission { + + public: + + DxvkCommandSubmission(); + ~DxvkCommandSubmission(); + + /** + * \brief Adds a semaphore to wait on + * + * \param [in] semaphore The semaphore + * \param [in] value Semaphore value + * \param [in] stageMask Stages to block + */ + void waitSemaphore( + VkSemaphore semaphore, + uint64_t value, + VkPipelineStageFlags2 stageMask); + + /** + * \brief Adds a semaphore to signal + * + * \param [in] semaphore The semaphore + * \param [in] value Semaphore value + * \param [in] stageMask Stages to signal on + */ + void signalSemaphore( + VkSemaphore semaphore, + uint64_t value, + VkPipelineStageFlags2 stageMask); + + /** + * \brief Adds a command buffer to execute + * \param [in] commandBuffer The command buffer + */ + void executeCommandBuffer( + VkCommandBuffer commandBuffer); + + /** + * \brief Executes submission and resets object + * + * \param [in] device DXVK device + * \param [in] queue Queue to submit to + * \returns Submission return value + */ + VkResult submit( + DxvkDevice* device, + VkQueue queue); + + /** + * \brief Resets object + */ + void reset(); + + private: + + std::vector m_semaphoreWaits; + std::vector m_semaphoreSignals; + std::vector m_commandBuffers; - void reset() { - waitInfos.clear(); - signalInfos.clear(); - cmdBuffers.clear(); - } }; /** @@ -862,7 +911,8 @@ namespace dxvk { DxvkGpuQueryTracker m_gpuQueryTracker; DxvkBufferTracker m_bufferTracker; DxvkStatCounters m_statCounters; - DxvkQueueSubmission m_submission; + + DxvkCommandSubmission m_commandSubmission; std::vector m_waitSemaphores; std::vector m_signalSemaphores; @@ -879,10 +929,6 @@ namespace dxvk { if (cmdBuffer == DxvkCmdBuffer::SdmaBuffer) return m_sdmaBuffer; return VK_NULL_HANDLE; } - - VkResult submitToQueue( - VkQueue queue, - const DxvkQueueSubmission& info); }; From def93fd18ba3347f219c615f514190297b3e8644 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 13:50:10 +0200 Subject: [PATCH 0648/1348] [dxvk] Introduce DxvkCommandSubmissionInfo --- src/dxvk/dxvk_cmdlist.cpp | 37 +++---- src/dxvk/dxvk_cmdlist.h | 222 ++++++++++++++++++++------------------ 2 files changed, 133 insertions(+), 126 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 80454d111..cc5af6ca3 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -90,8 +90,7 @@ namespace dxvk { DxvkCommandList::DxvkCommandList(DxvkDevice* device) : m_device (device), m_vkd (device->vkd()), - m_vki (device->instance()->vki()), - m_cmdBuffersUsed(0) { + m_vki (device->instance()->vki()) { const auto& graphicsQueue = m_device->queues().graphics; const auto& transferQueue = m_device->queues().transfer; @@ -130,9 +129,9 @@ namespace dxvk { cmdInfoDma.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; cmdInfoDma.commandBufferCount = 1; - if (m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoGfx, &m_execBuffer) != VK_SUCCESS - || m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoGfx, &m_initBuffer) != VK_SUCCESS - || m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoDma, &m_sdmaBuffer) != VK_SUCCESS) + if (m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoGfx, &m_cmd.execBuffer) != VK_SUCCESS + || m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoGfx, &m_cmd.initBuffer) != VK_SUCCESS + || m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoDma, &m_cmd.sdmaBuffer) != VK_SUCCESS) throw DxvkError("DxvkCommandList: Failed to allocate command buffer"); } @@ -157,8 +156,8 @@ namespace dxvk { m_commandSubmission.reset(); - if (m_cmdBuffersUsed.test(DxvkCmdBuffer::SdmaBuffer)) { - m_commandSubmission.executeCommandBuffer(m_sdmaBuffer); + if (m_cmd.usedFlags.test(DxvkCmdBuffer::SdmaBuffer)) { + m_commandSubmission.executeCommandBuffer(m_cmd.sdmaBuffer); if (m_device->hasDedicatedTransferQueue()) { m_commandSubmission.signalSemaphore(m_sdmaSemaphore, 0, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); @@ -170,11 +169,11 @@ namespace dxvk { } } - if (m_cmdBuffersUsed.test(DxvkCmdBuffer::InitBuffer)) - m_commandSubmission.executeCommandBuffer(m_initBuffer); + if (m_cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer)) + m_commandSubmission.executeCommandBuffer(m_cmd.initBuffer); - if (m_cmdBuffersUsed.test(DxvkCmdBuffer::ExecBuffer)) - m_commandSubmission.executeCommandBuffer(m_execBuffer); + if (m_cmd.usedFlags.test(DxvkCmdBuffer::ExecBuffer)) + m_commandSubmission.executeCommandBuffer(m_cmd.execBuffer); if (m_wsiSemaphores.acquire) { m_commandSubmission.waitSemaphore(m_wsiSemaphores.acquire, @@ -216,21 +215,17 @@ namespace dxvk { || (m_transferPool && m_vkd->vkResetCommandPool(m_vkd->device(), m_transferPool, 0) != VK_SUCCESS)) Logger::err("DxvkCommandList: Failed to reset command buffer"); - if (m_vkd->vkBeginCommandBuffer(m_execBuffer, &info) != VK_SUCCESS - || m_vkd->vkBeginCommandBuffer(m_initBuffer, &info) != VK_SUCCESS - || m_vkd->vkBeginCommandBuffer(m_sdmaBuffer, &info) != VK_SUCCESS) + if (m_vkd->vkBeginCommandBuffer(m_cmd.execBuffer, &info) != VK_SUCCESS + || m_vkd->vkBeginCommandBuffer(m_cmd.initBuffer, &info) != VK_SUCCESS + || m_vkd->vkBeginCommandBuffer(m_cmd.sdmaBuffer, &info) != VK_SUCCESS) Logger::err("DxvkCommandList: Failed to begin command buffer"); - - // Unconditionally mark the exec buffer as used. There - // is virtually no use case where this isn't correct. - m_cmdBuffersUsed = DxvkCmdBuffer::ExecBuffer; } void DxvkCommandList::endRecording() { - if (m_vkd->vkEndCommandBuffer(m_execBuffer) != VK_SUCCESS - || m_vkd->vkEndCommandBuffer(m_initBuffer) != VK_SUCCESS - || m_vkd->vkEndCommandBuffer(m_sdmaBuffer) != VK_SUCCESS) + if (m_vkd->vkEndCommandBuffer(m_cmd.execBuffer) != VK_SUCCESS + || m_vkd->vkEndCommandBuffer(m_cmd.initBuffer) != VK_SUCCESS + || m_vkd->vkEndCommandBuffer(m_cmd.sdmaBuffer) != VK_SUCCESS) Logger::err("DxvkCommandList::endRecording: Failed to record command buffer"); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index e844556e6..25bd59127 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -102,6 +102,21 @@ namespace dxvk { }; + + /** + * \brief Command submission info + * + * Stores a set of command buffers, as well as a + * mask of command buffers that were actually used. + */ + struct DxvkCommandSubmissionInfo { + DxvkCmdBufferFlags usedFlags = 0; + VkCommandBuffer execBuffer = VK_NULL_HANDLE; + VkCommandBuffer initBuffer = VK_NULL_HANDLE; + VkCommandBuffer sdmaBuffer = VK_NULL_HANDLE; + }; + + /** * \brief DXVK command list * @@ -313,9 +328,9 @@ namespace dxvk { VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vkd->vkCmdBeginQuery(m_execBuffer, + m_vkd->vkCmdBeginQuery(m_cmd.execBuffer, queryPool, query, flags); } @@ -325,18 +340,18 @@ namespace dxvk { uint32_t query, VkQueryControlFlags flags, uint32_t index) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); m_vkd->vkCmdBeginQueryIndexedEXT( - m_execBuffer, queryPool, query, flags, index); + m_cmd.execBuffer, queryPool, query, flags, index); } void cmdBeginRendering( const VkRenderingInfo* pRenderingInfo) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vkd->vkCmdBeginRendering(m_execBuffer, pRenderingInfo); + m_vkd->vkCmdBeginRendering(m_cmd.execBuffer, pRenderingInfo); } @@ -345,7 +360,7 @@ namespace dxvk { uint32_t bufferCount, const VkBuffer* counterBuffers, const VkDeviceSize* counterOffsets) { - m_vkd->vkCmdBeginTransformFeedbackEXT(m_execBuffer, + m_vkd->vkCmdBeginTransformFeedbackEXT(m_cmd.execBuffer, firstBuffer, bufferCount, counterBuffers, counterOffsets); } @@ -356,7 +371,7 @@ namespace dxvk { VkDescriptorSet descriptorSet, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets) { - m_vkd->vkCmdBindDescriptorSets(m_execBuffer, + m_vkd->vkCmdBindDescriptorSets(m_cmd.execBuffer, pipeline, pipelineLayout, 0, 1, &descriptorSet, dynamicOffsetCount, pDynamicOffsets); } @@ -370,7 +385,7 @@ namespace dxvk { const VkDescriptorSet* descriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets) { - m_vkd->vkCmdBindDescriptorSets(m_execBuffer, + m_vkd->vkCmdBindDescriptorSets(m_cmd.execBuffer, pipeline, pipelineLayout, firstSet, descriptorSetCount, descriptorSets, dynamicOffsetCount, pDynamicOffsets); } @@ -380,7 +395,7 @@ namespace dxvk { VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType) { - m_vkd->vkCmdBindIndexBuffer(m_execBuffer, + m_vkd->vkCmdBindIndexBuffer(m_cmd.execBuffer, buffer, offset, indexType); } @@ -388,7 +403,7 @@ namespace dxvk { void cmdBindPipeline( VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) { - m_vkd->vkCmdBindPipeline(m_execBuffer, + m_vkd->vkCmdBindPipeline(m_cmd.execBuffer, pipelineBindPoint, pipeline); } @@ -399,7 +414,7 @@ namespace dxvk { const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes) { - m_vkd->vkCmdBindTransformFeedbackBuffersEXT(m_execBuffer, + m_vkd->vkCmdBindTransformFeedbackBuffersEXT(m_cmd.execBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes); } @@ -411,23 +426,23 @@ namespace dxvk { const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides) { - m_vkd->vkCmdBindVertexBuffers2(m_execBuffer, + m_vkd->vkCmdBindVertexBuffers2(m_cmd.execBuffer, firstBinding, bindingCount, pBuffers, pOffsets, pSizes, pStrides); } void cmdLaunchCuKernel(VkCuLaunchInfoNVX launchInfo) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vkd->vkCmdCuLaunchKernelNVX(m_execBuffer, &launchInfo); + m_vkd->vkCmdCuLaunchKernelNVX(m_cmd.execBuffer, &launchInfo); } void cmdBlitImage( const VkBlitImageInfo2* pBlitInfo) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vkd->vkCmdBlitImage2(m_execBuffer, pBlitInfo); + m_vkd->vkCmdBlitImage2(m_cmd.execBuffer, pBlitInfo); } @@ -436,7 +451,7 @@ namespace dxvk { const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects) { - m_vkd->vkCmdClearAttachments(m_execBuffer, + m_vkd->vkCmdClearAttachments(m_cmd.execBuffer, attachmentCount, pAttachments, rectCount, pRects); } @@ -448,9 +463,9 @@ namespace dxvk { const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vkd->vkCmdClearColorImage(m_execBuffer, + m_vkd->vkCmdClearColorImage(m_cmd.execBuffer, image, imageLayout, pColor, rangeCount, pRanges); } @@ -462,9 +477,9 @@ namespace dxvk { const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vkd->vkCmdClearDepthStencilImage(m_execBuffer, + m_vkd->vkCmdClearDepthStencilImage(m_cmd.execBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges); } @@ -473,7 +488,7 @@ namespace dxvk { void cmdCopyBuffer( DxvkCmdBuffer cmdBuffer, const VkCopyBufferInfo2* copyInfo) { - m_cmdBuffersUsed.set(cmdBuffer); + m_cmd.usedFlags.set(cmdBuffer); m_vkd->vkCmdCopyBuffer2(getCmdBuffer(cmdBuffer), copyInfo); } @@ -482,7 +497,7 @@ namespace dxvk { void cmdCopyBufferToImage( DxvkCmdBuffer cmdBuffer, const VkCopyBufferToImageInfo2* copyInfo) { - m_cmdBuffersUsed.set(cmdBuffer); + m_cmd.usedFlags.set(cmdBuffer); m_vkd->vkCmdCopyBufferToImage2(getCmdBuffer(cmdBuffer), copyInfo); } @@ -491,7 +506,7 @@ namespace dxvk { void cmdCopyImage( DxvkCmdBuffer cmdBuffer, const VkCopyImageInfo2* copyInfo) { - m_cmdBuffersUsed.set(cmdBuffer); + m_cmd.usedFlags.set(cmdBuffer); m_vkd->vkCmdCopyImage2(getCmdBuffer(cmdBuffer), copyInfo); } @@ -500,7 +515,7 @@ namespace dxvk { void cmdCopyImageToBuffer( DxvkCmdBuffer cmdBuffer, const VkCopyImageToBufferInfo2* copyInfo) { - m_cmdBuffersUsed.set(cmdBuffer); + m_cmd.usedFlags.set(cmdBuffer); m_vkd->vkCmdCopyImageToBuffer2(getCmdBuffer(cmdBuffer), copyInfo); } @@ -514,9 +529,9 @@ namespace dxvk { VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vkd->vkCmdCopyQueryPoolResults(m_execBuffer, + m_vkd->vkCmdCopyQueryPoolResults(m_cmd.execBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, stride, flags); } @@ -526,19 +541,19 @@ namespace dxvk { uint32_t x, uint32_t y, uint32_t z) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vkd->vkCmdDispatch(m_execBuffer, x, y, z); + m_vkd->vkCmdDispatch(m_cmd.execBuffer, x, y, z); } void cmdDispatchIndirect( VkBuffer buffer, VkDeviceSize offset) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); m_vkd->vkCmdDispatchIndirect( - m_execBuffer, buffer, offset); + m_cmd.execBuffer, buffer, offset); } @@ -547,7 +562,7 @@ namespace dxvk { uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) { - m_vkd->vkCmdDraw(m_execBuffer, + m_vkd->vkCmdDraw(m_cmd.execBuffer, vertexCount, instanceCount, firstVertex, firstInstance); } @@ -558,7 +573,7 @@ namespace dxvk { VkDeviceSize offset, uint32_t drawCount, uint32_t stride) { - m_vkd->vkCmdDrawIndirect(m_execBuffer, + m_vkd->vkCmdDrawIndirect(m_cmd.execBuffer, buffer, offset, drawCount, stride); } @@ -570,7 +585,7 @@ namespace dxvk { VkDeviceSize countOffset, uint32_t maxDrawCount, uint32_t stride) { - m_vkd->vkCmdDrawIndirectCount(m_execBuffer, + m_vkd->vkCmdDrawIndirectCount(m_cmd.execBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride); } @@ -581,7 +596,7 @@ namespace dxvk { uint32_t firstIndex, uint32_t vertexOffset, uint32_t firstInstance) { - m_vkd->vkCmdDrawIndexed(m_execBuffer, + m_vkd->vkCmdDrawIndexed(m_cmd.execBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); @@ -593,7 +608,7 @@ namespace dxvk { VkDeviceSize offset, uint32_t drawCount, uint32_t stride) { - m_vkd->vkCmdDrawIndexedIndirect(m_execBuffer, + m_vkd->vkCmdDrawIndexedIndirect(m_cmd.execBuffer, buffer, offset, drawCount, stride); } @@ -605,7 +620,7 @@ namespace dxvk { VkDeviceSize countOffset, uint32_t maxDrawCount, uint32_t stride) { - m_vkd->vkCmdDrawIndexedIndirectCount(m_execBuffer, + m_vkd->vkCmdDrawIndexedIndirectCount(m_cmd.execBuffer, buffer, offset, countBuffer, countOffset, maxDrawCount, stride); } @@ -617,7 +632,7 @@ namespace dxvk { VkDeviceSize counterBufferOffset, uint32_t counterOffset, uint32_t vertexStride) { - m_vkd->vkCmdDrawIndirectByteCountEXT(m_execBuffer, + m_vkd->vkCmdDrawIndirectByteCountEXT(m_cmd.execBuffer, instanceCount, firstInstance, counterBuffer, counterBufferOffset, counterOffset, vertexStride); } @@ -626,7 +641,7 @@ namespace dxvk { void cmdEndQuery( VkQueryPool queryPool, uint32_t query) { - m_vkd->vkCmdEndQuery(m_execBuffer, queryPool, query); + m_vkd->vkCmdEndQuery(m_cmd.execBuffer, queryPool, query); } @@ -635,12 +650,12 @@ namespace dxvk { uint32_t query, uint32_t index) { m_vkd->vkCmdEndQueryIndexedEXT( - m_execBuffer, queryPool, query, index); + m_cmd.execBuffer, queryPool, query, index); } void cmdEndRendering() { - m_vkd->vkCmdEndRendering(m_execBuffer); + m_vkd->vkCmdEndRendering(m_cmd.execBuffer); } @@ -649,7 +664,7 @@ namespace dxvk { uint32_t bufferCount, const VkBuffer* counterBuffers, const VkDeviceSize* counterOffsets) { - m_vkd->vkCmdEndTransformFeedbackEXT(m_execBuffer, + m_vkd->vkCmdEndTransformFeedbackEXT(m_cmd.execBuffer, firstBuffer, bufferCount, counterBuffers, counterOffsets); } @@ -660,7 +675,7 @@ namespace dxvk { VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) { - m_cmdBuffersUsed.set(cmdBuffer); + m_cmd.usedFlags.set(cmdBuffer); m_vkd->vkCmdFillBuffer(getCmdBuffer(cmdBuffer), dstBuffer, dstOffset, size, data); @@ -670,7 +685,7 @@ namespace dxvk { void cmdPipelineBarrier( DxvkCmdBuffer cmdBuffer, const VkDependencyInfo* dependencyInfo) { - m_cmdBuffersUsed.set(cmdBuffer); + m_cmd.usedFlags.set(cmdBuffer); m_vkd->vkCmdPipelineBarrier2(getCmdBuffer(cmdBuffer), dependencyInfo); } @@ -682,16 +697,16 @@ namespace dxvk { uint32_t offset, uint32_t size, const void* pValues) { - m_vkd->vkCmdPushConstants(m_execBuffer, + m_vkd->vkCmdPushConstants(m_cmd.execBuffer, layout, stageFlags, offset, size, pValues); } void cmdResolveImage( const VkResolveImageInfo2* resolveInfo) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vkd->vkCmdResolveImage2(m_execBuffer, resolveInfo); + m_vkd->vkCmdResolveImage2(m_cmd.execBuffer, resolveInfo); } @@ -701,7 +716,7 @@ namespace dxvk { VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData) { - m_cmdBuffersUsed.set(cmdBuffer); + m_cmd.usedFlags.set(cmdBuffer); m_vkd->vkCmdUpdateBuffer(getCmdBuffer(cmdBuffer), dstBuffer, dstOffset, dataSize, pData); @@ -709,13 +724,13 @@ namespace dxvk { void cmdSetBlendConstants(const float blendConstants[4]) { - m_vkd->vkCmdSetBlendConstants(m_execBuffer, blendConstants); + m_vkd->vkCmdSetBlendConstants(m_cmd.execBuffer, blendConstants); } void cmdSetDepthBiasState( VkBool32 depthBiasEnable) { - m_vkd->vkCmdSetDepthBiasEnable(m_execBuffer, depthBiasEnable); + m_vkd->vkCmdSetDepthBiasEnable(m_cmd.execBuffer, depthBiasEnable); } @@ -723,7 +738,7 @@ namespace dxvk { float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor) { - m_vkd->vkCmdSetDepthBias(m_execBuffer, + m_vkd->vkCmdSetDepthBias(m_cmd.execBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor); @@ -733,7 +748,7 @@ namespace dxvk { void cmdSetDepthBounds( float minDepthBounds, float maxDepthBounds) { - m_vkd->vkCmdSetDepthBounds(m_execBuffer, + m_vkd->vkCmdSetDepthBounds(m_cmd.execBuffer, minDepthBounds, maxDepthBounds); } @@ -741,7 +756,7 @@ namespace dxvk { void cmdSetDepthBoundsState( VkBool32 depthBoundsTestEnable) { - m_vkd->vkCmdSetDepthBoundsTestEnable(m_execBuffer, depthBoundsTestEnable); + m_vkd->vkCmdSetDepthBoundsTestEnable(m_cmd.execBuffer, depthBoundsTestEnable); } @@ -749,14 +764,14 @@ namespace dxvk { VkBool32 depthTestEnable, VkBool32 depthWriteEnable, VkCompareOp depthCompareOp) { - m_vkd->vkCmdSetDepthTestEnable(m_execBuffer, depthTestEnable); + m_vkd->vkCmdSetDepthTestEnable(m_cmd.execBuffer, depthTestEnable); if (depthTestEnable) { - m_vkd->vkCmdSetDepthWriteEnable(m_execBuffer, depthWriteEnable); - m_vkd->vkCmdSetDepthCompareOp(m_execBuffer, depthCompareOp); + m_vkd->vkCmdSetDepthWriteEnable(m_cmd.execBuffer, depthWriteEnable); + m_vkd->vkCmdSetDepthCompareOp(m_cmd.execBuffer, depthCompareOp); } else { - m_vkd->vkCmdSetDepthWriteEnable(m_execBuffer, VK_FALSE); - m_vkd->vkCmdSetDepthCompareOp(m_execBuffer, VK_COMPARE_OP_ALWAYS); + m_vkd->vkCmdSetDepthWriteEnable(m_cmd.execBuffer, VK_FALSE); + m_vkd->vkCmdSetDepthCompareOp(m_cmd.execBuffer, VK_COMPARE_OP_ALWAYS); } } @@ -764,17 +779,17 @@ namespace dxvk { void cmdSetEvent( VkEvent event, const VkDependencyInfo* dependencyInfo) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vkd->vkCmdSetEvent2(m_execBuffer, event, dependencyInfo); + m_vkd->vkCmdSetEvent2(m_cmd.execBuffer, event, dependencyInfo); } void cmdSetRasterizerState( VkCullModeFlags cullMode, VkFrontFace frontFace) { - m_vkd->vkCmdSetCullMode(m_execBuffer, cullMode); - m_vkd->vkCmdSetFrontFace(m_execBuffer, frontFace); + m_vkd->vkCmdSetCullMode(m_cmd.execBuffer, cullMode); + m_vkd->vkCmdSetFrontFace(m_cmd.execBuffer, frontFace); } @@ -782,7 +797,7 @@ namespace dxvk { uint32_t scissorCount, const VkRect2D* scissors) { m_vkd->vkCmdSetScissorWithCount( - m_execBuffer, scissorCount, scissors); + m_cmd.execBuffer, scissorCount, scissors); } @@ -791,32 +806,32 @@ namespace dxvk { const VkStencilOpState& front, const VkStencilOpState& back) { m_vkd->vkCmdSetStencilTestEnable( - m_execBuffer, enableStencilTest); + m_cmd.execBuffer, enableStencilTest); if (enableStencilTest) { - m_vkd->vkCmdSetStencilOp(m_execBuffer, + m_vkd->vkCmdSetStencilOp(m_cmd.execBuffer, VK_STENCIL_FACE_FRONT_BIT, front.failOp, front.passOp, front.depthFailOp, front.compareOp); - m_vkd->vkCmdSetStencilCompareMask(m_execBuffer, + m_vkd->vkCmdSetStencilCompareMask(m_cmd.execBuffer, VK_STENCIL_FACE_FRONT_BIT, front.compareMask); - m_vkd->vkCmdSetStencilWriteMask(m_execBuffer, + m_vkd->vkCmdSetStencilWriteMask(m_cmd.execBuffer, VK_STENCIL_FACE_FRONT_BIT, front.writeMask); - m_vkd->vkCmdSetStencilOp(m_execBuffer, + m_vkd->vkCmdSetStencilOp(m_cmd.execBuffer, VK_STENCIL_FACE_BACK_BIT, back.failOp, back.passOp, back.depthFailOp, back.compareOp); - m_vkd->vkCmdSetStencilCompareMask(m_execBuffer, + m_vkd->vkCmdSetStencilCompareMask(m_cmd.execBuffer, VK_STENCIL_FACE_BACK_BIT, back.compareMask); - m_vkd->vkCmdSetStencilWriteMask(m_execBuffer, + m_vkd->vkCmdSetStencilWriteMask(m_cmd.execBuffer, VK_STENCIL_FACE_BACK_BIT, back.writeMask); } else { - m_vkd->vkCmdSetStencilOp(m_execBuffer, + m_vkd->vkCmdSetStencilOp(m_cmd.execBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS); - m_vkd->vkCmdSetStencilCompareMask(m_execBuffer, + m_vkd->vkCmdSetStencilCompareMask(m_cmd.execBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, 0x0); - m_vkd->vkCmdSetStencilWriteMask(m_execBuffer, + m_vkd->vkCmdSetStencilWriteMask(m_cmd.execBuffer, VK_STENCIL_FACE_FRONT_AND_BACK, 0x0); } } @@ -825,7 +840,7 @@ namespace dxvk { void cmdSetStencilReference( VkStencilFaceFlags faceMask, uint32_t reference) { - m_vkd->vkCmdSetStencilReference(m_execBuffer, + m_vkd->vkCmdSetStencilReference(m_cmd.execBuffer, faceMask, reference); } @@ -834,7 +849,7 @@ namespace dxvk { uint32_t viewportCount, const VkViewport* viewports) { m_vkd->vkCmdSetViewportWithCount( - m_execBuffer, viewportCount, viewports); + m_cmd.execBuffer, viewportCount, viewports); } @@ -842,33 +857,33 @@ namespace dxvk { VkPipelineStageFlagBits2 pipelineStage, VkQueryPool queryPool, uint32_t query) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vkd->vkCmdWriteTimestamp2(m_execBuffer, + m_vkd->vkCmdWriteTimestamp2(m_cmd.execBuffer, pipelineStage, queryPool, query); } void cmdBeginDebugUtilsLabel( VkDebugUtilsLabelEXT* pLabelInfo) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vki->vkCmdBeginDebugUtilsLabelEXT(m_execBuffer, pLabelInfo); + m_vki->vkCmdBeginDebugUtilsLabelEXT(m_cmd.execBuffer, pLabelInfo); } void cmdEndDebugUtilsLabel() { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vki->vkCmdEndDebugUtilsLabelEXT(m_execBuffer); + m_vki->vkCmdEndDebugUtilsLabelEXT(m_cmd.execBuffer); } void cmdInsertDebugUtilsLabel( VkDebugUtilsLabelEXT* pLabelInfo) { - m_cmdBuffersUsed.set(DxvkCmdBuffer::ExecBuffer); + m_cmd.usedFlags.set(DxvkCmdBuffer::ExecBuffer); - m_vki->vkCmdInsertDebugUtilsLabelEXT(m_execBuffer, pLabelInfo); + m_vki->vkCmdInsertDebugUtilsLabelEXT(m_cmd.execBuffer, pLabelInfo); } @@ -889,28 +904,25 @@ namespace dxvk { private: - DxvkDevice* m_device; - Rc m_vkd; - Rc m_vki; + DxvkDevice* m_device; + Rc m_vkd; + Rc m_vki; - VkCommandPool m_graphicsPool = VK_NULL_HANDLE; - VkCommandPool m_transferPool = VK_NULL_HANDLE; - - VkCommandBuffer m_execBuffer = VK_NULL_HANDLE; - VkCommandBuffer m_initBuffer = VK_NULL_HANDLE; - VkCommandBuffer m_sdmaBuffer = VK_NULL_HANDLE; + VkCommandPool m_graphicsPool = VK_NULL_HANDLE; + VkCommandPool m_transferPool = VK_NULL_HANDLE; - VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE; + VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE; - vk::PresenterSync m_wsiSemaphores = { }; + DxvkCommandSubmissionInfo m_cmd; - DxvkCmdBufferFlags m_cmdBuffersUsed; - DxvkLifetimeTracker m_resources; - DxvkSignalTracker m_signalTracker; - DxvkGpuEventTracker m_gpuEventTracker; - DxvkGpuQueryTracker m_gpuQueryTracker; - DxvkBufferTracker m_bufferTracker; - DxvkStatCounters m_statCounters; + vk::PresenterSync m_wsiSemaphores = { }; + + DxvkLifetimeTracker m_resources; + DxvkSignalTracker m_signalTracker; + DxvkGpuEventTracker m_gpuEventTracker; + DxvkGpuQueryTracker m_gpuQueryTracker; + DxvkBufferTracker m_bufferTracker; + DxvkStatCounters m_statCounters; DxvkCommandSubmission m_commandSubmission; @@ -924,9 +936,9 @@ namespace dxvk { std::vector m_pipelines; VkCommandBuffer getCmdBuffer(DxvkCmdBuffer cmdBuffer) const { - if (cmdBuffer == DxvkCmdBuffer::ExecBuffer) return m_execBuffer; - if (cmdBuffer == DxvkCmdBuffer::InitBuffer) return m_initBuffer; - if (cmdBuffer == DxvkCmdBuffer::SdmaBuffer) return m_sdmaBuffer; + if (cmdBuffer == DxvkCmdBuffer::ExecBuffer) return m_cmd.execBuffer; + if (cmdBuffer == DxvkCmdBuffer::InitBuffer) return m_cmd.initBuffer; + if (cmdBuffer == DxvkCmdBuffer::SdmaBuffer) return m_cmd.sdmaBuffer; return VK_NULL_HANDLE; } From c3a721f562b590b8d301d9d7a2a4e989928f1eeb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 14:05:29 +0200 Subject: [PATCH 0649/1348] [dxvk] Introduce DxvkCommandPool --- src/dxvk/dxvk_cmdlist.cpp | 65 +++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_cmdlist.h | 46 ++++++++++++++++++++++++++- 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index cc5af6ca3..cd3a1be62 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -87,6 +87,71 @@ namespace dxvk { } + DxvkCommandPool::DxvkCommandPool( + DxvkDevice* device, + uint32_t queueFamily) + : m_device(device) { + auto vk = m_device->vkd(); + + VkCommandPoolCreateInfo poolInfo = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; + poolInfo.queueFamilyIndex = queueFamily; + + if (vk->vkCreateCommandPool(vk->device(), &poolInfo, nullptr, &m_commandPool)) + throw DxvkError("DxvkCommandPool: Failed to create command pool"); + } + + + DxvkCommandPool::~DxvkCommandPool() { + auto vk = m_device->vkd(); + + vk->vkDestroyCommandPool(vk->device(), m_commandPool, nullptr); + } + + + VkCommandBuffer DxvkCommandPool::getCommandBuffer() { + auto vk = m_device->vkd(); + + if (m_next == m_commandBuffers.size()) { + // Allocate a new command buffer and add it to the list + VkCommandBufferAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; + allocInfo.commandPool = m_commandPool; + allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocInfo.commandBufferCount = 1; + + VkCommandBuffer commandBuffer = VK_NULL_HANDLE; + + if (vk->vkAllocateCommandBuffers(vk->device(), &allocInfo, &commandBuffer)) + throw DxvkError("DxvkCommandPool: Failed to allocate command buffer"); + + m_commandBuffers.push_back(commandBuffer); + } + + // Take existing command buffer. All command buffers + // will be in reset state, so we can begin it safely. + VkCommandBuffer commandBuffer = m_commandBuffers[m_next++]; + + VkCommandBufferBeginInfo info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + + if (vk->vkBeginCommandBuffer(commandBuffer, &info)) + throw DxvkError("DxvkCommandPool: Failed to begin command buffer"); + + return commandBuffer; + } + + + void DxvkCommandPool::reset() { + auto vk = m_device->vkd(); + + if (m_next) { + if (vk->vkResetCommandPool(vk->device(), m_commandPool, 0)) + throw DxvkError("DxvkCommandPool: Failed to reset command pool"); + + m_next = 0; + } + } + + DxvkCommandList::DxvkCommandList(DxvkDevice* device) : m_device (device), m_vkd (device->vkd()), diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 25bd59127..9d1487474 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -118,7 +118,51 @@ namespace dxvk { /** - * \brief DXVK command list + * \brief Command pool + * + * Simple command pool abstraction that allows + * us to easily obtain command buffers. + */ + class DxvkCommandPool : public RcObject { + + public: + + /** + * \brief Creates command pool + * + * \param [in] device DXVK device + * \param [in] queueFamily Target queue family + */ + DxvkCommandPool( + DxvkDevice* device, + uint32_t queueFamily); + + ~DxvkCommandPool(); + + /** + * \brief Retrieves or allocates a command buffer + * \returns New command buffer in begun state + */ + VkCommandBuffer getCommandBuffer(); + + /** + * \brief Resets command pool and all command buffers + */ + void reset(); + + private: + + DxvkDevice* m_device; + + VkCommandPool m_commandPool = VK_NULL_HANDLE; + std::vector m_commandBuffers; + size_t m_next = 0; + + }; + + + /** + * \brief Command list * * Stores a command buffer that a context can use to record Vulkan * commands. The command list shall also reference the resources From e378be826ecd539220858040f7108ef1590df520 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 14:14:06 +0200 Subject: [PATCH 0650/1348] [dxvk] Use DxvkCommandPool --- src/dxvk/dxvk_cmdlist.cpp | 63 ++++++++------------------------------- src/dxvk/dxvk_cmdlist.h | 4 +-- 2 files changed, 15 insertions(+), 52 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index cd3a1be62..2395df340 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -164,49 +164,18 @@ namespace dxvk { if (m_vkd->vkCreateSemaphore(m_vkd->device(), &semaphoreInfo, nullptr, &m_sdmaSemaphore)) throw DxvkError("DxvkCommandList: Failed to create semaphore"); - VkCommandPoolCreateInfo poolInfo; - poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - poolInfo.pNext = nullptr; - poolInfo.flags = 0; - poolInfo.queueFamilyIndex = graphicsQueue.queueFamily; - - if (m_vkd->vkCreateCommandPool(m_vkd->device(), &poolInfo, nullptr, &m_graphicsPool) != VK_SUCCESS) - throw DxvkError("DxvkCommandList: Failed to create graphics command pool"); - - if (m_device->hasDedicatedTransferQueue()) { - poolInfo.queueFamilyIndex = transferQueue.queueFamily; + m_graphicsPool = new DxvkCommandPool(device, graphicsQueue.queueFamily); - if (m_vkd->vkCreateCommandPool(m_vkd->device(), &poolInfo, nullptr, &m_transferPool) != VK_SUCCESS) - throw DxvkError("DxvkCommandList: Failed to create transfer command pool"); - } - - VkCommandBufferAllocateInfo cmdInfoGfx; - cmdInfoGfx.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - cmdInfoGfx.pNext = nullptr; - cmdInfoGfx.commandPool = m_graphicsPool; - cmdInfoGfx.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - cmdInfoGfx.commandBufferCount = 1; - - VkCommandBufferAllocateInfo cmdInfoDma; - cmdInfoDma.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - cmdInfoDma.pNext = nullptr; - cmdInfoDma.commandPool = m_transferPool ? m_transferPool : m_graphicsPool; - cmdInfoDma.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - cmdInfoDma.commandBufferCount = 1; - - if (m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoGfx, &m_cmd.execBuffer) != VK_SUCCESS - || m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoGfx, &m_cmd.initBuffer) != VK_SUCCESS - || m_vkd->vkAllocateCommandBuffers(m_vkd->device(), &cmdInfoDma, &m_cmd.sdmaBuffer) != VK_SUCCESS) - throw DxvkError("DxvkCommandList: Failed to allocate command buffer"); + if (transferQueue.queueFamily != graphicsQueue.queueFamily) + m_transferPool = new DxvkCommandPool(device, transferQueue.queueFamily); + else + m_transferPool = m_graphicsPool; } DxvkCommandList::~DxvkCommandList() { this->reset(); - m_vkd->vkDestroyCommandPool(m_vkd->device(), m_graphicsPool, nullptr); - m_vkd->vkDestroyCommandPool(m_vkd->device(), m_transferPool, nullptr); - m_vkd->vkDestroySemaphore(m_vkd->device(), m_sdmaSemaphore, nullptr); } @@ -270,20 +239,10 @@ namespace dxvk { void DxvkCommandList::beginRecording() { - VkCommandBufferBeginInfo info; - info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - info.pNext = nullptr; - info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - info.pInheritanceInfo = nullptr; - - if ((m_graphicsPool && m_vkd->vkResetCommandPool(m_vkd->device(), m_graphicsPool, 0) != VK_SUCCESS) - || (m_transferPool && m_vkd->vkResetCommandPool(m_vkd->device(), m_transferPool, 0) != VK_SUCCESS)) - Logger::err("DxvkCommandList: Failed to reset command buffer"); - - if (m_vkd->vkBeginCommandBuffer(m_cmd.execBuffer, &info) != VK_SUCCESS - || m_vkd->vkBeginCommandBuffer(m_cmd.initBuffer, &info) != VK_SUCCESS - || m_vkd->vkBeginCommandBuffer(m_cmd.sdmaBuffer, &info) != VK_SUCCESS) - Logger::err("DxvkCommandList: Failed to begin command buffer"); + m_cmd = DxvkCommandSubmissionInfo(); + m_cmd.execBuffer = m_graphicsPool->getCommandBuffer(); + m_cmd.initBuffer = m_graphicsPool->getCommandBuffer(); + m_cmd.sdmaBuffer = m_transferPool->getCommandBuffer(); } @@ -327,6 +286,10 @@ namespace dxvk { m_signalSemaphores.clear(); m_wsiSemaphores = vk::PresenterSync(); + + // Reset actual command buffers and pools + m_graphicsPool->reset(); + m_transferPool->reset(); } } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 9d1487474..3bcf9c491 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -952,8 +952,8 @@ namespace dxvk { Rc m_vkd; Rc m_vki; - VkCommandPool m_graphicsPool = VK_NULL_HANDLE; - VkCommandPool m_transferPool = VK_NULL_HANDLE; + Rc m_graphicsPool; + Rc m_transferPool; VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE; From 6f2ff2562d83ba20582168da7fe16fedb427cf01 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 15:27:08 +0200 Subject: [PATCH 0651/1348] [dxvk] Support splitting command lists into multipe submissions --- src/dxvk/dxvk_cmdlist.cpp | 162 ++++++++++++++++++++++++++++---------- src/dxvk/dxvk_cmdlist.h | 36 +++++++-- src/dxvk/dxvk_context.cpp | 4 +- src/dxvk/dxvk_device.cpp | 1 - 4 files changed, 150 insertions(+), 53 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 2395df340..bf979715d 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -72,7 +72,7 @@ namespace dxvk { VkResult vr = VK_SUCCESS; - if (submitInfo.waitSemaphoreInfoCount || submitInfo.commandBufferInfoCount || submitInfo.signalSemaphoreInfoCount) + if (!this->isEmpty()) vr = vk->vkQueueSubmit2(queue, 1, &submitInfo, VK_NULL_HANDLE); this->reset(); @@ -87,6 +87,13 @@ namespace dxvk { } + bool DxvkCommandSubmission::isEmpty() const { + return m_semaphoreWaits.empty() + && m_semaphoreSignals.empty() + && m_commandBuffers.empty(); + } + + DxvkCommandPool::DxvkCommandPool( DxvkDevice* device, uint32_t queueFamily) @@ -190,10 +197,29 @@ namespace dxvk { m_commandSubmission.reset(); - if (m_cmd.usedFlags.test(DxvkCmdBuffer::SdmaBuffer)) { - m_commandSubmission.executeCommandBuffer(m_cmd.sdmaBuffer); + for (size_t i = 0; i < m_cmdSubmissions.size(); i++) { + bool isFirst = i == 0; + bool isLast = i == m_cmdSubmissions.size() - 1; - if (m_device->hasDedicatedTransferQueue()) { + const auto& cmd = m_cmdSubmissions[i]; + + if (isFirst) { + // Wait for per-command list semaphores on first submission + for (const auto& entry : m_waitSemaphores) { + m_commandSubmission.waitSemaphore( + entry.fence->handle(), + entry.value, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); + } + } + + // Submit transfer commands as necessary + if (cmd.usedFlags.test(DxvkCmdBuffer::SdmaBuffer)) + m_commandSubmission.executeCommandBuffer(cmd.sdmaBuffer); + + // If we had either a transfer command or a semaphore wait, + // submit to the transfer queue so that all subsequent commands + // get stalled appropriately. + if (m_device->hasDedicatedTransferQueue() && !m_commandSubmission.isEmpty()) { m_commandSubmission.signalSemaphore(m_sdmaSemaphore, 0, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); if ((status = m_commandSubmission.submit(m_device, transfer.queueHandle))) @@ -201,58 +227,101 @@ namespace dxvk { m_commandSubmission.waitSemaphore(m_sdmaSemaphore, 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); } + + // We promise to never do weird stuff to WSI images on + // the transfer queue, so blocking graphics is sufficient + if (isFirst && m_wsiSemaphores.acquire) { + m_commandSubmission.waitSemaphore(m_wsiSemaphores.acquire, + 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); + } + + // Submit graphics commands + if (cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer)) + m_commandSubmission.executeCommandBuffer(cmd.initBuffer); + + if (cmd.usedFlags.test(DxvkCmdBuffer::ExecBuffer)) + m_commandSubmission.executeCommandBuffer(cmd.execBuffer); + + // Signal global timeline semaphore at the end of every submission + m_commandSubmission.signalSemaphore(semaphore, + ++semaphoreValue, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); + + if (isLast) { + // Signal per-command list semaphores on the final submission + for (const auto& entry : m_signalSemaphores) { + m_commandSubmission.signalSemaphore( + entry.fence->handle(), + entry.value, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); + } + + // Signal WSI semaphore on the final submission + if (m_wsiSemaphores.present) { + m_commandSubmission.signalSemaphore(m_wsiSemaphores.present, + 0, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); + } + } + + // Finally, submit all graphics commands of the current submission + if ((status = m_commandSubmission.submit(m_device, graphics.queueHandle))) + return status; } - if (m_cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer)) - m_commandSubmission.executeCommandBuffer(m_cmd.initBuffer); - - if (m_cmd.usedFlags.test(DxvkCmdBuffer::ExecBuffer)) - m_commandSubmission.executeCommandBuffer(m_cmd.execBuffer); - - if (m_wsiSemaphores.acquire) { - m_commandSubmission.waitSemaphore(m_wsiSemaphores.acquire, - 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); - } - - if (m_wsiSemaphores.present) { - m_commandSubmission.signalSemaphore(m_wsiSemaphores.present, - 0, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); - } - - for (const auto& entry : m_waitSemaphores) { - m_commandSubmission.waitSemaphore( - entry.fence->handle(), - entry.value, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); - } - - for (const auto& entry : m_signalSemaphores) - m_commandSubmission.signalSemaphore(entry.fence->handle(), entry.value, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); - - m_commandSubmission.signalSemaphore(semaphore, - ++semaphoreValue, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); - - if ((status = m_commandSubmission.submit(m_device, graphics.queueHandle))) - return status; - return VK_SUCCESS; } - void DxvkCommandList::beginRecording() { + void DxvkCommandList::init() { m_cmd = DxvkCommandSubmissionInfo(); + + // Grab a fresh set of command buffers from the pools m_cmd.execBuffer = m_graphicsPool->getCommandBuffer(); m_cmd.initBuffer = m_graphicsPool->getCommandBuffer(); m_cmd.sdmaBuffer = m_transferPool->getCommandBuffer(); } - void DxvkCommandList::endRecording() { - if (m_vkd->vkEndCommandBuffer(m_cmd.execBuffer) != VK_SUCCESS - || m_vkd->vkEndCommandBuffer(m_cmd.initBuffer) != VK_SUCCESS - || m_vkd->vkEndCommandBuffer(m_cmd.sdmaBuffer) != VK_SUCCESS) - Logger::err("DxvkCommandList::endRecording: Failed to record command buffer"); + void DxvkCommandList::finalize() { + if (m_cmdSubmissions.empty() || m_cmd.usedFlags != 0) + m_cmdSubmissions.push_back(m_cmd); + + // For consistency, end all command buffers here, + // regardless of whether they have been used. + this->endCommandBuffer(m_cmd.execBuffer); + this->endCommandBuffer(m_cmd.initBuffer); + this->endCommandBuffer(m_cmd.sdmaBuffer); + + // Reset all command buffer handles + m_cmd = DxvkCommandSubmissionInfo(); + + // Increment queue submission count + uint64_t submissionCount = m_cmdSubmissions.size(); + m_statCounters.addCtr(DxvkStatCounter::QueueSubmitCount, submissionCount); } - + + + void DxvkCommandList::next() { + if (m_cmd.usedFlags != 0) + m_cmdSubmissions.push_back(m_cmd); + + // Only replace used command buffer to save resources + if (m_cmd.usedFlags.test(DxvkCmdBuffer::ExecBuffer)) { + this->endCommandBuffer(m_cmd.execBuffer); + m_cmd.execBuffer = m_graphicsPool->getCommandBuffer(); + } + + if (m_cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer)) { + this->endCommandBuffer(m_cmd.initBuffer); + m_cmd.initBuffer = m_graphicsPool->getCommandBuffer(); + } + + if (m_cmd.usedFlags.test(DxvkCmdBuffer::SdmaBuffer)) { + this->endCommandBuffer(m_cmd.sdmaBuffer); + m_cmd.sdmaBuffer = m_transferPool->getCommandBuffer(); + } + + m_cmd.usedFlags = 0; + } + void DxvkCommandList::reset() { // Free resources and other objects @@ -284,6 +353,7 @@ namespace dxvk { m_waitSemaphores.clear(); m_signalSemaphores.clear(); + m_cmdSubmissions.clear(); m_wsiSemaphores = vk::PresenterSync(); @@ -292,4 +362,12 @@ namespace dxvk { m_transferPool->reset(); } + + void DxvkCommandList::endCommandBuffer(VkCommandBuffer cmdBuffer) { + auto vk = m_device->vkd(); + + if (vk->vkEndCommandBuffer(cmdBuffer)) + throw DxvkError("DxvkCommandList: Failed to end command buffer"); + } + } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 3bcf9c491..7d41777f2 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -94,6 +94,14 @@ namespace dxvk { */ void reset(); + /** + * \brief Checks whether the submission is empty + * + * \returns \c true if there are no command + * buffers or semaphores. + */ + bool isEmpty() const; + private: std::vector m_semaphoreWaits; @@ -215,21 +223,29 @@ namespace dxvk { } /** - * \brief Begins recording - * - * Resets the command buffer and - * begins command buffer recording. + * \brief Initializes command buffers + * + * Prepares command list for command recording. */ - void beginRecording(); + void init(); /** * \brief Ends recording - * + * * Ends command buffer recording, making * the command list ready for submission. * \param [in] stats Stat counters */ - void endRecording(); + void finalize(); + + /** + * \brief Interrupts recording + * + * Begins a new set of command buffers while adding the + * current set to the submission list. This can be useful + * to split the command list into multiple submissions. + */ + void next(); /** * \brief Frees buffer slice @@ -972,6 +988,8 @@ namespace dxvk { std::vector m_waitSemaphores; std::vector m_signalSemaphores; + + std::vector m_cmdSubmissions; std::vector, @@ -985,7 +1003,9 @@ namespace dxvk { if (cmdBuffer == DxvkCmdBuffer::SdmaBuffer) return m_cmd.sdmaBuffer; return VK_NULL_HANDLE; } - + + void endCommandBuffer(VkCommandBuffer cmdBuffer); + }; } diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index c304bfc8e..0cd344f07 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -64,7 +64,7 @@ namespace dxvk { void DxvkContext::beginRecording(const Rc& cmdList) { m_cmd = cmdList; - m_cmd->beginRecording(); + m_cmd->init(); // Mark all resources as untracked m_vbTracked.clear(); @@ -120,7 +120,7 @@ namespace dxvk { m_descriptorPool = m_descriptorManager->getDescriptorPool(); } - m_cmd->endRecording(); + m_cmd->finalize(); return std::exchange(m_cmd, nullptr); } diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 49ef7158e..6bdaaac37 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -274,7 +274,6 @@ namespace dxvk { std::lock_guard statLock(m_statLock); m_statCounters.merge(commandList->statCounters()); - m_statCounters.addCtr(DxvkStatCounter::QueueSubmitCount, 1); } From 07a1045ffb3f9939a49f5cc13cd6f93496f6426b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 15:44:00 +0200 Subject: [PATCH 0652/1348] [dxvk] Add context methods for submission splitting --- src/dxvk/dxvk_context.cpp | 106 +++++++++++++++++++++++--------------- src/dxvk/dxvk_context.h | 6 +++ 2 files changed, 70 insertions(+), 42 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 0cd344f07..721467eca 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -66,54 +66,15 @@ namespace dxvk { m_cmd = cmdList; m_cmd->init(); - // Mark all resources as untracked - m_vbTracked.clear(); - m_rcTracked.clear(); - - // The current state of the internal command buffer is - // undefined, so we have to bind and set up everything - // before any draw or dispatch command is recorded. - m_flags.clr( - DxvkContextFlag::GpRenderPassBound, - DxvkContextFlag::GpXfbActive, - DxvkContextFlag::GpIndependentSets); - - m_flags.set( - DxvkContextFlag::GpDirtyFramebuffer, - DxvkContextFlag::GpDirtyPipeline, - DxvkContextFlag::GpDirtyPipelineState, - DxvkContextFlag::GpDirtyVertexBuffers, - DxvkContextFlag::GpDirtyIndexBuffer, - DxvkContextFlag::GpDirtyXfbBuffers, - DxvkContextFlag::GpDirtyBlendConstants, - DxvkContextFlag::GpDirtyStencilRef, - DxvkContextFlag::GpDirtyRasterizerState, - DxvkContextFlag::GpDirtyViewport, - DxvkContextFlag::GpDirtyDepthBias, - DxvkContextFlag::GpDirtyDepthBounds, - DxvkContextFlag::GpDirtyDepthStencilState, - DxvkContextFlag::CpDirtyPipelineState, - DxvkContextFlag::DirtyDrawBuffer); - - m_descriptorState.dirtyStages( - VK_SHADER_STAGE_ALL_GRAPHICS | - VK_SHADER_STAGE_COMPUTE_BIT); - - m_state.gp.pipeline = nullptr; - m_state.cp.pipeline = nullptr; - if (m_descriptorPool == nullptr) m_descriptorPool = m_descriptorManager->getDescriptorPool(); + + this->beginCurrentCommands(); } Rc DxvkContext::endRecording() { - this->spillRenderPass(true); - this->flushSharedImages(); - - m_sdmaBarriers.recordCommands(m_cmd); - m_initBarriers.recordCommands(m_cmd); - m_execBarriers.recordCommands(m_cmd); + this->endCurrentCommands(); if (m_descriptorPool->shouldSubmit(false)) { m_cmd->trackDescriptorPool(m_descriptorPool, m_descriptorManager); @@ -5831,4 +5792,65 @@ namespace dxvk { } } + + void DxvkContext::beginCurrentCommands() { + // Mark all resources as untracked + m_vbTracked.clear(); + m_rcTracked.clear(); + + // The current state of the internal command buffer is + // undefined, so we have to bind and set up everything + // before any draw or dispatch command is recorded. + m_flags.clr( + DxvkContextFlag::GpRenderPassBound, + DxvkContextFlag::GpXfbActive, + DxvkContextFlag::GpIndependentSets); + + m_flags.set( + DxvkContextFlag::GpDirtyFramebuffer, + DxvkContextFlag::GpDirtyPipeline, + DxvkContextFlag::GpDirtyPipelineState, + DxvkContextFlag::GpDirtyVertexBuffers, + DxvkContextFlag::GpDirtyIndexBuffer, + DxvkContextFlag::GpDirtyXfbBuffers, + DxvkContextFlag::GpDirtyBlendConstants, + DxvkContextFlag::GpDirtyStencilRef, + DxvkContextFlag::GpDirtyRasterizerState, + DxvkContextFlag::GpDirtyViewport, + DxvkContextFlag::GpDirtyDepthBias, + DxvkContextFlag::GpDirtyDepthBounds, + DxvkContextFlag::GpDirtyDepthStencilState, + DxvkContextFlag::CpDirtyPipelineState, + DxvkContextFlag::DirtyDrawBuffer); + + m_descriptorState.dirtyStages( + VK_SHADER_STAGE_ALL_GRAPHICS | + VK_SHADER_STAGE_COMPUTE_BIT); + + m_state.gp.pipeline = nullptr; + m_state.cp.pipeline = nullptr; + } + + + void DxvkContext::endCurrentCommands() { + this->spillRenderPass(true); + this->flushSharedImages(); + + m_sdmaBarriers.recordCommands(m_cmd); + m_initBarriers.recordCommands(m_cmd); + m_execBarriers.recordCommands(m_cmd); + } + + + void DxvkContext::splitCommands() { + // This behaves the same as a pair of endRecording and + // beginRecording calls, except that we keep the same + // command list object for subsequent commands. + this->endCurrentCommands(); + + m_cmd->next(); + + this->beginCurrentCommands(); + } + } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index fe24c556e..376cfdb4c 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1588,6 +1588,12 @@ namespace dxvk { void resizeDescriptorArrays( uint32_t bindingCount); + void beginCurrentCommands(); + + void endCurrentCommands(); + + void splitCommands(); + }; } From 17959640c3bfe96a96a600ab14b96658f6acf4d6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 20:30:16 +0200 Subject: [PATCH 0653/1348] [dxvk] Work around vkWaitSemaphore incorrectly returning with VK_TIMEOUT --- src/dxvk/dxvk_queue.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_queue.cpp b/src/dxvk/dxvk_queue.cpp index 02671a096..46a594ce0 100644 --- a/src/dxvk/dxvk_queue.cpp +++ b/src/dxvk/dxvk_queue.cpp @@ -104,7 +104,13 @@ namespace dxvk { waitInfo.pSemaphores = &m_semaphore; waitInfo.pValues = &semaphoreValue; - VkResult vr = vk->vkWaitSemaphores(vk->device(), &waitInfo, ~0ull); + // 32-bit winevulkan on Proton seems to be broken here + // and returns with VK_TIMEOUT, even though the timeout + // is infinite. Work around this by spinning. + VkResult vr = VK_TIMEOUT; + + while (vr == VK_TIMEOUT) + vr = vk->vkWaitSemaphores(vk->device(), &waitInfo, ~0ull); if (vr) Logger::err(str::format("Failed to synchronize with global timeline semaphore: ", vr)); From 372a27fad256ed7f9d4740031873389f8651a53e Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Mon, 22 Aug 2022 12:58:23 +0200 Subject: [PATCH 0654/1348] [util] remove allowDoNotWait from example config --- dxvk.conf | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index 9eaa9f7e7..6d0aba1e8 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -505,16 +505,6 @@ # d3d9.forceAspectRatio = "" -# Allow Do Not Wait -# -# Allow the do not wait lock flag to be used -# Useful if some apps use this incorrectly. -# -# Supported values: -# - True/False - -# d3d9.allowDoNotWait = True - # Allow Discard # # Allow the discard lock flag to be used From 87b1f9fa2d3de5910a6c11d4cc7ae351ce0d43fd Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Mon, 22 Aug 2022 23:25:47 +0200 Subject: [PATCH 0655/1348] [dxso] Fix write mask for nrm --- src/dxso/dxso_compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 67066ec4f..d80ad019e 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -2055,7 +2055,7 @@ namespace dxvk { } // r * rsq(r . r) - result.id = emitMul(vec3, emitRegisterExtend(rcpLength, 3)).id; + result.id = emitMul(emitRegisterLoad(src[0], mask), emitRegisterExtend(rcpLength, mask.popCount())).id; break; } case DxsoOpcode::SinCos: { From 86bdda70b431cdec5fdc7c0d4ec40a21ebee41ca Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 24 Aug 2022 12:14:43 +0200 Subject: [PATCH 0656/1348] [d3d11] Move D3D10Multithread instance to immediate context Deferred contexts do not support this. --- src/d3d11/d3d11_context.cpp | 6 ------ src/d3d11/d3d11_context.h | 9 ++++----- src/d3d11/d3d11_context_def.h | 4 ++++ src/d3d11/d3d11_context_imm.cpp | 6 ++++++ src/d3d11/d3d11_context_imm.h | 7 ++++++- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 80671283b..36d79a899 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -15,7 +15,6 @@ namespace dxvk { : D3D11DeviceChild(pParent), m_contextExt(GetTypedContext()), m_annotation(GetTypedContext(), Device), - m_multithread(this, false), m_device (Device), m_flags (ContextFlags), m_staging (Device, StagingBufferSize), @@ -62,11 +61,6 @@ namespace dxvk { return S_OK; } - if (riid == __uuidof(ID3D10Multithread)) { - *ppvObject = ref(&m_multithread); - return S_OK; - } - Logger::warn("D3D11DeviceContext::QueryInterface: Unknown interface query"); Logger::warn(str::format(riid)); return E_NOINTERFACE; diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index a9acbbdce..571871e0c 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -756,15 +756,10 @@ namespace dxvk { VkImageLayout OldLayout, VkImageLayout NewLayout); - D3D10DeviceLock LockContext() { - return m_multithread.AcquireLock(); - } - protected: D3D11DeviceContextExt m_contextExt; D3D11UserDefinedAnnotation m_annotation; - D3D10Multithread m_multithread; Rc m_device; @@ -1124,6 +1119,10 @@ namespace dxvk { return static_cast(this); } + D3D10DeviceLock LockContext() { + return GetTypedContext()->LockContext(); + } + }; } diff --git a/src/d3d11/d3d11_context_def.h b/src/d3d11/d3d11_context_def.h index 4a5a41246..869ae09ea 100644 --- a/src/d3d11/d3d11_context_def.h +++ b/src/d3d11/d3d11_context_def.h @@ -79,6 +79,10 @@ namespace dxvk { ID3DDeviceContextState* pState, ID3DDeviceContextState** ppPreviousState); + D3D10DeviceLock LockContext() { + return D3D10DeviceLock(); + } + private: // Command list that we're recording diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index b9978d91a..e754ca608 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -18,6 +18,7 @@ namespace dxvk { : D3D11CommonContext(pParent, Device, 0, DxvkCsChunkFlag::SingleUse), m_csThread(Device, Device->createContext(DxvkContextType::Primary)), m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize), + m_multithread(this, false), m_videoContext(this, Device) { EmitCs([ cDevice = m_device, @@ -54,6 +55,11 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::QueryInterface(REFIID riid, void** ppvObject) { + if (riid == __uuidof(ID3D10Multithread)) { + *ppvObject = ref(&m_multithread); + return S_OK; + } + if (riid == __uuidof(ID3D11VideoContext)) { *ppvObject = ref(&m_videoContext); return S_OK; diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index dce444843..e64c2d620 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -79,7 +79,11 @@ namespace dxvk { void SynchronizeCsThread( uint64_t SequenceNumber); - + + D3D10DeviceLock LockContext() { + return m_multithread.AcquireLock(); + } + private: DxvkCsThread m_csThread; @@ -95,6 +99,7 @@ namespace dxvk { dxvk::high_resolution_clock::time_point m_lastFlush = dxvk::high_resolution_clock::now(); + D3D10Multithread m_multithread; D3D11VideoContext m_videoContext; Com m_stateObject; From 559fa50f547cd2b712097a8aebbc10c990cf537d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 24 Aug 2022 12:27:02 +0200 Subject: [PATCH 0657/1348] [d3d11] Introduce d3d11.enableContextLock option --- dxvk.conf | 8 ++++++++ src/d3d10/d3d10_multithread.cpp | 17 +++++++++++++---- src/d3d10/d3d10_multithread.h | 5 ++++- src/d3d11/d3d11_context_imm.cpp | 2 +- src/d3d11/d3d11_options.cpp | 1 + src/d3d11/d3d11_options.h | 5 +++++ 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index 6d0aba1e8..d029dce2a 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -236,6 +236,14 @@ # d3d11.cachedDynamicResources = "" +# Force-enables the D3D11 context lock via the ID3D10Multithread +# interface. This may be useful to debug race conditions. +# +# Supported values: True, False + +# d3d11.enableContextLock = False + + # Sets number of pipeline compiler threads. # # If the graphics pipeline library feature is enabled, the given diff --git a/src/d3d10/d3d10_multithread.cpp b/src/d3d10/d3d10_multithread.cpp index 65932b53d..20a97eef0 100644 --- a/src/d3d10/d3d10_multithread.cpp +++ b/src/d3d10/d3d10_multithread.cpp @@ -6,9 +6,12 @@ namespace dxvk { D3D10Multithread::D3D10Multithread( IUnknown* pParent, - BOOL Protected) + BOOL Protected, + BOOL Force) : m_parent (pParent), - m_protected (Protected) { + m_protected (Protected || Force), + m_enabled (Protected), + m_forced (Force) { } @@ -49,12 +52,18 @@ namespace dxvk { BOOL STDMETHODCALLTYPE D3D10Multithread::SetMultithreadProtected( BOOL bMTProtect) { - return std::exchange(m_protected, bMTProtect); + BOOL result = m_enabled; + m_enabled = bMTProtect; + + if (!m_forced) + m_protected = m_enabled; + + return result; } BOOL STDMETHODCALLTYPE D3D10Multithread::GetMultithreadProtected() { - return m_protected; + return m_enabled; } } diff --git a/src/d3d10/d3d10_multithread.h b/src/d3d10/d3d10_multithread.h index 39a736cc0..75d4060f2 100644 --- a/src/d3d10/d3d10_multithread.h +++ b/src/d3d10/d3d10_multithread.h @@ -64,7 +64,8 @@ namespace dxvk { D3D10Multithread( IUnknown* pParent, - BOOL Protected); + BOOL Protected, + BOOL Force); ~D3D10Multithread(); @@ -95,6 +96,8 @@ namespace dxvk { IUnknown* m_parent; BOOL m_protected; + BOOL m_enabled; + BOOL m_forced; sync::RecursiveSpinlock m_mutex; diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index e754ca608..3aa4d3613 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -18,7 +18,7 @@ namespace dxvk { : D3D11CommonContext(pParent, Device, 0, DxvkCsChunkFlag::SingleUse), m_csThread(Device, Device->createContext(DxvkContextType::Primary)), m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize), - m_multithread(this, false), + m_multithread(this, false, pParent->GetOptions()->enableContextLock), m_videoContext(this, Device) { EmitCs([ cDevice = m_device, diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index 4874e114e..83c321de0 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -25,6 +25,7 @@ namespace dxvk { this->invariantPosition = config.getOption("d3d11.invariantPosition", true); this->floatControls = config.getOption("d3d11.floatControls", true); this->disableMsaa = config.getOption("d3d11.disableMsaa", false); + this->enableContextLock = config.getOption("d3d11.enableContextLock", false); this->deferSurfaceCreation = config.getOption("dxgi.deferSurfaceCreation", false); this->numBackBuffers = config.getOption("dxgi.numBackBuffers", 0); this->maxFrameLatency = config.getOption("dxgi.maxFrameLatency", 0); diff --git a/src/d3d11/d3d11_options.h b/src/d3d11/d3d11_options.h index dcbef7c3c..67bceaa54 100644 --- a/src/d3d11/d3d11_options.h +++ b/src/d3d11/d3d11_options.h @@ -111,6 +111,11 @@ namespace dxvk { /// in cached system memory. Enabled automatically when recording /// an api trace. uint32_t cachedDynamicResources; + + /// Always lock immediate context on every API call. May be + /// useful for debugging purposes or when applications have + /// race conditions. + bool enableContextLock; }; } \ No newline at end of file From 5117210c93d7736f36719cf62d1780c4ae62ebfa Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 25 Aug 2022 02:25:09 +0200 Subject: [PATCH 0658/1348] [dxvk] Fix fb resolve barriers No idea how that ended up broken *this* badly. --- src/dxvk/dxvk_context.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 721467eca..e3cb0a42d 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -3964,15 +3964,20 @@ namespace dxvk { m_cmd->cmdDraw(3, region.dstSubresource.layerCount, 0, 0); m_cmd->cmdEndRendering(); - if (srcImage->info().layout != srcLayout) { - m_execBarriers.accessImage( - srcImage, srcSubresourceRange, srcLayout, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, - srcImage->info().layout, - srcImage->info().stages, - srcImage->info().access); - } - + m_execBarriers.accessImage( + srcImage, srcSubresourceRange, srcLayout, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, + srcImage->info().layout, + srcImage->info().stages, + srcImage->info().access); + + m_execBarriers.accessImage( + dstImage, dstSubresourceRange, + dstLayout, dstStages, dstAccess, + dstImage->info().layout, + dstImage->info().stages, + dstImage->info().access); + m_cmd->trackResource(dstImage); m_cmd->trackResource(srcImage); m_cmd->trackResource(views); From a2a21cb4d373903fc0d34b628e9d3a964bb2b192 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 25 Aug 2022 18:20:11 +0200 Subject: [PATCH 0659/1348] [dxvk] Clean up internal memory allocation API --- src/dxvk/dxvk_buffer.cpp | 37 +++++++----- src/dxvk/dxvk_image.cpp | 93 ++++++++++++++--------------- src/dxvk/dxvk_memory.cpp | 122 +++++++++++++++++++++------------------ src/dxvk/dxvk_memory.h | 49 ++++++++++------ 4 files changed, 165 insertions(+), 136 deletions(-) diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 78a5946cd..314a1b68d 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -65,25 +65,32 @@ namespace dxvk { DxvkBufferHandle handle; - if (vkd->vkCreateBuffer(vkd->device(), - &info, nullptr, &handle.buffer) != VK_SUCCESS) { + if (vkd->vkCreateBuffer(vkd->device(), &info, nullptr, &handle.buffer)) { throw DxvkError(str::format( "DxvkBuffer: Failed to create buffer:" "\n size: ", info.size, "\n usage: ", info.usage)); } - - VkMemoryDedicatedRequirements dedicatedRequirements = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS }; - VkMemoryRequirements2 memReq = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &dedicatedRequirements }; - - VkBufferMemoryRequirementsInfo2 memReqInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 }; - memReqInfo.buffer = handle.buffer; - - VkMemoryDedicatedAllocateInfo dedMemoryAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO }; - dedMemoryAllocInfo.buffer = handle.buffer; - vkd->vkGetBufferMemoryRequirements2( - vkd->device(), &memReqInfo, &memReq); + // Query memory requirements and whether to use a dedicated allocation + DxvkMemoryRequirements memoryRequirements = { }; + memoryRequirements.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS }; + memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &memoryRequirements.dedicated }; + + VkBufferMemoryRequirementsInfo2 memoryRequirementInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 }; + memoryRequirementInfo.buffer = handle.buffer; + + vkd->vkGetBufferMemoryRequirements2(vkd->device(), + &memoryRequirementInfo, &memoryRequirements.core); + + // Fill in desired memory properties + DxvkMemoryProperties memoryProperties = { }; + memoryProperties.flags = m_memFlags; + + if (memoryRequirements.dedicated.prefersDedicatedAllocation) { + memoryProperties.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO }; + memoryProperties.dedicated.buffer = handle.buffer; + } // Use high memory priority for GPU-writable resources bool isGpuWritable = (m_info.access & ( @@ -102,9 +109,7 @@ namespace dxvk { && (m_info.usage & VK_BUFFER_USAGE_TRANSFER_SRC_BIT)) hints.set(DxvkMemoryFlag::Transient); - // Ask driver whether we should be using a dedicated allocation - handle.memory = m_memAlloc->alloc(&memReq.memoryRequirements, - dedicatedRequirements, dedMemoryAllocInfo, m_memFlags, hints); + handle.memory = m_memAlloc->alloc(memoryRequirements, memoryProperties, hints); if (vkd->vkBindBufferMemory(vkd->device(), handle.buffer, handle.memory.memory(), handle.memory.offset()) != VK_SUCCESS) diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index d48fc05ed..013420386 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -22,7 +22,10 @@ namespace dxvk { VkImageFormatListCreateInfo formatList = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO }; formatList.viewFormatCount = createInfo.viewFormatCount; formatList.pViewFormats = createInfo.viewFormats; - + + VkExternalMemoryImageCreateInfo externalInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO }; + externalInfo.handleTypes = createInfo.sharing.type; + VkImageCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, &formatList }; info.flags = createInfo.flags; info.imageType = createInfo.type; @@ -36,17 +39,10 @@ namespace dxvk { info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; info.initialLayout = createInfo.initialLayout; - m_shared = canShareImage(info, createInfo.sharing); - - VkExternalMemoryImageCreateInfo externalInfo = { VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO }; - - if (m_shared) { + if ((m_shared = canShareImage(info, createInfo.sharing))) externalInfo.pNext = std::exchange(info.pNext, &externalInfo); - externalInfo.handleTypes = createInfo.sharing.type; - } - - if (m_vkd->vkCreateImage(m_vkd->device(), - &info, nullptr, &m_image.image) != VK_SUCCESS) { + + if (m_vkd->vkCreateImage(m_vkd->device(), &info, nullptr, &m_image.image)) { throw DxvkError(str::format( "DxvkImage: Failed to create image:", "\n Type: ", info.imageType, @@ -61,40 +57,52 @@ namespace dxvk { "\n Tiling: ", info.tiling)); } - // Get memory requirements for the image. We may enforce strict - // alignment on non-linear images in order not to violate the - // bufferImageGranularity limit, which may be greater than the - // required resource memory alignment on some GPUs. - VkMemoryDedicatedRequirements dedicatedRequirements = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS }; - VkMemoryRequirements2 memReq = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &dedicatedRequirements }; - - VkImageMemoryRequirementsInfo2 memReqInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 }; - memReqInfo.image = m_image.image; + // Get memory requirements for the image and ask driver + // whether we need to use a dedicated allocation. + DxvkMemoryRequirements memoryRequirements = { }; + memoryRequirements.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS }; + memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &memoryRequirements.dedicated }; - VkMemoryDedicatedAllocateInfo dedMemoryAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO }; - dedMemoryAllocInfo.image = m_image.image; + VkImageMemoryRequirementsInfo2 memoryRequirementInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 }; + memoryRequirementInfo.image = m_image.image; - VkExportMemoryAllocateInfo exportInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO }; - if (m_shared && createInfo.sharing.mode == DxvkSharedHandleMode::Export) { - exportInfo.pNext = std::exchange(dedMemoryAllocInfo.pNext, &exportInfo); - exportInfo.handleTypes = createInfo.sharing.type; + m_vkd->vkGetImageMemoryRequirements2(m_vkd->device(), + &memoryRequirementInfo, &memoryRequirements.core); + + // Fill in desired memory properties + DxvkMemoryProperties memoryProperties = { }; + memoryProperties.flags = m_memFlags; + + if (m_shared) { + memoryRequirements.dedicated.prefersDedicatedAllocation = VK_TRUE; + memoryRequirements.dedicated.requiresDedicatedAllocation = VK_TRUE; + + if (createInfo.sharing.mode == DxvkSharedHandleMode::Export) { + memoryProperties.sharedExport = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO }; + memoryProperties.sharedExport.handleTypes = createInfo.sharing.type; + } + + if (createInfo.sharing.mode == DxvkSharedHandleMode::Import) { + memoryProperties.sharedImportWin32 = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR }; + memoryProperties.sharedImportWin32.handleType = createInfo.sharing.type; + memoryProperties.sharedImportWin32.handle = createInfo.sharing.handle; + } } -#ifdef _WIN32 - VkImportMemoryWin32HandleInfoKHR importInfo = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR }; - if (m_shared && createInfo.sharing.mode == DxvkSharedHandleMode::Import) { - importInfo.pNext = std::exchange(dedMemoryAllocInfo.pNext, &importInfo); - importInfo.handleType = createInfo.sharing.type; - importInfo.handle = createInfo.sharing.handle; + if (memoryRequirements.dedicated.prefersDedicatedAllocation) { + memoryProperties.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO }; + memoryProperties.dedicated.image = m_image.image; } -#endif - m_vkd->vkGetImageMemoryRequirements2( - m_vkd->device(), &memReqInfo, &memReq); + // If there's a chance we won't create the image with a dedicated + // allocation, enforce strict alignment for tiled images to not + // violate the bufferImageGranularity requirement on some GPUs. + if (info.tiling != VK_IMAGE_TILING_LINEAR && !memoryRequirements.dedicated.requiresDedicatedAllocation) { + VkDeviceSize granularity = memAlloc.bufferImageGranularity(); - if (info.tiling != VK_IMAGE_TILING_LINEAR && !dedicatedRequirements.prefersDedicatedAllocation) { - memReq.memoryRequirements.size = align(memReq.memoryRequirements.size, memAlloc.bufferImageGranularity()); - memReq.memoryRequirements.alignment = align(memReq.memoryRequirements.alignment , memAlloc.bufferImageGranularity()); + auto& core = memoryRequirements.core.memoryRequirements; + core.size = align(core.size, granularity); + core.alignment = align(core.alignment, granularity); } // Use high memory priority for GPU-writable resources @@ -110,14 +118,7 @@ namespace dxvk { if (isGpuWritable) hints.set(DxvkMemoryFlag::GpuWritable); - if (m_shared) { - dedicatedRequirements.prefersDedicatedAllocation = VK_TRUE; - dedicatedRequirements.requiresDedicatedAllocation = VK_TRUE; - } - - // Ask driver whether we should be using a dedicated allocation - m_image.memory = memAlloc.alloc(&memReq.memoryRequirements, - dedicatedRequirements, dedMemoryAllocInfo, memFlags, hints); + m_image.memory = memAlloc.alloc(memoryRequirements, memoryProperties, hints); // Try to bind the allocated memory slice to the image if (m_vkd->vkBindImageMemory(m_vkd->device(), m_image.image, diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index e59e7ddce..f0dfa6696 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -211,63 +211,66 @@ namespace dxvk { DxvkMemory DxvkMemoryAllocator::alloc( - const VkMemoryRequirements* req, - const VkMemoryDedicatedRequirements& dedAllocReq, - const VkMemoryDedicatedAllocateInfo& dedAllocInfo, - VkMemoryPropertyFlags flags, + const DxvkMemoryRequirements& req, + DxvkMemoryProperties info, DxvkMemoryFlags hints) { std::lock_guard lock(m_mutex); // Keep small allocations together to avoid fragmenting // chunks for larger resources with lots of small gaps, // as well as resources with potentially weird lifetimes - if (req->size <= SmallAllocationThreshold) { + if (req.core.memoryRequirements.size <= SmallAllocationThreshold) { hints.set(DxvkMemoryFlag::Small); hints.clr(DxvkMemoryFlag::GpuWritable, DxvkMemoryFlag::GpuReadable); } // Ignore most hints for host-visible allocations since they // usually don't make much sense for those resources - if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + if (info.flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) hints = hints & DxvkMemoryFlag::Transient; // Try to allocate from a memory type which supports the given flags exactly - auto dedAllocPtr = dedAllocReq.prefersDedicatedAllocation ? &dedAllocInfo : nullptr; - DxvkMemory result = this->tryAlloc(req, dedAllocPtr, flags, hints); + DxvkMemory result = this->tryAlloc(req, info, hints); - // If the first attempt failed, try ignoring the dedicated allocation - if (!result && dedAllocPtr && !dedAllocReq.requiresDedicatedAllocation) { - result = this->tryAlloc(req, nullptr, flags, hints); - dedAllocPtr = nullptr; + if (!result && !req.dedicated.requiresDedicatedAllocation) { + // If that failed, try without a dedicated allocation + if (info.dedicated.image || info.dedicated.buffer) { + info.dedicated.image = VK_NULL_HANDLE; + info.dedicated.buffer = VK_NULL_HANDLE; + + result = this->tryAlloc(req, info, hints); + } } - // Retry without the hint constraints if (!result) { + // Retry without the hint constraints hints.set(DxvkMemoryFlag::IgnoreConstraints); - result = this->tryAlloc(req, nullptr, flags, hints); + result = this->tryAlloc(req, info, hints); } - // If that still didn't work, probe slower memory types as well - VkMemoryPropertyFlags optFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT - | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; - VkMemoryPropertyFlags remFlags = 0; - - while (!result && (flags & optFlags)) { - remFlags |= optFlags & -optFlags; - optFlags &= ~remFlags; + if (!result) { + // If that still didn't work, probe slower memory types as well + VkMemoryPropertyFlags optFlags = info.flags & ( + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_CACHED_BIT); - result = this->tryAlloc(req, dedAllocPtr, flags & ~remFlags, hints); + while (!result && optFlags) { + VkMemoryPropertyFlags bit = optFlags & -optFlags; + optFlags &= ~bit; + + info.flags &= ~bit; + result = this->tryAlloc(req, info, hints); + } } - + if (!result) { DxvkAdapterMemoryInfo memHeapInfo = m_device->adapter()->getMemoryHeapInfo(); Logger::err(str::format( "DxvkMemoryAllocator: Memory allocation failed", - "\n Size: ", req->size, - "\n Alignment: ", req->alignment, - "\n Mem flags: ", "0x", std::hex, flags, - "\n Mem types: ", "0x", std::hex, req->memoryTypeBits)); + "\n Size: ", req.core.memoryRequirements.size, + "\n Alignment: ", req.core.memoryRequirements.alignment, + "\n Mem types: ", "0x", std::hex, req.core.memoryRequirements.memoryTypeBits)); for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { Logger::err(str::format("Heap ", i, ": ", @@ -290,19 +293,20 @@ namespace dxvk { DxvkMemory DxvkMemoryAllocator::tryAlloc( - const VkMemoryRequirements* req, - const VkMemoryDedicatedAllocateInfo* dedAllocInfo, - VkMemoryPropertyFlags flags, + const DxvkMemoryRequirements& req, + const DxvkMemoryProperties& info, DxvkMemoryFlags hints) { DxvkMemory result; for (uint32_t i = 0; i < m_memProps.memoryTypeCount && !result; i++) { - const bool supported = (req->memoryTypeBits & (1u << i)) != 0; - const bool adequate = (m_memTypes[i].memType.propertyFlags & flags) == flags; + const bool supported = (req.core.memoryRequirements.memoryTypeBits & (1u << i)) != 0; + const bool adequate = (m_memTypes[i].memType.propertyFlags & info.flags) == info.flags; if (supported && adequate) { result = this->tryAllocFromType(&m_memTypes[i], - flags, req->size, req->alignment, hints, dedAllocInfo); + req.core.memoryRequirements.size, + req.core.memoryRequirements.alignment, + info, hints); } } @@ -312,27 +316,25 @@ namespace dxvk { DxvkMemory DxvkMemoryAllocator::tryAllocFromType( DxvkMemoryType* type, - VkMemoryPropertyFlags flags, VkDeviceSize size, VkDeviceSize align, - DxvkMemoryFlags hints, - const VkMemoryDedicatedAllocateInfo* dedAllocInfo) { + const DxvkMemoryProperties& info, + DxvkMemoryFlags hints) { VkDeviceSize chunkSize = pickChunkSize(type->memTypeId, hints); DxvkMemory memory; - if (size >= chunkSize || dedAllocInfo) { + if (size >= chunkSize || info.dedicated.buffer || info.dedicated.image) { if (this->shouldFreeEmptyChunks(type->heap, size)) this->freeEmptyChunks(type->heap); - DxvkDeviceMemory devMem = this->tryAllocDeviceMemory( - type, flags, size, hints, dedAllocInfo); + DxvkDeviceMemory devMem = this->tryAllocDeviceMemory(type, size, info, hints); if (devMem.memHandle != VK_NULL_HANDLE) memory = DxvkMemory(this, nullptr, type, devMem.memHandle, 0, size, devMem.memPointer); } else { for (uint32_t i = 0; i < type->chunks.size() && !memory; i++) - memory = type->chunks[i]->alloc(flags, size, align, hints); + memory = type->chunks[i]->alloc(info.flags, size, align, hints); if (!memory) { DxvkDeviceMemory devMem; @@ -341,11 +343,11 @@ namespace dxvk { this->freeEmptyChunks(type->heap); for (uint32_t i = 0; i < 6 && (chunkSize >> i) >= size && !devMem.memHandle; i++) - devMem = tryAllocDeviceMemory(type, flags, chunkSize >> i, hints, nullptr); + devMem = tryAllocDeviceMemory(type, chunkSize >> i, info, hints); if (devMem.memHandle) { Rc chunk = new DxvkMemoryChunk(this, type, devMem, hints); - memory = chunk->alloc(flags, size, align, hints); + memory = chunk->alloc(info.flags, size, align, hints); type->chunks.push_back(std::move(chunk)); } @@ -361,11 +363,10 @@ namespace dxvk { DxvkDeviceMemory DxvkMemoryAllocator::tryAllocDeviceMemory( DxvkMemoryType* type, - VkMemoryPropertyFlags flags, VkDeviceSize size, - DxvkMemoryFlags hints, - const VkMemoryDedicatedAllocateInfo* dedAllocInfo) { - bool useMemoryPriority = (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) + DxvkMemoryProperties info, + DxvkMemoryFlags hints) { + bool useMemoryPriority = (info.flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) && (m_device->features().extMemoryPriority.memoryPriority); if (type->heap->budget && type->heap->stats.memoryAllocated + size > type->heap->budget) @@ -380,23 +381,32 @@ namespace dxvk { DxvkDeviceMemory result; result.memSize = size; - result.memFlags = flags; + result.memFlags = info.flags; result.priority = priority; - VkMemoryPriorityAllocateInfoEXT prio = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT }; - prio.priority = priority; + VkMemoryPriorityAllocateInfoEXT priorityInfo = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT }; + priorityInfo.priority = priority; - VkMemoryAllocateInfo info = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, dedAllocInfo }; - info.allocationSize = size; - info.memoryTypeIndex = type->memTypeId; + VkMemoryAllocateInfo memoryInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; + memoryInfo.allocationSize = size; + memoryInfo.memoryTypeIndex = type->memTypeId; + + if (info.sharedExport.handleTypes) + info.sharedExport.pNext = std::exchange(memoryInfo.pNext, &info.sharedExport); + + if (info.sharedImportWin32.handleType) + info.sharedImportWin32.pNext = std::exchange(memoryInfo.pNext, &info.sharedImportWin32); + + if (info.dedicated.buffer || info.dedicated.image) + info.dedicated.pNext = std::exchange(memoryInfo.pNext, &info.dedicated); if (useMemoryPriority) - prio.pNext = std::exchange(info.pNext, &prio); + priorityInfo.pNext = std::exchange(memoryInfo.pNext, &priorityInfo); - if (m_vkd->vkAllocateMemory(m_vkd->device(), &info, nullptr, &result.memHandle) != VK_SUCCESS) + if (m_vkd->vkAllocateMemory(m_vkd->device(), &memoryInfo, nullptr, &result.memHandle) != VK_SUCCESS) return DxvkDeviceMemory(); - if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { + if (info.flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { VkResult status = m_vkd->vkMapMemory(m_vkd->device(), result.memHandle, 0, VK_WHOLE_SIZE, 0, &result.memPointer); if (status != VK_SUCCESS) { diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index 5b8e829dc..af377a95f 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -271,8 +271,28 @@ namespace dxvk { bool checkHints(DxvkMemoryFlags hints) const; }; - - + + + /** + * \brief Memory requirement info + */ + struct DxvkMemoryRequirements { + VkMemoryDedicatedRequirements dedicated; + VkMemoryRequirements2 core; + }; + + + /** + * \brief Memory allocation info + */ + struct DxvkMemoryProperties { + VkExportMemoryAllocateInfo sharedExport; + VkImportMemoryWin32HandleInfoKHR sharedImportWin32; + VkMemoryDedicatedAllocateInfo dedicated; + VkMemoryPropertyFlags flags; + }; + + /** * \brief Memory allocator * @@ -305,17 +325,13 @@ namespace dxvk { * \brief Allocates device memory * * \param [in] req Memory requirements - * \param [in] dedAllocReq Dedicated allocation requirements - * \param [in] dedAllocInfo Dedicated allocation info - * \param [in] flags Memory type flags + * \param [in] info Memory properties * \param [in] hints Memory hints * \returns Allocated memory slice */ DxvkMemory alloc( - const VkMemoryRequirements* req, - const VkMemoryDedicatedRequirements& dedAllocReq, - const VkMemoryDedicatedAllocateInfo& dedAllocInfo, - VkMemoryPropertyFlags flags, + const DxvkMemoryRequirements& req, + DxvkMemoryProperties info, DxvkMemoryFlags hints); /** @@ -342,25 +358,22 @@ namespace dxvk { std::array m_memTypes; DxvkMemory tryAlloc( - const VkMemoryRequirements* req, - const VkMemoryDedicatedAllocateInfo* dedAllocInfo, - VkMemoryPropertyFlags flags, + const DxvkMemoryRequirements& req, + const DxvkMemoryProperties& info, DxvkMemoryFlags hints); DxvkMemory tryAllocFromType( DxvkMemoryType* type, - VkMemoryPropertyFlags flags, VkDeviceSize size, VkDeviceSize align, - DxvkMemoryFlags hints, - const VkMemoryDedicatedAllocateInfo* dedAllocInfo); + const DxvkMemoryProperties& info, + DxvkMemoryFlags hints); DxvkDeviceMemory tryAllocDeviceMemory( DxvkMemoryType* type, - VkMemoryPropertyFlags flags, VkDeviceSize size, - DxvkMemoryFlags hints, - const VkMemoryDedicatedAllocateInfo* dedAllocInfo); + DxvkMemoryProperties info, + DxvkMemoryFlags hints); void free( const DxvkMemory& memory); From 8f24093864339edd511ee3cbbf667d4877f5604a Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Thu, 25 Aug 2022 22:52:01 +0200 Subject: [PATCH 0660/1348] [util] cap MGS V Ground Zeroes vram at 4095 --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index ea4629b87..4d0753cc7 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -289,6 +289,11 @@ namespace dxvk { { R"(\\Stray-Win64-Shipping\.exe$)", {{ { "d3d11.ignoreGraphicsBarriers", "True" }, }} }, + /* Metal Gear Solid V: Ground Zeroes * + * Texture quality can break at high vram */ + { R"(\\MgsGroundZeroes\.exe$)", {{ + { "dxgi.maxDeviceMemory", "4095" }, + }} }, /**********************************************/ /* D3D9 GAMES */ From f521a342d0920ec148fc16bb8ebe8b5d4eae3690 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 26 Aug 2022 04:55:38 +0200 Subject: [PATCH 0661/1348] [d3d11] Report marker support appropriately --- src/d3d11/d3d11_device.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 0df056825..4afe91116 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1658,7 +1658,7 @@ namespace dxvk { if (FeatureSupportDataSize != sizeof(*info)) return E_INVALIDARG; - info->Profile = FALSE; + info->Profile = m_context->IsAnnotationEnabled(); } return S_OK; case D3D11_FEATURE_D3D9_OPTIONS1: { From 9420391dce5cfa7a7cc2034ff502b3d45d6bfbc9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 26 Aug 2022 04:56:40 +0200 Subject: [PATCH 0662/1348] [d3d11] Adjust reported resource sharing caps --- src/d3d11/d3d11_device.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 4afe91116..773086f78 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1588,7 +1588,7 @@ namespace dxvk { info->MultisampleRTVWithForcedSampleCountOne = TRUE; /* not really */ info->SAD4ShaderInstructions = TRUE; info->ExtendedDoublesShaderInstructions = TRUE; - info->ExtendedResourceSharing = TRUE; /* not really */ + info->ExtendedResourceSharing = TRUE; } return S_OK; case D3D11_FEATURE_ARCHITECTURE_INFO: { @@ -1726,7 +1726,7 @@ namespace dxvk { if (FeatureSupportDataSize != sizeof(*info)) return E_INVALIDARG; - info->ExtendedNV12SharedTextureSupported = FALSE; + info->ExtendedNV12SharedTextureSupported = TRUE; } return S_OK; default: From 9b4e53cee20d459c3c857ca7f6a68ce3f0c84607 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 26 Aug 2022 04:58:33 +0200 Subject: [PATCH 0663/1348] [d3d11] Handle D3D11_FEATURE_SHADER_CACHE --- src/d3d11/d3d11_device.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 773086f78..cd97decc3 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1729,6 +1729,18 @@ namespace dxvk { info->ExtendedNV12SharedTextureSupported = TRUE; } return S_OK; + case D3D11_FEATURE_SHADER_CACHE: { + auto info = static_cast(pFeatureSupportData); + + if (FeatureSupportDataSize != sizeof(*info)) + return E_INVALIDARG; + + // DXVK will keep all shaders in memory once created, and all Vulkan + // drivers that we know of that can run DXVK have an on-disk cache. + info->SupportFlags = D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE + | D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE; + } return S_OK; + default: Logger::err(str::format("D3D11Device: CheckFeatureSupport: Unknown feature: ", Feature)); return E_INVALIDARG; From edc74f4c8be354e3e138b88ba7710782cad51a4b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 26 Aug 2022 05:03:21 +0200 Subject: [PATCH 0664/1348] [d3d11] Handle D3D11_FEATURE_D3D11_OPTIONS5 --- src/d3d11/d3d11_device.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index cd97decc3..845a0c271 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1741,6 +1741,17 @@ namespace dxvk { | D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE; } return S_OK; + case D3D11_FEATURE_D3D11_OPTIONS5: { + auto info = static_cast(pFeatureSupportData); + + if (FeatureSupportDataSize != sizeof(*info)) + return E_INVALIDARG; + + // Shared resources are all sorts of wonky for obvious + // reasons, so don't over-promise things here for now + info->SharedResourceTier = D3D11_SHARED_RESOURCE_TIER_1; + } return S_OK; + default: Logger::err(str::format("D3D11Device: CheckFeatureSupport: Unknown feature: ", Feature)); return E_INVALIDARG; From 3ee808afd6d864a89094f0fe28bcdff5b2b1f21e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 25 Aug 2022 21:02:10 +0200 Subject: [PATCH 0665/1348] [dxvk] Make memory object of an image publicly accessible --- src/d3d9/d3d9_common_texture.cpp | 2 +- src/dxvk/dxvk_image.h | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index cdcd469f1..65910e074 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -69,7 +69,7 @@ namespace dxvk { CreateSampleView(0); if (!IsManaged()) { - m_size = m_image->memSize(); + m_size = m_image->memory().length(); if (!m_device->ChangeReportedMemory(-m_size)) throw DxvkError("D3D9: Reporting out of memory from tracking."); } diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index 285c5e9ee..e569979a3 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -162,7 +162,7 @@ namespace dxvk { VkImage handle() const { return m_image.image; } - + /** * \brief Image properties * @@ -301,12 +301,11 @@ namespace dxvk { } /** - * \brief Memory size - * - * \returns The memory size of the image + * \brief Memory object + * \returns Backing memory */ - VkDeviceSize memSize() const { - return m_image.memory.length(); + const DxvkMemory& memory() const { + return m_image.memory; } /** From 6e6d64b83e80f303a1acdaf232322c12334b1e6e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 20:38:00 +0200 Subject: [PATCH 0666/1348] [dxvk] Remove redundant error message --- src/dxvk/dxvk_queue.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dxvk/dxvk_queue.cpp b/src/dxvk/dxvk_queue.cpp index 46a594ce0..2db3fdd36 100644 --- a/src/dxvk/dxvk_queue.cpp +++ b/src/dxvk/dxvk_queue.cpp @@ -203,7 +203,6 @@ namespace dxvk { status = synchronizeSemaphore(entry.submit.semaphoreValue); if (status != VK_SUCCESS) { - Logger::err(str::format("DxvkSubmissionQueue: Failed to sync fence: ", status)); m_lastError = status; m_device->waitForIdle(); } From 71c9c4a5cc18ee037bfd94527e71a69c55a23263 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 19 Aug 2022 16:48:58 +0200 Subject: [PATCH 0667/1348] [dxvk] Log sparse features --- src/dxvk/dxvk_adapter.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 1c7adbbed..3974e6272 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -795,17 +795,28 @@ namespace dxvk { "\n shaderFloat64 : ", features.core.features.shaderFloat64 ? "1" : "0", "\n shaderInt64 : ", features.core.features.shaderInt64 ? "1" : "0", "\n variableMultisampleRate : ", features.core.features.variableMultisampleRate ? "1" : "0", + "\n shaderResourceResidency : ", features.core.features.shaderResourceResidency ? "1" : "0", + "\n shaderResourceMinLod : ", features.core.features.shaderResourceMinLod ? "1" : "0", + "\n sparseBinding : ", features.core.features.sparseBinding ? "1" : "0", + "\n sparseResidencyBuffer : ", features.core.features.sparseResidencyBuffer ? "1" : "0", + "\n sparseResidencyImage2D : ", features.core.features.sparseResidencyImage2D ? "1" : "0", + "\n sparseResidencyImage3D : ", features.core.features.sparseResidencyImage3D ? "1" : "0", + "\n sparseResidency2Samples : ", features.core.features.sparseResidency2Samples ? "1" : "0", + "\n sparseResidency4Samples : ", features.core.features.sparseResidency4Samples ? "1" : "0", + "\n sparseResidency8Samples : ", features.core.features.sparseResidency8Samples ? "1" : "0", + "\n sparseResidency16Samples : ", features.core.features.sparseResidency16Samples ? "1" : "0", + "\n sparseResidencyAliased : ", features.core.features.sparseResidencyAliased ? "1" : "0", "\nVulkan 1.1", "\n shaderDrawParameters : ", features.vk11.shaderDrawParameters, "\nVulkan 1.2", "\n samplerMirrorClampToEdge : ", features.vk12.samplerMirrorClampToEdge, "\n drawIndirectCount : ", features.vk12.drawIndirectCount, + "\n samplerFilterMinmax : ", features.vk12.samplerFilterMinmax, "\n hostQueryReset : ", features.vk12.hostQueryReset, "\n timelineSemaphore : ", features.vk12.timelineSemaphore, "\n bufferDeviceAddress : ", features.vk12.bufferDeviceAddress, "\n shaderOutputViewportIndex : ", features.vk12.shaderOutputViewportIndex, "\n shaderOutputLayer : ", features.vk12.shaderOutputLayer, - "\n timelineSemaphore : ", features.vk12.timelineSemaphore, "\nVulkan 1.3", "\n robustImageAccess : ", features.vk13.robustImageAccess, "\n pipelineCreationCacheControl : ", features.vk13.pipelineCreationCacheControl, From 388288114a6236a1a27aabb44996de71626033a3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 19 Aug 2022 17:08:55 +0200 Subject: [PATCH 0668/1348] [dxvk] Find a sparse binding queue --- src/dxvk/dxvk_adapter.cpp | 18 ++++++++++++++++-- src/dxvk/dxvk_adapter.h | 1 + src/dxvk/dxvk_device.cpp | 6 +++++- src/dxvk/dxvk_device.h | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 3974e6272..4479686fa 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -91,10 +91,22 @@ namespace dxvk { if (transferQueue == VK_QUEUE_FAMILY_IGNORED) transferQueue = computeQueue; - + + uint32_t sparseQueue = VK_QUEUE_FAMILY_IGNORED; + + if (m_queueFamilies[graphicsQueue].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) { + // Prefer using the graphics queue as a sparse binding queue + sparseQueue = graphicsQueue; + } else { + sparseQueue = findQueueFamily( + VK_QUEUE_SPARSE_BINDING_BIT, + VK_QUEUE_SPARSE_BINDING_BIT); + } + DxvkAdapterQueueIndices queues; queues.graphics = graphicsQueue; queues.transfer = transferQueue; + queues.sparse = sparseQueue; return queues; } @@ -465,6 +477,7 @@ namespace dxvk { DxvkAdapterQueueIndices queueFamilies = findQueueFamilies(); queueFamiliySet.insert(queueFamilies.graphics); queueFamiliySet.insert(queueFamilies.transfer); + queueFamiliySet.insert(queueFamilies.sparse); this->logQueueFamilies(queueFamilies); for (uint32_t family : queueFamiliySet) { @@ -855,7 +868,8 @@ namespace dxvk { void DxvkAdapter::logQueueFamilies(const DxvkAdapterQueueIndices& queues) { Logger::info(str::format("Queue families:", "\n Graphics : ", queues.graphics, - "\n Transfer : ", queues.transfer)); + "\n Transfer : ", queues.transfer, + "\n Sparse : ", queues.sparse != VK_QUEUE_FAMILY_IGNORED ? str::format(queues.sparse) : "n/a")); } } diff --git a/src/dxvk/dxvk_adapter.h b/src/dxvk/dxvk_adapter.h index c35fc47c5..52cebcab9 100644 --- a/src/dxvk/dxvk_adapter.h +++ b/src/dxvk/dxvk_adapter.h @@ -49,6 +49,7 @@ namespace dxvk { struct DxvkAdapterQueueIndices { uint32_t graphics; uint32_t transfer; + uint32_t sparse; }; /** diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 6bdaaac37..3608a66ce 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -22,6 +22,7 @@ namespace dxvk { auto queueFamilies = m_adapter->findQueueFamilies(); m_queues.graphics = getQueue(queueFamilies.graphics, 0); m_queues.transfer = getQueue(queueFamilies.transfer, 0); + m_queues.sparse = getQueue(queueFamilies.sparse, 0); } @@ -337,7 +338,10 @@ namespace dxvk { uint32_t family, uint32_t index) const { VkQueue queue = VK_NULL_HANDLE; - m_vkd->vkGetDeviceQueue(m_vkd->device(), family, index, &queue); + + if (family != VK_QUEUE_FAMILY_IGNORED) + m_vkd->vkGetDeviceQueue(m_vkd->device(), family, index, &queue); + return DxvkDeviceQueue { queue, family, index }; } diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 2899f8137..af89f1a17 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -66,6 +66,7 @@ namespace dxvk { struct DxvkDeviceQueueSet { DxvkDeviceQueue graphics; DxvkDeviceQueue transfer; + DxvkDeviceQueue sparse; }; /** From e923cc5b69cf1d0d7c03fe88eb8b3145c52c0a7d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 19 Aug 2022 18:30:21 +0200 Subject: [PATCH 0669/1348] [dxvk] Change emitGraphicsBarrier to specify a dependency --- src/d3d9/d3d9_device.cpp | 6 +++++- src/dxvk/dxvk_context.cpp | 23 ++++++++++++++++++++--- src/dxvk/dxvk_context.h | 10 +++++++++- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 2592e7858..bbb6c3a73 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5316,7 +5316,11 @@ namespace dxvk { void D3D9DeviceEx::MarkRenderHazards() { EmitCs([](DxvkContext* ctx) { - ctx->emitGraphicsBarrier(); + ctx->emitGraphicsBarrier( + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_ACCESS_SHADER_READ_BIT); }); for (uint32_t rtIdx : bit::BitMask(m_activeHazardsRT)) { diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index e3cb0a42d..cda3de723 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1498,9 +1498,26 @@ namespace dxvk { } - void DxvkContext::emitGraphicsBarrier() { - if (!m_barrierControl.test(DxvkBarrierControl::IgnoreGraphicsBarriers)) - this->spillRenderPass(true); + void DxvkContext::emitGraphicsBarrier( + VkPipelineStageFlags srcStages, + VkAccessFlags srcAccess, + VkPipelineStageFlags dstStages, + VkAccessFlags dstAccess) { + // Emit barrier early so we can fold this into + // the spill render pass barrier if possible + if (srcStages | dstStages) { + m_execBarriers.accessMemory( + srcStages, srcAccess, + dstStages, dstAccess); + } + + this->spillRenderPass(true); + + // Flush barriers if there was no active render pass. + // This is necessary because there are no resources + // associated with the barrier to allow tracking. + if (srcStages | dstStages) + m_execBarriers.recordCommands(m_cmd); } diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 376cfdb4c..d18c7e5f0 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -826,8 +826,16 @@ namespace dxvk { * render target, or when subsequent draw calls access any * given resource for writing. It is assumed that no hazards * can happen between storage descriptors and other resources. + * \param [in] srcStages Source pipeline stages + * \param [in] srcAccess Source access + * \param [in] dstStages Destination pipeline stages + * \param [in] dstAccess Destination access */ - void emitGraphicsBarrier(); + void emitGraphicsBarrier( + VkPipelineStageFlags srcStages, + VkAccessFlags srcAccess, + VkPipelineStageFlags dstStages, + VkAccessFlags dstAccess); /** * \brief Generates mip maps From bc3affc26463eb004ebd42829da5e7de1adb5e1d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 20 Aug 2022 14:36:49 +0200 Subject: [PATCH 0670/1348] [dxvk] Add functionality to query sparse metadata --- src/dxvk/dxvk_sparse.cpp | 186 ++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_sparse.h | 200 +++++++++++++++++++++++++++++++++++++++ src/dxvk/meson.build | 1 + 3 files changed, 387 insertions(+) create mode 100644 src/dxvk/dxvk_sparse.cpp create mode 100644 src/dxvk/dxvk_sparse.h diff --git a/src/dxvk/dxvk_sparse.cpp b/src/dxvk/dxvk_sparse.cpp new file mode 100644 index 000000000..367eb4a34 --- /dev/null +++ b/src/dxvk/dxvk_sparse.cpp @@ -0,0 +1,186 @@ +#include "dxvk_buffer.h" +#include "dxvk_device.h" +#include "dxvk_image.h" +#include "dxvk_sparse.h" + +namespace dxvk { + + DxvkSparsePageTable::DxvkSparsePageTable() { + + } + + + DxvkSparsePageTable::DxvkSparsePageTable( + DxvkDevice* device, + const DxvkBuffer* buffer) + : m_buffer(buffer) { + VkDeviceSize bufferSize = buffer->info().size; + + // For linear buffers, the mapping is very simple + // and consists of consecutive 64k pages + size_t pageCount = align(bufferSize, SparseMemoryPageSize) / SparseMemoryPageSize; + m_metadata.resize(pageCount); + + for (size_t i = 0; i < pageCount; i++) { + VkDeviceSize pageOffset = SparseMemoryPageSize * i; + m_metadata[i].type = DxvkSparsePageType::Buffer; + m_metadata[i].buffer.offset = pageOffset; + m_metadata[i].buffer.length = std::min(SparseMemoryPageSize, bufferSize - pageOffset); + } + + // Initialize properties and subresource info so that we can + // easily query this without having to know the resource type + m_subresources.resize(1); + m_subresources[0].pageCount = { uint32_t(pageCount), 1u, 1u }; + m_subresources[0].pageIndex = 0; + + m_properties.pageRegionExtent = { uint32_t(SparseMemoryPageSize), 1u, 1u }; + } + + + DxvkSparsePageTable::DxvkSparsePageTable( + DxvkDevice* device, + const DxvkImage* image) + : m_image(image) { + auto vk = device->vkd(); + + // Query sparse memory requirements + uint32_t reqCount = 0; + vk->vkGetImageSparseMemoryRequirements(vk->device(), image->handle(), &reqCount, nullptr); + + std::vector req(reqCount); + vk->vkGetImageSparseMemoryRequirements(vk->device(), image->handle(), &reqCount, req.data()); + + // Find first non-metadata struct and use it to fill in the image properties + bool foundMainAspect = false; + + for (const auto& r : req) { + if (r.formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) { + VkDeviceSize metadataSize = r.imageMipTailSize; + + if (!(r.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT)) + metadataSize *= m_image->info().numLayers; + + m_properties.metadataPageCount += uint32_t(metadataSize / SparseMemoryPageSize); + } else if (!foundMainAspect) { + m_properties.flags = r.formatProperties.flags; + m_properties.pageRegionExtent = r.formatProperties.imageGranularity; + + if (r.imageMipTailFirstLod < image->info().mipLevels && r.imageMipTailSize) { + m_properties.pagedMipCount = r.imageMipTailFirstLod; + m_properties.mipTailOffset = r.imageMipTailOffset; + m_properties.mipTailSize = r.imageMipTailSize; + m_properties.mipTailStride = r.imageMipTailStride; + } else { + m_properties.pagedMipCount = image->info().mipLevels; + } + + foundMainAspect = true; + } else { + Logger::err(str::format("Found multiple aspects for sparse image:" + "\n Type: ", image->info().type, + "\n Format: ", image->info().format, + "\n Flags: ", image->info().flags, + "\n Extent: ", "(", image->info().extent.width, + ",", image->info().extent.height, + ",", image->info().extent.depth, ")", + "\n Mip levels: ", image->info().mipLevels, + "\n Array layers: ", image->info().numLayers, + "\n Samples: ", image->info().sampleCount, + "\n Usage: ", image->info().usage, + "\n Tiling: ", image->info().tiling)); + } + } + + // Fill in subresource metadata and compute page count + uint32_t totalPageCount = 0; + uint32_t subresourceCount = image->info().numLayers * image->info().mipLevels; + m_subresources.reserve(subresourceCount); + + for (uint32_t l = 0; l < image->info().numLayers; l++) { + for (uint32_t m = 0; m < image->info().mipLevels; m++) { + if (m < m_properties.pagedMipCount) { + // Compute block count for current mip based on image properties + DxvkSparseImageSubresourceProperties subresourceInfo; + subresourceInfo.isMipTail = VK_FALSE; + subresourceInfo.pageCount = util::computeBlockCount( + image->mipLevelExtent(m), m_properties.pageRegionExtent); + + // Advance total page count by number of pages in the subresource + subresourceInfo.pageIndex = totalPageCount; + totalPageCount += util::flattenImageExtent(subresourceInfo.pageCount); + + m_subresources.push_back(subresourceInfo); + } else { + DxvkSparseImageSubresourceProperties subresourceInfo = { }; + subresourceInfo.isMipTail = VK_TRUE; + subresourceInfo.pageCount = { 0u, 0u, 0u }; + subresourceInfo.pageIndex = 0u; + m_subresources.push_back(subresourceInfo); + } + } + } + + if (m_properties.mipTailSize) { + m_properties.mipTailPageIndex = totalPageCount; + + // We may need multiple mip tails for the image + uint32_t mipTailPageCount = m_properties.mipTailSize / SparseMemoryPageSize; + + if (!(m_properties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT)) + mipTailPageCount *= m_image->info().numLayers; + + totalPageCount += mipTailPageCount; + } + + // Fill in page metadata + m_metadata.reserve(totalPageCount); + + for (uint32_t l = 0; l < image->info().numLayers; l++) { + for (uint32_t m = 0; m < m_properties.pagedMipCount; m++) { + VkExtent3D mipExtent = image->mipLevelExtent(m); + VkExtent3D pageCount = util::computeBlockCount(mipExtent, m_properties.pageRegionExtent); + + for (uint32_t z = 0; z < pageCount.depth; z++) { + for (uint32_t y = 0; y < pageCount.height; y++) { + for (uint32_t x = 0; x < pageCount.width; x++) { + DxvkSparsePageInfo pageInfo; + pageInfo.type = DxvkSparsePageType::Image; + pageInfo.image.subresource.aspectMask = image->formatInfo()->aspectMask; + pageInfo.image.subresource.mipLevel = m; + pageInfo.image.subresource.arrayLayer = l; + pageInfo.image.offset.x = x * m_properties.pageRegionExtent.width; + pageInfo.image.offset.y = y * m_properties.pageRegionExtent.height; + pageInfo.image.offset.z = z * m_properties.pageRegionExtent.depth; + pageInfo.image.extent.width = std::min(m_properties.pageRegionExtent.width, mipExtent.width - pageInfo.image.offset.x); + pageInfo.image.extent.height = std::min(m_properties.pageRegionExtent.height, mipExtent.height - pageInfo.image.offset.y); + pageInfo.image.extent.depth = std::min(m_properties.pageRegionExtent.depth, mipExtent.depth - pageInfo.image.offset.z); + m_metadata.push_back(pageInfo); + } + } + } + } + } + + if (m_properties.mipTailSize) { + uint32_t pageCount = m_properties.mipTailSize / SparseMemoryPageSize; + uint32_t layerCount = 1; + + if (!(m_properties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT)) + layerCount = image->info().numLayers; + + for (uint32_t i = 0; i < layerCount; i++) { + for (uint32_t j = 0; j < pageCount; j++) { + DxvkSparsePageInfo pageInfo; + pageInfo.type = DxvkSparsePageType::ImageMipTail; + pageInfo.mipTail.resourceOffset = m_properties.mipTailOffset + + i * m_properties.mipTailStride + + j * SparseMemoryPageSize; + pageInfo.mipTail.resourceLength = SparseMemoryPageSize; + m_metadata.push_back(pageInfo); + } + } + } + } + +} diff --git a/src/dxvk/dxvk_sparse.h b/src/dxvk/dxvk_sparse.h new file mode 100644 index 000000000..46c373ba3 --- /dev/null +++ b/src/dxvk/dxvk_sparse.h @@ -0,0 +1,200 @@ +#pragma once + +#include "dxvk_memory.h" +#include "dxvk_resource.h" + +namespace dxvk { + + class DxvkCommandList; + class DxvkDevice; + class DxvkBuffer; + class DxvkImage; + class DxvkSparsePage; + class DxvkSparsePagePool; + + constexpr static VkDeviceSize SparseMemoryPageSize = 1ull << 16; + + /** + * \brief Sparse page handle + */ + struct DxvkSparsePageHandle { + VkDeviceMemory memory; + VkDeviceSize offset; + VkDeviceSize length; + }; + + + /** + * \brief Buffer info for sparse page + * + * Stores the buffer region backed by + * any given page. + */ + struct DxvkSparsePageBufferInfo { + VkDeviceSize offset; + VkDeviceSize length; + }; + + + /** + * \brief Image info for sparse page + * + * Stores the image region backed by + * any given page. + */ + struct DxvkSparsePageImageInfo { + VkImageSubresource subresource; + VkOffset3D offset; + VkExtent3D extent; + }; + + + /** + * \brief Image mip tail info for sparse page + * + * Stores the virtual resource offset and size + * within the mip tail backed by any given page. + */ + struct DxvkSparsePageMipTailInfo { + VkDeviceSize resourceOffset; + VkDeviceSize resourceLength; + }; + + + /** + * \brief Page type + */ + enum class DxvkSparsePageType : uint32_t { + None = 0, + Buffer = 1, + Image = 2, + ImageMipTail = 3, + }; + + + /** + * \brief Sparse page table metadata + * + * Stores the resource region backed by any given page. + */ + struct DxvkSparsePageInfo { + DxvkSparsePageType type; + union { + DxvkSparsePageBufferInfo buffer; + DxvkSparsePageImageInfo image; + DxvkSparsePageMipTailInfo mipTail; + }; + }; + + + /** + * \brief Image tiling info + */ + struct DxvkSparseImageProperties { + VkSparseImageFormatFlags flags; + VkExtent3D pageRegionExtent; + uint32_t pagedMipCount; + uint32_t metadataPageCount; + uint32_t mipTailPageIndex; + VkDeviceSize mipTailOffset; + VkDeviceSize mipTailSize; + VkDeviceSize mipTailStride; + }; + + + /** + * \brief Image subresource tiling info + */ + struct DxvkSparseImageSubresourceProperties { + VkBool32 isMipTail; + VkExtent3D pageCount; + uint32_t pageIndex; + }; + + + /** + * \brief Sparse page table + * + * Stores mappings from a resource region to a given memory page, + * as well as mapping tile indices to the given resource region. + */ + class DxvkSparsePageTable { + + public: + + DxvkSparsePageTable(); + + DxvkSparsePageTable( + DxvkDevice* device, + const DxvkBuffer* buffer); + + DxvkSparsePageTable( + DxvkDevice* device, + const DxvkImage* image); + + /** + * \brief Counts total number of pages in the resources + * + * Counts the number of pages for the entire resource, both + * for paged subresources as well as the mip tail. + * \returns Total number of pages + */ + uint32_t getPageCount() const { + return uint32_t(m_metadata.size()); + } + + /** + * \brief Counts number of subresource infos + * \returns Subresource info count + */ + uint32_t getSubresourceCount() const { + return uint32_t(m_subresources.size()); + } + + /** + * \brief Retrieves image properties + * + * Only contains meaningful info if the page + * table object was created for an image. + * \returns Image properties + */ + DxvkSparseImageProperties getProperties() const { + return m_properties; + } + + /** + * \brief Retrieves image subresource properties + * + * \param [in] subresource The subresource to query + * \returns Properties of the given subresource + */ + DxvkSparseImageSubresourceProperties getSubresourceProperties(uint32_t subresource) const { + return subresource < getSubresourceCount() + ? m_subresources[subresource] + : DxvkSparseImageSubresourceProperties(); + } + + /** + * \brief Queries info for a given page + * + * \param [in] page Page index + * \returns Page info + */ + DxvkSparsePageInfo getPageInfo(uint32_t page) const { + return page < getPageCount() + ? m_metadata[page] + : DxvkSparsePageInfo(); + } + + private: + + const DxvkBuffer* m_buffer = nullptr; + const DxvkImage* m_image = nullptr; + + DxvkSparseImageProperties m_properties = { }; + std::vector m_subresources; + std::vector m_metadata; + + }; + +} \ No newline at end of file diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 56aa42102..8c4b81784 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -98,6 +98,7 @@ dxvk_src = [ 'dxvk_shader.cpp', 'dxvk_shader_key.cpp', 'dxvk_signal.cpp', + 'dxvk_sparse.cpp', 'dxvk_staging.cpp', 'dxvk_state_cache.cpp', 'dxvk_stats.cpp', From f7c255de2a603fead37580d7857a018fe23bb73f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 20 Aug 2022 14:53:41 +0200 Subject: [PATCH 0671/1348] [dxvk] Implement sparse buffer creation --- src/dxvk/dxvk_buffer.cpp | 96 +++++++++++++++++++++++++++++----------- src/dxvk/dxvk_buffer.h | 20 ++++++++- 2 files changed, 88 insertions(+), 28 deletions(-) diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 314a1b68d..eeb7afade 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -16,33 +16,49 @@ namespace dxvk { m_memAlloc (&memAlloc), m_memFlags (memFlags), m_shaderStages (util::shaderStages(createInfo.stages)) { - // Align slices so that we don't violate any alignment - // requirements imposed by the Vulkan device/driver - VkDeviceSize sliceAlignment = computeSliceAlignment(); - m_physSliceLength = createInfo.size; - m_physSliceStride = align(createInfo.size, sliceAlignment); - m_physSliceCount = std::max(1, 256 / m_physSliceStride); + if (!(m_info.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)) { + // Align slices so that we don't violate any alignment + // requirements imposed by the Vulkan device/driver + VkDeviceSize sliceAlignment = computeSliceAlignment(); + m_physSliceLength = createInfo.size; + m_physSliceStride = align(createInfo.size, sliceAlignment); + m_physSliceCount = std::max(1, 256 / m_physSliceStride); - // Limit size of multi-slice buffers to reduce fragmentation - constexpr VkDeviceSize MaxBufferSize = 256 << 10; + // Limit size of multi-slice buffers to reduce fragmentation + constexpr VkDeviceSize MaxBufferSize = 256 << 10; - m_physSliceMaxCount = MaxBufferSize >= m_physSliceStride - ? MaxBufferSize / m_physSliceStride - : 1; + m_physSliceMaxCount = MaxBufferSize >= m_physSliceStride + ? MaxBufferSize / m_physSliceStride + : 1; - // Allocate the initial set of buffer slices. Only clear - // buffer memory if there is more than one slice, since - // we expect the client api to initialize the first slice. - m_buffer = allocBuffer(m_physSliceCount, m_physSliceCount > 1); + // Allocate the initial set of buffer slices. Only clear + // buffer memory if there is more than one slice, since + // we expect the client api to initialize the first slice. + m_buffer = allocBuffer(m_physSliceCount, m_physSliceCount > 1); - DxvkBufferSliceHandle slice; - slice.handle = m_buffer.buffer; - slice.offset = 0; - slice.length = m_physSliceLength; - slice.mapPtr = m_buffer.memory.mapPtr(0); + m_physSlice.handle = m_buffer.buffer; + m_physSlice.offset = 0; + m_physSlice.length = m_physSliceLength; + m_physSlice.mapPtr = m_buffer.memory.mapPtr(0); - m_physSlice = slice; - m_lazyAlloc = m_physSliceCount > 1; + m_lazyAlloc = m_physSliceCount > 1; + } else { + m_physSliceLength = createInfo.size; + m_physSliceStride = createInfo.size; + m_physSliceCount = 1; + m_physSliceMaxCount = 1; + + m_buffer = createSparseBuffer(); + + m_physSlice.handle = m_buffer.buffer; + m_physSlice.offset = 0; + m_physSlice.length = createInfo.size; + m_physSlice.mapPtr = nullptr; + + m_lazyAlloc = false; + + m_sparsePageTable = DxvkSparsePageTable(device, this); + } } @@ -59,17 +75,19 @@ namespace dxvk { auto vkd = m_device->vkd(); VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; - info.size = m_physSliceStride * sliceCount; - info.usage = m_info.usage; - info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + info.flags = m_info.flags; + info.size = m_physSliceStride * sliceCount; + info.usage = m_info.usage; + info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; DxvkBufferHandle handle; if (vkd->vkCreateBuffer(vkd->device(), &info, nullptr, &handle.buffer)) { throw DxvkError(str::format( "DxvkBuffer: Failed to create buffer:" - "\n size: ", info.size, - "\n usage: ", info.usage)); + "\n flags: ", std::hex, info.flags, + "\n size: ", std::dec, info.size, + "\n usage: ", std::hex, info.usage)); } // Query memory requirements and whether to use a dedicated allocation @@ -122,6 +140,30 @@ namespace dxvk { } + DxvkBufferHandle DxvkBuffer::createSparseBuffer() const { + auto vkd = m_device->vkd(); + + VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + info.flags = m_info.flags; + info.size = m_info.size; + info.usage = m_info.usage; + info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + DxvkBufferHandle handle = { }; + + if (vkd->vkCreateBuffer(vkd->device(), + &info, nullptr, &handle.buffer) != VK_SUCCESS) { + throw DxvkError(str::format( + "DxvkBuffer: Failed to create buffer:" + "\n flags: ", std::hex, info.flags, + "\n size: ", std::dec, info.size, + "\n usage: ", std::hex, info.usage)); + } + + return handle; + } + + VkDeviceSize DxvkBuffer::computeSliceAlignment() const { const auto& devInfo = m_device->properties(); diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 3dbbf5b9a..3c383c2e1 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -8,6 +8,7 @@ #include "dxvk_hash.h" #include "dxvk_memory.h" #include "dxvk_resource.h" +#include "dxvk_sparse.h" namespace dxvk { @@ -18,6 +19,9 @@ namespace dxvk { * passed to \ref DxvkDevice::createBuffer */ struct DxvkBufferCreateInfo { + /// Buffer create flags + VkBufferCreateFlags flags = 0; + /// Size of the buffer, in bytes VkDeviceSize size; @@ -289,7 +293,17 @@ namespace dxvk { std::unique_lock swapLock(m_swapMutex); m_nextSlices.push_back(slice); } - + + /** + * \brief Queries sparse page table + * \returns Page table, or \c nullptr for a non-sparse resource + */ + DxvkSparsePageTable* getSparsePageTable() { + return m_info.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT + ? &m_sparsePageTable + : nullptr; + } + private: DxvkDevice* m_device; @@ -302,6 +316,8 @@ namespace dxvk { DxvkBufferSliceHandle m_physSlice; uint32_t m_vertexStride = 0; + DxvkSparsePageTable m_sparsePageTable; + alignas(CACHE_LINE_SIZE) sync::Spinlock m_freeMutex; @@ -331,6 +347,8 @@ namespace dxvk { VkDeviceSize sliceCount, bool clear) const; + DxvkBufferHandle createSparseBuffer() const; + VkDeviceSize computeSliceAlignment() const; }; From 2d124b811bd3a708847fd2e5d868bdc7197f80de Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 20 Aug 2022 15:59:19 +0200 Subject: [PATCH 0672/1348] [dxvk] Implement sparse image creation --- src/dxvk/dxvk_image.cpp | 143 ++++++++++++++++++++++++---------------- src/dxvk/dxvk_image.h | 17 ++++- 2 files changed, 103 insertions(+), 57 deletions(-) diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index 013420386..0cf60e3da 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -5,7 +5,7 @@ namespace dxvk { DxvkImage::DxvkImage( - const DxvkDevice* device, + DxvkDevice* device, const DxvkImageCreateInfo& createInfo, DxvkMemoryAllocator& memAlloc, VkMemoryPropertyFlags memFlags) @@ -47,6 +47,7 @@ namespace dxvk { "DxvkImage: Failed to create image:", "\n Type: ", info.imageType, "\n Format: ", info.format, + "\n Flags: ", info.flags, "\n Extent: ", "(", info.extent.width, ",", info.extent.height, ",", info.extent.depth, ")", @@ -56,79 +57,107 @@ namespace dxvk { "\n Usage: ", info.usage, "\n Tiling: ", info.tiling)); } - - // Get memory requirements for the image and ask driver - // whether we need to use a dedicated allocation. - DxvkMemoryRequirements memoryRequirements = { }; - memoryRequirements.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS }; - memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &memoryRequirements.dedicated }; VkImageMemoryRequirementsInfo2 memoryRequirementInfo = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 }; memoryRequirementInfo.image = m_image.image; - m_vkd->vkGetImageMemoryRequirements2(m_vkd->device(), - &memoryRequirementInfo, &memoryRequirements.core); + if (!(info.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) { + // Get memory requirements for the image and ask driver + // whether we need to use a dedicated allocation. + DxvkMemoryRequirements memoryRequirements = { }; + memoryRequirements.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS }; + memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &memoryRequirements.dedicated }; - // Fill in desired memory properties - DxvkMemoryProperties memoryProperties = { }; - memoryProperties.flags = m_memFlags; + m_vkd->vkGetImageMemoryRequirements2(m_vkd->device(), + &memoryRequirementInfo, &memoryRequirements.core); - if (m_shared) { - memoryRequirements.dedicated.prefersDedicatedAllocation = VK_TRUE; - memoryRequirements.dedicated.requiresDedicatedAllocation = VK_TRUE; + // Fill in desired memory properties + DxvkMemoryProperties memoryProperties = { }; + memoryProperties.flags = m_memFlags; - if (createInfo.sharing.mode == DxvkSharedHandleMode::Export) { - memoryProperties.sharedExport = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO }; - memoryProperties.sharedExport.handleTypes = createInfo.sharing.type; + if (m_shared) { + memoryRequirements.dedicated.prefersDedicatedAllocation = VK_TRUE; + memoryRequirements.dedicated.requiresDedicatedAllocation = VK_TRUE; + + if (createInfo.sharing.mode == DxvkSharedHandleMode::Export) { + memoryProperties.sharedExport = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO }; + memoryProperties.sharedExport.handleTypes = createInfo.sharing.type; + } + + if (createInfo.sharing.mode == DxvkSharedHandleMode::Import) { + memoryProperties.sharedImportWin32 = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR }; + memoryProperties.sharedImportWin32.handleType = createInfo.sharing.type; + memoryProperties.sharedImportWin32.handle = createInfo.sharing.handle; + } } - if (createInfo.sharing.mode == DxvkSharedHandleMode::Import) { - memoryProperties.sharedImportWin32 = { VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR }; - memoryProperties.sharedImportWin32.handleType = createInfo.sharing.type; - memoryProperties.sharedImportWin32.handle = createInfo.sharing.handle; + if (memoryRequirements.dedicated.prefersDedicatedAllocation) { + memoryProperties.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO }; + memoryProperties.dedicated.image = m_image.image; } - } - if (memoryRequirements.dedicated.prefersDedicatedAllocation) { - memoryProperties.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO }; - memoryProperties.dedicated.image = m_image.image; - } + // If there's a chance we won't create the image with a dedicated + // allocation, enforce strict alignment for tiled images to not + // violate the bufferImageGranularity requirement on some GPUs. + if (info.tiling != VK_IMAGE_TILING_LINEAR && !memoryRequirements.dedicated.requiresDedicatedAllocation) { + VkDeviceSize granularity = memAlloc.bufferImageGranularity(); - // If there's a chance we won't create the image with a dedicated - // allocation, enforce strict alignment for tiled images to not - // violate the bufferImageGranularity requirement on some GPUs. - if (info.tiling != VK_IMAGE_TILING_LINEAR && !memoryRequirements.dedicated.requiresDedicatedAllocation) { - VkDeviceSize granularity = memAlloc.bufferImageGranularity(); + auto& core = memoryRequirements.core.memoryRequirements; + core.size = align(core.size, granularity); + core.alignment = align(core.alignment, granularity); + } - auto& core = memoryRequirements.core.memoryRequirements; - core.size = align(core.size, granularity); - core.alignment = align(core.alignment, granularity); - } + // Use high memory priority for GPU-writable resources + bool isGpuWritable = (m_info.access & ( + VK_ACCESS_SHADER_WRITE_BIT | + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT)) != 0; - // Use high memory priority for GPU-writable resources - bool isGpuWritable = (m_info.access & ( - VK_ACCESS_SHADER_WRITE_BIT | - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT)) != 0; - - DxvkMemoryFlags hints(DxvkMemoryFlag::GpuReadable); + DxvkMemoryFlags hints(DxvkMemoryFlag::GpuReadable); - if (isGpuWritable) - hints.set(DxvkMemoryFlag::GpuWritable); + if (isGpuWritable) + hints.set(DxvkMemoryFlag::GpuWritable); - m_image.memory = memAlloc.alloc(memoryRequirements, memoryProperties, hints); - - // Try to bind the allocated memory slice to the image - if (m_vkd->vkBindImageMemory(m_vkd->device(), m_image.image, + m_image.memory = memAlloc.alloc(memoryRequirements, memoryProperties, hints); + + // Try to bind the allocated memory slice to the image + if (m_vkd->vkBindImageMemory(m_vkd->device(), m_image.image, m_image.memory.memory(), m_image.memory.offset()) != VK_SUCCESS) - throw DxvkError("DxvkImage::DxvkImage: Failed to bind device memory"); + throw DxvkError("DxvkImage::DxvkImage: Failed to bind device memory"); + } else { + // Initialize sparse info. We do not immediately bind the metadata + // aspects of the image here, the caller needs to explicitly do that. + m_sparsePageTable = DxvkSparsePageTable(device, this); + + // Allocate memory for sparse metadata if necessary + auto properties = m_sparsePageTable.getProperties(); + + if (properties.metadataPageCount) { + DxvkMemoryRequirements memoryRequirements = { }; + memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 }; + + m_vkd->vkGetImageMemoryRequirements2(m_vkd->device(), + &memoryRequirementInfo, &memoryRequirements.core); + + DxvkMemoryProperties memoryProperties = { }; + memoryProperties.flags = m_memFlags; + + // Set size and alignment to match the metadata requirements + auto& core = memoryRequirements.core.memoryRequirements; + core.size = SparseMemoryPageSize * properties.metadataPageCount; + core.alignment = SparseMemoryPageSize; + + m_image.memory = memAlloc.alloc(memoryRequirements, + memoryProperties, DxvkMemoryFlag::GpuReadable); + } + } } DxvkImage::DxvkImage( - const DxvkDevice* device, + DxvkDevice* device, const DxvkImageCreateInfo& info, VkImage image) : m_vkd(device->vkd()), m_device(device), m_info(info), m_image({ image }) { @@ -143,12 +172,13 @@ namespace dxvk { DxvkImage::~DxvkImage() { // This is a bit of a hack to determine whether // the image is implementation-handled or not - if (m_image.memory.memory() != VK_NULL_HANDLE) + if ((m_image.memory.memory()) + || (m_info.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) m_vkd->vkDestroyImage(m_vkd->device(), m_image.image, nullptr); } - bool DxvkImage::canShareImage(const VkImageCreateInfo& createInfo, const DxvkSharedHandleInfo& sharingInfo) const { + bool DxvkImage::canShareImage(const VkImageCreateInfo& createInfo, const DxvkSharedHandleInfo& sharingInfo) const { if (sharingInfo.mode == DxvkSharedHandleMode::None) return false; @@ -157,6 +187,9 @@ namespace dxvk { return false; } + if (createInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) + return false; + VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO }; externalImageFormatInfo.handleType = sharingInfo.type; diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index e569979a3..7cda6f5a1 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -4,6 +4,7 @@ #include "dxvk_format.h" #include "dxvk_memory.h" #include "dxvk_resource.h" +#include "dxvk_sparse.h" #include "dxvk_util.h" namespace dxvk { @@ -127,7 +128,7 @@ namespace dxvk { public: DxvkImage( - const DxvkDevice* device, + DxvkDevice* device, const DxvkImageCreateInfo& createInfo, DxvkMemoryAllocator& memAlloc, VkMemoryPropertyFlags memFlags); @@ -141,7 +142,7 @@ namespace dxvk { * otherwise some image operations may fail. */ DxvkImage( - const DxvkDevice* device, + DxvkDevice* device, const DxvkImageCreateInfo& info, VkImage image); @@ -323,6 +324,16 @@ namespace dxvk { return result; } + /** + * \brief Queries sparse page table + * \returns Page table, or \c nullptr for a non-sparse resource + */ + DxvkSparsePageTable* getSparsePageTable() { + return m_info.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT + ? &m_sparsePageTable + : nullptr; + } + /** * \brief Create a new shared handle to dedicated memory backing the image * \returns The shared handle with the type given by DxvkSharedHandleInfo::type @@ -336,6 +347,8 @@ namespace dxvk { DxvkImageCreateInfo m_info; VkMemoryPropertyFlags m_memFlags; DxvkPhysicalImage m_image; + DxvkSparsePageTable m_sparsePageTable; + bool m_shared = false; small_vector m_viewFormats; From dd54de4d97d179c19d1f54225288e858485d5f48 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 16:02:43 +0200 Subject: [PATCH 0673/1348] [dxvk] Introduce DxvkPagedResource --- src/dxvk/dxvk_buffer.h | 14 +------------- src/dxvk/dxvk_image.h | 13 +------------ src/dxvk/dxvk_sparse.h | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 3c383c2e1..5ea4ca91c 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -103,7 +103,7 @@ namespace dxvk { * unformatted data. Can be accessed by the host * if allocated on an appropriate memory type. */ - class DxvkBuffer : public DxvkResource { + class DxvkBuffer : public DxvkPagedResource { friend class DxvkBufferView; public: @@ -294,16 +294,6 @@ namespace dxvk { m_nextSlices.push_back(slice); } - /** - * \brief Queries sparse page table - * \returns Page table, or \c nullptr for a non-sparse resource - */ - DxvkSparsePageTable* getSparsePageTable() { - return m_info.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT - ? &m_sparsePageTable - : nullptr; - } - private: DxvkDevice* m_device; @@ -316,8 +306,6 @@ namespace dxvk { DxvkBufferSliceHandle m_physSlice; uint32_t m_vertexStride = 0; - DxvkSparsePageTable m_sparsePageTable; - alignas(CACHE_LINE_SIZE) sync::Spinlock m_freeMutex; diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index 7cda6f5a1..a29d916cf 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -122,7 +122,7 @@ namespace dxvk { * Can be accessed by the host if allocated on a suitable * memory type and if created with the linear tiling option. */ - class DxvkImage : public DxvkResource { + class DxvkImage : public DxvkPagedResource { friend class DxvkContext; friend class DxvkImageView; public: @@ -324,16 +324,6 @@ namespace dxvk { return result; } - /** - * \brief Queries sparse page table - * \returns Page table, or \c nullptr for a non-sparse resource - */ - DxvkSparsePageTable* getSparsePageTable() { - return m_info.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT - ? &m_sparsePageTable - : nullptr; - } - /** * \brief Create a new shared handle to dedicated memory backing the image * \returns The shared handle with the type given by DxvkSharedHandleInfo::type @@ -347,7 +337,6 @@ namespace dxvk { DxvkImageCreateInfo m_info; VkMemoryPropertyFlags m_memFlags; DxvkPhysicalImage m_image; - DxvkSparsePageTable m_sparsePageTable; bool m_shared = false; diff --git a/src/dxvk/dxvk_sparse.h b/src/dxvk/dxvk_sparse.h index 46c373ba3..1563e90e4 100644 --- a/src/dxvk/dxvk_sparse.h +++ b/src/dxvk/dxvk_sparse.h @@ -132,6 +132,14 @@ namespace dxvk { DxvkDevice* device, const DxvkImage* image); + /** + * \brief Checks whether page table is defined + * \returns \c true if the page table is defined + */ + operator bool () const { + return m_buffer || m_image; + } + /** * \brief Counts total number of pages in the resources * @@ -197,4 +205,31 @@ namespace dxvk { }; + + /** + * \brief Paged resource + * + * Base class for any resource that can + * hold a sparse page table. + */ + class DxvkPagedResource : public DxvkResource { + + public: + + /** + * \brief Queries sparse page table + * \returns Sparse page table, if defined + */ + DxvkSparsePageTable* getSparsePageTable() { + return m_sparsePageTable + ? &m_sparsePageTable + : nullptr; + } + + protected: + + DxvkSparsePageTable m_sparsePageTable; + + }; + } \ No newline at end of file From 6f216f9df460a906c2495e5832b851858bfff158 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 20:51:54 +0200 Subject: [PATCH 0674/1348] [dxvk] Do not discard sparse buffers This would only blow up. --- src/dxvk/dxvk_context.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index cda3de723..c2ab3b5b8 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1170,7 +1170,8 @@ namespace dxvk { void DxvkContext::discardBuffer( const Rc& buffer) { - if (buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + if ((buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + || (buffer->info().flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)) return; if (m_execBarriers.isBufferDirty(buffer->getSliceHandle(), DxvkAccess::Write)) @@ -5745,6 +5746,10 @@ namespace dxvk { if (buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) return false; + // Don't discard sparse buffers + if (buffer->info().flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) + return false; + // Suspend the current render pass if transform feedback is active prior to // invalidating the buffer, since otherwise we may invalidate a bound buffer. if ((buffer->info().usage & VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT) From f9db4921e0cdabfc268026476350fcfc69696206 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 20 Aug 2022 21:57:46 +0200 Subject: [PATCH 0675/1348] [dxvk] Implement sparse memory allocator --- src/dxvk/dxvk_device.cpp | 5 ++ src/dxvk/dxvk_device.h | 7 ++ src/dxvk/dxvk_memory.cpp | 93 +++++++++++++++++++++--- src/dxvk/dxvk_memory.h | 24 +++++-- src/dxvk/dxvk_sparse.cpp | 152 +++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_sparse.h | 149 +++++++++++++++++++++++++++++++++++++- 6 files changed, 415 insertions(+), 15 deletions(-) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 3608a66ce..4820cf778 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -216,6 +216,11 @@ namespace dxvk { } + Rc DxvkDevice::createSparsePageAllocator() { + return new DxvkSparsePageAllocator(this, m_objects.memoryManager()); + } + + DxvkStatCounters DxvkDevice::getStatCounters() { DxvkPipelineCount pipe = m_objects.pipelineManager().getPipelineCount(); diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index af89f1a17..9ee2744a9 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -22,6 +22,7 @@ #include "dxvk_renderpass.h" #include "dxvk_sampler.h" #include "dxvk_shader.h" +#include "dxvk_sparse.h" #include "dxvk_stats.h" #include "dxvk_unbound.h" #include "dxvk_marker.h" @@ -380,6 +381,12 @@ namespace dxvk { Rc createSampler( const DxvkSamplerCreateInfo& createInfo); + /** + * \brief Creates a sparse page allocator + * \returns Sparse page allocator + */ + Rc createSparsePageAllocator(); + /** * \brief Retrieves stat counters * diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index f0dfa6696..135bf9991 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -179,9 +179,8 @@ namespace dxvk { } - DxvkMemoryAllocator::DxvkMemoryAllocator(const DxvkDevice* device) - : m_vkd (device->vkd()), - m_device (device), + DxvkMemoryAllocator::DxvkMemoryAllocator(DxvkDevice* device) + : m_device (device), m_devProps (device->adapter()->deviceProperties()), m_memProps (device->adapter()->memoryProperties()) { for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { @@ -202,6 +201,9 @@ namespace dxvk { m_memTypes[i].memType = m_memProps.memoryTypes[i]; m_memTypes[i].memTypeId = i; } + + if (device->features().core.features.sparseBinding) + m_sparseMemoryTypes = determineSparseMemoryTypes(device); } @@ -366,6 +368,8 @@ namespace dxvk { VkDeviceSize size, DxvkMemoryProperties info, DxvkMemoryFlags hints) { + auto vk = m_device->vkd(); + bool useMemoryPriority = (info.flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) && (m_device->features().extMemoryPriority.memoryPriority); @@ -403,15 +407,15 @@ namespace dxvk { if (useMemoryPriority) priorityInfo.pNext = std::exchange(memoryInfo.pNext, &priorityInfo); - if (m_vkd->vkAllocateMemory(m_vkd->device(), &memoryInfo, nullptr, &result.memHandle) != VK_SUCCESS) + if (vk->vkAllocateMemory(vk->device(), &memoryInfo, nullptr, &result.memHandle)) return DxvkDeviceMemory(); if (info.flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - VkResult status = m_vkd->vkMapMemory(m_vkd->device(), result.memHandle, 0, VK_WHOLE_SIZE, 0, &result.memPointer); + VkResult status = vk->vkMapMemory(vk->device(), result.memHandle, 0, VK_WHOLE_SIZE, 0, &result.memPointer); - if (status != VK_SUCCESS) { + if (status) { Logger::err(str::format("DxvkMemoryAllocator: Mapping memory failed with ", status)); - m_vkd->vkFreeMemory(m_vkd->device(), result.memHandle, nullptr); + vk->vkFreeMemory(vk->device(), result.memHandle, nullptr); return DxvkDeviceMemory(); } } @@ -467,7 +471,9 @@ namespace dxvk { void DxvkMemoryAllocator::freeDeviceMemory( DxvkMemoryType* type, DxvkDeviceMemory memory) { - m_vkd->vkFreeMemory(m_vkd->device(), memory.memHandle, nullptr); + auto vk = m_device->vkd(); + vk->vkFreeMemory(vk->device(), memory.memHandle, nullptr); + type->heap->stats.memoryAllocated -= memory.memSize; m_device->adapter()->notifyHeapMemoryFree(type->heapId, memory.memSize); } @@ -542,4 +548,75 @@ namespace dxvk { } } + + uint32_t DxvkMemoryAllocator::determineSparseMemoryTypes( + DxvkDevice* device) const { + auto vk = device->vkd(); + + VkMemoryRequirements requirements = { }; + uint32_t typeMask = ~0u; + + // Create sparse dummy buffer to find available memory types + VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + bufferInfo.flags = VK_BUFFER_CREATE_SPARSE_BINDING_BIT + | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT + | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT; + bufferInfo.size = 65536; + bufferInfo.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT + | VK_BUFFER_USAGE_INDEX_BUFFER_BIT + | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT + | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT + | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT + | VK_BUFFER_USAGE_TRANSFER_DST_BIT + | VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + VkBuffer buffer = VK_NULL_HANDLE; + + if (vk->vkCreateBuffer(vk->device(), &bufferInfo, nullptr, &buffer)) { + Logger::err("Failed to create dummy buffer to query sparse memory types"); + return 0; + } + + vk->vkGetBufferMemoryRequirements(vk->device(), buffer, &requirements); + vk->vkDestroyBuffer(vk->device(), buffer, nullptr); + typeMask &= requirements.memoryTypeBits; + + // Create sparse dummy image to find available memory types + VkImageCreateInfo imageInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; + imageInfo.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT + | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT + | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT; + imageInfo.imageType = VK_IMAGE_TYPE_2D; + imageInfo.format = VK_FORMAT_R8G8B8A8_UNORM; + imageInfo.extent = { 256, 256, 1 }; + imageInfo.mipLevels = 1; + imageInfo.arrayLayers = 1; + imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT + | VK_IMAGE_USAGE_SAMPLED_BIT + | VK_IMAGE_USAGE_STORAGE_BIT + | VK_IMAGE_USAGE_TRANSFER_DST_BIT + | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + VkImage image = VK_NULL_HANDLE; + + if (vk->vkCreateImage(vk->device(), &imageInfo, nullptr, &image)) { + Logger::err("Failed to create dummy image to query sparse memory types"); + return 0; + } + + vk->vkGetImageMemoryRequirements(vk->device(), image, &requirements); + vk->vkDestroyImage(vk->device(), image, nullptr); + typeMask &= requirements.memoryTypeBits; + + Logger::log(typeMask ? LogLevel::Info : LogLevel::Error, + str::format("Memory type mask for sparse resources: 0x", std::hex, typeMask)); + return typeMask; + } + } diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index af377a95f..c5caaf88c 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -306,7 +306,7 @@ namespace dxvk { constexpr static VkDeviceSize SmallAllocationThreshold = 256 << 10; public: - DxvkMemoryAllocator(const DxvkDevice* device); + DxvkMemoryAllocator(DxvkDevice* device); ~DxvkMemoryAllocator(); /** @@ -320,7 +320,15 @@ namespace dxvk { VkDeviceSize bufferImageGranularity() const { return m_devProps.limits.bufferImageGranularity; } - + + /** + * \brief Memory type mask for sparse resources + * \returns Sparse resource memory types + */ + uint32_t getSparseMemoryTypes() const { + return m_sparseMemoryTypes; + } + /** * \brief Allocates device memory * @@ -348,15 +356,16 @@ namespace dxvk { private: - const Rc m_vkd; - const DxvkDevice* m_device; - const VkPhysicalDeviceProperties m_devProps; - const VkPhysicalDeviceMemoryProperties m_memProps; + DxvkDevice* m_device; + VkPhysicalDeviceProperties m_devProps; + VkPhysicalDeviceMemoryProperties m_memProps; dxvk::mutex m_mutex; std::array m_memHeaps; std::array m_memTypes; + uint32_t m_sparseMemoryTypes = 0u; + DxvkMemory tryAlloc( const DxvkMemoryRequirements& req, const DxvkMemoryProperties& info, @@ -403,6 +412,9 @@ namespace dxvk { void freeEmptyChunks( const DxvkMemoryHeap* heap); + uint32_t determineSparseMemoryTypes( + DxvkDevice* device) const; + }; } diff --git a/src/dxvk/dxvk_sparse.cpp b/src/dxvk/dxvk_sparse.cpp index 367eb4a34..9b0e2eaa5 100644 --- a/src/dxvk/dxvk_sparse.cpp +++ b/src/dxvk/dxvk_sparse.cpp @@ -5,6 +5,156 @@ namespace dxvk { + DxvkSparseMapping::DxvkSparseMapping() + : m_pool(nullptr), + m_page(nullptr) { + + } + + + DxvkSparseMapping::DxvkSparseMapping( + Rc allocator, + Rc page) + : m_pool(std::move(allocator)), + m_page(std::move(page)) { + + } + + + DxvkSparseMapping::DxvkSparseMapping( + DxvkSparseMapping&& other) + : m_pool(std::move(other.m_pool)), + m_page(std::move(other.m_page)) { + // No need to acquire here. The only place from which + // this constructor can be called does this atomically. + } + + + DxvkSparseMapping::DxvkSparseMapping( + const DxvkSparseMapping& other) + : m_pool(other.m_pool), + m_page(other.m_page) { + this->acquire(); + } + + + DxvkSparseMapping& DxvkSparseMapping::operator = ( + DxvkSparseMapping&& other) { + this->release(); + + m_pool = std::move(other.m_pool); + m_page = std::move(other.m_page); + return *this; + } + + + DxvkSparseMapping& DxvkSparseMapping::operator = ( + const DxvkSparseMapping& other) { + other.acquire(); + this->release(); + + m_pool = other.m_pool; + m_page = other.m_page; + return *this; + } + + + DxvkSparseMapping::~DxvkSparseMapping() { + this->release(); + } + + + void DxvkSparseMapping::acquire() const { + if (m_page != nullptr) + m_pool->acquirePage(m_page); + } + + + void DxvkSparseMapping::release() const { + if (m_page != nullptr) + m_pool->releasePage(m_page); + } + + + DxvkSparsePageAllocator::DxvkSparsePageAllocator( + DxvkDevice* device, + DxvkMemoryAllocator& memoryAllocator) + : m_device(device), m_memory(&memoryAllocator) { + + } + + + DxvkSparsePageAllocator::~DxvkSparsePageAllocator() { + + } + + + DxvkSparseMapping DxvkSparsePageAllocator::acquirePage( + uint32_t page) { + std::lock_guard lock(m_mutex); + + if (unlikely(page >= m_pageCount)) + return DxvkSparseMapping(); + + m_useCount += 1; + return DxvkSparseMapping(this, m_pages[page]); + } + + + void DxvkSparsePageAllocator::setCapacity( + uint32_t pageCount) { + std::lock_guard lock(m_mutex); + + if (pageCount < m_pageCount) { + if (!m_useCount) + m_pages.resize(pageCount); + } else if (pageCount > m_pageCount) { + while (m_pages.size() < pageCount) + m_pages.push_back(allocPage()); + } + + m_pageCount = pageCount; + } + + + Rc DxvkSparsePageAllocator::allocPage() { + DxvkMemoryRequirements memoryRequirements = { }; + memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 }; + + // We don't know what kind of resource the memory6 + // might be bound to, so just guess the memory types + auto& core = memoryRequirements.core.memoryRequirements; + core.size = SparseMemoryPageSize; + core.alignment = SparseMemoryPageSize; + core.memoryTypeBits = m_memory->getSparseMemoryTypes(); + + DxvkMemoryProperties memoryProperties = { }; + memoryProperties.flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + + DxvkMemory memory = m_memory->alloc(memoryRequirements, + memoryProperties, DxvkMemoryFlag::GpuReadable); + + return new DxvkSparsePage(std::move(memory)); + } + + + void DxvkSparsePageAllocator::acquirePage( + const Rc& page) { + std::lock_guard lock(m_mutex); + m_useCount += 1; + } + + + void DxvkSparsePageAllocator::releasePage( + const Rc& page) { + std::lock_guard lock(m_mutex); + m_useCount -= 1; + + if (!m_useCount) + m_pages.resize(m_pageCount); + } + + DxvkSparsePageTable::DxvkSparsePageTable() { } @@ -20,6 +170,7 @@ namespace dxvk { // and consists of consecutive 64k pages size_t pageCount = align(bufferSize, SparseMemoryPageSize) / SparseMemoryPageSize; m_metadata.resize(pageCount); + m_mappings.resize(pageCount); for (size_t i = 0; i < pageCount; i++) { VkDeviceSize pageOffset = SparseMemoryPageSize * i; @@ -135,6 +286,7 @@ namespace dxvk { // Fill in page metadata m_metadata.reserve(totalPageCount); + m_mappings.resize(totalPageCount); for (uint32_t l = 0; l < image->info().numLayers; l++) { for (uint32_t m = 0; m < m_properties.pagedMipCount; m++) { diff --git a/src/dxvk/dxvk_sparse.h b/src/dxvk/dxvk_sparse.h index 1563e90e4..c0585fa3b 100644 --- a/src/dxvk/dxvk_sparse.h +++ b/src/dxvk/dxvk_sparse.h @@ -10,7 +10,7 @@ namespace dxvk { class DxvkBuffer; class DxvkImage; class DxvkSparsePage; - class DxvkSparsePagePool; + class DxvkSparsePageAllocator; constexpr static VkDeviceSize SparseMemoryPageSize = 1ull << 16; @@ -112,6 +112,152 @@ namespace dxvk { }; + /** + * \brief Sparse memory page + * + * Stores a single reference-counted page + * of memory. The page size is 64k. + */ + class DxvkSparsePage : public DxvkResource { + + public: + + DxvkSparsePage(DxvkMemory&& memory) + : m_memory(std::move(memory)) { } + + /** + * \brief Queries memory handle + * \returns Memory information + */ + DxvkSparsePageHandle getHandle() const { + DxvkSparsePageHandle result; + result.memory = m_memory.memory(); + result.offset = m_memory.offset(); + result.length = m_memory.length(); + return result; + } + + private: + + DxvkMemory m_memory; + + }; + + + /** + * \brief Sparse page mapping + * + * Stores a reference to a page as well as the pool that the page + * was allocated from, and automatically manages the use counter + * of the pool as the reference is being moved or copied around. + */ + class DxvkSparseMapping { + friend DxvkSparsePageAllocator; + public: + + DxvkSparseMapping(); + + DxvkSparseMapping(DxvkSparseMapping&& other); + DxvkSparseMapping(const DxvkSparseMapping& other); + + DxvkSparseMapping& operator = (DxvkSparseMapping&& other); + DxvkSparseMapping& operator = (const DxvkSparseMapping& other); + + ~DxvkSparseMapping(); + + Rc getPage() const { + return m_page; + } + + bool operator == (const DxvkSparseMapping& other) const { + // Pool is a function of the page, so no need to check both + return m_page == other.m_page; + } + + bool operator != (const DxvkSparseMapping& other) const { + return m_page != other.m_page; + } + + operator bool () const { + return m_page != nullptr; + } + + private: + + Rc m_pool; + Rc m_page; + + DxvkSparseMapping( + Rc allocator, + Rc page); + + void acquire() const; + + void release() const; + + }; + + + /** + * \brief Sparse memory allocator + * + * Provides an allocator for sparse pages with variable capacity. + * Pages are use-counted to make sure they are not removed from + * the allocator too early. + */ + class DxvkSparsePageAllocator : public RcObject { + friend DxvkSparseMapping; + public: + + DxvkSparsePageAllocator( + DxvkDevice* device, + DxvkMemoryAllocator& memoryAllocator); + + ~DxvkSparsePageAllocator(); + + /** + * \brief Acquires page at the given offset + * + * If the offset is valid, this will atomically + * increment the allocator's use count and return + * a reference to the page. + * \param [in] page Page index + * \returns Page mapping object + */ + DxvkSparseMapping acquirePage( + uint32_t page); + + /** + * \brief Changes the allocator's maximum capacity + * + * Allocates new pages as necessary, and frees existing + * pages if none of the pages are currently in use. + * \param [in] pageCount New capacity, in pages + */ + void setCapacity( + uint32_t pageCount); + + private: + + DxvkDevice* m_device; + DxvkMemoryAllocator* m_memory; + + dxvk::mutex m_mutex; + uint32_t m_pageCount = 0u; + uint32_t m_useCount = 0u; + std::vector> m_pages; + + Rc allocPage(); + + void acquirePage( + const Rc& page); + + void releasePage( + const Rc& page); + + }; + + /** * \brief Sparse page table * @@ -202,6 +348,7 @@ namespace dxvk { DxvkSparseImageProperties m_properties = { }; std::vector m_subresources; std::vector m_metadata; + std::vector m_mappings; }; From 3057f6a51b50d3928284902304f06ce24a8a2fe1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 15:50:55 +0200 Subject: [PATCH 0676/1348] [dxvk] Add structures for sparse binding operations --- src/dxvk/dxvk_sparse.cpp | 61 ++++++++++++++++++++ src/dxvk/dxvk_sparse.h | 117 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 176 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_sparse.cpp b/src/dxvk/dxvk_sparse.cpp index 9b0e2eaa5..e521a49f1 100644 --- a/src/dxvk/dxvk_sparse.cpp +++ b/src/dxvk/dxvk_sparse.cpp @@ -335,4 +335,65 @@ namespace dxvk { } } + + VkBuffer DxvkSparsePageTable::getBufferHandle() const { + return m_buffer ? m_buffer->getSliceHandle().handle : VK_NULL_HANDLE; + } + + + VkImage DxvkSparsePageTable::getImageHandle() const { + return m_image ? m_image->handle() : VK_NULL_HANDLE; + } + + + uint32_t DxvkSparsePageTable::computePageIndex( + uint32_t subresource, + VkOffset3D regionOffset, + VkExtent3D regionExtent, + VkBool32 regionIsLinear, + uint32_t pageIndex) const { + auto subresourceInfo = getSubresourceProperties(subresource); + + // The mip tail is always linear + if (subresourceInfo.isMipTail) + return m_properties.mipTailPageIndex + pageIndex; + + // Compute offset into the given subresource + VkOffset3D pageOffset = regionOffset; + + if (!regionIsLinear) { + pageOffset.x += (pageIndex % regionExtent.width); + pageOffset.y += (pageIndex / regionExtent.width) % regionExtent.height; + pageOffset.z += (pageIndex / regionExtent.width) / regionExtent.height; + pageIndex = 0; + } + + uint32_t result = subresourceInfo.pageIndex + pageOffset.x + + subresourceInfo.pageCount.width * (pageOffset.y + + subresourceInfo.pageCount.height * pageOffset.z); + + return result + pageIndex; + } + + + DxvkSparseMapping DxvkSparsePageTable::getMapping( + uint32_t page) { + return page < m_mappings.size() + ? m_mappings[page] + : DxvkSparseMapping(); + } + + + void DxvkSparsePageTable::updateMapping( + DxvkCommandList* cmd, + uint32_t page, + DxvkSparseMapping&& mapping) { + if (m_mappings[page] != page) { + if (m_mappings[page]) + cmd->trackResource(m_mappings[page].m_page); + + m_mappings[page] = std::move(mapping); + } + } + } diff --git a/src/dxvk/dxvk_sparse.h b/src/dxvk/dxvk_sparse.h index c0585fa3b..f68aeb06a 100644 --- a/src/dxvk/dxvk_sparse.h +++ b/src/dxvk/dxvk_sparse.h @@ -9,8 +9,10 @@ namespace dxvk { class DxvkDevice; class DxvkBuffer; class DxvkImage; + class DxvkPagedResource; class DxvkSparsePage; class DxvkSparsePageAllocator; + class DxvkSparsePageTable; constexpr static VkDeviceSize SparseMemoryPageSize = 1ull << 16; @@ -112,6 +114,55 @@ namespace dxvk { }; + /** + * \brief Sparse binding flags + */ + enum class DxvkSparseBindFlag : uint32_t { + SkipSynchronization, + }; + + using DxvkSparseBindFlags = Flags; + + + /** + * \brief Sparse page binding mode + */ + enum class DxvkSparseBindMode : uint32_t { + Null, ///< Unbind the given resource page + Bind, ///< Bind to given allocator page + Copy, ///< Copy bindig from source resource + }; + + + /** + * \brief Sparse page binding info for a given page + * + * Stores the resource page index as well as the index + * of the allocator page that should be bound to that + * resource page. + */ + struct DxvkSparseBind { + DxvkSparseBindMode mode; + uint32_t dstPage; + uint32_t srcPage; + }; + + + /** + * \brief Sparse binding info + * + * Stores the resource to change page bindings for, the + * allocator from which pages will be allocated, and + * a list of page bidnings + */ + struct DxvkSparseBindInfo { + Rc dstResource; + Rc srcResource; + Rc srcAllocator; + std::vector binds; + }; + + /** * \brief Sparse memory page * @@ -153,6 +204,7 @@ namespace dxvk { */ class DxvkSparseMapping { friend DxvkSparsePageAllocator; + friend DxvkSparsePageTable; public: DxvkSparseMapping(); @@ -165,8 +217,15 @@ namespace dxvk { ~DxvkSparseMapping(); - Rc getPage() const { - return m_page; + /** + * \brief Queries memory handle + * \returns Memory information + */ + DxvkSparsePageHandle getHandle() const { + if (m_page == nullptr) + return DxvkSparsePageHandle(); + + return m_page->getHandle(); } bool operator == (const DxvkSparseMapping& other) const { @@ -286,6 +345,18 @@ namespace dxvk { return m_buffer || m_image; } + /** + * \brief Queries buffer handle + * \returns Buffer handle + */ + VkBuffer getBufferHandle() const; + + /** + * \brief Queries image handle + * \returns Image handle + */ + VkImage getImageHandle() const; + /** * \brief Counts total number of pages in the resources * @@ -340,6 +411,48 @@ namespace dxvk { : DxvkSparsePageInfo(); } + /** + * \brief Computes page index within a given image region + * + * \param [in] subresource Subresource index + * \param [in] regionOffset Region offset, in pages + * \param [in] regionExtent Region extent, in pages + * \param [in] regionIsLinear Whether to use the region extent + * \param [in] pageIndex Page within the given region + * \returns Page index. The returned number may be out + * of bounds if the given region is invalid. + */ + uint32_t computePageIndex( + uint32_t subresource, + VkOffset3D regionOffset, + VkExtent3D regionExtent, + VkBool32 regionIsLinear, + uint32_t pageIndex) const; + + /** + * \brief Queries page mapping + * + * \param [in] page Page index + * \returns Current page mapping + */ + DxvkSparseMapping getMapping( + uint32_t page); + + /** + * \brief Changes a page mapping + * + * Updates the given page mapping in the table, and ensures + * that the previously mapped page does not get destroyed + * prematurely by tracking it in the given command list. + * \param [in] cmd Command list + * \param [in] page Page index + * \param [in] mapping New mapping + */ + void updateMapping( + DxvkCommandList* cmd, + uint32_t page, + DxvkSparseMapping&& mapping); + private: const DxvkBuffer* m_buffer = nullptr; From d3b6502a17efd1b06e0811eda22a9f5c772f30ca Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 20:15:46 +0200 Subject: [PATCH 0677/1348] [dxvk] Introduce DxvkSparseBindSubmission --- src/dxvk/dxvk_sparse.cpp | 328 +++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_sparse.h | 264 ++++++++++++++++++++++++++++++- 2 files changed, 591 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_sparse.cpp b/src/dxvk/dxvk_sparse.cpp index e521a49f1..c022b8063 100644 --- a/src/dxvk/dxvk_sparse.cpp +++ b/src/dxvk/dxvk_sparse.cpp @@ -1,3 +1,5 @@ +#include + #include "dxvk_buffer.h" #include "dxvk_device.h" #include "dxvk_image.h" @@ -396,4 +398,330 @@ namespace dxvk { } } + + DxvkSparseBindSubmission::DxvkSparseBindSubmission() { + + } + + + DxvkSparseBindSubmission::~DxvkSparseBindSubmission() { + + } + + + void DxvkSparseBindSubmission::waitSemaphore( + VkSemaphore semaphore, + uint64_t value) { + m_waitSemaphores.push_back(semaphore); + m_waitSemaphoreValues.push_back(value); + } + + + void DxvkSparseBindSubmission::signalSemaphore( + VkSemaphore semaphore, + uint64_t value) { + m_signalSemaphores.push_back(semaphore); + m_signalSemaphoreValues.push_back(value); + } + + + void DxvkSparseBindSubmission::bindBufferMemory( + const DxvkSparseBufferBindKey& key, + const DxvkSparsePageHandle& memory) { + m_bufferBinds.insert_or_assign(key, memory); + } + + + void DxvkSparseBindSubmission::bindImageMemory( + const DxvkSparseImageBindKey& key, + const DxvkSparsePageHandle& memory) { + m_imageBinds.insert_or_assign(key, memory); + } + + + void DxvkSparseBindSubmission::bindImageOpaqueMemory( + const DxvkSparseImageOpaqueBindKey& key, + const DxvkSparsePageHandle& memory) { + m_imageOpaqueBinds.insert_or_assign(key, memory); + } + + + VkResult DxvkSparseBindSubmission::submit( + DxvkDevice* device, + VkQueue queue) { + auto vk = device->vkd(); + + DxvkSparseBufferBindArrays buffer; + this->processBufferBinds(buffer); + + DxvkSparseImageBindArrays image; + this->processImageBinds(image); + + DxvkSparseImageOpaqueBindArrays opaque; + this->processOpaqueBinds(opaque); + + // The sparse binding API has never been updated to take the new + // semaphore submission info structs, so we have to do this instead + VkTimelineSemaphoreSubmitInfo timelineInfo = { VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO }; + timelineInfo.waitSemaphoreValueCount = m_waitSemaphoreValues.size(); + timelineInfo.pWaitSemaphoreValues = m_waitSemaphoreValues.data(); + timelineInfo.signalSemaphoreValueCount = m_signalSemaphoreValues.size(); + timelineInfo.pSignalSemaphoreValues = m_signalSemaphoreValues.data(); + + VkBindSparseInfo bindInfo = { VK_STRUCTURE_TYPE_BIND_SPARSE_INFO }; + + if (!m_waitSemaphores.empty()) { + bindInfo.pNext = &timelineInfo; + bindInfo.waitSemaphoreCount = m_waitSemaphores.size(); + bindInfo.pWaitSemaphores = m_waitSemaphores.data(); + } + + if (!buffer.infos.empty()) { + bindInfo.bufferBindCount = buffer.infos.size(); + bindInfo.pBufferBinds = buffer.infos.data(); + } + + if (!opaque.infos.empty()) { + bindInfo.imageOpaqueBindCount = opaque.infos.size(); + bindInfo.pImageOpaqueBinds = opaque.infos.data(); + } + + if (!image.infos.empty()) { + bindInfo.imageBindCount = image.infos.size(); + bindInfo.pImageBinds = image.infos.data(); + } + + if (!m_signalSemaphores.empty()) { + bindInfo.pNext = &timelineInfo; + bindInfo.signalSemaphoreCount = m_signalSemaphores.size(); + bindInfo.pSignalSemaphores = m_signalSemaphores.data(); + } + + VkResult vr = vk->vkQueueBindSparse(queue, 1, &bindInfo, VK_NULL_HANDLE); + + if (vr) { + Logger::err(str::format("Sparse binding failed: ", vr)); + this->logSparseBindingInfo(LogLevel::Error, &bindInfo); + } + + this->reset(); + return vr; + } + + + void DxvkSparseBindSubmission::reset() { + m_waitSemaphoreValues.clear(); + m_waitSemaphores.clear(); + m_signalSemaphoreValues.clear(); + m_signalSemaphores.clear(); + + m_bufferBinds.clear(); + m_imageBinds.clear(); + m_imageOpaqueBinds.clear(); + } + + + bool DxvkSparseBindSubmission::tryMergeMemoryBind( + VkSparseMemoryBind& oldBind, + const VkSparseMemoryBind& newBind) { + if (newBind.memory != oldBind.memory || newBind.flags != oldBind.flags) + return false; + + // The resource region must be consistent + if (newBind.resourceOffset != oldBind.resourceOffset + oldBind.size) + return false; + + // If memory is not null, the memory range must also be consistent + if (newBind.memory && newBind.memoryOffset != oldBind.memoryOffset + oldBind.size) + return false; + + oldBind.size += newBind.size; + return true; + } + + + void DxvkSparseBindSubmission::processBufferBinds( + DxvkSparseBufferBindArrays& buffer) { + std::vector> ranges; + ranges.reserve(m_bufferBinds.size()); + + for (const auto& e : m_bufferBinds) { + const auto& key = e.first; + const auto& handle = e.second; + + VkSparseMemoryBind bind = { }; + bind.resourceOffset = key.offset; + bind.size = key.size; + bind.memory = handle.memory; + bind.memoryOffset = handle.offset; + + bool merged = false; + + if (!ranges.empty() && ranges.back().first == key.buffer) + merged = tryMergeMemoryBind(ranges.back().second, bind); + + if (!merged) + ranges.push_back({ key.buffer, bind }); + } + + populateOutputArrays(buffer.binds, buffer.infos, ranges); + } + + + void DxvkSparseBindSubmission::processImageBinds( + DxvkSparseImageBindArrays& image) { + std::vector> ranges; + ranges.reserve(m_imageBinds.size()); + + for (const auto& e : m_imageBinds) { + const auto& key = e.first; + const auto& handle = e.second; + + VkSparseImageMemoryBind bind = { }; + bind.subresource = key.subresource; + bind.offset = key.offset; + bind.extent = key.extent; + bind.memory = handle.memory; + bind.memoryOffset = handle.offset; + + ranges.push_back({ key.image, bind }); + } + + populateOutputArrays(image.binds, image.infos, ranges); + } + + + void DxvkSparseBindSubmission::processOpaqueBinds( + DxvkSparseImageOpaqueBindArrays& opaque) { + std::vector> ranges; + ranges.reserve(m_imageOpaqueBinds.size()); + + for (const auto& e : m_imageOpaqueBinds) { + const auto& key = e.first; + const auto& handle = e.second; + + VkSparseMemoryBind bind = { }; + bind.resourceOffset = key.offset; + bind.size = key.size; + bind.memory = handle.memory; + bind.memoryOffset = handle.offset; + bind.flags = key.flags; + + bool merged = false; + + if (!ranges.empty() && ranges.back().first == key.image) + merged = tryMergeMemoryBind(ranges.back().second, bind); + + if (!merged) + ranges.push_back({ key.image, bind }); + } + + populateOutputArrays(opaque.binds, opaque.infos, ranges); + } + + + template + void DxvkSparseBindSubmission::populateOutputArrays( + std::vector& binds, + std::vector& infos, + const std::vector>& input) { + HandleType handle = VK_NULL_HANDLE; + + // Resize bind array so that pointers remain + // valid as we iterate over the input array + binds.resize(input.size()); + + for (size_t i = 0; i < input.size(); i++) { + binds[i] = input[i].second; + + if (handle != input[i].first) { + // Create new info entry if the handle + // differs from that of the previous entry + handle = input[i].first; + infos.push_back({ handle, 1u, &binds[i] }); + } else { + // Otherwise just increment the bind count + infos.back().bindCount += 1; + } + } + } + + + void DxvkSparseBindSubmission::logSparseBindingInfo( + LogLevel level, + const VkBindSparseInfo* info) { + std::stringstream str; + str << "VkBindSparseInfo:" << std::endl; + + auto timelineInfo = static_cast(info->pNext); + + if (info->waitSemaphoreCount) { + str << " Wait semaphores (" << std::dec << info->waitSemaphoreCount << "):" << std::endl; + + for (uint32_t i = 0; i < info->waitSemaphoreCount; i++) + str << " " << info->pWaitSemaphores[i] << " (" << timelineInfo->pWaitSemaphoreValues[i] << ")" << std::endl; + } + + if (info->bufferBindCount) { + str << " Buffer binds (" << std::dec << info->bufferBindCount << "):" << std::endl; + + for (uint32_t i = 0; i < info->bufferBindCount; i++) { + const auto* bindInfo = &info->pBufferBinds[i]; + str << " VkBuffer " << bindInfo->buffer << " (" << bindInfo->bindCount << "):" << std::endl; + + for (uint32_t j = 0; j < bindInfo->bindCount; j++) { + const auto* bind = &bindInfo->pBinds[j]; + str << " " << bind->resourceOffset << " -> " << bind->memory + << " (" << bind->memoryOffset << "," << bind->size << ")" << std::endl; + } + } + } + + if (info->imageOpaqueBindCount) { + str << " Opaque image binds (" << std::dec << info->imageOpaqueBindCount << "):" << std::endl; + + for (uint32_t i = 0; i < info->imageOpaqueBindCount; i++) { + const auto* bindInfo = &info->pImageOpaqueBinds[i]; + str << " VkImage " << bindInfo->image << " (" << bindInfo->bindCount << "):" << std::endl; + + for (uint32_t j = 0; j < bindInfo->bindCount; j++) { + const auto* bind = &bindInfo->pBinds[j]; + str << " " << bind->resourceOffset << " -> " << bind->memory + << " (" << bind->memoryOffset << "," << bind->size << ")" << std::endl; + } + } + } + + if (info->imageBindCount) { + str << " Opaque image binds (" << std::dec << info->imageOpaqueBindCount << "):" << std::endl; + + for (uint32_t i = 0; i < info->imageBindCount; i++) { + const auto* bindInfo = &info->pImageBinds[i]; + str << " VkImage " << bindInfo->image << " (" << bindInfo->bindCount << "):" << std::endl; + + for (uint32_t j = 0; j < bindInfo->bindCount; j++) { + const auto* bind = &bindInfo->pBinds[j]; + + str << " Aspect 0x" << std::hex << bind->subresource.aspectMask + << ", Mip " << std::dec << bind->subresource.mipLevel + << ", Layer " << bind->subresource.arrayLayer + << ":" << std::endl; + + str << " " << bind->offset.x << "," << bind->offset.y << "," << bind->offset.z << ":" + << bind->extent.width << "x" << bind->extent.height << "x" << bind->extent.depth + << " -> " << bind->memory << " (" << bind->memoryOffset << ")" << std::endl; + } + } + } + + if (info->signalSemaphoreCount) { + str << " Signal semaphores (" << std::dec << info->signalSemaphoreCount << "):" << std::endl; + + for (uint32_t i = 0; i < info->signalSemaphoreCount; i++) + str << " " << info->pSignalSemaphores[i] << " (" << timelineInfo->pSignalSemaphoreValues[i] << ")" << std::endl; + } + + Logger::log(level, str.str()); + } + } diff --git a/src/dxvk/dxvk_sparse.h b/src/dxvk/dxvk_sparse.h index f68aeb06a..158a2b5a7 100644 --- a/src/dxvk/dxvk_sparse.h +++ b/src/dxvk/dxvk_sparse.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "dxvk_memory.h" #include "dxvk_resource.h" @@ -492,4 +494,264 @@ namespace dxvk { }; -} \ No newline at end of file + + /** + * \brief Key for sparse buffer binding entry + * + * Provides a strong ordering by resource, resource offset, + * and finally, size. The ordering can be used to easily + * merge adjacent ranges. + */ + struct DxvkSparseBufferBindKey { + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; + + bool operator < (const DxvkSparseBufferBindKey& other) const { + if (buffer < other.buffer) return true; + if (buffer > other.buffer) return false; + + if (offset < other.offset) return true; + if (offset > other.offset) return false; + + return size < other.size; + } + }; + + + /** + * \brief Key for sparse image binding entry + * + * Provides a strong ordering by resource, subresource, + * offset (z -> y -> x), and finally, extent (d -> h -> w). + * The ordering can be used to easily merge adjacent regions. + */ + struct DxvkSparseImageBindKey { + VkImage image; + VkImageSubresource subresource; + VkOffset3D offset; + VkExtent3D extent; + + bool operator < (const DxvkSparseImageBindKey& other) const { + if (image < other.image) return true; + if (image > other.image) return false; + + uint64_t aSubresource = this->encodeSubresource(); + uint64_t bSubresource = other.encodeSubresource(); + + if (aSubresource < bSubresource) return true; + if (aSubresource > bSubresource) return false; + + uint64_t aOffset = this->encodeOffset(); + uint64_t bOffset = other.encodeOffset(); + + if (aOffset < bOffset) return true; + if (aOffset > bOffset) return false; + + uint64_t aExtent = this->encodeExtent(); + uint64_t bExtent = other.encodeExtent(); + + return aExtent < bExtent; + } + + uint64_t encodeSubresource() const { + return uint64_t(subresource.aspectMask) << 48 + | uint64_t(subresource.arrayLayer) << 24 + | uint64_t(subresource.mipLevel); + } + + uint64_t encodeOffset() const { + return uint64_t(offset.z) << 48 + | uint64_t(offset.y) << 24 + | uint64_t(offset.x); + } + + uint64_t encodeExtent() const { + return uint64_t(extent.depth) << 48 + | uint64_t(extent.height) << 24 + | uint64_t(extent.width); + } + }; + + + /** + * \brief Key for sparse opaque image binding entry + * + * Provides a strong ordering by resource, resource offset, + * and finally, size. The ordering can be used to easily + * merge adjacent ranges. + */ + struct DxvkSparseImageOpaqueBindKey { + VkImage image; + VkDeviceSize offset; + VkDeviceSize size; + VkSparseMemoryBindFlags flags; + + bool operator < (const DxvkSparseImageOpaqueBindKey& other) const { + if (image < other.image) return true; + if (image > other.image) return false; + + if (offset < other.offset) return true; + if (offset > other.offset) return false; + + return size < other.size; + } + }; + + + /** + * \brief Arrays required for buffer binds + */ + struct DxvkSparseBufferBindArrays { + std::vector binds; + std::vector infos; + }; + + + /** + * \brief Arrays required for image binds + */ + struct DxvkSparseImageBindArrays { + std::vector binds; + std::vector infos; + }; + + + /** + * \brief Arrays required for opaque image binds + */ + struct DxvkSparseImageOpaqueBindArrays { + std::vector binds; + std::vector infos; + }; + + + /** + * \brief Sparse bind submission + * + * Stores information for a single sparse binding operation, + * and supports submitting that operation to a device queue. + * + * All methods to add bindings assume that the binding range is + * either identical to an existing range, in which case the old + * binding will be overwritten, or otherwise, that the range is + * disjoint from all existing ranges. Overlapping ranges are not + * supported. This condition is trivial to maintain when binding + * only one sparse page at a time. + */ + class DxvkSparseBindSubmission { + + public: + + DxvkSparseBindSubmission(); + + ~DxvkSparseBindSubmission(); + + /** + * \brief Waits for a semaphore + * + * \param [in] semaphore Semaphore to wait for + * \param [in] value Semaphore value to wait on + */ + void waitSemaphore( + VkSemaphore semaphore, + uint64_t value); + + /** + * \brief Signals a semaphore + * + * \param [in] semaphore Semaphore to signal + * \param [in] value Calue to signal semaphore to + */ + void signalSemaphore( + VkSemaphore semaphore, + uint64_t value); + + /** + * \brief Adds a buffer memory bind + * + * \param [in] key Buffer range key + * \param [in] memory Page handle + */ + void bindBufferMemory( + const DxvkSparseBufferBindKey& key, + const DxvkSparsePageHandle& memory); + + /** + * \brief Adds an image memory bind + * + * \param [in] key Image region key + * \param [in] memory Page handle + */ + void bindImageMemory( + const DxvkSparseImageBindKey& key, + const DxvkSparsePageHandle& memory); + + /** + * \brief Adds an opaque image memory bind + * + * \param [in] key Opaque region key + * \param [in] memory Page handle + */ + void bindImageOpaqueMemory( + const DxvkSparseImageOpaqueBindKey& key, + const DxvkSparsePageHandle& memory); + + /** + * \brief Submits sparse binding operation + * + * Generates structures required for the sparse bind, resolving + * any conflicts in the process and merging ranges where possible. + * Note that this operation is slow. Resets object after the call. + * \param [in] device DXVK device + * \param [in] queue Queue to perform the operation on + * \returns Return value of the sparse bind operation + */ + VkResult submit( + DxvkDevice* device, + VkQueue queue); + + /** + * \brief Resets object + * + * Clears all internal structures. + */ + void reset(); + + private: + + std::vector m_waitSemaphoreValues; + std::vector m_waitSemaphores; + std::vector m_signalSemaphoreValues; + std::vector m_signalSemaphores; + + std::map m_bufferBinds; + std::map m_imageBinds; + std::map m_imageOpaqueBinds; + + static bool tryMergeMemoryBind( + VkSparseMemoryBind& oldBind, + const VkSparseMemoryBind& newBind); + + void processBufferBinds( + DxvkSparseBufferBindArrays& buffer); + + void processImageBinds( + DxvkSparseImageBindArrays& image); + + void processOpaqueBinds( + DxvkSparseImageOpaqueBindArrays& opaque); + + template + void populateOutputArrays( + std::vector& binds, + std::vector& infos, + const std::vector>& input); + + void logSparseBindingInfo( + LogLevel level, + const VkBindSparseInfo* info); + + }; + +} From 2615af7664c332cf8a8f395604b77ca1cc9a7bc7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 20:55:53 +0200 Subject: [PATCH 0678/1348] [dxvk] Submit sparse binding operations alongside command buffers --- src/dxvk/dxvk_cmdlist.cpp | 35 ++++++++++++++++++++++++++++++++--- src/dxvk/dxvk_cmdlist.h | 4 ++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index bf979715d..2026a9162 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -194,6 +194,7 @@ namespace dxvk { const auto& graphics = m_device->queues().graphics; const auto& transfer = m_device->queues().transfer; + const auto& sparse = m_device->queues().sparse; m_commandSubmission.reset(); @@ -203,15 +204,41 @@ namespace dxvk { const auto& cmd = m_cmdSubmissions[i]; + auto sparseBind = cmd.sparseBind + ? &m_cmdSparseBinds[cmd.sparseCmd] + : nullptr; + + if (sparseBind) { + // Sparse bindig needs to serialize command execution, so wait + // for any prior submissions, then block any subsequent ones + sparseBind->waitSemaphore(semaphore, semaphoreValue); + sparseBind->signalSemaphore(semaphore, ++semaphoreValue); + + m_commandSubmission.waitSemaphore(semaphore, semaphoreValue, + VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); + } + if (isFirst) { // Wait for per-command list semaphores on first submission for (const auto& entry : m_waitSemaphores) { - m_commandSubmission.waitSemaphore( - entry.fence->handle(), - entry.value, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); + if (sparseBind) { + sparseBind->waitSemaphore( + entry.fence->handle(), + entry.value); + } else { + m_commandSubmission.waitSemaphore( + entry.fence->handle(), + entry.value, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); + } } } + // Execute sparse bind + if (sparseBind) { + if ((status = sparseBind->submit(m_device, sparse.queueHandle))) + return status; + } + // Submit transfer commands as necessary if (cmd.usedFlags.test(DxvkCmdBuffer::SdmaBuffer)) m_commandSubmission.executeCommandBuffer(cmd.sdmaBuffer); @@ -353,7 +380,9 @@ namespace dxvk { m_waitSemaphores.clear(); m_signalSemaphores.clear(); + m_cmdSubmissions.clear(); + m_cmdSparseBinds.clear(); m_wsiSemaphores = vk::PresenterSync(); diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 7d41777f2..6188b5c48 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -15,6 +15,7 @@ #include "dxvk_limits.h" #include "dxvk_pipelayout.h" #include "dxvk_signal.h" +#include "dxvk_sparse.h" #include "dxvk_staging.h" #include "dxvk_stats.h" @@ -122,6 +123,8 @@ namespace dxvk { VkCommandBuffer execBuffer = VK_NULL_HANDLE; VkCommandBuffer initBuffer = VK_NULL_HANDLE; VkCommandBuffer sdmaBuffer = VK_NULL_HANDLE; + VkBool32 sparseBind = VK_FALSE; + uint32_t sparseCmd = 0; }; @@ -990,6 +993,7 @@ namespace dxvk { std::vector m_signalSemaphores; std::vector m_cmdSubmissions; + std::vector m_cmdSparseBinds; std::vector, From 12d2f8a9d4442132fb2fcf00e190a901dab7d1a3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 21:02:29 +0200 Subject: [PATCH 0679/1348] [dxvk] Expose sparse binding operations as part of the command list --- src/dxvk/dxvk_cmdlist.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 6188b5c48..fc096b016 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -958,6 +958,27 @@ namespace dxvk { } + void bindBufferMemory( + const DxvkSparseBufferBindKey& key, + const DxvkSparsePageHandle& memory) { + getSparseBindSubmission().bindBufferMemory(key, memory); + } + + + void bindImageMemory( + const DxvkSparseImageBindKey& key, + const DxvkSparsePageHandle& memory) { + getSparseBindSubmission().bindImageMemory(key, memory); + } + + + void bindImageOpaqueMemory( + const DxvkSparseImageOpaqueBindKey& key, + const DxvkSparsePageHandle& memory) { + getSparseBindSubmission().bindImageOpaqueMemory(key, memory); + } + + void trackDescriptorPool( const Rc& pool, const Rc& manager) { @@ -1008,6 +1029,16 @@ namespace dxvk { return VK_NULL_HANDLE; } + DxvkSparseBindSubmission& getSparseBindSubmission() { + if (likely(m_cmd.sparseBind)) + return m_cmdSparseBinds[m_cmd.sparseCmd]; + + m_cmd.sparseBind = VK_TRUE; + m_cmd.sparseCmd = uint32_t(m_cmdSparseBinds.size()); + + return m_cmdSparseBinds.emplace_back(); + } + void endCommandBuffer(VkCommandBuffer cmdBuffer); }; From d5348a0cf083189fa8ee34f9a22102d6dbfda0ac Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 15:51:24 +0200 Subject: [PATCH 0680/1348] [dxvk] Introduce updatePageTable --- src/dxvk/dxvk_context.cpp | 91 +++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_context.h | 13 +++++- 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index c2ab3b5b8..2fda77b7c 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2460,6 +2460,97 @@ namespace dxvk { } + void DxvkContext::updatePageTable( + const DxvkSparseBindInfo& bindInfo, + DxvkSparseBindFlags flags) { + // Split command buffers here so that we execute + // the sparse binding operation at the right time + if (!flags.test(DxvkSparseBindFlag::SkipSynchronization)) + this->splitCommands(); + + DxvkSparsePageAllocator* srcAllocator = bindInfo.srcAllocator.ptr(); + DxvkSparsePageTable* dstPageTable = bindInfo.dstResource->getSparsePageTable(); + DxvkSparsePageTable* srcPageTable = nullptr; + + if (bindInfo.srcResource != nullptr) + srcPageTable = bindInfo.srcResource->getSparsePageTable(); + + // In order to support copies properly, we need to buffer the new + // mappings first before we apply them to the destination resource. + size_t bindCount = bindInfo.binds.size(); + std::vector mappings(bindCount); + + for (size_t i = 0; i < bindCount; i++) { + DxvkSparseBind bind = bindInfo.binds[i]; + + switch (bind.mode) { + case DxvkSparseBindMode::Null: + // The mapping array is already default-initialized + // so we don't actually need to do anything here + break; + + case DxvkSparseBindMode::Bind: + mappings[i] = srcAllocator->acquirePage(bind.srcPage); + break; + + case DxvkSparseBindMode::Copy: + mappings[i] = srcPageTable->getMapping(bind.srcPage); + break; + } + } + + // Process the actual page table updates here and resolve + // our internal structures to Vulkan resource and memory + // handles. The rest will be done at submission time. + for (size_t i = 0; i < bindCount; i++) { + DxvkSparseBind bind = bindInfo.binds[i]; + DxvkSparseMapping mapping = std::move(mappings[i]); + + DxvkSparsePageInfo pageInfo = dstPageTable->getPageInfo(bind.dstPage); + + switch (pageInfo.type) { + case DxvkSparsePageType::None: + break; + + case DxvkSparsePageType::Buffer: { + DxvkSparseBufferBindKey key; + key.buffer = dstPageTable->getBufferHandle(); + key.offset = pageInfo.buffer.offset; + key.size = pageInfo.buffer.length; + + m_cmd->bindBufferMemory(key, mapping.getHandle()); + } break; + + case DxvkSparsePageType::Image: { + DxvkSparseImageBindKey key; + key.image = dstPageTable->getImageHandle(); + key.subresource = pageInfo.image.subresource; + key.offset = pageInfo.image.offset; + key.extent = pageInfo.image.extent; + + m_cmd->bindImageMemory(key, mapping.getHandle()); + } break; + + case DxvkSparsePageType::ImageMipTail: { + DxvkSparseImageOpaqueBindKey key; + key.image = dstPageTable->getImageHandle(); + key.offset = pageInfo.mipTail.resourceOffset; + key.size = pageInfo.mipTail.resourceLength; + key.flags = 0; + + m_cmd->bindImageOpaqueMemory(key, mapping.getHandle()); + } break; + } + + // Update the page table mapping for tracking purposes + if (pageInfo.type != DxvkSparsePageType::None) + dstPageTable->updateMapping(m_cmd.ptr(), bind.dstPage, std::move(mapping)); + } + + m_cmd->trackResource(bindInfo.dstResource); + } + + void DxvkContext::signalGpuEvent(const Rc& event) { this->spillRenderPass(true); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index d18c7e5f0..952f1aae6 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1170,7 +1170,18 @@ namespace dxvk { */ void setBarrierControl( DxvkBarrierControlFlags control); - + + /** + * \brief Updates page table for a given sparse resource + * + * Note that this is a very high overhead operation. + * \param [in] bindInfo Sparse bind info + * \param [in] flags Sparse bind flags + */ + void updatePageTable( + const DxvkSparseBindInfo& bindInfo, + DxvkSparseBindFlags flags); + /** * \brief Launches a Cuda kernel * From fc0d952edb59655b12fd6cadefe24c6bb86796ab Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 25 Aug 2022 05:37:47 +0200 Subject: [PATCH 0681/1348] [dxvk] Introduce copySparsePages{To,From}Buffer --- src/dxvk/dxvk_context.cpp | 206 ++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_context.h | 58 ++++++++++- 2 files changed, 263 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 2fda77b7c..cd804b498 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1168,6 +1168,30 @@ namespace dxvk { } + void DxvkContext::copySparsePagesToBuffer( + const Rc& dstBuffer, + VkDeviceSize dstOffset, + const Rc& srcResource, + uint32_t pageCount, + const uint32_t* pages) { + this->copySparsePages( + srcResource, pageCount, pages, + dstBuffer, dstOffset); + } + + + void DxvkContext::copySparsePagesFromBuffer( + const Rc& dstResource, + uint32_t pageCount, + const uint32_t* pages, + const Rc& srcBuffer, + VkDeviceSize srcOffset) { + this->copySparsePages( + dstResource, pageCount, pages, + srcBuffer, srcOffset); + } + + void DxvkContext::discardBuffer( const Rc& buffer) { if ((buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) @@ -3723,6 +3747,188 @@ namespace dxvk { } + template + void DxvkContext::copySparsePages( + const Rc& sparse, + uint32_t pageCount, + const uint32_t* pages, + const Rc& buffer, + VkDeviceSize offset) { + auto pageTable = sparse->getSparsePageTable(); + auto bufferHandle = buffer->getSliceHandle(offset, SparseMemoryPageSize * pageCount); + + if (m_execBarriers.isBufferDirty(bufferHandle, + ToBuffer ? DxvkAccess::Write : DxvkAccess::Read)) + m_execBarriers.recordCommands(m_cmd); + + if (pageTable->getBufferHandle()) { + this->copySparseBufferPages( + static_cast(sparse.ptr()), + pageCount, pages, buffer, offset); + } else { + this->copySparseImagePages( + static_cast(sparse.ptr()), + pageCount, pages, buffer, offset); + } + } + + + template + void DxvkContext::copySparseBufferPages( + const Rc& sparse, + uint32_t pageCount, + const uint32_t* pages, + const Rc& buffer, + VkDeviceSize offset) { + std::vector regions; + regions.reserve(pageCount); + + auto pageTable = sparse->getSparsePageTable(); + + auto sparseHandle = sparse->getSliceHandle(); + auto bufferHandle = buffer->getSliceHandle(offset, SparseMemoryPageSize * pageCount); + + if (m_execBarriers.isBufferDirty(sparseHandle, + ToBuffer ? DxvkAccess::Read : DxvkAccess::Write)) + m_execBarriers.recordCommands(m_cmd); + + for (uint32_t i = 0; i < pageCount; i++) { + auto pageInfo = pageTable->getPageInfo(pages[i]); + + if (pageInfo.type == DxvkSparsePageType::Buffer) { + VkDeviceSize sparseOffset = pageInfo.buffer.offset; + VkDeviceSize bufferOffset = bufferHandle.offset + SparseMemoryPageSize * i; + + VkBufferCopy2 copy = { VK_STRUCTURE_TYPE_BUFFER_COPY_2 }; + copy.srcOffset = ToBuffer ? sparseOffset : bufferOffset; + copy.dstOffset = ToBuffer ? bufferOffset : sparseOffset; + copy.size = pageInfo.buffer.length; + + regions.push_back(copy); + } + } + + VkCopyBufferInfo2 info = { VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 }; + info.srcBuffer = ToBuffer ? sparseHandle.handle : bufferHandle.handle; + info.dstBuffer = ToBuffer ? bufferHandle.handle : sparseHandle.handle; + info.regionCount = uint32_t(regions.size()); + info.pRegions = regions.data(); + + if (info.regionCount) + m_cmd->cmdCopyBuffer(DxvkCmdBuffer::ExecBuffer, &info); + + m_execBarriers.accessBuffer(sparseHandle, + VK_PIPELINE_STAGE_TRANSFER_BIT, + ToBuffer ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_TRANSFER_WRITE_BIT, + sparse->info().stages, + sparse->info().access); + + m_execBarriers.accessBuffer(bufferHandle, + VK_PIPELINE_STAGE_TRANSFER_BIT, + ToBuffer ? VK_ACCESS_TRANSFER_WRITE_BIT : VK_ACCESS_TRANSFER_READ_BIT, + buffer->info().stages, + buffer->info().access); + + m_cmd->trackResource(sparse); + m_cmd->trackResource(buffer); + } + + + template + void DxvkContext::copySparseImagePages( + const Rc& sparse, + uint32_t pageCount, + const uint32_t* pages, + const Rc& buffer, + VkDeviceSize offset) { + std::vector regions; + regions.reserve(pageCount); + + auto pageTable = sparse->getSparsePageTable(); + auto pageExtent = pageTable->getProperties().pageRegionExtent; + + auto bufferHandle = buffer->getSliceHandle(offset, SparseMemoryPageSize * pageCount); + auto sparseSubresources = sparse->getAvailableSubresources(); + + if (m_execBarriers.isImageDirty(sparse, sparseSubresources, DxvkAccess::Write)) + m_execBarriers.recordCommands(m_cmd); + + VkImageLayout transferLayout = sparse->pickLayout(ToBuffer + ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL + : VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + VkAccessFlags transferAccess = ToBuffer + ? VK_ACCESS_TRANSFER_READ_BIT + : VK_ACCESS_TRANSFER_WRITE_BIT; + + if (sparse->info().layout != transferLayout) { + m_execAcquires.accessImage(sparse, sparseSubresources, + sparse->info().layout, + sparse->info().stages, 0, + transferLayout, + VK_PIPELINE_STAGE_TRANSFER_BIT, + transferAccess); + + m_execAcquires.recordCommands(m_cmd); + } + + for (uint32_t i = 0; i < pageCount; i++) { + auto pageInfo = pageTable->getPageInfo(pages[i]); + + if (pageInfo.type == DxvkSparsePageType::Image) { + VkBufferImageCopy2 copy = { VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 }; + copy.bufferOffset = bufferHandle.offset + SparseMemoryPageSize * i; + copy.bufferRowLength = pageExtent.width; + copy.bufferImageHeight = pageExtent.height; + copy.imageSubresource = vk::makeSubresourceLayers(pageInfo.image.subresource); + copy.imageOffset = pageInfo.image.offset; + copy.imageExtent = pageInfo.image.extent; + + regions.push_back(copy); + } + } + + if (ToBuffer) { + VkCopyImageToBufferInfo2 info = { VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2 }; + info.srcImage = sparse->handle(); + info.srcImageLayout = transferLayout; + info.dstBuffer = bufferHandle.handle; + info.regionCount = regions.size(); + info.pRegions = regions.data(); + + if (info.regionCount) + m_cmd->cmdCopyImageToBuffer(DxvkCmdBuffer::ExecBuffer, &info); + } else { + VkCopyBufferToImageInfo2 info = { VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 }; + info.srcBuffer = bufferHandle.handle; + info.dstImage = sparse->handle(); + info.dstImageLayout = transferLayout; + info.regionCount = regions.size(); + info.pRegions = regions.data(); + + if (info.regionCount) + m_cmd->cmdCopyBufferToImage(DxvkCmdBuffer::ExecBuffer, &info); + } + + m_execAcquires.accessImage(sparse, sparseSubresources, + transferLayout, + VK_PIPELINE_STAGE_TRANSFER_BIT, + transferAccess, + sparse->info().layout, + sparse->info().stages, + sparse->info().access); + + m_execBarriers.accessBuffer(bufferHandle, + VK_PIPELINE_STAGE_TRANSFER_BIT, + ToBuffer ? VK_ACCESS_TRANSFER_WRITE_BIT : VK_ACCESS_TRANSFER_READ_BIT, + buffer->info().stages, + buffer->info().access); + + m_cmd->trackResource(sparse); + m_cmd->trackResource(buffer); + } + + void DxvkContext::resolveImageHw( const Rc& dstImage, const Rc& srcImage, diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 952f1aae6..b9ec506cd 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -669,7 +669,39 @@ namespace dxvk { VkOffset2D srcOffset, VkExtent2D srcExtent, VkFormat format); - + + /** + * \brief Copies pages from a sparse resource to a buffer + * + * \param [in] dstBuffer Buffer to write to + * \param [in] dstOffset Buffer offset + * \param [in] srcResource Source resource + * \param [in] pageCount Number of pages to copy + * \param [in] pages Page indices to copy + */ + void copySparsePagesToBuffer( + const Rc& dstBuffer, + VkDeviceSize dstOffset, + const Rc& srcResource, + uint32_t pageCount, + const uint32_t* pages); + + /** + * \brief Copies pages from a buffer to a sparse resource + * + * \param [in] dstResource Resource to write to + * \param [in] pageCount Number of pages to copy + * \param [in] pages Page indices to copy + * \param [in] srcBuffer Source buffer + * \param [in] srcOffset Buffer offset + */ + void copySparsePagesFromBuffer( + const Rc& dstResource, + uint32_t pageCount, + const uint32_t* pages, + const Rc& srcBuffer, + VkDeviceSize srcOffset); + /** * \brief Discards a buffer * @@ -1422,6 +1454,30 @@ namespace dxvk { const Rc& srcImage, VkImageSubresourceLayers srcSubresource); + template + void copySparsePages( + const Rc& sparse, + uint32_t pageCount, + const uint32_t* pages, + const Rc& buffer, + VkDeviceSize offset); + + template + void copySparseBufferPages( + const Rc& sparse, + uint32_t pageCount, + const uint32_t* pages, + const Rc& buffer, + VkDeviceSize offset); + + template + void copySparseImagePages( + const Rc& sparse, + uint32_t pageCount, + const uint32_t* pages, + const Rc& buffer, + VkDeviceSize offset); + void resolveImageHw( const Rc& dstImage, const Rc& srcImage, From 43b19f773c652eb5c4ee346e3c2c2f9b424e731e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 25 Aug 2022 21:15:14 +0200 Subject: [PATCH 0682/1348] [dxvk] Introduce initSparseImage --- src/dxvk/dxvk_context.cpp | 54 +++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_context.h | 12 ++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index cd804b498..c6ceda9db 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1523,6 +1523,60 @@ namespace dxvk { } + void DxvkContext::initSparseImage( + const Rc& image) { + auto vk = m_device->vkd(); + + // Query sparse memory requirements + uint32_t reqCount = 0; + vk->vkGetImageSparseMemoryRequirements(vk->device(), image->handle(), &reqCount, nullptr); + + std::vector req(reqCount); + vk->vkGetImageSparseMemoryRequirements(vk->device(), image->handle(), &reqCount, req.data()); + + // Bind metadata aspects. Since the image was just created, + // we do not need to interrupt our command list for that. + VkDeviceMemory imageMemory = image->memory().memory(); + VkDeviceSize imageOffset = image->memory().offset(); + + for (const auto& r : req) { + if (!(r.formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)) + continue; + + uint32_t layerCount = (r.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT) + ? 1u : image->info().numLayers; + + for (uint32_t i = 0; i < layerCount; i++) { + DxvkSparseImageOpaqueBindKey key; + key.image = image->handle(); + key.offset = r.imageMipTailOffset + i * r.imageMipTailStride; + key.size = r.imageMipTailSize; + key.flags = VK_SPARSE_MEMORY_BIND_METADATA_BIT; + + DxvkSparsePageHandle page; + page.memory = imageMemory; + page.offset = imageOffset; + page.length = r.imageMipTailSize; + + m_cmd->bindImageOpaqueMemory(key, page); + + imageOffset += r.imageMipTailSize; + } + } + + // Perform initial layout transition + m_initBarriers.accessImage(image, + image->getAvailableSubresources(), + VK_IMAGE_LAYOUT_UNDEFINED, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, + image->info().layout, + image->info().stages, + image->info().access); + + m_cmd->trackResource(image); + } + + void DxvkContext::emitGraphicsBarrier( VkPipelineStageFlags srcStages, VkAccessFlags srcAccess, diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index b9ec506cd..aa42ef79f 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -905,7 +905,17 @@ namespace dxvk { const Rc& image, const VkImageSubresourceRange& subresources, VkImageLayout initialLayout); - + + /** + * \brief Initializes sparse image + * + * Binds any metadata aspects that the image might + * have, and performs the initial layout transition. + * \param [in] image Image to initialize + */ + void initSparseImage( + const Rc& image); + /** * \brief Invalidates a buffer's contents * From 2329c71b6fad69c5edbf66e8de3e9427b1757520 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 25 Aug 2022 16:05:15 +0200 Subject: [PATCH 0683/1348] [dxvk] Implement sampler reduction mode --- src/d3d11/d3d11_sampler.cpp | 2 ++ src/d3d11/d3d11_video.cpp | 1 + src/d3d9/d3d9_device.cpp | 1 + src/dxvk/dxvk_sampler.cpp | 6 ++++++ src/dxvk/dxvk_sampler.h | 5 ++++- src/dxvk/dxvk_swapchain_blitter.cpp | 1 + src/dxvk/dxvk_unbound.cpp | 1 + src/dxvk/hud/dxvk_hud_renderer.cpp | 1 + 8 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_sampler.cpp b/src/d3d11/d3d11_sampler.cpp index 8150c29c3..335717766 100644 --- a/src/d3d11/d3d11_sampler.cpp +++ b/src/d3d11/d3d11_sampler.cpp @@ -34,6 +34,8 @@ namespace dxvk { info.compareToDepth = (filterBits & 0x80) ? VK_TRUE : VK_FALSE; info.compareOp = DecodeCompareOp(desc.ComparisonFunc); + info.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; + for (uint32_t i = 0; i < 4; i++) info.borderColor.float32[i] = desc.BorderColor[i]; diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index d3422466f..8635f63d6 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -362,6 +362,7 @@ namespace dxvk { samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samplerInfo.compareToDepth = VK_FALSE; samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; + samplerInfo.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; samplerInfo.borderColor = VkClearColorValue(); samplerInfo.usePixelCoord = VK_FALSE; samplerInfo.nonSeamless = VK_FALSE; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index bbb6c3a73..54b1ab10b 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5978,6 +5978,7 @@ namespace dxvk { info.mipmapLodBias = cKey.MipmapLodBias; info.mipmapLodMin = mipFilter.MipsEnabled ? float(cKey.MaxMipLevel) : 0; info.mipmapLodMax = mipFilter.MipsEnabled ? FLT_MAX : 0; + info.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; info.usePixelCoord = VK_FALSE; info.nonSeamless = m_dxvkDevice->features().extNonSeamlessCubeMap.nonSeamlessCubeMap && !m_d3d9Options.seamlessCubes; diff --git a/src/dxvk/dxvk_sampler.cpp b/src/dxvk/dxvk_sampler.cpp index 00d926555..49a35f47e 100644 --- a/src/dxvk/dxvk_sampler.cpp +++ b/src/dxvk/dxvk_sampler.cpp @@ -10,6 +10,9 @@ namespace dxvk { VkSamplerCustomBorderColorCreateInfoEXT borderColorInfo = { VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT }; borderColorInfo.customBorderColor = info.borderColor; + VkSamplerReductionModeCreateInfo reductionInfo = { VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO }; + reductionInfo.reductionMode = info.reductionMode; + VkSamplerCreateInfo samplerInfo = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; samplerInfo.flags = info.nonSeamless ? VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT : 0; samplerInfo.magFilter = info.magFilter; @@ -39,6 +42,9 @@ namespace dxvk { if (samplerInfo.borderColor == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT) borderColorInfo.pNext = std::exchange(samplerInfo.pNext, &borderColorInfo); + if (reductionInfo.reductionMode != VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE) + reductionInfo.pNext = std::exchange(samplerInfo.pNext, &reductionInfo); + if (m_vkd->vkCreateSampler(m_vkd->device(), &samplerInfo, nullptr, &m_sampler) != VK_SUCCESS) throw DxvkError("DxvkSampler::DxvkSampler: Failed to create sampler"); diff --git a/src/dxvk/dxvk_sampler.h b/src/dxvk/dxvk_sampler.h index e2e421b35..61d64a076 100644 --- a/src/dxvk/dxvk_sampler.h +++ b/src/dxvk/dxvk_sampler.h @@ -33,9 +33,12 @@ namespace dxvk { VkBool32 compareToDepth; VkCompareOp compareOp; + /// Reduction mode for min/max samplers + VkSamplerReductionMode reductionMode; + /// Texture border color VkClearColorValue borderColor; - + /// Enables unnormalized coordinates VkBool32 usePixelCoord; diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index 846dd8916..d1c03a7f5 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -301,6 +301,7 @@ namespace dxvk { samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; samplerInfo.compareToDepth = VK_FALSE; samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; + samplerInfo.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; samplerInfo.borderColor = VkClearColorValue(); samplerInfo.usePixelCoord = VK_TRUE; samplerInfo.nonSeamless = VK_FALSE; diff --git a/src/dxvk/dxvk_unbound.cpp b/src/dxvk/dxvk_unbound.cpp index 39f390ce8..a06eafe98 100644 --- a/src/dxvk/dxvk_unbound.cpp +++ b/src/dxvk/dxvk_unbound.cpp @@ -29,6 +29,7 @@ namespace dxvk { info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; info.compareToDepth = VK_FALSE; info.compareOp = VK_COMPARE_OP_NEVER; + info.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; info.borderColor = VkClearColorValue(); info.usePixelCoord = VK_FALSE; info.nonSeamless = VK_FALSE; diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index 893d6d346..b797d68e3 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -309,6 +309,7 @@ namespace dxvk::hud { info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; info.compareToDepth = VK_FALSE; info.compareOp = VK_COMPARE_OP_NEVER; + info.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; info.borderColor = VkClearColorValue(); info.usePixelCoord = VK_TRUE; info.nonSeamless = VK_FALSE; From 70158fa9cf9a9c1b036158012e7e984a1a430c56 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 02:54:45 +0200 Subject: [PATCH 0684/1348] [spirv] Add support for sparse image opcodes --- src/spirv/spirv_module.cpp | 100 +++++++++++++++++++++++++++---------- src/spirv/spirv_module.h | 7 ++- 2 files changed, 81 insertions(+), 26 deletions(-) diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index d59f87f08..75fef45e8 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -3082,8 +3082,11 @@ namespace dxvk { const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns (spv::OpImageRead, - 5 + getImageOperandWordCount(operands)); + spv::Op op = operands.sparse + ? spv::OpImageSparseRead + : spv::OpImageRead; + + m_code.putIns(op, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(image); @@ -3109,6 +3112,20 @@ namespace dxvk { } + uint32_t SpirvModule::opImageSparseTexelsResident( + uint32_t resultType, + uint32_t residentCode) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpImageSparseTexelsResident, 4); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(residentCode); + + return resultId; + } + + uint32_t SpirvModule::opSampledImage( uint32_t resultType, uint32_t image, @@ -3216,9 +3233,12 @@ namespace dxvk { uint32_t coordinates, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - - m_code.putIns(spv::OpImageFetch, - 5 + getImageOperandWordCount(operands)); + + spv::Op op = operands.sparse + ? spv::OpImageSparseFetch + : spv::OpImageFetch; + + m_code.putIns(op, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(image); @@ -3237,8 +3257,11 @@ namespace dxvk { const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns(spv::OpImageGather, - 6 + getImageOperandWordCount(operands)); + spv::Op op = operands.sparse + ? spv::OpImageSparseGather + : spv::OpImageGather; + + m_code.putIns(op, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); @@ -3258,8 +3281,11 @@ namespace dxvk { const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns(spv::OpImageDrefGather, - 6 + getImageOperandWordCount(operands)); + spv::Op op = operands.sparse + ? spv::OpImageSparseDrefGather + : spv::OpImageDrefGather; + + m_code.putIns(op, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); @@ -3278,8 +3304,11 @@ namespace dxvk { const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns(spv::OpImageSampleImplicitLod, - 5 + getImageOperandWordCount(operands)); + spv::Op op = operands.sparse + ? spv::OpImageSparseSampleImplicitLod + : spv::OpImageSampleImplicitLod; + + m_code.putIns(op, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); @@ -3297,8 +3326,11 @@ namespace dxvk { const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns(spv::OpImageSampleExplicitLod, - 5 + getImageOperandWordCount(operands)); + spv::Op op = operands.sparse + ? spv::OpImageSparseSampleExplicitLod + : spv::OpImageSampleExplicitLod; + + m_code.putIns(op, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); @@ -3316,8 +3348,11 @@ namespace dxvk { const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns(spv::OpImageSampleProjImplicitLod, - 5 + getImageOperandWordCount(operands)); + spv::Op op = operands.sparse + ? spv::OpImageSparseSampleProjImplicitLod + : spv::OpImageSampleProjImplicitLod; + + m_code.putIns(op, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); @@ -3335,8 +3370,11 @@ namespace dxvk { const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns(spv::OpImageSampleProjExplicitLod, - 5 + getImageOperandWordCount(operands)); + spv::Op op = operands.sparse + ? spv::OpImageSparseSampleProjExplicitLod + : spv::OpImageSampleProjExplicitLod; + + m_code.putIns(op, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); @@ -3355,8 +3393,11 @@ namespace dxvk { const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns(spv::OpImageSampleDrefImplicitLod, - 6 + getImageOperandWordCount(operands)); + spv::Op op = operands.sparse + ? spv::OpImageSparseSampleDrefImplicitLod + : spv::OpImageSampleDrefImplicitLod; + + m_code.putIns(op, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); @@ -3376,8 +3417,11 @@ namespace dxvk { const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns(spv::OpImageSampleDrefExplicitLod, - 6 + getImageOperandWordCount(operands)); + spv::Op op = operands.sparse + ? spv::OpImageSparseSampleDrefExplicitLod + : spv::OpImageSampleDrefExplicitLod; + + m_code.putIns(op, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); @@ -3397,8 +3441,11 @@ namespace dxvk { const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns(spv::OpImageSampleProjDrefImplicitLod, - 6 + getImageOperandWordCount(operands)); + spv::Op op = operands.sparse + ? spv::OpImageSparseSampleProjDrefImplicitLod + : spv::OpImageSampleProjDrefImplicitLod; + + m_code.putIns(op, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); @@ -3418,8 +3465,11 @@ namespace dxvk { const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns(spv::OpImageSampleProjDrefExplicitLod, - 6 + getImageOperandWordCount(operands)); + spv::Op op = operands.sparse + ? spv::OpImageSparseSampleProjDrefExplicitLod + : spv::OpImageSampleProjDrefExplicitLod; + + m_code.putIns(op, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index f1ef6947e..8e52806e8 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -27,6 +27,7 @@ namespace dxvk { uint32_t gConstOffsets = 0; uint32_t sSampleId = 0; uint32_t sMinLod = 0; + bool sparse = false; }; constexpr uint32_t spvVersion(uint32_t major, uint32_t minor) { @@ -1063,7 +1064,11 @@ namespace dxvk { uint32_t coordinates, uint32_t texel, const SpirvImageOperands& operands); - + + uint32_t opImageSparseTexelsResident( + uint32_t resultType, + uint32_t residentCode); + uint32_t opImageTexelPointer( uint32_t resultType, uint32_t image, From eb8a238d6f7fe7678cd90bd4bd12bf15fd985370 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 02:40:34 +0200 Subject: [PATCH 0685/1348] [dxbc] Add definitions for sparse feedback instructions --- src/dxbc/dxbc_defs.cpp | 140 ++++++++++++++++++++++++++++++++++++++++- src/dxbc/dxbc_defs.h | 1 + src/dxbc/dxbc_enums.h | 17 +++++ 3 files changed, 157 insertions(+), 1 deletion(-) diff --git a/src/dxbc/dxbc_defs.cpp b/src/dxbc/dxbc_defs.cpp index 4e383d8a6..d8763ea00 100644 --- a/src/dxbc/dxbc_defs.cpp +++ b/src/dxbc/dxbc_defs.cpp @@ -2,7 +2,7 @@ namespace dxvk { - const std::array g_instructionFormats = {{ + const std::array g_instructionFormats = {{ /* Add */ { 3, DxbcInstClass::VectorAlu, { { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, @@ -1103,6 +1103,144 @@ namespace dxvk { { DxbcOperandKind::DstReg, DxbcScalarType::Float64 }, { DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 }, } }, + /* ReservedBegin11_2 */ + { }, + /* Gather4S */ + { 5, DxbcInstClass::TextureGather, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, + /* Gather4CS */ + { 6, DxbcInstClass::TextureGather, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, + /* Gather4PoS */ + { 6, DxbcInstClass::TextureGather, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, + /* Gather4PoCS */ + { 7, DxbcInstClass::TextureGather, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, + /* LdS */ + { 4, DxbcInstClass::TextureFetch, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, + /* LdMsS */ + { 5, DxbcInstClass::TextureFetch, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 }, + } }, + /* LdUavTypedS */ + { 4, DxbcInstClass::TypedUavLoad, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 }, + } }, + /* LdRawS */ + { 4, DxbcInstClass::BufferLoad, { + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 }, + } }, + /* LdStructuredS */ + { 5, DxbcInstClass::BufferLoad, { + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Sint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 }, + } }, + /* SampleLS */ + { 6, DxbcInstClass::TextureSample, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, + /* SampleClzS */ + { 6, DxbcInstClass::TextureSample, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, + /* SampleClampS */ + { 6, DxbcInstClass::TextureSample, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, + /* SampleBClampS */ + { 7, DxbcInstClass::TextureSample, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, + /* SampleDClampS */ + { 8, DxbcInstClass::TextureSample, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, + /* SampleCClampS */ + { 7, DxbcInstClass::TextureSample, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, + /* CheckAccessFullyMapped */ + { 2, DxbcInstClass::SparseCheckAccess, { + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Uint32 }, + } }, }}; diff --git a/src/dxbc/dxbc_defs.h b/src/dxbc/dxbc_defs.h index decd76707..8782481af 100644 --- a/src/dxbc/dxbc_defs.h +++ b/src/dxbc/dxbc_defs.h @@ -47,6 +47,7 @@ namespace dxvk { HullShaderInstCnt, ///< Hull shader phase instance count Interpolate, ///< Input attribute interpolation NoOperation, ///< The most useful instruction class + SparseCheckAccess, ///< Verifies sparse resource access TextureQuery, ///< Texture query instruction TextureQueryLod, ///< Texture LOD query instruction TextureQueryMs, ///< Multisample texture query diff --git a/src/dxbc/dxbc_enums.h b/src/dxbc/dxbc_enums.h index 214780d07..ead8fd4fe 100644 --- a/src/dxbc/dxbc_enums.h +++ b/src/dxbc/dxbc_enums.h @@ -226,6 +226,23 @@ namespace dxvk { DtoU = 215, ItoD = 216, UtoD = 217, + ReservedBegin11_2 = 218, + Gather4S = 219, + Gather4CS = 220, + Gather4PoS = 221, + Gather4PoCS = 222, + LdS = 223, + LdMsS = 224, + LdUavTypedS = 225, + LdRawS = 226, + LdStructuredS = 227, + SampleLS = 228, + SampleClzS = 229, + SampleClampS = 230, + SampleBClampS = 231, + SampleDClampS = 232, + SampleCClampS = 233, + CheckAccessFullyMapped = 234, }; From 614024873dde1e79d75246751a987dc507e54333 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 03:04:06 +0200 Subject: [PATCH 0686/1348] [dxbc] Implement CheckAccessFullyMapped instruction --- src/dxbc/dxbc_compiler.cpp | 26 +++++++++++++++++++++++++- src/dxbc/dxbc_compiler.h | 3 +++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 927114a9e..98abfc8b6 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -130,7 +130,10 @@ namespace dxvk { case DxbcInstClass::NoOperation: return; - + + case DxbcInstClass::SparseCheckAccess: + return this->emitSparseCheckAccess(ins); + case DxbcInstClass::TextureQuery: return this->emitTextureQuery(ins); @@ -3048,6 +3051,27 @@ namespace dxvk { } + void DxbcCompiler::emitSparseCheckAccess( + const DxbcShaderInstruction& ins) { + // check_access_mapped has two operands: + // (dst0) The destination register + // (src0) The residency code + m_module.enableCapability(spv::CapabilitySparseResidency); + + DxbcRegisterValue srcValue = emitRegisterLoad(ins.src[0], ins.dst[0].mask); + + uint32_t boolId = m_module.opImageSparseTexelsResident( + m_module.defBoolType(), srcValue.id); + + DxbcRegisterValue dstValue; + dstValue.type = { DxbcScalarType::Uint32, 1 }; + dstValue.id = m_module.opSelect(getScalarTypeId(DxbcScalarType::Uint32), + boolId, m_module.constu32(~0u), m_module.constu32(0)); + + emitRegisterStore(ins.dst[0], dstValue); + } + + void DxbcCompiler::emitTextureQuery(const DxbcShaderInstruction& ins) { // resinfo has three operands: // (dst0) The destination register diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 46afc8062..0a192e08e 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -709,6 +709,9 @@ namespace dxvk { void emitInterpolate( const DxbcShaderInstruction& ins); + void emitSparseCheckAccess( + const DxbcShaderInstruction& ins); + void emitTextureQuery( const DxbcShaderInstruction& ins); From d5b68b364208c4c203301263d4fda98afa77d124 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 03:38:12 +0200 Subject: [PATCH 0687/1348] [dxbc] Implement gather operations with sparse feedback --- src/dxbc/dxbc_compiler.cpp | 95 +++++++++++++++++++++++++++++++------- src/dxbc/dxbc_compiler.h | 17 ++++++- 2 files changed, 94 insertions(+), 18 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 98abfc8b6..d6a135d3e 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -3386,6 +3386,7 @@ namespace dxvk { void DxbcCompiler::emitTextureGather(const DxbcShaderInstruction& ins) { // Gather4 takes the following operands: // (dst0) The destination register + // (dst1) The residency code for sparse ops // (src0) Texture coordinates // (src1) The texture itself // (src2) The sampler, with a component selector @@ -3396,7 +3397,9 @@ namespace dxvk { // TODO reduce code duplication by moving some common code // in both sample() and gather() into separate methods const bool isExtendedGather = ins.op == DxbcOpcode::Gather4Po - || ins.op == DxbcOpcode::Gather4PoC; + || ins.op == DxbcOpcode::Gather4PoC + || ins.op == DxbcOpcode::Gather4PoS + || ins.op == DxbcOpcode::Gather4PoCS; const DxbcRegister& texCoordReg = ins.src[0]; const DxbcRegister& textureReg = ins.src[1 + isExtendedGather]; @@ -3415,8 +3418,10 @@ namespace dxvk { // Load reference value for depth-compare operations const bool isDepthCompare = ins.op == DxbcOpcode::Gather4C - || ins.op == DxbcOpcode::Gather4PoC; - + || ins.op == DxbcOpcode::Gather4PoC + || ins.op == DxbcOpcode::Gather4CS + || ins.op == DxbcOpcode::Gather4PoCS; + const DxbcRegisterValue referenceValue = isDepthCompare ? emitRegisterLoad(ins.src[3 + isExtendedGather], DxbcRegMask(true, false, false, false)) @@ -3424,7 +3429,8 @@ namespace dxvk { // Accumulate additional image operands. SpirvImageOperands imageOperands; - + imageOperands.sparse = ins.dstCount == 2; + if (isExtendedGather) { m_module.enableCapability(spv::CapabilityImageGatherExtended); @@ -3445,30 +3451,41 @@ namespace dxvk { getVectorTypeId({ DxbcScalarType::Sint32, imageLayerDim }), imageLayerDim, offsetIds.data()); } - + // Gathering texels always returns a four-component // vector, even for the depth-compare variants. uint32_t sampledImageId = emitLoadSampledImage(texture, sampler, isDepthCompare); - DxbcRegisterValue result; - result.type.ctype = texture.sampledType; - result.type.ccount = 4; - + DxbcVectorType texelType; + texelType.ctype = texture.sampledType; + texelType.ccount = 4; + + uint32_t texelTypeId = getVectorTypeId(texelType); + uint32_t resultTypeId = texelTypeId; + uint32_t resultId = 0; + + if (imageOperands.sparse) + resultTypeId = getSparseResultTypeId(texelTypeId); + switch (ins.op) { // Simple image gather operation case DxbcOpcode::Gather4: - case DxbcOpcode::Gather4Po: { - result.id = m_module.opImageGather( - getVectorTypeId(result.type), sampledImageId, coord.id, + case DxbcOpcode::Gather4S: + case DxbcOpcode::Gather4Po: + case DxbcOpcode::Gather4PoS: { + resultId = m_module.opImageGather( + resultTypeId, sampledImageId, coord.id, m_module.consti32(samplerReg.swizzle[0]), imageOperands); } break; // Depth-compare operation case DxbcOpcode::Gather4C: - case DxbcOpcode::Gather4PoC: { - result.id = m_module.opImageDrefGather( - getVectorTypeId(result.type), sampledImageId, coord.id, + case DxbcOpcode::Gather4CS: + case DxbcOpcode::Gather4PoC: + case DxbcOpcode::Gather4PoCS: { + resultId = m_module.opImageDrefGather( + resultTypeId, sampledImageId, coord.id, referenceValue.id, imageOperands); } break; @@ -3478,13 +3495,23 @@ namespace dxvk { ins.op)); return; } - + + // If necessary, deal with the sparse result + DxbcRegisterValue result; + result.type = texelType; + result.id = imageOperands.sparse + ? emitExtractSparseTexel(texelTypeId, resultId) + : resultId; + // Swizzle components using the texture swizzle // and the destination operand's write mask result = emitRegisterSwizzle(result, textureReg.swizzle, ins.dst[0].mask); emitRegisterStore(ins.dst[0], result); + + if (imageOperands.sparse) + emitStoreSparseFeedback(ins.dst[1], resultId); } @@ -4549,6 +4576,33 @@ namespace dxvk { } + uint32_t DxbcCompiler::emitExtractSparseTexel( + uint32_t texelTypeId, + uint32_t resultId) { + uint32_t index = 1; + + return m_module.opCompositeExtract( + texelTypeId, resultId, 1, &index); + } + + + void DxbcCompiler::emitStoreSparseFeedback( + const DxbcRegister& feedbackRegister, + uint32_t resultId) { + if (feedbackRegister.type != DxbcOperandType::Null) { + uint32_t index = 0; + + DxbcRegisterValue result; + result.type = { DxbcScalarType::Uint32, 1 }; + result.id = m_module.opCompositeExtract( + getScalarTypeId(DxbcScalarType::Uint32), + resultId, 1, &index); + + emitRegisterStore(feedbackRegister, result); + } + } + + DxbcRegisterValue DxbcCompiler::emitDstOperandModifiers( DxbcRegisterValue value, DxbcOpModifiers modifiers) { @@ -7592,6 +7646,15 @@ namespace dxvk { } + uint32_t DxbcCompiler::getSparseResultTypeId(uint32_t baseType) { + m_module.enableCapability(spv::CapabilitySparseResidency); + + uint32_t uintType = getScalarTypeId(DxbcScalarType::Uint32); + std::array typeIds = { uintType, baseType }; + return m_module.defStructType(typeIds.size(), typeIds.data()); + } + + uint32_t DxbcCompiler::getPerVertexBlockId() { uint32_t t_f32 = m_module.defFloatType(32); uint32_t t_f32_v4 = m_module.defVectorType(t_f32, 4); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 0a192e08e..17fb7d87e 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -882,6 +882,16 @@ namespace dxvk { DxbcRegisterValue value, DxbcOpModifiers modifiers); + /////////////////////////// + // Sparse feedback methods + uint32_t emitExtractSparseTexel( + uint32_t texelTypeId, + uint32_t resultId); + + void emitStoreSparseFeedback( + const DxbcRegister& feedbackRegister, + uint32_t resultId); + //////////////////////////////// // Pointer manipulation methods DxbcRegisterPointer emitArrayAccess( @@ -1149,7 +1159,7 @@ namespace dxvk { uint32_t emitSamplePosArray(); void emitFloatControl(); - + /////////////////////////////// // Variable definition methods uint32_t emitNewVariable( @@ -1223,7 +1233,10 @@ namespace dxvk { uint32_t getPointerTypeId( const DxbcRegisterInfo& type); - + + uint32_t getSparseResultTypeId( + uint32_t baseType); + uint32_t getPerVertexBlockId(); uint32_t getFunctionId( From 0faba649da0a334b4ab4b099f158ecdb7841e2f8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 03:54:48 +0200 Subject: [PATCH 0688/1348] [dxbc] Implement sample operations with sparse feedback --- src/dxbc/dxbc_compiler.cpp | 102 ++++++++++++++++++++++++++----------- 1 file changed, 73 insertions(+), 29 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index d6a135d3e..338081bdc 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -3536,14 +3536,17 @@ namespace dxvk { // Load reference value for depth-compare operations const bool isDepthCompare = ins.op == DxbcOpcode::SampleC - || ins.op == DxbcOpcode::SampleClz; + || ins.op == DxbcOpcode::SampleClz + || ins.op == DxbcOpcode::SampleCClampS + || ins.op == DxbcOpcode::SampleClzS; const DxbcRegisterValue referenceValue = isDepthCompare ? emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false)) : DxbcRegisterValue(); // Load explicit gradients for sample operations that require them - const bool hasExplicitGradients = ins.op == DxbcOpcode::SampleD; + const bool hasExplicitGradients = ins.op == DxbcOpcode::SampleD + || ins.op == DxbcOpcode::SampleDClampS; const DxbcRegisterValue explicitGradientX = hasExplicitGradients ? emitRegisterLoad(ins.src[3], DxbcRegMask::firstN(imageLayerDim)) @@ -3555,16 +3558,29 @@ namespace dxvk { // LOD for certain sample operations const bool hasLod = ins.op == DxbcOpcode::SampleL - || ins.op == DxbcOpcode::SampleB; + || ins.op == DxbcOpcode::SampleLS + || ins.op == DxbcOpcode::SampleB + || ins.op == DxbcOpcode::SampleBClampS; const DxbcRegisterValue lod = hasLod ? emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false)) : DxbcRegisterValue(); - + + // Min LOD for certain sparse operations + const bool hasMinLod = ins.op == DxbcOpcode::SampleClampS + || ins.op == DxbcOpcode::SampleBClampS + || ins.op == DxbcOpcode::SampleDClampS + || ins.op == DxbcOpcode::SampleCClampS; + + const DxbcRegisterValue minLod = hasMinLod && ins.src[ins.srcCount - 1].type != DxbcOperandType::Null + ? emitRegisterLoad(ins.src[ins.srcCount - 1], DxbcRegMask(true, false, false, false)) + : DxbcRegisterValue(); + // Accumulate additional image operands. These are // not part of the actual operand token in SPIR-V. SpirvImageOperands imageOperands; - + imageOperands.sparse = ins.dstCount == 2; + if (ins.sampleControls.u != 0 || ins.sampleControls.v != 0 || ins.sampleControls.w != 0) { const std::array offsetIds = { imageLayerDim >= 1 ? m_module.consti32(ins.sampleControls.u) : 0, @@ -3577,70 +3593,89 @@ namespace dxvk { getVectorTypeId({ DxbcScalarType::Sint32, imageLayerDim }), imageLayerDim, offsetIds.data()); } - + + if (hasMinLod) { + m_module.enableCapability(spv::CapabilityMinLod); + + imageOperands.flags |= spv::ImageOperandsMinLodMask; + imageOperands.sMinLod = minLod.id; + } + // Combine the texture and the sampler into a sampled image uint32_t sampledImageId = emitLoadSampledImage(texture, sampler, isDepthCompare); // Sampling an image always returns a four-component // vector, whereas depth-compare ops return a scalar. - DxbcRegisterValue result; - result.type.ctype = texture.sampledType; - result.type.ccount = isDepthCompare ? 1 : 4; - + DxbcVectorType texelType; + texelType.ctype = texture.sampledType; + texelType.ccount = isDepthCompare ? 1 : 4; + + uint32_t texelTypeId = getVectorTypeId(texelType); + uint32_t resultTypeId = texelTypeId; + uint32_t resultId = 0; + + if (imageOperands.sparse) + resultTypeId = getSparseResultTypeId(texelTypeId); + switch (ins.op) { // Simple image sample operation - case DxbcOpcode::Sample: { - result.id = m_module.opImageSampleImplicitLod( - getVectorTypeId(result.type), - sampledImageId, coord.id, + case DxbcOpcode::Sample: + case DxbcOpcode::SampleClampS: { + resultId = m_module.opImageSampleImplicitLod( + resultTypeId, sampledImageId, coord.id, imageOperands); } break; // Depth-compare operation - case DxbcOpcode::SampleC: { - result.id = m_module.opImageSampleDrefImplicitLod( - getVectorTypeId(result.type), sampledImageId, coord.id, + case DxbcOpcode::SampleC: + case DxbcOpcode::SampleCClampS: { + resultId = m_module.opImageSampleDrefImplicitLod( + resultTypeId, sampledImageId, coord.id, referenceValue.id, imageOperands); } break; // Depth-compare operation on mip level zero - case DxbcOpcode::SampleClz: { + case DxbcOpcode::SampleClz: + case DxbcOpcode::SampleClzS: { imageOperands.flags |= spv::ImageOperandsLodMask; imageOperands.sLod = m_module.constf32(0.0f); - result.id = m_module.opImageSampleDrefExplicitLod( - getVectorTypeId(result.type), sampledImageId, coord.id, + resultId = m_module.opImageSampleDrefExplicitLod( + resultTypeId, sampledImageId, coord.id, referenceValue.id, imageOperands); } break; // Sample operation with explicit gradients - case DxbcOpcode::SampleD: { + case DxbcOpcode::SampleD: + case DxbcOpcode::SampleDClampS: { imageOperands.flags |= spv::ImageOperandsGradMask; imageOperands.sGradX = explicitGradientX.id; imageOperands.sGradY = explicitGradientY.id; - result.id = m_module.opImageSampleExplicitLod( - getVectorTypeId(result.type), sampledImageId, coord.id, + resultId = m_module.opImageSampleExplicitLod( + resultTypeId, sampledImageId, coord.id, imageOperands); } break; // Sample operation with explicit LOD - case DxbcOpcode::SampleL: { + case DxbcOpcode::SampleL: + case DxbcOpcode::SampleLS: { imageOperands.flags |= spv::ImageOperandsLodMask; imageOperands.sLod = lod.id; - result.id = m_module.opImageSampleExplicitLod( - getVectorTypeId(result.type), sampledImageId, coord.id, + resultId = m_module.opImageSampleExplicitLod( + resultTypeId, sampledImageId, coord.id, imageOperands); } break; // Sample operation with LOD bias - case DxbcOpcode::SampleB: { + case DxbcOpcode::SampleB: + case DxbcOpcode::SampleBClampS: { imageOperands.flags |= spv::ImageOperandsBiasMask; imageOperands.sLodBias = lod.id; - result.id = m_module.opImageSampleImplicitLod( - getVectorTypeId(result.type), sampledImageId, coord.id, + resultId = m_module.opImageSampleImplicitLod( + resultTypeId, sampledImageId, coord.id, imageOperands); } break; @@ -3651,6 +3686,12 @@ namespace dxvk { return; } + DxbcRegisterValue result; + result.type = texelType; + result.id = imageOperands.sparse + ? emitExtractSparseTexel(texelTypeId, resultId) + : resultId; + // Swizzle components using the texture swizzle // and the destination operand's write mask if (result.type.ccount != 1) { @@ -3659,6 +3700,9 @@ namespace dxvk { } emitRegisterStore(ins.dst[0], result); + + if (imageOperands.sparse) + emitStoreSparseFeedback(ins.dst[1], resultId); } From db3b2e23fb5959db23cc80fde21d8219923c859d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 04:05:35 +0200 Subject: [PATCH 0689/1348] [dxbc] Implement ld_uav_typed with sparse feedback --- src/dxbc/dxbc_compiler.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 338081bdc..5c2d796f5 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -3717,21 +3717,40 @@ namespace dxvk { // Load texture coordinates DxbcRegisterValue texCoord = emitLoadTexCoord( ins.src[0], uavInfo.imageInfo); - + + SpirvImageOperands imageOperands; + imageOperands.sparse = ins.dstCount == 2; + + DxbcVectorType texelType; + texelType.ctype = uavInfo.sampledType; + texelType.ccount = 4; + + uint32_t texelTypeId = getVectorTypeId(texelType); + uint32_t resultTypeId = texelTypeId; + uint32_t resultId = 0; + + if (imageOperands.sparse) + resultTypeId = getSparseResultTypeId(texelTypeId); + // Load source value from the UAV - DxbcRegisterValue uavValue; - uavValue.type.ctype = uavInfo.sampledType; - uavValue.type.ccount = 4; - uavValue.id = m_module.opImageRead( - getVectorTypeId(uavValue.type), + resultId = m_module.opImageRead(resultTypeId, m_module.opLoad(uavInfo.imageTypeId, uavInfo.varId), - texCoord.id, SpirvImageOperands()); + texCoord.id, imageOperands); // Apply component swizzle and mask + DxbcRegisterValue uavValue; + uavValue.type = texelType; + uavValue.id = imageOperands.sparse + ? emitExtractSparseTexel(texelTypeId, resultId) + : resultId; + uavValue = emitRegisterSwizzle(uavValue, ins.src[1].swizzle, ins.dst[0].mask); emitRegisterStore(ins.dst[0], uavValue); + + if (imageOperands.sparse) + emitStoreSparseFeedback(ins.dst[1], resultId); } From e58f9a5e99565c9292037d20ea16b808acc7dd44 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 04:29:56 +0200 Subject: [PATCH 0690/1348] [dxbc] Implement ld for images with sparse feedback --- src/dxbc/dxbc_compiler.cpp | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 5c2d796f5..2638b4fd6 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -3310,6 +3310,9 @@ namespace dxvk { const auto& texture = m_textures.at(ins.src[1].idx[0].offset); const uint32_t imageLayerDim = getTexLayerDim(texture.imageInfo); + bool isMultisampled = ins.op == DxbcOpcode::LdMs + || ins.op == DxbcOpcode::LdMsS; + // Load the texture coordinates. The last component // contains the LOD if the resource is an image. const DxbcRegisterValue address = emitRegisterLoad( @@ -3318,6 +3321,7 @@ namespace dxvk { // Additional image operands. This will store // the LOD and the address offset if present. SpirvImageOperands imageOperands; + imageOperands.sparse = ins.dstCount == 2; if (ins.sampleControls.u != 0 || ins.sampleControls.v != 0 || ins.sampleControls.w != 0) { const std::array offsetIds = { @@ -3337,7 +3341,7 @@ namespace dxvk { if (texture.imageInfo.dim != spv::DimBuffer && texture.imageInfo.ms == 0) { DxbcRegisterValue imageLod; - if (ins.op != DxbcOpcode::LdMs) { + if (!isMultisampled) { imageLod = emitRegisterExtract( address, DxbcRegMask(false, false, false, true)); } else { @@ -3350,9 +3354,9 @@ namespace dxvk { imageOperands.sLod = imageLod.id; } - // The ld2ms instruction has a sample index, but we + // The ld2dms instruction has a sample index, but we // are only allowed to set it for multisample views - if (ins.op == DxbcOpcode::LdMs && texture.imageInfo.ms == 1) { + if (isMultisampled && texture.imageInfo.ms == 1) { DxbcRegisterValue sampleId = emitRegisterLoad( ins.src[2], DxbcRegMask(true, false, false, false)); @@ -3366,13 +3370,26 @@ namespace dxvk { // Reading a typed image or buffer view // always returns a four-component vector. const uint32_t imageId = m_module.opLoad(texture.imageTypeId, texture.varId); - + + DxbcVectorType texelType; + texelType.ctype = texture.sampledType; + texelType.ccount = 4; + + uint32_t texelTypeId = getVectorTypeId(texelType); + uint32_t resultTypeId = texelTypeId; + uint32_t resultId = 0; + + if (imageOperands.sparse) + resultTypeId = getSparseResultTypeId(texelTypeId); + + resultId = m_module.opImageFetch(resultTypeId, + imageId, coord.id, imageOperands); + DxbcRegisterValue result; - result.type.ctype = texture.sampledType; - result.type.ccount = 4; - result.id = m_module.opImageFetch( - getVectorTypeId(result.type), imageId, - coord.id, imageOperands); + result.type = texelType; + result.id = imageOperands.sparse + ? emitExtractSparseTexel(texelTypeId, resultId) + : resultId; // Swizzle components using the texture swizzle // and the destination operand's write mask @@ -3380,6 +3397,9 @@ namespace dxvk { ins.src[1].swizzle, ins.dst[0].mask); emitRegisterStore(ins.dst[0], result); + + if (imageOperands.sparse) + emitStoreSparseFeedback(ins.dst[1], resultId); } From d6613f50c5881a2328fda2bd75e16662dbc2ca00 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 04:55:31 +0200 Subject: [PATCH 0691/1348] [dxbc] Implement ld for buffers with sparse feedback --- src/dxbc/dxbc_compiler.cpp | 63 ++++++++++++++++++++++++++++---------- src/dxbc/dxbc_compiler.h | 3 +- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 2638b4fd6..5900367c1 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -2758,7 +2758,8 @@ namespace dxvk { // (src0) Structure index // (src1) Byte offset // (src2) Source register - const bool isStructured = ins.op == DxbcOpcode::LdStructured; + const bool isStructured = ins.op == DxbcOpcode::LdStructured + || ins.op == DxbcOpcode::LdStructuredS; // Source register. The exact way we access // the data depends on the register type. @@ -2776,9 +2777,14 @@ namespace dxvk { bufferInfo.stride) : emitCalcBufferIndexRaw( emitRegisterLoad(ins.src[0], DxbcRegMask(true, false, false, false))); - - emitRegisterStore(dstReg, - emitRawBufferLoad(srcReg, elementIndex, dstReg.mask)); + + uint32_t sparseFeedbackId = uint32_t(ins.dstCount == 2); + + emitRegisterStore(dstReg, emitRawBufferLoad(srcReg, + elementIndex, dstReg.mask, sparseFeedbackId)); + + if (sparseFeedbackId) + emitStoreSparseFeedback(ins.dst[1], sparseFeedbackId); } @@ -5111,7 +5117,8 @@ namespace dxvk { DxbcRegisterValue DxbcCompiler::emitRawBufferLoad( const DxbcRegister& operand, DxbcRegisterValue elementIndex, - DxbcRegMask writeMask) { + DxbcRegMask writeMask, + uint32_t& sparseFeedbackId) { const DxbcBufferInfo bufferInfo = getBufferInfo(operand); // Shared memory is the only type of buffer that @@ -5131,7 +5138,14 @@ namespace dxvk { std::array ccomps = { 0, 0, 0, 0 }; std::array scomps = { 0, 0, 0, 0 }; uint32_t scount = 0; - + + // The sparse feedback ID will be non-zero for sparse + // instructions on input. We need to reset it to 0. + SpirvImageOperands imageOperands; + imageOperands.sparse = sparseFeedbackId != 0; + + sparseFeedbackId = 0; + for (uint32_t i = 0; i < 4; i++) { uint32_t sindex = operand.swizzle[i]; @@ -5155,18 +5169,33 @@ namespace dxvk { ccomps[sindex] = m_module.opLoad(scalarTypeId, m_module.opAccessChain(bufferInfo.typeId, bufferInfo.varId, 2, indices)); - } else if (operand.type == DxbcOperandType::Resource) { - ccomps[sindex] = m_module.opCompositeExtract(scalarTypeId, - m_module.opImageFetch(vectorTypeId, - bufferId, elementIndexAdjusted, - SpirvImageOperands()), 1, &zero); - } else if (operand.type == DxbcOperandType::UnorderedAccessView) { - ccomps[sindex] = m_module.opCompositeExtract(scalarTypeId, - m_module.opImageRead(vectorTypeId, - bufferId, elementIndexAdjusted, - SpirvImageOperands()), 1, &zero); } else { - throw DxvkError("DxbcCompiler: Invalid operand type for strucured/raw load"); + uint32_t resultTypeId = vectorTypeId; + uint32_t resultId = 0; + + if (imageOperands.sparse) + resultTypeId = getSparseResultTypeId(vectorTypeId); + + if (operand.type == DxbcOperandType::Resource) { + resultId = m_module.opImageFetch(resultTypeId, + bufferId, elementIndexAdjusted, imageOperands); + } else if (operand.type == DxbcOperandType::UnorderedAccessView) { + resultId = m_module.opImageRead(resultTypeId, + bufferId, elementIndexAdjusted, imageOperands); + } else { + throw DxvkError("DxbcCompiler: Invalid operand type for strucured/raw load"); + } + + // Only read sparse feedback once. This may be somewhat inaccurate + // for reads that straddle pages, but we can't easily emulate this. + if (imageOperands.sparse) { + imageOperands.sparse = false; + sparseFeedbackId = resultId; + + resultId = emitExtractSparseTexel(vectorTypeId, resultId); + } + + ccomps[sindex] = m_module.opCompositeExtract(scalarTypeId, resultId, 1, &zero); } } } diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 17fb7d87e..24e54dda5 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -938,7 +938,8 @@ namespace dxvk { DxbcRegisterValue emitRawBufferLoad( const DxbcRegister& operand, DxbcRegisterValue elementIndex, - DxbcRegMask writeMask); + DxbcRegMask writeMask, + uint32_t& sparseFeedbackId); void emitRawBufferStore( const DxbcRegister& operand, From 336aafcdf7d1359aa06ca0f21de47931c41a2d55 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 05:04:24 +0200 Subject: [PATCH 0692/1348] [dxbc] Explicitly store whether a resource is a raw SSBO --- src/dxbc/dxbc_compiler.cpp | 33 ++++++++++++--------------------- src/dxbc/dxbc_compiler.h | 2 +- src/dxbc/dxbc_decoder.h | 4 ++-- 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 5900367c1..b5357390c 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -1000,7 +1000,7 @@ namespace dxvk { uav.sampledTypeId = sampledTypeId; uav.imageTypeId = imageTypeId; uav.structStride = 0; - uav.structAlign = 0; + uav.isRawSsbo = false; m_uavs.at(registerId) = uav; } else { DxbcShaderResource res; @@ -1013,7 +1013,7 @@ namespace dxvk { res.colorTypeId = imageTypeId; res.depthTypeId = 0; res.structStride = 0; - res.structAlign = 0; + res.isRawSsbo = false; if ((sampledType == DxbcScalarType::Float32) && (resourceType == DxbcResourceDim::Texture2D @@ -1149,7 +1149,7 @@ namespace dxvk { uav.sampledTypeId = sampledTypeId; uav.imageTypeId = resTypeId; uav.structStride = resStride; - uav.structAlign = resAlign; + uav.isRawSsbo = useRawSsbo; m_uavs.at(registerId) = uav; } else { DxbcShaderResource res; @@ -1162,7 +1162,7 @@ namespace dxvk { res.colorTypeId = resTypeId; res.depthTypeId = 0; res.structStride = resStride; - res.structAlign = resAlign; + res.isRawSsbo = useRawSsbo; m_textures.at(registerId) = res; } @@ -2271,10 +2271,7 @@ namespace dxvk { bool isImm = ins.dstCount == 2; bool isUav = ins.dst[ins.dstCount - 1].type == DxbcOperandType::UnorderedAccessView; - - bool isSsbo = m_moduleInfo.options.minSsboAlignment <= bufferInfo.align - && bufferInfo.type != DxbcResourceType::Typed - && isUav; + bool isSsbo = bufferInfo.isSsbo; // Retrieve destination pointer for the atomic operation> const DxbcRegisterPointer pointer = emitGetAtomicPointer( @@ -2719,9 +2716,7 @@ namespace dxvk { // (dst0) The destination register // (src0) The buffer register to query const DxbcBufferInfo bufferInfo = getBufferInfo(ins.src[0]); - - bool isSsbo = m_moduleInfo.options.minSsboAlignment <= bufferInfo.align - && bufferInfo.type != DxbcResourceType::Typed; + bool isSsbo = bufferInfo.isSsbo; // We'll store this as a scalar unsigned integer DxbcRegisterValue result = isSsbo @@ -5058,9 +5053,7 @@ namespace dxvk { // For UAVs and shared memory, different methods // of obtaining the final pointer are used. bool isTgsm = operand.type == DxbcOperandType::ThreadGroupSharedMemory; - bool isSsbo = m_moduleInfo.options.minSsboAlignment <= resourceInfo.align - && resourceInfo.type != DxbcResourceType::Typed - && !isTgsm; + bool isSsbo = resourceInfo.isSsbo; // Compute the actual address into the resource const DxbcRegisterValue addressValue = [&] { @@ -5124,8 +5117,7 @@ namespace dxvk { // Shared memory is the only type of buffer that // is not accessed through a texel buffer view bool isTgsm = operand.type == DxbcOperandType::ThreadGroupSharedMemory; - bool isSsbo = m_moduleInfo.options.minSsboAlignment <= bufferInfo.align - && !isTgsm; + bool isSsbo = bufferInfo.isSsbo; // Common types and IDs used while loading the data uint32_t bufferId = isTgsm || isSsbo ? 0 : m_module.opLoad(bufferInfo.typeId, bufferInfo.varId); @@ -5233,8 +5225,7 @@ namespace dxvk { // Thread Group Shared Memory is not accessed through a texel buffer view bool isTgsm = operand.type == DxbcOperandType::ThreadGroupSharedMemory; - bool isSsbo = m_moduleInfo.options.minSsboAlignment <= bufferInfo.align - && !isTgsm; + bool isSsbo = bufferInfo.isSsbo; // Perform the actual write operation uint32_t bufferId = isTgsm || isSsbo ? 0 : m_module.opLoad(bufferInfo.typeId, bufferInfo.varId); @@ -7488,7 +7479,7 @@ namespace dxvk { result.typeId = texture.imageTypeId; result.varId = texture.varId; result.stride = texture.structStride; - result.align = texture.structAlign; + result.isSsbo = texture.isRawSsbo; return result; } break; @@ -7502,7 +7493,7 @@ namespace dxvk { result.typeId = uav.imageTypeId; result.varId = uav.varId; result.stride = uav.structStride; - result.align = uav.structAlign; + result.isSsbo = uav.isRawSsbo; return result; } break; @@ -7516,7 +7507,7 @@ namespace dxvk { spv::StorageClassWorkgroup); result.varId = m_gRegs.at(registerId).varId; result.stride = m_gRegs.at(registerId).elementStride; - result.align = 0; + result.isSsbo = false; return result; } break; diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 24e54dda5..771a4c623 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -346,7 +346,7 @@ namespace dxvk { uint32_t typeId; uint32_t varId; uint32_t stride; - uint32_t align; + bool isSsbo; }; diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index 72b4e961f..3a605029f 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -80,7 +80,7 @@ namespace dxvk { uint32_t colorTypeId = 0; uint32_t depthTypeId = 0; uint32_t structStride = 0; - uint32_t structAlign = 0; + bool isRawSsbo = false; }; @@ -100,7 +100,7 @@ namespace dxvk { uint32_t sampledTypeId = 0; uint32_t imageTypeId = 0; uint32_t structStride = 0; - uint32_t structAlign = 0; + bool isRawSsbo = false; }; From eaa5d1661638c81e8d2f442b00867f0b7408b989 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 05:11:59 +0200 Subject: [PATCH 0693/1348] [dxbc] Use texel buffers for raw/structured buffers with sparse feedback --- src/dxbc/dxbc_analysis.cpp | 5 +++++ src/dxbc/dxbc_analysis.h | 14 +++++++++++++- src/dxbc/dxbc_compiler.cpp | 6 +++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/dxbc/dxbc_analysis.cpp b/src/dxbc/dxbc_analysis.cpp index 69922211b..8a8f44b54 100644 --- a/src/dxbc/dxbc_analysis.cpp +++ b/src/dxbc/dxbc_analysis.cpp @@ -52,10 +52,15 @@ namespace dxvk { case DxbcInstClass::BufferLoad: { uint32_t operandId = ins.op == DxbcOpcode::LdStructured ? 2 : 1; + bool sparseFeedback = ins.dstCount == 2; if (ins.src[operandId].type == DxbcOperandType::UnorderedAccessView) { const uint32_t registerId = ins.src[operandId].idx[0].offset; m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT; + m_analysis->uavInfos[registerId].sparseFeedback |= sparseFeedback; + } else if (ins.src[operandId].type == DxbcOperandType::Resource) { + const uint32_t registerId = ins.src[operandId].idx[0].offset; + m_analysis->srvInfos[registerId].sparseFeedback |= sparseFeedback; } } break; diff --git a/src/dxbc/dxbc_analysis.h b/src/dxbc/dxbc_analysis.h index b40cc94db..fcbc1ddad 100644 --- a/src/dxbc/dxbc_analysis.h +++ b/src/dxbc/dxbc_analysis.h @@ -19,9 +19,20 @@ namespace dxvk { struct DxbcUavInfo { bool accessTypedLoad = false; bool accessAtomicOp = false; + bool sparseFeedback = false; VkAccessFlags accessFlags = 0; }; + /** + * \brief Info about shader resource views + * + * Stores whether an SRV is accessed with + * sparse feedback. Useful for buffers. + */ + struct DxbcSrvInfo { + bool sparseFeedback = false; + }; + /** * \brief Counts cull and clip distances */ @@ -34,7 +45,8 @@ namespace dxvk { * \brief Shader analysis info */ struct DxbcAnalysisInfo { - std::array uavInfos; + std::array uavInfos; + std::array srvInfos; std::array xRegMasks; DxbcClipCullInfo clipCullIn; diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index b5357390c..5fafe7672 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -1096,7 +1096,11 @@ namespace dxvk { : computeSrvBinding(m_programInfo.type(), registerId); // Test whether we should use a raw SSBO for this resource - bool useRawSsbo = m_moduleInfo.options.minSsboAlignment <= resAlign; + bool hasSparseFeedback = isUav + ? m_analysis->uavInfos[registerId].sparseFeedback + : m_analysis->srvInfos[registerId].sparseFeedback; + + bool useRawSsbo = m_moduleInfo.options.minSsboAlignment <= resAlign && !hasSparseFeedback; if (useRawSsbo) { uint32_t elemType = getScalarTypeId(DxbcScalarType::Uint32); From 626ccef43b248c1c8472d35615ef34bdb1f330c7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 19 Aug 2022 16:49:25 +0200 Subject: [PATCH 0694/1348] [d3d11] Enable sparse features if supported by the device --- src/d3d11/d3d11_device.cpp | 56 ++++++++++++++++++++++++++++++++++++-- src/d3d11/d3d11_device.h | 4 +++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 845a0c271..07c3891bd 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1948,7 +1948,11 @@ namespace dxvk { enabled.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor = supported.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor; enabled.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor = supported.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor; - + + D3D11_TILED_RESOURCES_TIER sparseTier = DetermineTiledResourcesTier(supported, adapter->devicePropertiesExt()); + VkBool32 hasSparseTier1 = sparseTier >= D3D11_TILED_RESOURCES_TIER_1; + VkBool32 hasSparseTier2 = sparseTier >= D3D11_TILED_RESOURCES_TIER_2; + if (supported.extCustomBorderColor.customBorderColorWithoutFormat) { enabled.extCustomBorderColor.customBorderColors = VK_TRUE; enabled.extCustomBorderColor.customBorderColorWithoutFormat = VK_TRUE; @@ -1997,14 +2001,36 @@ namespace dxvk { enabled.core.features.shaderFloat64 = supported.core.features.shaderFloat64; enabled.core.features.shaderInt64 = supported.core.features.shaderInt64; enabled.core.features.tessellationShader = VK_TRUE; + enabled.core.features.sparseBinding = hasSparseTier1; + enabled.core.features.sparseResidencyBuffer = hasSparseTier1; + enabled.core.features.sparseResidencyImage2D = hasSparseTier1; + enabled.core.features.sparseResidencyImage3D = hasSparseTier1 && supported.core.features.sparseResidencyImage3D; + enabled.core.features.sparseResidency2Samples = hasSparseTier1 && supported.core.features.sparseResidency2Samples; + enabled.core.features.sparseResidency4Samples = hasSparseTier1 && supported.core.features.sparseResidency4Samples; + enabled.core.features.sparseResidency8Samples = hasSparseTier1 && supported.core.features.sparseResidency8Samples; + enabled.core.features.sparseResidency16Samples = hasSparseTier1 && supported.core.features.sparseResidency16Samples; + enabled.core.features.sparseResidencyAliased = hasSparseTier1; } if (featureLevel >= D3D_FEATURE_LEVEL_11_1) { enabled.core.features.logicOp = VK_TRUE; enabled.core.features.variableMultisampleRate = VK_TRUE; enabled.core.features.vertexPipelineStoresAndAtomics = VK_TRUE; + enabled.core.features.shaderResourceResidency = hasSparseTier2; + enabled.core.features.shaderResourceMinLod = hasSparseTier2; + enabled.vk12.samplerFilterMinmax = hasSparseTier2; } - + + if (featureLevel >= D3D_FEATURE_LEVEL_12_0) { + enabled.core.features.shaderResourceResidency = VK_TRUE; + enabled.core.features.shaderResourceMinLod = VK_TRUE; + enabled.core.features.sparseBinding = VK_TRUE; + enabled.core.features.sparseResidencyBuffer = VK_TRUE; + enabled.core.features.sparseResidencyImage2D = VK_TRUE; + enabled.core.features.sparseResidencyAliased = VK_TRUE; + enabled.vk12.samplerFilterMinmax = VK_TRUE; + } + return enabled; } @@ -2440,6 +2466,32 @@ namespace dxvk { } + D3D11_TILED_RESOURCES_TIER D3D11Device::DetermineTiledResourcesTier( + const DxvkDeviceFeatures& Features, + const DxvkDeviceInfo& Properties) { + if (!Features.core.features.sparseBinding + || !Features.core.features.sparseResidencyBuffer + || !Features.core.features.sparseResidencyImage2D + || !Features.core.features.sparseResidencyAliased + || !Properties.core.properties.sparseProperties.residencyStandard2DBlockShape) + return D3D11_TILED_RESOURCES_NOT_SUPPORTED; + + if (!Features.core.features.shaderResourceResidency + || !Features.core.features.shaderResourceMinLod + || !Features.vk12.samplerFilterMinmax + || !Properties.vk12.filterMinmaxSingleComponentFormats + || !Properties.core.properties.sparseProperties.residencyNonResidentStrict + || Properties.core.properties.sparseProperties.residencyAlignedMipSize) + return D3D11_TILED_RESOURCES_TIER_1; + + if (!Features.core.features.sparseResidencyImage3D + || !Properties.core.properties.sparseProperties.residencyStandard3DBlockShape) + return D3D11_TILED_RESOURCES_TIER_2; + + return D3D11_TILED_RESOURCES_TIER_3; + } + + D3D_FEATURE_LEVEL D3D11Device::GetMaxFeatureLevel(const Rc& pInstance) { static const std::array, 9> s_featureLevels = {{ { "12_1", D3D_FEATURE_LEVEL_12_1 }, diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index da0e481b1..0fe42524b 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -491,6 +491,10 @@ namespace dxvk { UINT Subresource, const D3D11_BOX* pBox); + static D3D11_TILED_RESOURCES_TIER DetermineTiledResourcesTier( + const DxvkDeviceFeatures& Features, + const DxvkDeviceInfo& Properties); + static D3D_FEATURE_LEVEL GetMaxFeatureLevel( const Rc& pInstance); From f97660e210111e19d774d8201a6c6e4efb60b94a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 19 Aug 2022 19:48:26 +0200 Subject: [PATCH 0695/1348] [d3d11] Implement TiledResourceBarrier --- src/d3d11/d3d11_context.cpp | 56 +++++++++++++++++++++++++++++++++++++ src/d3d11/d3d11_context.h | 3 ++ 2 files changed, 59 insertions(+) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 36d79a899..414a9117a 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2669,7 +2669,19 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11CommonContext::TiledResourceBarrier( ID3D11DeviceChild* pTiledResourceOrViewAccessBeforeBarrier, ID3D11DeviceChild* pTiledResourceOrViewAccessAfterBarrier) { + DxvkGlobalPipelineBarrier srcBarrier = GetTiledResourceDependency(pTiledResourceOrViewAccessBeforeBarrier); + DxvkGlobalPipelineBarrier dstBarrier = GetTiledResourceDependency(pTiledResourceOrViewAccessAfterBarrier); + if (srcBarrier.stages && dstBarrier.stages) { + EmitCs([ + cSrcBarrier = srcBarrier, + cDstBarrier = dstBarrier + ] (DxvkContext* ctx) { + ctx->emitGraphicsBarrier( + cSrcBarrier.stages, cSrcBarrier.access, + cDstBarrier.stages, cDstBarrier.access); + }); + } } @@ -3885,6 +3897,50 @@ namespace dxvk { } + template + DxvkGlobalPipelineBarrier D3D11CommonContext::GetTiledResourceDependency( + ID3D11DeviceChild* pObject) { + if (!pObject) { + DxvkGlobalPipelineBarrier result; + result.stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + result.access = VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_MEMORY_READ_BIT; + return result; + } else { + Com resource; + + if (FAILED(pObject->QueryInterface(IID_PPV_ARGS(&resource)))) { + Com view; + + if (FAILED(pObject->QueryInterface(IID_PPV_ARGS(&view)))) + return DxvkGlobalPipelineBarrier(); + + view->GetResource(&resource); + } + + D3D11CommonTexture* texture = GetCommonTexture(resource.ptr()); + + if (texture) { + Rc image = texture->GetImage(); + + DxvkGlobalPipelineBarrier result; + result.stages = image->info().stages; + result.access = image->info().access; + return result; + } else { + Rc buffer = static_cast(resource.ptr())->GetBuffer(); + + if (buffer == nullptr) + return DxvkGlobalPipelineBarrier(); + + DxvkGlobalPipelineBarrier result; + result.stages = buffer->info().stages; + result.access = buffer->info().access; + return result; + } + } + } + + template D3D11MaxUsedBindings D3D11CommonContext::GetMaxUsedBindings() { D3D11MaxUsedBindings result; diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 571871e0c..4df399139 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -912,6 +912,9 @@ namespace dxvk { UINT NumSamplers, ID3D11SamplerState** ppSamplers); + DxvkGlobalPipelineBarrier GetTiledResourceDependency( + ID3D11DeviceChild* pObject); + D3D11MaxUsedBindings GetMaxUsedBindings(); void ResetCommandListState(); From 3f7093325b896a5d4ed9ce19284f164c61b75250 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 20 Aug 2022 16:33:48 +0200 Subject: [PATCH 0696/1348] [d3d11] Implement GetResourceTiling --- src/d3d11/d3d11_device.cpp | 91 ++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 14 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 07c3891bd..628fd8cc1 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1837,27 +1837,90 @@ namespace dxvk { UINT* pNumSubresourceTilings, UINT FirstSubresourceTilingToGet, D3D11_SUBRESOURCE_TILING* pSubresourceTilingsForNonPackedMips) { - static bool s_errorShown = false; + D3D11_COMMON_RESOURCE_DESC desc = { }; + GetCommonResourceDesc(pTiledResource, &desc); - if (!std::exchange(s_errorShown, true)) - Logger::err("D3D11Device::GetResourceTiling: Tiled resources not supported"); + if (!(desc.MiscFlags & D3D11_RESOURCE_MISC_TILED)) { + if (pNumTilesForEntireResource) + *pNumTilesForEntireResource = 0; - if (pNumTilesForEntireResource) - *pNumTilesForEntireResource = 0; + if (pPackedMipDesc) + *pPackedMipDesc = D3D11_PACKED_MIP_DESC(); - if (pPackedMipDesc) - *pPackedMipDesc = D3D11_PACKED_MIP_DESC(); + if (pStandardTileShapeForNonPackedMips) + *pStandardTileShapeForNonPackedMips = D3D11_TILE_SHAPE(); - if (pStandardTileShapeForNonPackedMips) - *pStandardTileShapeForNonPackedMips = D3D11_TILE_SHAPE(); + if (pNumSubresourceTilings) { + if (pSubresourceTilingsForNonPackedMips) { + for (uint32_t i = 0; i < *pNumSubresourceTilings; i++) + pSubresourceTilingsForNonPackedMips[i] = D3D11_SUBRESOURCE_TILING(); + } - if (pNumSubresourceTilings) { - if (pSubresourceTilingsForNonPackedMips) { - for (uint32_t i = 0; i < *pNumSubresourceTilings; i++) - pSubresourceTilingsForNonPackedMips[i] = D3D11_SUBRESOURCE_TILING(); + *pNumSubresourceTilings = 0; + } + } else { + DxvkSparsePageTable* sparseInfo = nullptr; + uint32_t mipCount = 0; + + if (desc.Dim == D3D11_RESOURCE_DIMENSION_BUFFER) { + Rc buffer = static_cast(pTiledResource)->GetBuffer(); + sparseInfo = buffer->getSparsePageTable(); + } else { + Rc image = GetCommonTexture(pTiledResource)->GetImage(); + sparseInfo = image->getSparsePageTable(); + mipCount = image->info().mipLevels; } - *pNumSubresourceTilings = 0; + if (pNumTilesForEntireResource) + *pNumTilesForEntireResource = sparseInfo->getPageCount(); + + if (pPackedMipDesc) { + auto properties = sparseInfo->getProperties(); + + if (properties.mipTailSize) { + pPackedMipDesc->NumStandardMips = properties.pagedMipCount; + pPackedMipDesc->NumPackedMips = mipCount - properties.pagedMipCount; + pPackedMipDesc->NumTilesForPackedMips = sparseInfo->getPageCount() - properties.mipTailPageIndex; + pPackedMipDesc->StartTileIndexInOverallResource = properties.mipTailPageIndex; + } else { + pPackedMipDesc->NumStandardMips = mipCount; + pPackedMipDesc->NumPackedMips = 0; + pPackedMipDesc->NumTilesForPackedMips = 0; + pPackedMipDesc->StartTileIndexInOverallResource = 0; + } + } + + if (pStandardTileShapeForNonPackedMips) { + auto properties = sparseInfo->getProperties(); + pStandardTileShapeForNonPackedMips->WidthInTexels = properties.pageRegionExtent.width; + pStandardTileShapeForNonPackedMips->HeightInTexels = properties.pageRegionExtent.height; + pStandardTileShapeForNonPackedMips->DepthInTexels = properties.pageRegionExtent.depth; + } + + if (pNumSubresourceTilings) { + uint32_t subresourceCount = sparseInfo->getSubresourceCount(); + uint32_t tilingCount = subresourceCount - std::min(FirstSubresourceTilingToGet, subresourceCount); + tilingCount = std::min(tilingCount, *pNumSubresourceTilings); + + for (uint32_t i = 0; i < tilingCount; i++) { + auto subresourceInfo = sparseInfo->getSubresourceProperties(FirstSubresourceTilingToGet + i); + auto dstInfo = &pSubresourceTilingsForNonPackedMips[i]; + + if (subresourceInfo.isMipTail) { + dstInfo->WidthInTiles = 0u; + dstInfo->HeightInTiles = 0u; + dstInfo->DepthInTiles = 0u; + dstInfo->StartTileIndexInOverallResource = D3D11_PACKED_TILE; + } else { + dstInfo->WidthInTiles = subresourceInfo.pageCount.width; + dstInfo->HeightInTiles = subresourceInfo.pageCount.height; + dstInfo->DepthInTiles = subresourceInfo.pageCount.depth; + dstInfo->StartTileIndexInOverallResource = subresourceInfo.pageIndex; + } + } + + *pNumSubresourceTilings = tilingCount; + } } } From ca0dedd21314d91d2dc4ca74400f32ae99cc72b3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 20 Aug 2022 16:37:21 +0200 Subject: [PATCH 0697/1348] [d3d11] Implement multisampling support check for tiled resources --- src/d3d11/d3d11_device.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 628fd8cc1..f196dc7be 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1475,12 +1475,21 @@ namespace dxvk { if (FAILED(DecodeSampleCount(SampleCount, &sampleCountFlag))) return SampleCount && SampleCount <= 32 ? S_OK : E_FAIL; - + + // Get image create flags depending on function arguments + VkImageCreateFlags flags = 0; + + if (Flags & D3D11_CHECK_MULTISAMPLE_QUALITY_LEVELS_TILED_RESOURCE) { + flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT + | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT + | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT; + } + // Check if the device supports the given combination of format // and sample count. D3D exposes the opaque concept of quality // levels to the application, we'll just define one such level. auto properties = m_dxvkDevice->getFormatLimits(format, - VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, 0); + VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, flags); if (properties && (properties->sampleCounts & sampleCountFlag)) *pNumQualityLevels = 1; From 7f856b545a3d263f8c0a2c50d6cf32fa6a16f6dc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 01:21:50 +0200 Subject: [PATCH 0698/1348] [d3d11] Implement format feature check for tiled resources --- src/d3d11/d3d11_device.cpp | 24 ++++++++++++++++++------ src/d3d11/d3d11_device.h | 11 ++++++----- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index f196dc7be..42124597f 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2217,9 +2217,21 @@ namespace dxvk { if (imgFeatures & (VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) { const VkFormat depthFormat = LookupFormat(Format, DXGI_VK_FORMAT_MODE_DEPTH).Format; - if (GetImageTypeSupport(fmtMapping.Format, VK_IMAGE_TYPE_1D)) flags1 |= D3D11_FORMAT_SUPPORT_TEXTURE1D; - if (GetImageTypeSupport(fmtMapping.Format, VK_IMAGE_TYPE_2D)) flags1 |= D3D11_FORMAT_SUPPORT_TEXTURE2D; - if (GetImageTypeSupport(fmtMapping.Format, VK_IMAGE_TYPE_3D)) flags1 |= D3D11_FORMAT_SUPPORT_TEXTURE3D; + if (GetImageTypeSupport(fmtMapping.Format, VK_IMAGE_TYPE_1D, 0)) flags1 |= D3D11_FORMAT_SUPPORT_TEXTURE1D; + if (GetImageTypeSupport(fmtMapping.Format, VK_IMAGE_TYPE_2D, 0)) flags1 |= D3D11_FORMAT_SUPPORT_TEXTURE2D; + if (GetImageTypeSupport(fmtMapping.Format, VK_IMAGE_TYPE_3D, 0)) flags1 |= D3D11_FORMAT_SUPPORT_TEXTURE3D; + + // We only support tiled resources with a single aspect + VkImageAspectFlags sparseAspects = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; + + if (m_tiledResourcesTier && !(fmtProperties->aspectMask & ~sparseAspects)) { + VkImageCreateFlags flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT + | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT + | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT; + + if (GetImageTypeSupport(fmtMapping.Format, VK_IMAGE_TYPE_2D, flags)) + flags2 |= D3D11_FORMAT_SUPPORT2_TILED; + } flags1 |= D3D11_FORMAT_SUPPORT_MIP | D3D11_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT; @@ -2327,13 +2339,13 @@ namespace dxvk { } - BOOL D3D11Device::GetImageTypeSupport(VkFormat Format, VkImageType Type) const { + BOOL D3D11Device::GetImageTypeSupport(VkFormat Format, VkImageType Type, VkImageCreateFlags Flags) const { auto properties = m_dxvkDevice->getFormatLimits(Format, - Type, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, 0); + Type, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, Flags); if (!properties) { properties = m_dxvkDevice->getFormatLimits(Format, - Type, VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_SAMPLED_BIT, 0); + Type, VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_SAMPLED_BIT, Flags); } return properties.has_value(); diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 0fe42524b..fef0dca11 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -464,13 +464,14 @@ namespace dxvk { const DxbcModuleInfo* pModuleInfo); HRESULT GetFormatSupportFlags( - DXGI_FORMAT Format, - UINT* pFlags1, - UINT* pFlags2) const; + DXGI_FORMAT Format, + UINT* pFlags1, + UINT* pFlags2) const; BOOL GetImageTypeSupport( - VkFormat Format, - VkImageType Type) const; + VkFormat Format, + VkImageType Type, + VkImageCreateFlags Flags) const; template HRESULT OpenSharedResourceGeneric( From 0637fdf82e3f1f98983457cf8f7c6666445d4457 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 20 Aug 2022 17:02:49 +0200 Subject: [PATCH 0699/1348] [d3d11] Implement tiled buffer creation --- src/d3d11/d3d11_buffer.cpp | 44 ++++++++++++++++++++++++++------- src/d3d11/d3d11_buffer.h | 4 ++- src/d3d11/d3d11_device.cpp | 5 ++-- src/d3d11/d3d11_device.h | 2 ++ src/d3d11/d3d11_initializer.cpp | 10 +++++--- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index 3069d71ef..55e8d0b69 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -13,7 +13,8 @@ namespace dxvk { m_desc (*pDesc), m_resource (this), m_d3d10 (this) { - DxvkBufferCreateInfo info; + DxvkBufferCreateInfo info; + info.flags = 0; info.size = pDesc->ByteWidth; info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; @@ -66,6 +67,12 @@ namespace dxvk { info.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT; } + if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILED) { + info.flags |= VK_BUFFER_CREATE_SPARSE_BINDING_BIT + | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT + | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT; + } + // Create the buffer and set the entire buffer slice as mapped, // so that we only have to update it when invalidating th buffer m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags()); @@ -162,15 +169,11 @@ namespace dxvk { } - HRESULT D3D11Buffer::NormalizeBufferProperties(D3D11_BUFFER_DESC* pDesc) { + HRESULT D3D11Buffer::NormalizeBufferProperties(D3D11_BUFFER_DESC* pDesc, D3D11_TILED_RESOURCES_TIER TiledTier) { // Zero-sized buffers are illegal - if (!pDesc->ByteWidth) + if (!pDesc->ByteWidth && !(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) return E_INVALIDARG; - // We don't support tiled resources - if (pDesc->MiscFlags & (D3D11_RESOURCE_MISC_TILE_POOL | D3D11_RESOURCE_MISC_TILED)) - return E_INVALIDARG; - // Constant buffer size must be a multiple of 16 if ((pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER) && (pDesc->ByteWidth & 0xF)) @@ -191,7 +194,27 @@ namespace dxvk { // Mip generation obviously doesn't work for buffers if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) return E_INVALIDARG; - + + // Basic validation for tiled buffers + if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILED) { + if ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL) + || (pDesc->Usage != D3D11_USAGE_DEFAULT) + || (pDesc->CPUAccessFlags) + || (!TiledTier)) + return E_INVALIDARG; + } + + // Basic validation for tile pools + if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL) { + if ((pDesc->MiscFlags & ~D3D11_RESOURCE_MISC_TILE_POOL) + || (pDesc->ByteWidth % SparseMemoryPageSize) + || (pDesc->Usage != D3D11_USAGE_DEFAULT) + || (pDesc->BindFlags) + || (pDesc->CPUAccessFlags) + || (!TiledTier)) + return E_INVALIDARG; + } + if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)) pDesc->StructureByteStride = 0; @@ -209,7 +232,10 @@ namespace dxvk { VkMemoryPropertyFlags D3D11Buffer::GetMemoryFlags() const { VkMemoryPropertyFlags memoryFlags = 0; - + + if (m_desc.MiscFlags & (D3D11_RESOURCE_MISC_TILE_POOL | D3D11_RESOURCE_MISC_TILED)) + return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + switch (m_desc.Usage) { case D3D11_USAGE_IMMUTABLE: memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index b13b18aa0..90d069b01 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -138,10 +138,12 @@ namespace dxvk { * \brief Normalizes buffer description * * \param [in] pDesc Buffer description + * \param [in] TiledTier Tiled resources tier * \returns \c S_OK if the parameters are valid */ static HRESULT NormalizeBufferProperties( - D3D11_BUFFER_DESC* pDesc); + D3D11_BUFFER_DESC* pDesc, + D3D11_TILED_RESOURCES_TIER TiledTier); private: diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 42124597f..1feeb2b95 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -45,7 +45,8 @@ namespace dxvk { m_dxvkAdapter (m_dxvkDevice->adapter()), m_d3d11Formats (m_dxvkDevice), m_d3d11Options (m_dxvkDevice->instance()->config(), m_dxvkDevice), - m_dxbcOptions (m_dxvkDevice, m_d3d11Options) { + m_dxbcOptions (m_dxvkDevice, m_d3d11Options), + m_tiledResourcesTier(DetermineTiledResourcesTier(m_dxvkDevice->features(), m_dxvkDevice->properties())) { m_initializer = new D3D11Initializer(this); m_context = new D3D11ImmediateContext(this, m_dxvkDevice); m_d3d10Device = new D3D10Device(this, m_context.ptr()); @@ -84,7 +85,7 @@ namespace dxvk { return E_INVALIDARG; D3D11_BUFFER_DESC desc = *pDesc; - HRESULT hr = D3D11Buffer::NormalizeBufferProperties(&desc); + HRESULT hr = D3D11Buffer::NormalizeBufferProperties(&desc, m_tiledResourcesTier); if (FAILED(hr)) return hr; diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index fef0dca11..8d25a9ed7 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -455,6 +455,8 @@ namespace dxvk { D3D11StateObjectSet m_samplerObjects; D3D11ShaderModuleSet m_shaderModules; + D3D11_TILED_RESOURCES_TIER m_tiledResourcesTier; + HRESULT CreateShaderModule( D3D11CommonShader* pShaderModule, DxvkShaderKey ShaderKey, diff --git a/src/d3d11/d3d11_initializer.cpp b/src/d3d11/d3d11_initializer.cpp index 9aa9ac672..b90dbff6b 100644 --- a/src/d3d11/d3d11_initializer.cpp +++ b/src/d3d11/d3d11_initializer.cpp @@ -30,11 +30,13 @@ namespace dxvk { void D3D11Initializer::InitBuffer( D3D11Buffer* pBuffer, const D3D11_SUBRESOURCE_DATA* pInitialData) { - VkMemoryPropertyFlags memFlags = pBuffer->GetBuffer()->memFlags(); + if (!(pBuffer->Desc()->MiscFlags & D3D11_RESOURCE_MISC_TILED)) { + VkMemoryPropertyFlags memFlags = pBuffer->GetBuffer()->memFlags(); - (memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) - ? InitHostVisibleBuffer(pBuffer, pInitialData) - : InitDeviceLocalBuffer(pBuffer, pInitialData); + (memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + ? InitHostVisibleBuffer(pBuffer, pInitialData) + : InitDeviceLocalBuffer(pBuffer, pInitialData); + } } From 0cd67cb98a9a741b07a909795ad74c64454f0db2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 20 Aug 2022 17:16:42 +0200 Subject: [PATCH 0700/1348] [d3d11] Implement tiled image creation --- src/d3d11/d3d11_device.cpp | 13 +++++++++---- src/d3d11/d3d11_initializer.cpp | 18 +++++++++++++++--- src/d3d11/d3d11_initializer.h | 5 ++++- src/d3d11/d3d11_interop.cpp | 3 ++- src/d3d11/d3d11_texture.cpp | 28 ++++++++++++++++++++++++---- src/d3d11/d3d11_texture.h | 4 +++- 6 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 1feeb2b95..01c916632 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -128,7 +128,8 @@ namespace dxvk { desc.MiscFlags = pDesc->MiscFlags; desc.TextureLayout = D3D11_TEXTURE_LAYOUT_UNDEFINED; - HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc); + HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, + D3D11_TILED_RESOURCES_NOT_SUPPORTED); if (FAILED(hr)) return hr; @@ -204,7 +205,7 @@ namespace dxvk { desc.MiscFlags = pDesc->MiscFlags; desc.TextureLayout = pDesc->TextureLayout; - HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc); + HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, m_tiledResourcesTier); if (FAILED(hr)) return hr; @@ -279,11 +280,15 @@ namespace dxvk { desc.MiscFlags = pDesc->MiscFlags; desc.TextureLayout = pDesc->TextureLayout; - HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc); + HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, m_tiledResourcesTier); if (FAILED(hr)) return hr; - + + if ((desc.MiscFlags & D3D11_RESOURCE_MISC_TILED) + && (m_tiledResourcesTier < D3D11_TILED_RESOURCES_TIER_3)) + return E_INVALIDARG; + if (!ppTexture3D) return S_FALSE; diff --git a/src/d3d11/d3d11_initializer.cpp b/src/d3d11/d3d11_initializer.cpp index b90dbff6b..a5391adb2 100644 --- a/src/d3d11/d3d11_initializer.cpp +++ b/src/d3d11/d3d11_initializer.cpp @@ -43,9 +43,12 @@ namespace dxvk { void D3D11Initializer::InitTexture( D3D11CommonTexture* pTexture, const D3D11_SUBRESOURCE_DATA* pInitialData) { - (pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) - ? InitHostVisibleTexture(pTexture, pInitialData) - : InitDeviceLocalTexture(pTexture, pInitialData); + if (pTexture->Desc()->MiscFlags & D3D11_RESOURCE_MISC_TILED) + InitTiledTexture(pTexture); + else if (pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) + InitHostVisibleTexture(pTexture, pInitialData); + else + InitDeviceLocalTexture(pTexture, pInitialData); } @@ -255,6 +258,15 @@ namespace dxvk { } + void D3D11Initializer::InitTiledTexture( + D3D11CommonTexture* pTexture) { + m_context->initSparseImage(pTexture->GetImage()); + + m_transferCommands += 1; + FlushImplicit(); + } + + void D3D11Initializer::FlushImplicit() { if (m_transferCommands > MaxTransferCommands || m_transferMemory > MaxTransferMemory) diff --git a/src/d3d11/d3d11_initializer.h b/src/d3d11/d3d11_initializer.h index 8c96babda..8cfe84c63 100644 --- a/src/d3d11/d3d11_initializer.h +++ b/src/d3d11/d3d11_initializer.h @@ -64,7 +64,10 @@ namespace dxvk { void InitHostVisibleTexture( D3D11CommonTexture* pTexture, const D3D11_SUBRESOURCE_DATA* pInitialData); - + + void InitTiledTexture( + D3D11CommonTexture* pTexture); + void FlushImplicit(); void FlushInternal(); diff --git a/src/d3d11/d3d11_interop.cpp b/src/d3d11/d3d11_interop.cpp index 8fa50288b..b6cb129d4 100644 --- a/src/d3d11/d3d11_interop.cpp +++ b/src/d3d11/d3d11_interop.cpp @@ -146,7 +146,8 @@ namespace dxvk { desc.MiscFlags = pDesc->MiscFlags; desc.TextureLayout = pDesc->TextureLayout; - HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc); + HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, + D3D11_TILED_RESOURCES_NOT_SUPPORTED); if (FAILED(hr)) return hr; diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 1171b42b6..fd05fd532 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -136,10 +136,16 @@ namespace dxvk { if (m_desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) imageInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; + if (m_desc.MiscFlags & D3D11_RESOURCE_MISC_TILED) { + imageInfo.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT + | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT + | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT; + } + if (Dimension == D3D11_RESOURCE_DIMENSION_TEXTURE3D && (m_desc.BindFlags & D3D11_BIND_RENDER_TARGET)) imageInfo.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; - + // Swap chain back buffers need to be shader readable if (DxgiUsage & DXGI_USAGE_BACK_BUFFER) { imageInfo.usage |= VK_IMAGE_USAGE_SAMPLED_BIT; @@ -396,7 +402,7 @@ namespace dxvk { } - HRESULT D3D11CommonTexture::NormalizeTextureProperties(D3D11_COMMON_TEXTURE_DESC* pDesc) { + HRESULT D3D11CommonTexture::NormalizeTextureProperties(D3D11_COMMON_TEXTURE_DESC* pDesc, D3D11_TILED_RESOURCES_TIER TiledTier) { if (pDesc->Width == 0 || pDesc->Height == 0 || pDesc->Depth == 0 || pDesc->ArraySize == 0) return E_INVALIDARG; @@ -415,10 +421,24 @@ namespace dxvk { != (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) return E_INVALIDARG; - // TILE_POOL is invalid, but we don't support TILED either - if (pDesc->MiscFlags & (D3D11_RESOURCE_MISC_TILE_POOL | D3D11_RESOURCE_MISC_TILED)) + // TILE_POOL is invalid for textures + if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL) return E_INVALIDARG; + // Perform basic validation for tiled resources + if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILED) { + UINT invalidFlags = D3D11_RESOURCE_MISC_SHARED + | D3D11_RESOURCE_MISC_SHARED_NTHANDLE + | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX + | D3D11_RESOURCE_MISC_GDI_COMPATIBLE; + + if ((pDesc->MiscFlags & invalidFlags) + || (pDesc->Usage != D3D11_USAGE_DEFAULT) + || (pDesc->CPUAccessFlags) + || (!TiledTier)) + return E_INVALIDARG; + } + // Use the maximum possible mip level count if the supplied // mip level count is either unspecified (0) or invalid const uint32_t maxMipLevelCount = (pDesc->SampleDesc.Count <= 1) diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index 3ca91da21..0bb25b916 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -367,10 +367,12 @@ namespace dxvk { * parameters. Any error returned by this method should * be forwarded to the application. * \param [in,out] pDesc Texture description + * \param [in] TiledTier Tiled resources tier * \returns \c S_OK if the parameters are valid */ static HRESULT NormalizeTextureProperties( - D3D11_COMMON_TEXTURE_DESC* pDesc); + D3D11_COMMON_TEXTURE_DESC* pDesc, + D3D11_TILED_RESOURCES_TIER TiledTier); private: From e8f59bfd7c612fe2c147af9bcca36dbdf47b1dfb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 20 Aug 2022 22:04:51 +0200 Subject: [PATCH 0701/1348] [d3d11] Implement tile pool creation --- src/d3d11/d3d11_buffer.cpp | 24 ++++++++++++++++-------- src/d3d11/d3d11_buffer.h | 5 +++++ src/d3d11/d3d11_device.cpp | 5 ++++- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index 55e8d0b69..cbcbb1e71 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -73,16 +73,24 @@ namespace dxvk { | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT; } - // Create the buffer and set the entire buffer slice as mapped, - // so that we only have to update it when invalidating th buffer - m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags()); - m_mapped = m_buffer->getSliceHandle(); + if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) { + // Create the buffer and set the entire buffer slice as mapped, + // so that we only have to update it when invalidating the buffer + m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags()); + m_mapped = m_buffer->getSliceHandle(); - m_mapMode = DetermineMapMode(); + m_mapMode = DetermineMapMode(); - // For Stream Output buffers we need a counter - if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT) - m_soCounter = CreateSoCounterBuffer(); + // For Stream Output buffers we need a counter + if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT) + m_soCounter = CreateSoCounterBuffer(); + } else { + m_sparseAllocator = m_parent->GetDXVKDevice()->createSparsePageAllocator(); + m_sparseAllocator->setCapacity(info.size / SparseMemoryPageSize); + + m_mapped = DxvkBufferSliceHandle(); + m_mapMode = D3D11_COMMON_BUFFER_MAP_MODE_NONE; + } } diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index 90d069b01..5c9c0645b 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -73,6 +73,10 @@ namespace dxvk { Rc GetBuffer() const { return m_buffer; } + + Rc GetSparseAllocator() const { + return m_sparseAllocator; + } DxvkBufferSlice GetBufferSlice() const { return DxvkBufferSlice(m_buffer, 0, m_desc.ByteWidth); @@ -152,6 +156,7 @@ namespace dxvk { Rc m_buffer; Rc m_soCounter; + Rc m_sparseAllocator; DxvkBufferSliceHandle m_mapped; uint64_t m_seq = 0ull; diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 01c916632..2dd70877f 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -95,7 +95,10 @@ namespace dxvk { try { const Com buffer = new D3D11Buffer(this, &desc); - m_initializer->InitBuffer(buffer.ptr(), pInitialData); + + if (!(desc.MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) + m_initializer->InitBuffer(buffer.ptr(), pInitialData); + *ppBuffer = buffer.ref(); return S_OK; } catch (const DxvkError& e) { From 5130638ebecb794406ec2ed117495f20e536bb7a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 20 Aug 2022 22:25:02 +0200 Subject: [PATCH 0702/1348] [d3d11] Implement ResizeTilePool --- src/d3d11/d3d11_buffer.h | 4 ++++ src/d3d11/d3d11_context.cpp | 20 ++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index 5c9c0645b..b3420dc21 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -66,6 +66,10 @@ namespace dxvk { return &m_desc; } + BOOL IsTilePool() const { + return bool(m_desc.MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL); + } + D3D11_COMMON_BUFFER_MAP_MODE GetMapMode() const { return m_mapMode; } diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 414a9117a..b8549475a 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2656,12 +2656,24 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11CommonContext::ResizeTilePool( ID3D11Buffer* pTilePool, UINT64 NewSizeInBytes) { - static bool s_errorShown = false; + if (NewSizeInBytes % SparseMemoryPageSize) + return E_INVALIDARG; - if (!std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::ResizeTilePool: Not implemented"); + auto buffer = static_cast(pTilePool); - return DXGI_ERROR_INVALID_CALL; + if (!buffer->IsTilePool()) + return E_INVALIDARG; + + // Perform the resize operation. This is somewhat trivialized + // since all lifetime tracking is done by the backend. + EmitCs([ + cAllocator = buffer->GetSparseAllocator(), + cPageCount = NewSizeInBytes / SparseMemoryPageSize + ] (DxvkContext* ctx) { + cAllocator->setCapacity(cPageCount); + }); + + return S_OK; } From ff2ff3769646f25c2fa800d2f01d142b3f1a5f06 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 15:51:44 +0200 Subject: [PATCH 0703/1348] [d3d11] Implement UpdateTileMappings --- src/d3d11/d3d11_context.cpp | 153 +++++++++++++++++++++++++++++++++-- src/d3d11/d3d11_context.h | 8 +- src/d3d11/d3d11_resource.cpp | 11 +++ src/d3d11/d3d11_resource.h | 13 ++- 4 files changed, 171 insertions(+), 14 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index b8549475a..cf8fe3171 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2700,21 +2700,158 @@ namespace dxvk { template HRESULT STDMETHODCALLTYPE D3D11CommonContext::UpdateTileMappings( ID3D11Resource* pTiledResource, - UINT NumTiledResourceRegions, - const D3D11_TILED_RESOURCE_COORDINATE* pTiledResourceRegionStartCoordinates, - const D3D11_TILE_REGION_SIZE* pTiledResourceRegionSizes, + UINT NumRegions, + const D3D11_TILED_RESOURCE_COORDINATE* pRegionCoordinates, + const D3D11_TILE_REGION_SIZE* pRegionSizes, ID3D11Buffer* pTilePool, UINT NumRanges, const UINT* pRangeFlags, - const UINT* pTilePoolStartOffsets, + const UINT* pRangeTileOffsets, const UINT* pRangeTileCounts, UINT Flags) { - bool s_errorShown = false; + if (!pTiledResource || !NumRegions || !NumRanges) + return E_INVALIDARG; - if (std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::UpdateTileMappings: Not implemented"); + if constexpr (!IsDeferred) + GetTypedContext()->FlushImplicit(false); - return DXGI_ERROR_INVALID_CALL; + // Find sparse allocator if the tile pool is defined + DxvkSparseBindInfo bindInfo; + + if (pTilePool) { + auto tilePool = static_cast(pTilePool); + bindInfo.srcAllocator = tilePool->GetSparseAllocator(); + + if (bindInfo.srcAllocator == nullptr) + return E_INVALIDARG; + } + + // Find resource and sparse page table for the given resource + bindInfo.dstResource = GetPagedResource(pTiledResource); + auto pageTable = bindInfo.dstResource->getSparsePageTable(); + + if (!pageTable) + return E_INVALIDARG; + + // Lookup table in case the app tries to bind the same + // page multiple times. We should resolve that here and + // only consider the last bind to any given page. + std::vector bindIndices(pageTable->getPageCount(), ~0u); + + // This function allows pretty much every parameter to be nullptr + // in some way, so initialize some defaults as necessary + D3D11_TILED_RESOURCE_COORDINATE regionCoord = { }; + D3D11_TILE_REGION_SIZE regionSize = { }; + + if (!pRegionSizes) { + regionSize.NumTiles = pRegionCoordinates + ? 1 : pageTable->getPageCount(); + } + + uint32_t rangeFlag = 0u; + uint32_t rangeTileOffset = 0u; + uint32_t rangeTileCount = ~0u; + + // For now, just generate a simple list of tile index to + // page index mappings, and let the backend optimize later + uint32_t regionIdx = 0u; + uint32_t regionTile = 0u; + uint32_t rangeIdx = 0u; + uint32_t rangeTile = 0u; + + while (regionIdx < NumRegions && rangeIdx < NumRanges) { + if (!regionTile) { + if (pRegionCoordinates) + regionCoord = pRegionCoordinates[regionIdx]; + + if (pRegionSizes) + regionSize = pRegionSizes[regionIdx]; + } + + if (!rangeTile) { + if (pRangeFlags) + rangeFlag = pRangeFlags[rangeIdx]; + + if (pRangeTileOffsets) + rangeTileOffset = pRangeTileOffsets[rangeIdx]; + + if (pRangeTileCounts) + rangeTileCount = pRangeTileCounts[rangeIdx]; + } + + if (!(rangeFlag & D3D11_TILE_RANGE_SKIP)) { + if (regionCoord.Subresource >= pageTable->getSubresourceCount()) + return E_INVALIDARG; + + if (regionSize.bUseBox && regionSize.NumTiles != + regionSize.Width * regionSize.Height * regionSize.Depth) + return E_INVALIDARG; + + VkOffset3D regionOffset = { + int32_t(regionCoord.X), + int32_t(regionCoord.Y), + int32_t(regionCoord.Z) }; + + VkExtent3D regionExtent = { + uint32_t(regionSize.Width), + uint32_t(regionSize.Height), + uint32_t(regionSize.Depth) }; + + uint32_t resourceTile = pageTable->computePageIndex(regionCoord.Subresource, + regionOffset, regionExtent, !regionSize.bUseBox, regionTile); + + // Fill in bind info for the current tile + DxvkSparseBind bind = { }; + bind.dstPage = resourceTile; + + if (rangeFlag & D3D11_TILE_RANGE_NULL) { + bind.mode = DxvkSparseBindMode::Null; + } else if (pTilePool) { + bind.mode = DxvkSparseBindMode::Bind; + bind.srcPage = rangeFlag & D3D11_TILE_RANGE_REUSE_SINGLE_TILE + ? rangeTileOffset + : rangeTileOffset + rangeTile; + } else { + return E_INVALIDARG; + } + + // Add bind info to the bind list, overriding + // any existing bind for the same resource page + if (resourceTile < pageTable->getPageCount()) { + if (bindIndices[resourceTile] < bindInfo.binds.size()) + bindInfo.binds[bindIndices[resourceTile]] = bind; + else + bindInfo.binds.push_back(bind); + } + } + + if (++regionTile == regionSize.NumTiles) { + regionTile = 0; + regionIdx += 1; + } + + if (++rangeTile == rangeTileCount) { + rangeTile = 0; + rangeIdx += 1; + } + } + + // Translate flags. The backend benefits from NO_OVERWRITE since + // otherwise we have to serialize execution of the current command + // buffer, the sparse binding operation, and subsequent commands. + // With NO_OVERWRITE, we can execute it more or less asynchronously. + DxvkSparseBindFlags flags = (Flags & D3D11_TILE_MAPPING_NO_OVERWRITE) + ? DxvkSparseBindFlags(DxvkSparseBindFlag::SkipSynchronization) + : DxvkSparseBindFlags(); + + EmitCs([ + cBindInfo = std::move(bindInfo), + cFlags = flags + ] (DxvkContext* ctx) { + ctx->updatePageTable(cBindInfo, cFlags); + }); + + return S_OK; } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 4df399139..851087270 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -715,13 +715,13 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE UpdateTileMappings( ID3D11Resource* pTiledResource, - UINT NumTiledResourceRegions, - const D3D11_TILED_RESOURCE_COORDINATE* pTiledResourceRegionStartCoordinates, - const D3D11_TILE_REGION_SIZE* pTiledResourceRegionSizes, + UINT NumRegions, + const D3D11_TILED_RESOURCE_COORDINATE* pRegionCoordinates, + const D3D11_TILE_REGION_SIZE* pRegionSizes, ID3D11Buffer* pTilePool, UINT NumRanges, const UINT* pRangeFlags, - const UINT* pTilePoolStartOffsets, + const UINT* pRangeTileOffsets, const UINT* pRangeTileCounts, UINT Flags); diff --git a/src/d3d11/d3d11_resource.cpp b/src/d3d11/d3d11_resource.cpp index ab8aabe40..43dac598b 100644 --- a/src/d3d11/d3d11_resource.cpp +++ b/src/d3d11/d3d11_resource.cpp @@ -209,6 +209,17 @@ namespace dxvk { } + Rc GetPagedResource( + ID3D11Resource* pResource) { + auto texture = GetCommonTexture(pResource); + + if (texture) + return texture->GetImage(); + + return static_cast(pResource)->GetBuffer(); + } + + BOOL CheckResourceViewCompatibility( ID3D11Resource* pResource, UINT BindFlags, diff --git a/src/d3d11/d3d11_resource.h b/src/d3d11/d3d11_resource.h index 0fd29f48d..4baabd101 100644 --- a/src/d3d11/d3d11_resource.h +++ b/src/d3d11/d3d11_resource.h @@ -103,7 +103,7 @@ namespace dxvk { HRESULT GetCommonResourceDesc( ID3D11Resource* pResource, D3D11_COMMON_RESOURCE_DESC* pDesc); - + /** * \brief Checks whether a format can be used to view a resource * @@ -121,7 +121,16 @@ namespace dxvk { UINT BindFlags, DXGI_FORMAT Format, UINT Plane); - + + /** + * \brief Queries paged resource from resource pointer + * + * \param [in] resource The resource + * \returns Paged resource object + */ + Rc GetPagedResource( + ID3D11Resource* pResource); + /** * \brief Increments private reference count of a resource * From ca41bb4ea441cff3db7d52d4926c04671cae740c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 21 Aug 2022 16:22:23 +0200 Subject: [PATCH 0704/1348] [d3d11] Implement CopyTileMappings --- src/d3d11/d3d11_context.cpp | 77 ++++++++++++++++++++++++++++++++++--- src/d3d11/d3d11_context.h | 4 +- 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index cf8fe3171..fc08621e4 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2638,17 +2638,82 @@ namespace dxvk { template HRESULT STDMETHODCALLTYPE D3D11CommonContext::CopyTileMappings( ID3D11Resource* pDestTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pDestRegionStartCoordinate, + const D3D11_TILED_RESOURCE_COORDINATE* pDestRegionCoordinate, ID3D11Resource* pSourceTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionStartCoordinate, + const D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionCoordinate, const D3D11_TILE_REGION_SIZE* pTileRegionSize, UINT Flags) { - static bool s_errorShown = false; + if (!pDestTiledResource || !pSourceTiledResource) + return E_INVALIDARG; - if (!std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::CopyTileMappings: Not implemented"); + if constexpr (!IsDeferred) + GetTypedContext()->FlushImplicit(false); - return DXGI_ERROR_INVALID_CALL; + DxvkSparseBindInfo bindInfo; + bindInfo.dstResource = GetPagedResource(pDestTiledResource); + bindInfo.srcResource = GetPagedResource(pSourceTiledResource); + + auto dstPageTable = bindInfo.dstResource->getSparsePageTable(); + auto srcPageTable = bindInfo.srcResource->getSparsePageTable(); + + if (!dstPageTable || !srcPageTable) + return E_INVALIDARG; + + if (pDestRegionCoordinate->Subresource >= dstPageTable->getSubresourceCount() + || pSourceRegionCoordinate->Subresource >= srcPageTable->getSubresourceCount()) + return E_INVALIDARG; + + VkOffset3D dstRegionOffset = { + int32_t(pDestRegionCoordinate->X), + int32_t(pDestRegionCoordinate->Y), + int32_t(pDestRegionCoordinate->Z) }; + + VkOffset3D srcRegionOffset = { + int32_t(pSourceRegionCoordinate->X), + int32_t(pSourceRegionCoordinate->Y), + int32_t(pSourceRegionCoordinate->Z) }; + + VkExtent3D regionExtent = { + uint32_t(pTileRegionSize->Width), + uint32_t(pTileRegionSize->Height), + uint32_t(pTileRegionSize->Depth) }; + + for (uint32_t i = 0; i < pTileRegionSize->NumTiles; i++) { + // We don't know the current tile mappings of either resource since + // this may be called on a deferred context and tile mappings are + // updated on the CS thread, so just resolve the copy in the backend + uint32_t dstTile = dstPageTable->computePageIndex( + pDestRegionCoordinate->Subresource, dstRegionOffset, + regionExtent, !pTileRegionSize->bUseBox, i); + + uint32_t srcTile = srcPageTable->computePageIndex( + pSourceRegionCoordinate->Subresource, srcRegionOffset, + regionExtent, !pTileRegionSize->bUseBox, i); + + if (dstTile >= dstPageTable->getPageCount() + || srcTile >= srcPageTable->getPageCount()) + return E_INVALIDARG; + + DxvkSparseBind bind; + bind.mode = DxvkSparseBindMode::Copy; + bind.dstPage = dstTile; + bind.srcPage = srcTile; + + bindInfo.binds.push_back(bind); + } + + DxvkSparseBindFlags flags = (Flags & D3D11_TILE_MAPPING_NO_OVERWRITE) + ? DxvkSparseBindFlags(DxvkSparseBindFlag::SkipSynchronization) + : DxvkSparseBindFlags(); + + EmitCs([ + cBindInfo = std::move(bindInfo), + cFlags = flags + ] (DxvkContext* ctx) { + ctx->updatePageTable(cBindInfo, cFlags); + }); + + return S_OK; } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 851087270..205d3fa7e 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -699,9 +699,9 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE CopyTileMappings( ID3D11Resource* pDestTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pDestRegionStartCoordinate, + const D3D11_TILED_RESOURCE_COORDINATE* pDestRegionCoordinate, ID3D11Resource* pSourceTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionStartCoordinate, + const D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionCoordinate, const D3D11_TILE_REGION_SIZE* pTileRegionSize, UINT Flags); From 0a222aaaf0e15cdb8166aff460255f2a7bea599a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 23 Aug 2022 03:45:01 +0200 Subject: [PATCH 0705/1348] [d3d11] Implement CopyTiles and UpdateTiles --- src/d3d11/d3d11_context.cpp | 130 ++++++++++++++++++++++++++++++++++-- src/d3d11/d3d11_context.h | 7 ++ 2 files changed, 131 insertions(+), 6 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index fc08621e4..6173068ef 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2628,10 +2628,25 @@ namespace dxvk { ID3D11Buffer* pBuffer, UINT64 BufferStartOffsetInBytes, UINT Flags) { - static bool s_errorShown = false; + if (!pTiledResource || !pBuffer) + return; - if (!std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::CopyTiles: Not implemented"); + auto buffer = static_cast(pBuffer); + + // Get buffer slice and just forward the call + VkDeviceSize bufferSize = pTileRegionSize->NumTiles * SparseMemoryPageSize; + + if (buffer->Desc()->ByteWidth < BufferStartOffsetInBytes + bufferSize) + return; + + DxvkBufferSlice slice = buffer->GetBufferSlice(BufferStartOffsetInBytes, bufferSize); + + CopyTiledResourceData(pTiledResource, + pTileRegionStartCoordinate, + pTileRegionSize, slice, Flags); + + if (buffer->HasSequenceNumber()) + GetTypedContext()->TrackBufferSequenceNumber(buffer); } @@ -2927,10 +2942,25 @@ namespace dxvk { const D3D11_TILE_REGION_SIZE* pDestTileRegionSize, const void* pSourceTileData, UINT Flags) { - bool s_errorShown = false; + if (!pDestTiledResource || !pSourceTileData) + return; - if (std::exchange(s_errorShown, true)) - Logger::err("D3D11DeviceContext::UpdateTiles: Not implemented"); + // Allocate staging memory and copy source data into it, at a + // 64k page granularity. It is not clear whether this behaviour + // is correct in case we're writing to incmplete pages. + VkDeviceSize bufferSize = pDestTileRegionSize->NumTiles * SparseMemoryPageSize; + + DxvkBufferSlice slice = AllocStagingBuffer(bufferSize); + std::memcpy(slice.mapPtr(0), pSourceTileData, bufferSize); + + // Fix up flags. The runtime probably validates this in some + // way but our internal function relies on correct flags anyway. + Flags &= D3D11_TILE_MAPPING_NO_OVERWRITE; + Flags |= D3D11_TILE_COPY_LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE; + + CopyTiledResourceData(pDestTiledResource, + pDestTileRegionStartCoordinate, + pDestTileRegionSize, slice, Flags); } @@ -4016,6 +4046,94 @@ namespace dxvk { } + template + void D3D11CommonContext::CopyTiledResourceData( + ID3D11Resource* pResource, + const D3D11_TILED_RESOURCE_COORDINATE* pRegionCoordinate, + const D3D11_TILE_REGION_SIZE* pRegionSize, + DxvkBufferSlice BufferSlice, + UINT Flags) { + Rc resource = GetPagedResource(pResource); + + // Do some validation based on page table properties + auto pageTable = resource->getSparsePageTable(); + + if (!pageTable) + return; + + if (pRegionSize->bUseBox && pRegionSize->NumTiles != + pRegionSize->Width * pRegionSize->Height * pRegionSize->Depth) + return; + + if (pRegionSize->NumTiles > pageTable->getPageCount()) + return; + + // Ignore call if buffer access would be out of bounds + VkDeviceSize bufferSize = pRegionSize->NumTiles * SparseMemoryPageSize; + + if (BufferSlice.length() < bufferSize) + return; + + // Compute list of tile indices to copy + std::vector tiles(pRegionSize->NumTiles); + + for (uint32_t i = 0; i < pRegionSize->NumTiles; i++) { + VkOffset3D regionOffset = { + int32_t(pRegionCoordinate->X), + int32_t(pRegionCoordinate->Y), + int32_t(pRegionCoordinate->Z) }; + + VkExtent3D regionExtent = { + uint32_t(pRegionSize->Width), + uint32_t(pRegionSize->Height), + uint32_t(pRegionSize->Depth) }; + + uint32_t tile = pageTable->computePageIndex( + pRegionCoordinate->Subresource, regionOffset, + regionExtent, !pRegionSize->bUseBox, i); + + // Check that the tile is valid and not part of the mip tail + auto tileInfo = pageTable->getPageInfo(tile); + + if (tileInfo.type != DxvkSparsePageType::Buffer + && tileInfo.type != DxvkSparsePageType::Image) + return; + + tiles[i] = tile; + } + + // If D3D12 is anything to go by, not passing this flag will trigger + // the other code path, regardless of whether TO_LINEAR_BUFFER is set. + if (Flags & D3D11_TILE_COPY_LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE) { + EmitCs([ + cResource = std::move(resource), + cTiles = std::move(tiles), + cBuffer = std::move(BufferSlice) + ] (DxvkContext* ctx) { + ctx->copySparsePagesFromBuffer( + cResource, + cTiles.size(), + cTiles.data(), + cBuffer.buffer(), + cBuffer.offset()); + }); + } else { + EmitCs([ + cResource = std::move(resource), + cTiles = std::move(tiles), + cBuffer = std::move(BufferSlice) + ] (DxvkContext* ctx) { + ctx->copySparsePagesToBuffer( + cBuffer.buffer(), + cBuffer.offset(), + cResource, + cTiles.size(), + cTiles.data()); + }); + } + } + + template void D3D11CommonContext::DiscardBuffer( ID3D11Resource* pResource) { diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 205d3fa7e..ec2db673a 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -885,6 +885,13 @@ namespace dxvk { VkOffset3D SrcOffset, VkExtent3D SrcExtent); + void CopyTiledResourceData( + ID3D11Resource* pResource, + const D3D11_TILED_RESOURCE_COORDINATE* pRegionCoordinate, + const D3D11_TILE_REGION_SIZE* pRegionSize, + DxvkBufferSlice BufferSlice, + UINT Flags); + void DiscardBuffer( ID3D11Resource* pResource); From 790da795127dd87b34d6f6b113a1ee003749365a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 25 Aug 2022 16:18:21 +0200 Subject: [PATCH 0706/1348] [d3d11] Implement min/max filters --- src/d3d11/d3d11_device.cpp | 7 +++++-- src/d3d11/d3d11_sampler.cpp | 10 +++++----- src/d3d11/d3d11_util.cpp | 18 ++++++++++++++++++ src/d3d11/d3d11_util.h | 11 ++++++++--- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 2dd70877f..efa63019d 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1157,8 +1157,11 @@ namespace dxvk { if (FAILED(D3D11SamplerState::NormalizeDesc(&desc))) return E_INVALIDARG; - - if (ppSamplerState == nullptr) + + if (IsMinMaxFilter(desc.Filter) && m_tiledResourcesTier < D3D11_TILED_RESOURCES_TIER_2) + return E_INVALIDARG; + + if (!ppSamplerState) return S_FALSE; try { diff --git a/src/d3d11/d3d11_sampler.cpp b/src/d3d11/d3d11_sampler.cpp index 335717766..27767b5a0 100644 --- a/src/d3d11/d3d11_sampler.cpp +++ b/src/d3d11/d3d11_sampler.cpp @@ -31,10 +31,10 @@ namespace dxvk { info.addressModeV = DecodeAddressMode(desc.AddressV); info.addressModeW = DecodeAddressMode(desc.AddressW); - info.compareToDepth = (filterBits & 0x80) ? VK_TRUE : VK_FALSE; + info.compareToDepth = (filterBits & 0x180) == 0x80 ? VK_TRUE : VK_FALSE; info.compareOp = DecodeCompareOp(desc.ComparisonFunc); - - info.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; + + info.reductionMode = DecodeReductionMode(filterBits); for (uint32_t i = 0; i < 4; i++) info.borderColor.float32[i] = desc.BorderColor[i]; @@ -100,7 +100,7 @@ namespace dxvk { HRESULT D3D11SamplerState::NormalizeDesc(D3D11_SAMPLER_DESC* pDesc) { const uint32_t filterBits = uint32_t(pDesc->Filter); - if (filterBits & 0xFFFFFF2A) { + if (filterBits & 0xFFFFFE2A) { Logger::err(str::format( "D3D11SamplerState: Unhandled filter: ", filterBits)); return E_INVALIDARG; @@ -114,7 +114,7 @@ namespace dxvk { pDesc->MaxAnisotropy = 0; } - if (filterBits & 0x80 /* compare-to-depth */) { + if ((filterBits & 0x180) == 0x80 /* compare-to-depth */) { if (!ValidateComparisonFunc(pDesc->ComparisonFunc)) return E_INVALIDARG; } else { diff --git a/src/d3d11/d3d11_util.cpp b/src/d3d11/d3d11_util.cpp index 6c31ce3f7..f8208928a 100644 --- a/src/d3d11/d3d11_util.cpp +++ b/src/d3d11/d3d11_util.cpp @@ -64,6 +64,19 @@ namespace dxvk { } + VkSamplerReductionMode DecodeReductionMode( + UINT Filter) { + switch (Filter & 0x180) { + default: + return VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; + case 0x100: + return VK_SAMPLER_REDUCTION_MODE_MIN; + case 0x180: + return VK_SAMPLER_REDUCTION_MODE_MAX; + } + } + + VkConservativeRasterizationModeEXT DecodeConservativeRasterizationMode( D3D11_CONSERVATIVE_RASTERIZATION_MODE Mode) { switch (Mode) { @@ -125,4 +138,9 @@ namespace dxvk { } } + + BOOL IsMinMaxFilter(D3D11_FILTER Filter) { + return DecodeReductionMode(uint32_t(Filter)) != VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; + } + } \ No newline at end of file diff --git a/src/d3d11/d3d11_util.h b/src/d3d11/d3d11_util.h index beb3e13bc..8720bbbb3 100644 --- a/src/d3d11/d3d11_util.h +++ b/src/d3d11/d3d11_util.h @@ -21,13 +21,16 @@ namespace dxvk { HRESULT DecodeSampleCount( UINT Count, VkSampleCountFlagBits* pCount); - + VkSamplerAddressMode DecodeAddressMode( D3D11_TEXTURE_ADDRESS_MODE mode); - + VkCompareOp DecodeCompareOp( D3D11_COMPARISON_FUNC Mode); - + + VkSamplerReductionMode DecodeReductionMode( + UINT Filter); + VkConservativeRasterizationModeEXT DecodeConservativeRasterizationMode( D3D11_CONSERVATIVE_RASTERIZATION_MODE Mode); @@ -40,6 +43,8 @@ namespace dxvk { VkFormat GetPackedDepthStencilFormat( DXGI_FORMAT Format); + BOOL IsMinMaxFilter(D3D11_FILTER Filter); + /** * \brief Translates D3D11 shader stage to corresponding Vulkan stage * From 91ff6d68e173df0b20fb3fc458bd32d28de0e2f7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 01:52:31 +0200 Subject: [PATCH 0707/1348] [d3d11] Expose support for tiled resources --- src/d3d11/d3d11_device.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index efa63019d..314d3b2e3 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1658,8 +1658,8 @@ namespace dxvk { // Min/Max filtering requires Tiled Resources Tier 2 for some reason, // so we cannot support it even though Vulkan exposes this feature - info->TiledResourcesTier = D3D11_TILED_RESOURCES_NOT_SUPPORTED; - info->MinMaxFiltering = FALSE; + info->TiledResourcesTier = m_tiledResourcesTier; + info->MinMaxFiltering = m_tiledResourcesTier >= D3D11_TILED_RESOURCES_TIER_2; info->ClearViewAlsoSupportsDepthOnlyFormats = TRUE; info->MapOnDefaultBuffers = TRUE; } return S_OK; @@ -1707,7 +1707,7 @@ namespace dxvk { info->ROVsSupported = FALSE; info->ConservativeRasterizationTier = D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED; info->MapOnDefaultTextures = TRUE; - info->TiledResourcesTier = D3D11_TILED_RESOURCES_NOT_SUPPORTED; + info->TiledResourcesTier = m_tiledResourcesTier; info->StandardSwizzle = FALSE; info->UnifiedMemoryArchitecture = m_dxvkDevice->isUnifiedMemoryArchitecture(); From 91bdc8d06c94c85d8ce364532ecd17f2ae887521 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 22 Aug 2022 21:55:44 +0200 Subject: [PATCH 0708/1348] [d3d11] Expose feature level 12_0 --- src/d3d11/d3d11_device.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 314d3b2e3..0865f0e77 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2007,6 +2007,15 @@ namespace dxvk { if (!adapter->checkFeatureSupport(features)) return false; + if (featureLevel >= D3D_FEATURE_LEVEL_12_0) { + D3D11_TILED_RESOURCES_TIER tiledResourcesTier = DetermineTiledResourcesTier( + adapter->features(), + adapter->devicePropertiesExt()); + + if (tiledResourcesTier < D3D11_TILED_RESOURCES_TIER_2) + return false; + } + // TODO also check for required limits return true; } @@ -2609,9 +2618,10 @@ namespace dxvk { return pair.first == maxLevel; }); - return entry != s_featureLevels.end() - ? entry->second - : D3D_FEATURE_LEVEL_11_1; + if (entry != s_featureLevels.end()) + return entry->second; + + return D3D_FEATURE_LEVEL_12_0; } From 2f3b3e64b4238ad5bcc4a8e06a05a0ea0fdc4a2a Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 22 Aug 2022 01:18:37 +0000 Subject: [PATCH 0709/1348] [native] Add extra definitions needed for D3DCompiler --- include/native/windows/windows_base.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/native/windows/windows_base.h b/include/native/windows/windows_base.h index 747ef303f..7f0990031 100644 --- a/include/native/windows/windows_base.h +++ b/include/native/windows/windows_base.h @@ -96,7 +96,18 @@ typedef HANDLE HWND; typedef HANDLE HKEY; typedef DWORD COLORREF; +#if INTPTR_MAX == INT64_MAX +typedef int64_t INT_PTR; +typedef uint64_t UINT_PTR; +#else +typedef int32_t INT_PTR; +typedef uint32_t UINT_PTR; +#endif +typedef INT_PTR* PINT_PTR; +typedef UINT_PTR* PUINT_PTR; + typedef char* LPSTR; +typedef wchar_t* LPWSTR; typedef const char* LPCSTR; typedef const wchar_t* LPCWSTR; From a29896642c1fdedf5a0a76985cb8aeb6ebfa5954 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 22 Aug 2022 01:23:26 +0000 Subject: [PATCH 0710/1348] [native] Bump DirectX headers For _mingw_unicode for D3DCompiler --- include/native/directx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/native/directx b/include/native/directx index 9ae01457f..9df86f234 160000 --- a/include/native/directx +++ b/include/native/directx @@ -1 +1 @@ -Subproject commit 9ae01457f3f52b90fcdb472fc8ad86a0c89c15e5 +Subproject commit 9df86f2341616ef1888ae59919feaa6d4fad693d From bfd47ec8767e7589f86ce4b54372669da2963907 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Fri, 26 Aug 2022 21:51:50 +0200 Subject: [PATCH 0711/1348] [d3d9] Try to match either top or bottom mips in UpdateTexture --- src/d3d9/d3d9_device.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 54b1ab10b..88e5327fc 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -823,9 +823,19 @@ namespace dxvk { uint32_t mipLevels = dstTexInfo->IsAutomaticMip() ? 1 : dstTexInfo->Desc()->MipLevels; uint32_t arraySlices = std::min(srcTexInfo->Desc()->ArraySize, dstTexInfo->Desc()->ArraySize); - uint32_t srcMipOffset = srcTexInfo->Desc()->MipLevels - mipLevels; - VkExtent3D srcFirstMipExtent = util::computeMipLevelExtent(srcTexInfo->GetExtent(), srcMipOffset); + uint32_t srcMipOffset = 0; + VkExtent3D srcFirstMipExtent = srcTexInfo->GetExtent(); VkExtent3D dstFirstMipExtent = dstTexInfo->GetExtent(); + + if (srcFirstMipExtent != dstFirstMipExtent) { + // UpdateTexture can be used with textures that have different mip lengths. + // It will either match the the top mips or the bottom ones. + + srcMipOffset = srcTexInfo->Desc()->MipLevels - mipLevels; + srcFirstMipExtent = util::computeMipLevelExtent(srcTexInfo->GetExtent(), srcMipOffset); + dstFirstMipExtent = dstTexInfo->GetExtent(); + } + if (srcFirstMipExtent != dstFirstMipExtent) return D3DERR_INVALIDCALL; From f6fcbb7127aa30a15f3638c66e3db414b1f673de Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 26 Aug 2022 17:40:09 +0000 Subject: [PATCH 0712/1348] [util] Rename CloseLibrary to FreeLibrary in win32 compat headers Typo... --- src/util/util_win32_compat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/util_win32_compat.h b/src/util/util_win32_compat.h index 41eaf9c61..05597bd74 100644 --- a/src/util/util_win32_compat.h +++ b/src/util/util_win32_compat.h @@ -11,7 +11,7 @@ inline HMODULE LoadLibraryA(LPCSTR lpLibFileName) { return dlopen(lpLibFileName, RTLD_NOW); } -inline void CloseLibrary(HMODULE module) { +inline void FreeLibrary(HMODULE module) { dlclose(module); } From 482a7e433bd0214372d7049218d51ea3a76052dd Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 26 Aug 2022 17:33:25 +0000 Subject: [PATCH 0713/1348] [vulkan] Make LibraryLoader dynamically load vulkan-1 This makes LibraryLoader actually load the library and moves ownership of GetInstanceProcAddr into it, which means we pass through the loaders into their parents to grab stuff. --- meson.build | 2 -- src/dxvk/dxvk_adapter.cpp | 2 +- src/dxvk/dxvk_instance.cpp | 2 +- src/vulkan/meson.build | 2 +- src/vulkan/vulkan_loader.cpp | 39 +++++++++++++++++++++++++----------- src/vulkan/vulkan_loader.h | 27 ++++++++++++++++--------- 6 files changed, 48 insertions(+), 26 deletions(-) diff --git a/meson.build b/meson.build index e8b15fa96..b24c3a920 100644 --- a/meson.build +++ b/meson.build @@ -69,7 +69,6 @@ if platform == 'windows' dxvk_library_path = meson.current_source_dir() + '/lib32' endif - lib_vulkan = cpp.find_library('vulkan-1', dirs : dxvk_library_path) lib_d3d9 = cpp.find_library('d3d9') lib_d3d11 = cpp.find_library('d3d11') lib_dxgi = cpp.find_library('dxgi') @@ -100,7 +99,6 @@ if platform == 'windows' dxvk_wsi = 'win32' compiler_args += ['-DDXVK_WSI_WIN32'] else - lib_vulkan = cpp.find_library('vulkan') lib_sdl2 = cpp.find_library('SDL2') wrc = find_program('touch') diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 4479686fa..09d2c7994 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -523,7 +523,7 @@ namespace dxvk { throw DxvkError("DxvkAdapter: Failed to create device"); return new DxvkDevice(instance, this, - new vk::DeviceFn(true, m_vki->instance(), device), + new vk::DeviceFn(m_vki, true, device), devExtensions, enabledFeatures); } diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index 5efa4cf82..0d8d5a075 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -33,7 +33,7 @@ namespace dxvk { provider->initInstanceExtensions(); m_vkl = new vk::LibraryFn(); - m_vki = new vk::InstanceFn(true, this->createInstance()); + m_vki = new vk::InstanceFn(m_vkl, true, this->createInstance()); m_adapters = this->queryAdapters(); diff --git a/src/vulkan/meson.build b/src/vulkan/meson.build index 91350ea10..7fa26c18d 100644 --- a/src/vulkan/meson.build +++ b/src/vulkan/meson.build @@ -7,7 +7,7 @@ vkcommon_src = files([ thread_dep = dependency('threads') vkcommon_lib = static_library('vkcommon', vkcommon_src, - dependencies : [ thread_dep, lib_vulkan ], + dependencies : [ thread_dep ], include_directories : [ dxvk_include_path ], ) diff --git a/src/vulkan/vulkan_loader.cpp b/src/vulkan/vulkan_loader.cpp index faa5155f9..49ed5cf28 100644 --- a/src/vulkan/vulkan_loader.cpp +++ b/src/vulkan/vulkan_loader.cpp @@ -1,26 +1,41 @@ #include "vulkan_loader.h" +#include "../util/util_win32_compat.h" + namespace dxvk::vk { - static const PFN_vkGetInstanceProcAddr GetInstanceProcAddr = vkGetInstanceProcAddr; + LibraryLoader::LibraryLoader() + : m_library(LoadLibraryA("vulkan-1")) + , m_getInstanceProcAddr(reinterpret_cast( + GetProcAddress(m_library, "vkGetInstanceProcAddr"))) { + } + + LibraryLoader::~LibraryLoader() { + FreeLibrary(m_library); + } + + PFN_vkVoidFunction LibraryLoader::sym(VkInstance instance, const char* name) const { + return m_getInstanceProcAddr(instance, name); + } PFN_vkVoidFunction LibraryLoader::sym(const char* name) const { - return dxvk::vk::GetInstanceProcAddr(nullptr, name); + return sym(nullptr, name); } - InstanceLoader::InstanceLoader(bool owned, VkInstance instance) - : m_instance(instance), m_owned(owned) { } + InstanceLoader::InstanceLoader(const Rc& library, bool owned, VkInstance instance) + : m_library(library), m_instance(instance), m_owned(owned) { } PFN_vkVoidFunction InstanceLoader::sym(const char* name) const { - return dxvk::vk::GetInstanceProcAddr(m_instance, name); + return m_library->sym(m_instance, name); } - DeviceLoader::DeviceLoader(bool owned, VkInstance instance, VkDevice device) - : m_getDeviceProcAddr(reinterpret_cast( - dxvk::vk::GetInstanceProcAddr(instance, "vkGetDeviceProcAddr"))), + DeviceLoader::DeviceLoader(const Rc& library, bool owned, VkDevice device) + : m_library(library) + , m_getDeviceProcAddr(reinterpret_cast( + m_library->sym("vkGetDeviceProcAddr"))), m_device(device), m_owned(owned) { } @@ -33,16 +48,16 @@ namespace dxvk::vk { LibraryFn::~LibraryFn() { } - InstanceFn::InstanceFn(bool owned, VkInstance instance) - : InstanceLoader(owned, instance) { } + InstanceFn::InstanceFn(const Rc& library, bool owned, VkInstance instance) + : InstanceLoader(library, owned, instance) { } InstanceFn::~InstanceFn() { if (m_owned) this->vkDestroyInstance(m_instance, nullptr); } - DeviceFn::DeviceFn(bool owned, VkInstance instance, VkDevice device) - : DeviceLoader(owned, instance, device) { } + DeviceFn::DeviceFn(const Rc& library, bool owned, VkDevice device) + : DeviceLoader(library, owned, device) { } DeviceFn::~DeviceFn() { if (m_owned) this->vkDestroyDevice(m_device, nullptr); diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 6f469c650..ff56cb01c 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -10,15 +10,22 @@ ::PFN_ ## name name = reinterpret_cast<::PFN_ ## name>(sym(#name)) namespace dxvk::vk { - + /** * \brief Vulkan library loader * - * Provides methods to load Vulkan functions that - * can be called before creating a instance. + * Dynamically loads the vulkan-1 library and + * provides methods to load Vulkan functions that + * can be called before creating a instance. */ struct LibraryLoader : public RcObject { + LibraryLoader(); + ~LibraryLoader(); + PFN_vkVoidFunction sym(VkInstance instance, const char* name) const; PFN_vkVoidFunction sym(const char* name) const; + protected: + const HMODULE m_library; + const PFN_vkGetInstanceProcAddr m_getInstanceProcAddr; }; @@ -29,12 +36,13 @@ namespace dxvk::vk { * called for a specific instance. */ struct InstanceLoader : public RcObject { - InstanceLoader(bool owned, VkInstance instance); + InstanceLoader(const Rc& library, bool owned, VkInstance instance); PFN_vkVoidFunction sym(const char* name) const; VkInstance instance() const { return m_instance; } protected: - const VkInstance m_instance; - const bool m_owned; + Rc m_library; + const VkInstance m_instance; + const bool m_owned; }; @@ -45,10 +53,11 @@ namespace dxvk::vk { * specific device. */ struct DeviceLoader : public RcObject { - DeviceLoader(bool owned, VkInstance instance, VkDevice device); + DeviceLoader(const Rc& library, bool owned, VkDevice device); PFN_vkVoidFunction sym(const char* name) const; VkDevice device() const { return m_device; } protected: + Rc m_library; const PFN_vkGetDeviceProcAddr m_getDeviceProcAddr; const VkDevice m_device; const bool m_owned; @@ -78,7 +87,7 @@ namespace dxvk::vk { * are independent of any Vulkan devices. */ struct InstanceFn : InstanceLoader { - InstanceFn(bool owned, VkInstance instance); + InstanceFn(const Rc& library, bool owned, VkInstance instance); ~InstanceFn(); VULKAN_FN(vkCreateDevice); @@ -160,7 +169,7 @@ namespace dxvk::vk { * This ensures that no slow dispatch code is executed. */ struct DeviceFn : DeviceLoader { - DeviceFn(bool owned, VkInstance instance, VkDevice device); + DeviceFn(const Rc& library, bool owned, VkDevice device); ~DeviceFn(); VULKAN_FN(vkDestroyDevice); From 286ab017dad9944d7dbdb6e97a1b101409204f79 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 26 Aug 2022 17:38:26 +0000 Subject: [PATCH 0714/1348] [vulkan] Add valid method to LibraryLoader --- src/vulkan/vulkan_loader.cpp | 4 ++++ src/vulkan/vulkan_loader.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/vulkan/vulkan_loader.cpp b/src/vulkan/vulkan_loader.cpp index 49ed5cf28..c2b419e0e 100644 --- a/src/vulkan/vulkan_loader.cpp +++ b/src/vulkan/vulkan_loader.cpp @@ -21,6 +21,10 @@ namespace dxvk::vk { PFN_vkVoidFunction LibraryLoader::sym(const char* name) const { return sym(nullptr, name); } + + bool LibraryLoader::valid() const { + return m_getInstanceProcAddr != nullptr; + } InstanceLoader::InstanceLoader(const Rc& library, bool owned, VkInstance instance) diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index ff56cb01c..cf9ec1e6a 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -23,6 +23,7 @@ namespace dxvk::vk { ~LibraryLoader(); PFN_vkVoidFunction sym(VkInstance instance, const char* name) const; PFN_vkVoidFunction sym(const char* name) const; + bool valid() const; protected: const HMODULE m_library; const PFN_vkGetInstanceProcAddr m_getInstanceProcAddr; From 86efa46fcfe792ed0f96e012851a61f66d42455b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 26 Aug 2022 17:38:37 +0000 Subject: [PATCH 0715/1348] [dxvk] Throw DxvkError if we failed to load vulkan library --- src/dxvk/dxvk_instance.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index 0d8d5a075..8010e740b 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -33,6 +33,8 @@ namespace dxvk { provider->initInstanceExtensions(); m_vkl = new vk::LibraryFn(); + if (!m_vkl->valid()) + throw DxvkError("Failed to load vulkan-1 library."); m_vki = new vk::InstanceFn(m_vkl, true, this->createInstance()); m_adapters = this->queryAdapters(); From 2fa628fce600b6573e4250ab66c77b6c310caf77 Mon Sep 17 00:00:00 2001 From: Krzysztof Bogacki Date: Sat, 27 Aug 2022 20:48:20 +0200 Subject: [PATCH 0716/1348] [build] Remove vulkan-1.lib --- lib/vulkan-1.lib | Bin 38268 -> 0 bytes lib32/vulkan-1.lib | Bin 41304 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 lib/vulkan-1.lib delete mode 100755 lib32/vulkan-1.lib diff --git a/lib/vulkan-1.lib b/lib/vulkan-1.lib deleted file mode 100755 index 3c6574a94266e45aaa58d775feec7a0124e44fc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38268 zcmeHQTaaBv)m{Wdj4?(*jffI7hFgpzWM+aQ<}wMy+$J-*KnO`r=Imq+IdjhB%$dmr z2=^cmAV9c?`2Ut=QIzF_50+*9Wm%MEQ5FxB-{5AHGaDC879rs@uQ68};3+#d`z z4ihPwL>(2qxX;j|i;)lX(n3S6HAIR|HVuvaok-E-azl^&h)B_kZyS2yuSANP?;ARC z6_KK6mKv)6nMl#Z{f4q#M2aRLujt;N8|qFIDSGT7L&uO`QTLCAT5qCWpp(Bh)P$}S zO|LR^?k7ZwozczGyKgtEYu)xsv z-x4W0bD5!`8_?gN(?2xyJTMfEpl*srk*272r=dfCCQ@_|GMbj*7o^6DqT1Vr4*!%$ z({1<#4Wka4U}M9e5u_`+YoR6R>@Ltgv_;Wfe=>CE3L;IwyA!ngZ-(}~N2F-ib%ypF z#xrQ|dPAeofujA34edsIHJ!#UXx9Zp2YyDR=n!l|hVJes()0#?L8pccJ^ceBMNciVggQS3diqL3ZPZiI zsb3j-7IKQV?>BTFt$D6t#h)Xaebq&Mj4R z@ZjccLpz3d9UR;^vSE1h(5@ZB2dAf+$7-#wtfYenx9{G%wJ1RkvWOAbb;s`QTMiDc z+qDi^8sifOr;lyuWVLR#xi#6XwMH{4Fj#Ido9uSlr-We0VabiHsqw6XLWjmqO*Ter z&B1KCF`7-H?9wF8dwbUPb8SNHraC%vd0Khyc4xfS9qP0vvQD>AQc5UOTH5CE+R6iHs0>cP-HMb0vf2bn?j5;qgWnLh{Lz z*jsCKH`kkL64Em6nWaqGjy-)WV6fb}X0ttt3CNfxiVGMlx2comGU9>Lx78+G5&7So zy1O+l(&ZCNY-&zTjv?bjRyXAg*IGyQEL4`lIXAbaYt2SowIP;0napLl-Z9u4+T+mw zc-B&VP@cxQ*Ed@A^;1WVWF4o10!zy3InNW79F_#GEOasAh1wO4vu1v2aeve`YCJ(w;_k zA}CF>Sk^1S3Kw}SZA#X|%N1&#SiFy8CJmdl${q#(m1!M zgV#8nE!MU?!P#rh@=F~VtJN{zw(C=R5j0R9ljUv0yfjz5$K@QRu%X68)@-!04Ykp+ ze60Cg&S5e9LJv+mSvN=ysmdh09b1qZlNNs$gnW>$%|IAXh zj9e^Wu$;+_#L-S;qTB9ZB6Ia9PvhLS(0KMlBIgegys0oRRkJxyp;((K&gWcu3JyxN z>s-L)9K3nVlc5`BGbIU}Pi-g*c_K`f-#wxBdxacPHs>*V+tjIzXNUD>&DnwEu{6q7 zXLy<93|TT+-jqI^wJ<9U)h6?CB3LYI%N8lFXu)G?ObCX%4(Az3WT24K_7x+pCpNZ@?R2!f>PV-Y6H zug{J)T3!a|DZ*s=jjehpU0|`SY_D6`BTSaxFkV-CPo6uKy#*X0iGiY)#EEuCEv^uh z3}0?!v@to^*7KMa<7Z!LE7q>Pje2*?6_;~-$-!)*JGQ=2(?+XH%sIZ~`X&r~LtA^m z^td+l4A_1iQ&xMbRS(NIJYRYQ-h|Oc6Mce12TpX8$6WOzNzuG}F*>3-^Mq)=;S47@ zJ`xzkn#$w}BA@En!USadH{b`kHe-%B>Fmd5k<37T4;*rw!KzS!`)rYCuv60;$?>}W zD@f5mS>0$=2{5B5hvVj`HAX9FI7P|qWL8Hx#SC78%-5KlsC7rJZ4UBNL?S5GN;n2U2=dX*8gO%%hN5--LHXc`%Jk{wQSf(s#9mY>^%0(XzYRVMTqm$Ya(t zDeiHExBDFA?XCZ~PM##7)A))K+j-sZlfG4E&6t}A}j@=73yGAyNepHONNkxwnPECRG%ef zPiCVy#@MCacJ#)8$?|p|G&0pWQX9>-+%XJ27I`eK4s71-jmm=z|4fpnRKC{Gi1GjHNbfE!2x|`(`M*C@jind?jR!KC4@1uGJZ(iX|!oid4~-R7~X(jG+iI z)4C{|^FaHuhT#x0*8sLdR6|1nF2@5IGAa?%NHWDqn4>wTe zBqAzaM17F9@Fk)(h+b%(B>MXp%17Fd9wB-g>3@BJ==~o0Ux^h8`AGb zKfHtT29Y)m-p`Qt2-4pN|18q`?}jcwL#K#-@HEk)r%*QNO8kAH4Sj*X2>rSrZ5%oe z+j$&OQ=nz&qva11U5Y+?6TheNdnM#AMZYYC&cAUHBI#%zy+r$ICw-O<&=R_a9;GMg z7&WOz<1|eV(0z12b?F36(MfuOIy6ZwYSVF=fXO^f=jb#&MUTKdAEL+U3>~42j?#lv zr%@WCd#OQ(=@dOoXQ`jo&|S2Nw$oPnIDMDCM=R)B+C>}bYxE7egx1j=bTjRtZ_#r4 zCjA$^K>tkxbPMgH9T*^s=&N)c?WV8OZS*0!oz~N4T1|Ut3w?#w(lhiTEvAF?NxFhQ zL6_5|^m)36hUrTBB3(@j=~MI?y-weuo9G7m5-p`$>0|UNy+R+R%jhGtfacRj>C5yS zou}vNS^7S0pgy{jF3=a~b2LcH=w1i-zLd_9B~eC46nlYhezkVICyt{ZznLzLDs$DLhgz zxXOUCN@{FV;X7b=iffEb;zM4@FZH#=T?6VgU2?n)kKdx^Iw^gc&OID5pX0J8B1kl6 z=@`@bA%euhp-`l&ZIX7~M0ikb)I}uqnf5uAI*g2`s!)3D$UN&)plCtdSyFQHWHX5z z`%6#3`ph2pP&jQ%H9oE&=t8(W0nWP)mPbpLi5M{37xT|@#p4q4)6=*hp znSa*##YMf#oM3V1O_>Ws2XtDWnJZi{y-RAdfwnFL?|RLp_*bQViTR`y$(tuC<(n(^ zFuRHj%{x`sGC1P|ImB^AoCJKKp!0R9It(R1D!=n8-YxqG!R(_EG%uoD4%iF8dAymc zc)xf~iz+QLvNXQ%8~LU2-EY8kAvXbE1|bxZ3a7U~LOLt_q_RUAtVCT(1_tYKJ*C=| zn915C{MfbKGs;40(JGyYXO@=hTa{({X2nc#AInOxNxtDoW~`9~)3F)YKAcGfeBY*m z#K5R*YSF4}Ld2|WN@!QiE*KUk#4L-`a=&DtG3P8$4v#!d^^lqub-*aIu}E6G2+YZa z?wW|vSTt^4h7DggqR^HXW?K;BKAKgTEIebWzV|g>_ht$lP23_ULJw3@uuX;UL~d)n z5J}d7@-OMwev?ctba(ZkzD z`U!R{vJoZgacr7hrW!3`qBdtEScpawm0+`pY0F@L1jH0-B7SC^5D(zm#D3=J| zkSLYZ8Y%?JmWmrK=B;wG0s6yl(rje3-4))MCRzus29hii%Q`kM(> zI6O;5Q*KY0NyZZDKtGY_mJ_~#6KQ5e2_t`mfSdBQy0w#-Q)dkvCE_R;+BJ}p!xP~29H-*j`Z;;z97jYZ=zvF6HPU*ikK z-c3k`m8q7%2yMBDbcZg1r{zN5sj{a}j1-M&4q3P5Cekp73=P^Y|R+$k1i_E)2s8ZmTs@xGnUvbXaHx zcM-cP46}H9FUE@&(a%mNrZwQ@E(t9KTMe8M%r@?ZVoaGI2WG||=gFN8%wczfd!8{m zEO#*kd2;6hC#X|I9&YD36tswNC75RwSLVf5=(D8VK0`!2>JtjH?4Z|km*Dx%0#3*W zpeLWR^P^avMW4akqdE7hO=0BXv+PdNb%kz)IjeDr^6<~R;<2Ao+<4O^=_gMeyhBq) zrA63A-<{FZrBhbdy^TWJDKJ8Cv)?ova6%pF`2;;yceln=nM|Vg?Bt-$Jc^Tcx)8{ zJOE}Whs6>l`CDSOZ74hRMuVme6S|W3JBH~t4>&N$4Tg7uGf@%oW35PYM=`-e*W)NF z!zzl0SeY6%G9r^s)fQ1WWJZcf9WP_zW)27smgSP- zNLelvMy{1hieqF%D0P4|;)SE5X1l2qo3i|s#rSbiXK>S=?ot~~lsqEh#WHs|jK5@N zUp^NHLdy|HLH{N8@O5?njS;tM>fNWmK5AAzRoT^1b9uSb5AGm_b&?b0p>FzE^f)(t z%st=1V*IY9o8Gc={g#cW4*UZi%c;k; zwB)UM_`Mua9qQi#*{Eyj@*6GP%l&8 zxV0b@%KIm*H^VMj6k00!>lAC+|&PKOiKn>>3Cj0uVNiI>}$WkM-TU9S!?4k0myr(vTi-d4VMS3cpl~!#u?~OMv(xgV+e& zm_4=E|7SE zS6zb22G6E1SC`DIR{`^54l{Sz_kxvLHx@Eh@jgI8R@Z4_bbQ>yl%1;>a08>Q`UO9#MG0ySG@Nyn~{-f z-xUR{`~pcTRW^23m?bO6wXmH}NzCGLU&2-3m%L`7kSMDVe*~p7_cLT3nfxQA_4G zwVV1}fNDPgAR9TSws{rf<+r6hVez-JV>{E&3#>WYNhMaNFF3sLqE|MtYVW1ih^rY< z-Xcq|%6*p_4@(%$yQ7wHRoj-@317o#yjOD<;5{KGPBLF~i2m(*FL0U=3~G>|m8~?<#%l$ph?tOY z)peTa#p?=qHXfrV#MO!2#PtHvy5oDoa_-T{+5QHBC1Oc>!b^?78wH+=ROtz=zhpmg z9Y)}Ci57{2k-(L0G_kYzN)cBC+5D$aR}@i21W!+>B|28#wyz4*JUpl;w8ZGYiP8Mn zBMDb|^r!4~CF9A+rk>FH5_8QehZe+5^@Nx@5#DSNbx;srB}%Z$qav}|uP$Jj;GUlF z658w&c;3aR1gvZ=DSvmrj~GO&N!ZGIO{~HL0yTFhn%mx9FjHQdHBn3vXC;9v>o{ex zw|K}Vh)aUarDne-v4Rl6UNHMh&NRz0pMJfFS%^RE1v|C#xK&`!#m*yzrM}C+F@ZMP zPByEu&7|hl+a#6@RN#taqv~wYGN&37h)Bs^XhnsoyK~J z=OQbmDl3ou#4YUxfyM`78>1;9tG6&QlMhBPIRI3GR&Hma7dHybIXj~!b^)6N-dy>J zQaiZY1)htFmCCH%g9&ZkA<^=X+ura>Rtt6eyjkLT@w^hUs=cIE{%`q+#o%uVTwS+` zwr-KgUTC?5tlHMTl9RZ)sog3N3vufbv~oLB7Q0QOVkehJ!T0JjO6-!i7t!Wo9#8b+ z4vAR0F`vtR9FmBsEpp|4Jv-y5C7a}`?M+$Gu#a5aBv)={YDYdI(IVT% z$}KDLtf>3;T@ov@ZLErw@`vyCu*$ZLRS{E~+#?Yq+qbG%sk@rJ1+3z*uZ)*i8SnJ) zqT9F1R+;i_-X-yP1J~<3n%KMTi{V8!jFokoSfB2WVa7I$)is;g!R?o*C0oYItxT*? z_ei|5Eo1c-CQcd$Bw}>aSh;-(eIE4C;+w|Gc!`tEArG%~(^y@ji9W1(nBo<)o_0~G zIElj^V(E6VdMgulGiou_f~y?H=6^RRn^?IY6LwSAXvKH$dchkgX`On7BC~kj2W+A* za6{*pO%1!{04R)fO3e!ZX%l;~RptsnK#`CY@g*Fees=O)x)EMA8>)j{e;t>NSQ zZ`k!3)1C0A-K%j+-_(>{UVTI-&MLI7obA?62_-s9z0myD__VN>G{ zF&5fgwQc<+tH6ywYH6h8>#V4At7}MWRBwp{A zRjF#<10{2{dV%r&bWQwk2gpiP?t|1?^+3E9`IiZLLoV58twj6Jlpq(rd(cx221@on z>ILNo<2BGTK=G>zvKm$Gpg*C9hvKy;ezHMUpt=o|Sfbi1Jsht=zOecWdS&cXA3PGr z*87O!=O&~Is`kN}lJn-R(7>bdS|q<^(Mw$hN@m3Y)a9{~x|Dn3S_<_T(e9G?i=EvEbaZ)$I=NLEk zO_<(VTe23aSg>a_YWj;a5?nTaHZ5LV(z~Ap_OlvWe9lG!RqoT2r}jC66#M_Q_l8-r zzgBNyo!6LpL6e{2`H$f}pX137{q%&FiUWHg$Ftv(m9|mczmd9aelf?2JH4x0OUal} z5ib`sntp-D`;3J*+`Wg{jD*xp=}QH~-eYT1r$DE5B{E|CM z^{(uzITC+&s<%;4Vk?V*^&O1`@9BTIO|NMj?~_?QwJEjIf7f75;LBE7ZXR>sAuc%$ RsV{Q8t}*?uefjgr{{d;R(@y{Z diff --git a/lib32/vulkan-1.lib b/lib32/vulkan-1.lib deleted file mode 100755 index db227fd3e4610851f48d6e5687b6c5b664896ee7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41304 zcmeHQS&UrO(JmYECqHqB1B8%`7(xsfF!tCpV+fG(Hej$}GUJ8Sc#5JZ`h|Fic#5JZLQ%v6ilQhFDEaFwb#B$U=bY|4 zZQg!MMbE9}d}pb9mb!H>7hP9rj!oQf*40bozm>f!d;0rV_VxEk{tA1!az$^y`Fqz{ z01K`M7`YH&+h&06M*-%}H}udl07b`p3_bT307cL5vh)%DBE9erLoYS~6umHQ=-KT6 zik>`TX#c+e6y5)jp~sd2C_0ANiXQv9p<_SBYosUtY3L0sQ`4XE7wOS8hVIw^py&y# zucFs}V(9IE11LI<%M_2LTj4^P!>HA0Z#K9si8NAQ4i^EEK|`G)?Lx$1C|!yFH-fFmafHLqbO@4xM zq}oT8YWRzE*QbW=#(FBc2g_8n`)`KEwgV^{UuS3x>#Jxt_K&6}{vwT{FDTlD`L$?iY9o?{TWc~1_p{=(KkIv23CM)%;R>J7$t=l$lE^5Go zq+%4d-n8x3TShmm-MSV{s#DXWqjQt%n^~omZK}_-D)q5!U}X=4nWVoVn`t#0hn&G0 zr5|9D{>J+3RMtd@p@~B?)v-!#LpE0(%VsQ6QcPvsn6;$!Al7-diG^tNq&Qwiqd8S+ z4K*9nS+iAj6)F}M(uHk-``D^u0lA!cDl zzt9D7 zNY^^MmFRXASfuORn<~8VU@NQ7R2%g|uXn6kDBIK|Sh8-3D>l|Q`{$Mkcx*mh{wp6BVk*oAz%WKlw zR-bZurn`L(X%5zAXC|1^DTJ6x&nb+cniN+oQn&sA#Gan;sXF>O_-EH|j8F6$dp zIEGVMz2y&jP)?<+tJcTY&Fz`Amf;cWkGwVA2P;$o-A zrkw^WiGhR*N-6l|j7(RWGuE3#Y363YYU$FFYOGAT78@&FKw;fmrFRopemN7u(s!vE zC4<55U5`r^W*#5R^j3yV<2i>k?UbDh+%6_(k?wFdleILPwk>HBQVLy5C7Wyv%Er0;F7r90X-ns- z1s3UICulvtXM85)V?HbV+szezUP zU<;i9D>7Td`+l`vZDJC#H1#u+ho~H5k*=*7lelUz9%=KEw^y?RfzlnDYy^UndMJ)h zRt8B=0|F%Hkftp^7r3Hx7U^QoX(le-&1|MI+Z@Yq_t2Q7bv!MnQdr$wz1_)2ZP*=` zEO;HAP}bA2$;P0JOjO2kooS5E;s!$8puT|YELOlUCLv3MI8>d^YSntSzA`o;A&U~S zv?Ui6TpNobvc*0Z!VQ&H#ZJvp5!r6ZntL;0J!4H{60$UHy|IZ?Uv+GTia=|<8%;@N z3Alxrp2gFs?KD|HP)PP(pV`3;amhlCk9Az`6I2T(B3rLqrcoFoCL?QuJW`pOu4PT> zhKxtr7E7uJn51t?M}@Iwb-LAP;^fTgKzCM5PNi6Yn3`*5Oo7VrYg3rw^8%cRYzuX8 z8Uc7GBWu0f1WKQqj7i9nHvYLW_95*T5<;?9hXK#l?ByZ?vfDPT_T@p#sEBM$KMyu5 zQ`v64nHGNK^T`UaRJ_O+yYBS`WM|NZvpUYELzNlYLI>GoW3dWGVLn;mq-8ADVkitJ znEGt3(yX=)+2$q1REDXRI-XSO3$4@nY_cJzvU0Om z@I5XdBzxspo;dfofPn1QWqYf2AvZysFrTb8*2krd-Wi9uWWoEyZiMv85ayHB`l)es zlAw8*JUYN-7I>?w#ecfdq+=)+<1?lH$XIn|rr~B{tb5CMnWvx*{wNmazlx&1eZy7_=YGFb-f2h$hy}YaoTpUU>=LuK9vDGhpH^ z)`J2v&w3NiWCyKhnuDG-^#z{Yb_`FGA#IkdWl_XzH#92;?A{91-Ib@I!L#uJS0km! znMHjJYK-Cjn|#I^qGIJH27)_Ndk`QwH>dbVdH8zpomm4@IpqZDXPhJYf zS_lcVT;G^JM8iUD@_3%MIi|SbSIRky>8`6`98n!F>@iS{nqV>A9C2&I7DnC~7J0VX zW^2PX#Kc_?&(%$cn5|j$eX|0WSqxTdHDBN3G41uWtkPWHs5P3VRnBcf0^d&0DR$}z znTO?mDQjCTJQD*`Y9TmZ|Xqms#Kfzyl$OAvjD^FG-%R z$79+m9Hf;onxI!fEZO5RZCc6JRhrEzZv9OF0!=~!W~Y~99lprt43EdOaUnLk_AoOw zE;vk6x66e^^0EVbW~Ha`t<@>qJK}LAw+ir?m2!3mg#ac3!|&;!l$9`qvG06UbiP_- zGaKDYe9KAqZAifEZp{w1Fsw1H_O?_Wb)j_JoC%EPs>s<4@yViK~%n|3y{U7@V>%@Saee!&ma4xmD#n(-L|FIDs`+SWfOD&5jJ2rRBxqdZ>3CcXRtBS?>o{gmaN=RR@wQZEitS? zB^g&^s;bp?C#lm)0wS`-p69jpZ&JS^L#h)(N>rYxi`FhoVr^AqSs0LQX5-GSnYY_p zEFzbs?5NgP^+c)?l96@6Gqtk44Js|nAYikrz9mXp%p(hP4P{}T!W^dyM*uc&!yG8g z5j%elVA(?eJ;wq5@*L)UJrD2^(m!6noTe8s?+t&qKa2TrPXhdFKj!7#53uwxECchg zevZFC#@~OUtcl4}e@0sKD8Pn0u-qpAe)1Z?zu!hZEPE;beJ1K%iFsA0kdC7K4^IPZ zeForD#5wUg!22_Z{{XPhl=7%72CVTn8~ha3SV| zz55El@&>l!Ud;Ey-#75LXBJ@aL4Xgj{2$@p@8I8qhp;>>>o~S~@xuTEXm=jszSBb9 zG}>W5sHDT=DBFd&A7j~vvCRt+cOm{BzYpL##Qojv*oMb3R}JeofVS^roj*pqIn-bA zD!@5d);XyA+cyD*PD~kIx7|1nV*u+g|MR!_yAZFNNWU7zHt)iAqRvwMJ-dQ!#IhIf0eEjG zKp)C)!r$LuzSZKh$x2QGOnl{|=TngtB*$cMNU!q5K%~kDz>MhWV^WHy_0| zoWwDD3E+a45fACw!&pA@e}?V-a0m9=8<^vY{_}hEm3=ry6DN?G0Dr~bKjH7MvG0F@ zHow4fu3vz;z_1Wrg1g~|@O9V;OW-1S1RjS;s6hp$U=Hqwd*ME4;c(2tL3j+BFavdH zzBD{O>o;d(d|*1}D&3bw<|a3%Zz-h$`hZRm$<;7+&=w!mVz8ZLuv@O`)e zJ_k3#I@koOVF%m-SHS>01uwt_Fbe0udGHlD7yb*r4fnt>d;>0q@4(scRd@|M=2ch$ z%iz0k30wzXf>+=qd>+04{|$@aEchaP51xT%;W>C3PQiNUh1=mpxDdVx8(=BC4Clkw zU>Dp4L(l`4!%FxTjKCHD-*fZsxic_-az6Q(F6*-0o+lBlr3HdiaNEYCQYyR0SFtH9 z>aa#4eK?UJR$N4!v>Hg5;X=KIW0^4|!-Ho0)Y#@g6bZ5MqOn>S#-V7K-fDPaI_Bzg ziziEl%i@ulHj#q)2Qpao@)(Z}tOX@JFytxZVTzC-7W;{wmsufdkLDt90e&p1)=9jP z7nesJ^AeduqF<%rjIroL+4C{0Q9Ps-KctiM@!$(9G8snD0g*f?#LUv65|qk76|=+u zRA=FQdUPOd(;@v}T@f+yoFe|jBl3Je*2gMEWAq4aRZ@=u#G@MqkcxT6<87&kls*F4 zP${2#&GEqqB3UGMW_C{!T|IS~>M=?ohe4|3t3srVTtSVQ$*Cz;(&V$s$+X?cuH-Q* z;71yvn1*KxPCqaXCy2$l5Xy4akF8{Jbl2zkH(`0SlU-CY(9bOBSFA8k z*pQg1%)UaRk!RY`vDO`nb)bW7EX*LKPPR7A6u2>jq%aUx8oM>D7=P?`sNnbojj-oC zHI>S(qD|C4R#0?UD=2y_3A~&MufU=|TD!1Al8|26Db|oYQuvcKBU#Z~J%xa~T8*&3 zT4BUttu*AZBob+@UKd4umW*Y<+PC(Dow+=gu8%thxjV*?J6U;eD#TvAh^S+~inl5F zhTWA+(@n5!w!<$N_@y)FaJn)CZ=MWLWjjgmkEDXQBEq>zTpT!%VD!q&2u3E-)cMS( z;)ePq3!|q7iMPR}qbQJRVT z>~bd3vqk&f(`qK6KA^1Pu6~)}A zqvQ9Z@C_^DU^*L#%-iKsYyXM7L8E2zX&V)*MeH>?!B=jJBEkvrsLaEz~@HbYCXwUgOGTvCGOx}4^g1u;PDILd4GJ+b!wn>fXn_|O(>yOCrg=2*JQijI z;T#)&L$h=%_D)rv286mY=A{e98>blUB8iD*QJhP1i^;6{5sx%QREwBAp5=JqR8~(c zV_2S0Mz2UH;#Qhjh*)W^7ppQnl`~t&r}E=dsLELG{7q~-f4Qle@r%(Y66TXe!7dlc zb9ip558!6j6G0`lH;<$mq@MhXQT1X>1nNhZh#!tCk<`o&yr!B{=t4TyQS!5{1l=k5 ziJXch2|J3D$jvb{vFf6{!#64OQ@7)ZIvK)0Vv}Jg669WRU@;(%$GQ&v zM7=>$bU!P|{fN0(LFW6IQ=ll1s{nTstCdG~oL13MtSHh5b?MPlk-D7W9!YobxKuMDoSF^Y}Q>YajT#djf`kbeOI!Wh-UiH5Y5y# zpy{1(KWK$y1SBsf9Q!cxK-5DEqz|Oy9SMU%q$8lqV;muID7q2Q(>)T5YXp={*UC^u zK&`EU_NZVKBT!nq_(jMh9=V8Xdohc+VkkE^uI_1 z-E#G*p2{UXBsdTM_+O+yTgDmqI{+)*vwD4&jd^MK5AjG(T@JvK_ZH&sxtN!x{w?B- zx)jb`{CQ-m0@XiNz{#EGY^jbl8#9ePttFQYU%q7Xrdw~(Qtv;D@LCzF0x$9Y1VqJ|AdYUILOO#utCbEia-H6s zqxcu8|JZ-3EX-@PSL$aWW(ndK4(F9GcKW=fr*|dumWA3|{zunN)iLZX<64yehk45? z;wo?X30>G<~*Pb-y*d^k3>`X z=t1eR?CS~RE<@Y}m`AH{?N{3D5@MDXy^9yn{Gt;tN+BrVH`y{p4*z8Kql zhD6Q}6uf!BFFI*!Z+{r^dx&_ZK@5hlIZpYp?RDRdmOga}qJGYzVho!fl2m|Pfbxru zTG|_K>30$Hzj91=9w|VU_Tk=DVNA6KecoUea&URO=FzjX&G7ElrHJ?iiOAy$J>B(f zA1zlN>g9;4a^6imUF|5n8wMXse0J?UOCalbyxo1`Lm&amFS_-mFA7v1AmS+HN4AeX zu>r?=%lrMky+^~?A^r@HTaN>kcvH#peVN*#kZS%r83W z=iY=DpDS?n0-&BAatLwJ30|t5=N0jI(tmfjkrn3(^rx>1++qyETVTuIL6KG9JBWS0 z!{$#_MN`Y;C1#4R74UHWw@+7Bh|w&6*Q}20nZAkbydcN5PlUT{V`4}6b%CYVH}kw% zK=O-@JU4QusD1Z0LWp_CdJa?;xi>NwsvX)lePs8foTHQeEayK&)ncJVg~F8Gtsx-b(lOp>n)(=y*4t-s*~v@ z645PXD(OTtvpj0z{`?+C6)7!UVkXwHr4ADV426W5E^!lWy_DmMbet|R6Qg=r5z{66 zbcveSnOx3MT{c0Nc!^be8OP&^N&=E!bbEhZ!4X*&6vrq(+xA7;cqQJSR|>>nj+FrC z7oD^=6`{K-fGrZZIGC6%xSyYzZr&2itAiwCuZ&MN1)kQo?f8sEr z0v%x{dbXEidXInwXlV~h%?*7XY9SL+K=X@E+M7D__jBYt2ujbkIaKL>PQ{ScgmFcF zod7T0->JyTH4>dNLDt32_Dt7vJeO`MnpfVB60^k(0#Cl5+Z}3OWW7=GvLA5NU`la!*r^d6;MgW4=`R80 zdpNP4uPxvOmw@t^kzJyCqPb3B(hJg<^C`NOUvx4*q@Gu==ZJJHcUig|X&(FG#PgXA zA>2F#SOD{jj@p|T)r}lCKP7kXNr?!=Ajf1;EFZLVJ0o|hitgOVFkaJ+f+bE3_+2z2kY1p&)1I%;!d zeN)e@H*?g$I}sdf9_>wd@)m=PJ4E#sg?(J@-#X=I;l$c{YXI>y&HagSy-lE|4gkEb zyB*gdf!bypUb>h2BD3Oh^r#<3kmDQivh7ao!-qX|`xXs{5Q}an{hY!Z5qRMZDF^Qs zZ>zuyZ%9kyCA@c=#7k^QOQR;@0^0>@cvDy!FXFQ*6Kh8iFE}xj#!T!9ZUEku!CLt5k9HfK=#SjTYp@1;y&AN6-IX`K^zN-ca{5uPicCc6;rE5ND3|v9)Dy(2 zR|ol)X7`!)skq-hgPnK{Saf~qcK0TBmXj7c`2X({u>7JE-%p{|a@71#q~B=p6Dmrh zM(#NEj>=SydYay5=!>izS0h^8ptX7Tnzyg~8j^~mG#q~X&F=2dQ~R%J51qX?E`N;ZOc*vwjTJZH7>44Vm%rW8WL>st5Wb z>vuo)c`I0h*vtB&8s+D)#MsZedg#-C{wV+f$uGL~wmFCBeP@7!l=rsCdaYtQ2OJ`M zX~_SGL09Pgk!XN=;qahDPkkYwt2(6Sv_oDULjT`)0bbt65^Lq*9KHB)2La13I`OkL zk$%4c`~6;rD)%JGFGuhSl=i{?$f|Y?*55rU~)JwV##IOTj)Zn<~SNQ&jKdN`gAB@yO&kmvQb%?6)i;nsu;-hMAcqmenz{fy1 zY-!I-MZ6!5)FEGv@#Cspp{K^;NCaK)K|-G~>8d7cA}iqlj>RL9nzZ>wN>}yikHj** zkM%hkt55U;ETSr<=Zw_J|Iu_^N2??2r^=#x${@G< zl#!?azv!gpt0VJ(`VPs{248$9iI-o#wJG0v#-fG4!qg>hV;5#ZB0ZcPcmGa!O(4HVkG9S z-Zg!Nq2=E*;~rDqUsp%w+HWD=s|F8ayq|sBUNczUr`Wn{TWYuPy2YEuPo-tK%bcEg Tc4XJ2vJl@exP`CC$(H^fQyiNK From 7ebd359941fda3549aa3f7a2c3aa47f64bce81bd Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sat, 27 Aug 2022 21:58:21 +0200 Subject: [PATCH 0717/1348] [util] correct maxFeatureLevel to 12_0 in example config --- dxvk.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dxvk.conf b/dxvk.conf index d029dce2a..5c123f57d 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -129,7 +129,7 @@ # # Supported values: 9_1, 9_2, 9_3, 10_0, 10_1, 11_0, 11_1 -# d3d11.maxFeatureLevel = 11_1 +# d3d11.maxFeatureLevel = 12_0 # Overrides the maximum allowed tessellation factor. This can be used to From c49b1ee3909fd48bde7598de9c60c3b53916d9dd Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 29 Aug 2022 10:16:21 +0000 Subject: [PATCH 0718/1348] [d3d9] Use SetStateTexture in Reset Fixes m_activeTextures not getting updated --- src/d3d9/d3d9_device.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 88e5327fc..a661cc005 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -7180,7 +7180,7 @@ namespace dxvk { m_state.streamFreq[i] = 1; for (uint32_t i = 0; i < m_state.textures.size(); i++) - TextureChangePrivate(m_state.textures[i], nullptr); + SetStateTexture(i, nullptr); EmitCs([ cSize = m_state.textures.size() From 8395033f4a06846b20e379a7dcd6f4d8a288134a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 29 Aug 2022 18:45:21 +0200 Subject: [PATCH 0719/1348] [meta] Remove d3d10 options from setup script --- setup_dxvk.sh | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/setup_dxvk.sh b/setup_dxvk.sh index 3e63ecf0c..e6fd67401 100755 --- a/setup_dxvk.sh +++ b/setup_dxvk.sh @@ -17,7 +17,7 @@ uninstall) ;; *) echo "Unrecognized action: $action" - echo "Usage: $0 [install|uninstall] [--without-dxgi] [--with-d3d10] [--symlink]" + echo "Usage: $0 [install|uninstall] [--without-dxgi] [--symlink]" exit 1 esac @@ -25,7 +25,6 @@ esac shift with_dxgi=true -with_d3d10=false file_cmd="cp -v" while (($# > 0)); do @@ -33,9 +32,6 @@ while (($# > 0)); do "--without-dxgi") with_dxgi=false ;; - "--with-d3d10") - with_d3d10=true - ;; "--symlink") file_cmd="ln -s -v" ;; @@ -206,11 +202,5 @@ if $with_dxgi || [ "$action" == "uninstall" ]; then fi $action d3d9 - -if $with_d3d10 || [ "$action" == "uninstall" ]; then - $action d3d10 - $action d3d10_1 -fi - $action d3d10core $action d3d11 From c72c6ec6eda1e5e355e2d5d7805e911f67c1b1f4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 29 Aug 2022 18:47:17 +0200 Subject: [PATCH 0720/1348] [d3d10] Remove d3d10.dll and d3d10_1.dll These are incomplete and are already not being used anyway, so just drop them. --- lib/d3dcompiler_43.lib | Bin 4264 -> 0 bytes lib/libd3dcompiler_43.def | 17 -- lib32/d3dcompiler_43.lib | Bin 4490 -> 0 bytes lib32/libd3dcompiler_43.def | 17 -- src/d3d10/d3d10.def | 29 --- src/d3d10/d3d10_1.def | 29 --- src/d3d10/d3d10_interfaces.h | 9 - src/d3d10/d3d10_main.cpp | 335 ------------------------- src/d3d10/d3d10_reflection.cpp | 326 ------------------------ src/d3d10/d3d10_reflection.h | 163 ------------ src/d3d10/d3d10_state_block.cpp | 432 -------------------------------- src/d3d10/d3d10_state_block.h | 82 ------ src/d3d10/meson.build | 31 --- src/d3d10/version10.rc | 32 --- src/d3d10/version10_1.rc | 32 --- 15 files changed, 1534 deletions(-) delete mode 100644 lib/d3dcompiler_43.lib delete mode 100644 lib/libd3dcompiler_43.def delete mode 100644 lib32/d3dcompiler_43.lib delete mode 100644 lib32/libd3dcompiler_43.def delete mode 100644 src/d3d10/d3d10.def delete mode 100644 src/d3d10/d3d10_1.def delete mode 100644 src/d3d10/d3d10_interfaces.h delete mode 100644 src/d3d10/d3d10_main.cpp delete mode 100644 src/d3d10/d3d10_reflection.cpp delete mode 100644 src/d3d10/d3d10_reflection.h delete mode 100644 src/d3d10/d3d10_state_block.cpp delete mode 100644 src/d3d10/d3d10_state_block.h delete mode 100644 src/d3d10/version10.rc delete mode 100644 src/d3d10/version10_1.rc diff --git a/lib/d3dcompiler_43.lib b/lib/d3dcompiler_43.lib deleted file mode 100644 index 201bab8a3eb251eedbb3ef2e335f208a3408d751..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4264 zcmcIn&2AG(5Uw~766cq&mjx|rb|bMXf#Y~Q&LXW=PA~$CkVJOiLZtD}Ot6s?TjR-< zy+s^&2A*IaA}7R=140})?qQF-0sGZVx2FfU?TiR5mAj{^y1(w~s_OEMKWlEI`B!o^ z6>V##ku!`;cI}TSKO;W#cd}wsO%l;HqNz=y>6b(^Z-{2of?lHs&CLmVfu8AeK=XAX zpFW@mE$j>Wh#s`~M9^FGprt&MWtAT7?v(ee;=Rh$eX^JkohsHvKwqxd zvCor^-e;&b9hc!&zjFO?nSSk#d;zM-X!1<&z-P#;s>&!$`7ECh7S_@9EVE zyd8)tZfTnn+e#()B6@(qEBPV%0xfN(TXxN>tz@O>2MpeW{u7Kz^aaYC3O&3WL1Vos z;7L8^7ASR^K>s76k=yd%L2uHPrArXK^A+$sAy});y-&0$q?T11h z>5veJ_rpYpZyq5LAP4Yh5DYtN;GMzNtIdgtFJIJ|m_oeQ1W5}Ni2U6*CC5K&fG2cv ztb<9^*D*s5^KbHxXuLXh;Qt0c394f7EzvsGD`R?5)?Dw`ANEPY_o7qmG1$A_i)_f% zrg)Jd`RpD4$Pdx87xB8^%RA0;*FOP&Xi*b8291m~H)2}E;J-i^WxWwGXbMC5G0ZWj zwgMGo4CW-CWBrr-5IyUCFDswL!YkOvd3&k37UoVOj$`|T^WD$DLJEq!=b9`K`(90X zttqa`L%i$2;(UPTSH6uJxY(K8(4X!GkT|n3TKMp40OOx8r$_t+XzWu!RG)PXWb8AJ zK;*Xqh-%Gn9*Cy?jK2bn|7rz@VL_sSjBVHTAvei^jlx!7jw*M~V;A`$w!VcO@CzE8 zTvLc@z~kO?eu&j?0~ckyz}8i28t~ZmH;34tBME;V7+t9Y&joQrrr`fKK$KOc1}?63 R%^^3-aeFyHQ%hJ4;{TOr&olr4 diff --git a/lib/libd3dcompiler_43.def b/lib/libd3dcompiler_43.def deleted file mode 100644 index 344fbe0df..000000000 --- a/lib/libd3dcompiler_43.def +++ /dev/null @@ -1,17 +0,0 @@ -; File generated automatically from d3dcompiler_43.spec; do not edit! - -LIBRARY d3dcompiler_43.dll - -EXPORTS - D3DAssemble @1 - D3DCompile @3 - D3DCreateBlob @5 - D3DDisassemble @8 - D3DGetBlobPart @9 - D3DGetDebugInfo @10 - D3DGetInputAndOutputSignatureBlob @11 - D3DGetInputSignatureBlob @12 - D3DGetOutputSignatureBlob @13 - D3DPreprocess @14 - D3DReflect @15 - D3DStripShader @17 diff --git a/lib32/d3dcompiler_43.lib b/lib32/d3dcompiler_43.lib deleted file mode 100644 index d5578505e11648550a9154a908bafca1a3d44c8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4490 zcmcIn&2HO95FW{mQ_H_eb7_MDYU?IW5ZDqW$~IsWbfTgWqS%Jy}G=Ncs)QrIvq^n8*tZmz?>y-*R?lcKO3z(`j4{4Xnksas}uQ13L`hUv!z42iR8ca%-5NT-kUMCApdm&mOT zi$u?th~7i?mWkd$HdcsUL+%6o7V=;84{Ok9wy*+PcNsErwlB?r0TpCNUTY_RDM_NUX6^u@Nc$z zJ<4o}?aYNu8c$UeZ`Z4)=IGCB*6-h?2zh3=)MlHj?RwpLBzlaSSK`6#HClVP*=;wi z=DH$G*w*N8$bYV44!uUXOBYvi)x@}Y@Ch92HOgM5(SM6v=XNvvp?B$k+DqmxQ~ z`Xp%iO>R8bGzkxAME2}ELSug`PjpUbij0ARJd8Thu>LMz+{UA02KLptq^W_MFG=o+ zQJFA`6m?sQqO=`Fmzbk7cZ!UnHtcefqNpJB936j&2e;=a;&HDkI;L6c@4+8?AWNKs z%5FFZ{{_Q1?~Tbp)pe8|*_?xNlX9>q^c=_khzGa73NKIN*>&*GIyzN#R5OV z{grpX$2$mf1~&gIX5}4&Spz4FS+Ghwuk2s0)o{3A^&MLxXcI@$wkWNEb=?Ig4$^{m z!l7suGbzQab`G=PJ=OJl^yxNY0!bsh6te<(aN`$3@W-6zA|{Y{Exc_muogdq9X~Jj n4E(3XnXrzjCH!y2ewWUo5tK - -#include "d3d10_include.h" -#include "d3d10_reflection.h" - -#include "../dxgi/dxgi_adapter.h" - -namespace dxvk { - Logger Logger::s_instance("d3d10.log"); -} - -extern "C" { - using namespace dxvk; - - HRESULT __stdcall D3D10CoreCreateDevice( - IDXGIFactory* pFactory, - IDXGIAdapter* pAdapter, - UINT Flags, - D3D_FEATURE_LEVEL FeatureLevel, - ID3D10Device** ppDevice); - - static HRESULT D3D10InternalCreateDeviceAndSwapChain( - IDXGIAdapter* pAdapter, - D3D10_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - D3D10_FEATURE_LEVEL1 HardwareLevel, - UINT SDKVersion, - DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - IDXGISwapChain** ppSwapChain, - REFIID deviceIID, - void** ppDevice) { - InitReturnPtr(ppDevice); - InitReturnPtr(ppSwapChain); - - if (ppSwapChain && !pSwapChainDesc) - return E_INVALIDARG; - - HRESULT hr; - - // Get DXGI factory and adapter. This is mostly - // copied from the equivalent D3D11 functions. - Com dxgiFactory = nullptr; - Com dxgiAdapter = pAdapter; - Com device = nullptr; - - if (!pAdapter) { - if (DriverType != D3D10_DRIVER_TYPE_HARDWARE) - Logger::warn("D3D10CreateDevice: Unsupported driver type"); - - hr = CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast(&dxgiFactory)); - - if (FAILED(hr)) { - Logger::err("D3D10CreateDevice: Failed to create a DXGI factory"); - return hr; - } - - hr = dxgiFactory->EnumAdapters(0, &dxgiAdapter); - - if (FAILED(hr)) { - Logger::err("D3D10CreateDevice: No default adapter available"); - return hr; - } - } else { - if (FAILED(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast(&dxgiFactory)))) { - Logger::err("D3D10CreateDevice: Failed to query DXGI factory from DXGI adapter"); - return E_INVALIDARG; - } - - if (DriverType != D3D10_DRIVER_TYPE_HARDWARE || Software) - return E_INVALIDARG; - } - - hr = D3D10CoreCreateDevice( - dxgiFactory.ptr(), dxgiAdapter.ptr(), - Flags, D3D_FEATURE_LEVEL(HardwareLevel), - &device); - - if (FAILED(hr)) - return hr; - - if (ppSwapChain) { - DXGI_SWAP_CHAIN_DESC desc = *pSwapChainDesc; - hr = dxgiFactory->CreateSwapChain(device.ptr(), &desc, ppSwapChain); - - if (FAILED(hr)) { - Logger::err("D3D10CreateDevice: Failed to create swap chain"); - return hr; - } - } - - if (ppDevice) { - // Just assume that this succeeds - device->QueryInterface(deviceIID, ppDevice); - } - - if (!ppDevice && !ppSwapChain) - return S_FALSE; - - return S_OK; - } - - - DLLEXPORT HRESULT __stdcall D3D10CreateDevice( - IDXGIAdapter* pAdapter, - D3D10_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - UINT SDKVersion, - ID3D10Device** ppDevice) { - return D3D10InternalCreateDeviceAndSwapChain( - pAdapter, DriverType, Software, Flags, - D3D10_FEATURE_LEVEL_10_0, SDKVersion, - nullptr, nullptr, - __uuidof(ID3D10Device), - reinterpret_cast(ppDevice)); - } - - - DLLEXPORT HRESULT __stdcall D3D10CreateDevice1( - IDXGIAdapter* pAdapter, - D3D10_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - D3D10_FEATURE_LEVEL1 HardwareLevel, - UINT SDKVersion, - ID3D10Device1** ppDevice) { - return D3D10InternalCreateDeviceAndSwapChain( - pAdapter, DriverType, Software, Flags, - HardwareLevel, SDKVersion, - nullptr, nullptr, - __uuidof(ID3D10Device1), - reinterpret_cast(ppDevice)); - } - - - DLLEXPORT HRESULT __stdcall D3D10CreateDeviceAndSwapChain( - IDXGIAdapter* pAdapter, - D3D10_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - UINT SDKVersion, - DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - IDXGISwapChain** ppSwapChain, - ID3D10Device** ppDevice) { - return D3D10InternalCreateDeviceAndSwapChain( - pAdapter, DriverType, Software, Flags, - D3D10_FEATURE_LEVEL_10_0, SDKVersion, - pSwapChainDesc, ppSwapChain, - __uuidof(ID3D10Device), - reinterpret_cast(ppDevice)); - } - - - DLLEXPORT HRESULT __stdcall D3D10CreateDeviceAndSwapChain1( - IDXGIAdapter* pAdapter, - D3D10_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - D3D10_FEATURE_LEVEL1 HardwareLevel, - UINT SDKVersion, - DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - IDXGISwapChain** ppSwapChain, - ID3D10Device1** ppDevice) { - return D3D10InternalCreateDeviceAndSwapChain( - pAdapter, DriverType, Software, Flags, - HardwareLevel, SDKVersion, - pSwapChainDesc, ppSwapChain, - __uuidof(ID3D10Device1), - reinterpret_cast(ppDevice)); - } - - - const char* STDMETHODCALLTYPE D3D10GetVertexShaderProfile (ID3D10Device*) { return "vs_4_1"; } - const char* STDMETHODCALLTYPE D3D10GetGeometryShaderProfile (ID3D10Device*) { return "gs_4_1"; } - const char* STDMETHODCALLTYPE D3D10GetPixelShaderProfile (ID3D10Device*) { return "ps_4_1"; } - - - HRESULT STDMETHODCALLTYPE D3D10CreateBlob(SIZE_T size, LPD3D10BLOB* ppBuffer) { - return D3DCreateBlob(size, ppBuffer); - } - - - HRESULT STDMETHODCALLTYPE D3D10GetInputSignatureBlob( - const void* pShaderBytecode, - SIZE_T BytecodeLength, - ID3D10Blob** ppSignatureBlob) { - return D3DGetInputSignatureBlob( - pShaderBytecode, - BytecodeLength, - ppSignatureBlob); - } - - - HRESULT STDMETHODCALLTYPE D3D10GetOutputSignatureBlob( - const void* pShaderBytecode, - SIZE_T BytecodeLength, - ID3D10Blob** ppSignatureBlob) { - return D3DGetOutputSignatureBlob( - pShaderBytecode, - BytecodeLength, - ppSignatureBlob); - } - - - HRESULT STDMETHODCALLTYPE D3D10ReflectShader( - const void* pShaderBytecode, - SIZE_T BytecodeLength, - ID3D10ShaderReflection** ppReflector) { - static const GUID IID_ID3D11ShaderReflection = - {0x0a233719,0x3960,0x4578,{0x9d,0x7c,0x20,0x3b,0x8b,0x1d,0x9c,0xc1}}; - - InitReturnPtr(ppReflector); - - Com d3d11Reflector = nullptr; - - HRESULT hr = D3DReflect(pShaderBytecode, - BytecodeLength, IID_ID3D11ShaderReflection, - reinterpret_cast(&d3d11Reflector)); - - if (FAILED(hr)) { - Logger::err("D3D10ReflectShader: Failed to create ID3D11ShaderReflection"); - return hr; - } - - *ppReflector = ref(new D3D10ShaderReflection(d3d11Reflector.ptr())); - return S_OK; - } - - - HRESULT STDMETHODCALLTYPE D3D10CompileShader( - LPCSTR pSrcData, - SIZE_T SrcDataSize, - LPCSTR pFileName, - const D3D10_SHADER_MACRO* pDefines, - LPD3D10INCLUDE pInclude, - LPCSTR pFunctionName, - LPCSTR pProfile, - UINT Flags, - ID3D10Blob** ppShader, - ID3D10Blob** ppErrorMsgs) { - return D3DCompile(pSrcData, SrcDataSize, pFileName, - pDefines, pInclude, pFunctionName, pProfile, Flags, - 0, ppShader, ppErrorMsgs); - } - - - HRESULT STDMETHODCALLTYPE D3D10CreateEffectFromMemory( - void* pData, - SIZE_T DataSize, - UINT EffectFlags, - ID3D10Device* pDevice, - ID3D10EffectPool* pEffectPool, - ID3D10Effect** ppEffect) { - Logger::warn("D3D10CreateEffectFromMemory: Not implemented"); - return E_NOTIMPL; - } - - - HRESULT STDMETHODCALLTYPE D3D10CreateEffectPoolFromMemory( - void* pData, - SIZE_T DataSize, - UINT EffectFlags, - ID3D10Device* pDevice, - ID3D10EffectPool** ppEffectPool) { - Logger::warn("D3D10CreateEffectPoolFromMemory: Not implemented"); - return E_NOTIMPL; - } - - - HRESULT STDMETHODCALLTYPE D3D10CompileEffectFromMemory( - void* pData, - SIZE_T DataLength, - LPCSTR pSrcFileName, - const D3D10_SHADER_MACRO* pDefines, - ID3D10Include* pInclude, - UINT ShaderFlags, - UINT EffectFlags, - ID3D10Blob** ppCompiledEffect, - ID3D10Blob** ppErrors) { - Logger::warn("D3D10CompileEffectFromMemory: Not implemented"); - return E_NOTIMPL; - } - - - HRESULT STDMETHODCALLTYPE D3D10DisassembleEffect( - ID3D10Effect* pEffect, - BOOL EnableColorCode, - ID3D10Blob** ppDisassembly) { - Logger::warn("D3D10DisassembleEffect: Not implemented"); - return E_NOTIMPL; - } - - - HRESULT STDMETHODCALLTYPE D3D10DisassembleShader( - const void* pShader, - SIZE_T BytecodeLength, - BOOL EnableColorCode, - LPCSTR pComments, - ID3D10Blob** ppDisassembly) { - return D3DDisassemble( - pShader, BytecodeLength, - 0, pComments, ppDisassembly); - } - - - HRESULT STDMETHODCALLTYPE D3D10PreprocessShader( - LPCSTR pSrcData, - SIZE_T SrcDataSize, - LPCSTR pFileName, - const D3D10_SHADER_MACRO* pDefines, - LPD3D10INCLUDE pInclude, - ID3D10Blob** ppShaderText, - ID3D10Blob** ppErrorMsgs) { - return D3DPreprocess( - pSrcData, SrcDataSize, - pFileName, pDefines, - pInclude, - ppShaderText, - ppErrorMsgs); - } - - - UINT64 STDMETHODCALLTYPE D3D10GetVersion() { - return 0xa000100041770ull; - } - - - HRESULT STDMETHODCALLTYPE D3D10RegisterLayers() { - return E_NOTIMPL; - } - -} - - diff --git a/src/d3d10/d3d10_reflection.cpp b/src/d3d10/d3d10_reflection.cpp deleted file mode 100644 index d49dea905..000000000 --- a/src/d3d10/d3d10_reflection.cpp +++ /dev/null @@ -1,326 +0,0 @@ -#include "d3d10_reflection.h" - -namespace dxvk { - - D3D10ShaderReflectionType::D3D10ShaderReflectionType( - ID3D11ShaderReflectionType* d3d11) - : m_d3d11(d3d11) { - - } - - - D3D10ShaderReflectionType::~D3D10ShaderReflectionType() { - - } - - - HRESULT STDMETHODCALLTYPE D3D10ShaderReflectionType::GetDesc( - D3D10_SHADER_TYPE_DESC* pDesc) { - D3D11_SHADER_TYPE_DESC d3d11Desc; - HRESULT hr = m_d3d11->GetDesc(&d3d11Desc); - - if (FAILED(hr)) - return hr; - - pDesc->Class = D3D10_SHADER_VARIABLE_CLASS(d3d11Desc.Class); - pDesc->Type = D3D10_SHADER_VARIABLE_TYPE (d3d11Desc.Type); - pDesc->Rows = d3d11Desc.Rows; - pDesc->Columns = d3d11Desc.Columns; - pDesc->Elements = d3d11Desc.Elements; - pDesc->Members = d3d11Desc.Members; - pDesc->Offset = d3d11Desc.Offset; - return S_OK; - } - - - ID3D10ShaderReflectionType* STDMETHODCALLTYPE D3D10ShaderReflectionType::GetMemberTypeByIndex( - UINT Index) { - return FindMemberType(m_d3d11->GetMemberTypeByIndex(Index)); - } - - - ID3D10ShaderReflectionType* STDMETHODCALLTYPE D3D10ShaderReflectionType::GetMemberTypeByName( - const char* Name) { - return FindMemberType(m_d3d11->GetMemberTypeByName(Name)); - } - - - const char* STDMETHODCALLTYPE D3D10ShaderReflectionType::GetMemberTypeName( - UINT Index) { - return m_d3d11->GetMemberTypeName(Index); - } - - - ID3D10ShaderReflectionType* D3D10ShaderReflectionType::FindMemberType( - ID3D11ShaderReflectionType* pMemberType) { - if (!pMemberType) - return nullptr; - - auto entry = m_members.find(pMemberType); - - if (entry == m_members.end()) { - entry = m_members.insert({ pMemberType, - std::make_unique(pMemberType) }).first; - } - - return entry->second.get(); - } - - - D3D10ShaderReflectionVariable::D3D10ShaderReflectionVariable(ID3D11ShaderReflectionVariable* d3d11) - : m_d3d11(d3d11), m_type(m_d3d11->GetType()) { - - } - - - D3D10ShaderReflectionVariable::~D3D10ShaderReflectionVariable() { - - } - - - HRESULT STDMETHODCALLTYPE D3D10ShaderReflectionVariable::GetDesc( - D3D10_SHADER_VARIABLE_DESC* pDesc) { - D3D11_SHADER_VARIABLE_DESC d3d11Desc; - HRESULT hr = m_d3d11->GetDesc(&d3d11Desc); - - if (FAILED(hr)) - return hr; - - pDesc->Name = d3d11Desc.Name; - pDesc->StartOffset = d3d11Desc.StartOffset; - pDesc->Size = d3d11Desc.Size; - pDesc->uFlags = d3d11Desc.uFlags; - pDesc->DefaultValue = d3d11Desc.DefaultValue; - return S_OK; - } - - - ID3D10ShaderReflectionType* STDMETHODCALLTYPE D3D10ShaderReflectionVariable::GetType() { - return &m_type; - } - - - D3D10ShaderReflectionConstantBuffer::D3D10ShaderReflectionConstantBuffer( - ID3D11ShaderReflectionConstantBuffer* d3d11) - : m_d3d11(d3d11) { - - } - - - D3D10ShaderReflectionConstantBuffer::~D3D10ShaderReflectionConstantBuffer() { - - } - - - HRESULT STDMETHODCALLTYPE D3D10ShaderReflectionConstantBuffer::GetDesc( - D3D10_SHADER_BUFFER_DESC* pDesc) { - D3D11_SHADER_BUFFER_DESC d3d11Desc; - HRESULT hr = m_d3d11->GetDesc(&d3d11Desc); - - if (FAILED(hr)) - return hr; - - pDesc->Name = d3d11Desc.Name; - pDesc->Type = D3D10_CBUFFER_TYPE(d3d11Desc.Type); - pDesc->Variables = d3d11Desc.Variables; - pDesc->Size = d3d11Desc.Size; - pDesc->uFlags = d3d11Desc.uFlags; - return S_OK; - } - - - ID3D10ShaderReflectionVariable* STDMETHODCALLTYPE D3D10ShaderReflectionConstantBuffer::GetVariableByIndex( - UINT Index) { - return FindVariable(m_d3d11->GetVariableByIndex(Index)); - } - - - ID3D10ShaderReflectionVariable* STDMETHODCALLTYPE D3D10ShaderReflectionConstantBuffer::GetVariableByName( - LPCSTR Name) { - return FindVariable(m_d3d11->GetVariableByName(Name)); - } - - - ID3D10ShaderReflectionVariable* D3D10ShaderReflectionConstantBuffer::FindVariable( - ID3D11ShaderReflectionVariable* pVariable) { - if (!pVariable) - return nullptr; - - auto entry = m_variables.find(pVariable); - - if (entry == m_variables.end()) { - entry = m_variables.emplace( - std::piecewise_construct, - std::forward_as_tuple(pVariable), - std::forward_as_tuple(pVariable)).first; - } - - return &entry->second; - } - - - D3D10ShaderReflection::D3D10ShaderReflection(ID3D11ShaderReflection* d3d11) - : m_d3d11(d3d11) { - - } - - - D3D10ShaderReflection::~D3D10ShaderReflection() { - - } - - - HRESULT STDMETHODCALLTYPE D3D10ShaderReflection::QueryInterface( - REFIID riid, - void** ppvObject) { - if (ppvObject == nullptr) - return E_POINTER; - - static const GUID IID_ID3D10ShaderReflection - = {0xd40e20b6,0xf8f7,0x42ad,{0xab,0x20,0x4b,0xaf,0x8f,0x15,0xdf,0xaa}}; - - if (riid == __uuidof(IUnknown) - || riid == IID_ID3D10ShaderReflection) { - *ppvObject = ref(this); - return S_OK; - } - - return E_NOINTERFACE; - } - - - HRESULT STDMETHODCALLTYPE D3D10ShaderReflection::GetDesc( - D3D10_SHADER_DESC* pDesc) { - D3D11_SHADER_DESC d3d11Desc; - HRESULT hr = m_d3d11->GetDesc(&d3d11Desc); - - if (FAILED(hr)) - return hr; - - pDesc->Version = d3d11Desc.Version; - pDesc->Creator = d3d11Desc.Creator; - pDesc->Flags = d3d11Desc.Flags; - pDesc->ConstantBuffers = d3d11Desc.ConstantBuffers; - pDesc->BoundResources = d3d11Desc.BoundResources; - pDesc->InputParameters = d3d11Desc.InputParameters; - pDesc->OutputParameters = d3d11Desc.OutputParameters; - pDesc->InstructionCount = d3d11Desc.InstructionCount; - pDesc->TempRegisterCount = d3d11Desc.TempRegisterCount; - pDesc->TempArrayCount = d3d11Desc.TempArrayCount; - pDesc->DefCount = d3d11Desc.DefCount; - pDesc->DclCount = d3d11Desc.DclCount; - pDesc->TextureNormalInstructions = d3d11Desc.TextureNormalInstructions; - pDesc->TextureLoadInstructions = d3d11Desc.TextureLoadInstructions; - pDesc->TextureCompInstructions = d3d11Desc.TextureCompInstructions; - pDesc->TextureBiasInstructions = d3d11Desc.TextureBiasInstructions; - pDesc->TextureGradientInstructions = d3d11Desc.TextureGradientInstructions; - pDesc->FloatInstructionCount = d3d11Desc.FloatInstructionCount; - pDesc->IntInstructionCount = d3d11Desc.IntInstructionCount; - pDesc->UintInstructionCount = d3d11Desc.UintInstructionCount; - pDesc->StaticFlowControlCount = d3d11Desc.StaticFlowControlCount; - pDesc->DynamicFlowControlCount = d3d11Desc.DynamicFlowControlCount; - pDesc->MacroInstructionCount = d3d11Desc.MacroInstructionCount; - pDesc->ArrayInstructionCount = d3d11Desc.ArrayInstructionCount; - pDesc->CutInstructionCount = d3d11Desc.CutInstructionCount; - pDesc->EmitInstructionCount = d3d11Desc.EmitInstructionCount; - pDesc->GSOutputTopology = D3D10_PRIMITIVE_TOPOLOGY(d3d11Desc.GSOutputTopology); - pDesc->GSMaxOutputVertexCount = d3d11Desc.GSMaxOutputVertexCount; - return S_OK; - } - - - ID3D10ShaderReflectionConstantBuffer* STDMETHODCALLTYPE - D3D10ShaderReflection::GetConstantBufferByIndex( - UINT Index) { - return FindConstantBuffer(m_d3d11->GetConstantBufferByIndex(Index)); - } - - - ID3D10ShaderReflectionConstantBuffer* STDMETHODCALLTYPE - D3D10ShaderReflection::GetConstantBufferByName( - LPCSTR Name) { - return FindConstantBuffer(m_d3d11->GetConstantBufferByName(Name)); - } - - - HRESULT STDMETHODCALLTYPE D3D10ShaderReflection::GetInputParameterDesc( - UINT ParameterIndex, - D3D10_SIGNATURE_PARAMETER_DESC* pDesc) { - D3D11_SIGNATURE_PARAMETER_DESC d3d11Desc; - HRESULT hr = m_d3d11->GetInputParameterDesc(ParameterIndex, &d3d11Desc); - - if (FAILED(hr)) - return hr; - - ConvertSignatureParameterDesc(&d3d11Desc, pDesc); - return S_OK; - } - - - HRESULT STDMETHODCALLTYPE D3D10ShaderReflection::GetOutputParameterDesc( - UINT ParameterIndex, - D3D10_SIGNATURE_PARAMETER_DESC* pDesc) { - D3D11_SIGNATURE_PARAMETER_DESC d3d11Desc; - HRESULT hr = m_d3d11->GetOutputParameterDesc(ParameterIndex, &d3d11Desc); - - if (FAILED(hr)) - return hr; - - ConvertSignatureParameterDesc(&d3d11Desc, pDesc); - return S_OK; - } - - - HRESULT STDMETHODCALLTYPE D3D10ShaderReflection::GetResourceBindingDesc( - UINT ResourceIndex, - D3D10_SHADER_INPUT_BIND_DESC* pDesc) { - D3D11_SHADER_INPUT_BIND_DESC d3d11Desc; - HRESULT hr = m_d3d11->GetResourceBindingDesc( - ResourceIndex, &d3d11Desc); - - if (FAILED(hr)) - return hr; - - pDesc->Name = d3d11Desc.Name; - pDesc->Type = D3D10_SHADER_INPUT_TYPE(d3d11Desc.Type); - pDesc->BindPoint = d3d11Desc.BindPoint; - pDesc->BindCount = d3d11Desc.BindCount; - pDesc->uFlags = d3d11Desc.uFlags; - pDesc->ReturnType = D3D10_RESOURCE_RETURN_TYPE(d3d11Desc.ReturnType); - pDesc->Dimension = D3D10_SRV_DIMENSION (d3d11Desc.Dimension); - pDesc->NumSamples = d3d11Desc.NumSamples; - return S_OK; - } - - - ID3D10ShaderReflectionConstantBuffer* D3D10ShaderReflection::FindConstantBuffer( - ID3D11ShaderReflectionConstantBuffer* pConstantBuffer) { - if (!pConstantBuffer) - return nullptr; - - auto entry = m_constantBuffers.find(pConstantBuffer); - - if (entry == m_constantBuffers.end()) { - entry = m_constantBuffers.emplace( - std::piecewise_construct, - std::forward_as_tuple(pConstantBuffer), - std::forward_as_tuple(pConstantBuffer)).first; - } - - return &entry->second; - } - - - void D3D10ShaderReflection::ConvertSignatureParameterDesc( - const D3D11_SIGNATURE_PARAMETER_DESC* pSrcDesc, - D3D10_SIGNATURE_PARAMETER_DESC* pDstDesc) { - pDstDesc->SemanticName = pSrcDesc->SemanticName; - pDstDesc->SemanticIndex = pSrcDesc->SemanticIndex; - pDstDesc->Register = pSrcDesc->Register; - pDstDesc->SystemValueType = D3D10_NAME(pSrcDesc->SystemValueType); - pDstDesc->ComponentType = D3D10_REGISTER_COMPONENT_TYPE(pSrcDesc->ComponentType); - pDstDesc->Mask = pSrcDesc->Mask; - pDstDesc->ReadWriteMask = pSrcDesc->ReadWriteMask; - } - -} \ No newline at end of file diff --git a/src/d3d10/d3d10_reflection.h b/src/d3d10/d3d10_reflection.h deleted file mode 100644 index 482b4f0f9..000000000 --- a/src/d3d10/d3d10_reflection.h +++ /dev/null @@ -1,163 +0,0 @@ -#pragma once - -#include -#include - -#include "d3d10_include.h" - -#include -#include - -namespace dxvk { - - class D3D10ShaderReflectionType final : public ID3D10ShaderReflectionType { - - public: - - D3D10ShaderReflectionType( - ID3D11ShaderReflectionType* d3d11); - - ~D3D10ShaderReflectionType(); - - HRESULT STDMETHODCALLTYPE GetDesc( - D3D10_SHADER_TYPE_DESC* pDesc); - - ID3D10ShaderReflectionType* STDMETHODCALLTYPE GetMemberTypeByIndex( - UINT Index); - - ID3D10ShaderReflectionType* STDMETHODCALLTYPE GetMemberTypeByName( - const char* Name); - - const char* STDMETHODCALLTYPE GetMemberTypeName( - UINT Index); - - ID3D11ShaderReflectionType* GetD3D11Iface() { - return m_d3d11; - } - - private: - - ID3D11ShaderReflectionType* m_d3d11; - - std::unordered_map< - ID3D11ShaderReflectionType*, - std::unique_ptr> m_members; - - ID3D10ShaderReflectionType* FindMemberType( - ID3D11ShaderReflectionType* pMemberType); - - }; - - - class D3D10ShaderReflectionVariable final : public ID3D10ShaderReflectionVariable { - - public: - - D3D10ShaderReflectionVariable( - ID3D11ShaderReflectionVariable* d3d11); - - ~D3D10ShaderReflectionVariable(); - - HRESULT STDMETHODCALLTYPE GetDesc( - D3D10_SHADER_VARIABLE_DESC* pDesc); - - ID3D10ShaderReflectionType* STDMETHODCALLTYPE GetType(); - - ID3D11ShaderReflectionVariable* STDMETHODCALLTYPE GetD3D11Iface() { - return m_d3d11; - } - - private: - - ID3D11ShaderReflectionVariable* m_d3d11; - D3D10ShaderReflectionType m_type; - - }; - - - class D3D10ShaderReflectionConstantBuffer final : public ID3D10ShaderReflectionConstantBuffer { - - public: - - D3D10ShaderReflectionConstantBuffer( - ID3D11ShaderReflectionConstantBuffer* d3d11); - - ~D3D10ShaderReflectionConstantBuffer(); - - HRESULT STDMETHODCALLTYPE GetDesc( - D3D10_SHADER_BUFFER_DESC* pDesc); - - ID3D10ShaderReflectionVariable* STDMETHODCALLTYPE GetVariableByIndex( - UINT Index); - - ID3D10ShaderReflectionVariable* STDMETHODCALLTYPE GetVariableByName( - LPCSTR Name); - - ID3D11ShaderReflectionConstantBuffer* STDMETHODCALLTYPE GetD3D11Iface() { - return m_d3d11; - } - - private: - - ID3D11ShaderReflectionConstantBuffer* m_d3d11; - - std::unordered_map< - ID3D11ShaderReflectionVariable*, - D3D10ShaderReflectionVariable> m_variables; - - ID3D10ShaderReflectionVariable* FindVariable( - ID3D11ShaderReflectionVariable* pVariable); - - }; - - - class D3D10ShaderReflection : public ComObject { - - public: - - D3D10ShaderReflection(ID3D11ShaderReflection* d3d11); - ~D3D10ShaderReflection(); - - HRESULT STDMETHODCALLTYPE QueryInterface( - REFIID riid, - void** ppvObject); - - HRESULT STDMETHODCALLTYPE GetDesc( - D3D10_SHADER_DESC* pDesc); - - ID3D10ShaderReflectionConstantBuffer* STDMETHODCALLTYPE GetConstantBufferByIndex( - UINT Index); - - ID3D10ShaderReflectionConstantBuffer* STDMETHODCALLTYPE GetConstantBufferByName( - LPCSTR Name); - - HRESULT STDMETHODCALLTYPE GetInputParameterDesc( - UINT ParameterIndex, - D3D10_SIGNATURE_PARAMETER_DESC* pDesc); - - HRESULT STDMETHODCALLTYPE GetOutputParameterDesc( - UINT ParameterIndex, - D3D10_SIGNATURE_PARAMETER_DESC* pDesc); - - HRESULT STDMETHODCALLTYPE GetResourceBindingDesc( - UINT ResourceIndex, - D3D10_SHADER_INPUT_BIND_DESC* pDesc); - - private: - - Com m_d3d11; - - std::unordered_map< - ID3D11ShaderReflectionConstantBuffer*, - D3D10ShaderReflectionConstantBuffer> m_constantBuffers; - - ID3D10ShaderReflectionConstantBuffer* FindConstantBuffer( - ID3D11ShaderReflectionConstantBuffer* pConstantBuffer); - - void ConvertSignatureParameterDesc( - const D3D11_SIGNATURE_PARAMETER_DESC* pSrcDesc, - D3D10_SIGNATURE_PARAMETER_DESC* pDstDesc); - - }; - -} \ No newline at end of file diff --git a/src/d3d10/d3d10_state_block.cpp b/src/d3d10/d3d10_state_block.cpp deleted file mode 100644 index af628eb46..000000000 --- a/src/d3d10/d3d10_state_block.cpp +++ /dev/null @@ -1,432 +0,0 @@ -#include "d3d10_state_block.h" - -#define MAKE_STATE_TYPE(field, count) { offsetof(D3D10_STATE_BLOCK_MASK, field), count } - -namespace dxvk { - - static const std::array, 24> g_stateTypes = {{ - MAKE_STATE_TYPE(SOBuffers, 1), - MAKE_STATE_TYPE(OMRenderTargets, 1), - MAKE_STATE_TYPE(OMDepthStencilState, 1), - MAKE_STATE_TYPE(OMBlendState, 1), - MAKE_STATE_TYPE(VS, 1), - MAKE_STATE_TYPE(VSSamplers, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT), - MAKE_STATE_TYPE(VSShaderResources, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT), - MAKE_STATE_TYPE(VSConstantBuffers, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT), - MAKE_STATE_TYPE(GS, 1), - MAKE_STATE_TYPE(GSSamplers, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT), - MAKE_STATE_TYPE(GSShaderResources, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT), - MAKE_STATE_TYPE(GSConstantBuffers, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT), - MAKE_STATE_TYPE(PS, 1), - MAKE_STATE_TYPE(PSSamplers, D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT), - MAKE_STATE_TYPE(PSShaderResources, D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT), - MAKE_STATE_TYPE(PSConstantBuffers, D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT), - MAKE_STATE_TYPE(IAVertexBuffers, D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT), - MAKE_STATE_TYPE(IAIndexBuffer, 1), - MAKE_STATE_TYPE(IAInputLayout, 1), - MAKE_STATE_TYPE(IAPrimitiveTopology, 1), - MAKE_STATE_TYPE(RSViewports, 1), - MAKE_STATE_TYPE(RSScissorRects, 1), - MAKE_STATE_TYPE(RSRasterizerState, 1), - MAKE_STATE_TYPE(Predication, 1), - }}; - - - D3D10StateBlock::D3D10StateBlock( - ID3D10Device* pDevice, - const D3D10_STATE_BLOCK_MASK* pMask) - : m_device(pDevice), m_mask(*pMask) { - - } - - - D3D10StateBlock::~D3D10StateBlock() { - - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlock::QueryInterface( - REFIID riid, - void** ppvObject) { - if (ppvObject == nullptr) - return E_POINTER; - - *ppvObject = nullptr; - - if (riid == __uuidof(IUnknown) - || riid == __uuidof(ID3D10StateBlock)) { - *ppvObject = ref(this); - return S_OK; - } - - Logger::warn("D3D10StateBlock::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); - return E_NOINTERFACE; - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlock::Capture() { - m_state = D3D10_STATE_BLOCK_STATE(); - - if (TestBit(&m_mask.VS, 0)) m_device->VSGetShader(&m_state.vs); - if (TestBit(&m_mask.GS, 0)) m_device->GSGetShader(&m_state.gs); - if (TestBit(&m_mask.PS, 0)) m_device->PSGetShader(&m_state.ps); - - for (uint32_t i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) { - if (TestBit(m_mask.VSSamplers, i)) m_device->VSGetSamplers(i, 1, &m_state.vsSso[i]); - if (TestBit(m_mask.GSSamplers, i)) m_device->GSGetSamplers(i, 1, &m_state.gsSso[i]); - if (TestBit(m_mask.PSSamplers, i)) m_device->PSGetSamplers(i, 1, &m_state.psSso[i]); - } - - for (uint32_t i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) { - if (TestBit(m_mask.VSShaderResources, i)) m_device->VSGetShaderResources(i, 1, &m_state.vsSrv[i]); - if (TestBit(m_mask.GSShaderResources, i)) m_device->GSGetShaderResources(i, 1, &m_state.gsSrv[i]); - if (TestBit(m_mask.PSShaderResources, i)) m_device->PSGetShaderResources(i, 1, &m_state.psSrv[i]); - } - - for (uint32_t i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) { - if (TestBit(m_mask.VSConstantBuffers, i)) m_device->VSGetConstantBuffers(i, 1, &m_state.vsCbo[i]); - if (TestBit(m_mask.GSConstantBuffers, i)) m_device->GSGetConstantBuffers(i, 1, &m_state.gsCbo[i]); - if (TestBit(m_mask.PSConstantBuffers, i)) m_device->PSGetConstantBuffers(i, 1, &m_state.psCbo[i]); - } - - for (uint32_t i = 0; i < D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) { - if (TestBit(m_mask.IAVertexBuffers, i)) { - m_device->IAGetVertexBuffers(i, 1, - &m_state.iaVertexBuffers[i], - &m_state.iaVertexOffsets[i], - &m_state.iaVertexStrides[i]); - } - } - - if (TestBit(&m_mask.IAIndexBuffer, 0)) { - m_device->IAGetIndexBuffer( - &m_state.iaIndexBuffer, - &m_state.iaIndexFormat, - &m_state.iaIndexOffset); - } - - if (TestBit(&m_mask.IAInputLayout, 0)) - m_device->IAGetInputLayout(&m_state.iaInputLayout); - - if (TestBit(&m_mask.IAPrimitiveTopology, 0)) - m_device->IAGetPrimitiveTopology(&m_state.iaTopology); - - if (TestBit(&m_mask.OMRenderTargets, 0)) { - m_device->OMGetRenderTargets( - D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT, - &m_state.omRtv[0], &m_state.omDsv); - } - - if (TestBit(&m_mask.OMDepthStencilState, 0)) { - m_device->OMGetDepthStencilState( - &m_state.omDepthStencilState, - &m_state.omStencilRef); - } - - if (TestBit(&m_mask.OMBlendState, 0)) { - m_device->OMGetBlendState( - &m_state.omBlendState, - m_state.omBlendFactor, - &m_state.omSampleMask); - } - - if (TestBit(&m_mask.RSViewports, 0)) { - m_device->RSGetViewports(&m_state.rsViewportCount, nullptr); - m_device->RSGetViewports(&m_state.rsViewportCount, m_state.rsViewports); - } - - if (TestBit(&m_mask.RSScissorRects, 0)) { - m_device->RSGetScissorRects(&m_state.rsScissorCount, nullptr); - m_device->RSGetScissorRects(&m_state.rsScissorCount, m_state.rsScissors); - } - - if (TestBit(&m_mask.RSRasterizerState, 0)) - m_device->RSGetState(&m_state.rsState); - - if (TestBit(&m_mask.SOBuffers, 0)) { - m_device->SOGetTargets( - D3D10_SO_BUFFER_SLOT_COUNT, - &m_state.soBuffers[0], - &m_state.soOffsets[0]); - } - - if (TestBit(&m_mask.Predication, 0)) - m_device->GetPredication(&m_state.predicate, &m_state.predicateInvert); - - return S_OK; - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlock::Apply() { - if (TestBit(&m_mask.VS, 0)) m_device->VSSetShader(m_state.vs.ptr()); - if (TestBit(&m_mask.GS, 0)) m_device->GSSetShader(m_state.gs.ptr()); - if (TestBit(&m_mask.PS, 0)) m_device->PSSetShader(m_state.ps.ptr()); - - for (uint32_t i = 0; i < D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) { - if (TestBit(m_mask.VSSamplers, i)) m_device->VSSetSamplers(i, 1, &m_state.vsSso[i]); - if (TestBit(m_mask.GSSamplers, i)) m_device->GSSetSamplers(i, 1, &m_state.gsSso[i]); - if (TestBit(m_mask.PSSamplers, i)) m_device->PSSetSamplers(i, 1, &m_state.psSso[i]); - } - - for (uint32_t i = 0; i < D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) { - if (TestBit(m_mask.VSShaderResources, i)) m_device->VSSetShaderResources(i, 1, &m_state.vsSrv[i]); - if (TestBit(m_mask.GSShaderResources, i)) m_device->GSSetShaderResources(i, 1, &m_state.gsSrv[i]); - if (TestBit(m_mask.PSShaderResources, i)) m_device->PSSetShaderResources(i, 1, &m_state.psSrv[i]); - } - - for (uint32_t i = 0; i < D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) { - if (TestBit(m_mask.VSConstantBuffers, i)) m_device->VSSetConstantBuffers(i, 1, &m_state.vsCbo[i]); - if (TestBit(m_mask.GSConstantBuffers, i)) m_device->GSSetConstantBuffers(i, 1, &m_state.gsCbo[i]); - if (TestBit(m_mask.PSConstantBuffers, i)) m_device->PSSetConstantBuffers(i, 1, &m_state.psCbo[i]); - } - - for (uint32_t i = 0; i < D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) { - if (TestBit(m_mask.IAVertexBuffers, i)) { - m_device->IASetVertexBuffers(i, 1, - &m_state.iaVertexBuffers[i], - &m_state.iaVertexOffsets[i], - &m_state.iaVertexStrides[i]); - } - } - - if (TestBit(&m_mask.IAIndexBuffer, 0)) { - m_device->IASetIndexBuffer( - m_state.iaIndexBuffer.ptr(), - m_state.iaIndexFormat, - m_state.iaIndexOffset); - } - - if (TestBit(&m_mask.IAInputLayout, 0)) - m_device->IASetInputLayout(m_state.iaInputLayout.ptr()); - - if (TestBit(&m_mask.IAPrimitiveTopology, 0)) - m_device->IASetPrimitiveTopology(m_state.iaTopology); - - if (TestBit(&m_mask.OMRenderTargets, 0)) { - m_device->OMSetRenderTargets( - D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT, - &m_state.omRtv[0], m_state.omDsv.ptr()); - } - - if (TestBit(&m_mask.OMDepthStencilState, 0)) { - m_device->OMSetDepthStencilState( - m_state.omDepthStencilState.ptr(), - m_state.omStencilRef); - } - - if (TestBit(&m_mask.OMBlendState, 0)) { - m_device->OMSetBlendState( - m_state.omBlendState.ptr(), - m_state.omBlendFactor, - m_state.omSampleMask); - } - - if (TestBit(&m_mask.RSViewports, 0)) - m_device->RSSetViewports(m_state.rsViewportCount, m_state.rsViewports); - - if (TestBit(&m_mask.RSScissorRects, 0)) - m_device->RSSetScissorRects(m_state.rsScissorCount, m_state.rsScissors); - - if (TestBit(&m_mask.RSRasterizerState, 0)) - m_device->RSSetState(m_state.rsState.ptr()); - - if (TestBit(&m_mask.SOBuffers, 0)) { - m_device->SOSetTargets( - D3D10_SO_BUFFER_SLOT_COUNT, - &m_state.soBuffers[0], - &m_state.soOffsets[0]); - } - - if (TestBit(&m_mask.Predication, 0)) - m_device->SetPredication(m_state.predicate.ptr(), m_state.predicateInvert); - - return S_OK; - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlock::GetDevice( - ID3D10Device** ppDevice) { - Logger::err("D3D10StateBlock::GetDevice: Stub"); - return E_NOTIMPL; - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlock::ReleaseAllDeviceObjects() { - // Not entirely sure if this is correct? - m_state = D3D10_STATE_BLOCK_STATE(); - return S_OK; - } - - - BOOL D3D10StateBlock::TestBit( - const BYTE* pMask, - UINT Idx) { - uint32_t byte = Idx / 8; - uint32_t bit = Idx % 8; - return (pMask[byte] & (1 << bit)) != 0; - } - -} - -extern "C" { - using namespace dxvk; - - HRESULT STDMETHODCALLTYPE D3D10CreateStateBlock( - ID3D10Device* pDevice, - D3D10_STATE_BLOCK_MASK* pStateBlockMask, - ID3D10StateBlock** ppStateBlock) { - InitReturnPtr(ppStateBlock); - - if (!pDevice || !pStateBlockMask || !ppStateBlock) - return E_INVALIDARG; - - *ppStateBlock = ref(new D3D10StateBlock(pDevice, pStateBlockMask)); - return S_OK; - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskEnableCapture( - D3D10_STATE_BLOCK_MASK* pMask, - D3D10_DEVICE_STATE_TYPES StateType, - UINT StartIdx, - UINT Count) { - if (!pMask || !StateType || StateType > g_stateTypes.size()) - return E_INVALIDARG; - - auto pair = g_stateTypes[uint32_t(StateType) - 1]; - auto mask = reinterpret_cast(pMask) + pair.first; - - if (StartIdx + Count > pair.second) - return E_INVALIDARG; - - for (uint32_t i = StartIdx; i < StartIdx + Count; i++) { - uint32_t byte = i / 8; - uint32_t bit = i % 8; - mask[byte] |= 1 << bit; - } - - return S_OK; - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskDisableCapture( - D3D10_STATE_BLOCK_MASK* pMask, - D3D10_DEVICE_STATE_TYPES StateType, - UINT StartIdx, - UINT Count) { - if (!pMask || !StateType || StateType > g_stateTypes.size()) - return E_INVALIDARG; - - auto pair = g_stateTypes[uint32_t(StateType) - 1]; - auto mask = reinterpret_cast(pMask) + pair.first; - - if (StartIdx + Count > pair.second) - return E_INVALIDARG; - - for (uint32_t i = StartIdx; i < StartIdx + Count; i++) { - uint32_t byte = i / 8; - uint32_t bit = i % 8; - mask[byte] &= ~(1 << bit); - } - - return S_OK; - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskEnableAll( - D3D10_STATE_BLOCK_MASK* pMask) { - if (!pMask) - return E_INVALIDARG; - - *pMask = D3D10_STATE_BLOCK_MASK(); - for (size_t i = 0; i < g_stateTypes.size(); i++) { - D3D10StateBlockMaskEnableCapture(pMask, - D3D10_DEVICE_STATE_TYPES(i + 1), - 0, g_stateTypes[i].second); - } - - return S_OK; - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskDisableAll( - D3D10_STATE_BLOCK_MASK* pMask) { - if (!pMask) - return E_INVALIDARG; - - *pMask = D3D10_STATE_BLOCK_MASK(); - return S_OK; - } - - - BOOL STDMETHODCALLTYPE D3D10StateBlockMaskGetSetting( - D3D10_STATE_BLOCK_MASK* pMask, - D3D10_DEVICE_STATE_TYPES StateType, - UINT Idx) { - if (!pMask || !StateType || StateType > g_stateTypes.size()) - return FALSE; - - auto pair = g_stateTypes[uint32_t(StateType) - 1]; - auto mask = reinterpret_cast(pMask) + pair.first; - - if (Idx >= pair.second) - return FALSE; - - uint32_t byte = Idx / 8; - uint32_t bit = Idx % 8; - return (mask[byte] & (1 << bit)) != 0; - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskDifference( - D3D10_STATE_BLOCK_MASK* pA, - D3D10_STATE_BLOCK_MASK* pB, - D3D10_STATE_BLOCK_MASK* pResult) { - if (!pA || !pB || !pResult) - return E_INVALIDARG; - - auto a = reinterpret_cast(pA); - auto b = reinterpret_cast(pB); - auto r = reinterpret_cast(pResult); - - for (size_t i = 0; i < sizeof(D3D10_STATE_BLOCK_MASK); i++) - r[i] = a[i] ^ b[i]; - return S_OK; - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskIntersect( - D3D10_STATE_BLOCK_MASK* pA, - D3D10_STATE_BLOCK_MASK* pB, - D3D10_STATE_BLOCK_MASK* pResult) { - if (!pA || !pB || !pResult) - return E_INVALIDARG; - - auto a = reinterpret_cast(pA); - auto b = reinterpret_cast(pB); - auto r = reinterpret_cast(pResult); - - for (size_t i = 0; i < sizeof(D3D10_STATE_BLOCK_MASK); i++) - r[i] = a[i] & b[i]; - return S_OK; - } - - - HRESULT STDMETHODCALLTYPE D3D10StateBlockMaskUnion( - D3D10_STATE_BLOCK_MASK* pA, - D3D10_STATE_BLOCK_MASK* pB, - D3D10_STATE_BLOCK_MASK* pResult) { - if (!pA || !pB || !pResult) - return E_INVALIDARG; - - auto a = reinterpret_cast(pA); - auto b = reinterpret_cast(pB); - auto r = reinterpret_cast(pResult); - - for (size_t i = 0; i < sizeof(D3D10_STATE_BLOCK_MASK); i++) - r[i] = a[i] | b[i]; - return S_OK; - } - -} diff --git a/src/d3d10/d3d10_state_block.h b/src/d3d10/d3d10_state_block.h deleted file mode 100644 index b899034d5..000000000 --- a/src/d3d10/d3d10_state_block.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include "d3d10_include.h" -#include "d3d10_interfaces.h" - -namespace dxvk { - - struct D3D10_STATE_BLOCK_STATE { - Com vs = { }; - Com vsSso[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT] = { }; - Com vsSrv[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = { }; - Com vsCbo[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = { }; - Com gs = { }; - Com gsSso[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT] = { }; - Com gsSrv[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = { }; - Com gsCbo[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = { }; - Com ps = { }; - Com psSso[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT] = { }; - Com psSrv[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = { }; - Com psCbo[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = { }; - Com iaVertexBuffers[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = { }; - UINT iaVertexOffsets[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = { }; - UINT iaVertexStrides[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = { }; - Com iaIndexBuffer = { }; - DXGI_FORMAT iaIndexFormat = DXGI_FORMAT_UNKNOWN; - UINT iaIndexOffset = 0; - Com iaInputLayout = nullptr; - D3D10_PRIMITIVE_TOPOLOGY iaTopology = D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED; - Com omRtv[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT] = { }; - Com omDsv = { }; - Com omDepthStencilState = { }; - UINT omStencilRef = 0; - Com omBlendState = { }; - FLOAT omBlendFactor[4] = { }; - UINT omSampleMask = 0; - UINT rsViewportCount = 0; - D3D10_VIEWPORT rsViewports[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] = { }; - UINT rsScissorCount = 0; - RECT rsScissors [D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] = { }; - Com rsState = { }; - Com soBuffers[D3D10_SO_BUFFER_SLOT_COUNT] = { }; - UINT soOffsets[D3D10_SO_BUFFER_SLOT_COUNT] = { }; - Com predicate = { }; - BOOL predicateInvert = FALSE; - }; - - - class D3D10StateBlock : public ComObject { - - public: - D3D10StateBlock( - ID3D10Device* pDevice, - const D3D10_STATE_BLOCK_MASK* pMask); - - ~D3D10StateBlock(); - - HRESULT STDMETHODCALLTYPE QueryInterface( - REFIID riid, - void** ppvObject); - - HRESULT STDMETHODCALLTYPE Capture(); - - HRESULT STDMETHODCALLTYPE Apply(); - - HRESULT STDMETHODCALLTYPE GetDevice( - ID3D10Device** ppDevice); - - HRESULT STDMETHODCALLTYPE ReleaseAllDeviceObjects(); - - private: - - Com m_device; - D3D10_STATE_BLOCK_MASK m_mask; - D3D10_STATE_BLOCK_STATE m_state; - - static BOOL TestBit( - const BYTE* pMask, - UINT Idx); - - }; - -} diff --git a/src/d3d10/meson.build b/src/d3d10/meson.build index 0a78fcc37..20324939d 100644 --- a/src/d3d10/meson.build +++ b/src/d3d10/meson.build @@ -1,17 +1,9 @@ -d3d10_res = wrc_generator.process('version10.rc') -d3d10_1_res = wrc_generator.process('version10_1.rc') d3d10_core_res = wrc_generator.process('version10_core.rc') d3d10_core_src = [ 'd3d10_core.cpp', ] -d3d10_main_src = [ - 'd3d10_main.cpp', - 'd3d10_reflection.cpp', - 'd3d10_state_block.cpp', -] - d3d10_core_dll = shared_library('d3d10core'+dll_ext, d3d10_core_src, d3d10_core_res, name_prefix : '', dependencies : [ d3d11_dep ], @@ -23,26 +15,3 @@ d3d10_core_dll = shared_library('d3d10core'+dll_ext, d3d10_core_src, d3d10_core_ d3d10_core_dep = declare_dependency( link_with : [ d3d10_core_dll ], ) - -d3d10_deps = [ lib_d3dcompiler_43, lib_dxgi, dxbc_dep, dxvk_dep, d3d10_core_dep ] - -d3d10_dll = shared_library('d3d10'+dll_ext, d3d10_main_src, d3d10_res, - name_prefix : '', - dependencies : [ d3d10_deps ], - include_directories : dxvk_include_path, - install : true, - vs_module_defs : 'd3d10'+def_spec_ext, -) - -d3d10_1_dll = shared_library('d3d10_1'+dll_ext, d3d10_main_src, d3d10_1_res, - name_prefix : '', - dependencies : [ d3d10_deps ], - include_directories : dxvk_include_path, - install : true, - vs_module_defs : 'd3d10_1'+def_spec_ext, -) - -d3d10_dep = declare_dependency( - link_with : [ d3d10_dll, d3d10_1_dll, d3d10_core_dll ], - include_directories : [ dxvk_include_path ], -) diff --git a/src/d3d10/version10.rc b/src/d3d10/version10.rc deleted file mode 100644 index 43d7a62fd..000000000 --- a/src/d3d10/version10.rc +++ /dev/null @@ -1,32 +0,0 @@ -#include - -// DLL version information. -VS_VERSION_INFO VERSIONINFO -FILEVERSION 10,0,17763,1 -PRODUCTVERSION 10,0,17763,1 -FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -FILEFLAGS 0 -FILEOS VOS_NT_WINDOWS32 -FILETYPE VFT_DLL -FILESUBTYPE VFT2_UNKNOWN -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080904b0" - BEGIN - VALUE "CompanyName", "DXVK" - VALUE "FileDescription", "Direct3D 10 Runtime" - VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)" - VALUE "InternalName", "D3D10.dll" - VALUE "LegalCopyright", "zlib/libpng license" - VALUE "OriginalFilename", "D3D10.dll" - VALUE "ProductName", "DXVK" - VALUE "ProductVersion", "10.0.17763.1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0809, 1200 - END -END - diff --git a/src/d3d10/version10_1.rc b/src/d3d10/version10_1.rc deleted file mode 100644 index 92550d322..000000000 --- a/src/d3d10/version10_1.rc +++ /dev/null @@ -1,32 +0,0 @@ -#include - -// DLL version information. -VS_VERSION_INFO VERSIONINFO -FILEVERSION 10,0,17763,1 -PRODUCTVERSION 10,0,17763,1 -FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -FILEFLAGS 0 -FILEOS VOS_NT_WINDOWS32 -FILETYPE VFT_DLL -FILESUBTYPE VFT2_UNKNOWN -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080904b0" - BEGIN - VALUE "CompanyName", "DXVK" - VALUE "FileDescription", "Direct3D 10.1 Runtime" - VALUE "FileVersion", "10.0.17763.1 (WinBuild.160101.0800)" - VALUE "InternalName", "D3D10_1.dll" - VALUE "LegalCopyright", "zlib/libpng license" - VALUE "OriginalFilename", "D3D10_1.dll" - VALUE "ProductName", "DXVK" - VALUE "ProductVersion", "10.0.17763.1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0809, 1200 - END -END - From b96947107aae34ec0de6be93171bf1cdfc88949a Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Tue, 30 Aug 2022 09:24:09 +0200 Subject: [PATCH 0721/1348] [build] Remove dead lib_d3dcompiler_43. Fixes MSVC build. --- meson.build | 7 ------- 1 file changed, 7 deletions(-) diff --git a/meson.build b/meson.build index b24c3a920..ff3a1e1f5 100644 --- a/meson.build +++ b/meson.build @@ -63,16 +63,9 @@ if platform == 'windows' ] endif - if (cpu_family == 'x86_64') - dxvk_library_path = meson.current_source_dir() + '/lib' - else - dxvk_library_path = meson.current_source_dir() + '/lib32' - endif - lib_d3d9 = cpp.find_library('d3d9') lib_d3d11 = cpp.find_library('d3d11') lib_dxgi = cpp.find_library('dxgi') - lib_d3dcompiler_43 = cpp.find_library('d3dcompiler_43', dirs : dxvk_library_path) if dxvk_is_msvc lib_d3dcompiler_47 = cpp.find_library('d3dcompiler') From 575367461cdb3f98b7f0294e0ce9b42e4f62b05e Mon Sep 17 00:00:00 2001 From: Christophe Date: Tue, 16 Aug 2022 15:25:49 +0200 Subject: [PATCH 0722/1348] Add VKDK profiles file to express Vulkan requirements --- VP_DXVK_requirements.json | 585 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 585 insertions(+) create mode 100644 VP_DXVK_requirements.json diff --git a/VP_DXVK_requirements.json b/VP_DXVK_requirements.json new file mode 100644 index 000000000..ca4a637c6 --- /dev/null +++ b/VP_DXVK_requirements.json @@ -0,0 +1,585 @@ +{ + "$schema": "https://schema.khronos.org/vulkan/profiles-0.8.0-224.json#", + "capabilities": { + "vulkan10requirements": { + "features": { + "VkPhysicalDeviceFeatures": { + "robustBufferAccess": true + } + } + }, + "vulkan11requirements": { + "features": { + "VkPhysicalDeviceVulkan11Features": { + "multiview": true + } + }, + "properties": { + "VkPhysicalDeviceVulkan11Properties": { + "maxMultiviewViewCount": 6, + "maxMultiviewInstanceIndex": 134217727 + } + } + }, + "vulkan12requirements": { + "features": { + "VkPhysicalDeviceVulkan12Features": { + "uniformBufferStandardLayout": true, + "subgroupBroadcastDynamicId": true, + "imagelessFramebuffer": true, + "separateDepthStencilLayouts": true, + "hostQueryReset": true, + "timelineSemaphore": true, + "shaderSubgroupExtendedTypes": true + } + }, + "properties": { + "VkPhysicalDeviceVulkan12Properties": { + "maxTimelineSemaphoreValueDifference": 2147483647 + } + } + }, + "vulkan13requirements": { + "features": { + "VkPhysicalDeviceVulkan12Features": { + "vulkanMemoryModel": true, + "vulkanMemoryModelDeviceScope": true, + "bufferDeviceAddress": true + }, + "VkPhysicalDeviceVulkan13Features": { + "robustImageAccess": true, + "shaderTerminateInvocation": true, + "shaderZeroInitializeWorkgroupMemory": true, + "synchronization2": true, + "shaderIntegerDotProduct": true, + "maintenance4": true, + "pipelineCreationCacheControl": true, + "subgroupSizeControl": true, + "computeFullSubgroups": true, + "shaderDemoteToHelperInvocation": true, + "inlineUniformBlock": true, + "dynamicRendering": true + } + }, + "properties": { + "VkPhysicalDeviceVulkan13Properties": { + "maxBufferSize": 1073741824, + "maxInlineUniformBlockSize": 256, + "maxPerStageDescriptorInlineUniformBlocks": 4, + "maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks": 4, + "maxDescriptorSetInlineUniformBlocks": 4, + "maxDescriptorSetUpdateAfterBindInlineUniformBlocks": 4, + "maxInlineUniformTotalSize": 4 + } + } + }, + "d3d9_baseline": { + "extensions": { + "VK_EXT_robustness2": 1 + }, + "features": { + "VkPhysicalDeviceFeatures": { + "geometryShader": true, + "shaderStorageImageWriteWithoutFormat": true, + "imageCubeArray": true, + "depthClamp": true, + "depthBiasClamp": true, + "fillModeNonSolid": true, + "sampleRateShading": true, + "shaderClipDistance": true, + "shaderCullDistance": true, + "textureCompressionBC": true, + "occlusionQueryPrecise": true, + "independentBlend": true, + "fullDrawIndexUint32": true, + + "shaderImageGatherExtended": true + }, + "VkPhysicalDeviceVulkan12Features": { + "samplerMirrorClampToEdge": true + }, + "VkPhysicalDeviceRobustness2FeaturesEXT": { + "nullDescriptor": true, + "robustBufferAccess2": true + } + } + }, + "d3d9_optional": { + "extensions": { + "VK_EXT_memory_priority": 1, + "VK_EXT_vertex_attribute_divisor": 1, + "VK_EXT_depth_clip_enable": 1, + "VK_EXT_custom_border_color": 1, + "VK_EXT_attachment_feedback_loop_layout": 1, + "VK_EXT_non_seamless_cube_map": 1 + }, + "features": { + "VkPhysicalDeviceFeatures": { + "depthBounds": true, + "vertexPipelineStoresAndAtomics": true, + "pipelineStatisticsQuery": true, + "samplerAnisotropy": true + }, + "VkPhysicalDeviceMemoryPriorityFeaturesEXT": { + "memoryPriority": true + }, + "VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT": { + "vertexAttributeInstanceRateDivisor": true, + "vertexAttributeInstanceRateZeroDivisor": true + }, + "VkPhysicalDeviceDepthClipEnableFeaturesEXT": { + "depthClipEnable": true + }, + "VkPhysicalDeviceCustomBorderColorFeaturesEXT": { + "customBorderColors": true, + "customBorderColorWithoutFormat": true, + }, + "VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT": { + "attachmentFeedbackLoopLayout": true + }, + "VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT": { + "nonSeamlessCubeMap": true + } + } + }, + "d3d11_baseline": { + "extensions": { + "VK_EXT_robustness2": 1 + }, + "features": { + "VkPhysicalDeviceFeatures": { + "geometryShader": true, + "shaderStorageImageWriteWithoutFormat": true, + "depthBounds": true, + + "imageCubeArray": true, + "depthClamp": true, + "depthBiasClamp": true, + "fillModeNonSolid": true, + "sampleRateShading": true, + "shaderClipDistance": true, + "shaderCullDistance": true, + "textureCompressionBC": true, + "occlusionQueryPrecise": true, + "multiViewport": true, + "independentBlend": true, + "fullDrawIndexUint32": true, + + "shaderImageGatherExtended": true + }, + "VkPhysicalDeviceVulkan11Features": { + "shaderDrawParameters": true + }, + "VkPhysicalDeviceVulkan12Features": { + "samplerMirrorClampToEdge": true + }, + "VkPhysicalDeviceRobustness2FeaturesEXT": { + "nullDescriptor": true, + "robustBufferAccess2": true + } + } + }, + "d3d11_baseline_optional":{ + "extensions": { + "VK_EXT_memory_priority": 1, + "VK_EXT_vertex_attribute_divisor": 1, + "VK_EXT_custom_border_color": 1 + }, + "features": { + "VkPhysicalDeviceFeatures": { + "depthBounds": true + }, + "VkPhysicalDeviceMemoryPriorityFeaturesEXT": { + "memoryPriority": true + }, + "VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT": { + "vertexAttributeInstanceRateDivisor": true, + "vertexAttributeInstanceRateZeroDivisor": true + }, + + "VkPhysicalDeviceCustomBorderColorFeaturesEXT": { + "customBorderColors": true, + "customBorderColorWithoutFormat": true, + } + } + }, + "d3d11_level9_1": { + "extensions": { + "VK_EXT_transform_feedback": 1, + "VK_EXT_depth_clip_enable": 1 + }, + "features": { + "VkPhysicalDeviceFeatures": { + "depthClamp": true, + "depthBiasClamp": true, + "fillModeNonSolid": true, + "sampleRateShading": true, + "shaderClipDistance": true, + "shaderCullDistance": true, + "textureCompressionBC": true + }, + "VkPhysicalDeviceDepthClipEnableFeaturesEXT": { + "depthClipEnable": true + }, + } + }, + "d3d11_level9_1_optional": { + "extensions": { + "VK_EXT_depth_clip_enable": 1 + }, + "features": { + "VkPhysicalDeviceFeatures": { + "pipelineStatisticsQuery": true, + "samplerAnisotropy": true + }, + "VkPhysicalDeviceDepthClipEnableFeaturesEXT": { + "depthClipEnable": true + } + } + }, + "d3d11_level9_2": { + "features": { + "VkPhysicalDeviceFeatures": { + "occlusionQueryPrecise": true + } + } + }, + "d3d11_level9_3": { + "features": { + "VkPhysicalDeviceFeatures": { + "independentBlend": true, + "multiViewport": true + } + } + }, + "d3d11_level10_0": { + "extensions": { + "VK_EXT_transform_feedback": 1 + }, + "features": { + "VkPhysicalDeviceFeatures": { + "fullDrawIndexUint32": true, + "shaderImageGatherExtended": true + }, + "VkPhysicalDeviceTransformFeedbackFeaturesEXT": { + "transformFeedback": true, + "geometryStreams": true + } + } + }, + "d3d11_level10_0_optional": { + "features": { + "VkPhysicalDeviceFeatures": { + "logicOp": true, + "variableMultisampleRate": true + } + } + }, + "d3d11_level10_1": { + "features": { + "VkPhysicalDeviceFeatures": { + "dualSrcBlend": true, + "imageCubeArray": true + } + } + }, + "d3d11_level11_0": { + "features": { + "VkPhysicalDeviceFeatures": { + "drawIndirectFirstInstance": true, + "fragmentStoresAndAtomics": true, + "multiDrawIndirect": true, + "tessellationShader": true + } + } + }, + "d3d11_level11_0_optional": { + "features": { + "VkPhysicalDeviceFeatures": { + "shaderFloat64": true, + "shaderInt64": true, + "shaderStorageImageReadWithoutFormat": true + } + } + }, + "d3d11_level11_1": { + "features": { + "VkPhysicalDeviceFeatures": { + "logicOp": true, + "variableMultisampleRate": true, + "vertexPipelineStoresAndAtomics": true + } + } + }, + "d3d11_level12_0": { + "properties": { + "VkPhysicalDeviceProperties": { + "sparseProperties": { + "residencyStandard2DBlockShape": true, + "residencyAlignedMipSize": true + } + } + } + } + }, + "profiles": { + "VP_DXVK_d3d9_baseline": { + "version": 1, + "api-version": "1.3.204", + "label": "DXVK D3D9 Baseline profile", + "description": "DXVK for D3D9 minimum requirements", + "contributors": { + "Philip Rebohle": { + "company": "Valve" + }, + "Joshua Ashton": { + "company": "Valve" + }, + "Pierre-Loup A. Griffais": { + "company": "Valve" + }, + "Georg Lehmann": { + "company": "DXVK" + }, + "Christophe Riccio": { + "company": "LunarG" + } + }, + "history": [ + { + "revision": 1, + "date": "2022-08-22", + "author": "Christophe Riccio", + "comment": "Initial revision" + } + ], + "capabilities": [ + "vulkan10requirements", + "vulkan11requirements", + "vulkan12requirements", + "vulkan13requirements", + "d3d9_baseline" + ] + }, + "VP_DXVK_d3d9_optimal": { + "version": 1, + "api-version": "1.3.224", + "label": "DXVK D3D9 Optimal profile", + "description": "DXVK for D3D9 including optional capabilities", + "contributors": { + "Philip Rebohle": { + "company": "Valve" + }, + "Joshua Ashton": { + "company": "Valve" + }, + "Pierre-Loup A. Griffais": { + "company": "Valve" + }, + "Georg Lehmann": { + "company": "DXVK" + }, + "Christophe Riccio": { + "company": "LunarG" + } + }, + "history": [ + { + "revision": 1, + "date": "2022-08-22", + "author": "Christophe Riccio", + "comment": "Initial revision" + } + ], + "capabilities": [ + "vulkan10requirements", + "vulkan11requirements", + "vulkan12requirements", + "vulkan13requirements", + "d3d9_baseline", + "d3d9_optional" + ] + }, + "VP_DXVK_d3d10_level_10_1_baseline": { + "version": 1, + "api-version": "1.3.204", + "label": "DXVK D3D10 Level 10.1 Baseline profile", + "description": "DXVK for D3D10 Feature Level 10.1 minimum requirements", + "contributors": { + "Philip Rebohle": { + "company": "Valve" + }, + "Joshua Ashton": { + "company": "Valve" + }, + "Pierre-Loup A. Griffais": { + "company": "Valve" + }, + "Georg Lehmann": { + "company": "DXVK" + }, + "Christophe Riccio": { + "company": "LunarG" + } + }, + "history": [ + { + "revision": 1, + "date": "2022-08-22", + "author": "Christophe Riccio", + "comment": "Initial revision" + } + ], + "capabilities": [ + "vulkan10requirements", + "vulkan11requirements", + "vulkan12requirements", + "vulkan13requirements", + "d3d11_baseline", + "d3d11_level9_1", + "d3d11_level9_2", + "d3d11_level9_3", + "d3d11_level10_0", + "d3d11_level10_1" + ] + }, + "VP_DXVK_d3d11_level_11_0_baseline": { + "version": 1, + "api-version": "1.3.204", + "label": "DXVK D3D11 Level 11.0 Baseline profile", + "description": "DXVK for D3D11 Feature Level 11.0 minimum requirements", + "contributors": { + "Philip Rebohle": { + "company": "Valve" + }, + "Joshua Ashton": { + "company": "Valve" + }, + "Pierre-Loup A. Griffais": { + "company": "Valve" + }, + "Georg Lehmann": { + "company": "DXVK" + }, + "Christophe Riccio": { + "company": "LunarG" + } + }, + "history": [ + { + "revision": 1, + "date": "2022-08-22", + "author": "Christophe Riccio", + "comment": "Initial revision" + } + ], + "capabilities": [ + "vulkan10requirements", + "vulkan11requirements", + "vulkan12requirements", + "vulkan13requirements", + "d3d11_baseline", + "d3d11_level9_1", + "d3d11_level9_2", + "d3d11_level9_3", + "d3d11_level10_0", + "d3d11_level10_1", + "d3d11_level11_0" + ] + }, + "VP_DXVK_d3d11_level_11_1_baseline": { + "version": 1, + "api-version": "1.3.204", + "label": "DXVK D3D11 Level 11.1 Baseline profile", + "description": "DXVK for D3D11 Feature Level 11.1 minimum requirements", + "contributors": { + "Philip Rebohle": { + "company": "Valve" + }, + "Joshua Ashton": { + "company": "Valve" + }, + "Pierre-Loup A. Griffais": { + "company": "Valve" + }, + "Georg Lehmann": { + "company": "DXVK" + }, + "Christophe Riccio": { + "company": "LunarG" + } + }, + "history": [ + { + "revision": 1, + "date": "2022-08-22", + "author": "Christophe Riccio", + "comment": "Initial revision" + } + ], + "capabilities": [ + "vulkan10requirements", + "vulkan11requirements", + "vulkan12requirements", + "vulkan13requirements", + "baseline", + "d3d11_level9_1", + "d3d11_level9_2", + "d3d11_level9_3", + "d3d11_level10_0", + "d3d11_level10_1", + "d3d11_level11_0", + "d3d11_level11_1" + ] + }, + "VP_DXVK_d3d11_level_11_1_optimal": { + "version": 1, + "api-version": "1.3.204", + "label": "DXVK D3D11 Level 11.1 Optimal profile", + "description": "DXVK for D3D11 Feature Level 11.1 including optional capabilities", + "contributors": { + "Philip Rebohle": { + "company": "Valve" + }, + "Joshua Ashton": { + "company": "Valve" + }, + "Pierre-Loup A. Griffais": { + "company": "Valve" + }, + "Georg Lehmann": { + "company": "DXVK" + }, + "Christophe Riccio": { + "company": "LunarG" + } + }, + "history": [ + { + "revision": 1, + "date": "2022-08-22", + "author": "Christophe Riccio", + "comment": "Initial revision" + } + ], + "capabilities": [ + "vulkan10requirements", + "vulkan11requirements", + "vulkan12requirements", + "vulkan13requirements", + "d3d11_baseline", + "d3d11_baseline_optional", + "d3d11_level9_1", + "d3d11_level9_1_optional", + "d3d11_level9_2", + "d3d11_level9_3", + "d3d11_level10_0", + "d3d11_level10_0_optional", + "d3d11_level10_1", + "d3d11_level11_0", + "d3d11_level11_0_optional", + "d3d11_level11_1" + ] + } + } +} From 788d80cfe7980765572c7212808d836febf6ac8a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 30 Aug 2022 13:17:52 +0200 Subject: [PATCH 0723/1348] [meta] Fix some trailing comma warnings in Vulkan profile --- VP_DXVK_requirements.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/VP_DXVK_requirements.json b/VP_DXVK_requirements.json index ca4a637c6..8277be743 100644 --- a/VP_DXVK_requirements.json +++ b/VP_DXVK_requirements.json @@ -132,7 +132,7 @@ }, "VkPhysicalDeviceCustomBorderColorFeaturesEXT": { "customBorderColors": true, - "customBorderColorWithoutFormat": true, + "customBorderColorWithoutFormat": true }, "VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT": { "attachmentFeedbackLoopLayout": true @@ -199,7 +199,7 @@ "VkPhysicalDeviceCustomBorderColorFeaturesEXT": { "customBorderColors": true, - "customBorderColorWithoutFormat": true, + "customBorderColorWithoutFormat": true } } }, @@ -220,7 +220,7 @@ }, "VkPhysicalDeviceDepthClipEnableFeaturesEXT": { "depthClipEnable": true - }, + } } }, "d3d11_level9_1_optional": { From 399ba7138753f6cc4b0e2d37ffa3483a9d4a6b1e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 30 Aug 2022 13:18:15 +0200 Subject: [PATCH 0724/1348] [meta] Add profile for D3D11 FL12_0 --- VP_DXVK_requirements.json | 66 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/VP_DXVK_requirements.json b/VP_DXVK_requirements.json index 8277be743..2741b579e 100644 --- a/VP_DXVK_requirements.json +++ b/VP_DXVK_requirements.json @@ -312,11 +312,25 @@ } }, "d3d11_level12_0": { + "features": { + "VkPhysicalDeviceFeatures": { + "shaderResourceResidency": true, + "shaderResourceMinLod": true, + "sparseBinding": true, + "sparseResidencyBuffer": true, + "sparseResidencyAliased": true, + "sparseResidencyImage2D": true + }, + "VkPhysicalDeviceVulkan12Features": { + "samplerFilterMinmax": true + } + }, "properties": { "VkPhysicalDeviceProperties": { "sparseProperties": { "residencyStandard2DBlockShape": true, - "residencyAlignedMipSize": true + "residencyAlignedMipSize": false, + "residencyNonResidentStrict": true } } } @@ -580,6 +594,56 @@ "d3d11_level11_0_optional", "d3d11_level11_1" ] + }, + "VP_DXVK_d3d11_level_12_0_optimal": { + "version": 1, + "api-version": "1.3.204", + "label": "DXVK D3D11 Level 12.0 Optimal profile", + "description": "DXVK for D3D11 Feature Level 12.0 including optional capabilities", + "contributors": { + "Philip Rebohle": { + "company": "Valve" + }, + "Joshua Ashton": { + "company": "Valve" + }, + "Pierre-Loup A. Griffais": { + "company": "Valve" + }, + "Georg Lehmann": { + "company": "DXVK" + }, + "Christophe Riccio": { + "company": "LunarG" + } + }, + "history": [ + { + "revision": 1, + "date": "2022-08-30", + "author": "Philip Rebohle", + "comment": "Initial revision" + } + ], + "capabilities": [ + "vulkan10requirements", + "vulkan11requirements", + "vulkan12requirements", + "vulkan13requirements", + "d3d11_baseline", + "d3d11_baseline_optional", + "d3d11_level9_1", + "d3d11_level9_1_optional", + "d3d11_level9_2", + "d3d11_level9_3", + "d3d11_level10_0", + "d3d11_level10_0_optional", + "d3d11_level10_1", + "d3d11_level11_0", + "d3d11_level11_0_optional", + "d3d11_level11_1", + "d3d11_level12_0" + ] } } } From 5e33374fd28237ec94c06725009ccf23d5035b97 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 30 Aug 2022 13:19:39 +0200 Subject: [PATCH 0725/1348] [meta] Remove shaderStorageImage*WithoutFormat capabilities from profile We no longer use these. --- VP_DXVK_requirements.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/VP_DXVK_requirements.json b/VP_DXVK_requirements.json index 2741b579e..6317a829e 100644 --- a/VP_DXVK_requirements.json +++ b/VP_DXVK_requirements.json @@ -80,7 +80,6 @@ "features": { "VkPhysicalDeviceFeatures": { "geometryShader": true, - "shaderStorageImageWriteWithoutFormat": true, "imageCubeArray": true, "depthClamp": true, "depthBiasClamp": true, @@ -149,7 +148,6 @@ "features": { "VkPhysicalDeviceFeatures": { "geometryShader": true, - "shaderStorageImageWriteWithoutFormat": true, "depthBounds": true, "imageCubeArray": true, @@ -297,8 +295,7 @@ "features": { "VkPhysicalDeviceFeatures": { "shaderFloat64": true, - "shaderInt64": true, - "shaderStorageImageReadWithoutFormat": true + "shaderInt64": true } } }, From 3e0031cefe0731f0d027ccc5f4fe45bf5ab5bfa9 Mon Sep 17 00:00:00 2001 From: WinterSnowfall Date: Mon, 29 Aug 2022 17:59:19 +0300 Subject: [PATCH 0726/1348] [util] Add a maxAvailableMemory limit for Heroes of Annihilated Empires --- src/util/config/config.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 4d0753cc7..a428654f7 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -595,6 +595,13 @@ namespace dxvk { { "d3d9.textureMemory", "16" }, { "d3d9.allowDirectBufferMapping", "False" }, }} }, + /* Heroes of Annihilated Empires * + * Has issues with texture rendering and * + * video memory detection otherwise. */ + { R"(\\Heroes (o|O)f Annihilated Empires.*\\engine\.exe$)", {{ + { "d3d9.memoryTrackTest", "True" }, + { "d3d9.maxAvailableMemory", "2048" }, + }} }, }}; From 354b88d178acdba3334783e87453ac971c83e954 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Aug 2022 15:09:24 +0200 Subject: [PATCH 0727/1348] [dxvk] Add shader method to retrieve raw code --- src/dxvk/dxvk_shader.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index d3de90ea2..6f820050a 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -149,6 +149,13 @@ namespace dxvk { m_needsLibraryCompile.store(false); } + /** + * \brief Gets raw code without modification + */ + SpirvCodeBuffer getRawCode() const { + return m_code.decompress(); + } + /** * \brief Patches code using given info * From 610472e658fb991b11cabcde0f9517f12d7ec2af Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Aug 2022 15:00:46 +0200 Subject: [PATCH 0728/1348] [d3d11] Introduce ID3D11VkExtShader --- src/d3d11/d3d11_interfaces.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/d3d11/d3d11_interfaces.h b/src/d3d11/d3d11_interfaces.h index 3b0629bbd..587cde139 100644 --- a/src/d3d11/d3d11_interfaces.h +++ b/src/d3d11/d3d11_interfaces.h @@ -28,6 +28,26 @@ enum D3D11_VK_BARRIER_CONTROL : uint32_t { }; +/** + * \brief Extended shader interface + */ +MIDL_INTERFACE("bb8a4fb9-3935-4762-b44b-35189a26414a") +ID3D11VkExtShader : public IUnknown { + /** + * \brief Retrieves SPIR-V code from a shader object + * + * \param [in,out] pCodeSize Shader code size, in bytes. If + * \ref pCode is \c nullptr, this will return the total + * code size, otherwise the number of bytes written. + * \param [out] pCode SPIR-V shader code + * \returns \c S_OK, or \c S_FALSE if the buffer was too small + */ + virtual HRESULT STDMETHODCALLTYPE GetSpirvCode( + SIZE_T* pCodeSize, + void* pCode) = 0; +}; + + /** * \brief Extended D3D11 device * @@ -164,11 +184,13 @@ ID3D11VkExtContext1 : public ID3D11VkExtContext { #ifdef _MSC_VER +struct __declspec(uuid("bb8a4fb9-3935-4762-b44b-35189a26414a")) ID3D11VkExtShader; struct __declspec(uuid("8a6e3c42-f74c-45b7-8265-a231b677ca17")) ID3D11VkExtDevice; struct __declspec(uuid("cfcf64ef-9586-46d0-bca4-97cf2ca61b06")) ID3D11VkExtDevice1; struct __declspec(uuid("fd0bca13-5cb6-4c3a-987e-4750de2ca791")) ID3D11VkExtContext; struct __declspec(uuid("874b09b2-ae0b-41d8-8476-5f3b7a0e879d")) ID3D11VkExtContext1; #else +__CRT_UUID_DECL(ID3D11VkExtShader, 0xbb8a4fb9,0x3935,0x4762,0xb4,0x4b,0x35,0x18,0x9a,0x26,0x41,0x4a); __CRT_UUID_DECL(ID3D11VkExtDevice, 0x8a6e3c42,0xf74c,0x45b7,0x82,0x65,0xa2,0x31,0xb6,0x77,0xca,0x17); __CRT_UUID_DECL(ID3D11VkExtDevice1, 0xcfcf64ef,0x9586,0x46d0,0xbc,0xa4,0x97,0xcf,0x2c,0xa6,0x1b,0x06); __CRT_UUID_DECL(ID3D11VkExtContext, 0xfd0bca13,0x5cb6,0x4c3a,0x98,0x7e,0x47,0x50,0xde,0x2c,0xa7,0x91); From e882a7f8ba70006a83b708edce95d684528ceb03 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Aug 2022 15:15:57 +0200 Subject: [PATCH 0729/1348] [d3d11] Implement extended shader interface --- src/d3d11/d3d11_shader.cpp | 56 ++++++++++++++++++++++++++++++++++++++ src/d3d11/d3d11_shader.h | 47 +++++++++++++++++++++++++++++--- 2 files changed, 99 insertions(+), 4 deletions(-) diff --git a/src/d3d11/d3d11_shader.cpp b/src/d3d11/d3d11_shader.cpp index 085ad13f2..c153c8397 100644 --- a/src/d3d11/d3d11_shader.cpp +++ b/src/d3d11/d3d11_shader.cpp @@ -125,4 +125,60 @@ namespace dxvk { return S_OK; } + + D3D11ExtShader::D3D11ExtShader( + ID3D11DeviceChild* pParent, + D3D11CommonShader* pShader) + : m_parent(pParent), m_shader(pShader) { + + } + + + D3D11ExtShader::~D3D11ExtShader() { + + } + + + ULONG STDMETHODCALLTYPE D3D11ExtShader::AddRef() { + return m_parent->AddRef(); + } + + + ULONG STDMETHODCALLTYPE D3D11ExtShader::Release() { + return m_parent->Release(); + } + + + HRESULT STDMETHODCALLTYPE D3D11ExtShader::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_parent->QueryInterface(riid, ppvObject); + } + + + HRESULT STDMETHODCALLTYPE D3D11ExtShader::GetSpirvCode( + SIZE_T* pCodeSize, + void* pCode) { + auto shader = m_shader->GetShader(); + auto code = shader->getRawCode(); + + HRESULT hr = S_OK; + + if (pCode) { + size_t size = code.size(); + + if (size > *pCodeSize) { + size = *pCodeSize; + hr = S_FALSE; + } + + std::memcpy(pCode, code.data(), size); + *pCodeSize = size; + return hr; + } else { + *pCodeSize = code.size(); + return hr; + } + } + } diff --git a/src/d3d11/d3d11_shader.h b/src/d3d11/d3d11_shader.h index 4ef2e4b90..fe499bc14 100644 --- a/src/d3d11/d3d11_shader.h +++ b/src/d3d11/d3d11_shader.h @@ -59,8 +59,41 @@ namespace dxvk { Rc m_buffer; }; - - + + + /** + * \brief Extended shader interface + */ + class D3D11ExtShader : public ID3D11VkExtShader { + + public: + + D3D11ExtShader( + ID3D11DeviceChild* pParent, + D3D11CommonShader* pShader); + + ~D3D11ExtShader(); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + HRESULT STDMETHODCALLTYPE GetSpirvCode( + SIZE_T* pCodeSize, + void* pCode); + + private: + + ID3D11DeviceChild* m_parent; + D3D11CommonShader* m_shader; + + }; + + /** * \brief Common shader interface * @@ -75,7 +108,7 @@ namespace dxvk { D3D11Shader(D3D11Device* device, const D3D11CommonShader& shader) : D3D11DeviceChild(device), - m_shader(shader), m_d3d10(this) { } + m_shader(shader), m_d3d10(this), m_shaderExt(this, &m_shader) { } ~D3D11Shader() { } @@ -95,7 +128,12 @@ namespace dxvk { *ppvObject = ref(&m_d3d10); return S_OK; } - + + if (riid == __uuidof(ID3D11VkExtShader)) { + *ppvObject = ref(&m_shaderExt); + return S_OK; + } + Logger::warn("D3D11Shader::QueryInterface: Unknown interface query"); return E_NOINTERFACE; } @@ -112,6 +150,7 @@ namespace dxvk { D3D11CommonShader m_shader; D3D10ShaderClass m_d3d10; + D3D11ExtShader m_shaderExt; }; From 2b6a903ad991ece9c19388c342d38119a4bf80d7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Aug 2022 16:26:37 +0200 Subject: [PATCH 0730/1348] [tests] Remove DXBC tests --- tests/dxbc/meson.build | 6 -- tests/dxbc/test_dxbc_compiler.cpp | 57 ---------------- tests/dxbc/test_dxbc_disasm.cpp | 60 ---------------- tests/dxbc/test_hlsl_compiler.cpp | 110 ------------------------------ tests/meson.build | 1 - 5 files changed, 234 deletions(-) delete mode 100644 tests/dxbc/meson.build delete mode 100644 tests/dxbc/test_dxbc_compiler.cpp delete mode 100644 tests/dxbc/test_dxbc_disasm.cpp delete mode 100644 tests/dxbc/test_hlsl_compiler.cpp diff --git a/tests/dxbc/meson.build b/tests/dxbc/meson.build deleted file mode 100644 index 54a3533e4..000000000 --- a/tests/dxbc/meson.build +++ /dev/null @@ -1,6 +0,0 @@ -test_dxbc_deps = [ dxbc_dep, dxvk_dep ] - -executable('dxbc-compiler'+exe_ext, files('test_dxbc_compiler.cpp'), dependencies : test_dxbc_deps, install : true, gui_app : true) -executable('dxbc-disasm'+exe_ext, files('test_dxbc_disasm.cpp'), dependencies : [ test_dxbc_deps, lib_d3dcompiler_47 ], install : true, gui_app : true) -executable('hlsl-compiler'+exe_ext, files('test_hlsl_compiler.cpp'), dependencies : [ test_dxbc_deps, lib_d3dcompiler_47 ], install : true, gui_app : true) - diff --git a/tests/dxbc/test_dxbc_compiler.cpp b/tests/dxbc/test_dxbc_compiler.cpp deleted file mode 100644 index 0469c92ea..000000000 --- a/tests/dxbc/test_dxbc_compiler.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include - -#include "../../src/dxbc/dxbc_module.h" -#include "../../src/dxvk/dxvk_shader.h" - -#include -#include -#include - -namespace dxvk { - Logger Logger::s_instance("dxbc-compiler.log"); -} - -using namespace dxvk; - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - int argc = 0; - LPWSTR* argv = CommandLineToArgvW( - GetCommandLineW(), &argc); - - if (argc < 3) { - Logger::err("Usage: dxbc-compiler input.dxbc output.spv"); - return 1; - } - - try { - std::string ifileName = str::fromws(argv[1]); - std::ifstream ifile(ifileName, std::ios::binary); - ifile.ignore(std::numeric_limits::max()); - std::streamsize length = ifile.gcount(); - ifile.clear(); - - ifile.seekg(0, std::ios_base::beg); - std::vector dxbcCode(length); - ifile.read(dxbcCode.data(), length); - - DxbcReader reader(dxbcCode.data(), dxbcCode.size()); - DxbcModule module(reader); - - DxbcModuleInfo moduleInfo; - moduleInfo.options.useSubgroupOpsForAtomicCounters = true; - moduleInfo.options.minSsboAlignment = 4; - moduleInfo.xfb = nullptr; - - Rc shader = module.compile(moduleInfo, ifileName); - std::ofstream ofile(str::fromws(argv[2]), std::ios::binary); - shader->dump(ofile); - return 0; - } catch (const DxvkError& e) { - Logger::err(e.message()); - return 1; - } -} diff --git a/tests/dxbc/test_dxbc_disasm.cpp b/tests/dxbc/test_dxbc_disasm.cpp deleted file mode 100644 index c87ec3529..000000000 --- a/tests/dxbc/test_dxbc_disasm.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include - -#include - -#include -#include -#include - -#include "../../src/util/com/com_pointer.h" - -using namespace dxvk; - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - int argc = 0; - LPWSTR* argv = CommandLineToArgvW( - GetCommandLineW(), &argc); - - if (argc < 2 || argc > 3) { - std::cerr << "Usage: dxbc-disasm input.dxbc [output]" << std::endl; - return 1; - } - - Com assembly; - Com binary; - - // input file - if (FAILED(D3DReadFileToBlob(argv[1], &binary))) { - std::cerr << "Failed to read shader" << std::endl; - return 1; - } - - HRESULT hr = D3DDisassemble( - binary->GetBufferPointer(), - binary->GetBufferSize(), - D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING, nullptr, - &assembly); - - if (FAILED(hr)) { - std::cerr << "Failed to disassemble shader" << std::endl; - return 1; - } - - // output file variant - if (argc == 3 && FAILED(D3DWriteBlobToFile(assembly.ptr(), argv[2], 1))) { - std::cerr << "Failed to write shader" << std::endl; - return 1; - } - - // stdout variant - if (argc == 2) { - std::string data((const char *)assembly->GetBufferPointer(), assembly->GetBufferSize()); - std::cout << data; - } - - return 0; -} diff --git a/tests/dxbc/test_hlsl_compiler.cpp b/tests/dxbc/test_hlsl_compiler.cpp deleted file mode 100644 index 29707e3bb..000000000 --- a/tests/dxbc/test_hlsl_compiler.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include -#include - -#include - -#include -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - int argc = 0; - LPWSTR* argv = CommandLineToArgvW( - GetCommandLineW(), &argc); - - if (argc < 5) { - std::cerr << "Usage: hlsl-compiler target entrypoint input.hlsl output.dxbc [--strip] [--text]" << std::endl; - return 1; - } - - bool strip = false; - bool text = false; - - for (int i = 5; i < argc; i++) { - strip |= str::fromws(argv[i]) == "--strip"; - text |= str::fromws(argv[i]) == "--text"; - } - - const LPWSTR target = argv[1]; - const LPWSTR entryPoint = argv[2]; - const LPWSTR inputFile = argv[3]; - const LPWSTR outputFile = argv[4]; - - std::ifstream ifile(str::fromws(inputFile), std::ios::binary); - ifile.ignore(std::numeric_limits::max()); - std::streamsize length = ifile.gcount(); - ifile.clear(); - - ifile.seekg(0, std::ios_base::beg); - std::vector hlslCode(length); - ifile.read(hlslCode.data(), length); - - Com binary; - Com errors; - - HRESULT hr = D3DCompile( - hlslCode.data(), - hlslCode.size(), - "Shader", nullptr, - D3D_COMPILE_STANDARD_FILE_INCLUDE, - str::fromws(entryPoint).c_str(), - str::fromws(target).c_str(), - D3DCOMPILE_OPTIMIZATION_LEVEL3 | - D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES, - 0, &binary, &errors); - - if (FAILED(hr)) { - if (errors != nullptr) - std::cerr << reinterpret_cast(errors->GetBufferPointer()) << std::endl; - return 1; - } - - if (strip) { - Com strippedBlob; - - hr = D3DStripShader(binary->GetBufferPointer(), binary->GetBufferSize(), - D3DCOMPILER_STRIP_REFLECTION_DATA | D3DCOMPILER_STRIP_DEBUG_INFO, - &strippedBlob); - - if (FAILED(hr)) { - std::cerr << "Failed to strip shader" << std::endl; - return 1; - } - - binary = strippedBlob; - } - - std::ofstream file; - - if (str::fromws(outputFile) != "-") - file = std::ofstream(str::fromws(outputFile), std::ios::binary | std::ios::trunc); - - std::ostream& outputStream = file.is_open() ? file : std::cout; - - if (text) { - auto data = reinterpret_cast(binary->GetBufferPointer()); - auto size = binary->GetBufferSize() / sizeof(uint32_t); - - outputStream << std::hex; - - for (uint32_t i = 0; i < size; i++) { - if (i && !(i & 0x7)) - outputStream << std::endl; - outputStream << "0x" << std::setfill('0') << std::setw(8) << data[i] << ", "; - } - - outputStream << std::endl; - } else { - outputStream.write(reinterpret_cast(binary->GetBufferPointer()), binary->GetBufferSize()); - } - - return 0; -} diff --git a/tests/meson.build b/tests/meson.build index 54fb3d631..e92b2a03a 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,4 +1,3 @@ subdir('d3d9') subdir('d3d11') -subdir('dxbc') subdir('dxgi') From 632e26f687a0796a952199c0224315bd84684ba8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Aug 2022 16:43:55 +0200 Subject: [PATCH 0731/1348] [tests] Remove D3D11 and DXGI tests --- tests/d3d11/meson.build | 10 - tests/d3d11/test_d3d11_compute.cpp | 172 -------- tests/d3d11/test_d3d11_formats.cpp | 304 -------------- tests/d3d11/test_d3d11_map_read.cpp | 203 --------- tests/d3d11/test_d3d11_streamout.cpp | 288 ------------- tests/d3d11/test_d3d11_triangle.cpp | 606 --------------------------- tests/d3d11/test_d3d11_video.cpp | 459 -------------------- tests/d3d11/video_image.raw | Bin 49152 -> 0 bytes tests/dxgi/meson.build | 3 - tests/dxgi/test_dxgi_factory.cpp | 123 ------ tests/meson.build | 2 - 11 files changed, 2170 deletions(-) delete mode 100644 tests/d3d11/meson.build delete mode 100644 tests/d3d11/test_d3d11_compute.cpp delete mode 100644 tests/d3d11/test_d3d11_formats.cpp delete mode 100644 tests/d3d11/test_d3d11_map_read.cpp delete mode 100644 tests/d3d11/test_d3d11_streamout.cpp delete mode 100644 tests/d3d11/test_d3d11_triangle.cpp delete mode 100644 tests/d3d11/test_d3d11_video.cpp delete mode 100644 tests/d3d11/video_image.raw delete mode 100644 tests/dxgi/meson.build delete mode 100644 tests/dxgi/test_dxgi_factory.cpp diff --git a/tests/d3d11/meson.build b/tests/d3d11/meson.build deleted file mode 100644 index 31eba4ee3..000000000 --- a/tests/d3d11/meson.build +++ /dev/null @@ -1,10 +0,0 @@ -test_d3d11_deps = [ util_dep, lib_dxgi, lib_d3d11, lib_d3dcompiler_47 ] - -executable('d3d11-compute'+exe_ext, files('test_d3d11_compute.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true) -executable('d3d11-formats'+exe_ext, files('test_d3d11_formats.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true) -executable('d3d11-map-read'+exe_ext, files('test_d3d11_map_read.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true) -executable('d3d11-streamout'+exe_ext, files('test_d3d11_streamout.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true) -executable('d3d11-triangle'+exe_ext, files('test_d3d11_triangle.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true) -executable('d3d11-video'+exe_ext, files('test_d3d11_video.cpp'), dependencies : test_d3d11_deps, install : true, gui_app : true) - -install_data('video_image.raw', install_dir : get_option('bindir')) \ No newline at end of file diff --git a/tests/d3d11/test_d3d11_compute.cpp b/tests/d3d11/test_d3d11_compute.cpp deleted file mode 100644 index 878265819..000000000 --- a/tests/d3d11/test_d3d11_compute.cpp +++ /dev/null @@ -1,172 +0,0 @@ -#include - -#include -#include - -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -const std::string g_computeShaderCode = - "StructuredBuffer buf_in : register(t0);\n" - "RWStructuredBuffer buf_out : register(u0);\n" - "groupshared uint tmp[64];\n" - "[numthreads(64,1,1)]\n" - "void main(uint localId : SV_GroupIndex, uint3 globalId : SV_DispatchThreadID) {\n" - " tmp[localId] = buf_in[2 * globalId.x + 0]\n" - " + buf_in[2 * globalId.x + 1];\n" - " GroupMemoryBarrierWithGroupSync();\n" - " uint activeGroups = 32;\n" - " while (activeGroups != 0) {\n" - " if (localId < activeGroups)\n" - " tmp[localId] += tmp[localId + activeGroups];\n" - " GroupMemoryBarrierWithGroupSync();\n" - " activeGroups >>= 1;\n" - " }\n" - " if (localId == 0)\n" - " buf_out[0] = tmp[0];\n" - "}\n"; - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - Com device; - Com context; - Com computeShader; - - Com srcBuffer; - Com dstBuffer; - Com readBuffer; - - Com srcView; - Com dstView; - - if (FAILED(D3D11CreateDevice( - nullptr, D3D_DRIVER_TYPE_HARDWARE, - nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, - &device, nullptr, &context))) { - std::cerr << "Failed to create D3D11 device" << std::endl; - return 1; - } - - Com computeShaderBlob; - - if (FAILED(D3DCompile( - g_computeShaderCode.data(), - g_computeShaderCode.size(), - "Compute shader", - nullptr, nullptr, - "main", "cs_5_0", 0, 0, - &computeShaderBlob, - nullptr))) { - std::cerr << "Failed to compile compute shader" << std::endl; - return 1; - } - - if (FAILED(device->CreateComputeShader( - computeShaderBlob->GetBufferPointer(), - computeShaderBlob->GetBufferSize(), - nullptr, &computeShader))) { - std::cerr << "Failed to create compute shader" << std::endl; - return 1; - } - - std::array srcData; - for (uint32_t i = 0; i < srcData.size(); i++) - srcData[i] = i + 1; - - D3D11_BUFFER_DESC srcBufferDesc; - srcBufferDesc.ByteWidth = sizeof(uint32_t) * srcData.size(); - srcBufferDesc.Usage = D3D11_USAGE_IMMUTABLE; - srcBufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - srcBufferDesc.CPUAccessFlags = 0; - srcBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; - srcBufferDesc.StructureByteStride = sizeof(uint32_t); - - D3D11_SUBRESOURCE_DATA srcDataInfo; - srcDataInfo.pSysMem = srcData.data(); - srcDataInfo.SysMemPitch = 0; - srcDataInfo.SysMemSlicePitch = 0; - - if (FAILED(device->CreateBuffer(&srcBufferDesc, &srcDataInfo, &srcBuffer))) { - std::cerr << "Failed to create source buffer" << std::endl; - return 1; - } - - D3D11_BUFFER_DESC dstBufferDesc; - dstBufferDesc.ByteWidth = sizeof(uint32_t); - dstBufferDesc.Usage = D3D11_USAGE_DEFAULT; - dstBufferDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; - dstBufferDesc.CPUAccessFlags = 0; - dstBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; - dstBufferDesc.StructureByteStride = sizeof(uint32_t); - - if (FAILED(device->CreateBuffer(&dstBufferDesc, &srcDataInfo, &dstBuffer))) { - std::cerr << "Failed to create destination buffer" << std::endl; - return 1; - } - - D3D11_BUFFER_DESC readBufferDesc; - readBufferDesc.ByteWidth = sizeof(uint32_t); - readBufferDesc.Usage = D3D11_USAGE_STAGING; - readBufferDesc.BindFlags = 0; - readBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - readBufferDesc.MiscFlags = 0; - readBufferDesc.StructureByteStride = 0; - - if (FAILED(device->CreateBuffer(&readBufferDesc, nullptr, &readBuffer))) { - std::cerr << "Failed to create readback buffer" << std::endl; - return 1; - } - - D3D11_SHADER_RESOURCE_VIEW_DESC srcViewDesc; - srcViewDesc.Format = DXGI_FORMAT_UNKNOWN; - srcViewDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX; - srcViewDesc.BufferEx.FirstElement = 0; - srcViewDesc.BufferEx.NumElements = srcData.size(); - srcViewDesc.BufferEx.Flags = 0; - - if (FAILED(device->CreateShaderResourceView(srcBuffer.ptr(), &srcViewDesc, &srcView))) { - std::cerr << "Failed to create shader resource view" << std::endl; - return 1; - } - - D3D11_UNORDERED_ACCESS_VIEW_DESC dstViewDesc; - dstViewDesc.Format = DXGI_FORMAT_UNKNOWN; - dstViewDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; - dstViewDesc.Buffer.FirstElement = 0; - dstViewDesc.Buffer.NumElements = 1; - dstViewDesc.Buffer.Flags = 0; - - if (FAILED(device->CreateUnorderedAccessView(dstBuffer.ptr(), &dstViewDesc, &dstView))) { - std::cerr << "Failed to create unordered access view" << std::endl; - return 1; - } - - // Compute sum of the source buffer values - context->CSSetShader(computeShader.ptr(), nullptr, 0); - context->CSSetShaderResources(0, 1, &srcView); - context->CSSetUnorderedAccessViews(0, 1, &dstView, nullptr); - context->Dispatch(1, 1, 1); - - // Write data to the readback buffer and query the result - context->CopyResource(readBuffer.ptr(), dstBuffer.ptr()); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - if (FAILED(context->Map(readBuffer.ptr(), 0, D3D11_MAP_READ, 0, &mappedResource))) { - std::cerr << "Failed to map readback buffer" << std::endl; - return 1; - } - - uint32_t result = 0; - std::memcpy(&result, mappedResource.pData, sizeof(result)); - context->Unmap(readBuffer.ptr(), 0); - - std::cout << "Sum of the numbers 1 to " << srcData.size() << " = " << result << std::endl; - context->ClearState(); - return 0; -} diff --git a/tests/d3d11/test_d3d11_formats.cpp b/tests/d3d11/test_d3d11_formats.cpp deleted file mode 100644 index 3ec7f26a5..000000000 --- a/tests/d3d11/test_d3d11_formats.cpp +++ /dev/null @@ -1,304 +0,0 @@ -#include - -#include -#include - -#include -#include - -#include "../test_utils.h" - -#undef ENUM_NAME -#define ENUM_NAME(e) case e: return #e; - -using namespace dxvk; - -std::string GetFormatName(DXGI_FORMAT Format) { - switch (Format) { - ENUM_NAME(DXGI_FORMAT_UNKNOWN); - ENUM_NAME(DXGI_FORMAT_R32G32B32A32_TYPELESS); - ENUM_NAME(DXGI_FORMAT_R32G32B32A32_FLOAT); - ENUM_NAME(DXGI_FORMAT_R32G32B32A32_UINT); - ENUM_NAME(DXGI_FORMAT_R32G32B32A32_SINT); - ENUM_NAME(DXGI_FORMAT_R32G32B32_TYPELESS); - ENUM_NAME(DXGI_FORMAT_R32G32B32_FLOAT); - ENUM_NAME(DXGI_FORMAT_R32G32B32_UINT); - ENUM_NAME(DXGI_FORMAT_R32G32B32_SINT); - ENUM_NAME(DXGI_FORMAT_R16G16B16A16_TYPELESS); - ENUM_NAME(DXGI_FORMAT_R16G16B16A16_FLOAT); - ENUM_NAME(DXGI_FORMAT_R16G16B16A16_UNORM); - ENUM_NAME(DXGI_FORMAT_R16G16B16A16_UINT); - ENUM_NAME(DXGI_FORMAT_R16G16B16A16_SNORM); - ENUM_NAME(DXGI_FORMAT_R16G16B16A16_SINT); - ENUM_NAME(DXGI_FORMAT_R32G32_TYPELESS); - ENUM_NAME(DXGI_FORMAT_R32G32_FLOAT); - ENUM_NAME(DXGI_FORMAT_R32G32_UINT); - ENUM_NAME(DXGI_FORMAT_R32G32_SINT); - ENUM_NAME(DXGI_FORMAT_R32G8X24_TYPELESS); - ENUM_NAME(DXGI_FORMAT_D32_FLOAT_S8X24_UINT); - ENUM_NAME(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS); - ENUM_NAME(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT); - ENUM_NAME(DXGI_FORMAT_R10G10B10A2_TYPELESS); - ENUM_NAME(DXGI_FORMAT_R10G10B10A2_UNORM); - ENUM_NAME(DXGI_FORMAT_R10G10B10A2_UINT); - ENUM_NAME(DXGI_FORMAT_R11G11B10_FLOAT); - ENUM_NAME(DXGI_FORMAT_R8G8B8A8_TYPELESS); - ENUM_NAME(DXGI_FORMAT_R8G8B8A8_UNORM); - ENUM_NAME(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); - ENUM_NAME(DXGI_FORMAT_R8G8B8A8_UINT); - ENUM_NAME(DXGI_FORMAT_R8G8B8A8_SNORM); - ENUM_NAME(DXGI_FORMAT_R8G8B8A8_SINT); - ENUM_NAME(DXGI_FORMAT_R16G16_TYPELESS); - ENUM_NAME(DXGI_FORMAT_R16G16_FLOAT); - ENUM_NAME(DXGI_FORMAT_R16G16_UNORM); - ENUM_NAME(DXGI_FORMAT_R16G16_UINT); - ENUM_NAME(DXGI_FORMAT_R16G16_SNORM); - ENUM_NAME(DXGI_FORMAT_R16G16_SINT); - ENUM_NAME(DXGI_FORMAT_R32_TYPELESS); - ENUM_NAME(DXGI_FORMAT_D32_FLOAT); - ENUM_NAME(DXGI_FORMAT_R32_FLOAT); - ENUM_NAME(DXGI_FORMAT_R32_UINT); - ENUM_NAME(DXGI_FORMAT_R32_SINT); - ENUM_NAME(DXGI_FORMAT_R24G8_TYPELESS); - ENUM_NAME(DXGI_FORMAT_D24_UNORM_S8_UINT); - ENUM_NAME(DXGI_FORMAT_R24_UNORM_X8_TYPELESS); - ENUM_NAME(DXGI_FORMAT_X24_TYPELESS_G8_UINT); - ENUM_NAME(DXGI_FORMAT_R8G8_TYPELESS); - ENUM_NAME(DXGI_FORMAT_R8G8_UNORM); - ENUM_NAME(DXGI_FORMAT_R8G8_UINT); - ENUM_NAME(DXGI_FORMAT_R8G8_SNORM); - ENUM_NAME(DXGI_FORMAT_R8G8_SINT); - ENUM_NAME(DXGI_FORMAT_R16_TYPELESS); - ENUM_NAME(DXGI_FORMAT_R16_FLOAT); - ENUM_NAME(DXGI_FORMAT_D16_UNORM); - ENUM_NAME(DXGI_FORMAT_R16_UNORM); - ENUM_NAME(DXGI_FORMAT_R16_UINT); - ENUM_NAME(DXGI_FORMAT_R16_SNORM); - ENUM_NAME(DXGI_FORMAT_R16_SINT); - ENUM_NAME(DXGI_FORMAT_R8_TYPELESS); - ENUM_NAME(DXGI_FORMAT_R8_UNORM); - ENUM_NAME(DXGI_FORMAT_R8_UINT); - ENUM_NAME(DXGI_FORMAT_R8_SNORM); - ENUM_NAME(DXGI_FORMAT_R8_SINT); - ENUM_NAME(DXGI_FORMAT_A8_UNORM); - ENUM_NAME(DXGI_FORMAT_R1_UNORM); - ENUM_NAME(DXGI_FORMAT_R9G9B9E5_SHAREDEXP); - ENUM_NAME(DXGI_FORMAT_R8G8_B8G8_UNORM); - ENUM_NAME(DXGI_FORMAT_G8R8_G8B8_UNORM); - ENUM_NAME(DXGI_FORMAT_BC1_TYPELESS); - ENUM_NAME(DXGI_FORMAT_BC1_UNORM); - ENUM_NAME(DXGI_FORMAT_BC1_UNORM_SRGB); - ENUM_NAME(DXGI_FORMAT_BC2_TYPELESS); - ENUM_NAME(DXGI_FORMAT_BC2_UNORM); - ENUM_NAME(DXGI_FORMAT_BC2_UNORM_SRGB); - ENUM_NAME(DXGI_FORMAT_BC3_TYPELESS); - ENUM_NAME(DXGI_FORMAT_BC3_UNORM); - ENUM_NAME(DXGI_FORMAT_BC3_UNORM_SRGB); - ENUM_NAME(DXGI_FORMAT_BC4_TYPELESS); - ENUM_NAME(DXGI_FORMAT_BC4_UNORM); - ENUM_NAME(DXGI_FORMAT_BC4_SNORM); - ENUM_NAME(DXGI_FORMAT_BC5_TYPELESS); - ENUM_NAME(DXGI_FORMAT_BC5_UNORM); - ENUM_NAME(DXGI_FORMAT_BC5_SNORM); - ENUM_NAME(DXGI_FORMAT_B5G6R5_UNORM); - ENUM_NAME(DXGI_FORMAT_B5G5R5A1_UNORM); - ENUM_NAME(DXGI_FORMAT_B8G8R8A8_UNORM); - ENUM_NAME(DXGI_FORMAT_B8G8R8X8_UNORM); - ENUM_NAME(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM); - ENUM_NAME(DXGI_FORMAT_B8G8R8A8_TYPELESS); - ENUM_NAME(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB); - ENUM_NAME(DXGI_FORMAT_B8G8R8X8_TYPELESS); - ENUM_NAME(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB); - ENUM_NAME(DXGI_FORMAT_BC6H_TYPELESS); - ENUM_NAME(DXGI_FORMAT_BC6H_UF16); - ENUM_NAME(DXGI_FORMAT_BC6H_SF16); - ENUM_NAME(DXGI_FORMAT_BC7_TYPELESS); - ENUM_NAME(DXGI_FORMAT_BC7_UNORM); - ENUM_NAME(DXGI_FORMAT_BC7_UNORM_SRGB); - default: return std::to_string(Format); - } -} - - -std::string GetFormatFlagName(D3D11_FORMAT_SUPPORT Flag) { - switch (Flag) { - ENUM_NAME(D3D11_FORMAT_SUPPORT_BUFFER); - ENUM_NAME(D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER); - ENUM_NAME(D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER); - ENUM_NAME(D3D11_FORMAT_SUPPORT_SO_BUFFER); - ENUM_NAME(D3D11_FORMAT_SUPPORT_TEXTURE1D); - ENUM_NAME(D3D11_FORMAT_SUPPORT_TEXTURE2D); - ENUM_NAME(D3D11_FORMAT_SUPPORT_TEXTURE3D); - ENUM_NAME(D3D11_FORMAT_SUPPORT_TEXTURECUBE); - ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_LOAD); - ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_SAMPLE); - ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON); - ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_MONO_TEXT); - ENUM_NAME(D3D11_FORMAT_SUPPORT_MIP); - ENUM_NAME(D3D11_FORMAT_SUPPORT_MIP_AUTOGEN); - ENUM_NAME(D3D11_FORMAT_SUPPORT_RENDER_TARGET); - ENUM_NAME(D3D11_FORMAT_SUPPORT_BLENDABLE); - ENUM_NAME(D3D11_FORMAT_SUPPORT_DEPTH_STENCIL); - ENUM_NAME(D3D11_FORMAT_SUPPORT_CPU_LOCKABLE); - ENUM_NAME(D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE); - ENUM_NAME(D3D11_FORMAT_SUPPORT_DISPLAY); - ENUM_NAME(D3D11_FORMAT_SUPPORT_CAST_WITHIN_BIT_LAYOUT); - ENUM_NAME(D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET); - ENUM_NAME(D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD); - ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_GATHER); - ENUM_NAME(D3D11_FORMAT_SUPPORT_BACK_BUFFER_CAST); - ENUM_NAME(D3D11_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW); - ENUM_NAME(D3D11_FORMAT_SUPPORT_SHADER_GATHER_COMPARISON); - ENUM_NAME(D3D11_FORMAT_SUPPORT_DECODER_OUTPUT); - ENUM_NAME(D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_OUTPUT); - ENUM_NAME(D3D11_FORMAT_SUPPORT_VIDEO_PROCESSOR_INPUT); - ENUM_NAME(D3D11_FORMAT_SUPPORT_VIDEO_ENCODER); - default: return std::to_string(Flag); - } -} - - -std::string GetFormatFlagName2(UINT Flag) { - switch (Flag) { - ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_ADD); - ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS); - ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE); - ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE); - ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX); - ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX); - ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD); - ENUM_NAME(D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE); - ENUM_NAME(D3D11_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP); - ENUM_NAME(D3D11_FORMAT_SUPPORT2_TILED); - ENUM_NAME(D3D11_FORMAT_SUPPORT2_SHAREABLE); - ENUM_NAME(D3D11_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY); - default: return std::to_string(Flag); - } -} - - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - Com device; - - if (FAILED(D3D11CreateDevice( - nullptr, D3D_DRIVER_TYPE_HARDWARE, - nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, - &device, nullptr, nullptr))) { - std::cerr << "Failed to create D3D11 device" << std::endl; - return 1; - } - - D3D11_FEATURE_DATA_THREADING featureThreading = { }; - D3D11_FEATURE_DATA_DOUBLES featureDoubles = { }; - D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT featureMinPrecision = { }; - D3D11_FEATURE_DATA_D3D11_OPTIONS featureD3D11Options = { }; - D3D11_FEATURE_DATA_D3D11_OPTIONS1 featureD3D11Options1 = { }; - D3D11_FEATURE_DATA_D3D11_OPTIONS2 featureD3D11Options2 = { }; - D3D11_FEATURE_DATA_D3D11_OPTIONS3 featureD3D11Options3 = { }; - D3D11_FEATURE_DATA_D3D11_OPTIONS4 featureD3D11Options4 = { }; - - if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_THREADING, &featureThreading, sizeof(featureThreading)))) { - std::cout << "D3D11_FEATURE_THREADING:" << std::endl - << " DriverConcurrentCreates: " << featureThreading.DriverConcurrentCreates << std::endl - << " DriverCommandLists: " << featureThreading.DriverCommandLists << std::endl; - } - - if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_DOUBLES, &featureDoubles, sizeof(featureDoubles)))) { - std::cout << "D3D11_FEATURE_DOUBLES:" << std::endl - << " DoublePrecisionFloatShaderOps: " << featureDoubles.DoublePrecisionFloatShaderOps << std::endl; - } - - if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT, &featureMinPrecision, sizeof(featureMinPrecision)))) { - std::cout << "D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT:" << std::endl - << " PixelShaderMinPrecision: " << featureMinPrecision.PixelShaderMinPrecision << std::endl - << " AllOtherShaderStagesMinPrecision: " << featureMinPrecision.AllOtherShaderStagesMinPrecision << std::endl; - } - - if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &featureD3D11Options, sizeof(featureD3D11Options)))) { - std::cout << "D3D11_FEATURE_D3D11_OPTIONS:" << std::endl - << " OutputMergerLogicOp: " << featureD3D11Options.OutputMergerLogicOp << std::endl - << " UAVOnlyRenderingForcedSampleCount: " << featureD3D11Options.UAVOnlyRenderingForcedSampleCount << std::endl - << " DiscardAPIsSeenByDriver: " << featureD3D11Options.DiscardAPIsSeenByDriver << std::endl - << " FlagsForUpdateAndCopySeenByDriver: " << featureD3D11Options.FlagsForUpdateAndCopySeenByDriver << std::endl - << " ClearView: " << featureD3D11Options.ClearView << std::endl - << " CopyWithOverlap: " << featureD3D11Options.CopyWithOverlap << std::endl - << " ConstantBufferPartialUpdate: " << featureD3D11Options.ConstantBufferPartialUpdate << std::endl - << " ConstantBufferOffsetting: " << featureD3D11Options.ConstantBufferOffsetting << std::endl - << " MapNoOverwriteOnDynamicConstantBuffer: " << featureD3D11Options.MapNoOverwriteOnDynamicConstantBuffer << std::endl - << " MapNoOverwriteOnDynamicBufferSRV: " << featureD3D11Options.MapNoOverwriteOnDynamicBufferSRV << std::endl - << " MultisampleRTVWithForcedSampleCountOne: " << featureD3D11Options.MultisampleRTVWithForcedSampleCountOne << std::endl - << " SAD4ShaderInstructions: " << featureD3D11Options.SAD4ShaderInstructions << std::endl - << " ExtendedDoublesShaderInstructions: " << featureD3D11Options.ExtendedDoublesShaderInstructions << std::endl - << " ExtendedResourceSharing: " << featureD3D11Options.ExtendedResourceSharing << std::endl; - } - - if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS1, &featureD3D11Options1, sizeof(featureD3D11Options1)))) { - std::cout << "D3D11_FEATURE_D3D11_OPTIONS1:" << std::endl - << " TiledResourcesTier: " << featureD3D11Options1.TiledResourcesTier << std::endl - << " MinMaxFiltering: " << featureD3D11Options1.MinMaxFiltering << std::endl - << " ClearViewAlsoSupportsDepthOnlyFormats: " << featureD3D11Options1.ClearViewAlsoSupportsDepthOnlyFormats << std::endl - << " MapOnDefaultBuffers: " << featureD3D11Options1.MapOnDefaultBuffers << std::endl; - - } - - if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &featureD3D11Options2, sizeof(featureD3D11Options2)))) { - std::cout << "D3D11_FEATURE_D3D11_OPTIONS2:" << std::endl - << " PSSpecifiedStencilRefSupported: " << featureD3D11Options2.PSSpecifiedStencilRefSupported << std::endl - << " TypedUAVLoadAdditionalFormats: " << featureD3D11Options2.TypedUAVLoadAdditionalFormats << std::endl - << " ROVsSupported: " << featureD3D11Options2.ROVsSupported << std::endl - << " ConservativeRasterizationTier: " << featureD3D11Options2.ConservativeRasterizationTier << std::endl - << " MapOnDefaultTextures: " << featureD3D11Options2.MapOnDefaultTextures << std::endl - << " TiledResourcesTier: " << featureD3D11Options2.TiledResourcesTier << std::endl - << " StandardSwizzle: " << featureD3D11Options2.StandardSwizzle << std::endl - << " UnifiedMemoryArchitecture: " << featureD3D11Options2.UnifiedMemoryArchitecture << std::endl; - } - - if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &featureD3D11Options3, sizeof(featureD3D11Options3)))) { - std::cout << "D3D11_FEATURE_D3D11_OPTIONS3:" << std::endl - << " VPAndRTArrayIndexFromAnyShaderFeedingRasterizer: " << featureD3D11Options3.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer << std::endl; - } - - if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS4, &featureD3D11Options4, sizeof(featureD3D11Options4)))) { - std::cout << "D3D11_FEATURE_D3D11_OPTIONS4:" << std::endl - << " ExtendedNV12SharedTextureSupported: " << featureD3D11Options4.ExtendedNV12SharedTextureSupported << std::endl; - } - - for (UINT i = UINT(DXGI_FORMAT_UNKNOWN); - i <= UINT(DXGI_FORMAT_BC7_UNORM_SRGB); - i++) { - DXGI_FORMAT format = DXGI_FORMAT(i); - UINT flags = 0; - - std::cout << GetFormatName(format) << ": " << std::endl; - - if (SUCCEEDED(device->CheckFormatSupport(format, &flags))) { - for (uint32_t i = 0; i < 32; i++) { - if (flags & (1 << i)) { - std::cout << " " - << GetFormatFlagName(D3D11_FORMAT_SUPPORT(1 << i)) - << std::endl; - } - } - - D3D11_FEATURE_DATA_FORMAT_SUPPORT2 support2 = { }; - support2.InFormat = format; - - if (SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT2, &support2, sizeof(support2)))) { - for (uint32_t i = 0; i < 32; i++) { - if (support2.OutFormatSupport2 & (1u << i)) { - std::cout << " " - << GetFormatFlagName2(1u << i) - << std::endl; - } - } - } - } else { - std::cout << " Not supported" << std::endl; - } - } - - return 0; -} diff --git a/tests/d3d11/test_d3d11_map_read.cpp b/tests/d3d11/test_d3d11_map_read.cpp deleted file mode 100644 index 8e73dc45b..000000000 --- a/tests/d3d11/test_d3d11_map_read.cpp +++ /dev/null @@ -1,203 +0,0 @@ -#include -#include - -#include -#include - -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -const std::string g_vsCode = - "float4 main(float4 v_pos : VS_POSITION) : SV_POSITION {\n" - " return v_pos;\n" - "}\n"; - -Com g_d3d11Device; -Com g_d3d11Context; - -Com g_vertShader; -Com g_inputLayout; - -Com g_vertexBuffer; - -Com g_depthRender; -Com g_depthRead; -Com g_depthView; -Comg_depthState; - -struct Vertex { - float x, y, z, w; -}; - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - if (FAILED(D3D11CreateDevice( - nullptr, D3D_DRIVER_TYPE_HARDWARE, - nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, - &g_d3d11Device, nullptr, &g_d3d11Context))) { - std::cerr << "Failed to create D3D11 device" << std::endl; - return 1; - } - - Com vsBlob; - Com gsBlob; - - if (FAILED(D3DCompile(g_vsCode.data(), g_vsCode.size(), - "Vertex shader", nullptr, nullptr, "main", "vs_4_0", - 0, 0, &vsBlob, nullptr))) { - std::cerr << "Failed to compile vertex shader" << std::endl; - return 1; - } - - if (FAILED(g_d3d11Device->CreateVertexShader( - vsBlob->GetBufferPointer(), - vsBlob->GetBufferSize(), - nullptr, &g_vertShader))) { - std::cerr << "Failed to create vertex shader" << std::endl; - return 1; - } - - std::array iaElements = {{ - { "VS_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }}; - - if (FAILED(g_d3d11Device->CreateInputLayout( - iaElements.data(), - iaElements.size(), - vsBlob->GetBufferPointer(), - vsBlob->GetBufferSize(), - &g_inputLayout))) { - std::cerr << "Failed to create input layout" << std::endl; - return 1; - } - - std::array vertexData = {{ - { -1.0f, -1.0f, 0.00f, 1.0f }, - { -1.0f, 1.0f, 0.66f, 1.0f }, - { 1.0f, -1.0f, 0.33f, 1.0f }, - { 1.0f, 1.0f, 1.00f, 1.0f }, - }}; - - D3D11_BUFFER_DESC vertexDesc; - vertexDesc.ByteWidth = vertexData.size() * sizeof(Vertex); - vertexDesc.Usage = D3D11_USAGE_IMMUTABLE; - vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vertexDesc.CPUAccessFlags = 0; - vertexDesc.MiscFlags = 0; - vertexDesc.StructureByteStride = 0; - - D3D11_SUBRESOURCE_DATA vertexInfo; - vertexInfo.pSysMem = vertexData.data(); - vertexInfo.SysMemPitch = vertexDesc.ByteWidth; - vertexInfo.SysMemSlicePitch = vertexDesc.ByteWidth; - - if (FAILED(g_d3d11Device->CreateBuffer(&vertexDesc, &vertexInfo, &g_vertexBuffer))) { - std::cerr << "Failed to create vertex buffer" << std::endl; - return 1; - } - - D3D11_TEXTURE2D_DESC depthDesc; - depthDesc.Width = 16; - depthDesc.Height = 16; - depthDesc.MipLevels = 1; - depthDesc.ArraySize = 1; - depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - // depthDesc.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT; - depthDesc.SampleDesc = { 1, 0 }; - depthDesc.Usage = D3D11_USAGE_DEFAULT; - depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - depthDesc.CPUAccessFlags = 0; - depthDesc.MiscFlags = 0; - - if (FAILED(g_d3d11Device->CreateTexture2D(&depthDesc, nullptr, &g_depthRender))) { - std::cerr << "Failed to create render buffer" << std::endl; - return 1; - } - - depthDesc.Usage = D3D11_USAGE_STAGING; - depthDesc.BindFlags = 0; - depthDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - - if (FAILED(g_d3d11Device->CreateTexture2D(&depthDesc, nullptr, &g_depthRead))) { - std::cerr << "Failed to create readback buffer" << std::endl; - return 1; - } - - if (FAILED(g_d3d11Device->CreateDepthStencilView(g_depthRender.ptr(), nullptr, &g_depthView))) { - std::cerr << "Failed to create depth-stencil view" << std::endl; - return 1; - } - - D3D11_DEPTH_STENCIL_DESC dsDesc; - dsDesc.DepthEnable = TRUE; - dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.StencilEnable = FALSE; - dsDesc.StencilReadMask = 0; - dsDesc.StencilWriteMask = 0; - dsDesc.FrontFace = { }; - dsDesc.BackFace = { }; - - if (FAILED(g_d3d11Device->CreateDepthStencilState(&dsDesc, &g_depthState))) { - std::cerr << "Failed to create depth-stencil state" << std::endl; - return 1; - } - - FLOAT omBlendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - - D3D11_VIEWPORT omViewport; - omViewport.TopLeftX = 0.0f; - omViewport.TopLeftY = 0.0f; - omViewport.Width = 16.0f; - omViewport.Height = 16.0f; - omViewport.MinDepth = 0.0f; - omViewport.MaxDepth = 1.0f; - - UINT vbOffset = 0; - UINT vbStride = sizeof(Vertex); - - g_d3d11Context->RSSetState(nullptr); - g_d3d11Context->RSSetViewports(1, &omViewport); - - g_d3d11Context->OMSetRenderTargets(0, nullptr, g_depthView.ptr()); - g_d3d11Context->OMSetBlendState(nullptr, omBlendFactor, 0xFFFFFFFF); - g_d3d11Context->OMSetDepthStencilState(g_depthState.ptr(), 0); - - g_d3d11Context->ClearDepthStencilView(g_depthView.ptr(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.5f, 0x80); - - g_d3d11Context->IASetInputLayout(g_inputLayout.ptr()); - g_d3d11Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - g_d3d11Context->IASetVertexBuffers(0, 1, &g_vertexBuffer, &vbStride, &vbOffset); - - g_d3d11Context->VSSetShader(g_vertShader.ptr(), nullptr, 0); - g_d3d11Context->Draw(4, 0); - - g_d3d11Context->CopyResource(g_depthRead.ptr(), g_depthRender.ptr()); - - D3D11_MAPPED_SUBRESOURCE mapped; - - if (FAILED(g_d3d11Context->Map(g_depthRead.ptr(), 0, D3D11_MAP_READ, 0, &mapped))) { - std::cerr << "Failed to map image" << std::endl; - return 1; - } - - for (uint32_t y = 0; y < 16; y++) { - auto data = reinterpret_cast(mapped.pData) - + (y * mapped.RowPitch / 4); - - for (uint32_t x = 0; x < 16; x++) - std::cout << std::hex << std::setfill('0') << std::setw(8) << data[x] << " "; - - std::cout << std::endl; - } - - g_d3d11Context->Unmap(g_depthRead.ptr(), 0); - g_d3d11Context->ClearState(); - return 0; -} diff --git a/tests/d3d11/test_d3d11_streamout.cpp b/tests/d3d11/test_d3d11_streamout.cpp deleted file mode 100644 index 3ff5f9ec3..000000000 --- a/tests/d3d11/test_d3d11_streamout.cpp +++ /dev/null @@ -1,288 +0,0 @@ -#include -#include - -#include -#include - -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -const std::string g_vsCode = - "struct VS_IFACE {\n" - " float4 pos : VS_POSITION;\n" - "};\n" - "VS_IFACE main(VS_IFACE ia_in) {\n" - " return ia_in;\n" - "}\n"; - -const std::string g_gsCode = - "struct GS_IN {\n" - " float4 pos : VS_POSITION;\n" - "};\n" - "struct GS_OUT_NORMAL {\n" - " float3 nor : GS_NORMAL;\n" - " float len : GS_LENGTH;\n" - "};\n" - "[maxvertexcount(1)]\n" - "void main(triangle GS_IN vs_in[3], inout PointStream o_normals) {\n" - " float3 ds1 = vs_in[1].pos.xyz - vs_in[0].pos.xyz;\n" - " float3 ds2 = vs_in[2].pos.xyz - vs_in[0].pos.xyz;\n" - " float3 cv = cross(ds1, ds2);\n" - " float cl = length(cv);\n" - " GS_OUT_NORMAL normal;\n" - " normal.nor = cv / cl;\n" - " normal.len = cl;" - " o_normals.Append(normal);\n" - "}\n"; - -Com g_d3d11Device; -Com g_d3d11Context; - -Com g_vertShader; -Com g_geomShader; - -Com g_inputLayout; - -Com g_vertexBuffer; -Com g_normalBuffer; -Com g_readBuffer; - -Com g_soStream; -Com g_soOverflow; - -struct Vertex { - float x, y, z, w; -}; - -struct Normal { - float x, y, z, len; -}; - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - if (FAILED(D3D11CreateDevice( - nullptr, D3D_DRIVER_TYPE_HARDWARE, - nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, - &g_d3d11Device, nullptr, &g_d3d11Context))) { - std::cerr << "Failed to create D3D11 device" << std::endl; - return 1; - } - - Com vsBlob; - Com gsBlob; - - if (FAILED(D3DCompile(g_vsCode.data(), g_vsCode.size(), - "Vertex shader", nullptr, nullptr, "main", "vs_4_0", - 0, 0, &vsBlob, nullptr))) { - std::cerr << "Failed to compile vertex shader" << std::endl; - return 1; - } - - if (FAILED(D3DCompile(g_gsCode.data(), g_gsCode.size(), - "Geometry shader", nullptr, nullptr, "main", "gs_4_0", - 0, 0, &gsBlob, nullptr))) { - std::cerr << "Failed to compile geometry shader" << std::endl; - return 1; - } - - if (FAILED(g_d3d11Device->CreateVertexShader( - vsBlob->GetBufferPointer(), - vsBlob->GetBufferSize(), - nullptr, &g_vertShader))) { - std::cerr << "Failed to create vertex shader" << std::endl; - return 1; - } - - std::array soDeclarations = {{ - { 0, "GS_NORMAL", 0, 0, 3, 0 }, - { 0, "GS_LENGTH", 0, 0, 1, 0 }, - }}; - - std::array soBufferStrides = {{ - sizeof(Normal), - }}; - - if (FAILED(g_d3d11Device->CreateGeometryShaderWithStreamOutput( - gsBlob->GetBufferPointer(), - gsBlob->GetBufferSize(), - soDeclarations.data(), - soDeclarations.size(), - soBufferStrides.data(), - soBufferStrides.size(), - D3D11_SO_NO_RASTERIZED_STREAM, - nullptr, &g_geomShader))) { - std::cerr << "Failed to create geometry shader" << std::endl; - return 1; - } - - std::array iaElements = {{ - { "VS_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }}; - - if (FAILED(g_d3d11Device->CreateInputLayout( - iaElements.data(), - iaElements.size(), - vsBlob->GetBufferPointer(), - vsBlob->GetBufferSize(), - &g_inputLayout))) { - std::cerr << "Failed to create input layout" << std::endl; - return 1; - } - - std::array vertexData = {{ - { 0.0f, 0.0f, 0.0f, 1.0f }, - { 1.0f, 0.0f, 0.0f, 1.0f }, - { 0.0f, 1.0f, 0.0f, 1.0f }, - - { 0.5f,-1.0f,-0.2f, 1.0f }, - { 3.2f, 2.0f, 0.0f, 1.0f }, - {-1.0f,-1.0f, 0.4f, 1.0f }, - - { 0.7f,-0.5f,-0.8f, 1.0f }, - { 1.2f, 1.0f,-1.0f, 1.0f }, - {-0.1f, 1.0f,-2.7f, 1.0f }, - }}; - - D3D11_BUFFER_DESC vertexDesc; - vertexDesc.ByteWidth = vertexData.size() * sizeof(Vertex); - vertexDesc.Usage = D3D11_USAGE_IMMUTABLE; - vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vertexDesc.CPUAccessFlags = 0; - vertexDesc.MiscFlags = 0; - vertexDesc.StructureByteStride = 0; - - D3D11_SUBRESOURCE_DATA vertexInfo; - vertexInfo.pSysMem = vertexData.data(); - vertexInfo.SysMemPitch = vertexDesc.ByteWidth; - vertexInfo.SysMemSlicePitch = vertexDesc.ByteWidth; - - if (FAILED(g_d3d11Device->CreateBuffer(&vertexDesc, &vertexInfo, &g_vertexBuffer))) { - std::cerr << "Failed to create vertex buffer" << std::endl; - return 1; - } - - std::array normalData = { }; - - D3D11_BUFFER_DESC normalDesc; - normalDesc.ByteWidth = normalData.size() * sizeof(Normal); - normalDesc.Usage = D3D11_USAGE_DEFAULT; - normalDesc.BindFlags = D3D11_BIND_STREAM_OUTPUT; - normalDesc.CPUAccessFlags = 0; - normalDesc.MiscFlags = 0; - normalDesc.StructureByteStride = 0; - - D3D11_SUBRESOURCE_DATA normalInfo; - normalInfo.pSysMem = normalData.data(); - normalInfo.SysMemPitch = normalDesc.ByteWidth; - normalInfo.SysMemSlicePitch = normalDesc.ByteWidth; - - if (FAILED(g_d3d11Device->CreateBuffer(&normalDesc, &normalInfo, &g_normalBuffer))) { - std::cerr << "Failed to create normal buffer" << std::endl; - return 1; - } - - D3D11_BUFFER_DESC readDesc; - readDesc.ByteWidth = normalDesc.ByteWidth; - readDesc.Usage = D3D11_USAGE_STAGING; - readDesc.BindFlags = 0; - readDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - readDesc.MiscFlags = 0; - readDesc.StructureByteStride = 0; - - if (FAILED(g_d3d11Device->CreateBuffer(&readDesc, nullptr, &g_readBuffer))) { - std::cerr << "Failed to create readback buffer" << std::endl; - return 1; - } - - D3D11_QUERY_DESC soQueryDesc; - soQueryDesc.Query = D3D11_QUERY_SO_STATISTICS_STREAM0; - soQueryDesc.MiscFlags = 0; - - if (FAILED(g_d3d11Device->CreateQuery(&soQueryDesc, &g_soStream))) { - std::cerr << "Failed to create streamout query" << std::endl; - return 1; - } - - soQueryDesc.Query = D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0; - if (FAILED(g_d3d11Device->CreateQuery(&soQueryDesc, &g_soOverflow))) { - std::cerr << "Failed to create streamout overflow query" << std::endl; - return 1; - } - - UINT soOffset = 0; - UINT vbOffset = 0; - UINT vbStride = sizeof(Vertex); - - FLOAT omBlendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - - D3D11_VIEWPORT omViewport; - omViewport.TopLeftX = 0.0f; - omViewport.TopLeftY = 0.0f; - omViewport.Width = 256.0f; - omViewport.Height = 256.0f; - omViewport.MinDepth = 0.0f; - omViewport.MaxDepth = 1.0f; - - g_d3d11Context->IASetInputLayout(g_inputLayout.ptr()); - g_d3d11Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - g_d3d11Context->IASetVertexBuffers(0, 1, &g_vertexBuffer, &vbStride, &vbOffset); - - g_d3d11Context->RSSetState(nullptr); - g_d3d11Context->RSSetViewports(1, &omViewport); - - g_d3d11Context->OMSetRenderTargets(0, nullptr, nullptr); - g_d3d11Context->OMSetBlendState(nullptr, omBlendFactor, 0xFFFFFFFF); - g_d3d11Context->OMSetDepthStencilState(nullptr, 0); - - g_d3d11Context->SOSetTargets(1, &g_normalBuffer, &soOffset); - - g_d3d11Context->VSSetShader(g_vertShader.ptr(), nullptr, 0); - g_d3d11Context->GSSetShader(g_geomShader.ptr(), nullptr, 0); - - g_d3d11Context->Begin(g_soStream.ptr()); - g_d3d11Context->Begin(g_soOverflow.ptr()); - - g_d3d11Context->Draw(vertexData.size(), 0); - - g_d3d11Context->End(g_soOverflow.ptr()); - g_d3d11Context->End(g_soStream.ptr()); - - g_d3d11Context->CopyResource( - g_readBuffer.ptr(), - g_normalBuffer.ptr()); - - D3D11_QUERY_DATA_SO_STATISTICS soQueryData = { }; - BOOL soOverflowData = false; - - while (g_d3d11Context->GetData(g_soStream.ptr(), &soQueryData, sizeof(soQueryData), 0) != S_OK - || g_d3d11Context->GetData(g_soOverflow.ptr(), &soOverflowData, sizeof(soOverflowData), 0) != S_OK) - continue; - - std::cout << "Written: " << soQueryData.NumPrimitivesWritten << std::endl; - std::cout << "Needed: " << soQueryData.PrimitivesStorageNeeded << std::endl; - std::cout << "Overflow: " << (soOverflowData ? "Yes" : "No") << std::endl; - - D3D11_MAPPED_SUBRESOURCE mapInfo; - - if (FAILED(g_d3d11Context->Map(g_readBuffer.ptr(), 0, D3D11_MAP_READ, 0, &mapInfo))) { - std::cerr << "Failed to map readback buffer" << std::endl; - return 1; - } - - std::memcpy(normalData.data(), mapInfo.pData, normalDesc.ByteWidth); - g_d3d11Context->Unmap(g_readBuffer.ptr(), 0); - - for (uint32_t i = 0; i < normalData.size(); i++) { - std::cout << i << ": " << normalData[i].x << "," - << normalData[i].y << "," << normalData[i].z << "," - << normalData[i].len << std::endl; - } - - return 0; -} diff --git a/tests/d3d11/test_d3d11_triangle.cpp b/tests/d3d11/test_d3d11_triangle.cpp deleted file mode 100644 index 5c2ea78f0..000000000 --- a/tests/d3d11/test_d3d11_triangle.cpp +++ /dev/null @@ -1,606 +0,0 @@ -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -struct Vertex { - float x, y; -}; - -struct VsConstants { - float x, y; - float w, h; -}; - -struct VsConstantsPad { - VsConstants data; - uint32_t pad[60]; -}; - -struct PsConstants { - float r, g, b, a; -}; - -struct DrawOptions { - bool mapDiscardOnce; - bool sortByTexture; - bool drawIndexed; -}; - -const std::string g_vertexShaderCode = - "cbuffer vs_cb : register(b0) {\n" - " float2 v_offset;\n" - " float2 v_scale;\n" - "};\n" - "float4 main(float4 v_pos : IN_POSITION) : SV_POSITION {\n" - " float2 coord = 2.0f * (v_pos * v_scale + v_offset) - 1.0f;\n" - " return float4(coord, 0.0f, 1.0f);\n" - "}\n"; - -const std::string g_pixelShaderCode = - "Texture2D tex0 : register(t0);" - "cbuffer ps_cb : register(b0) {\n" - " float4 color;\n" - "};\n" - "float4 main() : SV_TARGET {\n" - " return color * tex0.Load(int3(0, 0, 0));\n" - "}\n"; - -class TriangleApp { - -public: - - TriangleApp(HINSTANCE instance, HWND window) - : m_window(window) { - Com device; - - D3D_FEATURE_LEVEL fl = D3D_FEATURE_LEVEL_11_1; - - HRESULT status = D3D11CreateDevice( - nullptr, D3D_DRIVER_TYPE_HARDWARE, - nullptr, 0, &fl, 1, D3D11_SDK_VERSION, - &device, nullptr, nullptr); - - if (FAILED(status)) { - std::cerr << "Failed to create D3D11 device" << std::endl; - return; - } - - if (FAILED(device->QueryInterface(IID_PPV_ARGS(&m_device)))) { - std::cerr << "Failed to query ID3D11DeviceContext1" << std::endl; - return; - } - - Com dxgiDevice; - - if (FAILED(m_device->QueryInterface(IID_PPV_ARGS(&dxgiDevice)))) { - std::cerr << "Failed to query DXGI device" << std::endl; - return; - } - - if (FAILED(dxgiDevice->GetAdapter(&m_adapter))) { - std::cerr << "Failed to query DXGI adapter" << std::endl; - return; - } - - if (FAILED(m_adapter->GetParent(IID_PPV_ARGS(&m_factory)))) { - std::cerr << "Failed to query DXGI factory" << std::endl; - return; - } - - m_device->GetImmediateContext1(&m_context); - - DXGI_SWAP_CHAIN_DESC1 swapDesc; - swapDesc.Width = m_windowSizeW; - swapDesc.Height = m_windowSizeH; - swapDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - swapDesc.Stereo = FALSE; - swapDesc.SampleDesc = { 1, 0 }; - swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapDesc.BufferCount = 3; - swapDesc.Scaling = DXGI_SCALING_STRETCH; - swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - swapDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; - swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT - | DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING; - - DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsDesc; - fsDesc.RefreshRate = { 0, 0 }; - fsDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - fsDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - fsDesc.Windowed = TRUE; - - Com swapChain; - if (FAILED(m_factory->CreateSwapChainForHwnd(m_device.ptr(), m_window, &swapDesc, &fsDesc, nullptr, &swapChain))) { - std::cerr << "Failed to create DXGI swap chain" << std::endl; - return; - } - - if (FAILED(swapChain->QueryInterface(IID_PPV_ARGS(&m_swapChain)))) { - std::cerr << "Failed to query DXGI swap chain interface" << std::endl; - return; - } - - m_factory->MakeWindowAssociation(m_window, 0); - - Com vertexShaderBlob; - Com pixelShaderBlob; - - if (FAILED(D3DCompile(g_vertexShaderCode.data(), g_vertexShaderCode.size(), - "Vertex shader", nullptr, nullptr, "main", "vs_5_0", 0, 0, &vertexShaderBlob, nullptr))) { - std::cerr << "Failed to compile vertex shader" << std::endl; - return; - } - - if (FAILED(D3DCompile(g_pixelShaderCode.data(), g_pixelShaderCode.size(), - "Pixel shader", nullptr, nullptr, "main", "ps_5_0", 0, 0, &pixelShaderBlob, nullptr))) { - std::cerr << "Failed to compile pixel shader" << std::endl; - return; - } - - if (FAILED(m_device->CreateVertexShader( - vertexShaderBlob->GetBufferPointer(), - vertexShaderBlob->GetBufferSize(), - nullptr, &m_vs))) { - std::cerr << "Failed to create vertex shader" << std::endl; - return; - } - - if (FAILED(m_device->CreatePixelShader( - pixelShaderBlob->GetBufferPointer(), - pixelShaderBlob->GetBufferSize(), - nullptr, &m_ps))) { - std::cerr << "Failed to create pixel shader" << std::endl; - return; - } - - std::array vertexFormatDesc = {{ - { "IN_POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }}; - - if (FAILED(m_device->CreateInputLayout( - vertexFormatDesc.data(), - vertexFormatDesc.size(), - vertexShaderBlob->GetBufferPointer(), - vertexShaderBlob->GetBufferSize(), - &m_vertexFormat))) { - std::cerr << "Failed to create input layout" << std::endl; - return; - } - - std::array vertexData = {{ - Vertex { -0.3f, 0.1f }, - Vertex { 0.5f, 0.9f }, - Vertex { 1.3f, 0.1f }, - Vertex { -0.3f, 0.9f }, - Vertex { 1.3f, 0.9f }, - Vertex { 0.5f, 0.1f }, - }}; - - D3D11_BUFFER_DESC vboDesc; - vboDesc.ByteWidth = sizeof(vertexData); - vboDesc.Usage = D3D11_USAGE_IMMUTABLE; - vboDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vboDesc.CPUAccessFlags = 0; - vboDesc.MiscFlags = 0; - vboDesc.StructureByteStride = 0; - - D3D11_SUBRESOURCE_DATA vboData; - vboData.pSysMem = vertexData.data(); - vboData.SysMemPitch = vboDesc.ByteWidth; - vboData.SysMemSlicePitch = vboDesc.ByteWidth; - - if (FAILED(m_device->CreateBuffer(&vboDesc, &vboData, &m_vbo))) { - std::cerr << "Failed to create index buffer" << std::endl; - return; - } - - std::array indexData = {{ 0, 1, 2, 3, 4, 5 }}; - - D3D11_BUFFER_DESC iboDesc; - iboDesc.ByteWidth = sizeof(indexData); - iboDesc.Usage = D3D11_USAGE_IMMUTABLE; - iboDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; - iboDesc.CPUAccessFlags = 0; - iboDesc.MiscFlags = 0; - iboDesc.StructureByteStride = 0; - - D3D11_SUBRESOURCE_DATA iboData; - iboData.pSysMem = indexData.data(); - iboData.SysMemPitch = iboDesc.ByteWidth; - iboData.SysMemSlicePitch = iboDesc.ByteWidth; - - if (FAILED(m_device->CreateBuffer(&iboDesc, &iboData, &m_ibo))) { - std::cerr << "Failed to create index buffer" << std::endl; - return; - } - - D3D11_BUFFER_DESC cbDesc; - cbDesc.ByteWidth = sizeof(PsConstants); - cbDesc.Usage = D3D11_USAGE_DYNAMIC; - cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - cbDesc.MiscFlags = 0; - cbDesc.StructureByteStride = 0; - - if (FAILED(m_device->CreateBuffer(&cbDesc, nullptr, &m_cbPs))) { - std::cerr << "Failed to create constant buffer" << std::endl; - return; - } - - cbDesc.ByteWidth = sizeof(VsConstantsPad) * 128 * 8; - - if (FAILED(m_device->CreateBuffer(&cbDesc, nullptr, &m_cbVs))) { - std::cerr << "Failed to create constant buffer" << std::endl; - return; - } - - std::array colors = { 0xFFFFFFFF, 0xFFC0C0C0 }; - - D3D11_SUBRESOURCE_DATA texData; - texData.pSysMem = &colors[0]; - texData.SysMemPitch = sizeof(colors[0]); - texData.SysMemSlicePitch = sizeof(colors[0]); - - D3D11_TEXTURE2D_DESC texDesc; - texDesc.Width = 1; - texDesc.Height = 1; - texDesc.MipLevels = 1; - texDesc.ArraySize = 1; - texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - texDesc.SampleDesc = { 1, 0 }; - texDesc.Usage = D3D11_USAGE_IMMUTABLE; - texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - texDesc.CPUAccessFlags = 0; - texDesc.MiscFlags = 0; - - if (FAILED(m_device->CreateTexture2D(&texDesc, &texData, &m_tex0))) { - std::cerr << "Failed to create texture" << std::endl; - return; - } - - texData.pSysMem = &colors[1]; - - if (FAILED(m_device->CreateTexture2D(&texDesc, &texData, &m_tex1))) { - std::cerr << "Failed to create texture" << std::endl; - return; - } - - if (FAILED(m_device->CreateShaderResourceView(m_tex0.ptr(), nullptr, &m_srv0)) - || FAILED(m_device->CreateShaderResourceView(m_tex1.ptr(), nullptr, &m_srv1))) { - std::cerr << "Failed to create SRV" << std::endl; - return; - } - - m_initialized = true; - } - - - ~TriangleApp() { - m_context->ClearState(); - } - - - bool run() { - if (!m_initialized) - return false; - - if (m_occluded && (m_occluded = isOccluded())) - return true; - - if (!beginFrame()) - return true; - - std::array colors = {{ - PsConstants { 0.25f, 0.25f, 0.25f, 1.0f }, - PsConstants { 0.40f, 0.40f, 0.40f, 1.0f }, - }}; - - for (uint32_t i = 0; i < 8; i++) { - DrawOptions options; - options.sortByTexture = i & 1; - options.drawIndexed = i & 2; - options.mapDiscardOnce = i & 4; - drawLines(colors[i & 1], options, i); - } - - if (!endFrame()) - return false; - - updateFps(); - return true; - } - - - void drawLines(const PsConstants& psData, const DrawOptions& options, uint32_t baseY) { - D3D11_MAPPED_SUBRESOURCE sr; - - // Update color for the row - m_context->PSSetConstantBuffers(0, 1, &m_cbPs); - m_context->Map(m_cbPs.ptr(), 0, D3D11_MAP_WRITE_DISCARD, 0, &sr); - std::memcpy(sr.pData, &psData, sizeof(psData)); - m_context->Unmap(m_cbPs.ptr(), 0); - - baseY *= 8; - - if (options.mapDiscardOnce) { - uint32_t drawIndex = 0; - - // Discard and map the entire vertex constant buffer - // once, then bind sub-ranges while emitting draw calls - m_context->Map(m_cbVs.ptr(), 0, D3D11_MAP_WRITE_DISCARD, 0, &sr); - auto vsData = reinterpret_cast(sr.pData); - - for (uint32_t y = 0; y < 8; y++) { - for (uint32_t x = 0; x < 128; x++) - vsData[drawIndex++].data = getVsConstants(x, baseY + y); - } - - m_context->Unmap(m_cbVs.ptr(), 0); - } - - if (options.drawIndexed) - m_context->IASetIndexBuffer(m_ibo.ptr(), DXGI_FORMAT_R32_UINT, 0); - - uint32_t vsStride = sizeof(Vertex); - uint32_t vsOffset = 0; - m_context->IASetVertexBuffers(0, 1, &m_vbo, &vsStride, &vsOffset); - - uint32_t maxZ = options.sortByTexture ? 2 : 1; - - for (uint32_t z = 0; z < maxZ; z++) { - uint32_t drawIndex = z; - - if (options.sortByTexture) { - ID3D11ShaderResourceView* view = z ? m_srv1.ptr() : m_srv0.ptr(); - m_context->PSSetShaderResources(0, 1, &view); - } - - for (uint32_t y = 0; y < 8; y++) { - for (uint32_t x = z; x < 128; x += maxZ) { - uint32_t triIndex = (x ^ y) & 1; - - if (!options.mapDiscardOnce) { - D3D11_MAP mapMode = drawIndex ? D3D11_MAP_WRITE_NO_OVERWRITE : D3D11_MAP_WRITE_DISCARD; - m_context->Map(m_cbVs.ptr(), 0, mapMode, 0, &sr); - auto vsData = reinterpret_cast(sr.pData); - vsData[drawIndex].data = getVsConstants(x, baseY + y); - m_context->Unmap(m_cbVs.ptr(), 0); - } - - uint32_t constantOffset = 16 * drawIndex; - uint32_t constantCount = 16; - m_context->VSSetConstantBuffers1(0, 1, &m_cbVs, &constantOffset, &constantCount); - - if (!options.sortByTexture) { - ID3D11ShaderResourceView* view = triIndex ? m_srv1.ptr() : m_srv0.ptr(); - m_context->PSSetShaderResources(0, 1, &view); - } - - // Submit draw call - uint32_t baseIndex = 3 * triIndex; - - if (options.drawIndexed) - m_context->DrawIndexed(3, baseIndex, 0); - else - m_context->Draw(3, baseIndex); - - drawIndex += maxZ; - } - } - } - } - - - static VsConstants getVsConstants(uint32_t x, uint32_t y) { - VsConstants result; - result.x = float(x) / 128.0f; - result.y = float(y) / 64.0f; - result.w = 1.0f / 128.0f; - result.h = 1.0f / 64.0f; - return result; - } - - - bool beginFrame() { - // Make sure we can actually render to the window - RECT windowRect = { 0, 0, 1024, 600 }; - GetClientRect(m_window, &windowRect); - - uint32_t newWindowSizeW = uint32_t(windowRect.right - windowRect.left); - uint32_t newWindowSizeH = uint32_t(windowRect.bottom - windowRect.top); - - if (m_windowSizeW != newWindowSizeW || m_windowSizeH != newWindowSizeH) { - m_rtv = nullptr; - m_context->ClearState(); - - DXGI_SWAP_CHAIN_DESC1 desc; - m_swapChain->GetDesc1(&desc); - - if (FAILED(m_swapChain->ResizeBuffers(desc.BufferCount, - newWindowSizeW, newWindowSizeH, desc.Format, desc.Flags))) { - std::cerr << "Failed to resize back buffers" << std::endl; - return false; - } - - Com backBuffer; - if (FAILED(m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)))) { - std::cerr << "Failed to get swap chain back buffer" << std::endl; - return false; - } - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - rtvDesc.Texture2D = { 0u }; - - if (FAILED(m_device->CreateRenderTargetView(backBuffer.ptr(), &rtvDesc, &m_rtv))) { - std::cerr << "Failed to create render target view" << std::endl; - return false; - } - - m_windowSizeW = newWindowSizeW; - m_windowSizeH = newWindowSizeH; - } - - // Set up render state - FLOAT color[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; - m_context->OMSetRenderTargets(1, &m_rtv, nullptr); - m_context->ClearRenderTargetView(m_rtv.ptr(), color); - - m_context->VSSetShader(m_vs.ptr(), nullptr, 0); - m_context->PSSetShader(m_ps.ptr(), nullptr, 0); - - m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - m_context->IASetInputLayout(m_vertexFormat.ptr()); - - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0.0f; - viewport.TopLeftY = 0.0f; - viewport.Width = float(m_windowSizeW); - viewport.Height = float(m_windowSizeH); - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - m_context->RSSetViewports(1, &viewport); - return true; - } - - - bool endFrame() { - HRESULT hr = m_swapChain->Present(0, DXGI_PRESENT_TEST); - - if (hr == S_OK) - hr = m_swapChain->Present(0, 0); - - m_occluded = hr == DXGI_STATUS_OCCLUDED; - return true; - } - - void updateFps() { - if (!m_qpcFrequency.QuadPart) - QueryPerformanceFrequency(&m_qpcFrequency); - - if (!m_qpcLastUpdate.QuadPart) - QueryPerformanceCounter(&m_qpcLastUpdate); - - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - - m_frameCount++; - - if (now.QuadPart - m_qpcLastUpdate.QuadPart < m_qpcFrequency.QuadPart) - return; - - double seconds = double(now.QuadPart - m_qpcLastUpdate.QuadPart) / double(m_qpcFrequency.QuadPart); - double fps = double(m_frameCount) / seconds; - - std::wstringstream str; - str << L"D3D11 triangle (" << fps << L" FPS)"; - - SetWindowTextW(m_window, str.str().c_str()); - - m_qpcLastUpdate = now; - m_frameCount = 0; - } - - bool isOccluded() { - return m_swapChain->Present(0, DXGI_PRESENT_TEST) == DXGI_STATUS_OCCLUDED; - } - -private: - - HWND m_window; - uint32_t m_windowSizeW = 1024; - uint32_t m_windowSizeH = 600; - bool m_initialized = false; - bool m_occluded = false; - - Com m_factory; - Com m_adapter; - Com m_device; - Com m_context; - Com m_swapChain; - - Com m_rtv; - Com m_ibo; - Com m_vbo; - Com m_vertexFormat; - - Com m_tex0; - Com m_tex1; - Com m_srv0; - Com m_srv1; - - Com m_cbPs; - Com m_cbVs; - - Com m_vs; - Com m_ps; - - LARGE_INTEGER m_qpcLastUpdate = { }; - LARGE_INTEGER m_qpcFrequency = { }; - - uint32_t m_frameCount = 0; - -}; - -LRESULT CALLBACK WindowProc(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - WNDCLASSEXW wc = { }; - wc.cbSize = sizeof(wc); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = WindowProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hbrBackground = HBRUSH(COLOR_WINDOW); - wc.lpszClassName = L"WindowClass"; - RegisterClassExW(&wc); - - HWND hWnd = CreateWindowExW(0, L"WindowClass", L"D3D11 triangle", - WS_OVERLAPPEDWINDOW, 300, 300, 1024, 600, - nullptr, nullptr, hInstance, nullptr); - ShowWindow(hWnd, nCmdShow); - - TriangleApp app(hInstance, hWnd); - - MSG msg; - - while (true) { - if (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessageW(&msg); - - if (msg.message == WM_QUIT) - return msg.wParam; - } else { - if (!app.run()) - break; - } - } - - return msg.wParam; -} - -LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - - return DefWindowProcW(hWnd, message, wParam, lParam); -} diff --git a/tests/d3d11/test_d3d11_video.cpp b/tests/d3d11/test_d3d11_video.cpp deleted file mode 100644 index a974962a4..000000000 --- a/tests/d3d11/test_d3d11_video.cpp +++ /dev/null @@ -1,459 +0,0 @@ -#include - -#include -#include - -#include -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -class VideoApp { - -public: - - VideoApp(HINSTANCE instance, HWND window) - : m_window(window) { - // Create base D3D11 device and swap chain - DXGI_SWAP_CHAIN_DESC swapchainDesc = { }; - swapchainDesc.BufferDesc.Width = m_windowSizeX; - swapchainDesc.BufferDesc.Height = m_windowSizeY; - swapchainDesc.BufferDesc.RefreshRate = { 0, 0 }; - swapchainDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - swapchainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - swapchainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - swapchainDesc.BufferCount = 2; - swapchainDesc.SampleDesc = { 1, 0 }; - swapchainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapchainDesc.OutputWindow = m_window; - swapchainDesc.Windowed = true; - swapchainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - swapchainDesc.Flags = 0; - - HRESULT hr = D3D11CreateDeviceAndSwapChain(nullptr, - D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, - D3D11_SDK_VERSION, &swapchainDesc, &m_swapchain, - &m_device, nullptr, &m_context); - - if (FAILED(hr)) { - std::cerr << "Failed to initialize D3D11 device and swap chain" << std::endl; - return; - } - - if (FAILED(hr = m_device->QueryInterface(IID_PPV_ARGS(&m_vdevice)))) { - std::cerr << "Failed to query D3D11 video device" << std::endl; - return; - } - - if (FAILED(hr = m_context->QueryInterface(IID_PPV_ARGS(&m_vcontext)))) { - std::cerr << "Failed to query D3D11 video context" << std::endl; - return; - } - - if (FAILED(hr = m_swapchain->ResizeTarget(&swapchainDesc.BufferDesc))) { - std::cerr << "Failed to resize target" << std::endl; - return; - } - - if (FAILED(hr = m_swapchain->GetBuffer(0, IID_PPV_ARGS(&m_swapImage)))) { - std::cerr << "Failed to query swap chain image" << std::endl; - return; - } - - if (FAILED(hr = m_device->CreateRenderTargetView(m_swapImage.ptr(), nullptr, &m_swapImageView))) { - std::cerr << "Failed to create render target view" << std::endl; - return; - } - - // Create video processor instance - D3D11_VIDEO_PROCESSOR_CONTENT_DESC videoEnumDesc = { }; - videoEnumDesc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE; - videoEnumDesc.InputFrameRate = { 60, 1 }; - videoEnumDesc.InputWidth = 128; - videoEnumDesc.InputHeight = 128; - videoEnumDesc.OutputFrameRate = { 60, 1 }; - videoEnumDesc.OutputWidth = 256; - videoEnumDesc.OutputHeight = 256; - videoEnumDesc.Usage = D3D11_VIDEO_USAGE_PLAYBACK_NORMAL; - - if (FAILED(hr = m_vdevice->CreateVideoProcessorEnumerator(&videoEnumDesc, &m_venum))) { - std::cerr << "Failed to create D3D11 video processor enumerator" << std::endl; - return; - } - - if (FAILED(hr = m_vdevice->CreateVideoProcessor(m_venum.ptr(), 0, &m_vprocessor))) { - std::cerr << "Failed to create D3D11 video processor" << std::endl; - return; - } - - // Video output image and view - D3D11_TEXTURE2D_DESC textureDesc = { }; - textureDesc.Width = 256; - textureDesc.Height = 256; - textureDesc.MipLevels = 1; - textureDesc.ArraySize = 1; - textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - textureDesc.SampleDesc = { 1, 0 }; - textureDesc.Usage = D3D11_USAGE_DEFAULT; - textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET; - - if (FAILED(hr = m_device->CreateTexture2D(&textureDesc, nullptr, &m_videoOutput))) { - std::cerr << "Failed to create D3D11 video output image" << std::endl; - return; - } - - D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC outputDesc = { }; - outputDesc.ViewDimension = D3D11_VPOV_DIMENSION_TEXTURE2D; - outputDesc.Texture2D.MipSlice = 0; - - if (FAILED(hr = m_vdevice->CreateVideoProcessorOutputView(m_videoOutput.ptr(), m_venum.ptr(), &outputDesc, &m_videoOutputView))) { - std::cerr << "Failed to create D3D11 video output view" << std::endl; - return; - } - - if (FAILED(hr = m_device->CreateRenderTargetView(m_videoOutput.ptr(), nullptr, &m_videoOutputRtv))) { - std::cerr << "Failed to create video render target view" << std::endl; - return; - } - - // RGBA input image and view - textureDesc.Width = 128; - textureDesc.Height = 128; - textureDesc.BindFlags = 0; - - size_t pixelCount = textureDesc.Width * textureDesc.Height; - - size_t rowSizeRgba = textureDesc.Width * 4; - size_t rowSizeNv12 = textureDesc.Width; - size_t rowSizeYuy2 = textureDesc.Width * 2; - size_t imageSizeRgba = textureDesc.Height * rowSizeRgba; - size_t imageSizeNv12 = pixelCount + pixelCount / 2; - size_t imageSizeYuy2 = textureDesc.Height * rowSizeYuy2; - - std::vector srcData(pixelCount * 3); - std::vector imgDataRgba(imageSizeRgba); - std::vector imgDataNv12(imageSizeNv12); - std::vector imgDataYuy2(imageSizeYuy2); - std::ifstream ifile("video_image.raw", std::ios::binary); - - if (!ifile || !ifile.read(reinterpret_cast(srcData.data()), srcData.size())) { - std::cerr << "Failed to read image file" << std::endl; - return; - } - - for (size_t i = 0; i < pixelCount; i++) { - imgDataRgba[4 * i + 0] = srcData[3 * i + 0]; - imgDataRgba[4 * i + 1] = srcData[3 * i + 1]; - imgDataRgba[4 * i + 2] = srcData[3 * i + 2]; - imgDataRgba[4 * i + 3] = 0xFF; - - imgDataNv12[i] = y_coeff(&srcData[3 * i], 0.299000f, 0.587000f, 0.114000f); - - imgDataYuy2[2 * i + 0] = y_coeff(&srcData[3 * i], 0.299000f, 0.587000f, 0.114000f); - imgDataYuy2[2 * i + 1] = i % 2 - ? c_coeff(&srcData[3 * i], -0.168736f, -0.331264f, 0.500000f) - : c_coeff(&srcData[3 * i], 0.500000f, -0.418688f, -0.081312f); - } - - for (size_t y = 0; y < textureDesc.Height / 2; y++) { - for (size_t x = 0; x < textureDesc.Width / 2; x++) { - size_t p = textureDesc.Width * (2 * y) + 2 * x; - size_t i = pixelCount + textureDesc.Width * y + 2 * x; - imgDataNv12[i + 0] = c_coeff(&srcData[3 * p], 0.500000f, -0.418688f, -0.081312f); - imgDataNv12[i + 1] = c_coeff(&srcData[3 * p], -0.168736f, -0.331264f, 0.500000f); - } - } - - D3D11_SUBRESOURCE_DATA subresourceData = { }; - subresourceData.pSysMem = imgDataRgba.data(); - subresourceData.SysMemPitch = rowSizeRgba; - subresourceData.SysMemSlicePitch = rowSizeRgba * textureDesc.Height; - - if (FAILED(hr = m_device->CreateTexture2D(&textureDesc, &subresourceData, &m_videoInput))) { - std::cerr << "Failed to create D3D11 video input image" << std::endl; - return; - } - - D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC inputDesc = { }; - inputDesc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D; - inputDesc.Texture2D.MipSlice = 0; - - if (FAILED(hr = m_vdevice->CreateVideoProcessorInputView(m_videoInput.ptr(), m_venum.ptr(), &inputDesc, &m_videoInputView))) { - std::cerr << "Failed to create D3D11 video input view" << std::endl; - return; - } - - // NV12 input image and view - textureDesc.Format = DXGI_FORMAT_NV12; - textureDesc.BindFlags = 0; - - subresourceData.pSysMem = imgDataNv12.data(); - subresourceData.SysMemPitch = rowSizeNv12; - subresourceData.SysMemSlicePitch = rowSizeNv12 * textureDesc.Height; - - if (SUCCEEDED(hr = m_device->CreateTexture2D(&textureDesc, nullptr, &m_videoInputNv12))) { - if (FAILED(hr = m_vdevice->CreateVideoProcessorInputView(m_videoInputNv12.ptr(), m_venum.ptr(), &inputDesc, &m_videoInputViewNv12))) { - std::cerr << "Failed to create D3D11 video input view for NV12" << std::endl; - return; - } - } else { - std::cerr << "NV12 not supported" << std::endl; - } - - textureDesc.Usage = D3D11_USAGE_STAGING; - textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ; - - if (SUCCEEDED(hr = m_device->CreateTexture2D(&textureDesc, nullptr, &m_videoInputNv12Host))) { - D3D11_MAPPED_SUBRESOURCE mr = { }; - m_context->Map(m_videoInputNv12Host.ptr(), 0, D3D11_MAP_WRITE, D3D11_MAP_FLAG_DO_NOT_WAIT, &mr); - memcpy(mr.pData, imgDataNv12.data(), imgDataNv12.size()); - m_context->Unmap(m_videoInputNv12Host.ptr(), 0); - D3D11_BOX box = { 0, 0, 0, 128, 128, 1 }; - m_context->CopySubresourceRegion(m_videoInputNv12.ptr(), 0, 0, 0, 0, m_videoInputNv12Host.ptr(), 0, &box); - } - - // YUY2 input image and view - textureDesc.Format = DXGI_FORMAT_YUY2; - textureDesc.BindFlags = 0; - textureDesc.Usage = D3D11_USAGE_DEFAULT; - textureDesc.CPUAccessFlags = 0; - - subresourceData.pSysMem = imgDataYuy2.data(); - subresourceData.SysMemPitch = rowSizeYuy2; - subresourceData.SysMemSlicePitch = imageSizeYuy2; - - if (SUCCEEDED(hr = m_device->CreateTexture2D(&textureDesc, &subresourceData, &m_videoInputYuy2))) { - if (FAILED(hr = m_vdevice->CreateVideoProcessorInputView(m_videoInputYuy2.ptr(), m_venum.ptr(), &inputDesc, &m_videoInputViewYuy2))) { - std::cerr << "Failed to create D3D11 video input view for YUY2" << std::endl; - return; - } - } else { - std::cerr << "YUY2 not supported" << std::endl; - } - - m_initialized = true; - } - - - ~VideoApp() { - - } - - - void run() { - this->adjustBackBuffer(); - - float color[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; - m_context->ClearRenderTargetView(m_swapImageView.ptr(), color); - - // Full range RGB output color space - D3D11_VIDEO_PROCESSOR_COLOR_SPACE csOut = { }; - csOut.Usage = 0; // Present - csOut.RGB_Range = 0; // Full range - csOut.Nominal_Range = 1; // Full range - - D3D11_VIDEO_PROCESSOR_COLOR_SPACE csIn = { }; - csIn.Usage = 0; // Present - csIn.RGB_Range = 0; // Full range - csIn.Nominal_Range = 1; // Full range - csIn.YCbCr_Matrix = 0; // BT.601 - - m_vcontext->VideoProcessorSetStreamAutoProcessingMode(m_vprocessor.ptr(), 0, false); - m_vcontext->VideoProcessorSetOutputColorSpace(m_vprocessor.ptr(), &csOut); - m_vcontext->VideoProcessorSetStreamColorSpace(m_vprocessor.ptr(), 0, &csIn); - blit(m_videoInputView.ptr(), 32, 32); - blit(m_videoInputViewNv12.ptr(), 32, 320); - blit(m_videoInputViewYuy2.ptr(), 32, 608); - - csIn.RGB_Range = 1; // Limited range - csIn.Nominal_Range = 0; // Limited range - m_vcontext->VideoProcessorSetStreamColorSpace(m_vprocessor.ptr(), 0, &csIn); - blit(m_videoInputView.ptr(), 320, 32); - blit(m_videoInputViewNv12.ptr(), 320, 320); - blit(m_videoInputViewYuy2.ptr(), 320, 608); - - // Limited range RGB output color space - csOut.RGB_Range = 1; - csOut.Nominal_Range = 0; - m_vcontext->VideoProcessorSetOutputColorSpace(m_vprocessor.ptr(), &csOut); - - csIn.RGB_Range = 0; // Full range - csIn.Nominal_Range = 1; // Full range - m_vcontext->VideoProcessorSetStreamColorSpace(m_vprocessor.ptr(), 0, &csIn); - blit(m_videoInputView.ptr(), 608, 32); - blit(m_videoInputViewNv12.ptr(), 608, 320); - blit(m_videoInputViewYuy2.ptr(), 608, 608); - - csIn.RGB_Range = 1; // Limited range - csIn.Nominal_Range = 0; // Limited range - m_vcontext->VideoProcessorSetStreamColorSpace(m_vprocessor.ptr(), 0, &csIn); - blit(m_videoInputView.ptr(), 896, 32); - blit(m_videoInputViewNv12.ptr(), 896, 320); - blit(m_videoInputViewYuy2.ptr(), 896, 608); - - m_swapchain->Present(1, 0); - } - - - void blit(ID3D11VideoProcessorInputView* pView, uint32_t x, uint32_t y) { - if (!pView) - return; - - D3D11_VIDEO_PROCESSOR_STREAM stream = { }; - stream.Enable = true; - stream.pInputSurface = pView; - - D3D11_BOX box; - box.left = 0; - box.top = 0; - box.front = 0; - box.right = 256; - box.bottom = 256; - box.back = 1; - - FLOAT red[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; - m_context->ClearRenderTargetView(m_videoOutputRtv.ptr(), red); - m_vcontext->VideoProcessorBlt(m_vprocessor.ptr(), m_videoOutputView.ptr(), 0, 1, &stream); - m_context->CopySubresourceRegion(m_swapImage.ptr(), 0, x, y, 0, m_videoOutput.ptr(), 0, &box); - } - - - void adjustBackBuffer() { - RECT windowRect = { }; - GetClientRect(m_window, &windowRect); - - if (uint32_t(windowRect.right - windowRect.left) != m_windowSizeX - || uint32_t(windowRect.bottom - windowRect.top) != m_windowSizeY) { - m_windowSizeX = windowRect.right - windowRect.left; - m_windowSizeY = windowRect.bottom - windowRect.top; - - m_swapImage = nullptr; - m_swapImageView = nullptr; - - HRESULT hr = m_swapchain->ResizeBuffers(0, - m_windowSizeX, m_windowSizeY, DXGI_FORMAT_UNKNOWN, 0); - - if (FAILED(hr)) { - std::cerr << "Failed to resize swap chain buffer" << std::endl; - return; - } - - if (FAILED(hr = m_swapchain->GetBuffer(0, IID_PPV_ARGS(&m_swapImage)))) { - std::cerr << "Failed to query swap chain image" << std::endl; - return; - } - - if (FAILED(hr = m_device->CreateRenderTargetView(m_swapImage.ptr(), nullptr, &m_swapImageView))) { - std::cerr << "Failed to create render target view" << std::endl; - return; - } - } - } - - operator bool () const { - return m_initialized; - } - -private: - - HWND m_window; - uint32_t m_windowSizeX = 1280; - uint32_t m_windowSizeY = 720; - - Com m_swapchain; - Com m_device; - Com m_context; - Com m_vdevice; - Com m_vcontext; - Com m_venum; - Com m_vprocessor; - Com m_swapImage; - Com m_swapImageView; - Com m_videoOutput; - Com m_videoOutputView; - Com m_videoOutputRtv; - Com m_videoInput; - Com m_videoInputView; - Com m_videoInputNv12; - Com m_videoInputNv12Host; - Com m_videoInputYuy2; - Com m_videoInputViewNv12; - Com m_videoInputViewYuy2; - - bool m_initialized = false; - - static inline uint8_t y_coeff(const uint8_t* rgb, float r, float g, float b) { - float x = (rgb[0] * r + rgb[1] * g + rgb[2] * b) / 255.0f; - return 16 + uint8_t(std::roundf(219.0f * std::clamp(x, 0.0f, 1.0f))); - } - - static inline uint8_t c_coeff(const uint8_t* rgb, float r, float g, float b) { - float x = ((rgb[0] * r + rgb[1] * g + rgb[2] * b) / 255.0f) + 0.5f; - return uint8_t(std::roundf(255.0f * std::clamp(x, 0.0f, 1.0f))); - } - -}; - -LRESULT CALLBACK WindowProc(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - HWND hWnd; - WNDCLASSEXW wc; - ZeroMemory(&wc, sizeof(WNDCLASSEX)); - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = WindowProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"WindowClass1"; - RegisterClassExW(&wc); - - hWnd = CreateWindowExW(0, - L"WindowClass1", - L"Our First Windowed Program", - WS_OVERLAPPEDWINDOW, - 300, 300, - 1280, 720, - nullptr, - nullptr, - hInstance, - nullptr); - ShowWindow(hWnd, nCmdShow); - - MSG msg; - VideoApp app(hInstance, hWnd); - - while (app) { - if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - return msg.wParam; - } else { - app.run(); - } - } - - return 0; -} - -LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} diff --git a/tests/d3d11/video_image.raw b/tests/d3d11/video_image.raw deleted file mode 100644 index 7d1b5f38e0e2737f5c8fa77c85e25ead70ef986a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49152 zcmdsgcbrz$we~tDnnaA60Eq<)AZS1ZqzDQ~?^SwL2BcT%y-Axw8_EDP1I#cC3>}6t z^r1KDC?KGapixZJ8*^{GUy}VjYwfenyWg3Y-0%K=pZVk6v)+By-shY>xLotB=d8W= zd5H}D+vMN*s~#ZpAeo<&Dd3sM$P^^=8!}IjDMIEsGR4T0AoDviFOw-t<~1^v$W$Ry zl}rsXwaL^Y(~wM4GR?`fCexNo2QppAyz80nWO|Y5OJ*RM!DNP#8AWCcnek*Mllg$m zbTV;d63EOavw+NEGRr)ZN@gXQ3^HrTWRclOW-FO&`u7GmXJvyvw}=InM^hQW;VXr8NK#@h|I%c z{Kv@@66b%?GtZEDo=kBvB^~F7@n2Wt*CbO%jNeF{zlAt|J2D-~bQR;n`FoS;M`jS2 zA!LS&^N%Gnfy@+f{+VRr$;|fH`4@R?{A4oA$)u54O=c~bb!0Y?*+ynNnVjgg|If)h zLgrEH{GNFd&hPoiV~uZ}zdV_WWZv)?dEQdwX`sl{N|6V~f0shYGeDew7@3jb$TLHc zXPzKW5}BpsBhM;99vFXvAP2|A@Bdp?_ra18743H4OWYY1oDH7jclM6d4%592q!&B{)BsY7%xW^4PGO2YKN9 zJrsEmcHa+2p2?n>Mh3=@1M-l8^DiU==U=ACgRl$ZuMa~WvzN?)=(Yc&9*12xKO;{* z&QnH=59FyVoCnAQ=db4(AWsuAFh0UAV84UqJc2xM{yt;|DDuGh0sG)Qla%wsit*=q z9CjBA@*wQ4BoiRdMs@z3j67yPnOu0K<22Fa|1f?*;XFVdgk6g~FADO!>M`Mj@dM;R z*sV)!{KjOOiSgTzvB(4D2l80w2lBYiZ;@vTvGdQ8usc^cCyc*D!tM&;JaGOjasJH` zc7Z%OWcHCcNajfN+W*(WIpO>kd5S6L0rJ54E$6AC$Wz;6!rw@Y59e^?1F7sf9k zVfSSv{CSZ_p0?op&BgiKI)opD6UNVjJfjtPrjoJ7j~Cbn@&NY1c>?5FErc^b9vFYO zk38lmnG?}#|KAGd0rEUAoW~*$oWHC(Kf-QxGC-a>7I{2=+6C;l7URSDE%LmVFYLnj zaDH$eAkTC`9)#Vw^0c*3k!QIe4~&nnyFtUQi#+1|=4ABRAFvPPc}}0UUb=s(p}rsw zj1T02@!|X(HS7ZRt@8tUhA8rk5#vwRr!62)f}3g(!k?z8hINu^*g^)zhx6|N=Mm%) z=QpRL*ZvlHiaLb_JKUs z`4=hjAnXG6GZA(@cK*$Nsv(3tM;Lj`DKclH*ZwZ@lp+JpQ%*Q1j1T0g<|2=T-IkK) zX(vxxKpuo$Yy7^#dEopbB+nBd4~#!kIL{n$ejrbhrW#gis=*q6n>c@tgk5l+!yIK`H#c+j686Db2)nLU!2T~WMKSP zg!7cwr>y{a>dVtsQ!)YaAnaP?f%Es)B&RjL}AzIR8j_+5+-SmOPJjejv|$ z&q;E6JiUUjYn^|SWcc$V&k3LNF!Fpv<{FtB(QAJgAI@))r?MgsoWGtt?KY8ALo4Mx zoppNUJtx&LG#~Oz7s4NgJWi@1Kpwz;HqR{vNlu$;;IIqWx5xwIe?sQd=(RtLUsh8M zZ)&Qct{A_O7$3;f+9o+Yp4g31!r$MSUKypxGetPhOyQhx{zM78OPwTVfIRkT%Q`CZV|`><2Mz~1Ltq2sfKQnVeX|#&LK{! zAwV8${MnjnNRsK5)O<-!IRAEVPRwly=K<$DDo?v-)c6RyaDEv7Gtc}!dhP$3%x&dC zo`#xgfbrYt(-xc`oTul%T-5;BkCi;n++azGgFKnadEopoK9C1t7n~>8W5N&EKjnno zs|@?*7MVL_?nbZuD+uR#Ly@PBPOn(!x5fwO=^Bna10~NkB0SXq*oX7Sli{#?AHu&u zpSJ!5@?4g%dtIFWHkm(=`67DlZ;_{}B2PWxJP5mheK>zxMV@zcRRcIDj6YZ&b-{VY z==91|F}`*Fd5-hjr!7nP*Gq;O$OGf=3Qsk_`EA$*>|5l4^M6V}9`iYwFQa$c& zZ+c~~a-L%X`$5?KNC+o~T_1VOS7iPiz4o`rQ%eYcBPZ+vd93pTd3tErwa7CxQj!zM z1LMQ_Vf@9)c~&|}&P~pGDi|MO_mFU&lVo80b6${Y;IIqiLD*&FA#;z+x6y0=>N34j zN5gJ&fqjJC_By>16HfTw7vy)5XS&0AfIN%BS8}e_m7D?c?2%MMt{@MbKM(SJBAn;8 zAkP~K9NJ-8iLik5{oadRKNzR$Vc>?E8(&?2non8sT?sg%Z zaQ*{2y#nXAPg~$TA9J2Z2)~3~7$3;(x;zU4dt@*wOo@<`ad!bwh>YOsXghF$ZmXa0lCU!&Ll7I~Uz zssYXq*zX)9IrV94kZ_(6%6TTb&hIhd50EEWrdQznnNE^3TR7)#C&>xqITg-%u6z8n z1?2ey6MlyMKM@=Mdoq8EUi;U#>#00m)d1%Q?7PU*OH&Pi{b7>iw8%4AlAJ)EI9WrE zunX7+@+_0-m6Z~9*XkPbt?K+P^1%6lJaGO?p(Lk6_{I2wJm$a1{GaHxKadB`Z;jv9 z^PL}@2Vu9TgFHj;pX7w`1LR2&KAh7qfe4Z)vKss`^&U6RQ7 z<*t7IkD}%0}>xUi<&d*#K5pci%nZtOqS6Gi2pt zZoaZ+i|k`V0}0;EC0o~8SE9e;tVHi8%=LYJW*dvg29MW+PSaE=9vkL6+c4n#U``pj z4FmCGo6Ximul;{68^8kOc~Z6kJg2L&fIKhD!l3fH^|YF%O6!a95xiSEsnX8*9vgr> z!<^s^=JbIshE8zSM!@-De8i7c&Z?{}!8}3q+P{Eq0E6>CA-nIM)qTG&Icp;T`+@V< z(rp+pKAgXmOwzQM#|9uzcS%^d$TM7!XZ(HEMl5oIH;m80Tajn0I6nvP=(YbZ$viF_ zkbWzBkSy}pup1x`oFB%2LsO*)yKw%-IzwrZr=ydw=%vibI{zqL8v*2j^UrjinHPqy z2LwL4uBswWJ)ItIp~%xgSE9rDd+KAu zAp6Ybg>3+vAxjbg`}5?n0nVQXc@TC1`!GJj?#|$`A$slqD|P;-mGit{x1M^TRaq8! zsyi#u;rz{<4Pb!%uHiG3F#b@1eK`L(-G+g%J4-jcBkWq_NzwJ77J1g|V*{KY$g|hZ z6GX553p%^+o|kPHFY0>Ga!U9ElptnPL1rx*qgs^x7X`_etkztArv?8C{hH;{$o#!on2YeHVn?w$3DtMIMCR z0lFk{gofQox(6v%*G44jGqZJm7(Y`9{}z2_-tEj29FJD}d%}70Z#|VIi4~Re1jtig zx1PfJ+t^7O&tDAvp565B@uv6pLHIp>+5+L9sK&Qpca9SNB|1-#E`%Sj59HaDZ%N`| zo3Myh`#Zbuic8o9=Xph!#8pzxQ$r_d8tFU%IFC&=bP>WIhCCi4zfCnv(5>VpnBFul;S)!}zU$JhBqKv%cu3mk@sI`~mWeSLB%?)AIr0 zU#x2*Ea%D8C5Z^TF5!ps!}uqH>G|lje=*&CXPy5wT@U)EaGqK^Jq*rcpSBQoJ7}sQ zMi-{I$b+yuPE!qV{#a+8V3D)+G(9}kuuYz}a&(>muzyTvD9>Y(EPCxJRK9HxPgk8&dfIM~ebsNoOdZmr7 z%IfO*+c5g*^a^0#K5eW6!9MK*_Sb5X6Uc+Gi?>|u)g_6?HSAvScR!lz(QE%w z4&evkg!5O^^`Q0ev?ZJqVb>D=P7dekb)O_BGW>x3nF{;!^DjyCLL0zr*ahd=&Ig+Z5s#n91ff9w3^b$Z1*KR6GJ55n10!){w=C3+7Hy90#q4^!s{=b7ZZ<;o&Y zqOQsU@~qT-*Fc_)l4rA=XSahqCp7F{l--Y4WmVR#=(Rt>Zbam1ps9wpHPv99zgzfv z&>=dvXpv`%v*~?~rW%qo)sUu~XT2slw|k+tTpa@E^nB;H$n%jdN&GZ=?O#?1zYV)U z9)#UG_kXkJyWvSrYy6Qqy#nN!YLlFvzZiOfuFA@vY5?*e?1FIGu*=3*&V#TE=fC3d zlEfQ!8%Ffn-y%eceVLVdhK6HIZuE*4V|#t&RI{@J$!lv z&JX0Vgx?|$I1ij3VRxP`NnECHxmx8+ufX^~o?VJOxq>`_^8@*>=wj$wvL5#?_8>*C z{i`VQ)KcVWESx7m9ymW>KSnu^O*O#y!=3e1Q=G7Ck!O*l8j>Z?2ImiuXR|Kp0p|ho z9JEhcUhtx&;EfOdPJlniV(71;*ZyyYZ#@O)1oE`>{7vs2!&43YWO~bn-Of{Dai^aQ<pqpB)QWoPO1UUzr&ec zIV{ePr`-?37en9hcpCo#2ENwe#zJpW5XwuBS@L&7-$`*42yv~|UQ%N1|HgYoamO9$?e z`9_TYpJaZBUi%~L!ugvk^0XJ^LD=oCgdfHq?1Wv5JX4kM!};fFs$q$~YbIThXM?Qd z+@^1Q*r%z6W0K_jP+%X(^Ktk~2Q2dZS&;vGI6pRkMX&uW^0W*`o^G1tMA#h^{tY@4 zbv@NA4ZA=dI6sV^EQAxzpCO!Qoxnag&vro`82*-0qK$O?;&}{ z*#Pr9ouMhOlLXbmpBWH2@c*xsfL8~do5$ZzFK2pksJ^0ayt^>MyKlB4)1giH|Mxd7 zKd|zH)J_+-(W%`({Ouv42g!p#vGSlO7|8tXhfw_knk=@QIA(a(wHXHr{T>K}eE zkpGtYhyP~Xiu@8>omZ}Wgr6%{KC%@K{?CKX?yq0T?yo2Gdq|4vw*i#aRY8?>J>pyP z%z(%N@M;|X%+LuBY>}oXhwGbh@%IyeSG@C1ZVO&3G;-T_a&NM`zpxeZ`@eku7l<67 zpux2it4ND`rTH+Cl>+1yAPU5M{}+tK@)wBcsBsUU2-R{9SA0*uBzi;y$}h=##Iw!6 zesBKzR~C%Kx(xaKU*Z4wRrUs}*x&rfg^L$2>IZ62en#dO9)APU~&%F*|X=)qMSQtkAd=Y+5H9M|Jr`{ntmHVG2Md!=P#=>G*yCy5xOdbyyc7u%GyZ03r9739Oe1#tQk#lkpv_eFX zf+AM8O>^%njAg$1N))T#gU%nPS9I>A!o>0$kw7m@_r5k?-!orJeGk_`mnN?E{Cl7T zzq!z9TTY!m4Uy{9DX6Ck=6h@lB-;SWIMb7F>XNLw_dy;we~j+_>L<<* z*tgCfWGkjQlLU$3doWh%^dxB0X3dl4NS^fbpxlMVA6waOX-k)CPY^{E^Z8x#`R5_I zD^1+RU3Z-m{zdc@h2%-qpQJCoFcF0a7dhA2ruXFWh~?OEgk3m)L2-T{PZ2Rbkmp5b z4@P-i42rM|_A(w?V-_;tgNN(LSkeed6 zZnAEhas_@*aH-Xc9kk`Zfdi~ag~NdZzml+PInT4={3T>P9AN)dMV{AnJz_1Ln{OPx z`^!3icYS8)AO6f>k!Ome>a6kSIPa$f@`Llh`B&SO(E24jJ0(xLS7vAqAvbjO>a}aA zu7)bxkT##NMVlpwASI->x@}@0bL}eE;d0GsyE?r{zPu!gtzV>T*A2@xk?ZEVRjz^m z;P(Xggp|En_W6o`1nmDt_F&{k9yosmaelx)kf(-Y{HD4X6k!*}hx3E;0C_CoAE?<1 zIR6+YTQSqwce+54XSu%aAwV8Hux01VlU}-X`SRsUmvLZ)HLIh=nzZ=@_i|l|D599l zm&~P0=JI6~Y2qF|A?NrCkxNvX=;e@js$aQc0>RC!qrMFL>lLivW?y#Y~{DN7%KVAnZ=J>k;KeS(fkv z_LnL0WB_^ebv1DQ9hxUa*gYJq3S!!JiVJEcZmjt#AM_&^;Cuz5@$t7DO*be?U0}cLKR8GQ$->-T^KRJO*I4yBRu~_ zSt${Be|hZufc^bCLvvj6q{ogOJ1Rd=SoJGWMCY^8YY&x)B8oY7ET0@jkMthRe~zk< zFK?)Vo;T?DaT8ITi{v`Je*>3|8#Z!5EiFDgEt{^3YO29Sp2~_mwG?^a{4Ja%S)KJQ zaXs}daWMW+ouL_rr!6n+o5ttq?k_k$jE}IJ?ktS3$OGqR&J!$*&^&4GpEX8K3gx#KzA@s6{X)7V$lB|`w zFv1f4%}&?_?B~i14UB(UUy-P!A&VqZE|u%0tL<8uz%<}S5Hq*OA|@Q0gZIO6jkIw*ahsD(+qP}ecGxU zDb>(fIgbsy{Uz+a?;y{_@FXV)KRC~#`|tkB_WZEB&q1D(&ccXo+1s{dhsrj;WOKJY zCr8^vPh+A+M5wI--HOT1Hrd-)wm}Jm8`6ueZK`k&H6dzBT(fw-(wMeyH;`V z>$28~aNL4|A6xhswD=OfE^A#YqSi#HT|tjomu0fDq+Z7g%Q`gCz(K@z*^AauTcS1| zwLwj+bCYE~E?sZdujhME`?3!Hk6(f-Y#maP7AM)l$HhsDxp3c0;e;QY#}fX)_>IG- zSAaZSHOYyv8z9f{@P!f6oDE18c`WBy?l}L3d`ZrO`da8yx+>+8E{w?FV8tZ^nlxCE zlEH25)xP#b5yfO=nANLAtl~G(1x+Nwp0+*Iks?ZFrU{ePev_z!+<-bv7Tl+l(&?4* zp0Uo)$RkNkgk2avKpuqMPMT)}^1%5m^1%6F{E<%Bh4E)NsRnSKBtd>4&q|$MStmQ* z1J1KYk>`jm28Htjd9LWfh?RaxTe%Vtur((V@9&G5o88;kx zEa3;|vB)#RNpeng7Dmi<7Dlk~J^x!bv+_-^AnXEp@U#og6FC26U6OSR&kHHZ$&h3@ zik`v+eO&pvsJ5#cQ67nr9+RAcu|$$pK{MHH1XrYhDdV>85hOL$KvHa-!nzgW8}bP5 zk4Zp@=ZZ^wLOkpIc~z2}6`Va77J2GB&fi9!b}i@W7M|p^oM)7?Bn!?zOW(3I-%hW{ zSI({w)}3<-Cs9kB{WcTi3L#qU>iZNHsy#*dJ;k2 z3)P9w_c1@$JDUU_B762r38ES1{osKc+r@AU7S#U)nipyFm(8+JX0 zeIQQ_Npf1k59Dc~OR_pD@&tr`pb~x{&lpW|g7eIDkOyHmK%O+`6<3>_ufhQG?AKJo zNnMiVA`hJZ4*rgSpNWa6@e$o`aYF>%dPGNJU!sVDflOkeS&*pp0@iUaxA_E4qst1K z)Q_mYBevO(7A%yDP%ktK7l=Sv2>auTe&pev;7;zDK5hE6Y4}W^jw3!S+y%l3%@Wc6mJP5lWoZECIG>i}A z0qh?aoogWT zq_(=PgR4E<=E==cPoClzUzv;}t1j}?6vEjcd`U_BJcM7v?hsv%IM(xDaRukM$OG61 z@+_28!!kF?Daf-C&hPn4vi9okucHe42)mZ^T+@}%F#hMrUB|}B4=Pq;y8P2}f=?4}c4dq-$Iy%!#+T`;NRNM7?(w*`H;f)TcFdTuT)4)^%GfbL9w0wp zA7K};590@fzpcLR;az7Bh9&$%?d~tnUs5tf@@%mV@+=BRp4Eyxn;qn_VfRS*i)Jo| ze-8|t{|i|O&3~@=o3#g4q{zY7ogSPXM+6x!Vs+azlP9xG3F;}f2W_iO;d4`LjZT_C zc?E+`AihFn>Qpmjs+l^4MSrJU6uNW#h>;^9K?!sizq%0qI=ZR>VHZ!kt;5$-_0Uxf z12pUc_Qys_a$4j;*iF{0cNxy^FAMv->?^MHX$zbaux|-JVE?Lq2@k?9jQ^#48^ieV zJ84}I${+ zCA8%{?>G~?ZmPj@p8F*^mx%F^YDm{r4d6UL9t-<9y6^O`!2U@m$qCrMCdU8F+5H9M ze}`!uDZ{ux8#a`W;!dFoeJtEPbXXh_BvvKR&9Gr+*ifle8OqIJW;kRx*TYZ`=bA6& zQSwMU_sC6V=rH`lLgS%HB&YM${qIx2c`Wk4`GGtzK9HxK!+GHRy_EC3AD(KM;`uL{ zi3{Fo>-pb(2jj2QRKt34{;iti+@q<6V@{s!qU3piJU8;}JN3W*%dr3CDFegWq1M1b z(B}|E6b$6cKvkq?uo)atXs!%|+A4O?xfBc&rVNDr?WK9^KE3%zN*`$WaOu-K2)l6p z=9=UTp0>I>$TQeUasqiK*(9fY@ne8IHtd4)!1$|l55`8#vjO&Z%hOh_L-@}s;fL`* z!Mip*f8S|1J>0Z|}{L{`va`t~#Ztn|g8rmruy ztH0^r&-Cwa`awYrokv;djHOKsgIjqd3;^9KePMrG9f-Y}@9)v$JqQ=BxnWy%^&3R2 z^S4pX1LTRxmueU;oD;?e@__S97s8*Q8<1f9Bxer>IL}%k{CL{6VHd~)!hcZ1u0@^; z!7Hx9o&PKS2CDDL{3qN1|LUGn{6kMYLg61RxQs7NB8n)cXU~Yz%k&cI*~>tz&NVF| z7K~*Tt?e-H*}>im4Vm{kzHKQwyWOYM3tvNS-z?cx!>*4!9`F9b3xyGOE$5l66T3hj zIR89n-zktMO_3)Hi`nEWXMy~1{s4JE_+k7ry5k*T7qAcH`BYL3ca`&equ)UF10F!S z#l-M`0$2Em&Z;V*E_*J8D32sd4+b(Z-MDrordy1O>26}A?v6UfbnkAUbk94A4w`qE z7#S}H{+}9Ax_0T(r7Ma(unG-b4Rs|aV83m6k`u=7bN{z#&(QT$b2Z7i)LGS#sf2%v zhFu`fK6QS}dB8d0{Fin2SMap;h39|w-FJdK|HWVbWjc51+_^LVi=ptr9ynm7F^w z?RbatpL0?TH=VExsjmCeXzE}q&1z#t?4={^W9+?-3Mj#?4RDdS6aXBD+j!@VsOXh@3&1I z{&vc!=E4aKKCRbnlL6ybRD=nJ&+QPV37R>(L{JAg8n_qO^!Xk4PKQVh* zp@fvjsGB=wU&Z|sL}xqM?S*`UuoSci^$44QBYgOv~FcuS!r!rLqu=g zx{ZOf(Yj4**11XRDI|6jse@rKMk^VHds+j3aD%?={z>`ospT{hGp~^w5n&n^gd$$fv|rkw*Rn}DI=REk7=}Y zT-_xTYc82w4fbC&qvFC@Wf#P~oH+ZX`SXg;OMGtb!l&mX{dV@Uf(a>)#;j0TA02q<;{H-+_q}pzZ`otJ%ftTrcD3w>p z^^aLOu<3^29i%5s9q=U~vK_zuI(KZoR$@Y-mYGfJ((%9D*< zG%<}Eo5rd%fexYVL>K~fxVU5BI&R7hdNuB`xA`^xSx#vJy-AbCIDB*Tse4C?e17=Z z-ybS^E4TP{*nj^^7xuq=cHgTf_mn-d`?W(k6|McZ@2IwA$6Fh+YXWM(HI@fjUoBCGjsbZV7n+Ug|wgO#5Zt_R6 zZ>C~zBv5co!nx#a$mT1u;i8fzq_#S@zu=iUi=Ujmr10$I$Kz8UiCg)L*i|)a)pQCs@^zpm)VI&0eUw-B!u~aD z`ckW=fpD`H>e{AOZBrXk%a>ZU45T*g*HNH25)5M%9*Kv6{hf>ao4KcsmfCgrM+zVQ zeB`Mwk34ht@N>6wi{8vFaqYm1Z2$c)pV?dH1P9;p2RQgvk>Fc>V>ZCQ7J_fu*7~WN z8!g$~WYNZEZ2t|dV%N2up4DFL-*t56yRiS@Rqyp*)w_3k-yUfL#Q)!KpE|5n>PQ6N zMhL!3Ce})t4Ew*acsjuUwFPmnBy#XAF)#7?xeK4Q_D_KSv;BV_yQ*5%s#Wo+R*eN8 z6u*Nt|09aMGM5N)$fHA|*d}UIt(roKYNB1UrUc(-?jAz$W%Bd!ftN1r|K0h0FAMp3 z?Ql+o1G_@xXOm-pfdA6XO&4u!K3~ZX{D0EgPUF_R!{ldmkHHAOtC;)<_=EfmW%83e zvgxuh4VQ}jL4K_L7tJik?sLZqjHfBzY0AQ`kg?zW<1pou%lvzMZF?>SQ?a;Xge|AK?>^GtpYu>CLYD=p-w z%&|SM)wnhsn?8hJNtf&|)r=PbNPfDES9%4( zmlZ=grVeeBI=rQj9|T{3Ka-!N4=OK0@U`S;_KWind>4THJT+$t>|ZdR$!7tvf0;6` z;wMx@cRO(ERp*j(L@J&t++)g=F|U^4+6r`$vZicAq4N|bI#w`19wq$h(9IPqR;tJa zb)`yHaHv?3$~3+!Z5g%2eTqqL)R;CX&|`y%4_9bD_5@EYdF}V`oxN5 zCsi&#rD~-Qs#lp-^UWD`-Jtano;tMt^wCWpp4@uwO!oP6 zJ1<_^efgvPA6+~6@y)~6Zy&$$hm*IyIP>XO=SrfK&Ab_C( zle!7b8_apT@w~Q8=XYqapi8So@3u|q(P3$?&dGhdrVNN#KIFZX!(jh@tHummJz?;g z$-}JuH^hyF{Wr~fAZymY**|AT4fAZGnZ2zJt#rzMn zVnKsDr9eTqUUie`CV5grVYwl-DOyyd7}v$Dj=ESeW2Lw%XcjMyU5U5kHryX5GF(v^ zz#l9avKagy*V#+0;@73|cgY|Bk5-!e*E^|Fxye;3Os)F*2Q}W9Uc1`NdNpDj){bvl zcXo@0b6Pi<*RFYDrUuM|P$i+nvGo&&@h@BxL`K=XYJY zwCD22`#-*(dkyx7|KB}%>yICPcJKT%&pcD4ND;2_LFG4~aNFtjFStz*_8ArER?tItoPnTQxlI^@Zxz9i{-{M@e_Zi5aP`C?Yo-j#nl^IXtT7wn$8VZDX>;P#ZHuO7FP*s~C4Se6**UA`?a5rQFKh9E z4NDGgPR@n>cfkIuPO$&4JAGv1nd4i|p5Au;?2Zc;axP!ld*$kZkKzBH9{uDF?0@>! zmmhxi^@S(?m*sP!K<+xadE$vMdD3q_X`T$1r)-nHAYX#v(DOOv8764z)qI;5y7`OZ zQeG(j0*?H#Rq^7JUN1l8P1yhSX*J&v``3tVR3~2TKfgWv|Lp}`+boW0m-Jr8rG2_4 z_kTBaQ1|6Sd!`NVlRg^YKWO#D_t#Dxo;7{c`q;4>64?G*5~prmJbnApS-$<#=k104 z*TMcvVgJL~E5!d-pV+_VWbV4tM>l?W0`?d1zXc=P{G2ca3NC| zwH2!uGKIqK4@S91xSNNOF$y_@$*=mF2!g9a^>ZlCKmR-*aOBE<#Qv40R!FMYM-=n+Ik8AKfb8ORD4!+wjoZEE~;KRW;_v($q*FFXKpSS`0 zf64ZL^f6m-RMqd{jz{zLeM1yc%wvzKJgUlL=F!IX;Y7E?JQ@tfW0=Pt z1^(c49{CPEMT$HP$i#;aq4M;k$`z)*=>*>fq2N2$4ZhtwBKX4pQ~Jli{vbaqNAyh} zJplfnIf=>O77*Uj97(19951mAR6|q-a zo$Du_c#`Ew)U2_>hbJb({t|p=aPWOAwo&c4ru7n9fc!L?+qT*Kjx9kxL4Fo@XY#YG zuMNIERtyvHA3Goe&P8wX$5e|ApVTm)Z$zmT70On$bD{r6>_ zIGA->$PdWp`44woK=8c``ycq|dM@mL{r0gNcTe5?f`jkvKVN$2!G|7v@FAz5{Sb>3 zKJ_3MuBGR1L=nY2^pJV*A@k6KEKpcy`I-3{*Yg$otd!hmT@;lh)vRD}Jf)p%nD$S258qgwGz>oNIh#pDO}cZ2V; zzVD_C6!OWzw|~aCfteC~*G?a~-Ui<}6B+zLev*{@`1S|+;ouAMb9hJEQ6@hC|E$xN z`~dvJg6|=aPX>P*eD7Vj^UXysygU%z%-ee4fqxMFohYcGSTUZ*@_ z%j6T_-<_YlMo91-hu}LTb1IV`YyXY#e-6GvK2zd$u9&?W - -#include - -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - Com factory; - - if (CreateDXGIFactory(__uuidof(IDXGIFactory), - reinterpret_cast(&factory)) != S_OK) { - std::cerr << "Failed to create DXGI factory" << std::endl; - return 1; - } - - Com adapter; - - for (UINT i = 0; factory->EnumAdapters(i, &adapter) == S_OK; i++) { - DXGI_ADAPTER_DESC adapterDesc; - - if (adapter->GetDesc(&adapterDesc) != S_OK) { - std::cerr << "Failed to get DXGI adapter info" << std::endl; - return 1; - } - - DXGI_ADAPTER_DESC desc; - - if (adapter->GetDesc(&desc) != S_OK) { - std::cerr << "Failed to get DXGI adapter info" << std::endl; - return 1; - } - - std::cout << str::format("Adapter ", i, ":") << std::endl; - std::cout << str::format(" ", desc.Description) << std::endl; - std::cout << str::format(" Vendor: ", desc.VendorId) << std::endl; - std::cout << str::format(" Device: ", desc.DeviceId) << std::endl; - std::cout << str::format(" Dedicated RAM: ", desc.DedicatedVideoMemory) << std::endl; - std::cout << str::format(" Shared RAM: ", desc.SharedSystemMemory) << std::endl; - - Com output; - - for (UINT j = 0; adapter->EnumOutputs(j, &output) == S_OK; j++) { - std::vector modes; - - DXGI_OUTPUT_DESC desc; - - if (output->GetDesc(&desc) != S_OK) { - std::cerr << "Failed to get DXGI output info" << std::endl; - return 1; - } - - std::cout << str::format(" Output ", j, ":") << std::endl; - std::cout << str::format(" ", desc.DeviceName) << std::endl; - std::cout << str::format(" Coordinates: ", - desc.DesktopCoordinates.left, ",", - desc.DesktopCoordinates.top, ":", - desc.DesktopCoordinates.right - desc.DesktopCoordinates.left, "x", - desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top) << std::endl; - - HRESULT status = S_OK; - UINT displayModeCount = 0; - - do { - if (output->GetDisplayModeList( - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_ENUM_MODES_SCALING, - &displayModeCount, nullptr) != S_OK) { - std::cerr << "Failed to get DXGI output display mode count" << std::endl; - return 1; - } - - modes.resize(displayModeCount); - - status = output->GetDisplayModeList( - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_ENUM_MODES_SCALING, - &displayModeCount, modes.data()); - } while (status == DXGI_ERROR_MORE_DATA); - - if (status != S_OK) { - std::cerr << "Failed to get DXGI output display mode list" << std::endl; - return 1; - } - - for (auto mode : modes) { - std::cout << str::format(" ", - mode.Width, "x", mode.Height, " @ ", - mode.RefreshRate.Numerator / mode.RefreshRate.Denominator, - mode.Scaling == DXGI_MODE_SCALING_CENTERED ? " (native)" : "") << std::endl; - - //test matching modes - DXGI_MODE_DESC matched_mode{ 0 }; - status = output->FindClosestMatchingMode(&mode, &matched_mode, nullptr); - - if (status != S_OK) { - std::cerr << "Failed to get matching mode" << std::endl; - return 1; - } - - if (matched_mode.Width != mode.Width || - matched_mode.Height != mode.Height || - matched_mode.RefreshRate.Numerator != mode.RefreshRate.Numerator || - matched_mode.RefreshRate.Denominator != mode.RefreshRate.Denominator || - matched_mode.Format != mode.Format) - { - std::cerr << "Matched mode is incorrect" << std::endl; - return 1; - } - } - } - } - - return 0; -} - diff --git a/tests/meson.build b/tests/meson.build index e92b2a03a..d2ec1394a 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,3 +1 @@ subdir('d3d9') -subdir('d3d11') -subdir('dxgi') From a11fb568b920ca3ba159e32e5b9af158a40d8d73 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Aug 2022 16:59:58 +0200 Subject: [PATCH 0732/1348] [tests] Remove D3D9 tests --- meson.build | 6 - meson_options.txt | 1 - package-release.sh | 1 - src/meson.build | 6 +- tests/d3d9/meson.build | 9 - tests/d3d9/test_d3d9_bc_update_surface.cpp | 362 - tests/d3d9/test_d3d9_buffer.cpp | 220 - tests/d3d9/test_d3d9_clear.cpp | 173 - tests/d3d9/test_d3d9_l6v5u5.cpp | 361 - tests/d3d9/test_d3d9_nv12.cpp | 370 - tests/d3d9/test_d3d9_nv12.yuv.h | 12803 ------------------- tests/d3d9/test_d3d9_triangle.cpp | 529 - tests/d3d9/test_d3d9_up.cpp | 429 - tests/meson.build | 1 - tests/test_utils.h | 17 - 15 files changed, 3 insertions(+), 15285 deletions(-) delete mode 100644 tests/d3d9/meson.build delete mode 100644 tests/d3d9/test_d3d9_bc_update_surface.cpp delete mode 100644 tests/d3d9/test_d3d9_buffer.cpp delete mode 100644 tests/d3d9/test_d3d9_clear.cpp delete mode 100644 tests/d3d9/test_d3d9_l6v5u5.cpp delete mode 100644 tests/d3d9/test_d3d9_nv12.cpp delete mode 100644 tests/d3d9/test_d3d9_nv12.yuv.h delete mode 100644 tests/d3d9/test_d3d9_triangle.cpp delete mode 100644 tests/d3d9/test_d3d9_up.cpp delete mode 100644 tests/meson.build delete mode 100644 tests/test_utils.h diff --git a/meson.build b/meson.build index ff3a1e1f5..b6efedce8 100644 --- a/meson.build +++ b/meson.build @@ -135,9 +135,3 @@ dxvk_version = vcs_tag( ) subdir('src') - -enable_tests = get_option('enable_tests') - -if enable_tests - subdir('tests') -endif diff --git a/meson_options.txt b/meson_options.txt index 6af1f6b74..36fd01365 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,4 +1,3 @@ -option('enable_tests', type : 'boolean', value : false) option('enable_dxgi', type : 'boolean', value : true, description: 'Build DXGI') option('enable_d3d9', type : 'boolean', value : true, description: 'Build D3D9') option('enable_d3d10', type : 'boolean', value : true, description: 'Build D3D10') diff --git a/package-release.sh b/package-release.sh index 9318226cb..6401b2020 100755 --- a/package-release.sh +++ b/package-release.sh @@ -63,7 +63,6 @@ function build_arch { $opt_strip \ --bindir "x$1" \ --libdir "x$1" \ - -Denable_tests=false \ -Dbuild_id=$opt_buildid \ "$DXVK_BUILD_DIR/build.$1" diff --git a/src/meson.build b/src/meson.build index e7efdbca8..f4de1099c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -11,7 +11,7 @@ if get_option('enable_dxgi') subdir('dxgi') endif -if get_option('enable_d3d10') or get_option('enable_d3d11') or get_option('enable_tests') +if get_option('enable_d3d10') or get_option('enable_d3d11') subdir('dxbc') endif @@ -36,6 +36,6 @@ if get_option('enable_d3d9') endif # Nothing selected -if not get_option('enable_d3d9') and not get_option('enable_d3d10') and not get_option('enable_d3d11') and not get_option('enable_tests') - warning('Nothing selected to be built. Are you missing a frontend or tests?') +if not get_option('enable_d3d9') and not get_option('enable_d3d10') and not get_option('enable_d3d11') + warning('Nothing selected to be built.?') endif diff --git a/tests/d3d9/meson.build b/tests/d3d9/meson.build deleted file mode 100644 index f6af1d9c4..000000000 --- a/tests/d3d9/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -test_d3d9_deps = [ util_dep, lib_d3d9, lib_d3dcompiler_47 ] - -executable('d3d9-clear'+exe_ext, files('test_d3d9_clear.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true) -executable('d3d9-buffer'+exe_ext, files('test_d3d9_buffer.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true) -executable('d3d9-triangle'+exe_ext, files('test_d3d9_triangle.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true) -executable('d3d9-l6v5u5'+exe_ext, files('test_d3d9_l6v5u5.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true) -executable('d3d9-nv12'+exe_ext, files('test_d3d9_nv12.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true) -executable('d3d9-bc-update-surface'+exe_ext, files('test_d3d9_bc_update_surface.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true) -executable('d3d9-up'+exe_ext, files('test_d3d9_up.cpp'), dependencies : test_d3d9_deps, install : true, gui_app : true) diff --git a/tests/d3d9/test_d3d9_bc_update_surface.cpp b/tests/d3d9/test_d3d9_bc_update_surface.cpp deleted file mode 100644 index 6be3f29e8..000000000 --- a/tests/d3d9/test_d3d9_bc_update_surface.cpp +++ /dev/null @@ -1,362 +0,0 @@ -#include - -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -struct Extent2D { - uint32_t w, h; -}; - -const std::string g_vertexShaderCode = R"( - -struct VS_INPUT { - float3 Position : POSITION; -}; - -struct VS_OUTPUT { - float4 Position : POSITION; - float2 Texcoord : TEXCOORD0; -}; - -VS_OUTPUT main( VS_INPUT IN ) { - VS_OUTPUT OUT; - OUT.Position = float4(IN.Position, 0.6f); - OUT.Texcoord = IN.Position.xy + float2(0.5, 0.5); - OUT.Texcoord.y = 1.0 - OUT.Texcoord.y; - - return OUT; -} - -)"; - -const std::string g_pixelShaderCode = R"( - -struct VS_OUTPUT { - float4 Position : POSITION; - float2 Texcoord : TEXCOORD0; -}; - -struct PS_OUTPUT { - float4 Colour : COLOR; -}; - -sampler g_frogTex : register( s0 ); - -PS_OUTPUT main( VS_OUTPUT IN ) { - PS_OUTPUT OUT; - - OUT.Colour = float4(1, 0, 0, 1); - - return OUT; -} - - -)"; - -Logger Logger::s_instance("triangle.log"); - -class TriangleApp { - -public: - - TriangleApp(HINSTANCE instance, HWND window) - : m_window(window) { - HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 interface"); - - UINT adapter = D3DADAPTER_DEFAULT; - - D3DADAPTER_IDENTIFIER9 adapterId; - m_d3d->GetAdapterIdentifier(adapter, 0, &adapterId); - - Logger::info(str::format("Using adapter: ", adapterId.Description)); - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - - status = m_d3d->CreateDeviceEx( - adapter, - D3DDEVTYPE_HAL, - m_window, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - ¶ms, - nullptr, - &m_device); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 device"); - - - // Vertex Shader - { - Com blob; - - status = D3DCompile( - g_vertexShaderCode.data(), - g_vertexShaderCode.length(), - nullptr, nullptr, nullptr, - "main", - "vs_2_0", - 0, 0, &blob, - nullptr); - - if (FAILED(status)) - throw DxvkError("Failed to compile vertex shader"); - - status = m_device->CreateVertexShader(reinterpret_cast(blob->GetBufferPointer()), &m_vs); - - if (FAILED(status)) - throw DxvkError("Failed to create vertex shader"); - } - - // Pixel Shader - { - Com blob; - - status = D3DCompile( - g_pixelShaderCode.data(), - g_pixelShaderCode.length(), - nullptr, nullptr, nullptr, - "main", - "ps_3_0", - 0, 0, &blob, - nullptr); - - if (FAILED(status)) - throw DxvkError("Failed to compile pixel shader"); - - status = m_device->CreatePixelShader(reinterpret_cast(blob->GetBufferPointer()), &m_ps); - - if (FAILED(status)) - throw DxvkError("Failed to create pixel shader"); - } - - m_device->SetVertexShader(m_vs.ptr()); - m_device->SetPixelShader(m_ps.ptr()); - - m_device->AddRef(); - - - std::array vertices = { - 0.0f, 0.5f, 0.0f, - 0.5f, -0.5f, 0.0f, - -0.5f, -0.5f, 0.0f, - }; - - const size_t vbSize = vertices.size() * sizeof(float); - - status = m_device->CreateVertexBuffer(vbSize, 0, 0, D3DPOOL_DEFAULT, &m_vb, nullptr); - if (FAILED(status)) - throw DxvkError("Failed to create vertex buffer"); - - void* data = nullptr; - status = m_vb->Lock(0, 0, &data, 0); - if (FAILED(status)) - throw DxvkError("Failed to lock vertex buffer"); - - std::memcpy(data, vertices.data(), vbSize); - - status = m_vb->Unlock(); - if (FAILED(status)) - throw DxvkError("Failed to unlock vertex buffer"); - - m_device->SetStreamSource(0, m_vb.ptr(), 0, 3 * sizeof(float)); - - std::array elements; - - elements[0].Method = 0; - elements[0].Offset = 0; - elements[0].Stream = 0; - elements[0].Type = D3DDECLTYPE_FLOAT3; - elements[0].Usage = D3DDECLUSAGE_POSITION; - elements[0].UsageIndex = 0; - - elements[1] = D3DDECL_END(); - - HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl); - if (FAILED(result)) - throw DxvkError("Failed to create vertex decl"); - - m_device->SetVertexDeclaration(m_decl.ptr()); - - const uint32_t imageSize = 8; - - Com texDefault; - Com texDefaultSurf; - status = m_device->CreateTexture(imageSize, imageSize, 4, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &texDefault, nullptr); - status = texDefault->GetSurfaceLevel(2, &texDefaultSurf); - - Com texSysmem; - Com texSysmemSurf; - status = m_device->CreateTexture(imageSize, imageSize, 4, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &texSysmem, nullptr); - status = texSysmem->GetSurfaceLevel(2, &texSysmemSurf); - - D3DLOCKED_RECT rect = {}; - status = texSysmemSurf->LockRect(&rect, nullptr, 0); - std::memset(rect.pBits, 0xF0, 2 * rect.Pitch); - status = texSysmemSurf->UnlockRect(); - - // 1 returns invalid call - // 2 succeeds - RECT sourceRect = { 0, 0, 2, 2 }; - POINT destPoint = { 0, 0 }; - status = m_device->UpdateSurface(texSysmemSurf.ptr(), &sourceRect, texDefaultSurf.ptr(), &destPoint); - } - - void run() { - this->adjustBackBuffer(); - - m_device->BeginScene(); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_TARGET, - D3DCOLOR_RGBA(44, 62, 80, 0), - 0, - 0); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_ZBUFFER, - 0, - 0.5f, - 0); - - m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); - - m_device->EndScene(); - - m_device->PresentEx( - nullptr, - nullptr, - nullptr, - nullptr, - 0); - } - - void adjustBackBuffer() { - RECT windowRect = { 0, 0, 1024, 600 }; - GetClientRect(m_window, &windowRect); - - Extent2D newSize = { - static_cast(windowRect.right - windowRect.left), - static_cast(windowRect.bottom - windowRect.top), - }; - - if (m_windowSize.w != newSize.w - || m_windowSize.h != newSize.h) { - m_windowSize = newSize; - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - HRESULT status = m_device->ResetEx(¶ms, nullptr); - - if (FAILED(status)) - throw DxvkError("Device reset failed"); - } - } - - void getPresentParams(D3DPRESENT_PARAMETERS& params) { - params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - params.BackBufferCount = 1; - params.BackBufferFormat = D3DFMT_X8R8G8B8; - params.BackBufferWidth = m_windowSize.w; - params.BackBufferHeight = m_windowSize.h; - params.EnableAutoDepthStencil = 0; - params.Flags = 0; - params.FullScreen_RefreshRateInHz = 0; - params.hDeviceWindow = m_window; - params.MultiSampleQuality = 0; - params.MultiSampleType = D3DMULTISAMPLE_NONE; - params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - params.SwapEffect = D3DSWAPEFFECT_DISCARD; - params.Windowed = TRUE; - } - -private: - - HWND m_window; - Extent2D m_windowSize = { 1024, 600 }; - - Com m_d3d; - Com m_device; - - Com m_vs; - Com m_ps; - Com m_vb; - Com m_decl; - -}; - -LRESULT CALLBACK WindowProc(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - HWND hWnd; - WNDCLASSEXW wc; - ZeroMemory(&wc, sizeof(WNDCLASSEX)); - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = WindowProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"WindowClass1"; - RegisterClassExW(&wc); - - hWnd = CreateWindowExW(0, - L"WindowClass1", - L"Our First Windowed Program", - WS_OVERLAPPEDWINDOW, - 300, 300, - 640, 480, - nullptr, - nullptr, - hInstance, - nullptr); - ShowWindow(hWnd, nCmdShow); - - MSG msg; - - try { - TriangleApp app(hInstance, hWnd); - - while (true) { - if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - return msg.wParam; - } else { - app.run(); - } - } - } catch (const dxvk::DxvkError& e) { - std::cerr << e.message() << std::endl; - return msg.wParam; - } -} - -LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} diff --git a/tests/d3d9/test_d3d9_buffer.cpp b/tests/d3d9/test_d3d9_buffer.cpp deleted file mode 100644 index f27c7b350..000000000 --- a/tests/d3d9/test_d3d9_buffer.cpp +++ /dev/null @@ -1,220 +0,0 @@ -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -struct Extent2D { - uint32_t w, h; -}; - -DWORD g_UsagePermuatations[] = { - 0, - D3DUSAGE_DYNAMIC, - D3DUSAGE_WRITEONLY, - D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, -}; - -DWORD g_MapFlagPermutations[] = { - 0, - D3DLOCK_DISCARD, - D3DLOCK_DONOTWAIT, - D3DLOCK_NOOVERWRITE -}; - -class BufferApp { - -public: - - BufferApp(HINSTANCE instance, HWND window) - : m_window(window) { - HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 interface"); - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - - status = m_d3d->CreateDeviceEx( - D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - m_window, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - ¶ms, - nullptr, - &m_device); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 device"); - - uint8_t* data = new uint8_t[512]; - std::memset(data, 0xFC, 512); - - for (uint32_t i = 0; i < ARRAYSIZE(g_UsagePermuatations); i++) { - for (uint32_t j = 0; j < ARRAYSIZE(g_MapFlagPermutations); j++) { - testBuffer(data, g_UsagePermuatations[i], g_MapFlagPermutations[j]); - } - } - - delete[] data; - } - - void testBuffer(uint8_t* data, DWORD usage, DWORD mapFlags) { - Com buffer; - HRESULT status = m_device->CreateVertexBuffer(512, usage, 0, D3DPOOL_DEFAULT, &buffer, nullptr); - - if (FAILED(status)) - throw DxvkError("Failed to create buffer"); - - void* bufferMem = nullptr; - status = buffer->Lock(0, 0, &bufferMem, mapFlags); - - if (FAILED(status) || bufferMem == nullptr) - throw DxvkError("Failed to lock buffer"); - - std::memcpy(bufferMem, data, 512); - - status = buffer->Unlock(); - - if (FAILED(status)) - throw DxvkError("Failed to unlock buffer"); - } - - void run() { - this->adjustBackBuffer(); - - m_device->BeginScene(); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_TARGET, - D3DCOLOR_RGBA(255, 50, 139, 0), - 0.0f, - 0); - - m_device->EndScene(); - - m_device->PresentEx( - nullptr, - nullptr, - nullptr, - nullptr, - 0); - } - - void adjustBackBuffer() { - RECT windowRect = { 0, 0, 1024, 600 }; - GetClientRect(m_window, &windowRect); - - Extent2D newSize = { - static_cast(windowRect.right - windowRect.left), - static_cast(windowRect.bottom - windowRect.top), - }; - - if (m_windowSize.w != newSize.w - || m_windowSize.h != newSize.h) { - m_windowSize = newSize; - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - HRESULT status = m_device->ResetEx(¶ms, nullptr); - - if (FAILED(status)) - throw DxvkError("Device reset failed"); - } - } - - void getPresentParams(D3DPRESENT_PARAMETERS& params) { - params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - params.BackBufferCount = 1; - params.BackBufferFormat = D3DFMT_X8R8G8B8; - params.BackBufferWidth = m_windowSize.w; - params.BackBufferHeight = m_windowSize.h; - params.EnableAutoDepthStencil = FALSE; - params.Flags = 0; - params.FullScreen_RefreshRateInHz = 0; - params.hDeviceWindow = m_window; - params.MultiSampleQuality = 0; - params.MultiSampleType = D3DMULTISAMPLE_NONE; - params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - params.SwapEffect = D3DSWAPEFFECT_DISCARD; - params.Windowed = TRUE; - } - -private: - - HWND m_window; - Extent2D m_windowSize = { 1024, 600 }; - - Com m_d3d; - Com m_device; - -}; - -LRESULT CALLBACK WindowProc(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - HWND hWnd; - WNDCLASSEXW wc; - ZeroMemory(&wc, sizeof(WNDCLASSEX)); - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = WindowProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"WindowClass1"; - RegisterClassExW(&wc); - - hWnd = CreateWindowExW(0, - L"WindowClass1", - L"Our First Windowed Program", - WS_OVERLAPPEDWINDOW, - 300, 300, - 640, 480, - nullptr, - nullptr, - hInstance, - nullptr); - ShowWindow(hWnd, nCmdShow); - - MSG msg; - - try { - BufferApp app(hInstance, hWnd); - - while (true) { - if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - return msg.wParam; - } else { - app.run(); - } - } - } catch (const dxvk::DxvkError& e) { - std::cerr << e.message() << std::endl; - return msg.wParam; - } -} - -LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} diff --git a/tests/d3d9/test_d3d9_clear.cpp b/tests/d3d9/test_d3d9_clear.cpp deleted file mode 100644 index 9715333f1..000000000 --- a/tests/d3d9/test_d3d9_clear.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include - -#include "../test_utils.h" - -using namespace dxvk; - -struct Extent2D { - uint32_t w, h; -}; - -class ClearApp { - -public: - - ClearApp(HINSTANCE instance, HWND window) - : m_window(window) { - HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 interface"); - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - - status = m_d3d->CreateDeviceEx( - D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - m_window, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - ¶ms, - nullptr, - &m_device); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 device"); - } - - void run() { - this->adjustBackBuffer(); - - m_device->BeginScene(); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_TARGET, - D3DCOLOR_RGBA(255, 0, 0, 0), - 0.0f, - 0); - - m_device->EndScene(); - - m_device->PresentEx( - nullptr, - nullptr, - nullptr, - nullptr, - 0); - } - - void adjustBackBuffer() { - RECT windowRect = { 0, 0, 1024, 600 }; - GetClientRect(m_window, &windowRect); - - Extent2D newSize = { - static_cast(windowRect.right - windowRect.left), - static_cast(windowRect.bottom - windowRect.top), - }; - - if (m_windowSize.w != newSize.w - || m_windowSize.h != newSize.h) { - m_windowSize = newSize; - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - HRESULT status = m_device->ResetEx(¶ms, nullptr); - - if (FAILED(status)) - throw DxvkError("Device reset failed"); - } - } - - void getPresentParams(D3DPRESENT_PARAMETERS& params) { - params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - params.BackBufferCount = 1; - params.BackBufferFormat = D3DFMT_X8R8G8B8; - params.BackBufferWidth = m_windowSize.w; - params.BackBufferHeight = m_windowSize.h; - params.EnableAutoDepthStencil = FALSE; - params.Flags = 0; - params.FullScreen_RefreshRateInHz = 0; - params.hDeviceWindow = m_window; - params.MultiSampleQuality = 0; - params.MultiSampleType = D3DMULTISAMPLE_NONE; - params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - params.SwapEffect = D3DSWAPEFFECT_DISCARD; - params.Windowed = TRUE; - } - -private: - - HWND m_window; - Extent2D m_windowSize = { 1024, 600 }; - - Com m_d3d; - Com m_device; - -}; - -LRESULT CALLBACK WindowProc(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - HWND hWnd; - WNDCLASSEXW wc; - ZeroMemory(&wc, sizeof(WNDCLASSEX)); - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = WindowProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"WindowClass1"; - RegisterClassExW(&wc); - - hWnd = CreateWindowExW(0, - L"WindowClass1", - L"Our First Windowed Program", - WS_OVERLAPPEDWINDOW, - 300, 300, - 640, 480, - nullptr, - nullptr, - hInstance, - nullptr); - ShowWindow(hWnd, nCmdShow); - - MSG msg; - - try { - ClearApp app(hInstance, hWnd); - - while (true) { - if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - return msg.wParam; - } else { - app.run(); - } - } - } catch (const dxvk::DxvkError& e) { - std::cerr << e.message() << std::endl; - return msg.wParam; - } -} - -LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} diff --git a/tests/d3d9/test_d3d9_l6v5u5.cpp b/tests/d3d9/test_d3d9_l6v5u5.cpp deleted file mode 100644 index 09465278c..000000000 --- a/tests/d3d9/test_d3d9_l6v5u5.cpp +++ /dev/null @@ -1,361 +0,0 @@ -#include - -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -struct Extent2D { - uint32_t w, h; -}; - -const std::string g_vertexShaderCode = R"( - -struct VS_INPUT { - float3 Position : POSITION; -}; - -struct VS_OUTPUT { - float4 Position : POSITION; -}; - -VS_OUTPUT main( VS_INPUT IN ) { - VS_OUTPUT OUT; - OUT.Position = float4(IN.Position, 1.0f); - - return OUT; -} - -)"; - -const std::string g_pixelShaderCode = R"( - -struct VS_OUTPUT { - float4 Position : POSITION; -}; - -struct PS_OUTPUT { - float4 Colour : COLOR; -}; - -sampler g_tex : register( s0 ); - -PS_OUTPUT main( VS_OUTPUT IN ) { - PS_OUTPUT OUT; - - float4 color = float4(tex2D(g_tex, float2(0.5, 0.5)).rgb, 1.0f); - color.r = -color.r; - color.g = -color.g; - OUT.Colour = color; - - - return OUT; -} - - -)"; - -class TriangleApp { - -public: - - TriangleApp(HINSTANCE instance, HWND window) - : m_window(window) { - HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 interface"); - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - - status = m_d3d->CreateDeviceEx( - D3DADAPTER_DEFAULT, - D3DDEVTYPE_HAL, - m_window, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - ¶ms, - nullptr, - &m_device); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 device"); - - // Vertex Shader - { - Com blob; - - status = D3DCompile( - g_vertexShaderCode.data(), - g_vertexShaderCode.length(), - nullptr, nullptr, nullptr, - "main", - "vs_2_0", - 0, 0, &blob, - nullptr); - - if (FAILED(status)) - throw DxvkError("Failed to compile vertex shader"); - - status = m_device->CreateVertexShader(reinterpret_cast(blob->GetBufferPointer()), &m_vs); - - if (FAILED(status)) - throw DxvkError("Failed to create vertex shader"); - } - - // Pixel Shader - { - Com blob; - - status = D3DCompile( - g_pixelShaderCode.data(), - g_pixelShaderCode.length(), - nullptr, nullptr, nullptr, - "main", - "ps_2_0", - 0, 0, &blob, - nullptr); - - if (FAILED(status)) - throw DxvkError("Failed to compile pixel shader"); - - status = m_device->CreatePixelShader(reinterpret_cast(blob->GetBufferPointer()), &m_ps); - - if (FAILED(status)) - throw DxvkError("Failed to create pixel shader"); - } - - m_device->SetVertexShader(m_vs.ptr()); - m_device->SetPixelShader(m_ps.ptr()); - - std::array vertices = { - 0.0f, 0.5f, 0.0f, - 0.5f, -0.5f, 0.0f, - -0.5f, -0.5f, 0.0f, - }; - - const size_t vbSize = vertices.size() * sizeof(float); - - status = m_device->CreateVertexBuffer(vbSize, 0, 0, D3DPOOL_DEFAULT, &m_vb, nullptr); - if (FAILED(status)) - throw DxvkError("Failed to create vertex buffer"); - - void* data = nullptr; - status = m_vb->Lock(0, 0, &data, 0); - if (FAILED(status)) - throw DxvkError("Failed to lock vertex buffer"); - - std::memcpy(data, vertices.data(), vbSize); - - status = m_vb->Unlock(); - if (FAILED(status)) - throw DxvkError("Failed to unlock vertex buffer"); - - m_device->SetStreamSource(0, m_vb.ptr(), 0, 3 * sizeof(float)); - - std::array elements; - - elements[0].Method = 0; - elements[0].Offset = 0; - elements[0].Stream = 0; - elements[0].Type = D3DDECLTYPE_FLOAT3; - elements[0].Usage = D3DDECLUSAGE_POSITION; - elements[0].UsageIndex = 0; - - elements[1] = D3DDECL_END(); - - HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl); - if (FAILED(result)) - throw DxvkError("Failed to create vertex decl"); - - m_device->SetVertexDeclaration(m_decl.ptr()); - - // The actual texture we want to test... - - Com texture; - status = m_device->CreateTexture(64, 64, 1, D3DUSAGE_DYNAMIC, D3DFMT_L6V5U5, D3DPOOL_DEFAULT, &texture, nullptr); - - D3DLOCKED_RECT rect; - status = texture->LockRect(0, &rect, nullptr, 0); - - uint16_t* texData = reinterpret_cast(rect.pBits); - for (uint32_t i = 0; i < (rect.Pitch * 64) / sizeof(uint16_t); i++) { - // -> U -1, V -1, L 1 - texData[i] = 0b1111111000010000; - // -> U 1, V 1, L 1 - //texData[i] = 0b1111110111101111; - } - - status = texture->UnlockRect(0); - - status = m_device->SetTexture(0, texture.ptr()); - - ///////////// - - /*Com texture2; - status = m_device->CreateTexture(64, 64, 1, 0, D3DFMT_A8B8G8R8, D3DPOOL_MANAGED, &texture2, nullptr); - status = texture2->LockRect(0, &rect, nullptr, 0); - - uint32_t* texData2 = reinterpret_cast(rect.pBits); - for (uint32_t i = 0; i < (rect.Pitch * 64) / sizeof(uint32_t); i++) { - texData2[i] = 0b00000000000000000000000011111111; - } - - status = texture2->UnlockRect(0); - - status = m_device->SetTexture(0, texture2.ptr());*/ - } - - void run() { - this->adjustBackBuffer(); - - m_device->BeginScene(); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_TARGET, - D3DCOLOR_RGBA(44, 62, 80, 0), - 0, - 0); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_ZBUFFER, - 0, - 0.5f, - 0); - - m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); - - m_device->EndScene(); - - m_device->PresentEx( - nullptr, - nullptr, - nullptr, - nullptr, - 0); - } - - void adjustBackBuffer() { - RECT windowRect = { 0, 0, 1024, 600 }; - GetClientRect(m_window, &windowRect); - - Extent2D newSize = { - static_cast(windowRect.right - windowRect.left), - static_cast(windowRect.bottom - windowRect.top), - }; - - if (m_windowSize.w != newSize.w - || m_windowSize.h != newSize.h) { - m_windowSize = newSize; - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - HRESULT status = m_device->ResetEx(¶ms, nullptr); - - if (FAILED(status)) - throw DxvkError("Device reset failed"); - } - } - - void getPresentParams(D3DPRESENT_PARAMETERS& params) { - params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - params.BackBufferCount = 1; - params.BackBufferFormat = D3DFMT_X8R8G8B8; - params.BackBufferWidth = m_windowSize.w; - params.BackBufferHeight = m_windowSize.h; - params.EnableAutoDepthStencil = 0; - params.Flags = 0; - params.FullScreen_RefreshRateInHz = 0; - params.hDeviceWindow = m_window; - params.MultiSampleQuality = 0; - params.MultiSampleType = D3DMULTISAMPLE_NONE; - params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - params.SwapEffect = D3DSWAPEFFECT_DISCARD; - params.Windowed = TRUE; - } - -private: - - HWND m_window; - Extent2D m_windowSize = { 1024, 600 }; - - Com m_d3d; - Com m_device; - - Com m_vs; - Com m_ps; - Com m_vb; - Com m_decl; - -}; - -LRESULT CALLBACK WindowProc(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - HWND hWnd; - WNDCLASSEXW wc; - ZeroMemory(&wc, sizeof(WNDCLASSEX)); - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = WindowProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"WindowClass1"; - RegisterClassExW(&wc); - - hWnd = CreateWindowExW(0, - L"WindowClass1", - L"Our First Windowed Program", - WS_OVERLAPPEDWINDOW, - 300, 300, - 640, 480, - nullptr, - nullptr, - hInstance, - nullptr); - ShowWindow(hWnd, nCmdShow); - - MSG msg; - - try { - TriangleApp app(hInstance, hWnd); - - while (true) { - if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - return msg.wParam; - } else { - app.run(); - } - } - } catch (const dxvk::DxvkError& e) { - std::cerr << e.message() << std::endl; - return msg.wParam; - } -} - -LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} diff --git a/tests/d3d9/test_d3d9_nv12.cpp b/tests/d3d9/test_d3d9_nv12.cpp deleted file mode 100644 index 6d4f46175..000000000 --- a/tests/d3d9/test_d3d9_nv12.cpp +++ /dev/null @@ -1,370 +0,0 @@ -#include - -#include -#include - -#include "../test_utils.h" -#include "test_d3d9_nv12.yuv.h" - -using namespace dxvk; - -struct Extent2D { - uint32_t w, h; -}; - -const std::string g_vertexShaderCode = R"( - -struct VS_INPUT { - float3 Position : POSITION; -}; - -struct VS_OUTPUT { - float4 Position : POSITION; - float2 Texcoord : TEXCOORD0; -}; - -VS_OUTPUT main( VS_INPUT IN ) { - VS_OUTPUT OUT; - OUT.Position = float4(IN.Position, 0.6f); - OUT.Texcoord = IN.Position.xy + float2(0.5, 0.5); - OUT.Texcoord.y = 1.0 - OUT.Texcoord.y; - - return OUT; -} - -)"; - -const std::string g_pixelShaderCode = R"( - -struct VS_OUTPUT { - float4 Position : POSITION; - float2 Texcoord : TEXCOORD0; -}; - -struct PS_OUTPUT { - float4 Colour : COLOR; -}; - -sampler g_frogTex : register( s0 ); - -PS_OUTPUT main( VS_OUTPUT IN ) { - PS_OUTPUT OUT; - - OUT.Colour = tex2D(g_frogTex, IN.Texcoord); - - return OUT; -} - - -)"; - -Logger Logger::s_instance("triangle.log"); - -class TriangleApp { - -public: - - TriangleApp(HINSTANCE instance, HWND window) - : m_window(window) { - HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 interface"); - - UINT adapter = D3DADAPTER_DEFAULT; - - D3DADAPTER_IDENTIFIER9 adapterId; - m_d3d->GetAdapterIdentifier(adapter, 0, &adapterId); - - Logger::info(str::format("Using adapter: ", adapterId.Description)); - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - - status = m_d3d->CreateDeviceEx( - adapter, - D3DDEVTYPE_HAL, - m_window, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - ¶ms, - nullptr, - &m_device); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 device"); - - - // Vertex Shader - { - Com blob; - - status = D3DCompile( - g_vertexShaderCode.data(), - g_vertexShaderCode.length(), - nullptr, nullptr, nullptr, - "main", - "vs_2_0", - 0, 0, &blob, - nullptr); - - if (FAILED(status)) - throw DxvkError("Failed to compile vertex shader"); - - status = m_device->CreateVertexShader(reinterpret_cast(blob->GetBufferPointer()), &m_vs); - - if (FAILED(status)) - throw DxvkError("Failed to create vertex shader"); - } - - // Pixel Shader - { - Com blob; - - status = D3DCompile( - g_pixelShaderCode.data(), - g_pixelShaderCode.length(), - nullptr, nullptr, nullptr, - "main", - "ps_2_0", - 0, 0, &blob, - nullptr); - - if (FAILED(status)) - throw DxvkError("Failed to compile pixel shader"); - - status = m_device->CreatePixelShader(reinterpret_cast(blob->GetBufferPointer()), &m_ps); - - if (FAILED(status)) - throw DxvkError("Failed to create pixel shader"); - } - - m_device->SetVertexShader(m_vs.ptr()); - m_device->SetPixelShader(m_ps.ptr()); - - m_device->AddRef(); - - - std::array vertices = { - 0.0f, 0.5f, 0.0f, - 0.5f, -0.5f, 0.0f, - -0.5f, -0.5f, 0.0f, - }; - - const size_t vbSize = vertices.size() * sizeof(float); - - status = m_device->CreateVertexBuffer(vbSize, 0, 0, D3DPOOL_DEFAULT, &m_vb, nullptr); - if (FAILED(status)) - throw DxvkError("Failed to create vertex buffer"); - - void* data = nullptr; - status = m_vb->Lock(0, 0, &data, 0); - if (FAILED(status)) - throw DxvkError("Failed to lock vertex buffer"); - - std::memcpy(data, vertices.data(), vbSize); - - status = m_vb->Unlock(); - if (FAILED(status)) - throw DxvkError("Failed to unlock vertex buffer"); - - m_device->SetStreamSource(0, m_vb.ptr(), 0, 3 * sizeof(float)); - - std::array elements; - - elements[0].Method = 0; - elements[0].Offset = 0; - elements[0].Stream = 0; - elements[0].Type = D3DDECLTYPE_FLOAT3; - elements[0].Usage = D3DDECLUSAGE_POSITION; - elements[0].UsageIndex = 0; - - elements[1] = D3DDECL_END(); - - HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl); - if (FAILED(result)) - throw DxvkError("Failed to create vertex decl"); - - m_device->SetVertexDeclaration(m_decl.ptr()); - - const uint32_t imageSize = 320; - - Com texture; - Com texSurf; - status = m_device->CreateTexture(imageSize, imageSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, nullptr); - status = texture->GetSurfaceLevel(0, &texSurf); - - Com nv12Surf; - status = m_device->CreateOffscreenPlainSurface(imageSize, imageSize, (D3DFORMAT)MAKEFOURCC('N', 'V', '1', '2'), D3DPOOL_DEFAULT, &nv12Surf, nullptr); - D3DLOCKED_RECT rect; - nv12Surf->LockRect(&rect, nullptr, 0); - char* dst = (char*)rect.pBits; - char* src = (char*)test_d3d9_nv12_yuv; - for (uint32_t i = 0; i < imageSize; i++) - { - std::memcpy(dst, src, imageSize); - src += imageSize; - dst += rect.Pitch; - } - - for (uint32_t i = 0; i < imageSize / 2; i++) - { - std::memcpy(dst, src, imageSize); - src += imageSize; - dst += rect.Pitch; - } - nv12Surf->UnlockRect(); - status = m_device->StretchRect(nv12Surf.ptr(), nullptr, texSurf.ptr(), nullptr, D3DTEXF_LINEAR); - m_device->SetTexture(0, texture.ptr()); - } - - void run() { - this->adjustBackBuffer(); - - m_device->BeginScene(); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_TARGET, - D3DCOLOR_RGBA(44, 62, 80, 0), - 0, - 0); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_ZBUFFER, - 0, - 0.5f, - 0); - - m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); - - m_device->EndScene(); - - m_device->PresentEx( - nullptr, - nullptr, - nullptr, - nullptr, - 0); - } - - void adjustBackBuffer() { - RECT windowRect = { 0, 0, 1024, 600 }; - GetClientRect(m_window, &windowRect); - - Extent2D newSize = { - static_cast(windowRect.right - windowRect.left), - static_cast(windowRect.bottom - windowRect.top), - }; - - if (m_windowSize.w != newSize.w - || m_windowSize.h != newSize.h) { - m_windowSize = newSize; - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - HRESULT status = m_device->ResetEx(¶ms, nullptr); - - if (FAILED(status)) - throw DxvkError("Device reset failed"); - } - } - - void getPresentParams(D3DPRESENT_PARAMETERS& params) { - params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - params.BackBufferCount = 1; - params.BackBufferFormat = D3DFMT_X8R8G8B8; - params.BackBufferWidth = m_windowSize.w; - params.BackBufferHeight = m_windowSize.h; - params.EnableAutoDepthStencil = 0; - params.Flags = 0; - params.FullScreen_RefreshRateInHz = 0; - params.hDeviceWindow = m_window; - params.MultiSampleQuality = 0; - params.MultiSampleType = D3DMULTISAMPLE_NONE; - params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - params.SwapEffect = D3DSWAPEFFECT_DISCARD; - params.Windowed = TRUE; - } - -private: - - HWND m_window; - Extent2D m_windowSize = { 1024, 600 }; - - Com m_d3d; - Com m_device; - - Com m_vs; - Com m_ps; - Com m_vb; - Com m_decl; - -}; - -LRESULT CALLBACK WindowProc(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - HWND hWnd; - WNDCLASSEXW wc; - ZeroMemory(&wc, sizeof(WNDCLASSEX)); - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = WindowProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"WindowClass1"; - RegisterClassExW(&wc); - - hWnd = CreateWindowExW(0, - L"WindowClass1", - L"Our First Windowed Program", - WS_OVERLAPPEDWINDOW, - 300, 300, - 640, 480, - nullptr, - nullptr, - hInstance, - nullptr); - ShowWindow(hWnd, nCmdShow); - - MSG msg; - - try { - TriangleApp app(hInstance, hWnd); - - while (true) { - if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - return msg.wParam; - } else { - app.run(); - } - } - } catch (const dxvk::DxvkError& e) { - std::cerr << e.message() << std::endl; - return msg.wParam; - } -} - -LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} diff --git a/tests/d3d9/test_d3d9_nv12.yuv.h b/tests/d3d9/test_d3d9_nv12.yuv.h deleted file mode 100644 index 80a6f96a0..000000000 --- a/tests/d3d9/test_d3d9_nv12.yuv.h +++ /dev/null @@ -1,12803 +0,0 @@ -unsigned char test_d3d9_nv12_yuv[] = { - 0x7a, 0x78, 0x77, 0x75, 0x73, 0x72, 0x72, 0x70, 0x6f, 0x6f, 0x6e, 0x6d, - 0x6d, 0x6d, 0x6c, 0x6c, 0x6a, 0x69, 0x6a, 0x6b, 0x6b, 0x6a, 0x69, 0x69, - 0x6a, 0x6a, 0x6a, 0x6a, 0x69, 0x69, 0x6a, 0x70, 0x76, 0x7a, 0x80, 0x87, - 0x89, 0x8a, 0x8a, 0x8c, 0x8d, 0x8a, 0x87, 0x86, 0x85, 0x85, 0x85, 0x85, - 0x85, 0x86, 0x87, 0x87, 0x87, 0x87, 0x86, 0x85, 0x83, 0x82, 0x81, 0x81, - 0x7f, 0x7c, 0x7b, 0x7a, 0x7a, 0x79, 0x77, 0x76, 0x75, 0x74, 0x72, 0x72, - 0x74, 0x76, 0x76, 0x77, 0x79, 0x7a, 0x7c, 0x7d, 0x7e, 0x80, 0x82, 0x83, - 0x84, 0x84, 0x84, 0x83, 0x83, 0x82, 0x82, 0x82, 0x80, 0x7e, 0x7e, 0x7e, - 0x7d, 0x7b, 0x7a, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x82, 0x82, - 0x84, 0x83, 0x83, 0x82, 0x83, 0x82, 0x83, 0x83, 0x84, 0x84, 0x83, 0x83, - 0x83, 0x83, 0x82, 0x81, 0x82, 0x83, 0x83, 0x83, 0x83, 0x82, 0x81, 0x7f, - 0x7d, 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x81, - 0x82, 0x83, 0x84, 0x84, 0x85, 0x87, 0x86, 0x87, 0x89, 0x8a, 0x8a, 0x8a, - 0x8b, 0x8d, 0x8d, 0x8c, 0x8d, 0x8e, 0x8e, 0x8e, 0x90, 0x90, 0x90, 0x8f, - 0x90, 0x92, 0x93, 0x93, 0x93, 0x95, 0x96, 0x95, 0x95, 0x98, 0x99, 0x99, - 0x9a, 0x9b, 0x9a, 0x9d, 0x9e, 0x9e, 0x9e, 0x9d, 0x9e, 0xa1, 0xa2, 0xa2, - 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xa1, 0x9f, 0x9d, 0x9c, 0x9c, 0x9a, - 0x97, 0x96, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x93, 0x94, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x92, 0x92, 0x92, 0x92, 0x90, 0x90, 0x91, 0x92, - 0x92, 0x92, 0x92, 0x91, 0x91, 0x94, 0x94, 0x93, 0x92, 0x92, 0x90, 0x8f, - 0x91, 0x91, 0x90, 0x8f, 0x90, 0x8f, 0x8d, 0x8a, 0x87, 0x85, 0x84, 0x84, - 0x83, 0x84, 0x88, 0x8a, 0x89, 0x88, 0x85, 0x7d, 0x71, 0x69, 0x65, 0x62, - 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x65, 0x64, 0x63, 0x62, 0x63, - 0x63, 0x62, 0x60, 0x5f, 0x5d, 0x5a, 0x59, 0x56, 0x52, 0x4f, 0x4d, 0x4c, - 0x47, 0x41, 0x3c, 0x39, 0x36, 0x30, 0x27, 0x1d, 0x17, 0x14, 0x12, 0x12, - 0x11, 0x10, 0x11, 0x11, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, 0x79, 0x76, 0x75, 0x74, - 0x72, 0x71, 0x71, 0x71, 0x70, 0x6f, 0x6e, 0x6e, 0x6e, 0x6d, 0x6c, 0x6d, - 0x6d, 0x6c, 0x6c, 0x6b, 0x6a, 0x6a, 0x69, 0x69, 0x69, 0x6a, 0x69, 0x6a, - 0x6a, 0x6a, 0x6e, 0x76, 0x7a, 0x7d, 0x82, 0x87, 0x8a, 0x8c, 0x8d, 0x8e, - 0x8d, 0x8a, 0x89, 0x88, 0x86, 0x87, 0x86, 0x86, 0x86, 0x87, 0x88, 0x88, - 0x89, 0x88, 0x87, 0x85, 0x84, 0x83, 0x82, 0x81, 0x7e, 0x7c, 0x7b, 0x7a, - 0x79, 0x78, 0x76, 0x75, 0x75, 0x74, 0x73, 0x74, 0x76, 0x77, 0x79, 0x79, - 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81, 0x82, 0x84, 0x84, 0x84, 0x82, 0x82, - 0x81, 0x81, 0x80, 0x80, 0x7e, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, - 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x82, 0x82, 0x84, 0x84, 0x83, 0x83, - 0x82, 0x82, 0x83, 0x83, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x82, 0x81, - 0x82, 0x82, 0x82, 0x83, 0x83, 0x82, 0x81, 0x7f, 0x7d, 0x7d, 0x7c, 0x7c, - 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, 0x81, 0x82, 0x83, 0x83, 0x84, - 0x85, 0x87, 0x86, 0x87, 0x88, 0x8a, 0x8a, 0x8a, 0x8b, 0x8d, 0x8d, 0x8c, - 0x8d, 0x8e, 0x8e, 0x8e, 0x90, 0x90, 0x91, 0x90, 0x90, 0x91, 0x92, 0x92, - 0x93, 0x95, 0x95, 0x95, 0x95, 0x97, 0x98, 0x98, 0x98, 0x99, 0x9c, 0x9c, - 0x9c, 0x9d, 0x9e, 0x9d, 0x9e, 0xa0, 0xa1, 0xa1, 0xa3, 0xa4, 0xa4, 0xa4, - 0xa4, 0xa3, 0xa1, 0x9f, 0x9d, 0x9c, 0x9c, 0x9a, 0x97, 0x96, 0x95, 0x94, - 0x95, 0x94, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, - 0x92, 0x92, 0x92, 0x92, 0x90, 0x90, 0x91, 0x92, 0x92, 0x94, 0x93, 0x92, - 0x92, 0x91, 0x92, 0x91, 0x91, 0x90, 0x8e, 0x8e, 0x90, 0x90, 0x91, 0x91, - 0x8f, 0x8f, 0x8e, 0x8b, 0x88, 0x86, 0x86, 0x85, 0x84, 0x86, 0x89, 0x8a, - 0x89, 0x88, 0x84, 0x7c, 0x71, 0x69, 0x66, 0x64, 0x65, 0x65, 0x65, 0x64, - 0x65, 0x65, 0x65, 0x66, 0x65, 0x65, 0x64, 0x62, 0x63, 0x63, 0x62, 0x60, - 0x5c, 0x59, 0x58, 0x56, 0x52, 0x4e, 0x4d, 0x4c, 0x48, 0x43, 0x3e, 0x3b, - 0x37, 0x31, 0x29, 0x20, 0x18, 0x16, 0x13, 0x12, 0x11, 0x11, 0x11, 0x11, - 0x10, 0x11, 0x10, 0x11, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x12, 0x13, - 0x12, 0x12, 0x12, 0x14, 0x79, 0x77, 0x76, 0x75, 0x73, 0x71, 0x72, 0x71, - 0x71, 0x6f, 0x6f, 0x6f, 0x6e, 0x6d, 0x6c, 0x6e, 0x6e, 0x6e, 0x6e, 0x6c, - 0x6b, 0x6b, 0x6a, 0x69, 0x6a, 0x6a, 0x6a, 0x69, 0x6a, 0x6b, 0x70, 0x79, - 0x7e, 0x81, 0x83, 0x86, 0x8a, 0x8e, 0x8f, 0x8f, 0x8e, 0x8a, 0x89, 0x89, - 0x87, 0x87, 0x87, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x88, 0x85, - 0x84, 0x83, 0x82, 0x80, 0x7e, 0x7b, 0x7a, 0x79, 0x77, 0x76, 0x75, 0x76, - 0x75, 0x74, 0x74, 0x75, 0x77, 0x78, 0x79, 0x79, 0x7b, 0x7d, 0x7e, 0x7f, - 0x80, 0x82, 0x82, 0x84, 0x84, 0x83, 0x82, 0x81, 0x81, 0x80, 0x80, 0x7f, - 0x7e, 0x7d, 0x7c, 0x7c, 0x7b, 0x7b, 0x7a, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, - 0x7e, 0x80, 0x81, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x83, 0x83, - 0x84, 0x84, 0x83, 0x83, 0x83, 0x84, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, - 0x83, 0x82, 0x81, 0x7f, 0x7e, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, - 0x7c, 0x7d, 0x7f, 0x82, 0x82, 0x83, 0x83, 0x84, 0x85, 0x87, 0x87, 0x87, - 0x89, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, - 0x8f, 0x8f, 0x8f, 0x90, 0x8f, 0x91, 0x91, 0x93, 0x94, 0x94, 0x94, 0x94, - 0x95, 0x97, 0x97, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, - 0x9f, 0xa1, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xa1, 0x9f, - 0x9e, 0x9c, 0x9b, 0x99, 0x97, 0x96, 0x95, 0x94, 0x93, 0x93, 0x92, 0x92, - 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x92, 0x92, 0x92, 0x92, - 0x90, 0x90, 0x91, 0x92, 0x92, 0x93, 0x92, 0x92, 0x92, 0x91, 0x91, 0x90, - 0x8f, 0x90, 0x8e, 0x8d, 0x8f, 0x90, 0x91, 0x90, 0x91, 0x90, 0x8f, 0x8c, - 0x88, 0x87, 0x87, 0x86, 0x86, 0x87, 0x8b, 0x8c, 0x8a, 0x88, 0x83, 0x7a, - 0x71, 0x69, 0x66, 0x64, 0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x66, 0x67, - 0x66, 0x65, 0x64, 0x62, 0x62, 0x62, 0x63, 0x60, 0x5c, 0x59, 0x58, 0x56, - 0x52, 0x4f, 0x4c, 0x4b, 0x47, 0x43, 0x3f, 0x3b, 0x37, 0x32, 0x2a, 0x20, - 0x18, 0x15, 0x13, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x10, 0x11, 0x11, - 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11, 0x12, 0x13, 0x13, 0x13, 0x13, - 0x7a, 0x77, 0x76, 0x76, 0x74, 0x71, 0x72, 0x72, 0x71, 0x6f, 0x6f, 0x6e, - 0x6d, 0x6c, 0x6c, 0x6e, 0x6e, 0x6e, 0x6e, 0x6d, 0x6b, 0x6b, 0x6a, 0x6a, - 0x6a, 0x6a, 0x6a, 0x69, 0x6a, 0x6c, 0x72, 0x7a, 0x7f, 0x81, 0x84, 0x87, - 0x8b, 0x8e, 0x8f, 0x8f, 0x8e, 0x8b, 0x8a, 0x8a, 0x88, 0x88, 0x87, 0x88, - 0x89, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x88, 0x85, 0x84, 0x83, 0x82, 0x80, - 0x7d, 0x7a, 0x7a, 0x79, 0x77, 0x76, 0x75, 0x75, 0x75, 0x74, 0x74, 0x76, - 0x77, 0x79, 0x79, 0x79, 0x7c, 0x7d, 0x7f, 0x80, 0x81, 0x83, 0x83, 0x84, - 0x84, 0x84, 0x82, 0x80, 0x80, 0x80, 0x7f, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, - 0x7a, 0x7b, 0x7a, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, - 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x83, 0x83, 0x84, 0x83, 0x82, 0x82, - 0x83, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x81, 0x7f, - 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, 0x7e, 0x80, 0x82, - 0x82, 0x83, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x8a, 0x8b, 0x8b, 0x8c, - 0x8c, 0x8c, 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8f, 0x8f, 0x8f, 0x8f, - 0x8f, 0x90, 0x91, 0x93, 0x94, 0x94, 0x93, 0x94, 0x95, 0x96, 0x96, 0x96, - 0x97, 0x99, 0x9a, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa0, 0xa0, 0xa1, - 0xa2, 0xa4, 0xa4, 0xa4, 0xa4, 0xa3, 0xa1, 0xa0, 0x9e, 0x9d, 0x9c, 0x99, - 0x96, 0x95, 0x95, 0x93, 0x93, 0x93, 0x92, 0x92, 0x93, 0x94, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x92, 0x92, 0x92, 0x92, 0x90, 0x90, 0x90, 0x91, - 0x91, 0x93, 0x92, 0x92, 0x92, 0x91, 0x91, 0x90, 0x8f, 0x90, 0x8e, 0x8d, - 0x8f, 0x90, 0x91, 0x90, 0x91, 0x90, 0x90, 0x8d, 0x89, 0x87, 0x87, 0x87, - 0x86, 0x87, 0x8b, 0x8c, 0x8a, 0x88, 0x82, 0x79, 0x70, 0x69, 0x66, 0x65, - 0x66, 0x67, 0x68, 0x68, 0x68, 0x68, 0x67, 0x67, 0x67, 0x66, 0x65, 0x63, - 0x62, 0x62, 0x63, 0x61, 0x5d, 0x5a, 0x59, 0x56, 0x53, 0x4f, 0x4d, 0x4b, - 0x48, 0x44, 0x3f, 0x3b, 0x37, 0x33, 0x2b, 0x21, 0x18, 0x14, 0x12, 0x11, - 0x11, 0x12, 0x12, 0x12, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x13, 0x13, 0x13, 0x14, 0x7a, 0x78, 0x77, 0x76, - 0x75, 0x72, 0x72, 0x73, 0x72, 0x6f, 0x6e, 0x6e, 0x6e, 0x6d, 0x6e, 0x6d, - 0x6e, 0x6e, 0x6e, 0x6e, 0x6d, 0x6b, 0x6b, 0x6b, 0x6b, 0x6a, 0x6b, 0x6a, - 0x6b, 0x6f, 0x75, 0x7c, 0x80, 0x82, 0x85, 0x88, 0x8d, 0x8f, 0x90, 0x8f, - 0x8f, 0x8d, 0x8c, 0x8b, 0x8a, 0x8a, 0x89, 0x8b, 0x8b, 0x8a, 0x8a, 0x89, - 0x8a, 0x8a, 0x89, 0x85, 0x83, 0x82, 0x81, 0x7e, 0x7b, 0x7a, 0x78, 0x78, - 0x76, 0x76, 0x76, 0x77, 0x76, 0x76, 0x76, 0x77, 0x79, 0x7a, 0x7a, 0x7a, - 0x7c, 0x7e, 0x80, 0x81, 0x83, 0x84, 0x84, 0x84, 0x84, 0x83, 0x82, 0x81, - 0x7f, 0x7e, 0x7e, 0x7c, 0x7c, 0x7b, 0x7a, 0x78, 0x78, 0x7a, 0x7a, 0x7b, - 0x7d, 0x7d, 0x7e, 0x7f, 0x7f, 0x7f, 0x80, 0x82, 0x82, 0x82, 0x83, 0x82, - 0x83, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, 0x84, 0x83, - 0x83, 0x84, 0x84, 0x83, 0x83, 0x82, 0x81, 0x7f, 0x7d, 0x7c, 0x7c, 0x7c, - 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7f, 0x81, 0x83, 0x83, 0x83, 0x84, 0x84, - 0x85, 0x86, 0x86, 0x87, 0x89, 0x8b, 0x8c, 0x8c, 0x8c, 0x8c, 0x8e, 0x8f, - 0x8e, 0x8d, 0x8d, 0x8c, 0x8d, 0x8e, 0x8f, 0x8e, 0x8e, 0x8f, 0x91, 0x93, - 0x93, 0x93, 0x93, 0x93, 0x94, 0x95, 0x96, 0x96, 0x97, 0x98, 0x99, 0x9a, - 0x9b, 0x9c, 0x9e, 0x9e, 0x9f, 0x9f, 0x9f, 0xa1, 0xa1, 0xa3, 0xa3, 0xa3, - 0xa3, 0xa3, 0xa2, 0xa0, 0x9e, 0x9e, 0x9c, 0x98, 0x96, 0x94, 0x93, 0x94, - 0x93, 0x92, 0x92, 0x92, 0x92, 0x93, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, - 0x92, 0x92, 0x92, 0x92, 0x91, 0x90, 0x90, 0x90, 0x91, 0x92, 0x93, 0x92, - 0x92, 0x91, 0x91, 0x90, 0x90, 0x90, 0x8e, 0x8d, 0x8f, 0x90, 0x90, 0x90, - 0x91, 0x91, 0x91, 0x8e, 0x8a, 0x88, 0x88, 0x88, 0x87, 0x88, 0x8b, 0x8c, - 0x8a, 0x88, 0x82, 0x79, 0x6f, 0x68, 0x66, 0x65, 0x67, 0x67, 0x69, 0x69, - 0x68, 0x69, 0x67, 0x67, 0x67, 0x67, 0x65, 0x65, 0x63, 0x63, 0x63, 0x62, - 0x5e, 0x5b, 0x59, 0x57, 0x54, 0x51, 0x4e, 0x4c, 0x49, 0x45, 0x40, 0x3a, - 0x37, 0x33, 0x2c, 0x22, 0x18, 0x14, 0x12, 0x11, 0x12, 0x12, 0x12, 0x11, - 0x11, 0x10, 0x10, 0x10, 0x10, 0x11, 0x13, 0x12, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x12, 0x12, 0x15, 0x7b, 0x79, 0x79, 0x78, 0x76, 0x74, 0x72, 0x72, - 0x72, 0x6f, 0x6e, 0x6e, 0x6e, 0x6d, 0x6e, 0x6c, 0x6d, 0x6e, 0x6e, 0x6d, - 0x6d, 0x6b, 0x6b, 0x6b, 0x6a, 0x69, 0x6a, 0x6b, 0x6d, 0x72, 0x79, 0x7f, - 0x82, 0x83, 0x86, 0x8b, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8e, 0x8d, 0x8c, - 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8c, 0x8c, 0x89, 0x8a, 0x8a, 0x88, 0x84, - 0x82, 0x81, 0x80, 0x7d, 0x7b, 0x79, 0x78, 0x77, 0x76, 0x76, 0x77, 0x76, - 0x77, 0x78, 0x78, 0x77, 0x79, 0x7a, 0x7b, 0x7b, 0x7d, 0x7f, 0x81, 0x83, - 0x84, 0x83, 0x83, 0x83, 0x82, 0x82, 0x80, 0x80, 0x7e, 0x7d, 0x7c, 0x7a, - 0x7a, 0x7a, 0x79, 0x77, 0x77, 0x79, 0x7a, 0x7c, 0x7d, 0x7d, 0x7e, 0x7f, - 0x7f, 0x80, 0x80, 0x82, 0x82, 0x82, 0x83, 0x82, 0x83, 0x82, 0x83, 0x83, - 0x83, 0x83, 0x82, 0x82, 0x83, 0x84, 0x84, 0x83, 0x83, 0x84, 0x84, 0x83, - 0x83, 0x82, 0x81, 0x7f, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, - 0x7d, 0x7e, 0x80, 0x82, 0x82, 0x83, 0x85, 0x84, 0x85, 0x86, 0x86, 0x87, - 0x89, 0x8b, 0x8c, 0x8c, 0x8b, 0x8c, 0x8e, 0x8f, 0x8e, 0x8d, 0x8d, 0x8d, - 0x8e, 0x8f, 0x8f, 0x8f, 0x8e, 0x8f, 0x8f, 0x91, 0x91, 0x92, 0x91, 0x92, - 0x93, 0x93, 0x95, 0x95, 0x95, 0x97, 0x97, 0x99, 0x9a, 0x9b, 0x9b, 0x9d, - 0x9d, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa1, 0xa2, 0xa3, 0xa2, 0xa0, - 0x9e, 0x9d, 0x9c, 0x98, 0x96, 0x94, 0x94, 0x94, 0x93, 0x93, 0x93, 0x93, - 0x91, 0x91, 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x92, 0x91, 0x92, 0x92, - 0x90, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, 0x92, 0x92, 0x91, 0x91, 0x90, - 0x90, 0x90, 0x8e, 0x8d, 0x8f, 0x8f, 0x90, 0x91, 0x91, 0x91, 0x90, 0x8e, - 0x8c, 0x8a, 0x8a, 0x89, 0x89, 0x8a, 0x8c, 0x8c, 0x8a, 0x88, 0x83, 0x7a, - 0x70, 0x68, 0x66, 0x66, 0x68, 0x69, 0x6a, 0x6a, 0x6a, 0x6a, 0x69, 0x68, - 0x68, 0x68, 0x66, 0x65, 0x64, 0x64, 0x64, 0x62, 0x5e, 0x5c, 0x5a, 0x57, - 0x54, 0x52, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x3b, 0x37, 0x31, 0x2c, 0x23, - 0x19, 0x14, 0x12, 0x11, 0x12, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x11, 0x12, 0x14, 0x15, - 0x7b, 0x79, 0x79, 0x78, 0x76, 0x74, 0x73, 0x72, 0x71, 0x70, 0x6f, 0x6f, - 0x6e, 0x6d, 0x6d, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, 0x6c, 0x6c, 0x6d, 0x6c, - 0x6b, 0x6a, 0x6a, 0x6d, 0x71, 0x76, 0x7d, 0x81, 0x82, 0x83, 0x88, 0x8d, - 0x90, 0x90, 0x90, 0x90, 0x90, 0x8e, 0x8e, 0x8d, 0x8c, 0x8c, 0x8d, 0x8d, - 0x8d, 0x8d, 0x8c, 0x89, 0x88, 0x87, 0x86, 0x84, 0x82, 0x80, 0x7f, 0x7c, - 0x7a, 0x78, 0x77, 0x76, 0x76, 0x77, 0x77, 0x76, 0x76, 0x77, 0x79, 0x79, - 0x79, 0x7a, 0x7b, 0x7c, 0x7e, 0x7f, 0x81, 0x82, 0x82, 0x82, 0x81, 0x81, - 0x81, 0x81, 0x80, 0x7e, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x77, 0x77, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x80, 0x82, 0x82, - 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x83, 0x82, 0x82, - 0x82, 0x84, 0x84, 0x82, 0x81, 0x82, 0x83, 0x83, 0x83, 0x83, 0x81, 0x80, - 0x7e, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7f, 0x82, - 0x83, 0x84, 0x85, 0x85, 0x86, 0x88, 0x87, 0x87, 0x89, 0x8a, 0x8b, 0x8c, - 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, - 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x91, 0x90, 0x90, 0x91, 0x93, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9d, 0x9d, 0x9d, 0x9e, - 0xa0, 0xa0, 0xa2, 0xa2, 0xa2, 0xa2, 0xa1, 0xa0, 0x9f, 0x9e, 0x9c, 0x9a, - 0x97, 0x96, 0x95, 0x94, 0x92, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x94, - 0x95, 0x95, 0x95, 0x94, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x91, - 0x93, 0x94, 0x93, 0x93, 0x93, 0x91, 0x91, 0x90, 0x90, 0x91, 0x90, 0x8e, - 0x8e, 0x8f, 0x90, 0x8f, 0x90, 0x91, 0x90, 0x8e, 0x8d, 0x8c, 0x8c, 0x8c, - 0x8b, 0x8c, 0x8d, 0x8c, 0x8a, 0x88, 0x83, 0x79, 0x6f, 0x69, 0x68, 0x69, - 0x6b, 0x6b, 0x6b, 0x6b, 0x6a, 0x6b, 0x6a, 0x69, 0x6a, 0x6a, 0x68, 0x67, - 0x67, 0x66, 0x65, 0x62, 0x5f, 0x5d, 0x5b, 0x5a, 0x57, 0x52, 0x50, 0x4e, - 0x4a, 0x46, 0x41, 0x3c, 0x38, 0x33, 0x2c, 0x24, 0x1a, 0x16, 0x13, 0x12, - 0x11, 0x11, 0x10, 0x11, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, - 0x12, 0x11, 0x12, 0x11, 0x13, 0x13, 0x14, 0x14, 0x7c, 0x7a, 0x79, 0x78, - 0x76, 0x76, 0x75, 0x73, 0x72, 0x71, 0x70, 0x70, 0x6e, 0x6d, 0x6c, 0x6c, - 0x6d, 0x6e, 0x6e, 0x6d, 0x6d, 0x6c, 0x6d, 0x6e, 0x6d, 0x6b, 0x6c, 0x71, - 0x74, 0x7a, 0x80, 0x82, 0x83, 0x85, 0x8a, 0x8f, 0x91, 0x90, 0x90, 0x90, - 0x90, 0x8e, 0x8e, 0x8e, 0x8d, 0x8e, 0x8e, 0x8e, 0x8d, 0x8c, 0x8a, 0x89, - 0x87, 0x86, 0x85, 0x82, 0x81, 0x80, 0x7e, 0x7c, 0x79, 0x78, 0x77, 0x76, - 0x77, 0x78, 0x78, 0x76, 0x77, 0x78, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, - 0x7e, 0x7f, 0x81, 0x82, 0x82, 0x81, 0x80, 0x80, 0x81, 0x80, 0x7f, 0x7b, - 0x7b, 0x7a, 0x79, 0x78, 0x77, 0x76, 0x76, 0x76, 0x78, 0x7a, 0x7b, 0x7b, - 0x7c, 0x7c, 0x7c, 0x7c, 0x7e, 0x7f, 0x82, 0x83, 0x82, 0x82, 0x82, 0x83, - 0x83, 0x83, 0x83, 0x81, 0x81, 0x83, 0x84, 0x84, 0x83, 0x83, 0x83, 0x82, - 0x81, 0x82, 0x81, 0x82, 0x83, 0x82, 0x81, 0x7f, 0x7e, 0x7d, 0x7d, 0x7d, - 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, 0x7f, 0x7f, 0x81, 0x83, 0x84, 0x85, 0x85, - 0x87, 0x88, 0x88, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8d, 0x8d, - 0x8d, 0x8c, 0x8d, 0x8f, 0x90, 0x90, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x8f, 0x90, 0x90, 0x90, 0x92, 0x92, 0x93, 0x94, 0x96, 0x96, 0x97, - 0x98, 0x99, 0x99, 0x9a, 0x9c, 0x9c, 0x9c, 0x9d, 0x9f, 0x9f, 0xa0, 0xa1, - 0xa1, 0xa1, 0xa0, 0x9f, 0x9f, 0x9f, 0x9d, 0x9b, 0x97, 0x96, 0x96, 0x94, - 0x92, 0x92, 0x92, 0x93, 0x93, 0x92, 0x92, 0x94, 0x95, 0x96, 0x96, 0x96, - 0x94, 0x94, 0x93, 0x92, 0x93, 0x93, 0x92, 0x91, 0x93, 0x94, 0x93, 0x92, - 0x92, 0x91, 0x91, 0x90, 0x90, 0x91, 0x91, 0x8e, 0x8e, 0x8e, 0x90, 0x90, - 0x91, 0x91, 0x90, 0x8f, 0x8d, 0x8c, 0x8e, 0x8e, 0x8d, 0x8e, 0x8e, 0x8c, - 0x8a, 0x87, 0x82, 0x79, 0x6f, 0x69, 0x68, 0x69, 0x6b, 0x6c, 0x6b, 0x6b, - 0x69, 0x69, 0x6a, 0x6a, 0x69, 0x69, 0x68, 0x68, 0x69, 0x67, 0x65, 0x63, - 0x60, 0x5e, 0x5d, 0x5c, 0x58, 0x53, 0x51, 0x4f, 0x4a, 0x46, 0x43, 0x3d, - 0x39, 0x34, 0x2c, 0x24, 0x1b, 0x16, 0x13, 0x11, 0x11, 0x10, 0x11, 0x11, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x13, 0x14, 0x13, 0x14, 0x7c, 0x7a, 0x79, 0x79, 0x77, 0x76, 0x75, 0x73, - 0x72, 0x71, 0x70, 0x70, 0x6f, 0x6d, 0x6c, 0x6c, 0x6c, 0x6e, 0x6e, 0x6e, - 0x6d, 0x6c, 0x6e, 0x6e, 0x6d, 0x6c, 0x6e, 0x72, 0x76, 0x7b, 0x82, 0x83, - 0x84, 0x87, 0x8c, 0x90, 0x91, 0x90, 0x90, 0x91, 0x91, 0x8f, 0x8f, 0x8f, - 0x8d, 0x8e, 0x8e, 0x8e, 0x8d, 0x8b, 0x8a, 0x88, 0x86, 0x86, 0x84, 0x82, - 0x80, 0x7f, 0x7e, 0x7b, 0x78, 0x77, 0x76, 0x77, 0x78, 0x78, 0x78, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7e, 0x7f, 0x81, 0x82, - 0x81, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7d, 0x7a, 0x7a, 0x79, 0x78, 0x78, - 0x76, 0x75, 0x75, 0x75, 0x78, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, 0x7d, - 0x7e, 0x80, 0x82, 0x83, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x82, 0x82, - 0x82, 0x83, 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x82, - 0x83, 0x82, 0x81, 0x7f, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, - 0x7e, 0x7f, 0x7f, 0x81, 0x83, 0x84, 0x85, 0x85, 0x87, 0x88, 0x88, 0x88, - 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x90, - 0x90, 0x90, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x91, 0x90, 0x92, 0x93, 0x95, 0x96, 0x97, 0x97, 0x97, 0x98, 0x9a, - 0x9c, 0x9c, 0x9b, 0x9c, 0x9e, 0x9e, 0xa0, 0xa0, 0xa1, 0xa0, 0xa0, 0x9f, - 0x9f, 0x9f, 0x9d, 0x9b, 0x97, 0x96, 0x95, 0x94, 0x92, 0x92, 0x92, 0x93, - 0x93, 0x92, 0x92, 0x94, 0x95, 0x96, 0x96, 0x96, 0x95, 0x94, 0x94, 0x93, - 0x93, 0x93, 0x92, 0x91, 0x93, 0x94, 0x93, 0x93, 0x93, 0x91, 0x91, 0x90, - 0x90, 0x91, 0x90, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x91, 0x91, 0x91, 0x8f, - 0x8e, 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, 0x8f, 0x8c, 0x89, 0x86, 0x81, 0x79, - 0x6f, 0x69, 0x68, 0x69, 0x6b, 0x6c, 0x6b, 0x6a, 0x69, 0x69, 0x6a, 0x6a, - 0x69, 0x69, 0x69, 0x69, 0x69, 0x68, 0x64, 0x63, 0x61, 0x5f, 0x5e, 0x5c, - 0x58, 0x54, 0x51, 0x4f, 0x4b, 0x46, 0x43, 0x3e, 0x3a, 0x35, 0x2d, 0x24, - 0x1b, 0x16, 0x13, 0x11, 0x10, 0x11, 0x11, 0x12, 0x10, 0x10, 0x10, 0x10, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x14, 0x14, 0x13, 0x14, - 0x7d, 0x7b, 0x79, 0x78, 0x78, 0x77, 0x75, 0x75, 0x73, 0x72, 0x71, 0x71, - 0x6f, 0x6e, 0x6d, 0x6d, 0x6d, 0x6e, 0x6f, 0x6e, 0x6d, 0x6e, 0x6d, 0x6d, - 0x6e, 0x6d, 0x6f, 0x75, 0x79, 0x7e, 0x82, 0x83, 0x86, 0x89, 0x8c, 0x90, - 0x91, 0x90, 0x90, 0x91, 0x91, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, - 0x8d, 0x8b, 0x89, 0x87, 0x86, 0x85, 0x84, 0x81, 0x7f, 0x7d, 0x7c, 0x7a, - 0x79, 0x76, 0x76, 0x76, 0x78, 0x79, 0x78, 0x78, 0x79, 0x7a, 0x7b, 0x7b, - 0x7b, 0x7d, 0x7d, 0x7d, 0x7e, 0x7f, 0x81, 0x82, 0x81, 0x7f, 0x7e, 0x7e, - 0x7e, 0x7d, 0x7b, 0x78, 0x78, 0x78, 0x77, 0x77, 0x75, 0x74, 0x74, 0x75, - 0x78, 0x7a, 0x7b, 0x7b, 0x7c, 0x7c, 0x7d, 0x7f, 0x7f, 0x80, 0x82, 0x82, - 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x84, 0x84, 0x84, - 0x84, 0x83, 0x83, 0x83, 0x83, 0x82, 0x81, 0x82, 0x83, 0x81, 0x81, 0x80, - 0x7f, 0x7e, 0x7e, 0x7f, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7f, 0x80, 0x82, - 0x84, 0x84, 0x85, 0x85, 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8b, 0x8c, - 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8d, 0x8f, 0x90, 0x90, 0x90, 0x8f, 0x90, - 0x90, 0x90, 0x90, 0x8e, 0x8f, 0x90, 0x90, 0x8f, 0x8f, 0x90, 0x90, 0x92, - 0x92, 0x94, 0x96, 0x97, 0x96, 0x96, 0x98, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, - 0x9d, 0x9d, 0x9f, 0x9f, 0xa0, 0x9f, 0xa0, 0x9f, 0x9f, 0x9e, 0x9c, 0x99, - 0x97, 0x97, 0x96, 0x95, 0x93, 0x92, 0x93, 0x93, 0x93, 0x93, 0x93, 0x95, - 0x95, 0x95, 0x96, 0x96, 0x95, 0x95, 0x94, 0x93, 0x94, 0x93, 0x92, 0x91, - 0x92, 0x94, 0x94, 0x94, 0x94, 0x91, 0x91, 0x90, 0x8f, 0x90, 0x8f, 0x91, - 0x91, 0x91, 0x91, 0x90, 0x91, 0x91, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, - 0x8f, 0x90, 0x90, 0x8c, 0x89, 0x85, 0x80, 0x77, 0x6e, 0x68, 0x67, 0x68, - 0x6b, 0x6c, 0x6a, 0x69, 0x69, 0x69, 0x6a, 0x69, 0x69, 0x6a, 0x6a, 0x69, - 0x69, 0x68, 0x65, 0x64, 0x62, 0x61, 0x5f, 0x5e, 0x59, 0x55, 0x50, 0x4e, - 0x4b, 0x47, 0x43, 0x3f, 0x3b, 0x36, 0x2e, 0x25, 0x1c, 0x17, 0x12, 0x11, - 0x11, 0x11, 0x11, 0x12, 0x10, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x13, - 0x13, 0x11, 0x12, 0x13, 0x12, 0x12, 0x13, 0x13, 0x7d, 0x7b, 0x7a, 0x79, - 0x77, 0x76, 0x74, 0x74, 0x73, 0x72, 0x71, 0x72, 0x70, 0x6f, 0x6e, 0x6e, - 0x6f, 0x6f, 0x6f, 0x6e, 0x6e, 0x6e, 0x6d, 0x6d, 0x6d, 0x6e, 0x73, 0x78, - 0x7c, 0x7f, 0x83, 0x85, 0x88, 0x8b, 0x8e, 0x8e, 0x91, 0x91, 0x91, 0x91, - 0x91, 0x90, 0x91, 0x91, 0x90, 0x91, 0x8f, 0x8e, 0x8d, 0x8a, 0x89, 0x87, - 0x86, 0x85, 0x83, 0x80, 0x7e, 0x7c, 0x7b, 0x7a, 0x7a, 0x77, 0x76, 0x77, - 0x79, 0x7a, 0x79, 0x7a, 0x7b, 0x7b, 0x7a, 0x7a, 0x7b, 0x7d, 0x7d, 0x7d, - 0x7e, 0x7f, 0x81, 0x81, 0x80, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x79, 0x77, - 0x76, 0x77, 0x76, 0x74, 0x74, 0x74, 0x74, 0x76, 0x77, 0x7a, 0x7a, 0x7b, - 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x83, 0x82, - 0x83, 0x83, 0x83, 0x84, 0x84, 0x83, 0x82, 0x82, 0x82, 0x84, 0x84, 0x83, - 0x83, 0x83, 0x82, 0x83, 0x83, 0x82, 0x81, 0x80, 0x7f, 0x7f, 0x80, 0x80, - 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x80, 0x82, 0x83, 0x84, 0x85, 0x85, - 0x87, 0x88, 0x89, 0x89, 0x8a, 0x8b, 0x8c, 0x8b, 0x8c, 0x8c, 0x8e, 0x8f, - 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x90, 0x90, 0x90, 0x8f, 0x8e, - 0x8e, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x95, 0x96, - 0x96, 0x96, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9d, 0x9e, - 0x9e, 0x9f, 0xa0, 0x9f, 0x9f, 0x9e, 0x9d, 0x9a, 0x99, 0x98, 0x98, 0x96, - 0x93, 0x92, 0x93, 0x93, 0x93, 0x93, 0x94, 0x94, 0x94, 0x94, 0x95, 0x96, - 0x96, 0x96, 0x95, 0x93, 0x94, 0x94, 0x93, 0x92, 0x93, 0x94, 0x94, 0x94, - 0x94, 0x93, 0x92, 0x90, 0x8f, 0x8e, 0x8f, 0x91, 0x92, 0x92, 0x91, 0x90, - 0x90, 0x8f, 0x8f, 0x90, 0x8f, 0x90, 0x8f, 0x8f, 0x8f, 0x91, 0x90, 0x8c, - 0x89, 0x86, 0x80, 0x77, 0x6e, 0x69, 0x68, 0x6a, 0x6c, 0x6c, 0x6b, 0x6b, - 0x6d, 0x6d, 0x6b, 0x6a, 0x6a, 0x6a, 0x6b, 0x6a, 0x69, 0x68, 0x66, 0x65, - 0x62, 0x62, 0x61, 0x5e, 0x5a, 0x56, 0x51, 0x4f, 0x4b, 0x48, 0x43, 0x40, - 0x3d, 0x38, 0x31, 0x27, 0x1e, 0x18, 0x14, 0x11, 0x12, 0x11, 0x11, 0x12, - 0x12, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x12, 0x13, 0x13, 0x12, 0x13, - 0x13, 0x13, 0x12, 0x14, 0x7e, 0x7b, 0x7b, 0x7a, 0x79, 0x77, 0x75, 0x75, - 0x75, 0x74, 0x72, 0x71, 0x71, 0x70, 0x6f, 0x6e, 0x6f, 0x6e, 0x6f, 0x70, - 0x6f, 0x6d, 0x6d, 0x6d, 0x6e, 0x6f, 0x76, 0x7c, 0x7f, 0x82, 0x84, 0x87, - 0x8b, 0x8d, 0x8f, 0x8f, 0x90, 0x91, 0x91, 0x91, 0x92, 0x92, 0x93, 0x93, - 0x92, 0x90, 0x8e, 0x8d, 0x8c, 0x8a, 0x88, 0x86, 0x85, 0x83, 0x82, 0x7f, - 0x7d, 0x7b, 0x7a, 0x7a, 0x7a, 0x78, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, - 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x7d, 0x7e, 0x7f, 0x81, 0x81, - 0x80, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x75, 0x74, 0x73, 0x73, 0x73, - 0x73, 0x74, 0x74, 0x76, 0x76, 0x78, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, - 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x82, 0x84, 0x84, 0x84, - 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, 0x84, 0x83, 0x83, 0x83, 0x82, 0x83, - 0x84, 0x84, 0x83, 0x82, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7e, 0x7f, 0x7e, - 0x7e, 0x7f, 0x81, 0x84, 0x84, 0x84, 0x85, 0x85, 0x87, 0x87, 0x88, 0x8a, - 0x8b, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8e, 0x8f, 0x8f, 0x90, 0x90, 0x8f, - 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x8e, 0x8c, 0x8d, 0x8d, 0x8c, - 0x8c, 0x8c, 0x8d, 0x8f, 0x8f, 0x91, 0x94, 0x95, 0x94, 0x95, 0x96, 0x98, - 0x98, 0x99, 0x9a, 0x99, 0x9a, 0x99, 0x9b, 0x9d, 0x9d, 0x9d, 0x9e, 0x9f, - 0x9f, 0x9e, 0x9d, 0x9c, 0x9a, 0x99, 0x99, 0x97, 0x94, 0x92, 0x92, 0x92, - 0x93, 0x93, 0x94, 0x94, 0x94, 0x94, 0x95, 0x96, 0x96, 0x96, 0x94, 0x93, - 0x94, 0x93, 0x93, 0x93, 0x92, 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x92, - 0x91, 0x8f, 0x90, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x90, - 0x91, 0x90, 0x8f, 0x8f, 0x91, 0x93, 0x91, 0x8c, 0x87, 0x84, 0x7e, 0x75, - 0x6d, 0x6a, 0x6a, 0x6b, 0x6d, 0x6c, 0x6d, 0x6d, 0x6e, 0x6d, 0x6e, 0x6d, - 0x6d, 0x6c, 0x6b, 0x6b, 0x6b, 0x6a, 0x67, 0x65, 0x63, 0x62, 0x62, 0x5f, - 0x5a, 0x57, 0x53, 0x51, 0x4d, 0x49, 0x45, 0x41, 0x3f, 0x39, 0x32, 0x28, - 0x20, 0x1b, 0x15, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x11, 0x11, - 0x12, 0x12, 0x11, 0x12, 0x13, 0x13, 0x11, 0x13, 0x13, 0x12, 0x13, 0x11, - 0x7f, 0x7c, 0x7b, 0x7b, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, - 0x70, 0x70, 0x6f, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x6f, 0x6c, 0x6c, 0x6d, - 0x6e, 0x71, 0x78, 0x7d, 0x80, 0x83, 0x85, 0x89, 0x8d, 0x8f, 0x8f, 0x8f, - 0x8f, 0x90, 0x91, 0x92, 0x93, 0x93, 0x93, 0x93, 0x91, 0x8f, 0x8e, 0x8d, - 0x8b, 0x89, 0x87, 0x84, 0x83, 0x82, 0x80, 0x7e, 0x7b, 0x7b, 0x7a, 0x7a, - 0x7a, 0x79, 0x79, 0x79, 0x7a, 0x7b, 0x7b, 0x7b, 0x7d, 0x7d, 0x7d, 0x7d, - 0x7e, 0x7e, 0x7e, 0x7f, 0x7e, 0x80, 0x81, 0x80, 0x7f, 0x7c, 0x7b, 0x7b, - 0x7a, 0x79, 0x77, 0x74, 0x73, 0x72, 0x72, 0x71, 0x72, 0x73, 0x74, 0x76, - 0x76, 0x78, 0x7a, 0x7b, 0x7b, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x80, - 0x82, 0x82, 0x82, 0x81, 0x83, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, - 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x83, 0x84, 0x84, 0x84, 0x82, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x82, 0x83, - 0x84, 0x84, 0x85, 0x85, 0x87, 0x88, 0x89, 0x8b, 0x8b, 0x8c, 0x8b, 0x8b, - 0x8c, 0x8d, 0x8d, 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x8f, 0x8e, 0x8e, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x94, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x99, 0x99, - 0x98, 0x9a, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, - 0x9b, 0x9a, 0x99, 0x98, 0x95, 0x94, 0x93, 0x93, 0x92, 0x92, 0x94, 0x94, - 0x95, 0x94, 0x95, 0x95, 0x96, 0x96, 0x95, 0x94, 0x93, 0x94, 0x94, 0x94, - 0x93, 0x93, 0x93, 0x94, 0x95, 0x94, 0x93, 0x92, 0x91, 0x91, 0x90, 0x92, - 0x92, 0x92, 0x91, 0x91, 0x90, 0x8f, 0x8f, 0x8f, 0x91, 0x91, 0x91, 0x92, - 0x92, 0x94, 0x91, 0x8c, 0x87, 0x83, 0x7c, 0x75, 0x6d, 0x6b, 0x6b, 0x6c, - 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6e, 0x6d, 0x6d, 0x6c, 0x6c, 0x6b, - 0x6b, 0x6a, 0x67, 0x66, 0x63, 0x62, 0x62, 0x5e, 0x5c, 0x57, 0x55, 0x53, - 0x50, 0x4b, 0x45, 0x42, 0x40, 0x3a, 0x32, 0x2a, 0x22, 0x1b, 0x14, 0x11, - 0x10, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, - 0x11, 0x12, 0x11, 0x13, 0x13, 0x13, 0x12, 0x12, 0x7f, 0x7c, 0x7c, 0x7b, - 0x79, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, 0x70, 0x70, 0x6f, - 0x70, 0x6f, 0x6f, 0x70, 0x6f, 0x6c, 0x6c, 0x6d, 0x6e, 0x73, 0x7a, 0x7f, - 0x81, 0x83, 0x86, 0x8b, 0x8e, 0x90, 0x90, 0x8f, 0x8f, 0x90, 0x91, 0x93, - 0x93, 0x93, 0x93, 0x92, 0x90, 0x8e, 0x8d, 0x8c, 0x8b, 0x88, 0x86, 0x84, - 0x82, 0x81, 0x7f, 0x7d, 0x7b, 0x7a, 0x7a, 0x7b, 0x7a, 0x7b, 0x7a, 0x7a, - 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7f, 0x7f, - 0x7f, 0x80, 0x81, 0x80, 0x7f, 0x7b, 0x7a, 0x7a, 0x7a, 0x79, 0x76, 0x74, - 0x73, 0x72, 0x71, 0x70, 0x71, 0x73, 0x75, 0x76, 0x77, 0x78, 0x7a, 0x7a, - 0x7a, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x81, 0x81, 0x82, 0x82, 0x82, 0x81, - 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x83, 0x84, 0x84, - 0x84, 0x84, 0x83, 0x83, 0x84, 0x84, 0x84, 0x82, 0x81, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x7f, 0x81, 0x82, 0x83, 0x84, 0x85, 0x85, 0x85, - 0x87, 0x89, 0x89, 0x8b, 0x8c, 0x8c, 0x8b, 0x8b, 0x8c, 0x8d, 0x8d, 0x8e, - 0x8e, 0x8f, 0x8f, 0x90, 0x8f, 0x8f, 0x8f, 0x90, 0x8f, 0x8e, 0x8d, 0x8d, - 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8d, 0x8f, 0x8f, 0x91, 0x91, 0x93, - 0x94, 0x94, 0x96, 0x97, 0x98, 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x9a, - 0x9b, 0x9b, 0x9c, 0x9c, 0x9d, 0x9d, 0x9c, 0x9d, 0x9b, 0x9a, 0x9a, 0x98, - 0x96, 0x95, 0x93, 0x92, 0x91, 0x91, 0x93, 0x94, 0x94, 0x95, 0x95, 0x94, - 0x96, 0x96, 0x96, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x93, 0x92, 0x93, - 0x94, 0x94, 0x93, 0x91, 0x91, 0x91, 0x91, 0x92, 0x93, 0x93, 0x92, 0x92, - 0x90, 0x8f, 0x8e, 0x8e, 0x91, 0x91, 0x92, 0x93, 0x93, 0x94, 0x91, 0x8c, - 0x87, 0x83, 0x7c, 0x75, 0x6d, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, - 0x6e, 0x6e, 0x6f, 0x6d, 0x6d, 0x6d, 0x6d, 0x6b, 0x6b, 0x6a, 0x68, 0x67, - 0x64, 0x63, 0x62, 0x5f, 0x5c, 0x58, 0x56, 0x55, 0x51, 0x4c, 0x46, 0x42, - 0x40, 0x3a, 0x33, 0x2b, 0x21, 0x1c, 0x14, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x11, 0x12, 0x11, 0x13, - 0x13, 0x13, 0x12, 0x13, 0x80, 0x7d, 0x7d, 0x7c, 0x7a, 0x78, 0x78, 0x77, - 0x76, 0x75, 0x73, 0x72, 0x71, 0x71, 0x72, 0x71, 0x71, 0x6f, 0x6e, 0x6f, - 0x6f, 0x6d, 0x6c, 0x6d, 0x6f, 0x75, 0x7c, 0x81, 0x83, 0x85, 0x88, 0x8d, - 0x90, 0x90, 0x8f, 0x8f, 0x8e, 0x8f, 0x90, 0x93, 0x93, 0x93, 0x93, 0x93, - 0x91, 0x8e, 0x8c, 0x8b, 0x89, 0x87, 0x84, 0x83, 0x81, 0x80, 0x7e, 0x7d, - 0x7a, 0x79, 0x79, 0x79, 0x7b, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, - 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x7f, 0x80, 0x80, 0x7f, - 0x7e, 0x7c, 0x7b, 0x79, 0x79, 0x77, 0x75, 0x73, 0x71, 0x70, 0x6f, 0x70, - 0x72, 0x73, 0x75, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7a, 0x7d, 0x7f, 0x80, - 0x80, 0x80, 0x82, 0x82, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x82, 0x83, - 0x82, 0x82, 0x82, 0x82, 0x82, 0x84, 0x83, 0x85, 0x85, 0x85, 0x85, 0x84, - 0x85, 0x84, 0x84, 0x83, 0x81, 0x81, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, - 0x81, 0x82, 0x83, 0x85, 0x85, 0x85, 0x86, 0x86, 0x88, 0x8a, 0x8a, 0x8c, - 0x8c, 0x8c, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8f, 0x8f, 0x8f, - 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x8d, 0x8d, 0x8d, 0x8d, 0x8b, 0x8b, 0x8b, - 0x8b, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x96, - 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, 0x98, 0x99, 0x99, 0x9a, 0x9a, 0x9b, - 0x9d, 0x9d, 0x9d, 0x9d, 0x9b, 0x9a, 0x9a, 0x99, 0x97, 0x96, 0x94, 0x93, - 0x92, 0x92, 0x92, 0x93, 0x94, 0x95, 0x95, 0x95, 0x96, 0x97, 0x95, 0x96, - 0x95, 0x95, 0x95, 0x95, 0x95, 0x93, 0x92, 0x93, 0x94, 0x93, 0x93, 0x92, - 0x91, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, 0x90, 0x8f, 0x8e, 0x8f, - 0x91, 0x92, 0x93, 0x93, 0x93, 0x93, 0x91, 0x8b, 0x86, 0x81, 0x7b, 0x74, - 0x6d, 0x6c, 0x6c, 0x6d, 0x6e, 0x6d, 0x6e, 0x6f, 0x6f, 0x6e, 0x6e, 0x6d, - 0x6d, 0x6c, 0x6c, 0x6b, 0x6b, 0x6a, 0x68, 0x68, 0x66, 0x65, 0x63, 0x60, - 0x5d, 0x59, 0x57, 0x55, 0x52, 0x4d, 0x46, 0x42, 0x40, 0x3a, 0x34, 0x2b, - 0x22, 0x1c, 0x15, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x11, - 0x11, 0x12, 0x11, 0x13, 0x13, 0x11, 0x11, 0x12, 0x12, 0x12, 0x13, 0x11, - 0x81, 0x7e, 0x7d, 0x7c, 0x7b, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, - 0x72, 0x72, 0x73, 0x72, 0x72, 0x71, 0x70, 0x71, 0x70, 0x6f, 0x6e, 0x6f, - 0x70, 0x76, 0x7e, 0x83, 0x86, 0x87, 0x8a, 0x8d, 0x90, 0x90, 0x8f, 0x8f, - 0x8f, 0x8f, 0x90, 0x92, 0x94, 0x93, 0x92, 0x92, 0x91, 0x8e, 0x8c, 0x89, - 0x88, 0x86, 0x84, 0x81, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7a, 0x7a, - 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, - 0x7e, 0x7f, 0x7f, 0x80, 0x80, 0x7f, 0x7e, 0x7d, 0x7c, 0x7c, 0x7a, 0x79, - 0x78, 0x76, 0x73, 0x71, 0x70, 0x6f, 0x6f, 0x70, 0x72, 0x74, 0x75, 0x77, - 0x77, 0x78, 0x78, 0x79, 0x79, 0x7c, 0x7e, 0x80, 0x80, 0x7f, 0x81, 0x81, - 0x80, 0x7f, 0x7f, 0x81, 0x81, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, - 0x84, 0x84, 0x84, 0x85, 0x86, 0x86, 0x86, 0x85, 0x84, 0x84, 0x83, 0x82, - 0x83, 0x82, 0x81, 0x81, 0x82, 0x81, 0x81, 0x82, 0x82, 0x83, 0x84, 0x85, - 0x85, 0x85, 0x86, 0x86, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8c, 0x8c, 0x8c, - 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8e, 0x8e, 0x8f, 0x8f, - 0x8f, 0x8e, 0x8d, 0x8d, 0x8c, 0x8b, 0x8a, 0x8a, 0x89, 0x8a, 0x8b, 0x8c, - 0x8c, 0x8d, 0x8e, 0x90, 0x92, 0x93, 0x93, 0x95, 0x96, 0x95, 0x95, 0x96, - 0x97, 0x96, 0x97, 0x98, 0x99, 0x99, 0x99, 0x9a, 0x9c, 0x9c, 0x9c, 0x9c, - 0x9b, 0x99, 0x99, 0x99, 0x97, 0x96, 0x95, 0x94, 0x95, 0x94, 0x93, 0x93, - 0x94, 0x95, 0x95, 0x95, 0x96, 0x96, 0x95, 0x95, 0x96, 0x96, 0x96, 0x95, - 0x95, 0x94, 0x92, 0x93, 0x94, 0x94, 0x95, 0x94, 0x94, 0x94, 0x94, 0x93, - 0x93, 0x93, 0x93, 0x92, 0x90, 0x8f, 0x8e, 0x8e, 0x90, 0x92, 0x93, 0x93, - 0x94, 0x94, 0x8f, 0x89, 0x84, 0x80, 0x79, 0x72, 0x6d, 0x6c, 0x6d, 0x6e, - 0x6e, 0x6e, 0x6f, 0x70, 0x70, 0x6e, 0x6f, 0x6e, 0x6d, 0x6d, 0x6d, 0x6b, - 0x6c, 0x6c, 0x6b, 0x69, 0x67, 0x66, 0x64, 0x62, 0x5f, 0x5a, 0x58, 0x56, - 0x52, 0x4e, 0x49, 0x45, 0x41, 0x3b, 0x34, 0x2a, 0x21, 0x1b, 0x14, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 0x11, 0x12, 0x13, - 0x13, 0x13, 0x11, 0x12, 0x13, 0x13, 0x13, 0x11, 0x80, 0x7e, 0x7d, 0x7d, - 0x7c, 0x79, 0x7a, 0x79, 0x78, 0x74, 0x73, 0x73, 0x73, 0x73, 0x73, 0x71, - 0x71, 0x70, 0x70, 0x71, 0x71, 0x70, 0x6e, 0x6f, 0x71, 0x79, 0x81, 0x85, - 0x86, 0x87, 0x8a, 0x8e, 0x90, 0x90, 0x8f, 0x90, 0x90, 0x8f, 0x90, 0x91, - 0x92, 0x92, 0x92, 0x92, 0x91, 0x8e, 0x8c, 0x89, 0x87, 0x85, 0x81, 0x80, - 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, - 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7b, 0x7c, 0x7d, 0x7f, 0x7f, 0x80, - 0x80, 0x7f, 0x7e, 0x7e, 0x7c, 0x7c, 0x7a, 0x78, 0x76, 0x74, 0x73, 0x70, - 0x6f, 0x6f, 0x6f, 0x70, 0x72, 0x75, 0x76, 0x77, 0x77, 0x77, 0x78, 0x7a, - 0x7b, 0x7b, 0x7c, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x80, - 0x81, 0x80, 0x81, 0x82, 0x81, 0x82, 0x84, 0x86, 0x86, 0x86, 0x85, 0x86, - 0x87, 0x85, 0x85, 0x86, 0x86, 0x85, 0x84, 0x83, 0x83, 0x83, 0x84, 0x84, - 0x83, 0x82, 0x81, 0x82, 0x83, 0x84, 0x84, 0x85, 0x86, 0x86, 0x86, 0x86, - 0x88, 0x8a, 0x8b, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8d, - 0x8d, 0x8e, 0x8d, 0x8d, 0x8d, 0x8e, 0x8f, 0x8d, 0x8d, 0x8c, 0x8c, 0x8b, - 0x8b, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x8a, 0x8b, 0x8c, 0x8c, 0x8e, 0x8f, - 0x90, 0x91, 0x93, 0x93, 0x93, 0x93, 0x94, 0x95, 0x96, 0x96, 0x96, 0x96, - 0x96, 0x98, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9b, 0x9a, 0x9a, 0x99, - 0x98, 0x96, 0x95, 0x95, 0x95, 0x94, 0x93, 0x94, 0x94, 0x94, 0x95, 0x94, - 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x94, 0x94, 0x95, 0x95, 0x94, 0x93, - 0x93, 0x93, 0x95, 0x95, 0x95, 0x95, 0x95, 0x93, 0x94, 0x94, 0x94, 0x92, - 0x91, 0x90, 0x90, 0x8f, 0x90, 0x90, 0x92, 0x94, 0x95, 0x93, 0x8f, 0x88, - 0x83, 0x7f, 0x79, 0x71, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, - 0x6f, 0x6f, 0x6f, 0x6e, 0x6e, 0x6c, 0x6c, 0x6d, 0x6c, 0x6b, 0x6c, 0x6a, - 0x67, 0x66, 0x65, 0x63, 0x5f, 0x5b, 0x58, 0x55, 0x50, 0x4c, 0x49, 0x46, - 0x42, 0x3c, 0x35, 0x2b, 0x22, 0x1c, 0x15, 0x11, 0x11, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x13, 0x13, 0x13, 0x12, 0x12, - 0x12, 0x12, 0x12, 0x11, 0x80, 0x7e, 0x7d, 0x7d, 0x7c, 0x79, 0x79, 0x79, - 0x78, 0x74, 0x73, 0x74, 0x73, 0x72, 0x72, 0x71, 0x71, 0x70, 0x70, 0x71, - 0x71, 0x6f, 0x6e, 0x6f, 0x73, 0x7b, 0x82, 0x86, 0x87, 0x88, 0x8b, 0x90, - 0x91, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x91, 0x92, 0x91, 0x91, 0x91, - 0x90, 0x8c, 0x8b, 0x89, 0x86, 0x84, 0x81, 0x7f, 0x7d, 0x7c, 0x7c, 0x7d, - 0x7c, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, - 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7f, 0x7f, 0x7e, - 0x7d, 0x7c, 0x7a, 0x77, 0x76, 0x73, 0x72, 0x70, 0x6f, 0x6f, 0x70, 0x70, - 0x72, 0x75, 0x76, 0x77, 0x77, 0x77, 0x78, 0x7a, 0x7b, 0x7b, 0x7c, 0x7e, - 0x7e, 0x7f, 0x7e, 0x7e, 0x7f, 0x80, 0x80, 0x7f, 0x81, 0x80, 0x81, 0x82, - 0x81, 0x82, 0x84, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x87, - 0x85, 0x85, 0x84, 0x82, 0x83, 0x83, 0x84, 0x85, 0x84, 0x83, 0x82, 0x83, - 0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x87, 0x89, 0x8a, 0x8b, 0x8c, - 0x8c, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8d, 0x8e, 0x8f, 0x8d, 0x8d, - 0x8e, 0x8e, 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x8b, 0x8a, 0x8a, 0x89, - 0x88, 0x89, 0x8a, 0x8a, 0x8b, 0x8b, 0x8e, 0x8f, 0x8f, 0x90, 0x92, 0x93, - 0x92, 0x92, 0x93, 0x94, 0x95, 0x94, 0x95, 0x95, 0x95, 0x97, 0x97, 0x98, - 0x98, 0x99, 0x9a, 0x99, 0x9a, 0x9b, 0x9b, 0x9b, 0x9a, 0x98, 0x97, 0x96, - 0x97, 0x95, 0x95, 0x94, 0x94, 0x94, 0x96, 0x96, 0x95, 0x95, 0x96, 0x96, - 0x96, 0x95, 0x94, 0x94, 0x95, 0x95, 0x94, 0x94, 0x93, 0x93, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x93, 0x93, 0x94, 0x94, 0x92, 0x92, 0x91, 0x90, 0x8f, - 0x90, 0x90, 0x92, 0x93, 0x94, 0x92, 0x8e, 0x87, 0x81, 0x7e, 0x78, 0x70, - 0x6d, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x6f, 0x6f, 0x6e, - 0x6d, 0x6c, 0x6c, 0x6d, 0x6c, 0x6b, 0x6c, 0x6b, 0x67, 0x66, 0x65, 0x63, - 0x60, 0x5c, 0x59, 0x57, 0x52, 0x4d, 0x4b, 0x47, 0x43, 0x3c, 0x36, 0x2b, - 0x23, 0x1d, 0x15, 0x11, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x12, 0x13, 0x12, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x13, 0x11, - 0x81, 0x7e, 0x7d, 0x7c, 0x7c, 0x79, 0x79, 0x79, 0x78, 0x75, 0x73, 0x74, - 0x73, 0x72, 0x72, 0x71, 0x71, 0x70, 0x70, 0x71, 0x71, 0x6f, 0x6f, 0x70, - 0x73, 0x7c, 0x83, 0x86, 0x87, 0x89, 0x8c, 0x90, 0x91, 0x91, 0x90, 0x90, - 0x8f, 0x8f, 0x90, 0x91, 0x91, 0x90, 0x91, 0x90, 0x8f, 0x8c, 0x8b, 0x88, - 0x86, 0x83, 0x80, 0x7e, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, - 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, - 0x7e, 0x7e, 0x7f, 0x7f, 0x80, 0x7f, 0x7e, 0x7e, 0x7d, 0x7b, 0x79, 0x77, - 0x75, 0x73, 0x71, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x73, 0x75, 0x76, 0x77, - 0x77, 0x77, 0x78, 0x79, 0x7b, 0x7b, 0x7c, 0x7e, 0x7e, 0x7f, 0x7f, 0x7e, - 0x80, 0x80, 0x7f, 0x7f, 0x81, 0x80, 0x81, 0x82, 0x82, 0x82, 0x84, 0x86, - 0x86, 0x86, 0x85, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x84, 0x83, 0x82, - 0x83, 0x84, 0x85, 0x85, 0x84, 0x84, 0x83, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x87, 0x87, 0x87, 0x88, 0x8a, 0x8a, 0x8b, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, - 0x8c, 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8d, 0x8d, 0x8e, 0x8f, 0x8f, 0x8d, - 0x8d, 0x8d, 0x8c, 0x8b, 0x8b, 0x8a, 0x89, 0x88, 0x88, 0x89, 0x89, 0x8a, - 0x8a, 0x8a, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x92, 0x92, 0x92, 0x93, - 0x94, 0x93, 0x94, 0x94, 0x95, 0x96, 0x96, 0x97, 0x97, 0x99, 0x99, 0x99, - 0x9a, 0x9c, 0x9c, 0x9c, 0x9a, 0x99, 0x98, 0x97, 0x97, 0x96, 0x95, 0x94, - 0x93, 0x94, 0x96, 0x97, 0x95, 0x95, 0x96, 0x96, 0x96, 0x96, 0x95, 0x94, - 0x95, 0x95, 0x94, 0x94, 0x93, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x93, - 0x94, 0x94, 0x94, 0x93, 0x92, 0x90, 0x90, 0x8f, 0x90, 0x90, 0x92, 0x93, - 0x94, 0x91, 0x8d, 0x87, 0x81, 0x7d, 0x77, 0x70, 0x6d, 0x6e, 0x6f, 0x70, - 0x70, 0x6f, 0x71, 0x71, 0x71, 0x70, 0x6e, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, - 0x6d, 0x6c, 0x6c, 0x6b, 0x68, 0x66, 0x65, 0x63, 0x61, 0x5d, 0x59, 0x57, - 0x52, 0x4e, 0x4b, 0x47, 0x43, 0x3d, 0x36, 0x2b, 0x22, 0x1d, 0x15, 0x11, - 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x12, 0x12, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x11, 0x81, 0x7e, 0x7d, 0x7c, - 0x7c, 0x7a, 0x7a, 0x7a, 0x78, 0x76, 0x74, 0x75, 0x74, 0x73, 0x73, 0x71, - 0x71, 0x70, 0x6f, 0x70, 0x6f, 0x70, 0x6f, 0x71, 0x74, 0x7d, 0x84, 0x88, - 0x89, 0x8a, 0x8d, 0x91, 0x92, 0x92, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x91, 0x90, 0x90, 0x8f, 0x8d, 0x8c, 0x89, 0x87, 0x86, 0x83, 0x80, 0x7e, - 0x7c, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, - 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, - 0x7f, 0x7e, 0x7d, 0x7d, 0x7b, 0x7a, 0x78, 0x76, 0x74, 0x72, 0x71, 0x70, - 0x70, 0x70, 0x71, 0x71, 0x73, 0x75, 0x77, 0x78, 0x79, 0x77, 0x78, 0x79, - 0x7b, 0x7b, 0x7c, 0x7c, 0x7d, 0x7e, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, - 0x81, 0x80, 0x80, 0x80, 0x81, 0x83, 0x85, 0x86, 0x86, 0x85, 0x86, 0x86, - 0x86, 0x86, 0x86, 0x86, 0x85, 0x84, 0x84, 0x83, 0x84, 0x85, 0x85, 0x85, - 0x85, 0x85, 0x84, 0x84, 0x85, 0x86, 0x86, 0x87, 0x88, 0x88, 0x88, 0x89, - 0x8b, 0x8a, 0x8b, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8c, 0x8d, 0x8d, 0x8e, - 0x8e, 0x8e, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, - 0x8c, 0x8a, 0x88, 0x88, 0x88, 0x89, 0x8a, 0x89, 0x89, 0x8a, 0x8d, 0x8f, - 0x8e, 0x8f, 0x90, 0x92, 0x92, 0x91, 0x91, 0x93, 0x93, 0x93, 0x94, 0x94, - 0x94, 0x95, 0x96, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9c, 0x9c, - 0x9b, 0x99, 0x98, 0x98, 0x97, 0x96, 0x95, 0x95, 0x94, 0x95, 0x97, 0x97, - 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x97, 0x95, 0x96, 0x96, 0x94, 0x93, - 0x93, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, - 0x92, 0x91, 0x90, 0x90, 0x90, 0x90, 0x92, 0x93, 0x93, 0x90, 0x8b, 0x86, - 0x80, 0x7c, 0x76, 0x70, 0x6e, 0x6e, 0x70, 0x71, 0x71, 0x70, 0x71, 0x71, - 0x70, 0x70, 0x6f, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6d, 0x6d, 0x6c, 0x6a, - 0x69, 0x66, 0x65, 0x64, 0x61, 0x5c, 0x5a, 0x57, 0x53, 0x50, 0x4c, 0x48, - 0x44, 0x3e, 0x37, 0x2d, 0x23, 0x1d, 0x15, 0x11, 0x11, 0x11, 0x11, 0x10, - 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x11, 0x11, - 0x12, 0x12, 0x12, 0x13, 0x81, 0x7f, 0x7e, 0x7e, 0x7d, 0x7b, 0x7a, 0x79, - 0x78, 0x78, 0x76, 0x76, 0x75, 0x75, 0x74, 0x73, 0x73, 0x72, 0x71, 0x6f, - 0x6f, 0x70, 0x70, 0x71, 0x76, 0x7e, 0x85, 0x89, 0x8b, 0x8d, 0x8f, 0x91, - 0x91, 0x91, 0x90, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8e, - 0x8d, 0x8a, 0x88, 0x86, 0x84, 0x82, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, - 0x7f, 0x7f, 0x7f, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, - 0x7e, 0x7f, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x7e, 0x7d, 0x7c, - 0x7b, 0x79, 0x77, 0x75, 0x74, 0x72, 0x71, 0x71, 0x71, 0x71, 0x72, 0x72, - 0x73, 0x75, 0x76, 0x77, 0x79, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7b, 0x7b, - 0x7b, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7f, 0x7f, - 0x81, 0x84, 0x86, 0x86, 0x87, 0x86, 0x87, 0x88, 0x88, 0x88, 0x88, 0x88, - 0x86, 0x86, 0x85, 0x86, 0x85, 0x86, 0x86, 0x86, 0x86, 0x87, 0x86, 0x85, - 0x86, 0x88, 0x88, 0x87, 0x89, 0x89, 0x88, 0x89, 0x8b, 0x8b, 0x8b, 0x8d, - 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, - 0x8e, 0x8e, 0x8d, 0x8e, 0x8e, 0x8d, 0x8d, 0x8c, 0x8b, 0x89, 0x87, 0x86, - 0x87, 0x88, 0x89, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8d, 0x8e, 0x8f, 0x91, - 0x91, 0x90, 0x90, 0x91, 0x91, 0x91, 0x92, 0x92, 0x92, 0x93, 0x95, 0x95, - 0x96, 0x97, 0x98, 0x99, 0x9b, 0x9c, 0x9c, 0x9b, 0x99, 0x99, 0x99, 0x99, - 0x99, 0x97, 0x97, 0x97, 0x97, 0x96, 0x97, 0x96, 0x97, 0x97, 0x97, 0x98, - 0x98, 0x98, 0x97, 0x96, 0x97, 0x97, 0x95, 0x94, 0x95, 0x95, 0x95, 0x95, - 0x96, 0x95, 0x95, 0x96, 0x96, 0x96, 0x95, 0x95, 0x93, 0x91, 0x91, 0x91, - 0x91, 0x91, 0x92, 0x93, 0x93, 0x8e, 0x8a, 0x84, 0x7f, 0x7b, 0x76, 0x70, - 0x6e, 0x6f, 0x70, 0x71, 0x70, 0x71, 0x72, 0x72, 0x71, 0x71, 0x71, 0x70, - 0x70, 0x70, 0x6f, 0x6d, 0x6e, 0x6d, 0x6b, 0x6a, 0x6a, 0x68, 0x67, 0x66, - 0x62, 0x5e, 0x5b, 0x58, 0x55, 0x51, 0x4c, 0x48, 0x45, 0x3f, 0x37, 0x2d, - 0x23, 0x1c, 0x13, 0x11, 0x11, 0x11, 0x10, 0x11, 0x10, 0x10, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x11, 0x11, 0x12, 0x13, 0x14, 0x14, - 0x82, 0x80, 0x80, 0x7f, 0x7e, 0x7b, 0x7a, 0x79, 0x78, 0x78, 0x77, 0x77, - 0x76, 0x76, 0x75, 0x74, 0x74, 0x73, 0x72, 0x71, 0x70, 0x6f, 0x70, 0x72, - 0x77, 0x7f, 0x86, 0x8a, 0x8c, 0x8d, 0x91, 0x91, 0x91, 0x91, 0x91, 0x8f, - 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x8f, 0x8e, 0x8d, 0x8c, 0x89, 0x87, 0x85, - 0x83, 0x81, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x7f, - 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7f, 0x7f, 0x80, - 0x7f, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7b, 0x79, 0x78, 0x76, - 0x74, 0x72, 0x71, 0x73, 0x72, 0x73, 0x73, 0x74, 0x75, 0x76, 0x76, 0x77, - 0x79, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7c, 0x7b, 0x7c, 0x7d, 0x7e, 0x7e, - 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x81, 0x84, 0x86, 0x86, - 0x85, 0x86, 0x88, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x86, 0x86, 0x86, - 0x86, 0x86, 0x86, 0x87, 0x88, 0x88, 0x88, 0x87, 0x87, 0x89, 0x8a, 0x89, - 0x8a, 0x8a, 0x89, 0x8b, 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8c, 0x8c, 0x8c, - 0x8c, 0x8c, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, - 0x8e, 0x8d, 0x8d, 0x8b, 0x89, 0x89, 0x87, 0x86, 0x86, 0x88, 0x89, 0x89, - 0x89, 0x8a, 0x8b, 0x8c, 0x8c, 0x8d, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x91, - 0x91, 0x90, 0x91, 0x91, 0x91, 0x92, 0x95, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9b, 0x9c, 0x9c, 0x9c, 0x9a, 0x9b, 0x9b, 0x9b, 0x9a, 0x98, 0x98, 0x98, - 0x98, 0x98, 0x97, 0x96, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x97, 0x96, - 0x96, 0x97, 0x96, 0x95, 0x96, 0x94, 0x95, 0x95, 0x95, 0x94, 0x94, 0x95, - 0x95, 0x95, 0x95, 0x95, 0x94, 0x93, 0x92, 0x93, 0x92, 0x91, 0x92, 0x93, - 0x92, 0x8d, 0x89, 0x83, 0x7d, 0x7a, 0x75, 0x70, 0x6e, 0x6f, 0x70, 0x71, - 0x6f, 0x70, 0x72, 0x72, 0x73, 0x71, 0x72, 0x71, 0x71, 0x70, 0x6f, 0x6e, - 0x6e, 0x6d, 0x6c, 0x6a, 0x6a, 0x68, 0x67, 0x65, 0x63, 0x5f, 0x5b, 0x59, - 0x56, 0x52, 0x4e, 0x4a, 0x46, 0x40, 0x37, 0x2d, 0x23, 0x1c, 0x14, 0x11, - 0x12, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x12, 0x11, - 0x11, 0x11, 0x10, 0x11, 0x12, 0x13, 0x14, 0x13, 0x82, 0x80, 0x80, 0x7f, - 0x7d, 0x7b, 0x7b, 0x7a, 0x79, 0x79, 0x78, 0x77, 0x76, 0x75, 0x76, 0x74, - 0x74, 0x73, 0x72, 0x71, 0x72, 0x71, 0x71, 0x73, 0x78, 0x81, 0x88, 0x8b, - 0x8c, 0x8e, 0x92, 0x93, 0x92, 0x91, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, - 0x8f, 0x8f, 0x8e, 0x8e, 0x8c, 0x89, 0x86, 0x84, 0x84, 0x82, 0x81, 0x7f, - 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7d, 0x7d, 0x7d, 0x7d, - 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x80, 0x80, 0x81, 0x81, 0x80, 0x7f, - 0x7e, 0x7d, 0x7d, 0x7d, 0x7b, 0x79, 0x77, 0x77, 0x75, 0x74, 0x74, 0x75, - 0x74, 0x74, 0x74, 0x75, 0x76, 0x76, 0x78, 0x79, 0x7a, 0x7a, 0x7a, 0x7a, - 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7f, 0x7e, - 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x84, 0x86, 0x86, 0x86, 0x88, 0x89, 0x89, - 0x89, 0x89, 0x89, 0x89, 0x88, 0x86, 0x86, 0x87, 0x88, 0x87, 0x87, 0x88, - 0x8a, 0x8a, 0x8a, 0x88, 0x89, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8b, - 0x8c, 0x8c, 0x8c, 0x8d, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, 0x8d, - 0x8d, 0x8c, 0x8c, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, - 0x8a, 0x88, 0x87, 0x87, 0x86, 0x87, 0x89, 0x89, 0x89, 0x89, 0x89, 0x8b, - 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x90, 0x90, - 0x91, 0x92, 0x94, 0x94, 0x96, 0x96, 0x97, 0x98, 0x9a, 0x9b, 0x9c, 0x9d, - 0x9c, 0x9d, 0x9c, 0x9c, 0x99, 0x99, 0x98, 0x97, 0x97, 0x97, 0x98, 0x99, - 0x99, 0x99, 0x98, 0x97, 0x97, 0x98, 0x98, 0x97, 0x97, 0x98, 0x97, 0x97, - 0x97, 0x95, 0x96, 0x95, 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x95, 0x95, - 0x93, 0x92, 0x93, 0x93, 0x93, 0x92, 0x93, 0x93, 0x92, 0x8e, 0x8a, 0x82, - 0x7e, 0x79, 0x74, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x70, 0x71, 0x71, 0x72, - 0x73, 0x72, 0x72, 0x72, 0x71, 0x70, 0x6f, 0x6f, 0x6e, 0x6d, 0x6e, 0x6c, - 0x6a, 0x68, 0x67, 0x66, 0x62, 0x60, 0x5c, 0x59, 0x56, 0x53, 0x4d, 0x48, - 0x46, 0x41, 0x39, 0x2e, 0x23, 0x1d, 0x15, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x13, 0x12, 0x12, 0x12, 0x11, 0x11, - 0x12, 0x13, 0x13, 0x14, 0x82, 0x80, 0x80, 0x7f, 0x7d, 0x7b, 0x7b, 0x7a, - 0x79, 0x79, 0x78, 0x77, 0x76, 0x75, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, - 0x72, 0x71, 0x71, 0x73, 0x79, 0x82, 0x88, 0x8b, 0x8c, 0x8f, 0x92, 0x94, - 0x93, 0x91, 0x90, 0x91, 0x90, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, - 0x8c, 0x88, 0x85, 0x84, 0x84, 0x82, 0x82, 0x80, 0x80, 0x80, 0x81, 0x81, - 0x80, 0x80, 0x80, 0x7f, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, - 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x81, 0x81, 0x7f, 0x7e, 0x7c, 0x7c, 0x7d, - 0x7a, 0x78, 0x77, 0x76, 0x76, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x76, - 0x76, 0x77, 0x78, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, - 0x7c, 0x7d, 0x7c, 0x7c, 0x7e, 0x7f, 0x7f, 0x7e, 0x7e, 0x7f, 0x80, 0x81, - 0x83, 0x84, 0x85, 0x86, 0x86, 0x88, 0x89, 0x89, 0x88, 0x89, 0x89, 0x8a, - 0x88, 0x86, 0x86, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8a, 0x8a, 0x8a, 0x89, - 0x89, 0x8b, 0x8c, 0x8b, 0x8b, 0x8a, 0x8a, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, - 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8d, 0x8c, 0x8b, 0x8c, 0x8d, - 0x8e, 0x8e, 0x8e, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x88, 0x87, 0x87, - 0x86, 0x86, 0x88, 0x89, 0x89, 0x89, 0x89, 0x8b, 0x8b, 0x8b, 0x8c, 0x8e, - 0x8f, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x91, 0x93, 0x94, - 0x96, 0x96, 0x97, 0x98, 0x9a, 0x9a, 0x9b, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, - 0x9a, 0x9a, 0x98, 0x97, 0x96, 0x97, 0x99, 0x99, 0x9a, 0x9a, 0x98, 0x98, - 0x97, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97, 0x96, 0x97, 0x95, - 0x95, 0x95, 0x95, 0x96, 0x96, 0x96, 0x95, 0x96, 0x94, 0x93, 0x93, 0x93, - 0x93, 0x92, 0x93, 0x93, 0x92, 0x8e, 0x89, 0x82, 0x7d, 0x79, 0x73, 0x6e, - 0x6e, 0x6f, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x73, 0x73, 0x73, 0x72, - 0x70, 0x70, 0x6f, 0x6f, 0x6d, 0x6d, 0x6e, 0x6d, 0x6a, 0x68, 0x67, 0x66, - 0x62, 0x60, 0x5c, 0x59, 0x56, 0x52, 0x4d, 0x49, 0x46, 0x42, 0x3a, 0x2e, - 0x24, 0x1e, 0x16, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, - 0x10, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11, 0x12, 0x12, 0x12, 0x15, - 0x82, 0x80, 0x80, 0x7f, 0x7e, 0x7c, 0x7a, 0x79, 0x78, 0x79, 0x77, 0x77, - 0x76, 0x76, 0x77, 0x76, 0x74, 0x73, 0x73, 0x72, 0x72, 0x70, 0x71, 0x73, - 0x79, 0x82, 0x88, 0x8c, 0x8d, 0x8f, 0x92, 0x93, 0x93, 0x91, 0x90, 0x91, - 0x90, 0x8f, 0x8e, 0x8e, 0x8f, 0x8e, 0x8e, 0x8d, 0x8c, 0x88, 0x85, 0x84, - 0x83, 0x82, 0x82, 0x81, 0x82, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, - 0x7d, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x80, 0x80, 0x81, - 0x80, 0x81, 0x81, 0x7f, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, 0x78, 0x76, 0x76, - 0x76, 0x76, 0x76, 0x75, 0x75, 0x75, 0x76, 0x75, 0x75, 0x77, 0x78, 0x79, - 0x79, 0x7a, 0x7a, 0x7b, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, - 0x7e, 0x7f, 0x7f, 0x7f, 0x7e, 0x7f, 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, - 0x86, 0x87, 0x89, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x88, 0x87, 0x88, 0x89, - 0x89, 0x89, 0x89, 0x8a, 0x8b, 0x8b, 0x8b, 0x8a, 0x8b, 0x8c, 0x8c, 0x8c, - 0x8c, 0x8b, 0x8b, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8e, 0x8d, 0x8d, 0x8d, - 0x8d, 0x8e, 0x8e, 0x8d, 0x8d, 0x8b, 0x8c, 0x8d, 0x8e, 0x8e, 0x8e, 0x8d, - 0x8c, 0x8c, 0x8b, 0x8c, 0x8b, 0x88, 0x88, 0x87, 0x87, 0x86, 0x87, 0x88, - 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x8f, 0x8f, - 0x8f, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x92, 0x93, 0x95, 0x96, 0x98, 0x98, - 0x9a, 0x9a, 0x9b, 0x9d, 0x9d, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x99, 0x98, - 0x97, 0x98, 0x9a, 0x9a, 0x9a, 0x9a, 0x99, 0x98, 0x97, 0x97, 0x97, 0x98, - 0x98, 0x98, 0x98, 0x98, 0x96, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x95, - 0x95, 0x96, 0x96, 0x96, 0x95, 0x93, 0x92, 0x93, 0x93, 0x92, 0x92, 0x92, - 0x91, 0x8d, 0x88, 0x81, 0x7c, 0x78, 0x72, 0x6d, 0x6d, 0x6e, 0x6e, 0x6f, - 0x70, 0x71, 0x71, 0x71, 0x73, 0x74, 0x72, 0x71, 0x71, 0x71, 0x71, 0x70, - 0x6d, 0x6d, 0x6d, 0x6d, 0x6a, 0x68, 0x67, 0x66, 0x63, 0x60, 0x5c, 0x59, - 0x56, 0x52, 0x4d, 0x49, 0x46, 0x42, 0x3a, 0x2f, 0x24, 0x1e, 0x16, 0x11, - 0x10, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 0x10, 0x11, 0x12, 0x11, - 0x11, 0x11, 0x12, 0x11, 0x11, 0x11, 0x11, 0x14, 0x82, 0x80, 0x80, 0x80, - 0x7f, 0x7e, 0x7b, 0x79, 0x79, 0x7a, 0x79, 0x78, 0x77, 0x77, 0x77, 0x74, - 0x74, 0x74, 0x73, 0x72, 0x72, 0x71, 0x71, 0x73, 0x7a, 0x83, 0x8a, 0x8d, - 0x8e, 0x8f, 0x92, 0x93, 0x92, 0x91, 0x90, 0x90, 0x8f, 0x8f, 0x8e, 0x8e, - 0x8f, 0x8e, 0x8c, 0x8b, 0x8a, 0x89, 0x86, 0x85, 0x84, 0x83, 0x83, 0x82, - 0x82, 0x82, 0x81, 0x81, 0x80, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7d, 0x7e, - 0x7f, 0x7f, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x82, 0x80, 0x81, 0x80, 0x7f, - 0x7f, 0x7d, 0x7c, 0x7c, 0x7a, 0x79, 0x77, 0x76, 0x76, 0x75, 0x75, 0x77, - 0x77, 0x77, 0x77, 0x76, 0x76, 0x78, 0x78, 0x7a, 0x7b, 0x7b, 0x7b, 0x7b, - 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, - 0x7f, 0x80, 0x80, 0x82, 0x84, 0x85, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, - 0x89, 0x8a, 0x8b, 0x8b, 0x88, 0x87, 0x88, 0x8a, 0x89, 0x8a, 0x8b, 0x8c, - 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, 0x8c, 0x8c, 0x8d, 0x8d, - 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8d, 0x8d, - 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8d, 0x8d, 0x8c, 0x8b, 0x8c, - 0x8a, 0x88, 0x87, 0x87, 0x87, 0x87, 0x86, 0x87, 0x88, 0x88, 0x8a, 0x8a, - 0x89, 0x89, 0x8a, 0x8c, 0x8c, 0x8d, 0x8e, 0x8f, 0x8f, 0x8e, 0x8e, 0x8f, - 0x8f, 0x8f, 0x91, 0x93, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9a, 0x9b, 0x9d, - 0x9e, 0x9d, 0x9b, 0x9b, 0x9b, 0x9c, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x99, - 0x9a, 0x9a, 0x99, 0x99, 0x98, 0x98, 0x98, 0x97, 0x98, 0x98, 0x97, 0x97, - 0x97, 0x97, 0x98, 0x98, 0x98, 0x98, 0x98, 0x96, 0x96, 0x97, 0x98, 0x97, - 0x95, 0x95, 0x95, 0x94, 0x93, 0x94, 0x93, 0x93, 0x91, 0x8c, 0x86, 0x7f, - 0x7a, 0x76, 0x71, 0x6d, 0x6e, 0x6d, 0x6e, 0x70, 0x71, 0x71, 0x72, 0x72, - 0x73, 0x73, 0x73, 0x71, 0x70, 0x71, 0x71, 0x71, 0x6f, 0x6e, 0x6e, 0x6d, - 0x6b, 0x67, 0x66, 0x66, 0x63, 0x61, 0x5e, 0x5b, 0x57, 0x53, 0x4e, 0x4a, - 0x47, 0x43, 0x3b, 0x2e, 0x23, 0x1d, 0x16, 0x11, 0x10, 0x11, 0x11, 0x10, - 0x11, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x12, 0x11, - 0x11, 0x12, 0x13, 0x12, 0x83, 0x81, 0x81, 0x80, 0x7f, 0x7d, 0x7d, 0x7b, - 0x7a, 0x7a, 0x79, 0x79, 0x77, 0x76, 0x77, 0x75, 0x75, 0x73, 0x72, 0x71, - 0x72, 0x71, 0x70, 0x72, 0x79, 0x83, 0x8b, 0x8e, 0x8f, 0x90, 0x92, 0x93, - 0x91, 0x91, 0x90, 0x91, 0x90, 0x8f, 0x8e, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, - 0x8a, 0x89, 0x88, 0x86, 0x86, 0x85, 0x85, 0x83, 0x83, 0x83, 0x83, 0x82, - 0x80, 0x81, 0x80, 0x7f, 0x7f, 0x7e, 0x7d, 0x7e, 0x80, 0x80, 0x7f, 0x80, - 0x80, 0x81, 0x82, 0x82, 0x81, 0x80, 0x80, 0x81, 0x80, 0x7d, 0x7d, 0x7d, - 0x7b, 0x7a, 0x78, 0x77, 0x77, 0x76, 0x77, 0x78, 0x79, 0x79, 0x78, 0x78, - 0x78, 0x79, 0x79, 0x79, 0x7b, 0x7c, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, - 0x7d, 0x7c, 0x7d, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x80, 0x82, 0x82, 0x83, - 0x85, 0x85, 0x87, 0x88, 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x8c, 0x8c, - 0x8a, 0x89, 0x88, 0x89, 0x8a, 0x8a, 0x8c, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, - 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, - 0x8e, 0x8f, 0x90, 0x90, 0x90, 0x8f, 0x8c, 0x8c, 0x8d, 0x8e, 0x8d, 0x8c, - 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8a, 0x87, 0x88, 0x87, - 0x86, 0x86, 0x86, 0x87, 0x88, 0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8b, 0x8b, - 0x8c, 0x8c, 0x8d, 0x8e, 0x8e, 0x8d, 0x8d, 0x8f, 0x8f, 0x90, 0x92, 0x94, - 0x95, 0x96, 0x97, 0x97, 0x99, 0x9b, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, - 0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x99, 0x99, 0x99, 0x99, - 0x98, 0x98, 0x98, 0x97, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, 0x98, 0x99, - 0x99, 0x99, 0x98, 0x96, 0x96, 0x97, 0x98, 0x98, 0x95, 0x96, 0x96, 0x95, - 0x93, 0x94, 0x93, 0x92, 0x8f, 0x8a, 0x85, 0x7e, 0x78, 0x74, 0x70, 0x6e, - 0x6e, 0x6e, 0x6d, 0x6e, 0x70, 0x70, 0x72, 0x73, 0x73, 0x74, 0x74, 0x72, - 0x71, 0x71, 0x71, 0x70, 0x6f, 0x6e, 0x6f, 0x6d, 0x6b, 0x68, 0x67, 0x65, - 0x62, 0x60, 0x5e, 0x5c, 0x58, 0x53, 0x4f, 0x4c, 0x49, 0x44, 0x3b, 0x2e, - 0x24, 0x1d, 0x17, 0x12, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, 0x12, 0x11, 0x11, 0x13, 0x12, - 0x83, 0x81, 0x80, 0x81, 0x7f, 0x7d, 0x7e, 0x7d, 0x7b, 0x7a, 0x79, 0x78, - 0x77, 0x76, 0x76, 0x77, 0x76, 0x74, 0x73, 0x72, 0x73, 0x71, 0x70, 0x72, - 0x79, 0x83, 0x8a, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x92, 0x91, 0x90, 0x91, - 0x90, 0x90, 0x8e, 0x8d, 0x8d, 0x8b, 0x8c, 0x8c, 0x8a, 0x89, 0x89, 0x87, - 0x87, 0x87, 0x86, 0x84, 0x84, 0x84, 0x84, 0x83, 0x80, 0x81, 0x80, 0x7f, - 0x7f, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x81, 0x82, 0x82, - 0x81, 0x81, 0x81, 0x81, 0x80, 0x7f, 0x7f, 0x7e, 0x7d, 0x7c, 0x79, 0x78, - 0x79, 0x79, 0x7a, 0x79, 0x79, 0x79, 0x78, 0x7a, 0x79, 0x78, 0x78, 0x79, - 0x7b, 0x7c, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, - 0x7e, 0x7e, 0x7d, 0x7d, 0x80, 0x82, 0x82, 0x83, 0x85, 0x86, 0x87, 0x87, - 0x87, 0x87, 0x89, 0x89, 0x89, 0x89, 0x8c, 0x8d, 0x8b, 0x8b, 0x8a, 0x8b, - 0x8b, 0x8d, 0x8e, 0x8e, 0x8d, 0x8d, 0x8e, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, - 0x8d, 0x8e, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8d, 0x8e, 0x8f, 0x90, 0x90, - 0x8f, 0x8f, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8b, 0x8c, 0x8c, 0x8c, 0x8d, - 0x8d, 0x8d, 0x8c, 0x8c, 0x8a, 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x87, - 0x88, 0x87, 0x88, 0x88, 0x8a, 0x8a, 0x8b, 0x8a, 0x8c, 0x8c, 0x8c, 0x8c, - 0x8d, 0x8c, 0x8d, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x95, 0x95, 0x96, - 0x9a, 0x9b, 0x9c, 0x9d, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9b, - 0x9a, 0x9a, 0x9b, 0x9b, 0x9a, 0x9a, 0x99, 0x98, 0x98, 0x98, 0x98, 0x97, - 0x97, 0x97, 0x98, 0x99, 0x9a, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x96, - 0x96, 0x97, 0x98, 0x98, 0x96, 0x96, 0x96, 0x94, 0x94, 0x94, 0x93, 0x91, - 0x8e, 0x8a, 0x84, 0x7d, 0x77, 0x74, 0x6f, 0x6c, 0x6d, 0x6d, 0x6c, 0x6d, - 0x70, 0x71, 0x73, 0x73, 0x72, 0x74, 0x74, 0x73, 0x72, 0x72, 0x70, 0x70, - 0x6f, 0x6e, 0x6e, 0x6c, 0x6c, 0x69, 0x69, 0x66, 0x62, 0x60, 0x5d, 0x5c, - 0x59, 0x55, 0x4f, 0x4b, 0x48, 0x44, 0x3b, 0x2f, 0x25, 0x1e, 0x17, 0x12, - 0x11, 0x11, 0x11, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x12, 0x12, 0x12, 0x11, 0x11, 0x11, 0x13, 0x83, 0x81, 0x81, 0x81, - 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x7a, 0x79, 0x78, 0x77, 0x77, 0x77, 0x78, - 0x77, 0x74, 0x73, 0x73, 0x72, 0x71, 0x71, 0x73, 0x7a, 0x83, 0x8a, 0x8d, - 0x8e, 0x90, 0x92, 0x93, 0x92, 0x91, 0x90, 0x90, 0x90, 0x8f, 0x8e, 0x8d, - 0x8d, 0x8b, 0x8c, 0x8c, 0x8a, 0x89, 0x89, 0x88, 0x88, 0x88, 0x87, 0x84, - 0x84, 0x84, 0x85, 0x83, 0x80, 0x81, 0x81, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, - 0x80, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x82, 0x81, 0x81, 0x81, 0x81, - 0x80, 0x7f, 0x7f, 0x7e, 0x7d, 0x7c, 0x7a, 0x7a, 0x7a, 0x7b, 0x7c, 0x7a, - 0x7a, 0x7a, 0x79, 0x7a, 0x79, 0x78, 0x77, 0x78, 0x7b, 0x7c, 0x7c, 0x7c, - 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7d, - 0x80, 0x82, 0x82, 0x83, 0x85, 0x86, 0x87, 0x87, 0x88, 0x88, 0x89, 0x89, - 0x89, 0x8a, 0x8c, 0x8d, 0x8c, 0x8b, 0x8b, 0x8b, 0x8c, 0x8e, 0x8e, 0x8e, - 0x8d, 0x8d, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8f, 0x90, 0x90, - 0x8e, 0x8f, 0x8f, 0x8d, 0x8e, 0x8f, 0x90, 0x90, 0x8e, 0x8e, 0x8c, 0x8b, - 0x8c, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8c, 0x8b, - 0x8a, 0x88, 0x88, 0x87, 0x86, 0x87, 0x87, 0x88, 0x88, 0x87, 0x88, 0x88, - 0x8a, 0x8a, 0x8b, 0x8a, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8d, 0x8f, - 0x8f, 0x91, 0x91, 0x93, 0x94, 0x95, 0x94, 0x96, 0x9a, 0x9b, 0x9c, 0x9d, - 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9b, 0x9a, 0x9a, 0x9c, 0x9c, - 0x9b, 0x9a, 0x98, 0x98, 0x99, 0x98, 0x98, 0x97, 0x97, 0x97, 0x99, 0x99, - 0x9a, 0x99, 0x9a, 0x99, 0x98, 0x99, 0x99, 0x97, 0x97, 0x98, 0x99, 0x98, - 0x97, 0x96, 0x95, 0x94, 0x95, 0x94, 0x92, 0x90, 0x8d, 0x89, 0x83, 0x7c, - 0x77, 0x73, 0x6f, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x70, 0x71, 0x72, 0x73, - 0x73, 0x74, 0x74, 0x73, 0x73, 0x72, 0x71, 0x71, 0x6f, 0x6e, 0x6e, 0x6c, - 0x6c, 0x6a, 0x69, 0x67, 0x63, 0x60, 0x5d, 0x5c, 0x5a, 0x55, 0x4f, 0x4b, - 0x48, 0x44, 0x3c, 0x30, 0x26, 0x1f, 0x17, 0x13, 0x11, 0x11, 0x11, 0x10, - 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, - 0x11, 0x11, 0x11, 0x13, 0x83, 0x82, 0x81, 0x81, 0x81, 0x7e, 0x7e, 0x7d, - 0x7c, 0x7b, 0x7b, 0x79, 0x78, 0x78, 0x79, 0x78, 0x75, 0x75, 0x74, 0x73, - 0x71, 0x70, 0x71, 0x73, 0x79, 0x82, 0x8a, 0x8c, 0x8e, 0x8f, 0x92, 0x93, - 0x92, 0x91, 0x90, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8c, 0x8d, 0x8c, 0x8c, - 0x8c, 0x8a, 0x8a, 0x89, 0x89, 0x88, 0x86, 0x86, 0x84, 0x84, 0x84, 0x84, - 0x81, 0x81, 0x81, 0x80, 0x7e, 0x7f, 0x7e, 0x7f, 0x7f, 0x80, 0x81, 0x81, - 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81, 0x80, 0x80, 0x7f, 0x7f, - 0x7e, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7d, 0x7c, 0x7b, 0x79, - 0x79, 0x78, 0x78, 0x79, 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, - 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x80, 0x82, 0x82, 0x83, - 0x84, 0x86, 0x87, 0x88, 0x88, 0x89, 0x8a, 0x8a, 0x89, 0x8b, 0x8c, 0x8d, - 0x8d, 0x8c, 0x8b, 0x8c, 0x8d, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8f, 0x8f, - 0x90, 0x90, 0x90, 0x8e, 0x8f, 0x8f, 0x90, 0x8f, 0x8f, 0x90, 0x90, 0x8e, - 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, 0x8e, 0x8c, 0x8c, 0x8d, 0x8e, 0x8e, 0x8d, - 0x8d, 0x8d, 0x8c, 0x8d, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x89, 0x88, 0x88, - 0x87, 0x88, 0x87, 0x88, 0x88, 0x88, 0x89, 0x8a, 0x8a, 0x8a, 0x8b, 0x8b, - 0x8c, 0x8b, 0x8c, 0x8c, 0x8c, 0x8c, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x91, - 0x93, 0x94, 0x94, 0x97, 0x9a, 0x9a, 0x9b, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, - 0x9c, 0x9c, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x9c, 0x9b, 0x99, 0x99, - 0x9a, 0x99, 0x98, 0x97, 0x96, 0x99, 0x9a, 0x9a, 0x9b, 0x9a, 0x9a, 0x9a, - 0x9a, 0x9a, 0x99, 0x98, 0x99, 0x99, 0x99, 0x99, 0x97, 0x96, 0x95, 0x94, - 0x94, 0x93, 0x92, 0x90, 0x8c, 0x87, 0x81, 0x79, 0x74, 0x71, 0x6e, 0x6c, - 0x6c, 0x6d, 0x6e, 0x6e, 0x70, 0x71, 0x71, 0x72, 0x73, 0x72, 0x74, 0x74, - 0x74, 0x73, 0x73, 0x72, 0x6f, 0x6e, 0x6e, 0x6c, 0x6c, 0x6a, 0x69, 0x69, - 0x64, 0x60, 0x5e, 0x5c, 0x59, 0x55, 0x4f, 0x4a, 0x47, 0x43, 0x3b, 0x2f, - 0x27, 0x21, 0x17, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, - 0x83, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, 0x79, - 0x78, 0x79, 0x79, 0x77, 0x75, 0x75, 0x74, 0x73, 0x71, 0x70, 0x71, 0x74, - 0x79, 0x82, 0x88, 0x8c, 0x8d, 0x8e, 0x92, 0x93, 0x92, 0x91, 0x91, 0x8f, - 0x8f, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8b, 0x8c, 0x8a, 0x8a, 0x89, - 0x88, 0x88, 0x87, 0x87, 0x85, 0x84, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, - 0x7f, 0x7f, 0x7f, 0x7f, 0x81, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x84, - 0x84, 0x84, 0x83, 0x82, 0x82, 0x81, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x7e, - 0x7f, 0x7f, 0x7f, 0x7d, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7b, 0x7b, - 0x7a, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, - 0x7d, 0x7d, 0x7d, 0x7d, 0x80, 0x81, 0x81, 0x83, 0x83, 0x86, 0x87, 0x88, - 0x89, 0x8b, 0x8c, 0x8a, 0x8b, 0x8d, 0x8e, 0x8e, 0x8e, 0x8c, 0x8c, 0x8c, - 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x90, 0x8f, 0x90, 0x91, 0x91, 0x90, - 0x8f, 0x8f, 0x8f, 0x90, 0x8f, 0x8f, 0x90, 0x91, 0x90, 0x8f, 0x90, 0x8f, - 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8f, 0x8d, 0x8d, 0x8d, 0x8c, 0x8d, - 0x8d, 0x8c, 0x8b, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x87, 0x87, - 0x87, 0x87, 0x89, 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8b, 0x8b, 0x8c, 0x8d, - 0x8c, 0x8c, 0x8e, 0x8f, 0x8f, 0x90, 0x90, 0x91, 0x92, 0x93, 0x94, 0x97, - 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9d, 0x9d, - 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9a, 0x99, 0x9a, 0x99, 0x97, 0x96, - 0x97, 0x99, 0x99, 0x9a, 0x9a, 0x9b, 0x9a, 0x99, 0x9a, 0x9b, 0x9b, 0x9a, - 0x9a, 0x9a, 0x9a, 0x9a, 0x97, 0x96, 0x96, 0x97, 0x96, 0x94, 0x90, 0x8e, - 0x8b, 0x85, 0x7e, 0x77, 0x72, 0x6f, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, - 0x6e, 0x70, 0x70, 0x71, 0x72, 0x72, 0x74, 0x75, 0x74, 0x74, 0x74, 0x72, - 0x71, 0x70, 0x70, 0x6f, 0x6d, 0x6c, 0x6a, 0x69, 0x65, 0x62, 0x5e, 0x5c, - 0x59, 0x55, 0x4f, 0x4a, 0x47, 0x43, 0x3a, 0x2f, 0x27, 0x21, 0x17, 0x11, - 0x11, 0x11, 0x10, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x13, 0x82, 0x82, 0x81, 0x80, - 0x80, 0x80, 0x7f, 0x7e, 0x7d, 0x7c, 0x7c, 0x7a, 0x7a, 0x7a, 0x79, 0x77, - 0x76, 0x74, 0x74, 0x73, 0x71, 0x70, 0x71, 0x74, 0x7b, 0x82, 0x88, 0x8c, - 0x8d, 0x8f, 0x92, 0x93, 0x92, 0x91, 0x90, 0x90, 0x8e, 0x8d, 0x8d, 0x8d, - 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8b, 0x8a, 0x89, 0x89, 0x89, 0x89, 0x88, - 0x88, 0x86, 0x84, 0x82, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x80, 0x81, - 0x82, 0x82, 0x83, 0x84, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x83, - 0x82, 0x81, 0x81, 0x81, 0x82, 0x81, 0x81, 0x82, 0x81, 0x80, 0x80, 0x7f, - 0x7e, 0x7e, 0x7d, 0x7b, 0x7c, 0x7c, 0x7b, 0x7a, 0x7a, 0x7c, 0x7c, 0x7c, - 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7c, 0x7d, 0x7c, 0x7d, 0x7d, 0x7d, 0x7f, - 0x80, 0x80, 0x81, 0x82, 0x84, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, - 0x8c, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8c, 0x8d, 0x8d, 0x8f, 0x90, 0x90, - 0x8f, 0x90, 0x91, 0x90, 0x91, 0x91, 0x91, 0x91, 0x90, 0x8f, 0x8f, 0x91, - 0x91, 0x90, 0x90, 0x91, 0x91, 0x90, 0x91, 0x90, 0x8f, 0x8f, 0x90, 0x90, - 0x90, 0x8f, 0x8e, 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, - 0x8a, 0x89, 0x88, 0x88, 0x88, 0x87, 0x87, 0x87, 0x87, 0x87, 0x89, 0x89, - 0x87, 0x87, 0x88, 0x88, 0x8a, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8e, 0x8f, - 0x90, 0x8f, 0x91, 0x92, 0x92, 0x92, 0x93, 0x95, 0x98, 0x9a, 0x9b, 0x9c, - 0x9b, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, - 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9a, 0x98, 0x97, 0x97, 0x97, 0x99, 0x99, - 0x9a, 0x9b, 0x9b, 0x9a, 0x9b, 0x9c, 0x9c, 0x9a, 0x9a, 0x9a, 0x9b, 0x9a, - 0x97, 0x96, 0x97, 0x97, 0x96, 0x92, 0x8f, 0x8c, 0x88, 0x82, 0x7d, 0x76, - 0x70, 0x6c, 0x6a, 0x6a, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x70, - 0x72, 0x73, 0x75, 0x75, 0x75, 0x74, 0x74, 0x73, 0x72, 0x71, 0x71, 0x6f, - 0x6e, 0x6c, 0x6a, 0x67, 0x65, 0x62, 0x5e, 0x5b, 0x59, 0x55, 0x4f, 0x4a, - 0x47, 0x43, 0x3b, 0x2f, 0x26, 0x20, 0x18, 0x12, 0x11, 0x10, 0x10, 0x10, - 0x10, 0x11, 0x10, 0x11, 0x12, 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x12, 0x12, 0x83, 0x83, 0x82, 0x82, 0x80, 0x80, 0x7f, 0x7e, - 0x7c, 0x7c, 0x7b, 0x7a, 0x7a, 0x7a, 0x79, 0x79, 0x77, 0x76, 0x75, 0x73, - 0x72, 0x71, 0x72, 0x74, 0x7a, 0x83, 0x89, 0x8d, 0x8e, 0x8f, 0x92, 0x93, - 0x92, 0x91, 0x90, 0x90, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, - 0x8d, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x89, 0x88, 0x85, 0x83, - 0x83, 0x82, 0x82, 0x82, 0x83, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x85, - 0x85, 0x86, 0x87, 0x87, 0x86, 0x86, 0x86, 0x85, 0x83, 0x82, 0x82, 0x82, - 0x83, 0x83, 0x83, 0x83, 0x83, 0x81, 0x80, 0x81, 0x7f, 0x7e, 0x7d, 0x7d, - 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, - 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x81, 0x83, - 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8f, 0x8f, - 0x8f, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x91, 0x91, - 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x91, 0x92, 0x91, 0x90, 0x91, - 0x90, 0x91, 0x92, 0x91, 0x90, 0x90, 0x91, 0x91, 0x91, 0x90, 0x8f, 0x8d, - 0x8e, 0x8f, 0x8e, 0x8d, 0x8e, 0x8c, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, - 0x89, 0x88, 0x89, 0x89, 0x89, 0x89, 0x88, 0x87, 0x87, 0x86, 0x87, 0x88, - 0x8a, 0x8a, 0x8b, 0x8c, 0x8b, 0x8d, 0x8e, 0x8f, 0x8f, 0x90, 0x92, 0x92, - 0x92, 0x92, 0x93, 0x96, 0x98, 0x9a, 0x9a, 0x9b, 0x9a, 0x9a, 0x9c, 0x9c, - 0x9d, 0x9c, 0x9d, 0x9e, 0x9e, 0x9d, 0x9c, 0x9c, 0x9d, 0x9d, 0x9c, 0x9c, - 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9c, 0x9c, - 0x9c, 0x9d, 0x9d, 0x9b, 0x9b, 0x9b, 0x9c, 0x9b, 0x98, 0x97, 0x98, 0x98, - 0x95, 0x90, 0x8d, 0x8a, 0x86, 0x80, 0x7b, 0x73, 0x6e, 0x6b, 0x68, 0x68, - 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x72, 0x72, 0x74, 0x74, - 0x74, 0x74, 0x74, 0x74, 0x72, 0x71, 0x72, 0x70, 0x6e, 0x6c, 0x6a, 0x68, - 0x64, 0x62, 0x5e, 0x5b, 0x58, 0x55, 0x50, 0x4b, 0x48, 0x42, 0x3b, 0x30, - 0x26, 0x20, 0x19, 0x13, 0x12, 0x12, 0x12, 0x10, 0x11, 0x10, 0x10, 0x11, - 0x12, 0x12, 0x13, 0x12, 0x11, 0x11, 0x11, 0x13, 0x11, 0x11, 0x13, 0x13, - 0x82, 0x83, 0x82, 0x82, 0x80, 0x80, 0x7f, 0x7d, 0x7c, 0x7b, 0x7b, 0x7a, - 0x7a, 0x7a, 0x79, 0x79, 0x78, 0x76, 0x75, 0x73, 0x72, 0x71, 0x71, 0x74, - 0x7a, 0x83, 0x89, 0x8c, 0x8e, 0x8f, 0x92, 0x93, 0x92, 0x91, 0x90, 0x8f, - 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8e, 0x8e, 0x8d, 0x8d, 0x8c, 0x8c, 0x8b, - 0x8b, 0x8b, 0x8a, 0x8a, 0x89, 0x88, 0x86, 0x84, 0x83, 0x83, 0x83, 0x82, - 0x83, 0x83, 0x83, 0x83, 0x84, 0x83, 0x84, 0x86, 0x86, 0x87, 0x88, 0x88, - 0x87, 0x87, 0x87, 0x85, 0x83, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, - 0x83, 0x82, 0x81, 0x82, 0x80, 0x7f, 0x7e, 0x7d, 0x7d, 0x7c, 0x7b, 0x7b, - 0x7b, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, - 0x7d, 0x7d, 0x7e, 0x80, 0x80, 0x81, 0x82, 0x83, 0x85, 0x87, 0x89, 0x8a, - 0x8b, 0x8c, 0x8d, 0x8d, 0x8d, 0x8d, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, - 0x8e, 0x8f, 0x90, 0x90, 0x91, 0x91, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, - 0x91, 0x91, 0x91, 0x91, 0x92, 0x91, 0x90, 0x90, 0x90, 0x91, 0x92, 0x91, - 0x90, 0x90, 0x91, 0x91, 0x90, 0x8f, 0x8f, 0x8d, 0x8e, 0x8f, 0x8f, 0x8e, - 0x8d, 0x8c, 0x8b, 0x8b, 0x8b, 0x8a, 0x8b, 0x8a, 0x8a, 0x88, 0x8a, 0x8a, - 0x8a, 0x8a, 0x87, 0x87, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8a, 0x8b, 0x8b, - 0x8b, 0x8c, 0x8d, 0x8f, 0x8f, 0x8f, 0x92, 0x92, 0x92, 0x92, 0x93, 0x96, - 0x98, 0x99, 0x9a, 0x9a, 0x99, 0x99, 0x9b, 0x9c, 0x9d, 0x9c, 0x9d, 0x9e, - 0x9e, 0x9d, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9c, 0x99, 0x99, 0x99, 0x99, - 0x99, 0x99, 0x9a, 0x9a, 0x9b, 0x9a, 0x9c, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, - 0x9c, 0x9c, 0x9d, 0x9c, 0x99, 0x98, 0x98, 0x98, 0x94, 0x8f, 0x8c, 0x89, - 0x84, 0x7f, 0x79, 0x71, 0x6c, 0x69, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, - 0x6c, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x74, 0x74, 0x73, 0x74, 0x74, - 0x72, 0x71, 0x72, 0x6f, 0x6e, 0x6c, 0x6a, 0x68, 0x64, 0x62, 0x5e, 0x5c, - 0x58, 0x55, 0x50, 0x4b, 0x48, 0x41, 0x3b, 0x30, 0x26, 0x20, 0x18, 0x13, - 0x12, 0x12, 0x12, 0x10, 0x11, 0x10, 0x10, 0x11, 0x12, 0x12, 0x13, 0x12, - 0x11, 0x11, 0x12, 0x13, 0x12, 0x12, 0x13, 0x14, 0x82, 0x82, 0x82, 0x81, - 0x80, 0x80, 0x7f, 0x7d, 0x7c, 0x7c, 0x7b, 0x7a, 0x7a, 0x7a, 0x79, 0x79, - 0x77, 0x77, 0x76, 0x73, 0x72, 0x71, 0x71, 0x73, 0x79, 0x82, 0x88, 0x8b, - 0x8c, 0x8e, 0x91, 0x92, 0x91, 0x91, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, - 0x8d, 0x8e, 0x8e, 0x8d, 0x8e, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, - 0x8a, 0x89, 0x87, 0x85, 0x84, 0x84, 0x84, 0x83, 0x84, 0x84, 0x83, 0x84, - 0x85, 0x85, 0x86, 0x87, 0x87, 0x87, 0x88, 0x89, 0x87, 0x88, 0x88, 0x86, - 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x83, 0x84, 0x84, 0x83, 0x83, 0x82, - 0x81, 0x80, 0x7f, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, - 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7b, 0x7d, 0x7d, 0x7e, 0x80, - 0x81, 0x82, 0x83, 0x83, 0x85, 0x87, 0x89, 0x8a, 0x8b, 0x8c, 0x8e, 0x8e, - 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x90, 0x8f, 0x90, 0x8f, 0x8f, 0x90, 0x91, - 0x91, 0x92, 0x94, 0x94, 0x93, 0x93, 0x93, 0x93, 0x91, 0x91, 0x91, 0x91, - 0x91, 0x91, 0x90, 0x90, 0x91, 0x91, 0x92, 0x91, 0x90, 0x90, 0x91, 0x91, - 0x91, 0x90, 0x8f, 0x8d, 0x8e, 0x8e, 0x8f, 0x8d, 0x8d, 0x8c, 0x8b, 0x8b, - 0x8b, 0x8a, 0x8a, 0x8a, 0x89, 0x88, 0x8a, 0x8a, 0x8a, 0x8a, 0x88, 0x87, - 0x86, 0x87, 0x88, 0x89, 0x8a, 0x89, 0x8a, 0x8b, 0x8b, 0x8d, 0x8d, 0x8f, - 0x8f, 0x8f, 0x91, 0x92, 0x92, 0x92, 0x93, 0x96, 0x98, 0x98, 0x99, 0x9a, - 0x99, 0x9a, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9d, 0x9c, 0x9c, - 0x9c, 0x9d, 0x9d, 0x9c, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, - 0x9b, 0x9a, 0x9b, 0x9d, 0x9d, 0x9c, 0x9b, 0x9c, 0x9b, 0x9c, 0x9d, 0x9c, - 0x9a, 0x9a, 0x99, 0x96, 0x92, 0x8d, 0x89, 0x87, 0x82, 0x7b, 0x76, 0x6e, - 0x69, 0x67, 0x66, 0x66, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6d, 0x6e, 0x6f, - 0x70, 0x70, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x72, 0x71, 0x71, 0x6f, - 0x6e, 0x6c, 0x6b, 0x69, 0x64, 0x61, 0x5e, 0x5c, 0x58, 0x55, 0x50, 0x4a, - 0x46, 0x42, 0x3a, 0x2f, 0x26, 0x20, 0x17, 0x13, 0x11, 0x11, 0x11, 0x10, - 0x11, 0x10, 0x10, 0x11, 0x11, 0x11, 0x12, 0x11, 0x11, 0x12, 0x12, 0x11, - 0x11, 0x11, 0x11, 0x14, 0x83, 0x83, 0x83, 0x82, 0x80, 0x7e, 0x7e, 0x7d, - 0x7c, 0x7d, 0x7d, 0x7b, 0x79, 0x79, 0x7a, 0x79, 0x78, 0x77, 0x76, 0x75, - 0x73, 0x72, 0x72, 0x73, 0x77, 0x80, 0x86, 0x89, 0x8a, 0x8c, 0x8f, 0x92, - 0x92, 0x91, 0x90, 0x8f, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, - 0x8e, 0x8d, 0x8e, 0x8e, 0x8f, 0x8e, 0x8c, 0x8c, 0x8c, 0x8b, 0x88, 0x87, - 0x86, 0x85, 0x84, 0x83, 0x84, 0x85, 0x86, 0x86, 0x85, 0x86, 0x88, 0x89, - 0x88, 0x88, 0x89, 0x8a, 0x89, 0x89, 0x89, 0x88, 0x87, 0x86, 0x86, 0x86, - 0x85, 0x86, 0x85, 0x86, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x7f, 0x7e, - 0x7e, 0x7e, 0x7e, 0x7c, 0x7c, 0x7e, 0x7e, 0x7e, 0x7d, 0x7d, 0x7b, 0x7b, - 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7f, 0x80, 0x81, 0x81, 0x82, 0x84, - 0x86, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x8f, - 0x8f, 0x90, 0x90, 0x90, 0x90, 0x90, 0x91, 0x91, 0x93, 0x93, 0x94, 0x94, - 0x94, 0x93, 0x93, 0x93, 0x92, 0x92, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, - 0x93, 0x93, 0x92, 0x92, 0x91, 0x90, 0x90, 0x90, 0x8f, 0x8e, 0x8f, 0x8e, - 0x8e, 0x8e, 0x8f, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8a, 0x8a, 0x8a, - 0x8b, 0x89, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x88, 0x87, 0x87, 0x88, 0x88, - 0x8a, 0x8a, 0x8a, 0x8a, 0x8c, 0x8d, 0x8c, 0x8e, 0x8e, 0x8f, 0x91, 0x92, - 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x97, 0x98, 0x9b, 0x9c, 0x9b, 0x9c, - 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9d, 0x9d, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, - 0x9c, 0x9c, 0x9b, 0x9b, 0x9a, 0x9b, 0x9b, 0x9b, 0x9a, 0x9c, 0x9b, 0x9b, - 0x9c, 0x9c, 0x9c, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9b, 0x9a, 0x96, - 0x91, 0x8b, 0x85, 0x82, 0x7d, 0x79, 0x72, 0x6b, 0x67, 0x66, 0x65, 0x66, - 0x68, 0x69, 0x69, 0x69, 0x6b, 0x6c, 0x6e, 0x6e, 0x6f, 0x70, 0x73, 0x74, - 0x74, 0x73, 0x73, 0x72, 0x72, 0x72, 0x71, 0x70, 0x6e, 0x6d, 0x6c, 0x69, - 0x64, 0x61, 0x5f, 0x5d, 0x58, 0x54, 0x4f, 0x4a, 0x46, 0x41, 0x38, 0x2f, - 0x26, 0x20, 0x19, 0x13, 0x11, 0x11, 0x10, 0x10, 0x11, 0x11, 0x10, 0x10, - 0x10, 0x11, 0x12, 0x11, 0x11, 0x12, 0x12, 0x11, 0x10, 0x11, 0x12, 0x13, - 0x84, 0x84, 0x83, 0x82, 0x80, 0x7e, 0x7e, 0x7d, 0x7d, 0x7e, 0x7d, 0x7b, - 0x79, 0x79, 0x79, 0x78, 0x79, 0x78, 0x77, 0x75, 0x73, 0x72, 0x72, 0x73, - 0x77, 0x7f, 0x85, 0x88, 0x8a, 0x8c, 0x8f, 0x92, 0x92, 0x91, 0x90, 0x8f, - 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8e, 0x8e, 0x8d, 0x8d, 0x8e, 0x8f, - 0x90, 0x8f, 0x8d, 0x8d, 0x8d, 0x8c, 0x8a, 0x88, 0x87, 0x86, 0x85, 0x86, - 0x85, 0x86, 0x87, 0x87, 0x87, 0x89, 0x8b, 0x8b, 0x8a, 0x8a, 0x8b, 0x8a, - 0x8a, 0x8b, 0x8a, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x87, 0x87, 0x87, - 0x88, 0x87, 0x85, 0x83, 0x82, 0x81, 0x81, 0x7f, 0x7f, 0x80, 0x80, 0x7e, - 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7d, - 0x7d, 0x7d, 0x80, 0x82, 0x82, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8a, - 0x8b, 0x8d, 0x8d, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x8f, - 0x91, 0x92, 0x92, 0x93, 0x94, 0x94, 0x93, 0x94, 0x94, 0x93, 0x94, 0x93, - 0x93, 0x93, 0x93, 0x93, 0x94, 0x93, 0x93, 0x92, 0x94, 0x94, 0x92, 0x91, - 0x91, 0x90, 0x90, 0x90, 0x8f, 0x8e, 0x8f, 0x8e, 0x8e, 0x8e, 0x8f, 0x8d, - 0x8d, 0x8d, 0x8c, 0x8d, 0x8c, 0x8a, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x8a, - 0x8a, 0x89, 0x89, 0x87, 0x87, 0x88, 0x87, 0x87, 0x88, 0x89, 0x89, 0x89, - 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x91, 0x92, 0x92, 0x93, 0x94, 0x95, - 0x95, 0x96, 0x97, 0x98, 0x9b, 0x9d, 0x9c, 0x9c, 0x9d, 0x9c, 0x9d, 0x9d, - 0x9d, 0x9d, 0x9d, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9b, 0x9a, - 0x9b, 0x9c, 0x9c, 0x9c, 0x9b, 0x9c, 0x9b, 0x9a, 0x9b, 0x9c, 0x9c, 0x9c, - 0x9c, 0x9c, 0x9e, 0x9e, 0x9c, 0x9a, 0x98, 0x94, 0x8e, 0x87, 0x81, 0x7e, - 0x7a, 0x75, 0x6e, 0x69, 0x65, 0x65, 0x65, 0x65, 0x66, 0x68, 0x69, 0x68, - 0x6a, 0x6b, 0x6d, 0x6e, 0x6d, 0x6e, 0x71, 0x73, 0x73, 0x72, 0x72, 0x72, - 0x72, 0x72, 0x71, 0x71, 0x6e, 0x6d, 0x6c, 0x68, 0x65, 0x62, 0x60, 0x5d, - 0x58, 0x54, 0x4f, 0x4b, 0x48, 0x41, 0x37, 0x2e, 0x26, 0x21, 0x18, 0x12, - 0x11, 0x10, 0x10, 0x11, 0x11, 0x12, 0x11, 0x10, 0x10, 0x11, 0x11, 0x12, - 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x83, 0x83, 0x83, 0x83, - 0x81, 0x7f, 0x7f, 0x7d, 0x7d, 0x7d, 0x7c, 0x7a, 0x7a, 0x79, 0x79, 0x78, - 0x79, 0x78, 0x77, 0x75, 0x73, 0x73, 0x72, 0x73, 0x77, 0x7e, 0x83, 0x86, - 0x88, 0x8b, 0x90, 0x93, 0x93, 0x92, 0x91, 0x8f, 0x8e, 0x8e, 0x8e, 0x8d, - 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8f, 0x8f, 0x90, 0x8f, 0x8e, 0x8d, - 0x8d, 0x8d, 0x8b, 0x89, 0x88, 0x87, 0x87, 0x87, 0x86, 0x86, 0x88, 0x88, - 0x89, 0x8a, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8c, 0x8b, 0x8a, 0x8a, 0x8a, - 0x89, 0x89, 0x8a, 0x8a, 0x89, 0x88, 0x87, 0x87, 0x88, 0x87, 0x85, 0x83, - 0x83, 0x82, 0x81, 0x80, 0x80, 0x81, 0x81, 0x7f, 0x7e, 0x7d, 0x7e, 0x7e, - 0x7e, 0x7e, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7f, 0x7f, 0x81, 0x82, - 0x83, 0x84, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8c, 0x8b, 0x8d, 0x8e, 0x8f, - 0x8f, 0x8f, 0x90, 0x90, 0x8f, 0x90, 0x90, 0x90, 0x91, 0x93, 0x93, 0x94, - 0x95, 0x95, 0x94, 0x95, 0x94, 0x94, 0x94, 0x94, 0x93, 0x92, 0x93, 0x93, - 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x91, 0x91, 0x90, 0x91, - 0x91, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, - 0x8d, 0x8b, 0x8b, 0x8b, 0x8b, 0x89, 0x8a, 0x89, 0x89, 0x88, 0x89, 0x88, - 0x88, 0x88, 0x88, 0x87, 0x88, 0x87, 0x88, 0x89, 0x8b, 0x8d, 0x8d, 0x8e, - 0x8f, 0x8f, 0x92, 0x92, 0x93, 0x93, 0x94, 0x95, 0x95, 0x96, 0x98, 0x99, - 0x9b, 0x9c, 0x9c, 0x9c, 0x9d, 0x9c, 0x9d, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b, - 0x9c, 0x9c, 0x9b, 0x9c, 0x9c, 0x9b, 0x9b, 0x9a, 0x9c, 0x9d, 0x9d, 0x9d, - 0x9c, 0x9b, 0x9c, 0x9b, 0x9c, 0x9d, 0x9c, 0x9c, 0x9c, 0x9d, 0x9f, 0x9e, - 0x9c, 0x99, 0x97, 0x93, 0x8c, 0x84, 0x7f, 0x7b, 0x78, 0x73, 0x6c, 0x66, - 0x64, 0x64, 0x65, 0x65, 0x66, 0x67, 0x68, 0x68, 0x68, 0x6a, 0x6b, 0x6c, - 0x6c, 0x6d, 0x70, 0x71, 0x71, 0x71, 0x71, 0x73, 0x73, 0x73, 0x72, 0x71, - 0x6f, 0x6d, 0x6c, 0x69, 0x66, 0x62, 0x60, 0x5e, 0x59, 0x54, 0x4f, 0x4a, - 0x46, 0x3f, 0x38, 0x2e, 0x27, 0x22, 0x19, 0x12, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x10, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x11, - 0x10, 0x11, 0x11, 0x10, 0x83, 0x83, 0x82, 0x82, 0x81, 0x7f, 0x7f, 0x7e, - 0x7d, 0x7d, 0x7c, 0x7b, 0x7a, 0x7a, 0x79, 0x78, 0x79, 0x78, 0x77, 0x75, - 0x73, 0x72, 0x72, 0x73, 0x77, 0x7d, 0x83, 0x85, 0x87, 0x8b, 0x90, 0x92, - 0x93, 0x92, 0x90, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, - 0x8e, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8c, 0x8a, - 0x89, 0x88, 0x88, 0x88, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, - 0x8e, 0x8e, 0x8e, 0x8d, 0x8c, 0x8b, 0x8b, 0x8a, 0x8a, 0x89, 0x8a, 0x8b, - 0x89, 0x88, 0x88, 0x88, 0x88, 0x87, 0x85, 0x83, 0x83, 0x83, 0x82, 0x81, - 0x81, 0x81, 0x81, 0x7f, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7c, 0x7c, - 0x7c, 0x7d, 0x7e, 0x7f, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x85, 0x86, 0x86, - 0x88, 0x8a, 0x8b, 0x8c, 0x8c, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x90, - 0x8f, 0x90, 0x90, 0x90, 0x92, 0x93, 0x93, 0x94, 0x95, 0x95, 0x94, 0x95, - 0x94, 0x94, 0x95, 0x95, 0x93, 0x92, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, - 0x93, 0x93, 0x92, 0x92, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x8f, - 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8b, 0x8b, 0x8b, - 0x8b, 0x8a, 0x89, 0x89, 0x88, 0x88, 0x89, 0x88, 0x88, 0x88, 0x87, 0x86, - 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x92, 0x93, - 0x94, 0x94, 0x95, 0x95, 0x96, 0x96, 0x97, 0x99, 0x9b, 0x9c, 0x9c, 0x9c, - 0x9d, 0x9c, 0x9d, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b, 0x9b, 0x9b, 0x9a, 0x9b, - 0x9b, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9d, 0x9c, - 0x9c, 0x9d, 0x9c, 0x9d, 0x9d, 0x9e, 0x9f, 0x9e, 0x9b, 0x98, 0x96, 0x91, - 0x8b, 0x82, 0x7c, 0x7a, 0x76, 0x71, 0x6a, 0x65, 0x63, 0x63, 0x64, 0x64, - 0x65, 0x66, 0x67, 0x67, 0x68, 0x69, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, - 0x71, 0x70, 0x70, 0x73, 0x73, 0x72, 0x72, 0x71, 0x6f, 0x6d, 0x6c, 0x69, - 0x67, 0x63, 0x60, 0x5e, 0x5a, 0x55, 0x4f, 0x4a, 0x46, 0x3f, 0x38, 0x2f, - 0x28, 0x22, 0x19, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, - 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, - 0x84, 0x84, 0x83, 0x82, 0x82, 0x80, 0x7f, 0x7f, 0x7e, 0x7d, 0x7c, 0x7c, - 0x7a, 0x7a, 0x79, 0x79, 0x79, 0x78, 0x76, 0x75, 0x74, 0x73, 0x71, 0x72, - 0x76, 0x7d, 0x81, 0x84, 0x86, 0x8a, 0x8e, 0x92, 0x93, 0x93, 0x91, 0x8f, - 0x8f, 0x8f, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x90, 0x8f, 0x8f, - 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8d, 0x8b, 0x8a, 0x8a, 0x8a, 0x89, - 0x89, 0x88, 0x8a, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x90, 0x8e, 0x8e, - 0x8e, 0x8d, 0x8c, 0x8c, 0x8b, 0x8a, 0x8b, 0x8b, 0x8a, 0x8a, 0x8b, 0x8a, - 0x89, 0x87, 0x86, 0x84, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x7f, - 0x7e, 0x7f, 0x7e, 0x7e, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, 0x7e, 0x7f, 0x80, - 0x80, 0x80, 0x81, 0x82, 0x84, 0x85, 0x86, 0x86, 0x89, 0x8a, 0x8b, 0x8b, - 0x8b, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x92, - 0x93, 0x94, 0x94, 0x93, 0x94, 0x94, 0x95, 0x95, 0x95, 0x94, 0x95, 0x95, - 0x94, 0x94, 0x94, 0x92, 0x93, 0x92, 0x92, 0x93, 0x93, 0x93, 0x92, 0x92, - 0x91, 0x91, 0x92, 0x91, 0x91, 0x8f, 0x90, 0x8f, 0x90, 0x90, 0x90, 0x8f, - 0x8f, 0x8e, 0x8d, 0x8e, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8a, 0x89, 0x89, - 0x89, 0x89, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x86, 0x87, 0x87, 0x87, 0x87, - 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x91, 0x94, 0x95, 0x95, 0x95, 0x96, - 0x96, 0x96, 0x96, 0x97, 0x9a, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9d, - 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9c, - 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, 0x9d, 0x9e, - 0x9e, 0x9e, 0x9e, 0x9d, 0x9a, 0x96, 0x93, 0x8f, 0x87, 0x7e, 0x78, 0x76, - 0x73, 0x6e, 0x66, 0x63, 0x62, 0x62, 0x63, 0x65, 0x66, 0x65, 0x66, 0x67, - 0x67, 0x69, 0x6b, 0x6c, 0x6d, 0x6d, 0x6f, 0x70, 0x70, 0x71, 0x71, 0x72, - 0x72, 0x71, 0x71, 0x70, 0x6e, 0x6d, 0x6c, 0x69, 0x67, 0x62, 0x5f, 0x5d, - 0x5a, 0x54, 0x4e, 0x4a, 0x46, 0x3f, 0x38, 0x2f, 0x27, 0x21, 0x1a, 0x12, - 0x10, 0x10, 0x10, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x12, - 0x12, 0x12, 0x10, 0x10, 0x11, 0x11, 0x11, 0x12, 0x84, 0x84, 0x83, 0x82, - 0x82, 0x7f, 0x7f, 0x7f, 0x7f, 0x7d, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x79, - 0x79, 0x78, 0x77, 0x76, 0x75, 0x73, 0x71, 0x71, 0x74, 0x7b, 0x7e, 0x82, - 0x84, 0x88, 0x8c, 0x91, 0x93, 0x93, 0x91, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, - 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8f, 0x90, 0x91, 0x91, 0x91, 0x91, 0x91, - 0x91, 0x91, 0x90, 0x8d, 0x8d, 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x8d, 0x8d, - 0x8d, 0x8f, 0x91, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8e, 0x8d, 0x8d, - 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8d, 0x8b, 0x8b, 0x89, 0x87, 0x86, - 0x84, 0x84, 0x83, 0x83, 0x83, 0x82, 0x81, 0x80, 0x80, 0x7f, 0x7e, 0x7d, - 0x7c, 0x7d, 0x7e, 0x7d, 0x7d, 0x7d, 0x7f, 0x80, 0x7f, 0x80, 0x81, 0x84, - 0x86, 0x87, 0x87, 0x87, 0x88, 0x8a, 0x8c, 0x8c, 0x8d, 0x8f, 0x90, 0x90, - 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x91, 0x93, 0x94, 0x95, 0x95, 0x95, - 0x95, 0x96, 0x94, 0x94, 0x94, 0x95, 0x94, 0x95, 0x94, 0x94, 0x94, 0x92, - 0x91, 0x91, 0x91, 0x91, 0x93, 0x92, 0x92, 0x91, 0x91, 0x91, 0x92, 0x91, - 0x91, 0x90, 0x90, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8e, 0x8d, 0x8d, - 0x8c, 0x8d, 0x8c, 0x8c, 0x8b, 0x8b, 0x89, 0x89, 0x89, 0x89, 0x8a, 0x89, - 0x88, 0x87, 0x86, 0x86, 0x87, 0x88, 0x87, 0x87, 0x89, 0x8c, 0x8c, 0x8d, - 0x8e, 0x8f, 0x91, 0x94, 0x95, 0x96, 0x95, 0x97, 0x97, 0x97, 0x96, 0x97, - 0x9a, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9d, 0x9e, 0x9d, 0x9c, 0x9b, - 0x9a, 0x99, 0x9a, 0x9b, 0x9a, 0x9a, 0x9a, 0x9d, 0x9e, 0x9d, 0x9d, 0x9d, - 0x9d, 0x9d, 0x9d, 0x9d, 0x9e, 0x9e, 0x9d, 0x9f, 0x9f, 0x9e, 0x9d, 0x9b, - 0x97, 0x93, 0x90, 0x8a, 0x81, 0x7a, 0x76, 0x73, 0x6f, 0x67, 0x62, 0x61, - 0x61, 0x61, 0x62, 0x64, 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x6b, 0x6b, - 0x6c, 0x6c, 0x6e, 0x6e, 0x6f, 0x6f, 0x70, 0x71, 0x71, 0x71, 0x70, 0x70, - 0x6e, 0x6e, 0x6d, 0x6a, 0x67, 0x61, 0x5f, 0x5c, 0x58, 0x52, 0x4e, 0x49, - 0x45, 0x3f, 0x38, 0x2e, 0x27, 0x22, 0x1b, 0x13, 0x10, 0x11, 0x11, 0x12, - 0x11, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x10, 0x10, - 0x11, 0x11, 0x12, 0x14, 0x83, 0x83, 0x83, 0x83, 0x81, 0x7f, 0x7f, 0x80, - 0x7f, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7c, 0x7b, 0x7a, 0x78, 0x78, 0x77, - 0x74, 0x71, 0x70, 0x71, 0x73, 0x78, 0x7c, 0x80, 0x83, 0x88, 0x8c, 0x90, - 0x93, 0x93, 0x93, 0x90, 0x8e, 0x8f, 0x8e, 0x8e, 0x8d, 0x8e, 0x8d, 0x8d, - 0x8e, 0x8f, 0x8f, 0x91, 0x92, 0x92, 0x93, 0x92, 0x92, 0x92, 0x91, 0x8f, - 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8f, 0x90, 0x91, 0x91, 0x93, 0x94, - 0x93, 0x92, 0x91, 0x90, 0x8e, 0x8e, 0x8e, 0x8f, 0x8d, 0x8c, 0x8c, 0x8c, - 0x8c, 0x8c, 0x8d, 0x8c, 0x8b, 0x89, 0x87, 0x86, 0x86, 0x85, 0x85, 0x85, - 0x84, 0x82, 0x81, 0x80, 0x80, 0x80, 0x7f, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, - 0x7e, 0x7e, 0x7e, 0x7f, 0x81, 0x81, 0x82, 0x84, 0x86, 0x87, 0x87, 0x88, - 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x8f, 0x8f, 0x8f, 0x90, 0x91, - 0x91, 0x92, 0x92, 0x94, 0x95, 0x96, 0x95, 0x95, 0x95, 0x96, 0x95, 0x95, - 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x94, 0x93, 0x91, 0x92, 0x92, 0x92, - 0x92, 0x93, 0x92, 0x92, 0x90, 0x91, 0x91, 0x90, 0x90, 0x8f, 0x8f, 0x8f, - 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8e, 0x8d, 0x8c, 0x8c, 0x8d, 0x8c, 0x8c, - 0x8c, 0x8c, 0x8b, 0x8b, 0x8a, 0x89, 0x89, 0x89, 0x87, 0x87, 0x85, 0x85, - 0x87, 0x88, 0x88, 0x87, 0x88, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x91, 0x94, - 0x95, 0x96, 0x96, 0x97, 0x98, 0x98, 0x98, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, - 0x9d, 0x9d, 0x9c, 0x9d, 0x9e, 0x9d, 0x9b, 0x9a, 0x9b, 0x9a, 0x99, 0x9a, - 0x9a, 0x9b, 0x9c, 0x9d, 0x9c, 0x9e, 0x9e, 0x9e, 0x9d, 0x9f, 0x9e, 0x9e, - 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x99, 0x95, 0x91, 0x8e, 0x86, - 0x7e, 0x77, 0x72, 0x6e, 0x69, 0x62, 0x60, 0x60, 0x61, 0x62, 0x63, 0x64, - 0x64, 0x65, 0x65, 0x67, 0x68, 0x69, 0x6b, 0x6b, 0x6c, 0x6c, 0x6d, 0x6d, - 0x6e, 0x6f, 0x6e, 0x6f, 0x70, 0x71, 0x71, 0x71, 0x6e, 0x6e, 0x6d, 0x69, - 0x67, 0x62, 0x5e, 0x5c, 0x58, 0x52, 0x4d, 0x4a, 0x46, 0x3f, 0x38, 0x2f, - 0x27, 0x22, 0x1a, 0x13, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x12, 0x11, 0x10, 0x10, 0x12, 0x13, 0x13, 0x12, 0x13, - 0x82, 0x82, 0x83, 0x83, 0x81, 0x80, 0x7f, 0x80, 0x7f, 0x7e, 0x7f, 0x7e, - 0x7d, 0x7d, 0x7d, 0x7b, 0x79, 0x79, 0x79, 0x77, 0x74, 0x71, 0x70, 0x70, - 0x71, 0x75, 0x7c, 0x7f, 0x82, 0x86, 0x8b, 0x8e, 0x91, 0x92, 0x92, 0x91, - 0x8f, 0x8f, 0x8e, 0x8d, 0x8e, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x90, 0x91, - 0x92, 0x92, 0x93, 0x93, 0x93, 0x93, 0x92, 0x90, 0x90, 0x91, 0x91, 0x91, - 0x91, 0x90, 0x91, 0x91, 0x93, 0x93, 0x94, 0x95, 0x93, 0x93, 0x93, 0x92, - 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8c, - 0x8b, 0x89, 0x87, 0x87, 0x86, 0x85, 0x85, 0x85, 0x83, 0x82, 0x81, 0x81, - 0x81, 0x7f, 0x80, 0x7f, 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, - 0x81, 0x82, 0x83, 0x84, 0x86, 0x87, 0x87, 0x88, 0x8a, 0x8a, 0x8c, 0x8d, - 0x8e, 0x8f, 0x90, 0x90, 0x90, 0x8f, 0x90, 0x90, 0x91, 0x92, 0x93, 0x95, - 0x96, 0x96, 0x95, 0x95, 0x95, 0x96, 0x97, 0x97, 0x97, 0x95, 0x94, 0x95, - 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x93, 0x92, 0x92, 0x91, 0x91, - 0x90, 0x91, 0x91, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x90, - 0x90, 0x8f, 0x8e, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8c, 0x8c, - 0x8b, 0x89, 0x89, 0x88, 0x87, 0x86, 0x85, 0x85, 0x87, 0x88, 0x87, 0x88, - 0x89, 0x8c, 0x8c, 0x8d, 0x8e, 0x8f, 0x91, 0x94, 0x96, 0x96, 0x96, 0x97, - 0x97, 0x98, 0x99, 0x98, 0x9a, 0x9c, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9d, - 0x9e, 0x9d, 0x9b, 0x99, 0x9a, 0x9a, 0x99, 0x99, 0x9a, 0x9b, 0x9d, 0x9d, - 0x9d, 0x9f, 0x9f, 0x9f, 0x9e, 0x9f, 0x9f, 0x9d, 0x9c, 0x9c, 0x9d, 0x9e, - 0x9d, 0x9c, 0x9b, 0x97, 0x91, 0x8d, 0x89, 0x82, 0x7a, 0x74, 0x6e, 0x6a, - 0x64, 0x5f, 0x5f, 0x60, 0x60, 0x61, 0x62, 0x63, 0x63, 0x64, 0x65, 0x65, - 0x67, 0x69, 0x6a, 0x6b, 0x6c, 0x6c, 0x6d, 0x6d, 0x6e, 0x6f, 0x6f, 0x6f, - 0x70, 0x71, 0x71, 0x70, 0x6e, 0x6e, 0x6d, 0x6a, 0x66, 0x62, 0x5e, 0x5c, - 0x59, 0x53, 0x4d, 0x49, 0x46, 0x40, 0x36, 0x2e, 0x26, 0x21, 0x1a, 0x14, - 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x12, 0x11, 0x82, 0x82, 0x83, 0x82, - 0x81, 0x80, 0x80, 0x80, 0x7f, 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7b, - 0x79, 0x79, 0x78, 0x77, 0x74, 0x72, 0x70, 0x70, 0x6f, 0x74, 0x7a, 0x7f, - 0x82, 0x85, 0x8a, 0x8d, 0x91, 0x92, 0x92, 0x92, 0x90, 0x8f, 0x8f, 0x8d, - 0x8d, 0x8d, 0x8e, 0x8e, 0x8d, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x94, - 0x94, 0x94, 0x92, 0x92, 0x91, 0x92, 0x92, 0x92, 0x92, 0x91, 0x92, 0x92, - 0x94, 0x95, 0x95, 0x95, 0x94, 0x93, 0x94, 0x92, 0x90, 0x8f, 0x8f, 0x90, - 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8d, 0x8c, 0x8c, 0x89, 0x87, 0x86, - 0x86, 0x85, 0x85, 0x85, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x80, 0x7f, - 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x82, 0x82, 0x82, 0x84, - 0x86, 0x87, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, - 0x91, 0x90, 0x90, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x96, 0x95, 0x96, - 0x95, 0x96, 0x97, 0x98, 0x97, 0x94, 0x94, 0x94, 0x93, 0x92, 0x92, 0x93, - 0x92, 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x91, 0x91, 0x92, 0x91, 0x90, - 0x90, 0x8f, 0x8f, 0x8e, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x8f, 0x8e, 0x8d, - 0x8c, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8c, 0x8c, 0x8b, 0x89, 0x89, 0x88, - 0x87, 0x86, 0x85, 0x85, 0x87, 0x87, 0x87, 0x88, 0x89, 0x8c, 0x8c, 0x8e, - 0x8e, 0x8f, 0x91, 0x94, 0x96, 0x96, 0x96, 0x96, 0x96, 0x98, 0x99, 0x98, - 0x99, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9c, 0x9d, 0x9e, 0x9d, 0x9b, 0x99, - 0x9a, 0x9a, 0x98, 0x98, 0x99, 0x9b, 0x9d, 0x9d, 0x9d, 0x9e, 0x9f, 0x9f, - 0x9e, 0xa0, 0x9f, 0x9d, 0x9c, 0x9c, 0x9e, 0x9e, 0x9c, 0x9b, 0x9a, 0x95, - 0x8f, 0x8a, 0x86, 0x7f, 0x78, 0x71, 0x6b, 0x67, 0x61, 0x5e, 0x5f, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x63, 0x64, 0x65, 0x65, 0x67, 0x6a, 0x69, 0x6a, - 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6f, 0x70, 0x6f, 0x70, 0x71, 0x70, 0x70, - 0x6e, 0x6e, 0x6d, 0x6b, 0x66, 0x62, 0x5e, 0x5c, 0x59, 0x53, 0x4d, 0x49, - 0x46, 0x3f, 0x36, 0x2e, 0x25, 0x20, 0x19, 0x14, 0x11, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x12, 0x12, 0x11, 0x82, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, - 0x7f, 0x7e, 0x7d, 0x7d, 0x7e, 0x7e, 0x7d, 0x7b, 0x78, 0x78, 0x77, 0x76, - 0x74, 0x72, 0x70, 0x6f, 0x6e, 0x72, 0x79, 0x7e, 0x81, 0x84, 0x88, 0x8c, - 0x90, 0x91, 0x92, 0x91, 0x8f, 0x8f, 0x8e, 0x8d, 0x8e, 0x8e, 0x8e, 0x8f, - 0x8e, 0x90, 0x90, 0x91, 0x92, 0x94, 0x95, 0x94, 0x95, 0x95, 0x94, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x93, 0x94, 0x94, 0x94, 0x95, 0x96, 0x96, 0x96, - 0x95, 0x94, 0x94, 0x93, 0x91, 0x91, 0x91, 0x91, 0x90, 0x8f, 0x90, 0x90, - 0x8f, 0x8f, 0x8e, 0x8d, 0x8c, 0x8a, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, - 0x84, 0x83, 0x83, 0x82, 0x82, 0x81, 0x80, 0x7f, 0x7d, 0x7d, 0x7e, 0x7d, - 0x7d, 0x7d, 0x7f, 0x81, 0x81, 0x82, 0x83, 0x84, 0x86, 0x86, 0x87, 0x88, - 0x8a, 0x8b, 0x8c, 0x8d, 0x8d, 0x8e, 0x8f, 0x91, 0x91, 0x91, 0x91, 0x90, - 0x92, 0x93, 0x94, 0x94, 0x95, 0x96, 0x96, 0x96, 0x95, 0x96, 0x98, 0x98, - 0x97, 0x95, 0x94, 0x95, 0x94, 0x93, 0x93, 0x93, 0x91, 0x91, 0x92, 0x93, - 0x93, 0x93, 0x92, 0x92, 0x91, 0x92, 0x91, 0x90, 0x90, 0x8f, 0x90, 0x8f, - 0x8f, 0x8f, 0x90, 0x8f, 0x8f, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, - 0x8c, 0x8d, 0x8b, 0x8c, 0x8b, 0x8a, 0x8a, 0x89, 0x88, 0x87, 0x85, 0x85, - 0x87, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8c, 0x8e, 0x8e, 0x8f, 0x91, 0x94, - 0x94, 0x95, 0x95, 0x96, 0x96, 0x98, 0x99, 0x97, 0x98, 0x9b, 0x9b, 0x9b, - 0x9c, 0x9c, 0x9c, 0x9d, 0x9e, 0x9d, 0x9b, 0x9a, 0x9a, 0x9a, 0x99, 0x99, - 0x99, 0x9b, 0x9c, 0x9d, 0x9d, 0x9e, 0x9f, 0xa0, 0xa0, 0x9f, 0x9f, 0x9e, - 0x9d, 0x9c, 0x9e, 0x9e, 0x9b, 0x99, 0x97, 0x93, 0x8b, 0x86, 0x82, 0x7b, - 0x75, 0x6d, 0x66, 0x62, 0x5d, 0x5b, 0x5d, 0x5e, 0x5e, 0x60, 0x61, 0x61, - 0x63, 0x64, 0x66, 0x67, 0x68, 0x69, 0x69, 0x69, 0x6b, 0x6b, 0x6d, 0x6d, - 0x6e, 0x70, 0x70, 0x6f, 0x70, 0x70, 0x6f, 0x6f, 0x6e, 0x6e, 0x6d, 0x6a, - 0x66, 0x62, 0x5e, 0x5c, 0x59, 0x53, 0x4c, 0x48, 0x45, 0x3e, 0x35, 0x2e, - 0x26, 0x20, 0x19, 0x13, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x7f, 0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, - 0x7e, 0x7e, 0x7c, 0x7c, 0x79, 0x77, 0x77, 0x76, 0x73, 0x71, 0x6d, 0x6c, - 0x6c, 0x6f, 0x76, 0x7c, 0x7e, 0x82, 0x86, 0x8b, 0x8e, 0x8f, 0x91, 0x91, - 0x91, 0x90, 0x8f, 0x8e, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8f, 0x90, 0x92, - 0x93, 0x93, 0x95, 0x95, 0x96, 0x96, 0x95, 0x95, 0x95, 0x96, 0x96, 0x96, - 0x95, 0x97, 0x97, 0x97, 0x97, 0x97, 0x98, 0x97, 0x96, 0x96, 0x95, 0x94, - 0x93, 0x93, 0x92, 0x91, 0x92, 0x91, 0x90, 0x90, 0x91, 0x8f, 0x8f, 0x8e, - 0x8d, 0x8a, 0x89, 0x88, 0x87, 0x87, 0x87, 0x87, 0x84, 0x83, 0x83, 0x84, - 0x82, 0x81, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x7e, 0x7e, 0x7f, 0x81, - 0x81, 0x82, 0x84, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8e, 0x8d, - 0x8d, 0x8e, 0x90, 0x90, 0x91, 0x91, 0x90, 0x91, 0x93, 0x95, 0x95, 0x95, - 0x95, 0x95, 0x96, 0x96, 0x96, 0x97, 0x98, 0x98, 0x98, 0x98, 0x97, 0x95, - 0x94, 0x94, 0x94, 0x92, 0x91, 0x91, 0x92, 0x93, 0x94, 0x93, 0x92, 0x91, - 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x91, 0x90, 0x8f, 0x8f, 0x8f, 0x8d, - 0x8d, 0x8c, 0x8d, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8c, 0x8c, 0x8c, 0x8c, - 0x8b, 0x8b, 0x8b, 0x8a, 0x88, 0x87, 0x86, 0x86, 0x86, 0x86, 0x87, 0x89, - 0x8a, 0x8c, 0x8c, 0x8d, 0x8f, 0x90, 0x93, 0x94, 0x94, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x98, 0x97, 0x98, 0x9a, 0x9a, 0x9a, 0x9c, 0x9c, 0x9c, 0x9c, - 0x9c, 0x9b, 0x9b, 0x9a, 0x9b, 0x9b, 0x9b, 0x99, 0x99, 0x9b, 0x9c, 0x9e, - 0x9e, 0x9e, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x9f, 0x9e, 0x9d, 0x9c, 0x9b, - 0x98, 0x96, 0x93, 0x8e, 0x87, 0x82, 0x7e, 0x77, 0x6f, 0x66, 0x60, 0x5e, - 0x5b, 0x5b, 0x5b, 0x5d, 0x5e, 0x5f, 0x61, 0x62, 0x62, 0x64, 0x65, 0x67, - 0x67, 0x69, 0x69, 0x6a, 0x6c, 0x6d, 0x6c, 0x6d, 0x6d, 0x6f, 0x6f, 0x70, - 0x70, 0x70, 0x70, 0x6e, 0x6e, 0x6d, 0x6c, 0x68, 0x66, 0x62, 0x5e, 0x5c, - 0x58, 0x54, 0x4d, 0x48, 0x44, 0x3e, 0x36, 0x2f, 0x27, 0x21, 0x1a, 0x13, - 0x11, 0x11, 0x10, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, 0x13, - 0x13, 0x13, 0x12, 0x11, 0x11, 0x11, 0x11, 0x12, 0x7f, 0x80, 0x82, 0x82, - 0x82, 0x83, 0x82, 0x80, 0x80, 0x80, 0x7f, 0x7e, 0x7e, 0x7e, 0x7d, 0x7b, - 0x79, 0x78, 0x77, 0x76, 0x72, 0x6e, 0x6c, 0x6c, 0x6b, 0x6d, 0x74, 0x79, - 0x7c, 0x80, 0x85, 0x8a, 0x8c, 0x8e, 0x90, 0x91, 0x91, 0x90, 0x8f, 0x90, - 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x97, 0x97, 0x96, 0x96, 0x98, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, - 0x98, 0x99, 0x99, 0x99, 0x97, 0x97, 0x96, 0x95, 0x93, 0x94, 0x94, 0x94, - 0x94, 0x93, 0x92, 0x92, 0x92, 0x91, 0x8f, 0x8e, 0x8c, 0x8a, 0x89, 0x89, - 0x89, 0x89, 0x89, 0x88, 0x85, 0x84, 0x84, 0x84, 0x82, 0x81, 0x80, 0x7f, - 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x81, 0x81, 0x82, 0x82, 0x82, 0x83, 0x87, - 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x8d, 0x8e, 0x8e, 0x8d, 0x8e, 0x90, 0x91, - 0x92, 0x92, 0x92, 0x91, 0x92, 0x95, 0x95, 0x95, 0x96, 0x95, 0x96, 0x96, - 0x96, 0x96, 0x98, 0x98, 0x98, 0x99, 0x99, 0x96, 0x95, 0x94, 0x94, 0x92, - 0x91, 0x91, 0x92, 0x93, 0x94, 0x93, 0x92, 0x91, 0x91, 0x91, 0x91, 0x91, - 0x91, 0x91, 0x92, 0x91, 0x8f, 0x8e, 0x8e, 0x8d, 0x8d, 0x8c, 0x8d, 0x8e, - 0x8e, 0x8e, 0x8e, 0x8e, 0x8c, 0x8b, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8a, - 0x88, 0x87, 0x86, 0x86, 0x86, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, - 0x8f, 0x90, 0x92, 0x92, 0x94, 0x96, 0x97, 0x97, 0x97, 0x98, 0x98, 0x97, - 0x98, 0x9a, 0x9a, 0x9a, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9a, - 0x9b, 0x9b, 0x9b, 0x99, 0x99, 0x9a, 0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa1, - 0xa1, 0x9f, 0x9f, 0xa0, 0x9f, 0x9d, 0x9b, 0x98, 0x95, 0x92, 0x8e, 0x88, - 0x82, 0x7d, 0x79, 0x72, 0x6a, 0x61, 0x5c, 0x5a, 0x59, 0x59, 0x59, 0x5c, - 0x5f, 0x61, 0x61, 0x62, 0x62, 0x64, 0x65, 0x67, 0x67, 0x69, 0x69, 0x6a, - 0x6c, 0x6d, 0x6c, 0x6d, 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x70, 0x6e, - 0x6e, 0x6e, 0x6c, 0x68, 0x66, 0x62, 0x5c, 0x5a, 0x57, 0x54, 0x4d, 0x48, - 0x45, 0x3f, 0x36, 0x2d, 0x27, 0x22, 0x1a, 0x13, 0x11, 0x11, 0x10, 0x11, - 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x13, 0x13, 0x13, 0x13, 0x12, 0x13, - 0x12, 0x12, 0x11, 0x13, 0x80, 0x80, 0x82, 0x83, 0x82, 0x83, 0x83, 0x82, - 0x82, 0x80, 0x80, 0x7f, 0x7e, 0x7e, 0x7d, 0x7b, 0x79, 0x79, 0x78, 0x75, - 0x70, 0x6c, 0x6b, 0x6b, 0x6a, 0x6c, 0x73, 0x77, 0x7a, 0x7e, 0x83, 0x89, - 0x8b, 0x8d, 0x8f, 0x90, 0x91, 0x91, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, - 0x8e, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x97, 0x97, 0x97, 0x98, 0x98, - 0x97, 0x99, 0x9a, 0x99, 0x9a, 0x9a, 0x9b, 0x9a, 0x9a, 0x99, 0x99, 0x99, - 0x99, 0x97, 0x96, 0x95, 0x94, 0x94, 0x94, 0x95, 0x94, 0x94, 0x93, 0x93, - 0x92, 0x92, 0x90, 0x8e, 0x8d, 0x8b, 0x8a, 0x89, 0x8a, 0x8a, 0x8a, 0x89, - 0x86, 0x86, 0x85, 0x85, 0x82, 0x80, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x81, 0x82, 0x83, 0x82, 0x83, 0x84, 0x87, 0x89, 0x8a, 0x8a, 0x8b, - 0x8a, 0x8c, 0x8e, 0x8e, 0x8e, 0x8e, 0x91, 0x92, 0x92, 0x93, 0x92, 0x92, - 0x93, 0x95, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x97, 0x97, 0x99, 0x99, - 0x99, 0x99, 0x99, 0x97, 0x96, 0x96, 0x95, 0x93, 0x92, 0x92, 0x92, 0x93, - 0x93, 0x93, 0x92, 0x92, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, - 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8f, 0x8e, 0x8d, 0x8d, 0x8e, - 0x8c, 0x8c, 0x8c, 0x8d, 0x8c, 0x8d, 0x8b, 0x89, 0x88, 0x88, 0x87, 0x87, - 0x87, 0x87, 0x88, 0x89, 0x8a, 0x8a, 0x8c, 0x8d, 0x8f, 0x8f, 0x91, 0x93, - 0x95, 0x96, 0x98, 0x99, 0x98, 0x99, 0x99, 0x98, 0x99, 0x9a, 0x9b, 0x9c, - 0x9d, 0x9d, 0x9c, 0x9d, 0x9d, 0x9b, 0x9b, 0x9a, 0x9a, 0x9b, 0x9b, 0x9a, - 0x9a, 0x9c, 0x9c, 0x9e, 0xa0, 0xa1, 0xa1, 0xa1, 0xa0, 0x9f, 0xa0, 0x9f, - 0x9f, 0x9d, 0x9a, 0x96, 0x92, 0x8f, 0x8b, 0x84, 0x7d, 0x78, 0x76, 0x6f, - 0x65, 0x5c, 0x59, 0x58, 0x58, 0x57, 0x59, 0x5c, 0x5f, 0x60, 0x61, 0x61, - 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6c, 0x6d, - 0x6d, 0x6e, 0x6e, 0x70, 0x70, 0x70, 0x70, 0x6f, 0x6e, 0x6e, 0x6c, 0x68, - 0x64, 0x61, 0x5c, 0x5a, 0x57, 0x54, 0x4d, 0x48, 0x44, 0x3e, 0x38, 0x2e, - 0x25, 0x21, 0x1b, 0x14, 0x11, 0x11, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, - 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x12, 0x12, 0x14, - 0x80, 0x81, 0x82, 0x83, 0x83, 0x84, 0x83, 0x83, 0x82, 0x80, 0x80, 0x7f, - 0x7f, 0x7e, 0x7d, 0x7b, 0x79, 0x78, 0x77, 0x74, 0x6f, 0x6c, 0x6b, 0x6a, - 0x6a, 0x6b, 0x72, 0x76, 0x79, 0x7c, 0x82, 0x88, 0x8b, 0x8c, 0x8e, 0x8f, - 0x91, 0x91, 0x91, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x92, 0x92, - 0x93, 0x95, 0x96, 0x97, 0x97, 0x97, 0x98, 0x98, 0x99, 0x9a, 0x9b, 0x9a, - 0x9b, 0x9b, 0x9b, 0x9c, 0x9b, 0x9a, 0x99, 0x99, 0x99, 0x98, 0x95, 0x95, - 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x93, 0x93, 0x93, 0x93, 0x91, 0x8e, - 0x8d, 0x8b, 0x8a, 0x89, 0x8a, 0x89, 0x89, 0x89, 0x87, 0x86, 0x86, 0x85, - 0x83, 0x80, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x82, 0x82, - 0x82, 0x83, 0x85, 0x87, 0x89, 0x8a, 0x8a, 0x8b, 0x8a, 0x8c, 0x8e, 0x8f, - 0x8f, 0x8f, 0x90, 0x92, 0x92, 0x93, 0x93, 0x93, 0x94, 0x95, 0x95, 0x96, - 0x96, 0x97, 0x96, 0x97, 0x97, 0x98, 0x99, 0x99, 0x99, 0x99, 0x98, 0x97, - 0x97, 0x96, 0x95, 0x94, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, - 0x91, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8e, - 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, - 0x8d, 0x8d, 0x8a, 0x88, 0x88, 0x88, 0x87, 0x88, 0x87, 0x87, 0x88, 0x88, - 0x8a, 0x8a, 0x8c, 0x8e, 0x8f, 0x8f, 0x90, 0x93, 0x95, 0x96, 0x98, 0x99, - 0x98, 0x99, 0x99, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9d, - 0x9d, 0x9c, 0x9b, 0x9a, 0x9a, 0x9b, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, - 0xa0, 0xa1, 0xa1, 0xa1, 0xa0, 0x9f, 0xa0, 0x9f, 0x9e, 0x9c, 0x98, 0x94, - 0x90, 0x8d, 0x89, 0x81, 0x79, 0x75, 0x72, 0x6c, 0x62, 0x5a, 0x58, 0x58, - 0x58, 0x57, 0x59, 0x5c, 0x5f, 0x60, 0x60, 0x61, 0x64, 0x66, 0x67, 0x67, - 0x68, 0x69, 0x6a, 0x6a, 0x6b, 0x6d, 0x6c, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f, - 0x70, 0x70, 0x70, 0x6f, 0x6e, 0x6e, 0x6c, 0x68, 0x63, 0x61, 0x5d, 0x5b, - 0x57, 0x53, 0x4c, 0x48, 0x45, 0x3f, 0x39, 0x2e, 0x25, 0x20, 0x1b, 0x14, - 0x11, 0x11, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, - 0x11, 0x11, 0x13, 0x13, 0x12, 0x12, 0x13, 0x14, 0x81, 0x82, 0x82, 0x82, - 0x83, 0x84, 0x83, 0x83, 0x82, 0x81, 0x81, 0x7f, 0x7e, 0x7e, 0x7c, 0x7b, - 0x78, 0x77, 0x76, 0x74, 0x6f, 0x6c, 0x6a, 0x6a, 0x6a, 0x6a, 0x6f, 0x74, - 0x77, 0x7a, 0x81, 0x87, 0x8a, 0x8b, 0x8c, 0x8e, 0x91, 0x92, 0x91, 0x90, - 0x8f, 0x90, 0x8f, 0x90, 0x8f, 0x91, 0x92, 0x92, 0x93, 0x95, 0x95, 0x97, - 0x97, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, - 0x9c, 0x9b, 0x99, 0x9a, 0x99, 0x98, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, - 0x93, 0x94, 0x94, 0x93, 0x92, 0x92, 0x90, 0x8e, 0x8d, 0x8c, 0x8b, 0x89, - 0x89, 0x89, 0x88, 0x89, 0x87, 0x86, 0x86, 0x85, 0x82, 0x81, 0x7f, 0x7f, - 0x80, 0x80, 0x7f, 0x7f, 0x80, 0x80, 0x81, 0x81, 0x82, 0x83, 0x85, 0x87, - 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8c, 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x91, - 0x92, 0x93, 0x94, 0x93, 0x95, 0x95, 0x96, 0x97, 0x97, 0x98, 0x97, 0x97, - 0x97, 0x98, 0x9a, 0x9a, 0x99, 0x98, 0x98, 0x97, 0x97, 0x96, 0x95, 0x94, - 0x93, 0x93, 0x93, 0x91, 0x91, 0x92, 0x91, 0x91, 0x90, 0x8f, 0x8f, 0x8f, - 0x8f, 0x8f, 0x8f, 0x90, 0x8f, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, - 0x8f, 0x8d, 0x8c, 0x8d, 0x8e, 0x8d, 0x8c, 0x8d, 0x8d, 0x8c, 0x8a, 0x87, - 0x88, 0x87, 0x87, 0x87, 0x86, 0x87, 0x87, 0x88, 0x8a, 0x8a, 0x8d, 0x8e, - 0x8e, 0x8f, 0x90, 0x92, 0x94, 0x96, 0x98, 0x99, 0x98, 0x99, 0x98, 0x98, - 0x98, 0x99, 0x9b, 0x9b, 0x9a, 0x9a, 0x9b, 0x9c, 0x9c, 0x9c, 0x9a, 0x99, - 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9d, 0x9e, 0x9e, 0xa0, 0xa0, 0xa1, 0xa2, - 0xa2, 0xa0, 0xa0, 0x9e, 0x9d, 0x9a, 0x94, 0x90, 0x8c, 0x89, 0x85, 0x7d, - 0x75, 0x71, 0x6e, 0x66, 0x5c, 0x58, 0x57, 0x57, 0x57, 0x57, 0x5a, 0x5b, - 0x5e, 0x5e, 0x5f, 0x60, 0x64, 0x65, 0x66, 0x67, 0x67, 0x69, 0x68, 0x69, - 0x6a, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6f, 0x6f, 0x6f, 0x6f, 0x70, - 0x6e, 0x6d, 0x6b, 0x67, 0x63, 0x61, 0x5d, 0x5b, 0x56, 0x51, 0x4b, 0x47, - 0x45, 0x40, 0x38, 0x2e, 0x25, 0x20, 0x1a, 0x14, 0x11, 0x11, 0x11, 0x10, - 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, - 0x12, 0x12, 0x13, 0x12, 0x84, 0x84, 0x83, 0x84, 0x84, 0x85, 0x84, 0x84, - 0x84, 0x83, 0x81, 0x7f, 0x7e, 0x7c, 0x7b, 0x79, 0x76, 0x75, 0x74, 0x72, - 0x70, 0x6d, 0x6b, 0x6a, 0x6a, 0x6a, 0x6c, 0x70, 0x74, 0x77, 0x7f, 0x84, - 0x87, 0x88, 0x8a, 0x8e, 0x91, 0x92, 0x92, 0x91, 0x8f, 0x8e, 0x8f, 0x8f, - 0x8f, 0x90, 0x90, 0x92, 0x93, 0x95, 0x96, 0x96, 0x96, 0x97, 0x97, 0x99, - 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9b, 0x9a, 0x9a, - 0x9a, 0x9a, 0x98, 0x97, 0x97, 0x97, 0x97, 0x95, 0x93, 0x93, 0x93, 0x93, - 0x92, 0x91, 0x8f, 0x8d, 0x8c, 0x8c, 0x8a, 0x8a, 0x8a, 0x8a, 0x89, 0x89, - 0x87, 0x85, 0x85, 0x84, 0x82, 0x81, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x80, - 0x80, 0x81, 0x82, 0x82, 0x82, 0x83, 0x85, 0x87, 0x89, 0x89, 0x89, 0x8a, - 0x8a, 0x8c, 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x91, 0x92, 0x94, 0x94, 0x92, - 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x99, 0x98, 0x98, 0x98, 0x99, 0x9a, - 0x9a, 0x98, 0x97, 0x96, 0x97, 0x97, 0x95, 0x95, 0x93, 0x93, 0x93, 0x91, - 0x92, 0x92, 0x92, 0x91, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, - 0x90, 0x8f, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, 0x8d, 0x8d, - 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8c, 0x8a, 0x87, 0x88, 0x87, 0x87, 0x87, - 0x86, 0x86, 0x87, 0x88, 0x8a, 0x8a, 0x8c, 0x8e, 0x8f, 0x8f, 0x90, 0x93, - 0x94, 0x96, 0x98, 0x99, 0x98, 0x99, 0x99, 0x98, 0x98, 0x97, 0x99, 0x99, - 0x99, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9a, 0x99, 0x9a, 0x9a, 0x9a, 0x99, - 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa2, 0xa2, 0xa2, 0xa1, 0x9e, 0x9b, - 0x9a, 0x97, 0x91, 0x8b, 0x87, 0x84, 0x7e, 0x77, 0x70, 0x6a, 0x66, 0x5f, - 0x58, 0x56, 0x56, 0x56, 0x57, 0x57, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x60, - 0x62, 0x64, 0x65, 0x66, 0x66, 0x68, 0x68, 0x69, 0x6b, 0x6d, 0x6c, 0x6d, - 0x6d, 0x6d, 0x6d, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6e, 0x6d, 0x6b, 0x68, - 0x65, 0x61, 0x5d, 0x5a, 0x55, 0x50, 0x4b, 0x47, 0x45, 0x40, 0x37, 0x2d, - 0x26, 0x20, 0x1a, 0x13, 0x12, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, - 0x11, 0x11, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, - 0x84, 0x85, 0x86, 0x86, 0x85, 0x85, 0x85, 0x84, 0x83, 0x82, 0x80, 0x7e, - 0x7e, 0x7c, 0x79, 0x77, 0x75, 0x74, 0x73, 0x72, 0x70, 0x6e, 0x6d, 0x6c, - 0x6a, 0x68, 0x6a, 0x6d, 0x71, 0x75, 0x7b, 0x80, 0x83, 0x85, 0x88, 0x8c, - 0x8f, 0x92, 0x93, 0x93, 0x91, 0x91, 0x91, 0x90, 0x8f, 0x90, 0x91, 0x93, - 0x94, 0x94, 0x96, 0x96, 0x96, 0x97, 0x99, 0x9a, 0x9c, 0x9c, 0x9d, 0x9f, - 0x9f, 0xa0, 0xa0, 0xa0, 0x9e, 0x9b, 0x9b, 0x9c, 0x9b, 0x9a, 0x9a, 0x98, - 0x97, 0x97, 0x97, 0x96, 0x96, 0x94, 0x94, 0x94, 0x92, 0x91, 0x8f, 0x8e, - 0x8e, 0x8d, 0x8b, 0x8a, 0x8a, 0x8a, 0x89, 0x8a, 0x88, 0x87, 0x85, 0x84, - 0x82, 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x7f, 0x80, 0x81, 0x83, 0x83, - 0x84, 0x84, 0x84, 0x86, 0x89, 0x89, 0x89, 0x89, 0x8b, 0x8b, 0x8d, 0x8e, - 0x90, 0x90, 0x91, 0x92, 0x93, 0x93, 0x94, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x99, 0x9a, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x99, 0x98, 0x98, - 0x97, 0x96, 0x97, 0x96, 0x93, 0x93, 0x93, 0x91, 0x92, 0x92, 0x92, 0x92, - 0x91, 0x91, 0x91, 0x91, 0x91, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x8f, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8c, 0x8d, - 0x8d, 0x8b, 0x8b, 0x89, 0x89, 0x88, 0x87, 0x87, 0x88, 0x88, 0x88, 0x87, - 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x93, 0x95, 0x96, 0x97, 0x97, - 0x98, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x99, 0x9a, 0x99, 0x9a, - 0x9b, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9e, - 0xa0, 0xa0, 0xa2, 0xa2, 0xa1, 0xa0, 0x9c, 0x99, 0x97, 0x93, 0x8e, 0x86, - 0x81, 0x7d, 0x78, 0x73, 0x6a, 0x64, 0x60, 0x5a, 0x55, 0x54, 0x55, 0x56, - 0x57, 0x57, 0x58, 0x5a, 0x5c, 0x5d, 0x5d, 0x5f, 0x62, 0x64, 0x65, 0x65, - 0x67, 0x67, 0x69, 0x6a, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, 0x6f, 0x6f, 0x71, - 0x71, 0x71, 0x70, 0x6f, 0x6d, 0x6c, 0x6b, 0x67, 0x64, 0x5e, 0x5b, 0x58, - 0x56, 0x51, 0x4b, 0x47, 0x44, 0x3f, 0x38, 0x30, 0x26, 0x20, 0x1a, 0x14, - 0x12, 0x11, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x12, 0x12, 0x11, 0x12, 0x12, 0x13, 0x13, 0x12, 0x86, 0x86, 0x87, 0x87, - 0x86, 0x85, 0x85, 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7b, 0x77, 0x76, - 0x75, 0x74, 0x74, 0x72, 0x70, 0x70, 0x6e, 0x6d, 0x6a, 0x68, 0x69, 0x6b, - 0x6d, 0x72, 0x78, 0x7d, 0x81, 0x83, 0x87, 0x8a, 0x8e, 0x92, 0x93, 0x93, - 0x93, 0x93, 0x92, 0x91, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x95, - 0x96, 0x97, 0x99, 0x9b, 0x9d, 0x9d, 0x9e, 0xa0, 0xa1, 0xa1, 0xa1, 0xa1, - 0x9f, 0x9d, 0x9d, 0x9d, 0x9c, 0x9b, 0x9b, 0x99, 0x98, 0x99, 0x98, 0x96, - 0x96, 0x94, 0x94, 0x94, 0x93, 0x92, 0x90, 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, - 0x8b, 0x8a, 0x89, 0x8a, 0x89, 0x87, 0x86, 0x85, 0x82, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x82, 0x83, 0x84, 0x84, 0x84, 0x86, - 0x89, 0x89, 0x8a, 0x8a, 0x8b, 0x8b, 0x8d, 0x8e, 0x90, 0x90, 0x91, 0x93, - 0x93, 0x94, 0x95, 0x94, 0x95, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9a, 0x9a, - 0x99, 0x9a, 0x9b, 0x9a, 0x9a, 0x99, 0x98, 0x98, 0x97, 0x97, 0x97, 0x97, - 0x93, 0x92, 0x92, 0x91, 0x91, 0x93, 0x93, 0x92, 0x91, 0x92, 0x92, 0x91, - 0x91, 0x90, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91, 0x91, 0x8f, 0x8e, 0x8f, - 0x8f, 0x90, 0x90, 0x90, 0x90, 0x8e, 0x8d, 0x8e, 0x8e, 0x8c, 0x8a, 0x89, - 0x89, 0x89, 0x89, 0x87, 0x88, 0x88, 0x88, 0x87, 0x89, 0x89, 0x8b, 0x8d, - 0x8e, 0x8f, 0x91, 0x94, 0x96, 0x96, 0x97, 0x97, 0x98, 0x99, 0x99, 0x99, - 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9b, 0x9a, 0x99, 0x99, - 0x9b, 0x9b, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9f, 0xa0, 0xa0, 0xa1, 0xa2, - 0xa0, 0x9d, 0x9a, 0x97, 0x94, 0x8f, 0x89, 0x81, 0x7b, 0x78, 0x74, 0x6e, - 0x65, 0x60, 0x5c, 0x58, 0x55, 0x54, 0x55, 0x56, 0x57, 0x57, 0x57, 0x59, - 0x5c, 0x5d, 0x5d, 0x5f, 0x61, 0x64, 0x64, 0x64, 0x67, 0x68, 0x68, 0x69, - 0x6b, 0x6c, 0x6d, 0x6d, 0x6d, 0x6f, 0x70, 0x71, 0x71, 0x71, 0x70, 0x6f, - 0x6e, 0x6c, 0x6b, 0x68, 0x64, 0x5e, 0x5a, 0x58, 0x56, 0x52, 0x4b, 0x47, - 0x45, 0x40, 0x39, 0x31, 0x27, 0x21, 0x1b, 0x14, 0x12, 0x11, 0x10, 0x10, - 0x10, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, 0x12, - 0x12, 0x12, 0x13, 0x13, 0x87, 0x87, 0x87, 0x87, 0x86, 0x86, 0x85, 0x84, - 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7a, 0x77, 0x75, 0x76, 0x75, 0x74, 0x72, - 0x70, 0x6f, 0x6e, 0x6d, 0x6b, 0x69, 0x68, 0x69, 0x6b, 0x6f, 0x76, 0x7c, - 0x80, 0x82, 0x86, 0x89, 0x8e, 0x91, 0x93, 0x93, 0x95, 0x95, 0x93, 0x92, - 0x91, 0x92, 0x92, 0x93, 0x93, 0x95, 0x96, 0x95, 0x96, 0x97, 0x99, 0x9b, - 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa1, 0xa1, 0xa0, 0x9e, 0x9e, 0x9e, - 0x9d, 0x9c, 0x9b, 0x99, 0x99, 0x99, 0x99, 0x97, 0x96, 0x94, 0x94, 0x94, - 0x93, 0x91, 0x8f, 0x8f, 0x8e, 0x8d, 0x8c, 0x8c, 0x8b, 0x8a, 0x8a, 0x8a, - 0x89, 0x87, 0x85, 0x84, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, - 0x7f, 0x7f, 0x82, 0x83, 0x84, 0x84, 0x84, 0x86, 0x89, 0x89, 0x89, 0x8a, - 0x8b, 0x8b, 0x8d, 0x8e, 0x90, 0x90, 0x92, 0x93, 0x93, 0x94, 0x95, 0x95, - 0x95, 0x95, 0x96, 0x97, 0x98, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9a, - 0x9a, 0x99, 0x99, 0x99, 0x97, 0x97, 0x97, 0x96, 0x93, 0x92, 0x92, 0x92, - 0x92, 0x93, 0x93, 0x92, 0x91, 0x92, 0x92, 0x91, 0x91, 0x90, 0x90, 0x90, - 0x91, 0x91, 0x91, 0x91, 0x91, 0x8f, 0x8e, 0x8f, 0x8f, 0x90, 0x90, 0x90, - 0x90, 0x8e, 0x8e, 0x8f, 0x8e, 0x8d, 0x8b, 0x89, 0x89, 0x89, 0x88, 0x87, - 0x88, 0x88, 0x88, 0x87, 0x89, 0x89, 0x8b, 0x8d, 0x8d, 0x8f, 0x91, 0x94, - 0x95, 0x96, 0x96, 0x97, 0x98, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, - 0x98, 0x98, 0x99, 0x9a, 0x9b, 0x9a, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9a, - 0x9b, 0x9b, 0x9c, 0x9f, 0xa0, 0xa1, 0xa1, 0xa1, 0xa0, 0x9d, 0x99, 0x95, - 0x92, 0x8d, 0x86, 0x7e, 0x79, 0x75, 0x72, 0x6b, 0x61, 0x5d, 0x5a, 0x57, - 0x54, 0x54, 0x56, 0x57, 0x58, 0x57, 0x58, 0x5a, 0x5c, 0x5d, 0x5d, 0x5f, - 0x61, 0x64, 0x64, 0x64, 0x67, 0x68, 0x67, 0x68, 0x6b, 0x6c, 0x6d, 0x6d, - 0x6d, 0x6f, 0x70, 0x71, 0x71, 0x71, 0x70, 0x6f, 0x6e, 0x6c, 0x6b, 0x68, - 0x64, 0x5e, 0x5b, 0x58, 0x56, 0x52, 0x4c, 0x47, 0x45, 0x41, 0x38, 0x31, - 0x28, 0x22, 0x1b, 0x14, 0x12, 0x11, 0x10, 0x10, 0x10, 0x11, 0x10, 0x11, - 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x11, 0x12, 0x11, 0x12, 0x13, 0x12, - 0x88, 0x88, 0x87, 0x86, 0x86, 0x87, 0x86, 0x84, 0x83, 0x82, 0x7f, 0x7c, - 0x7a, 0x79, 0x76, 0x75, 0x75, 0x75, 0x74, 0x72, 0x6f, 0x6e, 0x6f, 0x6f, - 0x6d, 0x69, 0x67, 0x68, 0x69, 0x6c, 0x74, 0x7a, 0x7e, 0x81, 0x83, 0x88, - 0x8d, 0x91, 0x93, 0x94, 0x97, 0x97, 0x95, 0x93, 0x92, 0x92, 0x93, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x95, 0x96, 0x98, 0x9b, 0x9d, 0x9e, 0x9f, 0xa1, - 0xa2, 0xa3, 0xa2, 0xa1, 0xa1, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9c, 0x9a, - 0x99, 0x9a, 0x99, 0x98, 0x96, 0x94, 0x94, 0x93, 0x91, 0x90, 0x8f, 0x90, - 0x8f, 0x8e, 0x8c, 0x8c, 0x8c, 0x8b, 0x8a, 0x8a, 0x89, 0x86, 0x85, 0x83, - 0x82, 0x81, 0x81, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x82, 0x83, - 0x84, 0x84, 0x84, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8b, 0x8b, 0x8d, 0x8e, - 0x90, 0x91, 0x93, 0x94, 0x94, 0x94, 0x95, 0x94, 0x95, 0x96, 0x96, 0x97, - 0x99, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9a, 0x9b, 0x9a, 0x9a, 0x99, 0x99, - 0x98, 0x97, 0x98, 0x97, 0x93, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x92, - 0x91, 0x92, 0x92, 0x91, 0x91, 0x8f, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91, - 0x91, 0x8f, 0x8f, 0x90, 0x90, 0x8e, 0x8f, 0x8f, 0x8f, 0x90, 0x8f, 0x90, - 0x8f, 0x8d, 0x8b, 0x89, 0x89, 0x88, 0x86, 0x86, 0x88, 0x88, 0x88, 0x87, - 0x89, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x91, 0x93, 0x94, 0x95, 0x95, 0x97, - 0x99, 0x9a, 0x9a, 0x99, 0x98, 0x97, 0x97, 0x97, 0x98, 0x98, 0x9a, 0x9b, - 0x9b, 0x9a, 0x99, 0x98, 0x99, 0x99, 0x9a, 0x9b, 0x9b, 0x9b, 0x9c, 0x9e, - 0x9f, 0xa0, 0xa1, 0xa0, 0x9e, 0x9b, 0x97, 0x93, 0x90, 0x8a, 0x83, 0x7c, - 0x76, 0x73, 0x6f, 0x66, 0x5d, 0x5a, 0x58, 0x56, 0x54, 0x54, 0x56, 0x58, - 0x59, 0x58, 0x5a, 0x5b, 0x5c, 0x5d, 0x5d, 0x5f, 0x62, 0x63, 0x63, 0x63, - 0x66, 0x67, 0x67, 0x67, 0x6a, 0x6c, 0x6d, 0x6d, 0x6d, 0x6f, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x6f, 0x6e, 0x6c, 0x6b, 0x68, 0x62, 0x5f, 0x5a, 0x58, - 0x56, 0x52, 0x4c, 0x48, 0x45, 0x41, 0x39, 0x30, 0x28, 0x22, 0x1b, 0x14, - 0x11, 0x11, 0x10, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, - 0x12, 0x11, 0x12, 0x12, 0x11, 0x11, 0x12, 0x11, 0x8a, 0x8a, 0x89, 0x88, - 0x88, 0x87, 0x85, 0x83, 0x82, 0x7f, 0x7c, 0x7a, 0x78, 0x77, 0x76, 0x73, - 0x73, 0x73, 0x73, 0x72, 0x70, 0x6f, 0x6f, 0x6f, 0x6d, 0x69, 0x67, 0x66, - 0x68, 0x6a, 0x70, 0x77, 0x7a, 0x7d, 0x80, 0x86, 0x8c, 0x90, 0x93, 0x95, - 0x98, 0x98, 0x97, 0x95, 0x94, 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x93, - 0x94, 0x96, 0x98, 0x9b, 0x9d, 0x9e, 0x9f, 0xa1, 0xa2, 0xa4, 0xa3, 0xa3, - 0xa2, 0xa1, 0x9f, 0xa0, 0x9f, 0x9e, 0x9c, 0x9b, 0x9a, 0x99, 0x99, 0x98, - 0x96, 0x94, 0x93, 0x92, 0x91, 0x8f, 0x90, 0x90, 0x8e, 0x8d, 0x8d, 0x8d, - 0x8c, 0x8c, 0x8a, 0x8a, 0x87, 0x86, 0x86, 0x83, 0x82, 0x81, 0x81, 0x81, - 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x82, 0x81, 0x83, 0x83, 0x83, 0x85, - 0x86, 0x86, 0x87, 0x89, 0x8b, 0x8b, 0x8d, 0x8e, 0x90, 0x92, 0x94, 0x94, - 0x95, 0x95, 0x95, 0x95, 0x96, 0x97, 0x97, 0x97, 0x99, 0x9b, 0x9a, 0x9a, - 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x98, 0x99, 0x99, 0x98, 0x98, 0x97, - 0x97, 0x96, 0x94, 0x93, 0x93, 0x93, 0x93, 0x92, 0x91, 0x92, 0x92, 0x91, - 0x91, 0x8f, 0x90, 0x90, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, - 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x8f, 0x90, 0x8f, 0x8d, 0x8d, 0x8b, - 0x8a, 0x89, 0x87, 0x86, 0x88, 0x88, 0x88, 0x87, 0x89, 0x8b, 0x8c, 0x8d, - 0x8e, 0x8e, 0x90, 0x92, 0x93, 0x94, 0x95, 0x96, 0x99, 0x99, 0x98, 0x97, - 0x97, 0x96, 0x95, 0x96, 0x97, 0x98, 0x99, 0x99, 0x99, 0x99, 0x98, 0x97, - 0x98, 0x99, 0x9a, 0x99, 0x9a, 0x9c, 0x9e, 0x9f, 0x9f, 0xa0, 0xa0, 0x9e, - 0x9c, 0x98, 0x93, 0x8f, 0x8b, 0x84, 0x7d, 0x77, 0x72, 0x6f, 0x69, 0x61, - 0x5a, 0x58, 0x58, 0x56, 0x54, 0x54, 0x56, 0x57, 0x59, 0x5b, 0x5b, 0x5b, - 0x5c, 0x5d, 0x5e, 0x60, 0x60, 0x62, 0x62, 0x62, 0x64, 0x64, 0x66, 0x67, - 0x69, 0x6a, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x6f, - 0x6e, 0x6c, 0x6b, 0x68, 0x62, 0x5f, 0x5a, 0x58, 0x56, 0x52, 0x4c, 0x47, - 0x44, 0x40, 0x38, 0x30, 0x29, 0x24, 0x1c, 0x14, 0x12, 0x11, 0x10, 0x10, - 0x11, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x12, 0x12, - 0x11, 0x11, 0x12, 0x11, 0x8c, 0x8b, 0x8a, 0x88, 0x88, 0x86, 0x84, 0x81, - 0x80, 0x7d, 0x79, 0x78, 0x77, 0x76, 0x75, 0x72, 0x72, 0x72, 0x72, 0x71, - 0x6f, 0x6f, 0x6e, 0x6e, 0x6b, 0x68, 0x65, 0x65, 0x65, 0x67, 0x6c, 0x72, - 0x77, 0x7a, 0x7e, 0x84, 0x8b, 0x90, 0x92, 0x95, 0x99, 0x9a, 0x99, 0x98, - 0x96, 0x95, 0x95, 0x95, 0x95, 0x94, 0x93, 0x94, 0x95, 0x96, 0x98, 0x9b, - 0x9d, 0x9e, 0x9f, 0xa0, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa1, 0xa0, 0xa0, - 0xa0, 0x9f, 0x9d, 0x9c, 0x9b, 0x9b, 0x9a, 0x98, 0x95, 0x93, 0x94, 0x93, - 0x91, 0x8f, 0x90, 0x90, 0x8f, 0x8d, 0x8d, 0x8e, 0x8e, 0x8d, 0x8b, 0x8b, - 0x88, 0x86, 0x85, 0x83, 0x82, 0x81, 0x81, 0x80, 0x7f, 0x7f, 0x80, 0x80, - 0x80, 0x80, 0x82, 0x82, 0x83, 0x83, 0x83, 0x84, 0x86, 0x86, 0x86, 0x89, - 0x8a, 0x8b, 0x8d, 0x8e, 0x91, 0x92, 0x94, 0x94, 0x95, 0x95, 0x95, 0x95, - 0x96, 0x97, 0x97, 0x97, 0x99, 0x9b, 0x9a, 0x99, 0x9a, 0x9b, 0x9b, 0x9b, - 0x9b, 0x9a, 0x9a, 0x9a, 0x99, 0x98, 0x98, 0x97, 0x97, 0x96, 0x95, 0x93, - 0x92, 0x92, 0x92, 0x92, 0x91, 0x91, 0x92, 0x91, 0x91, 0x8f, 0x90, 0x8f, - 0x90, 0x90, 0x8f, 0x90, 0x90, 0x8f, 0x90, 0x90, 0x90, 0x8e, 0x8f, 0x8f, - 0x8f, 0x8f, 0x8f, 0x90, 0x8f, 0x8e, 0x8e, 0x8c, 0x8b, 0x89, 0x87, 0x87, - 0x88, 0x87, 0x87, 0x87, 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x8e, 0x90, 0x92, - 0x93, 0x93, 0x95, 0x96, 0x98, 0x99, 0x98, 0x98, 0x97, 0x96, 0x97, 0x97, - 0x96, 0x96, 0x98, 0x98, 0x98, 0x97, 0x97, 0x97, 0x99, 0x9a, 0x9a, 0x99, - 0x9a, 0x9c, 0x9d, 0x9d, 0xa0, 0x9f, 0x9d, 0x9b, 0x99, 0x94, 0x8d, 0x89, - 0x85, 0x7e, 0x77, 0x70, 0x6c, 0x68, 0x62, 0x5c, 0x59, 0x58, 0x58, 0x57, - 0x56, 0x56, 0x57, 0x58, 0x59, 0x5b, 0x5a, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, - 0x61, 0x62, 0x62, 0x63, 0x64, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6c, 0x6d, - 0x6d, 0x6c, 0x6f, 0x70, 0x70, 0x70, 0x70, 0x6f, 0x6d, 0x6b, 0x6a, 0x68, - 0x62, 0x5f, 0x5a, 0x58, 0x56, 0x52, 0x4c, 0x47, 0x44, 0x3f, 0x38, 0x30, - 0x29, 0x24, 0x1c, 0x14, 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x12, 0x13, 0x12, 0x12, 0x12, 0x11, 0x10, 0x11, 0x13, - 0x8e, 0x8c, 0x8b, 0x8a, 0x88, 0x86, 0x84, 0x82, 0x7f, 0x7c, 0x79, 0x77, - 0x76, 0x76, 0x75, 0x73, 0x72, 0x70, 0x70, 0x71, 0x6f, 0x6f, 0x6d, 0x6c, - 0x69, 0x68, 0x66, 0x63, 0x63, 0x64, 0x68, 0x6e, 0x74, 0x78, 0x7c, 0x81, - 0x89, 0x8e, 0x91, 0x94, 0x99, 0x9a, 0x9a, 0x99, 0x98, 0x96, 0x96, 0x95, - 0x95, 0x93, 0x93, 0x95, 0x95, 0x96, 0x98, 0x9b, 0x9d, 0x9e, 0x9f, 0xa0, - 0xa1, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa1, 0x9f, 0x9f, 0x9f, 0x9e, 0x9c, - 0x9c, 0x9b, 0x9b, 0x98, 0x96, 0x94, 0x94, 0x93, 0x90, 0x8f, 0x8e, 0x8f, - 0x8f, 0x8e, 0x8e, 0x8f, 0x8f, 0x8e, 0x8c, 0x8c, 0x89, 0x85, 0x83, 0x82, - 0x81, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x82, 0x82, - 0x82, 0x83, 0x84, 0x85, 0x87, 0x87, 0x87, 0x87, 0x8a, 0x8c, 0x8c, 0x8e, - 0x90, 0x92, 0x93, 0x93, 0x94, 0x96, 0x95, 0x96, 0x97, 0x98, 0x98, 0x98, - 0x99, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9b, 0x9b, 0x9c, 0x9b, 0x9a, 0x9a, - 0x99, 0x99, 0x99, 0x97, 0x97, 0x96, 0x95, 0x95, 0x93, 0x93, 0x93, 0x93, - 0x92, 0x92, 0x91, 0x90, 0x90, 0x91, 0x90, 0x90, 0x91, 0x91, 0x90, 0x91, - 0x90, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, - 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8b, 0x89, 0x87, 0x87, 0x87, 0x87, 0x87, - 0x88, 0x8a, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x97, 0x97, 0x97, 0x97, 0x95, 0x96, 0x96, 0x95, 0x95, 0x97, 0x97, - 0x96, 0x95, 0x96, 0x98, 0x99, 0x99, 0x9a, 0x9a, 0x9b, 0x9d, 0x9e, 0x9e, - 0x9f, 0x9e, 0x9b, 0x99, 0x96, 0x91, 0x8a, 0x85, 0x81, 0x7b, 0x74, 0x6d, - 0x67, 0x63, 0x5e, 0x5a, 0x58, 0x58, 0x57, 0x57, 0x56, 0x57, 0x57, 0x58, - 0x59, 0x5b, 0x5c, 0x5b, 0x5c, 0x5d, 0x5f, 0x60, 0x60, 0x61, 0x62, 0x64, - 0x65, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6b, 0x6b, 0x6c, 0x6e, 0x6f, 0x70, - 0x70, 0x70, 0x70, 0x6f, 0x6d, 0x6b, 0x69, 0x66, 0x63, 0x5e, 0x5b, 0x5a, - 0x56, 0x52, 0x4d, 0x47, 0x44, 0x3f, 0x37, 0x30, 0x29, 0x24, 0x1d, 0x14, - 0x11, 0x10, 0x10, 0x10, 0x11, 0x10, 0x11, 0x11, 0x12, 0x11, 0x11, 0x12, - 0x13, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x12, 0x8f, 0x8c, 0x8b, 0x8a, - 0x88, 0x85, 0x83, 0x81, 0x7f, 0x7c, 0x78, 0x77, 0x76, 0x75, 0x73, 0x73, - 0x71, 0x70, 0x6f, 0x70, 0x70, 0x70, 0x6d, 0x6b, 0x69, 0x68, 0x65, 0x62, - 0x62, 0x63, 0x66, 0x6c, 0x72, 0x76, 0x7b, 0x81, 0x88, 0x8d, 0x90, 0x93, - 0x99, 0x9a, 0x9a, 0x99, 0x98, 0x96, 0x96, 0x95, 0x94, 0x92, 0x93, 0x95, - 0x95, 0x95, 0x98, 0x9a, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa3, 0xa3, 0xa3, - 0xa3, 0xa2, 0xa2, 0xa0, 0x9e, 0x9e, 0x9e, 0x9d, 0x9d, 0x9b, 0x9a, 0x98, - 0x96, 0x94, 0x94, 0x93, 0x91, 0x90, 0x8e, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, - 0x8f, 0x8e, 0x8d, 0x8c, 0x88, 0x84, 0x82, 0x82, 0x80, 0x7f, 0x80, 0x80, - 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x81, 0x82, 0x82, 0x82, 0x84, 0x85, - 0x87, 0x87, 0x87, 0x87, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x93, - 0x95, 0x95, 0x96, 0x96, 0x98, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x9b, 0x9b, - 0x9b, 0x9a, 0x9b, 0x9c, 0x9c, 0x9c, 0x9a, 0x9a, 0x9a, 0x9a, 0x99, 0x97, - 0x97, 0x96, 0x96, 0x96, 0x94, 0x94, 0x94, 0x94, 0x93, 0x92, 0x90, 0x90, - 0x90, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, - 0x91, 0x90, 0x91, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8c, - 0x8c, 0x8c, 0x8a, 0x88, 0x86, 0x87, 0x87, 0x87, 0x87, 0x89, 0x8a, 0x8b, - 0x8c, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x96, 0x97, 0x96, 0x97, - 0x97, 0x95, 0x96, 0x96, 0x95, 0x95, 0x96, 0x96, 0x96, 0x95, 0x96, 0x98, - 0x98, 0x99, 0x9a, 0x9a, 0x9c, 0x9e, 0x9e, 0x9e, 0x9e, 0x9c, 0x9a, 0x98, - 0x94, 0x8f, 0x88, 0x83, 0x7f, 0x79, 0x71, 0x6a, 0x64, 0x60, 0x5c, 0x59, - 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x5a, 0x5b, 0x5c, 0x5b, - 0x5c, 0x5d, 0x5f, 0x60, 0x60, 0x61, 0x62, 0x64, 0x64, 0x64, 0x66, 0x67, - 0x68, 0x68, 0x6b, 0x6b, 0x6b, 0x6e, 0x6f, 0x70, 0x70, 0x70, 0x70, 0x6f, - 0x6c, 0x6a, 0x68, 0x66, 0x63, 0x5e, 0x5c, 0x5a, 0x56, 0x52, 0x4d, 0x47, - 0x43, 0x3f, 0x37, 0x30, 0x28, 0x23, 0x1d, 0x14, 0x11, 0x10, 0x10, 0x10, - 0x11, 0x10, 0x11, 0x11, 0x12, 0x11, 0x11, 0x12, 0x12, 0x11, 0x10, 0x11, - 0x11, 0x10, 0x11, 0x12, 0x90, 0x8d, 0x8b, 0x89, 0x87, 0x84, 0x82, 0x7f, - 0x7d, 0x7a, 0x76, 0x76, 0x75, 0x74, 0x72, 0x72, 0x70, 0x6e, 0x6e, 0x6f, - 0x6e, 0x6e, 0x6b, 0x69, 0x68, 0x68, 0x65, 0x63, 0x62, 0x61, 0x62, 0x68, - 0x6f, 0x73, 0x78, 0x7e, 0x85, 0x8b, 0x8e, 0x91, 0x97, 0x9a, 0x9a, 0x9a, - 0x99, 0x97, 0x97, 0x96, 0x95, 0x93, 0x93, 0x95, 0x95, 0x95, 0x96, 0x9a, - 0x9c, 0x9e, 0x9f, 0xa0, 0xa1, 0xa3, 0xa3, 0xa4, 0xa4, 0xa2, 0xa2, 0xa1, - 0xa0, 0x9f, 0x9f, 0x9d, 0x9d, 0x9b, 0x9a, 0x99, 0x96, 0x94, 0x94, 0x93, - 0x92, 0x8f, 0x8e, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8d, 0x8b, - 0x87, 0x83, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7e, - 0x7f, 0x80, 0x80, 0x81, 0x82, 0x83, 0x84, 0x84, 0x85, 0x85, 0x85, 0x86, - 0x89, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x93, 0x95, 0x95, 0x96, 0x97, - 0x97, 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9a, 0x9c, 0x9d, - 0x9c, 0x9c, 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x98, 0x98, 0x97, 0x97, 0x97, - 0x94, 0x94, 0x94, 0x94, 0x93, 0x91, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x90, - 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x91, 0x91, 0x91, 0x91, - 0x90, 0x91, 0x90, 0x90, 0x8f, 0x8e, 0x8e, 0x8d, 0x8b, 0x8a, 0x89, 0x89, - 0x87, 0x87, 0x87, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x90, 0x90, - 0x91, 0x92, 0x94, 0x96, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x95, - 0x94, 0x94, 0x96, 0x97, 0x97, 0x96, 0x96, 0x98, 0x97, 0x98, 0x99, 0x99, - 0x9b, 0x9d, 0x9d, 0x9d, 0x9c, 0x9a, 0x97, 0x95, 0x92, 0x8b, 0x84, 0x7e, - 0x7a, 0x74, 0x6d, 0x65, 0x60, 0x5d, 0x5a, 0x59, 0x57, 0x57, 0x57, 0x58, - 0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5f, 0x60, - 0x60, 0x61, 0x62, 0x63, 0x63, 0x65, 0x65, 0x66, 0x67, 0x67, 0x6a, 0x6b, - 0x6b, 0x6d, 0x6f, 0x70, 0x6f, 0x6f, 0x6f, 0x6f, 0x6c, 0x6a, 0x68, 0x66, - 0x63, 0x5e, 0x5c, 0x59, 0x56, 0x52, 0x4d, 0x47, 0x44, 0x3f, 0x36, 0x31, - 0x29, 0x24, 0x1c, 0x14, 0x11, 0x10, 0x10, 0x11, 0x11, 0x10, 0x10, 0x10, - 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x91, 0x8e, 0x8b, 0x89, 0x87, 0x83, 0x80, 0x7d, 0x7b, 0x78, 0x76, 0x74, - 0x73, 0x72, 0x71, 0x70, 0x6f, 0x6d, 0x6d, 0x6e, 0x6d, 0x6b, 0x69, 0x68, - 0x66, 0x66, 0x64, 0x62, 0x61, 0x60, 0x61, 0x66, 0x6c, 0x70, 0x75, 0x7d, - 0x84, 0x89, 0x8c, 0x8f, 0x95, 0x98, 0x9a, 0x9a, 0x9b, 0x99, 0x97, 0x97, - 0x97, 0x95, 0x93, 0x94, 0x94, 0x94, 0x95, 0x99, 0x9b, 0x9e, 0x9f, 0x9f, - 0xa1, 0xa3, 0xa3, 0xa4, 0xa5, 0xa5, 0xa4, 0xa2, 0xa1, 0xa1, 0xa0, 0x9f, - 0x9d, 0x9a, 0x99, 0x98, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x90, 0x8f, - 0x8f, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8c, 0x89, 0x87, 0x85, 0x83, 0x82, - 0x81, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x7e, 0x7f, 0x80, 0x80, 0x80, 0x81, - 0x82, 0x83, 0x83, 0x83, 0x83, 0x84, 0x85, 0x87, 0x89, 0x8c, 0x8c, 0x8e, - 0x90, 0x91, 0x93, 0x93, 0x95, 0x95, 0x95, 0x96, 0x97, 0x98, 0x99, 0x99, - 0x9a, 0x9a, 0x9a, 0x9a, 0x99, 0x9a, 0x9d, 0x9d, 0x9d, 0x9c, 0x9d, 0x9c, - 0x9a, 0x99, 0x9a, 0x99, 0x99, 0x98, 0x98, 0x97, 0x95, 0x93, 0x93, 0x93, - 0x92, 0x92, 0x92, 0x92, 0x91, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x91, - 0x90, 0x90, 0x91, 0x92, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x91, 0x91, - 0x90, 0x8f, 0x8f, 0x8d, 0x8d, 0x8b, 0x8a, 0x8a, 0x88, 0x89, 0x88, 0x88, - 0x87, 0x89, 0x89, 0x8b, 0x8c, 0x8d, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, - 0x96, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x95, 0x94, 0x94, 0x95, 0x96, - 0x96, 0x96, 0x96, 0x96, 0x96, 0x97, 0x99, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, - 0x9b, 0x97, 0x94, 0x92, 0x8e, 0x86, 0x7e, 0x78, 0x73, 0x6d, 0x67, 0x5f, - 0x5b, 0x5a, 0x58, 0x59, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, - 0x5b, 0x5a, 0x5b, 0x5b, 0x5c, 0x5d, 0x5f, 0x5f, 0x61, 0x61, 0x61, 0x62, - 0x62, 0x65, 0x66, 0x66, 0x66, 0x67, 0x69, 0x6b, 0x6b, 0x6c, 0x6d, 0x6f, - 0x6f, 0x6f, 0x6f, 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x64, 0x5e, 0x5c, 0x59, - 0x55, 0x50, 0x4b, 0x47, 0x44, 0x40, 0x38, 0x31, 0x2c, 0x26, 0x1d, 0x15, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x12, 0x12, 0x12, 0x11, 0x12, 0x12, 0x13, 0x11, 0x90, 0x8d, 0x8b, 0x89, - 0x86, 0x82, 0x7f, 0x7c, 0x7a, 0x78, 0x76, 0x72, 0x70, 0x70, 0x70, 0x70, - 0x6e, 0x6d, 0x6c, 0x6c, 0x6b, 0x68, 0x67, 0x66, 0x66, 0x65, 0x64, 0x62, - 0x61, 0x61, 0x62, 0x64, 0x68, 0x6b, 0x72, 0x7a, 0x82, 0x87, 0x8a, 0x8f, - 0x93, 0x96, 0x98, 0x9a, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, 0x93, 0x93, - 0x92, 0x93, 0x95, 0x97, 0x9b, 0x9e, 0x9f, 0xa0, 0xa1, 0xa4, 0xa4, 0xa5, - 0xa6, 0xa6, 0xa5, 0xa4, 0xa3, 0xa1, 0x9f, 0x9e, 0x9d, 0x9b, 0x99, 0x98, - 0x95, 0x94, 0x93, 0x92, 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x90, 0x90, - 0x8f, 0x8e, 0x8c, 0x89, 0x87, 0x85, 0x83, 0x82, 0x81, 0x80, 0x80, 0x80, - 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x80, 0x81, 0x81, 0x81, 0x81, 0x83, - 0x83, 0x85, 0x86, 0x87, 0x88, 0x8b, 0x8b, 0x8c, 0x8e, 0x91, 0x93, 0x94, - 0x94, 0x95, 0x95, 0x96, 0x98, 0x98, 0x99, 0x99, 0x9b, 0x9b, 0x9a, 0x9a, - 0x9a, 0x9c, 0x9e, 0x9e, 0x9d, 0x9d, 0x9d, 0x9b, 0x9b, 0x9c, 0x9b, 0x9a, - 0x9a, 0x98, 0x98, 0x97, 0x95, 0x94, 0x93, 0x92, 0x93, 0x92, 0x93, 0x93, - 0x92, 0x91, 0x92, 0x92, 0x91, 0x90, 0x90, 0x91, 0x92, 0x91, 0x92, 0x93, - 0x93, 0x92, 0x92, 0x92, 0x92, 0x93, 0x92, 0x91, 0x91, 0x8f, 0x90, 0x8e, - 0x8d, 0x8d, 0x8c, 0x8a, 0x8a, 0x89, 0x89, 0x89, 0x8a, 0x8b, 0x8a, 0x8b, - 0x8c, 0x8d, 0x8f, 0x8f, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x95, - 0x96, 0x94, 0x94, 0x95, 0x96, 0x95, 0x96, 0x95, 0x95, 0x95, 0x96, 0x96, - 0x97, 0x97, 0x97, 0x99, 0x9a, 0x9a, 0x9a, 0x9a, 0x99, 0x95, 0x91, 0x8e, - 0x89, 0x81, 0x78, 0x72, 0x6e, 0x68, 0x60, 0x5b, 0x5a, 0x59, 0x57, 0x57, - 0x58, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5b, 0x5c, 0x5f, - 0x60, 0x60, 0x60, 0x60, 0x61, 0x60, 0x5f, 0x60, 0x62, 0x64, 0x65, 0x65, - 0x65, 0x67, 0x68, 0x6a, 0x6a, 0x6b, 0x6c, 0x6e, 0x6d, 0x6e, 0x6f, 0x6f, - 0x6e, 0x6d, 0x6b, 0x68, 0x65, 0x61, 0x5c, 0x59, 0x56, 0x50, 0x4c, 0x49, - 0x46, 0x41, 0x3a, 0x32, 0x2c, 0x27, 0x1f, 0x16, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x12, 0x11, - 0x12, 0x12, 0x12, 0x13, 0x8f, 0x8c, 0x8a, 0x88, 0x85, 0x81, 0x7e, 0x7b, - 0x7a, 0x78, 0x75, 0x71, 0x70, 0x6f, 0x6f, 0x6f, 0x6e, 0x6b, 0x6a, 0x6a, - 0x69, 0x67, 0x65, 0x65, 0x64, 0x63, 0x62, 0x62, 0x62, 0x62, 0x62, 0x63, - 0x65, 0x68, 0x6f, 0x77, 0x7f, 0x85, 0x88, 0x8d, 0x92, 0x95, 0x98, 0x99, - 0x9b, 0x9b, 0x9b, 0x99, 0x98, 0x97, 0x94, 0x93, 0x92, 0x93, 0x94, 0x96, - 0x9a, 0x9d, 0x9e, 0x9f, 0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa5, 0xa6, 0xa4, - 0xa4, 0xa3, 0xa0, 0x9f, 0x9d, 0x9b, 0x99, 0x99, 0x96, 0x94, 0x93, 0x92, - 0x90, 0x91, 0x91, 0x90, 0x8f, 0x8f, 0x90, 0x90, 0x8f, 0x8f, 0x8c, 0x8a, - 0x87, 0x84, 0x83, 0x82, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7e, 0x7e, - 0x7e, 0x7f, 0x80, 0x82, 0x81, 0x80, 0x80, 0x82, 0x83, 0x84, 0x86, 0x86, - 0x87, 0x8a, 0x8b, 0x8c, 0x8e, 0x91, 0x93, 0x94, 0x95, 0x95, 0x96, 0x97, - 0x99, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9b, 0x9b, 0x9b, 0x9d, 0x9d, 0x9d, - 0x9d, 0x9d, 0x9d, 0x9b, 0x9c, 0x9c, 0x9c, 0x9a, 0x9b, 0x99, 0x99, 0x98, - 0x97, 0x95, 0x94, 0x93, 0x94, 0x93, 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, - 0x92, 0x91, 0x91, 0x93, 0x93, 0x92, 0x92, 0x94, 0x94, 0x93, 0x93, 0x93, - 0x93, 0x94, 0x93, 0x92, 0x92, 0x91, 0x90, 0x8f, 0x8f, 0x8e, 0x8c, 0x8a, - 0x8b, 0x8a, 0x89, 0x8a, 0x8a, 0x8b, 0x8a, 0x8b, 0x8c, 0x8c, 0x8e, 0x8f, - 0x90, 0x92, 0x93, 0x95, 0x96, 0x96, 0x96, 0x95, 0x96, 0x94, 0x94, 0x95, - 0x95, 0x95, 0x96, 0x96, 0x96, 0x95, 0x96, 0x95, 0x96, 0x96, 0x96, 0x99, - 0x9b, 0x9b, 0x9a, 0x99, 0x97, 0x93, 0x8f, 0x8b, 0x84, 0x7b, 0x73, 0x6d, - 0x69, 0x62, 0x5c, 0x5a, 0x59, 0x58, 0x57, 0x57, 0x57, 0x58, 0x59, 0x59, - 0x5a, 0x5c, 0x5c, 0x5c, 0x5c, 0x5b, 0x5d, 0x60, 0x61, 0x61, 0x5f, 0x60, - 0x61, 0x60, 0x60, 0x61, 0x61, 0x63, 0x64, 0x64, 0x64, 0x65, 0x67, 0x68, - 0x68, 0x69, 0x6b, 0x6d, 0x6e, 0x6e, 0x6f, 0x6f, 0x6e, 0x6e, 0x6c, 0x69, - 0x67, 0x62, 0x5c, 0x59, 0x56, 0x52, 0x4d, 0x4a, 0x46, 0x41, 0x3b, 0x34, - 0x2b, 0x27, 0x1f, 0x16, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x11, - 0x12, 0x12, 0x12, 0x11, 0x11, 0x12, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, - 0x90, 0x8c, 0x89, 0x87, 0x84, 0x80, 0x7c, 0x7a, 0x79, 0x77, 0x74, 0x70, - 0x6f, 0x6e, 0x6e, 0x6f, 0x6e, 0x6b, 0x6a, 0x69, 0x68, 0x66, 0x64, 0x64, - 0x63, 0x62, 0x62, 0x62, 0x62, 0x61, 0x62, 0x62, 0x64, 0x66, 0x6c, 0x75, - 0x7d, 0x83, 0x87, 0x8b, 0x90, 0x93, 0x96, 0x98, 0x9a, 0x9b, 0x9b, 0x9a, - 0x99, 0x97, 0x95, 0x94, 0x93, 0x93, 0x93, 0x95, 0x99, 0x9c, 0x9d, 0x9f, - 0xa1, 0xa2, 0xa4, 0xa5, 0xa7, 0xa6, 0xa6, 0xa5, 0xa4, 0xa3, 0xa1, 0x9f, - 0x9d, 0x9b, 0x99, 0x98, 0x96, 0x94, 0x93, 0x92, 0x90, 0x91, 0x90, 0x90, - 0x8f, 0x8f, 0x90, 0x8f, 0x8f, 0x8f, 0x8d, 0x8a, 0x87, 0x84, 0x83, 0x82, - 0x81, 0x80, 0x80, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x80, 0x81, - 0x80, 0x80, 0x80, 0x81, 0x82, 0x84, 0x84, 0x85, 0x86, 0x8a, 0x8c, 0x8c, - 0x8e, 0x91, 0x93, 0x94, 0x95, 0x96, 0x96, 0x97, 0x99, 0x9a, 0x9a, 0x9a, - 0x9a, 0x9c, 0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, - 0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9a, 0x99, 0x99, 0x97, 0x96, 0x95, 0x94, - 0x94, 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x93, - 0x93, 0x93, 0x92, 0x93, 0x94, 0x94, 0x94, 0x94, 0x94, 0x95, 0x94, 0x93, - 0x93, 0x92, 0x91, 0x8f, 0x8f, 0x8f, 0x8d, 0x8b, 0x8b, 0x8a, 0x89, 0x89, - 0x8a, 0x8b, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, - 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95, 0x96, 0x96, - 0x96, 0x95, 0x95, 0x94, 0x95, 0x95, 0x96, 0x98, 0x9a, 0x9b, 0x9a, 0x98, - 0x95, 0x91, 0x8e, 0x89, 0x81, 0x79, 0x70, 0x6a, 0x66, 0x5f, 0x59, 0x58, - 0x58, 0x57, 0x56, 0x56, 0x57, 0x58, 0x59, 0x59, 0x5b, 0x5d, 0x5d, 0x5c, - 0x5c, 0x5b, 0x5d, 0x60, 0x61, 0x61, 0x5f, 0x60, 0x61, 0x61, 0x60, 0x61, - 0x61, 0x61, 0x63, 0x63, 0x63, 0x65, 0x67, 0x67, 0x68, 0x69, 0x6a, 0x6d, - 0x6e, 0x6f, 0x6f, 0x6f, 0x6e, 0x6d, 0x6c, 0x6a, 0x67, 0x62, 0x5c, 0x5a, - 0x56, 0x52, 0x4d, 0x49, 0x46, 0x41, 0x3b, 0x34, 0x2c, 0x26, 0x1f, 0x15, - 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, - 0x12, 0x12, 0x12, 0x13, 0x12, 0x12, 0x12, 0x13, 0x90, 0x8b, 0x88, 0x85, - 0x82, 0x7e, 0x7a, 0x78, 0x78, 0x76, 0x73, 0x6e, 0x6d, 0x6d, 0x6e, 0x6e, - 0x6b, 0x6a, 0x69, 0x67, 0x66, 0x65, 0x64, 0x63, 0x61, 0x60, 0x62, 0x61, - 0x61, 0x61, 0x62, 0x62, 0x63, 0x64, 0x69, 0x72, 0x7b, 0x81, 0x84, 0x88, - 0x8e, 0x92, 0x94, 0x96, 0x99, 0x9b, 0x9c, 0x9b, 0x9a, 0x98, 0x96, 0x96, - 0x94, 0x93, 0x94, 0x95, 0x98, 0x9a, 0x9c, 0x9f, 0xa1, 0xa1, 0xa3, 0xa5, - 0xa7, 0xa7, 0xa6, 0xa6, 0xa5, 0xa4, 0xa2, 0xa0, 0x9e, 0x9c, 0x9a, 0x97, - 0x95, 0x93, 0x92, 0x92, 0x90, 0x90, 0x8f, 0x90, 0x90, 0x8f, 0x90, 0x8f, - 0x8f, 0x8f, 0x8d, 0x89, 0x87, 0x84, 0x83, 0x82, 0x81, 0x80, 0x80, 0x7f, - 0x7e, 0x7d, 0x7f, 0x80, 0x80, 0x7f, 0x7f, 0x80, 0x80, 0x7f, 0x7f, 0x81, - 0x83, 0x83, 0x83, 0x84, 0x86, 0x89, 0x8b, 0x8c, 0x8d, 0x90, 0x93, 0x94, - 0x94, 0x95, 0x95, 0x97, 0x99, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, - 0x9e, 0x9e, 0x9e, 0x9f, 0x9f, 0x9f, 0x9e, 0x9c, 0x9c, 0x9c, 0x9c, 0x9b, - 0x9b, 0x9a, 0x99, 0x99, 0x98, 0x97, 0x96, 0x95, 0x95, 0x95, 0x95, 0x94, - 0x94, 0x93, 0x93, 0x92, 0x91, 0x92, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, - 0x93, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94, 0x94, 0x93, 0x92, 0x91, - 0x90, 0x90, 0x8f, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x8a, 0x8a, 0x8a, 0x8a, - 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x96, - 0x96, 0x95, 0x95, 0x95, 0x96, 0x96, 0x96, 0x95, 0x95, 0x94, 0x95, 0x94, - 0x95, 0x95, 0x96, 0x97, 0x99, 0x9a, 0x99, 0x97, 0x93, 0x8e, 0x8a, 0x86, - 0x7f, 0x75, 0x6c, 0x65, 0x61, 0x5b, 0x58, 0x56, 0x56, 0x56, 0x57, 0x57, - 0x57, 0x59, 0x5a, 0x5a, 0x5d, 0x5e, 0x5e, 0x5d, 0x5c, 0x5c, 0x5d, 0x60, - 0x61, 0x61, 0x60, 0x5f, 0x60, 0x60, 0x60, 0x62, 0x62, 0x61, 0x62, 0x63, - 0x63, 0x66, 0x65, 0x67, 0x68, 0x69, 0x6a, 0x6d, 0x6e, 0x6f, 0x6f, 0x70, - 0x6e, 0x6c, 0x6b, 0x6a, 0x67, 0x62, 0x5d, 0x5a, 0x57, 0x53, 0x4d, 0x49, - 0x46, 0x42, 0x3c, 0x34, 0x2d, 0x28, 0x20, 0x15, 0x11, 0x11, 0x11, 0x10, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x13, 0x13, 0x12, 0x13, 0x11, - 0x12, 0x12, 0x12, 0x14, 0x8f, 0x8a, 0x86, 0x84, 0x80, 0x7c, 0x79, 0x77, - 0x76, 0x74, 0x70, 0x6c, 0x6b, 0x6b, 0x6c, 0x6b, 0x69, 0x68, 0x67, 0x64, - 0x63, 0x63, 0x62, 0x61, 0x60, 0x60, 0x60, 0x5f, 0x5f, 0x5f, 0x60, 0x61, - 0x62, 0x63, 0x67, 0x6d, 0x77, 0x7d, 0x81, 0x85, 0x8b, 0x90, 0x92, 0x94, - 0x98, 0x9b, 0x9b, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x94, 0x93, 0x93, 0x94, - 0x96, 0x98, 0x9a, 0x9e, 0xa0, 0xa1, 0xa3, 0xa5, 0xa7, 0xa8, 0xa6, 0xa6, - 0xa5, 0xa4, 0xa3, 0xa1, 0x9e, 0x9b, 0x99, 0x97, 0x95, 0x93, 0x92, 0x92, - 0x90, 0x90, 0x8f, 0x90, 0x90, 0x91, 0x90, 0x8f, 0x8f, 0x8e, 0x8c, 0x88, - 0x87, 0x85, 0x83, 0x82, 0x82, 0x80, 0x7f, 0x7f, 0x7d, 0x7d, 0x7f, 0x80, - 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83, 0x83, 0x83, 0x83, - 0x86, 0x87, 0x8a, 0x8c, 0x8f, 0x92, 0x93, 0x94, 0x95, 0x97, 0x97, 0x99, - 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9d, 0x9c, 0x9c, 0x9d, 0x9f, 0x9f, 0x9f, - 0x9f, 0x9e, 0x9e, 0x9d, 0x9d, 0x9d, 0x9d, 0x9b, 0x9c, 0x9b, 0x9a, 0x9a, - 0x99, 0x98, 0x96, 0x95, 0x96, 0x95, 0x96, 0x95, 0x94, 0x93, 0x92, 0x93, - 0x93, 0x93, 0x93, 0x92, 0x93, 0x94, 0x95, 0x94, 0x94, 0x96, 0x96, 0x96, - 0x96, 0x96, 0x96, 0x95, 0x95, 0x94, 0x94, 0x92, 0x92, 0x91, 0x91, 0x8f, - 0x8d, 0x8c, 0x8b, 0x89, 0x8a, 0x89, 0x8a, 0x8c, 0x8c, 0x8d, 0x8f, 0x90, - 0x91, 0x92, 0x93, 0x94, 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, - 0x95, 0x95, 0x96, 0x95, 0x94, 0x94, 0x94, 0x95, 0x96, 0x97, 0x97, 0x96, - 0x98, 0x98, 0x97, 0x94, 0x90, 0x89, 0x85, 0x81, 0x7a, 0x6f, 0x66, 0x5f, - 0x5c, 0x59, 0x58, 0x56, 0x56, 0x57, 0x58, 0x58, 0x5a, 0x5b, 0x5b, 0x5b, - 0x5d, 0x5f, 0x5e, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x61, 0x61, 0x61, 0x5f, - 0x60, 0x61, 0x61, 0x61, 0x61, 0x62, 0x63, 0x63, 0x63, 0x65, 0x65, 0x66, - 0x67, 0x69, 0x6b, 0x6e, 0x6f, 0x70, 0x70, 0x70, 0x6f, 0x6c, 0x6b, 0x6b, - 0x67, 0x63, 0x5f, 0x5d, 0x59, 0x53, 0x4f, 0x4b, 0x48, 0x43, 0x3d, 0x34, - 0x2f, 0x2b, 0x21, 0x16, 0x12, 0x11, 0x10, 0x11, 0x10, 0x12, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x14, 0x15, 0x13, 0x13, 0x11, 0x11, 0x11, 0x13, 0x14, - 0x8e, 0x8a, 0x86, 0x83, 0x7e, 0x7a, 0x77, 0x75, 0x73, 0x71, 0x6e, 0x6a, - 0x69, 0x69, 0x6a, 0x69, 0x67, 0x66, 0x65, 0x63, 0x62, 0x62, 0x62, 0x61, - 0x60, 0x5f, 0x5f, 0x5e, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x63, 0x64, 0x69, - 0x72, 0x79, 0x7d, 0x81, 0x88, 0x8d, 0x91, 0x94, 0x97, 0x9a, 0x9b, 0x9b, - 0x9a, 0x9a, 0x99, 0x96, 0x95, 0x94, 0x94, 0x93, 0x95, 0x98, 0x9a, 0x9d, - 0xa0, 0xa2, 0xa4, 0xa6, 0xa7, 0xa8, 0xa7, 0xa8, 0xa7, 0xa6, 0xa4, 0xa2, - 0x9e, 0x9b, 0x99, 0x96, 0x95, 0x93, 0x92, 0x91, 0x91, 0x90, 0x8f, 0x90, - 0x90, 0x91, 0x90, 0x8f, 0x8f, 0x8e, 0x8c, 0x89, 0x86, 0x84, 0x83, 0x82, - 0x81, 0x7f, 0x7f, 0x7f, 0x7d, 0x7d, 0x7e, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, - 0x80, 0x7f, 0x80, 0x81, 0x82, 0x84, 0x84, 0x83, 0x85, 0x86, 0x88, 0x8a, - 0x8e, 0x91, 0x93, 0x94, 0x95, 0x97, 0x97, 0x98, 0x9a, 0x9b, 0x9c, 0x9d, - 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9f, 0x9f, 0x9e, 0x9e, - 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9b, 0x9b, 0x9b, 0x99, 0x98, 0x96, 0x96, - 0x96, 0x95, 0x96, 0x95, 0x95, 0x93, 0x94, 0x95, 0x95, 0x95, 0x95, 0x94, - 0x95, 0x96, 0x96, 0x96, 0x97, 0x97, 0x96, 0x96, 0x97, 0x96, 0x96, 0x95, - 0x95, 0x95, 0x95, 0x94, 0x92, 0x92, 0x91, 0x8f, 0x8f, 0x8d, 0x8c, 0x8a, - 0x8a, 0x89, 0x89, 0x8b, 0x8c, 0x8d, 0x8f, 0x90, 0x91, 0x91, 0x92, 0x93, - 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, - 0x95, 0x94, 0x95, 0x95, 0x96, 0x96, 0x95, 0x96, 0x97, 0x97, 0x96, 0x93, - 0x8d, 0x86, 0x81, 0x7d, 0x75, 0x6b, 0x61, 0x5b, 0x59, 0x57, 0x58, 0x59, - 0x58, 0x58, 0x59, 0x59, 0x5b, 0x5b, 0x5b, 0x5a, 0x5c, 0x5e, 0x5e, 0x5e, - 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x61, 0x61, 0x5f, 0x60, 0x60, 0x5f, 0x60, - 0x61, 0x64, 0x65, 0x65, 0x64, 0x65, 0x66, 0x67, 0x68, 0x6a, 0x6b, 0x6e, - 0x6f, 0x70, 0x70, 0x71, 0x70, 0x6f, 0x6d, 0x6b, 0x68, 0x64, 0x60, 0x5d, - 0x5a, 0x54, 0x50, 0x4d, 0x49, 0x43, 0x3d, 0x34, 0x2f, 0x2b, 0x22, 0x17, - 0x12, 0x11, 0x10, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, 0x12, - 0x12, 0x11, 0x12, 0x11, 0x11, 0x11, 0x13, 0x13, 0x8c, 0x88, 0x85, 0x81, - 0x7b, 0x77, 0x74, 0x71, 0x6f, 0x6d, 0x6c, 0x69, 0x68, 0x67, 0x68, 0x67, - 0x65, 0x64, 0x64, 0x63, 0x61, 0x60, 0x60, 0x5f, 0x5f, 0x60, 0x5f, 0x5f, - 0x5f, 0x5f, 0x5f, 0x5f, 0x60, 0x62, 0x64, 0x67, 0x6e, 0x75, 0x78, 0x7d, - 0x85, 0x8a, 0x8e, 0x91, 0x95, 0x97, 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x96, - 0x95, 0x95, 0x95, 0x95, 0x95, 0x96, 0x98, 0x9b, 0x9e, 0xa2, 0xa4, 0xa4, - 0xa5, 0xa6, 0xa7, 0xa8, 0xa7, 0xa6, 0xa5, 0xa2, 0x9f, 0x9b, 0x99, 0x98, - 0x95, 0x94, 0x91, 0x91, 0x91, 0x90, 0x8f, 0x91, 0x91, 0x90, 0x90, 0x90, - 0x8e, 0x8d, 0x8b, 0x88, 0x86, 0x86, 0x85, 0x83, 0x81, 0x7f, 0x7e, 0x7e, - 0x7d, 0x7e, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x7e, 0x7e, 0x7d, 0x7f, - 0x82, 0x83, 0x83, 0x82, 0x84, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x92, 0x94, - 0x96, 0x97, 0x97, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0xa0, 0xa0, 0xa0, - 0x9f, 0x9e, 0xa0, 0x9f, 0x9e, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9d, - 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x99, 0x98, 0x98, 0x96, 0x96, 0x95, 0x95, - 0x95, 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x96, 0x97, 0x97, - 0x97, 0x95, 0x95, 0x96, 0x98, 0x97, 0x98, 0x96, 0x96, 0x97, 0x95, 0x95, - 0x94, 0x94, 0x92, 0x91, 0x90, 0x8f, 0x8e, 0x8c, 0x8a, 0x89, 0x89, 0x8b, - 0x8c, 0x8d, 0x8e, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x95, 0x95, 0x95, 0x95, - 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x95, 0x96, 0x96, 0x95, 0x95, 0x95, - 0x96, 0x96, 0x96, 0x96, 0x96, 0x95, 0x93, 0x90, 0x89, 0x82, 0x7d, 0x79, - 0x72, 0x67, 0x5e, 0x58, 0x57, 0x56, 0x57, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, - 0x5b, 0x5c, 0x5c, 0x5c, 0x5c, 0x5e, 0x5f, 0x5f, 0x5f, 0x5e, 0x5f, 0x5f, - 0x60, 0x61, 0x61, 0x60, 0x61, 0x60, 0x60, 0x60, 0x61, 0x64, 0x65, 0x64, - 0x63, 0x64, 0x66, 0x68, 0x68, 0x6a, 0x6b, 0x6e, 0x6f, 0x70, 0x70, 0x71, - 0x71, 0x6f, 0x6e, 0x6a, 0x68, 0x64, 0x61, 0x5e, 0x5b, 0x57, 0x51, 0x4d, - 0x4a, 0x44, 0x3d, 0x35, 0x2f, 0x2b, 0x23, 0x18, 0x12, 0x11, 0x10, 0x11, - 0x11, 0x10, 0x10, 0x11, 0x11, 0x12, 0x11, 0x12, 0x12, 0x12, 0x12, 0x11, - 0x12, 0x12, 0x12, 0x14, 0x8b, 0x87, 0x82, 0x7f, 0x79, 0x75, 0x72, 0x6f, - 0x6e, 0x6b, 0x68, 0x68, 0x66, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x61, - 0x60, 0x5d, 0x5e, 0x5f, 0x5e, 0x5f, 0x5e, 0x5e, 0x5f, 0x5e, 0x5f, 0x60, - 0x60, 0x61, 0x64, 0x68, 0x6c, 0x70, 0x73, 0x79, 0x81, 0x87, 0x8b, 0x8e, - 0x92, 0x96, 0x98, 0x99, 0x9a, 0x9a, 0x99, 0x98, 0x96, 0x96, 0x95, 0x95, - 0x95, 0x96, 0x97, 0x9a, 0x9d, 0xa1, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa6, 0xa6, 0xa4, 0xa1, 0x9e, 0x9c, 0x99, 0x97, 0x95, 0x94, 0x91, 0x91, - 0x91, 0x90, 0x90, 0x91, 0x91, 0x91, 0x90, 0x90, 0x8e, 0x8d, 0x8b, 0x88, - 0x86, 0x86, 0x85, 0x83, 0x81, 0x7f, 0x7e, 0x7d, 0x7d, 0x7d, 0x7f, 0x81, - 0x80, 0x7f, 0x7f, 0x7f, 0x7e, 0x7d, 0x7e, 0x80, 0x82, 0x82, 0x82, 0x81, - 0x83, 0x87, 0x89, 0x8a, 0x8d, 0x8f, 0x92, 0x94, 0x96, 0x97, 0x97, 0x99, - 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa1, 0xa1, 0xa0, 0x9f, 0x9f, 0xa0, 0x9f, - 0x9e, 0x9e, 0x9f, 0x9f, 0x9e, 0x9f, 0x9f, 0x9d, 0x9b, 0x9c, 0x9c, 0x9b, - 0x9a, 0x99, 0x98, 0x98, 0x97, 0x97, 0x96, 0x96, 0x96, 0x97, 0x97, 0x95, - 0x96, 0x96, 0x95, 0x95, 0x95, 0x96, 0x97, 0x97, 0x97, 0x96, 0x97, 0x98, - 0x98, 0x98, 0x99, 0x98, 0x97, 0x98, 0x96, 0x96, 0x95, 0x95, 0x94, 0x92, - 0x91, 0x90, 0x8e, 0x8c, 0x8c, 0x8b, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8e, - 0x8f, 0x90, 0x92, 0x92, 0x94, 0x95, 0x95, 0x95, 0x97, 0x97, 0x97, 0x97, - 0x97, 0x97, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x96, 0x96, 0x96, 0x96, - 0x95, 0x93, 0x91, 0x8d, 0x85, 0x7e, 0x7a, 0x76, 0x6f, 0x64, 0x5c, 0x58, - 0x57, 0x58, 0x57, 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, - 0x5b, 0x5e, 0x5f, 0x5f, 0x5d, 0x5d, 0x5d, 0x5d, 0x5f, 0x60, 0x61, 0x60, - 0x61, 0x61, 0x61, 0x62, 0x62, 0x63, 0x64, 0x64, 0x62, 0x64, 0x66, 0x68, - 0x68, 0x6a, 0x6b, 0x6e, 0x6f, 0x70, 0x70, 0x71, 0x71, 0x70, 0x6f, 0x6b, - 0x68, 0x63, 0x61, 0x5f, 0x5c, 0x57, 0x51, 0x4e, 0x4b, 0x46, 0x3e, 0x36, - 0x31, 0x2c, 0x23, 0x1a, 0x13, 0x11, 0x10, 0x11, 0x11, 0x10, 0x10, 0x11, - 0x11, 0x12, 0x12, 0x11, 0x12, 0x13, 0x13, 0x11, 0x12, 0x12, 0x11, 0x13, - 0x8b, 0x85, 0x81, 0x7e, 0x78, 0x74, 0x71, 0x6e, 0x6c, 0x6a, 0x67, 0x66, - 0x65, 0x64, 0x64, 0x62, 0x61, 0x60, 0x60, 0x60, 0x5f, 0x5c, 0x5d, 0x5e, - 0x5d, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x61, 0x63, 0x67, - 0x6b, 0x6e, 0x71, 0x76, 0x7e, 0x85, 0x89, 0x8c, 0x90, 0x95, 0x96, 0x98, - 0x99, 0x9a, 0x99, 0x98, 0x97, 0x96, 0x94, 0x95, 0x94, 0x95, 0x96, 0x99, - 0x9c, 0xa1, 0xa2, 0xa3, 0xa3, 0xa5, 0xa5, 0xa6, 0xa6, 0xa5, 0xa4, 0xa1, - 0x9e, 0x9b, 0x99, 0x97, 0x95, 0x94, 0x92, 0x91, 0x91, 0x90, 0x8f, 0x91, - 0x91, 0x91, 0x90, 0x90, 0x8e, 0x8c, 0x8b, 0x88, 0x86, 0x85, 0x85, 0x83, - 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7e, 0x80, 0x81, 0x81, 0x7f, 0x80, 0x80, - 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x81, 0x81, 0x83, 0x87, 0x89, 0x8a, - 0x8d, 0x8f, 0x92, 0x95, 0x95, 0x96, 0x97, 0x9a, 0x9c, 0x9d, 0x9d, 0x9f, - 0x9f, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa1, 0x9f, 0x9e, 0x9e, 0x9f, 0x9f, - 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9c, 0x9c, 0x9b, 0x99, 0x9a, 0x99, 0x99, - 0x98, 0x97, 0x97, 0x96, 0x96, 0x97, 0x97, 0x95, 0x95, 0x95, 0x96, 0x95, - 0x96, 0x96, 0x96, 0x98, 0x97, 0x98, 0x98, 0x98, 0x99, 0x99, 0x99, 0x99, - 0x98, 0x98, 0x97, 0x97, 0x95, 0x94, 0x94, 0x93, 0x92, 0x90, 0x8f, 0x8d, - 0x8c, 0x8c, 0x8b, 0x8b, 0x8c, 0x8d, 0x8e, 0x8e, 0x8f, 0x90, 0x91, 0x91, - 0x94, 0x96, 0x96, 0x95, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x95, 0x95, - 0x95, 0x95, 0x95, 0x95, 0x96, 0x96, 0x96, 0x96, 0x94, 0x92, 0x90, 0x8b, - 0x83, 0x7c, 0x77, 0x74, 0x6d, 0x62, 0x5a, 0x57, 0x58, 0x58, 0x57, 0x5a, - 0x5b, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5b, 0x5d, 0x5e, 0x5e, - 0x5d, 0x5d, 0x5c, 0x5d, 0x5f, 0x5f, 0x60, 0x60, 0x61, 0x61, 0x61, 0x62, - 0x63, 0x63, 0x64, 0x64, 0x63, 0x64, 0x67, 0x67, 0x68, 0x6a, 0x6a, 0x6d, - 0x6f, 0x70, 0x70, 0x71, 0x71, 0x70, 0x6f, 0x6c, 0x68, 0x63, 0x60, 0x5f, - 0x5c, 0x58, 0x52, 0x4f, 0x4b, 0x46, 0x3e, 0x36, 0x31, 0x2b, 0x23, 0x1a, - 0x14, 0x11, 0x10, 0x11, 0x11, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x13, 0x13, 0x11, 0x12, 0x12, 0x11, 0x13, 0x8a, 0x83, 0x7e, 0x7b, - 0x77, 0x72, 0x6e, 0x6b, 0x69, 0x66, 0x64, 0x64, 0x63, 0x62, 0x60, 0x5f, - 0x5f, 0x5e, 0x5d, 0x5e, 0x5d, 0x5b, 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5d, - 0x5d, 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x63, 0x66, 0x68, 0x6c, 0x6e, 0x73, - 0x7b, 0x82, 0x87, 0x8b, 0x8f, 0x92, 0x95, 0x97, 0x99, 0x9a, 0x99, 0x99, - 0x96, 0x95, 0x94, 0x95, 0x95, 0x95, 0x95, 0x97, 0x9a, 0x9e, 0xa0, 0xa1, - 0xa3, 0xa5, 0xa6, 0xa6, 0xa5, 0xa5, 0xa4, 0xa2, 0x9e, 0x9a, 0x99, 0x96, - 0x95, 0x94, 0x92, 0x92, 0x90, 0x90, 0x8f, 0x90, 0x91, 0x91, 0x90, 0x8e, - 0x8d, 0x8c, 0x8b, 0x88, 0x85, 0x85, 0x84, 0x82, 0x7f, 0x7f, 0x7e, 0x7e, - 0x7d, 0x7f, 0x80, 0x81, 0x81, 0x80, 0x80, 0x80, 0x7f, 0x7e, 0x7e, 0x7e, - 0x80, 0x81, 0x81, 0x81, 0x83, 0x86, 0x88, 0x89, 0x8c, 0x8f, 0x93, 0x95, - 0x95, 0x95, 0x97, 0x9a, 0x9c, 0x9d, 0x9d, 0x9e, 0x9f, 0xa2, 0xa2, 0xa2, - 0xa2, 0xa1, 0xa1, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9d, 0x9d, 0x9d, - 0x9d, 0x9c, 0x9c, 0x9a, 0x99, 0x9b, 0x9a, 0x9a, 0x98, 0x97, 0x96, 0x96, - 0x96, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96, 0x97, 0x97, 0x96, 0x98, - 0x98, 0x99, 0x99, 0x99, 0x99, 0x9a, 0x99, 0x9a, 0x9a, 0x99, 0x97, 0x97, - 0x96, 0x95, 0x95, 0x94, 0x92, 0x8f, 0x8e, 0x8e, 0x8c, 0x8b, 0x8c, 0x8c, - 0x8c, 0x8c, 0x8e, 0x8f, 0x8f, 0x90, 0x91, 0x91, 0x94, 0x94, 0x95, 0x96, - 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x95, 0x96, 0x96, 0x96, 0x95, 0x95, - 0x95, 0x96, 0x96, 0x95, 0x93, 0x90, 0x8e, 0x89, 0x81, 0x7a, 0x75, 0x70, - 0x69, 0x60, 0x59, 0x57, 0x58, 0x58, 0x58, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, - 0x5b, 0x5b, 0x5c, 0x5c, 0x5b, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5d, - 0x5d, 0x5e, 0x5f, 0x5e, 0x60, 0x60, 0x61, 0x62, 0x63, 0x63, 0x63, 0x63, - 0x64, 0x65, 0x66, 0x66, 0x67, 0x68, 0x6a, 0x6c, 0x6e, 0x6e, 0x6f, 0x71, - 0x71, 0x70, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x5e, 0x5c, 0x56, 0x52, 0x4e, - 0x4b, 0x46, 0x3f, 0x37, 0x30, 0x2b, 0x23, 0x1a, 0x14, 0x11, 0x11, 0x10, - 0x11, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, 0x11, 0x11, - 0x11, 0x12, 0x12, 0x13, 0x86, 0x7f, 0x7a, 0x78, 0x73, 0x6e, 0x6a, 0x67, - 0x66, 0x64, 0x62, 0x61, 0x61, 0x60, 0x5e, 0x5e, 0x5d, 0x5c, 0x5c, 0x5c, - 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5d, 0x5d, 0x5e, 0x5e, 0x60, - 0x61, 0x60, 0x62, 0x66, 0x68, 0x69, 0x6b, 0x6f, 0x77, 0x7e, 0x83, 0x86, - 0x8b, 0x90, 0x93, 0x95, 0x97, 0x98, 0x98, 0x99, 0x97, 0x95, 0x94, 0x95, - 0x95, 0x95, 0x95, 0x97, 0x99, 0x9d, 0x9f, 0xa0, 0xa2, 0xa3, 0xa5, 0xa4, - 0xa4, 0xa4, 0xa4, 0xa1, 0x9e, 0x9a, 0x99, 0x97, 0x97, 0x96, 0x94, 0x93, - 0x91, 0x90, 0x8f, 0x90, 0x90, 0x8f, 0x8f, 0x8c, 0x8b, 0x8b, 0x8a, 0x88, - 0x86, 0x85, 0x84, 0x82, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7e, 0x7f, 0x80, 0x80, 0x80, - 0x82, 0x85, 0x87, 0x88, 0x8a, 0x8f, 0x92, 0x94, 0x95, 0x95, 0x97, 0x9a, - 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa2, 0xa2, 0xa2, 0xa2, 0xa3, 0xa2, 0xa0, - 0x9f, 0x9f, 0x9e, 0x9e, 0x9d, 0x9c, 0x9d, 0x9d, 0x9d, 0x9c, 0x9b, 0x9a, - 0x9b, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x98, 0x98, 0x97, 0x96, 0x96, 0x96, - 0x96, 0x96, 0x96, 0x96, 0x97, 0x96, 0x95, 0x96, 0x98, 0x9a, 0x9a, 0x9a, - 0x99, 0x99, 0x9a, 0x9b, 0x9c, 0x9a, 0x98, 0x98, 0x97, 0x97, 0x96, 0x93, - 0x92, 0x90, 0x8f, 0x8f, 0x8e, 0x8c, 0x8d, 0x8d, 0x8d, 0x8d, 0x8f, 0x8f, - 0x8f, 0x90, 0x91, 0x91, 0x93, 0x94, 0x95, 0x97, 0x97, 0x96, 0x96, 0x96, - 0x96, 0x96, 0x97, 0x96, 0x96, 0x96, 0x95, 0x95, 0x96, 0x96, 0x96, 0x94, - 0x91, 0x8e, 0x8c, 0x87, 0x7d, 0x75, 0x70, 0x6b, 0x65, 0x5d, 0x59, 0x57, - 0x58, 0x59, 0x59, 0x5a, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, - 0x5c, 0x5c, 0x5b, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5d, 0x5e, 0x5e, - 0x60, 0x61, 0x61, 0x61, 0x62, 0x63, 0x62, 0x63, 0x64, 0x65, 0x64, 0x65, - 0x66, 0x68, 0x6a, 0x6b, 0x6d, 0x6e, 0x6e, 0x70, 0x70, 0x6f, 0x6e, 0x6b, - 0x69, 0x65, 0x62, 0x61, 0x5d, 0x56, 0x52, 0x4f, 0x4c, 0x47, 0x40, 0x38, - 0x32, 0x2c, 0x24, 0x1a, 0x13, 0x11, 0x10, 0x11, 0x12, 0x10, 0x10, 0x10, - 0x10, 0x11, 0x11, 0x11, 0x12, 0x11, 0x12, 0x11, 0x11, 0x11, 0x12, 0x11, - 0x82, 0x7b, 0x76, 0x74, 0x71, 0x6b, 0x67, 0x64, 0x63, 0x61, 0x5e, 0x5d, - 0x5f, 0x5f, 0x5d, 0x5d, 0x5c, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, - 0x5d, 0x5f, 0x5f, 0x5d, 0x5d, 0x5d, 0x5d, 0x5f, 0x60, 0x61, 0x61, 0x64, - 0x67, 0x68, 0x69, 0x6c, 0x72, 0x79, 0x80, 0x83, 0x88, 0x8d, 0x91, 0x92, - 0x94, 0x96, 0x98, 0x98, 0x98, 0x97, 0x96, 0x95, 0x95, 0x95, 0x95, 0x96, - 0x98, 0x9b, 0x9e, 0x9f, 0xa0, 0xa3, 0xa4, 0xa4, 0xa3, 0xa3, 0xa2, 0xa0, - 0x9e, 0x9b, 0x9a, 0x9a, 0x98, 0x97, 0x94, 0x93, 0x92, 0x90, 0x8f, 0x90, - 0x8f, 0x8e, 0x8d, 0x8c, 0x8a, 0x8a, 0x89, 0x87, 0x86, 0x85, 0x84, 0x82, - 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, - 0x80, 0x80, 0x7f, 0x7e, 0x7e, 0x7f, 0x7f, 0x80, 0x82, 0x84, 0x85, 0x86, - 0x89, 0x8e, 0x91, 0x93, 0x94, 0x95, 0x97, 0x9a, 0x9d, 0x9e, 0x9f, 0xa1, - 0xa2, 0xa3, 0xa3, 0xa3, 0xa2, 0xa3, 0xa2, 0xa0, 0x9f, 0x9f, 0x9e, 0x9e, - 0x9d, 0x9d, 0x9d, 0x9c, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x96, 0x95, - 0x94, 0x94, 0x94, 0x95, 0x95, 0x96, 0x95, 0x96, 0x97, 0x97, 0x96, 0x96, - 0x97, 0x96, 0x96, 0x96, 0x98, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9c, 0x9c, - 0x9c, 0x9b, 0x9b, 0x99, 0x98, 0x97, 0x96, 0x94, 0x92, 0x91, 0x90, 0x90, - 0x8f, 0x8e, 0x8c, 0x8d, 0x8d, 0x8d, 0x8f, 0x8f, 0x90, 0x90, 0x91, 0x91, - 0x93, 0x94, 0x95, 0x96, 0x95, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x95, - 0x95, 0x95, 0x97, 0x97, 0x96, 0x96, 0x95, 0x93, 0x90, 0x8c, 0x89, 0x83, - 0x79, 0x70, 0x6a, 0x66, 0x62, 0x5c, 0x58, 0x57, 0x57, 0x58, 0x59, 0x5a, - 0x5b, 0x5b, 0x5b, 0x59, 0x5a, 0x5b, 0x5b, 0x5a, 0x5c, 0x5b, 0x5c, 0x5c, - 0x5b, 0x5b, 0x5c, 0x5c, 0x5d, 0x5e, 0x5e, 0x5e, 0x61, 0x61, 0x61, 0x61, - 0x63, 0x63, 0x62, 0x63, 0x64, 0x65, 0x64, 0x65, 0x66, 0x67, 0x6a, 0x6b, - 0x6d, 0x6e, 0x6e, 0x70, 0x71, 0x70, 0x6f, 0x6c, 0x6a, 0x66, 0x63, 0x62, - 0x5e, 0x58, 0x53, 0x50, 0x4d, 0x48, 0x40, 0x39, 0x33, 0x2f, 0x26, 0x1a, - 0x13, 0x11, 0x10, 0x10, 0x11, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, - 0x12, 0x13, 0x13, 0x11, 0x12, 0x12, 0x13, 0x11, 0x81, 0x79, 0x74, 0x71, - 0x6d, 0x66, 0x63, 0x62, 0x61, 0x5f, 0x5c, 0x5c, 0x5d, 0x5d, 0x5c, 0x5a, - 0x5a, 0x59, 0x59, 0x5a, 0x5a, 0x59, 0x58, 0x59, 0x5c, 0x5f, 0x5f, 0x5e, - 0x5d, 0x5d, 0x5c, 0x5e, 0x60, 0x61, 0x62, 0x63, 0x67, 0x69, 0x6a, 0x6c, - 0x70, 0x76, 0x7c, 0x7f, 0x84, 0x8a, 0x8e, 0x90, 0x92, 0x94, 0x97, 0x98, - 0x98, 0x98, 0x96, 0x96, 0x95, 0x94, 0x94, 0x95, 0x97, 0x9b, 0x9d, 0x9e, - 0xa0, 0xa1, 0xa4, 0xa4, 0xa4, 0xa3, 0xa2, 0xa0, 0x9d, 0x9c, 0x9b, 0x9a, - 0x98, 0x97, 0x95, 0x94, 0x92, 0x91, 0x90, 0x8f, 0x8e, 0x8e, 0x8d, 0x8c, - 0x8a, 0x89, 0x87, 0x87, 0x85, 0x84, 0x83, 0x81, 0x80, 0x7f, 0x7e, 0x7e, - 0x7f, 0x7f, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x7f, 0x7f, - 0x7d, 0x7e, 0x7e, 0x7f, 0x81, 0x82, 0x84, 0x85, 0x88, 0x8c, 0x90, 0x92, - 0x93, 0x94, 0x98, 0x9c, 0x9e, 0x9e, 0x9f, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, - 0xa2, 0xa3, 0xa2, 0xa0, 0x9f, 0x9f, 0x9d, 0x9d, 0x9e, 0x9e, 0x9d, 0x9d, - 0x9c, 0x9b, 0x9a, 0x97, 0x95, 0x90, 0x8e, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, - 0x8d, 0x8f, 0x92, 0x94, 0x96, 0x97, 0x97, 0x98, 0x97, 0x96, 0x96, 0x98, - 0x99, 0x9b, 0x9b, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9a, - 0x98, 0x97, 0x95, 0x94, 0x93, 0x92, 0x92, 0x90, 0x8f, 0x8e, 0x8c, 0x8c, - 0x8c, 0x8e, 0x8e, 0x90, 0x90, 0x91, 0x91, 0x93, 0x94, 0x95, 0x95, 0x96, - 0x96, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97, 0x95, 0x95, 0x95, 0x97, 0x98, - 0x97, 0x97, 0x95, 0x91, 0x8d, 0x89, 0x86, 0x81, 0x78, 0x6e, 0x67, 0x63, - 0x5f, 0x5a, 0x57, 0x56, 0x57, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, - 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5c, 0x5c, - 0x5d, 0x5d, 0x5e, 0x5e, 0x61, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, - 0x65, 0x65, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6c, 0x6e, 0x6e, 0x6e, 0x70, - 0x71, 0x70, 0x6f, 0x6c, 0x6a, 0x66, 0x63, 0x61, 0x5e, 0x59, 0x54, 0x50, - 0x4e, 0x48, 0x3f, 0x38, 0x33, 0x30, 0x27, 0x1b, 0x13, 0x11, 0x10, 0x10, - 0x11, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x13, 0x12, 0x12, - 0x12, 0x12, 0x12, 0x13, 0x80, 0x77, 0x72, 0x6f, 0x6a, 0x62, 0x60, 0x60, - 0x5f, 0x5d, 0x5b, 0x5a, 0x5b, 0x5b, 0x5b, 0x5a, 0x59, 0x59, 0x59, 0x5a, - 0x5a, 0x58, 0x57, 0x58, 0x5b, 0x5e, 0x5e, 0x5e, 0x5d, 0x5d, 0x5d, 0x5f, - 0x5f, 0x60, 0x62, 0x64, 0x67, 0x68, 0x69, 0x6b, 0x6e, 0x74, 0x79, 0x7c, - 0x81, 0x87, 0x8c, 0x8e, 0x90, 0x92, 0x95, 0x97, 0x98, 0x97, 0x96, 0x96, - 0x95, 0x94, 0x94, 0x95, 0x97, 0x9a, 0x9b, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, - 0xa3, 0xa3, 0xa2, 0xa0, 0x9d, 0x9c, 0x9b, 0x9a, 0x98, 0x97, 0x95, 0x94, - 0x92, 0x91, 0x90, 0x8e, 0x8e, 0x8e, 0x8d, 0x8c, 0x8b, 0x89, 0x87, 0x86, - 0x85, 0x84, 0x82, 0x81, 0x80, 0x7f, 0x7e, 0x7e, 0x7f, 0x7f, 0x80, 0x81, - 0x81, 0x82, 0x81, 0x80, 0x81, 0x80, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x7e, - 0x81, 0x82, 0x84, 0x85, 0x88, 0x8c, 0x8f, 0x92, 0x93, 0x94, 0x98, 0x9c, - 0x9e, 0x9f, 0x9f, 0xa1, 0xa2, 0xa1, 0xa2, 0xa3, 0xa2, 0xa3, 0xa2, 0xa0, - 0x9f, 0x9f, 0x9d, 0x9d, 0x9e, 0x9e, 0x9c, 0x9b, 0x98, 0x97, 0x96, 0x92, - 0x8e, 0x88, 0x85, 0x84, 0x83, 0x82, 0x82, 0x83, 0x84, 0x87, 0x8b, 0x90, - 0x93, 0x95, 0x97, 0x98, 0x98, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9b, - 0x9b, 0x9d, 0x9c, 0x9b, 0x9c, 0x9c, 0x9c, 0x9a, 0x99, 0x97, 0x95, 0x94, - 0x94, 0x93, 0x92, 0x90, 0x90, 0x8e, 0x8c, 0x8c, 0x8c, 0x8e, 0x8e, 0x90, - 0x91, 0x90, 0x90, 0x93, 0x94, 0x95, 0x95, 0x96, 0x96, 0x98, 0x98, 0x98, - 0x98, 0x98, 0x97, 0x95, 0x95, 0x95, 0x97, 0x98, 0x97, 0x96, 0x94, 0x90, - 0x8c, 0x87, 0x84, 0x7f, 0x76, 0x6c, 0x65, 0x61, 0x5d, 0x59, 0x56, 0x56, - 0x57, 0x59, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5c, 0x5c, 0x5c, 0x5b, - 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e, - 0x61, 0x61, 0x61, 0x61, 0x62, 0x61, 0x62, 0x63, 0x65, 0x65, 0x65, 0x66, - 0x67, 0x68, 0x69, 0x6c, 0x6e, 0x6e, 0x6e, 0x70, 0x71, 0x70, 0x6f, 0x6d, - 0x6b, 0x66, 0x62, 0x60, 0x5e, 0x59, 0x54, 0x51, 0x4e, 0x48, 0x40, 0x39, - 0x34, 0x30, 0x28, 0x1c, 0x13, 0x11, 0x11, 0x10, 0x11, 0x10, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x12, 0x12, 0x13, 0x12, 0x12, 0x12, 0x12, 0x12, 0x14, - 0x7b, 0x74, 0x6e, 0x6b, 0x65, 0x5f, 0x5d, 0x5d, 0x5d, 0x5b, 0x59, 0x59, - 0x58, 0x58, 0x58, 0x57, 0x57, 0x57, 0x58, 0x59, 0x5a, 0x58, 0x58, 0x59, - 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x60, 0x61, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x6a, 0x6d, 0x70, 0x74, 0x77, 0x7e, 0x84, 0x89, 0x8b, - 0x8e, 0x91, 0x93, 0x95, 0x95, 0x96, 0x97, 0x97, 0x95, 0x94, 0x95, 0x95, - 0x96, 0x98, 0x9a, 0x9a, 0x9c, 0x9e, 0xa0, 0xa0, 0xa2, 0xa2, 0xa1, 0x9f, - 0x9d, 0x9c, 0x9b, 0x9a, 0x98, 0x97, 0x95, 0x94, 0x92, 0x91, 0x91, 0x8e, - 0x8e, 0x8d, 0x8d, 0x8c, 0x89, 0x89, 0x88, 0x87, 0x85, 0x84, 0x82, 0x81, - 0x80, 0x7f, 0x7e, 0x7e, 0x7f, 0x7f, 0x80, 0x81, 0x81, 0x82, 0x81, 0x80, - 0x81, 0x80, 0x7f, 0x7f, 0x7d, 0x7d, 0x7d, 0x7e, 0x80, 0x83, 0x84, 0x86, - 0x88, 0x8b, 0x8f, 0x92, 0x93, 0x94, 0x97, 0x9c, 0x9d, 0xa0, 0xa1, 0xa2, - 0xa2, 0xa2, 0xa3, 0xa3, 0xa2, 0xa2, 0xa1, 0x9f, 0x9f, 0x9f, 0x9e, 0x9c, - 0x9c, 0x9b, 0x98, 0x93, 0x8f, 0x8c, 0x89, 0x84, 0x80, 0x79, 0x74, 0x72, - 0x6f, 0x6f, 0x71, 0x71, 0x73, 0x75, 0x7b, 0x83, 0x88, 0x8c, 0x92, 0x96, - 0x98, 0x99, 0x99, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9d, 0x9c, 0x9c, - 0x9b, 0x9c, 0x9c, 0x9a, 0x99, 0x98, 0x97, 0x96, 0x95, 0x94, 0x93, 0x91, - 0x90, 0x8f, 0x8c, 0x8c, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x90, 0x90, 0x93, - 0x94, 0x95, 0x95, 0x96, 0x96, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97, 0x96, - 0x95, 0x95, 0x97, 0x98, 0x97, 0x95, 0x92, 0x8f, 0x8a, 0x85, 0x82, 0x7c, - 0x73, 0x68, 0x63, 0x5f, 0x5b, 0x58, 0x57, 0x57, 0x58, 0x59, 0x5a, 0x5a, - 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5a, 0x5b, 0x5b, 0x5b, 0x5b, - 0x5a, 0x5b, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x5e, 0x60, 0x61, 0x61, 0x61, - 0x62, 0x61, 0x62, 0x63, 0x66, 0x67, 0x66, 0x67, 0x67, 0x6a, 0x6b, 0x6b, - 0x6d, 0x6e, 0x6e, 0x70, 0x71, 0x70, 0x6f, 0x6d, 0x6b, 0x66, 0x63, 0x61, - 0x5f, 0x5a, 0x55, 0x52, 0x4f, 0x48, 0x42, 0x3a, 0x35, 0x31, 0x28, 0x1c, - 0x13, 0x12, 0x11, 0x10, 0x11, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x13, 0x11, 0x11, 0x12, 0x12, 0x12, 0x14, 0x75, 0x6d, 0x68, 0x64, - 0x61, 0x5d, 0x5b, 0x5c, 0x5b, 0x58, 0x57, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x57, 0x58, 0x58, 0x5a, 0x5a, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x60, - 0x60, 0x60, 0x60, 0x60, 0x61, 0x62, 0x63, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6c, 0x6d, 0x70, 0x73, 0x79, 0x81, 0x86, 0x89, 0x8b, 0x8e, 0x91, 0x93, - 0x94, 0x95, 0x95, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95, 0x96, 0x97, 0x98, - 0x9a, 0x9c, 0x9e, 0xa0, 0x9f, 0x9f, 0x9e, 0x9e, 0x9d, 0x9c, 0x9c, 0x9b, - 0x9a, 0x97, 0x96, 0x95, 0x93, 0x91, 0x90, 0x8e, 0x8d, 0x8d, 0x8c, 0x8a, - 0x89, 0x88, 0x88, 0x87, 0x85, 0x83, 0x81, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x81, 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x82, 0x81, 0x81, 0x80, 0x7e, - 0x7c, 0x7c, 0x7d, 0x7d, 0x80, 0x83, 0x84, 0x85, 0x87, 0x8b, 0x90, 0x92, - 0x93, 0x95, 0x99, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa2, 0xa2, 0xa3, 0xa3, - 0xa3, 0xa2, 0xa1, 0xa0, 0xa0, 0x9f, 0x9d, 0x9a, 0x96, 0x93, 0x8c, 0x82, - 0x7a, 0x74, 0x71, 0x6c, 0x67, 0x62, 0x5f, 0x5d, 0x5b, 0x5c, 0x5e, 0x60, - 0x60, 0x63, 0x68, 0x6f, 0x76, 0x7a, 0x82, 0x8d, 0x96, 0x99, 0x9a, 0x9b, - 0x9b, 0x9a, 0x9a, 0x9b, 0x9b, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c, 0x9b, 0x9a, - 0x9a, 0x99, 0x99, 0x98, 0x96, 0x95, 0x93, 0x93, 0x91, 0x90, 0x8d, 0x8c, - 0x8c, 0x8d, 0x8d, 0x8f, 0x90, 0x91, 0x92, 0x92, 0x94, 0x94, 0x95, 0x96, - 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x97, 0x97, - 0x97, 0x95, 0x92, 0x8e, 0x88, 0x83, 0x7f, 0x79, 0x6f, 0x66, 0x60, 0x5d, - 0x5a, 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x59, 0x58, 0x58, - 0x59, 0x5a, 0x5b, 0x5a, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5a, 0x5a, 0x5b, - 0x5d, 0x5e, 0x5f, 0x5f, 0x60, 0x61, 0x61, 0x61, 0x62, 0x63, 0x64, 0x64, - 0x65, 0x68, 0x69, 0x68, 0x68, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6f, 0x70, - 0x70, 0x70, 0x6f, 0x6d, 0x6b, 0x67, 0x64, 0x62, 0x60, 0x5b, 0x56, 0x53, - 0x50, 0x4a, 0x43, 0x3c, 0x37, 0x33, 0x2a, 0x1d, 0x14, 0x12, 0x12, 0x12, - 0x12, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x13, 0x13, 0x13, 0x13, 0x12, - 0x12, 0x12, 0x12, 0x14, 0x6e, 0x65, 0x5f, 0x5c, 0x5a, 0x59, 0x58, 0x59, - 0x59, 0x56, 0x55, 0x55, 0x54, 0x54, 0x55, 0x55, 0x56, 0x57, 0x57, 0x58, - 0x5a, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x61, - 0x62, 0x63, 0x63, 0x65, 0x67, 0x68, 0x69, 0x69, 0x6c, 0x6d, 0x6e, 0x70, - 0x76, 0x7c, 0x81, 0x85, 0x88, 0x8b, 0x8e, 0x91, 0x92, 0x92, 0x92, 0x94, - 0x94, 0x94, 0x95, 0x95, 0x94, 0x94, 0x96, 0x96, 0x98, 0x9b, 0x9c, 0x9e, - 0x9e, 0x9e, 0x9e, 0x9d, 0x9d, 0x9b, 0x9a, 0x9b, 0x99, 0x98, 0x97, 0x96, - 0x94, 0x92, 0x90, 0x8f, 0x8e, 0x8d, 0x8c, 0x89, 0x88, 0x88, 0x88, 0x86, - 0x84, 0x82, 0x80, 0x7f, 0x7e, 0x7f, 0x7f, 0x80, 0x82, 0x82, 0x82, 0x83, - 0x84, 0x84, 0x84, 0x82, 0x81, 0x81, 0x80, 0x7d, 0x7c, 0x7c, 0x7c, 0x7d, - 0x80, 0x82, 0x83, 0x84, 0x87, 0x8b, 0x8f, 0x92, 0x93, 0x96, 0x9a, 0x9d, - 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa3, 0xa3, 0xa2, 0xa3, 0xa1, 0xa0, - 0x9f, 0x9c, 0x97, 0x90, 0x88, 0x82, 0x77, 0x69, 0x61, 0x5d, 0x5a, 0x58, - 0x58, 0x57, 0x57, 0x57, 0x58, 0x5b, 0x60, 0x62, 0x61, 0x60, 0x61, 0x64, - 0x68, 0x6b, 0x73, 0x7f, 0x8b, 0x91, 0x94, 0x97, 0x9b, 0x9b, 0x9b, 0x9b, - 0x9b, 0x9b, 0x9d, 0x9c, 0x9d, 0x9c, 0x9b, 0x99, 0x99, 0x99, 0x99, 0x97, - 0x95, 0x94, 0x94, 0x93, 0x92, 0x92, 0x90, 0x8e, 0x8e, 0x8f, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x92, 0x94, 0x95, 0x94, 0x94, 0x96, 0x97, 0x97, 0x97, - 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, 0x96, 0x97, 0x96, 0x95, 0x91, 0x8c, - 0x86, 0x7f, 0x7b, 0x75, 0x6c, 0x64, 0x5d, 0x5b, 0x58, 0x56, 0x57, 0x59, - 0x59, 0x58, 0x58, 0x58, 0x58, 0x58, 0x57, 0x57, 0x58, 0x59, 0x5a, 0x5b, - 0x5a, 0x5a, 0x5b, 0x5a, 0x5a, 0x5b, 0x5a, 0x5b, 0x5d, 0x5e, 0x5f, 0x5e, - 0x5f, 0x5f, 0x5f, 0x60, 0x63, 0x64, 0x65, 0x65, 0x67, 0x68, 0x69, 0x69, - 0x69, 0x6a, 0x69, 0x6a, 0x6c, 0x6e, 0x6f, 0x71, 0x70, 0x70, 0x70, 0x6d, - 0x6b, 0x67, 0x64, 0x62, 0x5f, 0x5a, 0x57, 0x52, 0x4f, 0x4a, 0x44, 0x3f, - 0x38, 0x33, 0x2a, 0x1e, 0x14, 0x12, 0x11, 0x12, 0x10, 0x11, 0x10, 0x11, - 0x11, 0x11, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x14, - 0x68, 0x61, 0x5b, 0x58, 0x57, 0x57, 0x56, 0x57, 0x56, 0x55, 0x55, 0x54, - 0x53, 0x54, 0x55, 0x56, 0x57, 0x57, 0x56, 0x58, 0x5a, 0x5a, 0x5c, 0x5c, - 0x5d, 0x5e, 0x5f, 0x60, 0x60, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, - 0x67, 0x69, 0x69, 0x6a, 0x6b, 0x6d, 0x6d, 0x6e, 0x72, 0x78, 0x7e, 0x83, - 0x86, 0x89, 0x8c, 0x8d, 0x8e, 0x8f, 0x91, 0x92, 0x93, 0x95, 0x95, 0x96, - 0x95, 0x94, 0x95, 0x95, 0x97, 0x98, 0x99, 0x9c, 0x9d, 0x9d, 0x9d, 0x9c, - 0x9c, 0x9b, 0x9b, 0x9b, 0x98, 0x96, 0x96, 0x96, 0x94, 0x91, 0x90, 0x8f, - 0x8e, 0x8d, 0x8b, 0x89, 0x89, 0x89, 0x88, 0x86, 0x83, 0x82, 0x80, 0x7f, - 0x7e, 0x7f, 0x7f, 0x80, 0x82, 0x82, 0x83, 0x84, 0x85, 0x85, 0x84, 0x82, - 0x81, 0x80, 0x80, 0x7d, 0x7c, 0x7c, 0x7c, 0x7c, 0x7e, 0x80, 0x82, 0x84, - 0x86, 0x8a, 0x8e, 0x91, 0x93, 0x96, 0x9a, 0x9d, 0x9f, 0xa0, 0xa1, 0xa3, - 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x9f, 0x9c, 0x97, 0x8e, 0x81, - 0x77, 0x6f, 0x65, 0x5b, 0x56, 0x53, 0x52, 0x52, 0x53, 0x56, 0x58, 0x58, - 0x5a, 0x5e, 0x63, 0x66, 0x65, 0x64, 0x62, 0x64, 0x66, 0x68, 0x6b, 0x73, - 0x7b, 0x80, 0x83, 0x89, 0x92, 0x98, 0x9b, 0x9c, 0x9d, 0x9c, 0x9d, 0x9c, - 0x9b, 0x9a, 0x9b, 0x9a, 0x9b, 0x9a, 0x9a, 0x98, 0x95, 0x94, 0x94, 0x94, - 0x92, 0x93, 0x92, 0x8f, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x91, 0x92, 0x92, - 0x94, 0x94, 0x94, 0x94, 0x96, 0x97, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, - 0x98, 0x98, 0x96, 0x97, 0x96, 0x94, 0x90, 0x8a, 0x83, 0x7d, 0x78, 0x72, - 0x69, 0x62, 0x5c, 0x5a, 0x58, 0x57, 0x58, 0x59, 0x59, 0x59, 0x58, 0x57, - 0x57, 0x57, 0x58, 0x58, 0x58, 0x59, 0x59, 0x5a, 0x58, 0x58, 0x59, 0x59, - 0x59, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5e, 0x5e, 0x5f, 0x61, - 0x63, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6b, 0x6b, 0x6a, 0x6a, - 0x6c, 0x6e, 0x6f, 0x71, 0x70, 0x70, 0x70, 0x6d, 0x6a, 0x67, 0x64, 0x62, - 0x5f, 0x5a, 0x57, 0x52, 0x4f, 0x4b, 0x45, 0x3e, 0x38, 0x33, 0x2a, 0x1e, - 0x14, 0x11, 0x10, 0x11, 0x10, 0x10, 0x12, 0x12, 0x11, 0x11, 0x13, 0x13, - 0x13, 0x13, 0x12, 0x13, 0x13, 0x13, 0x12, 0x13, 0x64, 0x5f, 0x59, 0x56, - 0x55, 0x55, 0x54, 0x55, 0x54, 0x54, 0x54, 0x53, 0x53, 0x53, 0x55, 0x55, - 0x57, 0x57, 0x56, 0x57, 0x5a, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5f, 0x60, - 0x60, 0x60, 0x61, 0x61, 0x63, 0x63, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6a, - 0x6b, 0x6c, 0x6c, 0x6d, 0x6f, 0x75, 0x7c, 0x81, 0x84, 0x87, 0x8a, 0x8b, - 0x8d, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x95, 0x95, 0x94, 0x94, 0x95, - 0x96, 0x98, 0x99, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9a, - 0x97, 0x95, 0x96, 0x95, 0x93, 0x91, 0x90, 0x8e, 0x8e, 0x8d, 0x8b, 0x89, - 0x89, 0x89, 0x87, 0x85, 0x82, 0x81, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, - 0x81, 0x82, 0x83, 0x85, 0x86, 0x86, 0x84, 0x82, 0x81, 0x81, 0x80, 0x7e, - 0x7c, 0x7c, 0x7c, 0x7c, 0x7e, 0x80, 0x82, 0x83, 0x86, 0x8a, 0x8d, 0x90, - 0x93, 0x95, 0x9a, 0x9c, 0x9f, 0xa0, 0xa1, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, - 0xa3, 0xa3, 0xa1, 0x9e, 0x9a, 0x92, 0x85, 0x76, 0x6a, 0x64, 0x5c, 0x55, - 0x53, 0x50, 0x50, 0x51, 0x53, 0x57, 0x58, 0x5a, 0x5b, 0x5e, 0x63, 0x66, - 0x66, 0x65, 0x64, 0x66, 0x69, 0x69, 0x69, 0x6b, 0x6f, 0x71, 0x73, 0x7a, - 0x83, 0x8b, 0x92, 0x95, 0x98, 0x9b, 0x9d, 0x9c, 0x9c, 0x9a, 0x9b, 0x9a, - 0x9b, 0x9b, 0x9a, 0x98, 0x97, 0x95, 0x94, 0x94, 0x93, 0x93, 0x92, 0x8f, - 0x8f, 0x8f, 0x8f, 0x90, 0x91, 0x91, 0x92, 0x92, 0x94, 0x95, 0x95, 0x95, - 0x97, 0x97, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97, 0x97, - 0x95, 0x93, 0x8f, 0x89, 0x82, 0x7c, 0x77, 0x70, 0x67, 0x5f, 0x5b, 0x59, - 0x58, 0x57, 0x58, 0x58, 0x58, 0x59, 0x58, 0x57, 0x56, 0x57, 0x57, 0x57, - 0x57, 0x59, 0x59, 0x59, 0x57, 0x58, 0x59, 0x59, 0x59, 0x5a, 0x5b, 0x5b, - 0x5c, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f, 0x61, 0x64, 0x64, 0x66, 0x67, - 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6b, 0x6a, 0x6a, 0x6c, 0x6e, 0x6f, 0x71, - 0x71, 0x70, 0x70, 0x6d, 0x6a, 0x67, 0x65, 0x63, 0x60, 0x5b, 0x57, 0x52, - 0x4f, 0x4c, 0x45, 0x3d, 0x38, 0x33, 0x2a, 0x1e, 0x15, 0x11, 0x10, 0x11, - 0x10, 0x11, 0x12, 0x12, 0x11, 0x11, 0x13, 0x13, 0x13, 0x13, 0x12, 0x13, - 0x13, 0x13, 0x12, 0x12, 0x5d, 0x5a, 0x57, 0x55, 0x54, 0x53, 0x52, 0x52, - 0x52, 0x52, 0x53, 0x53, 0x52, 0x52, 0x54, 0x56, 0x56, 0x56, 0x57, 0x57, - 0x59, 0x5b, 0x5b, 0x5b, 0x5c, 0x5e, 0x60, 0x60, 0x60, 0x61, 0x62, 0x62, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x6a, 0x6b, 0x6c, 0x6d, 0x6c, - 0x6c, 0x71, 0x78, 0x7e, 0x80, 0x82, 0x86, 0x88, 0x8b, 0x8c, 0x8d, 0x8e, - 0x90, 0x92, 0x93, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x97, 0x98, 0x9a, - 0x9a, 0x9a, 0x9b, 0x9a, 0x9a, 0x9b, 0x9a, 0x98, 0x96, 0x95, 0x94, 0x93, - 0x92, 0x92, 0x90, 0x8d, 0x8d, 0x8c, 0x8b, 0x8a, 0x88, 0x87, 0x86, 0x84, - 0x82, 0x81, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x81, 0x82, 0x85, 0x86, - 0x86, 0x87, 0x86, 0x84, 0x83, 0x82, 0x7f, 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, - 0x7f, 0x81, 0x82, 0x83, 0x85, 0x89, 0x8c, 0x8f, 0x91, 0x94, 0x99, 0x9b, - 0x9e, 0x9e, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa0, 0x9b, - 0x95, 0x87, 0x74, 0x65, 0x5e, 0x5b, 0x56, 0x53, 0x52, 0x50, 0x50, 0x52, - 0x56, 0x58, 0x5a, 0x5a, 0x5a, 0x5b, 0x60, 0x62, 0x63, 0x64, 0x63, 0x66, - 0x68, 0x68, 0x64, 0x60, 0x5e, 0x5d, 0x5d, 0x5f, 0x64, 0x6b, 0x75, 0x7b, - 0x86, 0x90, 0x98, 0x9b, 0x9c, 0x9b, 0x9b, 0x99, 0x96, 0x94, 0x93, 0x94, - 0x96, 0x97, 0x97, 0x94, 0x92, 0x93, 0x91, 0x8f, 0x8f, 0x8f, 0x8f, 0x91, - 0x92, 0x92, 0x93, 0x93, 0x95, 0x96, 0x96, 0x96, 0x97, 0x97, 0x98, 0x98, - 0x98, 0x98, 0x98, 0x98, 0x98, 0x97, 0x97, 0x96, 0x93, 0x91, 0x8e, 0x87, - 0x7f, 0x78, 0x74, 0x6d, 0x64, 0x5d, 0x59, 0x57, 0x57, 0x56, 0x57, 0x57, - 0x57, 0x58, 0x57, 0x56, 0x57, 0x57, 0x57, 0x57, 0x56, 0x58, 0x58, 0x58, - 0x57, 0x59, 0x59, 0x59, 0x58, 0x58, 0x5a, 0x59, 0x5a, 0x5a, 0x5b, 0x5d, - 0x5f, 0x5f, 0x60, 0x61, 0x63, 0x65, 0x66, 0x66, 0x67, 0x68, 0x6b, 0x6c, - 0x6c, 0x6c, 0x6a, 0x6b, 0x6c, 0x6e, 0x6f, 0x71, 0x72, 0x71, 0x6f, 0x6d, - 0x6b, 0x68, 0x66, 0x64, 0x5f, 0x5b, 0x57, 0x52, 0x50, 0x4d, 0x46, 0x3e, - 0x3a, 0x35, 0x2c, 0x1f, 0x15, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x11, 0x11, 0x11, 0x13, 0x14, 0x13, 0x13, 0x13, 0x12, 0x11, 0x11, 0x13, - 0x58, 0x57, 0x55, 0x54, 0x54, 0x53, 0x51, 0x51, 0x51, 0x51, 0x51, 0x52, - 0x52, 0x52, 0x53, 0x56, 0x56, 0x58, 0x58, 0x58, 0x59, 0x5b, 0x5b, 0x5b, - 0x5c, 0x5e, 0x5f, 0x61, 0x61, 0x61, 0x61, 0x63, 0x63, 0x64, 0x65, 0x66, - 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6c, 0x6b, 0x6b, 0x6b, 0x6e, 0x73, 0x78, - 0x7a, 0x7d, 0x80, 0x84, 0x87, 0x88, 0x89, 0x8b, 0x8e, 0x8f, 0x90, 0x91, - 0x92, 0x93, 0x92, 0x92, 0x94, 0x96, 0x96, 0x98, 0x98, 0x98, 0x99, 0x99, - 0x9a, 0x9a, 0x99, 0x97, 0x96, 0x94, 0x93, 0x92, 0x91, 0x91, 0x8f, 0x8d, - 0x8d, 0x8d, 0x8b, 0x8a, 0x88, 0x88, 0x86, 0x84, 0x82, 0x81, 0x81, 0x7f, - 0x80, 0x80, 0x81, 0x82, 0x82, 0x83, 0x85, 0x85, 0x85, 0x86, 0x86, 0x85, - 0x84, 0x82, 0x80, 0x7d, 0x7b, 0x7c, 0x7c, 0x7c, 0x7e, 0x81, 0x82, 0x82, - 0x85, 0x89, 0x8c, 0x8e, 0x90, 0x93, 0x97, 0x9b, 0x9e, 0x9f, 0xa1, 0xa1, - 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x9d, 0x95, 0x8b, 0x77, 0x62, 0x5a, - 0x5a, 0x58, 0x54, 0x53, 0x52, 0x52, 0x53, 0x55, 0x59, 0x5b, 0x5c, 0x5c, - 0x5b, 0x5b, 0x5a, 0x59, 0x5a, 0x59, 0x59, 0x5b, 0x5c, 0x5a, 0x56, 0x54, - 0x54, 0x51, 0x50, 0x4f, 0x50, 0x51, 0x55, 0x5b, 0x64, 0x70, 0x7d, 0x8b, - 0x92, 0x97, 0x93, 0x89, 0x7f, 0x79, 0x71, 0x75, 0x84, 0x91, 0x95, 0x95, - 0x93, 0x92, 0x92, 0x91, 0x90, 0x90, 0x91, 0x90, 0x92, 0x92, 0x92, 0x93, - 0x95, 0x96, 0x96, 0x97, 0x96, 0x97, 0x97, 0x97, 0x97, 0x96, 0x98, 0x98, - 0x98, 0x97, 0x97, 0x95, 0x92, 0x90, 0x8d, 0x86, 0x7c, 0x76, 0x71, 0x69, - 0x61, 0x5b, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x59, 0x57, 0x55, - 0x56, 0x56, 0x55, 0x56, 0x55, 0x57, 0x57, 0x57, 0x56, 0x58, 0x59, 0x58, - 0x58, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5d, 0x5f, 0x5f, 0x60, 0x63, - 0x65, 0x65, 0x67, 0x68, 0x69, 0x69, 0x6b, 0x6d, 0x6e, 0x6e, 0x6c, 0x6c, - 0x6e, 0x6f, 0x6f, 0x71, 0x72, 0x70, 0x6f, 0x6d, 0x6b, 0x67, 0x66, 0x65, - 0x61, 0x5c, 0x58, 0x53, 0x50, 0x4c, 0x47, 0x40, 0x3b, 0x36, 0x2f, 0x23, - 0x15, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x13, - 0x14, 0x13, 0x13, 0x11, 0x12, 0x12, 0x11, 0x13, 0x57, 0x57, 0x54, 0x53, - 0x54, 0x53, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x53, 0x53, 0x55, - 0x56, 0x58, 0x58, 0x58, 0x59, 0x5b, 0x5b, 0x5c, 0x5d, 0x5e, 0x60, 0x62, - 0x61, 0x60, 0x61, 0x64, 0x64, 0x65, 0x66, 0x67, 0x66, 0x67, 0x69, 0x69, - 0x6a, 0x6b, 0x6a, 0x6a, 0x6a, 0x6b, 0x6d, 0x71, 0x74, 0x78, 0x7b, 0x80, - 0x83, 0x84, 0x86, 0x88, 0x8b, 0x8c, 0x8d, 0x8f, 0x90, 0x91, 0x91, 0x91, - 0x93, 0x95, 0x94, 0x95, 0x95, 0x96, 0x97, 0x98, 0x98, 0x98, 0x97, 0x96, - 0x94, 0x93, 0x93, 0x93, 0x91, 0x90, 0x8e, 0x8d, 0x8c, 0x8c, 0x8b, 0x89, - 0x88, 0x87, 0x86, 0x84, 0x83, 0x82, 0x81, 0x7e, 0x7f, 0x81, 0x82, 0x83, - 0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x86, 0x85, 0x83, 0x82, 0x80, 0x7c, - 0x7b, 0x7c, 0x7c, 0x7b, 0x7d, 0x80, 0x81, 0x81, 0x83, 0x88, 0x8c, 0x8e, - 0x90, 0x93, 0x96, 0x9a, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa2, 0xa3, - 0xa3, 0xa3, 0x9b, 0x8f, 0x82, 0x6c, 0x5d, 0x5a, 0x5a, 0x58, 0x54, 0x54, - 0x55, 0x57, 0x58, 0x5b, 0x5c, 0x5c, 0x5c, 0x5d, 0x5c, 0x5a, 0x59, 0x58, - 0x57, 0x59, 0x60, 0x60, 0x5d, 0x5b, 0x59, 0x54, 0x52, 0x4e, 0x4d, 0x4d, - 0x4d, 0x4c, 0x4f, 0x52, 0x57, 0x5d, 0x67, 0x73, 0x7b, 0x7e, 0x79, 0x84, - 0x8a, 0x83, 0x6c, 0x5b, 0x62, 0x73, 0x81, 0x93, 0x94, 0x93, 0x93, 0x91, - 0x90, 0x90, 0x91, 0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0x95, 0x95, 0x95, - 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x95, - 0x92, 0x8f, 0x8b, 0x83, 0x7a, 0x73, 0x6e, 0x67, 0x5e, 0x58, 0x56, 0x56, - 0x56, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, 0x55, 0x56, 0x55, 0x54, 0x55, - 0x54, 0x55, 0x56, 0x56, 0x55, 0x56, 0x58, 0x58, 0x57, 0x58, 0x59, 0x5a, - 0x5a, 0x5b, 0x5b, 0x5d, 0x5f, 0x5f, 0x60, 0x63, 0x66, 0x67, 0x68, 0x69, - 0x69, 0x6a, 0x6c, 0x6e, 0x6e, 0x6e, 0x6d, 0x6d, 0x6e, 0x6f, 0x70, 0x72, - 0x71, 0x70, 0x6f, 0x6e, 0x6c, 0x68, 0x66, 0x65, 0x60, 0x5e, 0x59, 0x54, - 0x51, 0x4e, 0x48, 0x40, 0x3b, 0x37, 0x2f, 0x21, 0x15, 0x11, 0x11, 0x11, - 0x10, 0x11, 0x10, 0x10, 0x10, 0x11, 0x12, 0x12, 0x11, 0x12, 0x13, 0x11, - 0x11, 0x11, 0x11, 0x13, 0x56, 0x56, 0x55, 0x53, 0x53, 0x53, 0x53, 0x53, - 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54, 0x55, 0x57, 0x58, 0x59, - 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x62, 0x63, 0x63, 0x62, 0x63, 0x65, - 0x65, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68, 0x68, 0x6a, 0x6a, 0x6a, 0x6a, - 0x6b, 0x6b, 0x6b, 0x6d, 0x70, 0x74, 0x77, 0x7c, 0x7f, 0x81, 0x83, 0x85, - 0x88, 0x89, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x93, 0x95, 0x95, - 0x94, 0x94, 0x95, 0x96, 0x96, 0x95, 0x95, 0x94, 0x94, 0x92, 0x93, 0x92, - 0x91, 0x8f, 0x8d, 0x8c, 0x8c, 0x8c, 0x8b, 0x89, 0x88, 0x87, 0x86, 0x83, - 0x81, 0x81, 0x80, 0x7e, 0x7e, 0x81, 0x83, 0x83, 0x84, 0x85, 0x86, 0x88, - 0x88, 0x89, 0x86, 0x84, 0x82, 0x81, 0x7f, 0x7d, 0x7b, 0x7b, 0x7b, 0x7a, - 0x7c, 0x7f, 0x81, 0x81, 0x83, 0x87, 0x8b, 0x8e, 0x91, 0x93, 0x95, 0x99, - 0x9c, 0x9e, 0x9f, 0xa1, 0xa2, 0xa2, 0xa2, 0xa2, 0xa3, 0xa2, 0x98, 0x8a, - 0x7d, 0x69, 0x5e, 0x5b, 0x59, 0x58, 0x55, 0x57, 0x59, 0x5b, 0x5c, 0x5d, - 0x5b, 0x5b, 0x5d, 0x5d, 0x5b, 0x58, 0x58, 0x5b, 0x63, 0x75, 0x83, 0x76, - 0x68, 0x65, 0x65, 0x5e, 0x5a, 0x53, 0x4f, 0x4d, 0x4b, 0x49, 0x4e, 0x51, - 0x56, 0x5c, 0x67, 0x6f, 0x6f, 0x68, 0x75, 0xa8, 0xb6, 0xac, 0x89, 0x5e, - 0x52, 0x58, 0x6a, 0x8f, 0x96, 0x93, 0x91, 0x90, 0x91, 0x90, 0x90, 0x92, - 0x94, 0x94, 0x95, 0x96, 0x97, 0x96, 0x95, 0x96, 0x97, 0x98, 0x98, 0x98, - 0x97, 0x96, 0x96, 0x96, 0x96, 0x97, 0x96, 0x93, 0x91, 0x8e, 0x89, 0x81, - 0x77, 0x70, 0x6c, 0x66, 0x5d, 0x56, 0x55, 0x55, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x57, 0x55, 0x56, 0x55, 0x54, 0x54, 0x55, 0x56, 0x56, 0x55, - 0x55, 0x57, 0x58, 0x58, 0x58, 0x58, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5d, - 0x5e, 0x60, 0x61, 0x63, 0x65, 0x68, 0x69, 0x6a, 0x6a, 0x6a, 0x6c, 0x6e, - 0x6f, 0x6f, 0x6e, 0x6e, 0x6e, 0x6f, 0x71, 0x72, 0x71, 0x70, 0x70, 0x6e, - 0x6b, 0x69, 0x67, 0x65, 0x61, 0x5d, 0x58, 0x55, 0x52, 0x4e, 0x48, 0x42, - 0x3e, 0x3a, 0x31, 0x22, 0x16, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x10, - 0x11, 0x12, 0x13, 0x12, 0x12, 0x13, 0x13, 0x13, 0x11, 0x11, 0x11, 0x13, - 0x56, 0x56, 0x55, 0x54, 0x53, 0x53, 0x54, 0x53, 0x53, 0x54, 0x54, 0x53, - 0x53, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5d, 0x5d, 0x5e, - 0x5f, 0x61, 0x63, 0x64, 0x64, 0x63, 0x64, 0x65, 0x65, 0x66, 0x66, 0x66, - 0x67, 0x67, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6c, - 0x6d, 0x70, 0x74, 0x79, 0x7d, 0x7e, 0x81, 0x82, 0x86, 0x87, 0x88, 0x8b, - 0x8e, 0x8f, 0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x93, 0x92, 0x93, 0x94, - 0x94, 0x93, 0x93, 0x93, 0x92, 0x91, 0x91, 0x91, 0x90, 0x8e, 0x8d, 0x8c, - 0x8c, 0x8c, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x82, 0x81, 0x81, 0x80, 0x7e, - 0x7f, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x89, 0x8a, 0x89, 0x86, 0x83, - 0x82, 0x81, 0x7f, 0x7d, 0x7b, 0x7b, 0x7b, 0x7a, 0x7c, 0x7e, 0x80, 0x81, - 0x83, 0x87, 0x8a, 0x8e, 0x90, 0x92, 0x96, 0x9a, 0x9c, 0x9d, 0x9f, 0xa1, - 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa1, 0x96, 0x87, 0x7a, 0x68, 0x5e, 0x5b, - 0x59, 0x57, 0x56, 0x59, 0x5c, 0x5c, 0x5d, 0x5d, 0x5b, 0x5b, 0x5d, 0x5d, - 0x5b, 0x5b, 0x63, 0x6b, 0x75, 0x8a, 0x97, 0x83, 0x74, 0x6f, 0x6a, 0x61, - 0x61, 0x56, 0x51, 0x4f, 0x4b, 0x4a, 0x4f, 0x53, 0x57, 0x5e, 0x69, 0x73, - 0x70, 0x66, 0x80, 0xbd, 0xca, 0xbd, 0x95, 0x61, 0x4d, 0x4c, 0x5d, 0x87, - 0x95, 0x93, 0x91, 0x90, 0x91, 0x90, 0x90, 0x92, 0x94, 0x95, 0x95, 0x96, - 0x97, 0x96, 0x95, 0x96, 0x97, 0x98, 0x98, 0x98, 0x97, 0x96, 0x96, 0x96, - 0x96, 0x96, 0x96, 0x93, 0x8f, 0x8c, 0x87, 0x7f, 0x75, 0x6e, 0x6a, 0x64, - 0x5b, 0x56, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x55, - 0x55, 0x55, 0x54, 0x54, 0x55, 0x55, 0x55, 0x54, 0x54, 0x57, 0x58, 0x58, - 0x59, 0x58, 0x59, 0x5a, 0x5a, 0x5b, 0x5b, 0x5d, 0x5e, 0x60, 0x61, 0x63, - 0x64, 0x68, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6e, 0x6f, 0x6f, 0x6e, 0x6e, - 0x6e, 0x6f, 0x72, 0x72, 0x72, 0x71, 0x70, 0x6e, 0x6b, 0x6a, 0x67, 0x65, - 0x61, 0x5d, 0x57, 0x54, 0x51, 0x4e, 0x49, 0x43, 0x3f, 0x3a, 0x31, 0x22, - 0x16, 0x12, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, - 0x12, 0x13, 0x13, 0x13, 0x11, 0x11, 0x11, 0x13, 0x56, 0x56, 0x56, 0x55, - 0x54, 0x54, 0x55, 0x54, 0x54, 0x55, 0x55, 0x54, 0x54, 0x54, 0x55, 0x56, - 0x57, 0x58, 0x5a, 0x5b, 0x5c, 0x5e, 0x5e, 0x5f, 0x60, 0x62, 0x63, 0x64, - 0x64, 0x64, 0x65, 0x64, 0x65, 0x66, 0x66, 0x66, 0x67, 0x68, 0x68, 0x69, - 0x69, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x69, 0x69, 0x6a, 0x6c, 0x70, 0x75, - 0x77, 0x7a, 0x7c, 0x7e, 0x82, 0x84, 0x86, 0x89, 0x8c, 0x8d, 0x8f, 0x90, - 0x91, 0x91, 0x92, 0x92, 0x90, 0x90, 0x91, 0x91, 0x91, 0x92, 0x91, 0x91, - 0x90, 0x8f, 0x8f, 0x8f, 0x8e, 0x8c, 0x8b, 0x8c, 0x8c, 0x8c, 0x8b, 0x8a, - 0x88, 0x87, 0x85, 0x82, 0x81, 0x80, 0x7f, 0x7f, 0x7f, 0x81, 0x82, 0x83, - 0x84, 0x85, 0x87, 0x8a, 0x8b, 0x8a, 0x87, 0x83, 0x82, 0x81, 0x7f, 0x7d, - 0x7b, 0x7b, 0x7a, 0x7a, 0x7c, 0x7d, 0x7f, 0x80, 0x83, 0x86, 0x89, 0x8d, - 0x8e, 0x91, 0x96, 0x9a, 0x9c, 0x9e, 0x9f, 0xa1, 0xa2, 0xa2, 0xa2, 0xa2, - 0xa2, 0xa0, 0x93, 0x83, 0x77, 0x69, 0x5f, 0x5a, 0x57, 0x57, 0x59, 0x5c, - 0x5e, 0x5e, 0x5d, 0x5c, 0x5b, 0x5d, 0x5e, 0x5d, 0x5c, 0x65, 0x7d, 0x8b, - 0x92, 0x9a, 0x9b, 0x8b, 0x85, 0x7d, 0x6a, 0x61, 0x67, 0x58, 0x51, 0x51, - 0x4d, 0x4d, 0x53, 0x55, 0x59, 0x60, 0x6c, 0x7c, 0x7d, 0x79, 0x9d, 0xc7, - 0xc6, 0xb6, 0x92, 0x64, 0x4c, 0x46, 0x51, 0x74, 0x92, 0x94, 0x92, 0x91, - 0x92, 0x91, 0x91, 0x93, 0x94, 0x95, 0x95, 0x97, 0x97, 0x96, 0x95, 0x96, - 0x97, 0x98, 0x98, 0x98, 0x98, 0x97, 0x97, 0x97, 0x97, 0x97, 0x95, 0x91, - 0x8e, 0x8b, 0x85, 0x7c, 0x72, 0x6b, 0x67, 0x61, 0x5a, 0x55, 0x55, 0x55, - 0x56, 0x57, 0x57, 0x57, 0x56, 0x55, 0x55, 0x54, 0x55, 0x54, 0x53, 0x53, - 0x54, 0x55, 0x55, 0x53, 0x53, 0x56, 0x57, 0x57, 0x58, 0x58, 0x59, 0x5a, - 0x5a, 0x5b, 0x5b, 0x5d, 0x5e, 0x5f, 0x61, 0x63, 0x64, 0x67, 0x69, 0x6b, - 0x6c, 0x6c, 0x6d, 0x6e, 0x6f, 0x6e, 0x6e, 0x6f, 0x6e, 0x6f, 0x72, 0x72, - 0x72, 0x71, 0x70, 0x6e, 0x6b, 0x6a, 0x68, 0x66, 0x63, 0x5e, 0x57, 0x54, - 0x52, 0x4e, 0x49, 0x42, 0x3e, 0x39, 0x30, 0x22, 0x16, 0x12, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x13, 0x13, 0x13, - 0x11, 0x11, 0x11, 0x13, 0x56, 0x56, 0x56, 0x55, 0x54, 0x55, 0x56, 0x57, - 0x56, 0x57, 0x57, 0x55, 0x55, 0x57, 0x58, 0x57, 0x59, 0x5a, 0x5b, 0x5d, - 0x5f, 0x5e, 0x5e, 0x5f, 0x61, 0x63, 0x63, 0x64, 0x64, 0x64, 0x64, 0x64, - 0x65, 0x66, 0x66, 0x67, 0x66, 0x67, 0x67, 0x67, 0x68, 0x69, 0x69, 0x69, - 0x6a, 0x69, 0x66, 0x67, 0x67, 0x68, 0x6c, 0x6e, 0x72, 0x74, 0x76, 0x79, - 0x7e, 0x81, 0x82, 0x86, 0x88, 0x8b, 0x8d, 0x8e, 0x8e, 0x90, 0x90, 0x90, - 0x8f, 0x8f, 0x8f, 0x90, 0x8f, 0x90, 0x8f, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, - 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8a, 0x88, 0x88, 0x86, 0x83, - 0x81, 0x80, 0x80, 0x7f, 0x7f, 0x81, 0x82, 0x84, 0x83, 0x86, 0x88, 0x8a, - 0x8a, 0x8b, 0x89, 0x86, 0x84, 0x82, 0x80, 0x7e, 0x7b, 0x7a, 0x7a, 0x7a, - 0x7a, 0x7d, 0x7e, 0x7f, 0x82, 0x85, 0x8a, 0x8c, 0x8d, 0x91, 0x95, 0x99, - 0x9c, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2, 0xa2, 0xa2, 0x9f, 0x8f, 0x7f, - 0x74, 0x68, 0x5f, 0x5a, 0x58, 0x59, 0x5d, 0x61, 0x61, 0x5e, 0x5d, 0x5b, - 0x5e, 0x5f, 0x5c, 0x5b, 0x5f, 0x6f, 0x7f, 0x84, 0x82, 0x7f, 0x83, 0x85, - 0x84, 0x7e, 0x73, 0x71, 0x6d, 0x5a, 0x52, 0x4f, 0x4d, 0x4e, 0x51, 0x53, - 0x58, 0x60, 0x6c, 0x83, 0x8f, 0x9d, 0xbb, 0xbb, 0x9e, 0x91, 0x88, 0x67, - 0x50, 0x48, 0x4d, 0x62, 0x83, 0x92, 0x92, 0x92, 0x92, 0x93, 0x92, 0x94, - 0x96, 0x96, 0x96, 0x96, 0x96, 0x97, 0x97, 0x97, 0x98, 0x98, 0x98, 0x98, - 0x98, 0x97, 0x97, 0x97, 0x97, 0x96, 0x93, 0x8e, 0x8a, 0x87, 0x81, 0x78, - 0x6f, 0x69, 0x65, 0x5f, 0x58, 0x55, 0x55, 0x54, 0x54, 0x56, 0x56, 0x56, - 0x56, 0x55, 0x55, 0x54, 0x52, 0x51, 0x50, 0x51, 0x53, 0x54, 0x54, 0x53, - 0x54, 0x54, 0x55, 0x56, 0x56, 0x58, 0x59, 0x5a, 0x5b, 0x5b, 0x5b, 0x5e, - 0x5f, 0x61, 0x62, 0x62, 0x64, 0x68, 0x69, 0x6a, 0x6b, 0x6e, 0x6f, 0x70, - 0x70, 0x6f, 0x70, 0x6f, 0x6f, 0x70, 0x72, 0x73, 0x71, 0x71, 0x71, 0x70, - 0x6d, 0x69, 0x67, 0x66, 0x63, 0x5e, 0x59, 0x55, 0x53, 0x4e, 0x49, 0x42, - 0x3d, 0x39, 0x31, 0x23, 0x16, 0x13, 0x12, 0x11, 0x11, 0x11, 0x12, 0x12, - 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x12, 0x11, 0x11, 0x13, - 0x57, 0x58, 0x57, 0x56, 0x55, 0x55, 0x57, 0x58, 0x58, 0x58, 0x58, 0x56, - 0x57, 0x58, 0x59, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x5f, 0x61, 0x61, - 0x62, 0x63, 0x64, 0x64, 0x64, 0x64, 0x65, 0x66, 0x67, 0x68, 0x68, 0x68, - 0x68, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, 0x6a, 0x68, 0x65, 0x65, - 0x65, 0x65, 0x67, 0x68, 0x6c, 0x6e, 0x6f, 0x73, 0x77, 0x7b, 0x7e, 0x81, - 0x85, 0x89, 0x8c, 0x8c, 0x8d, 0x8e, 0x8f, 0x8f, 0x8f, 0x8e, 0x8d, 0x8d, - 0x8c, 0x8d, 0x8d, 0x8b, 0x8b, 0x8a, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8c, - 0x8c, 0x8d, 0x8b, 0x88, 0x87, 0x87, 0x86, 0x83, 0x80, 0x80, 0x80, 0x7f, - 0x7f, 0x80, 0x83, 0x84, 0x84, 0x87, 0x89, 0x8b, 0x8b, 0x8a, 0x89, 0x86, - 0x84, 0x83, 0x80, 0x7e, 0x7b, 0x7a, 0x7a, 0x7a, 0x7b, 0x7d, 0x7e, 0x7f, - 0x82, 0x85, 0x89, 0x8b, 0x8c, 0x90, 0x95, 0x99, 0x9c, 0x9d, 0x9e, 0xa0, - 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x9b, 0x8b, 0x7b, 0x72, 0x68, 0x5f, 0x5b, - 0x59, 0x5b, 0x60, 0x65, 0x65, 0x62, 0x5f, 0x5e, 0x61, 0x5f, 0x5d, 0x5d, - 0x63, 0x6b, 0x6c, 0x6a, 0x69, 0x69, 0x6e, 0x6e, 0x75, 0x7c, 0x85, 0x7f, - 0x7b, 0x67, 0x5a, 0x51, 0x4d, 0x4b, 0x4c, 0x4d, 0x50, 0x56, 0x64, 0x86, - 0xa0, 0xbe, 0xc5, 0xa6, 0x89, 0x83, 0x84, 0x61, 0x53, 0x56, 0x58, 0x58, - 0x63, 0x8c, 0x94, 0x92, 0x92, 0x93, 0x93, 0x94, 0x96, 0x96, 0x96, 0x97, - 0x96, 0x97, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x96, 0x96, 0x96, - 0x95, 0x93, 0x90, 0x8b, 0x86, 0x83, 0x7d, 0x74, 0x6c, 0x65, 0x61, 0x5b, - 0x56, 0x55, 0x55, 0x55, 0x55, 0x54, 0x55, 0x55, 0x55, 0x55, 0x53, 0x52, - 0x51, 0x50, 0x50, 0x51, 0x50, 0x52, 0x52, 0x52, 0x53, 0x53, 0x55, 0x56, - 0x57, 0x59, 0x59, 0x5a, 0x5b, 0x5a, 0x5b, 0x5e, 0x5f, 0x61, 0x62, 0x62, - 0x65, 0x68, 0x6a, 0x6c, 0x6d, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x72, 0x72, - 0x72, 0x72, 0x71, 0x72, 0x71, 0x71, 0x71, 0x70, 0x6d, 0x69, 0x67, 0x65, - 0x62, 0x5f, 0x59, 0x56, 0x53, 0x4e, 0x4a, 0x43, 0x3d, 0x3a, 0x32, 0x24, - 0x17, 0x13, 0x12, 0x11, 0x11, 0x10, 0x10, 0x11, 0x11, 0x11, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x12, 0x11, 0x12, 0x14, 0x58, 0x59, 0x58, 0x57, - 0x56, 0x56, 0x57, 0x58, 0x58, 0x58, 0x57, 0x57, 0x58, 0x59, 0x5a, 0x5a, - 0x5c, 0x5d, 0x5d, 0x5d, 0x5f, 0x60, 0x62, 0x62, 0x62, 0x64, 0x64, 0x64, - 0x64, 0x64, 0x65, 0x67, 0x68, 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x68, - 0x68, 0x69, 0x69, 0x69, 0x6a, 0x68, 0x66, 0x64, 0x63, 0x64, 0x63, 0x64, - 0x67, 0x69, 0x6b, 0x6e, 0x73, 0x78, 0x7b, 0x7e, 0x82, 0x87, 0x8a, 0x8b, - 0x8c, 0x8d, 0x8e, 0x8e, 0x8e, 0x8d, 0x8c, 0x8c, 0x8c, 0x8d, 0x8c, 0x8a, - 0x89, 0x89, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8c, 0x8b, 0x88, - 0x87, 0x86, 0x84, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x82, 0x83, - 0x85, 0x88, 0x8b, 0x8c, 0x8c, 0x8a, 0x88, 0x85, 0x84, 0x82, 0x80, 0x7e, - 0x7b, 0x7b, 0x7b, 0x7a, 0x7b, 0x7d, 0x7f, 0x80, 0x82, 0x84, 0x88, 0x8a, - 0x8b, 0x8f, 0x94, 0x99, 0x9c, 0x9c, 0x9d, 0x9f, 0x9f, 0xa0, 0x9f, 0xa0, - 0xa0, 0x98, 0x89, 0x78, 0x6f, 0x68, 0x60, 0x5b, 0x5a, 0x5c, 0x62, 0x68, - 0x68, 0x62, 0x61, 0x60, 0x5f, 0x5e, 0x60, 0x62, 0x65, 0x65, 0x65, 0x65, - 0x65, 0x64, 0x65, 0x63, 0x6b, 0x75, 0x82, 0x80, 0x7c, 0x70, 0x69, 0x61, - 0x54, 0x47, 0x46, 0x48, 0x4a, 0x52, 0x66, 0x84, 0x9f, 0xc4, 0xc5, 0x99, - 0x82, 0x78, 0x6c, 0x5b, 0x56, 0x5f, 0x59, 0x41, 0x43, 0x86, 0x95, 0x92, - 0x91, 0x94, 0x94, 0x94, 0x96, 0x96, 0x96, 0x96, 0x96, 0x97, 0x98, 0x98, - 0x98, 0x96, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x95, 0x93, 0x8f, 0x89, - 0x84, 0x80, 0x7a, 0x71, 0x69, 0x62, 0x5e, 0x59, 0x54, 0x54, 0x54, 0x54, - 0x54, 0x53, 0x54, 0x55, 0x54, 0x53, 0x51, 0x52, 0x51, 0x50, 0x51, 0x50, - 0x50, 0x51, 0x52, 0x51, 0x53, 0x54, 0x55, 0x56, 0x56, 0x58, 0x59, 0x5b, - 0x5c, 0x5b, 0x5c, 0x5e, 0x60, 0x62, 0x62, 0x63, 0x66, 0x68, 0x6a, 0x6c, - 0x6d, 0x6e, 0x70, 0x70, 0x71, 0x72, 0x73, 0x73, 0x73, 0x73, 0x72, 0x72, - 0x72, 0x71, 0x71, 0x6f, 0x6d, 0x69, 0x66, 0x65, 0x62, 0x5f, 0x5a, 0x57, - 0x54, 0x4e, 0x49, 0x44, 0x3e, 0x3a, 0x31, 0x23, 0x16, 0x12, 0x11, 0x10, - 0x11, 0x10, 0x10, 0x10, 0x11, 0x11, 0x12, 0x13, 0x13, 0x12, 0x13, 0x12, - 0x12, 0x12, 0x11, 0x13, 0x58, 0x59, 0x58, 0x57, 0x56, 0x56, 0x57, 0x58, - 0x58, 0x58, 0x57, 0x58, 0x59, 0x59, 0x5b, 0x5b, 0x5d, 0x5e, 0x5e, 0x5e, - 0x5f, 0x60, 0x62, 0x63, 0x62, 0x64, 0x64, 0x65, 0x65, 0x65, 0x66, 0x67, - 0x68, 0x68, 0x69, 0x69, 0x68, 0x69, 0x69, 0x69, 0x68, 0x68, 0x69, 0x69, - 0x68, 0x68, 0x66, 0x64, 0x63, 0x63, 0x61, 0x62, 0x64, 0x66, 0x68, 0x6b, - 0x70, 0x75, 0x78, 0x7c, 0x80, 0x85, 0x88, 0x8a, 0x8a, 0x8c, 0x8d, 0x8e, - 0x8d, 0x8c, 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x89, 0x89, 0x88, 0x8a, 0x8a, - 0x89, 0x8a, 0x8a, 0x8c, 0x8c, 0x8c, 0x8b, 0x88, 0x87, 0x86, 0x83, 0x82, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x82, 0x84, 0x86, 0x89, 0x8c, 0x8d, - 0x8c, 0x8b, 0x88, 0x85, 0x84, 0x82, 0x80, 0x7e, 0x7b, 0x7b, 0x7a, 0x79, - 0x7a, 0x7d, 0x7f, 0x80, 0x82, 0x84, 0x87, 0x89, 0x8b, 0x8e, 0x93, 0x98, - 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa0, 0xa0, 0xa0, 0x97, 0x87, 0x77, - 0x6f, 0x68, 0x60, 0x5b, 0x5a, 0x5d, 0x63, 0x6a, 0x69, 0x63, 0x60, 0x60, - 0x61, 0x67, 0x6f, 0x72, 0x6f, 0x65, 0x61, 0x60, 0x60, 0x5f, 0x5f, 0x61, - 0x6a, 0x72, 0x7c, 0x77, 0x75, 0x77, 0x76, 0x72, 0x64, 0x48, 0x43, 0x45, - 0x49, 0x50, 0x66, 0x85, 0xa0, 0xc3, 0xbf, 0x93, 0x7c, 0x6f, 0x5e, 0x58, - 0x56, 0x5f, 0x55, 0x31, 0x35, 0x82, 0x95, 0x92, 0x92, 0x94, 0x95, 0x95, - 0x96, 0x96, 0x97, 0x96, 0x96, 0x98, 0x98, 0x98, 0x98, 0x96, 0x96, 0x96, - 0x97, 0x97, 0x97, 0x96, 0x95, 0x93, 0x8e, 0x87, 0x82, 0x7e, 0x78, 0x6f, - 0x67, 0x61, 0x5c, 0x57, 0x54, 0x54, 0x54, 0x54, 0x53, 0x53, 0x53, 0x54, - 0x53, 0x52, 0x51, 0x52, 0x51, 0x51, 0x52, 0x51, 0x50, 0x51, 0x51, 0x52, - 0x54, 0x54, 0x56, 0x56, 0x56, 0x58, 0x59, 0x5b, 0x5c, 0x5c, 0x5c, 0x5e, - 0x60, 0x62, 0x62, 0x63, 0x65, 0x68, 0x6a, 0x6c, 0x6d, 0x6e, 0x70, 0x70, - 0x71, 0x73, 0x73, 0x73, 0x73, 0x73, 0x72, 0x73, 0x73, 0x72, 0x71, 0x70, - 0x6d, 0x69, 0x67, 0x65, 0x62, 0x5f, 0x5b, 0x57, 0x54, 0x4f, 0x49, 0x45, - 0x3f, 0x3a, 0x31, 0x23, 0x17, 0x12, 0x11, 0x10, 0x11, 0x10, 0x10, 0x10, - 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11, 0x12, 0x12, 0x11, 0x12, - 0x58, 0x58, 0x57, 0x56, 0x55, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x59, - 0x59, 0x5a, 0x5b, 0x5b, 0x5d, 0x5e, 0x5f, 0x5e, 0x5f, 0x60, 0x62, 0x62, - 0x64, 0x65, 0x64, 0x66, 0x66, 0x65, 0x66, 0x66, 0x67, 0x68, 0x69, 0x69, - 0x68, 0x69, 0x6a, 0x6a, 0x69, 0x67, 0x68, 0x68, 0x67, 0x68, 0x66, 0x64, - 0x63, 0x63, 0x60, 0x60, 0x61, 0x61, 0x63, 0x67, 0x6e, 0x72, 0x74, 0x78, - 0x7c, 0x82, 0x86, 0x87, 0x89, 0x8a, 0x8c, 0x8c, 0x8b, 0x8c, 0x8c, 0x8b, - 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x89, 0x89, 0x88, 0x89, 0x8a, 0x8b, - 0x8b, 0x8b, 0x8b, 0x89, 0x87, 0x85, 0x83, 0x81, 0x80, 0x80, 0x81, 0x80, - 0x80, 0x81, 0x83, 0x84, 0x87, 0x8a, 0x8c, 0x8d, 0x8c, 0x8b, 0x88, 0x86, - 0x84, 0x83, 0x81, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x79, 0x7c, 0x7e, 0x7f, - 0x81, 0x82, 0x86, 0x88, 0x8a, 0x8e, 0x92, 0x96, 0x99, 0x9a, 0x9a, 0x9c, - 0x9f, 0xa0, 0xa0, 0xa0, 0xa0, 0x96, 0x85, 0x75, 0x6d, 0x67, 0x60, 0x5b, - 0x5a, 0x5d, 0x65, 0x6d, 0x67, 0x60, 0x5f, 0x64, 0x70, 0x84, 0x97, 0x98, - 0x8a, 0x71, 0x60, 0x58, 0x55, 0x51, 0x54, 0x5d, 0x6a, 0x71, 0x71, 0x62, - 0x68, 0x81, 0x8b, 0x8c, 0x84, 0x53, 0x42, 0x42, 0x49, 0x4c, 0x5e, 0x86, - 0xa2, 0xbc, 0xaf, 0x8d, 0x71, 0x61, 0x55, 0x58, 0x51, 0x53, 0x47, 0x24, - 0x2d, 0x7c, 0x94, 0x94, 0x93, 0x94, 0x95, 0x96, 0x96, 0x96, 0x96, 0x95, - 0x95, 0x97, 0x98, 0x98, 0x97, 0x96, 0x95, 0x96, 0x97, 0x98, 0x97, 0x95, - 0x93, 0x91, 0x8b, 0x84, 0x7f, 0x7b, 0x74, 0x6c, 0x63, 0x5d, 0x59, 0x56, - 0x53, 0x53, 0x52, 0x53, 0x53, 0x52, 0x53, 0x53, 0x53, 0x52, 0x51, 0x51, - 0x50, 0x51, 0x51, 0x51, 0x50, 0x51, 0x51, 0x51, 0x52, 0x55, 0x56, 0x56, - 0x56, 0x58, 0x59, 0x5b, 0x5c, 0x5c, 0x5d, 0x5e, 0x60, 0x62, 0x62, 0x63, - 0x65, 0x67, 0x6a, 0x6c, 0x6d, 0x6f, 0x71, 0x70, 0x71, 0x72, 0x73, 0x73, - 0x73, 0x73, 0x72, 0x72, 0x73, 0x73, 0x72, 0x70, 0x6d, 0x69, 0x67, 0x66, - 0x63, 0x5f, 0x5b, 0x57, 0x54, 0x50, 0x4b, 0x44, 0x3f, 0x3b, 0x33, 0x25, - 0x17, 0x12, 0x10, 0x11, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x12, 0x12, 0x11, 0x12, 0x13, 0x11, 0x12, 0x58, 0x58, 0x57, 0x56, - 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x59, 0x5a, 0x5a, 0x5b, 0x5c, - 0x5e, 0x5f, 0x5f, 0x5e, 0x5e, 0x5f, 0x61, 0x62, 0x64, 0x65, 0x64, 0x66, - 0x66, 0x65, 0x66, 0x66, 0x67, 0x68, 0x69, 0x69, 0x68, 0x69, 0x69, 0x6a, - 0x69, 0x67, 0x68, 0x68, 0x67, 0x66, 0x64, 0x64, 0x63, 0x61, 0x5e, 0x5e, - 0x5e, 0x5e, 0x5f, 0x62, 0x68, 0x6b, 0x6d, 0x72, 0x77, 0x7c, 0x80, 0x83, - 0x85, 0x87, 0x89, 0x8a, 0x8a, 0x8a, 0x8b, 0x89, 0x88, 0x88, 0x88, 0x86, - 0x87, 0x87, 0x87, 0x87, 0x87, 0x88, 0x89, 0x89, 0x89, 0x89, 0x8a, 0x89, - 0x86, 0x85, 0x83, 0x81, 0x80, 0x80, 0x81, 0x81, 0x81, 0x82, 0x84, 0x86, - 0x88, 0x8a, 0x8b, 0x8c, 0x8c, 0x8b, 0x88, 0x85, 0x83, 0x82, 0x80, 0x7d, - 0x7c, 0x7b, 0x7a, 0x79, 0x79, 0x7b, 0x7c, 0x7d, 0x7f, 0x81, 0x85, 0x87, - 0x89, 0x8d, 0x90, 0x92, 0x94, 0x95, 0x96, 0x97, 0x9a, 0x9e, 0xa0, 0xa0, - 0x9d, 0x93, 0x82, 0x72, 0x6b, 0x65, 0x5f, 0x5b, 0x5c, 0x5f, 0x66, 0x6e, - 0x65, 0x60, 0x65, 0x79, 0x96, 0xa8, 0xbc, 0xbc, 0xa3, 0x8b, 0x78, 0x6c, - 0x5f, 0x4c, 0x45, 0x50, 0x5c, 0x63, 0x67, 0x58, 0x67, 0x87, 0x97, 0x9e, - 0x94, 0x6a, 0x48, 0x41, 0x4b, 0x48, 0x57, 0x73, 0x88, 0x9c, 0x90, 0x86, - 0x68, 0x57, 0x50, 0x56, 0x46, 0x3c, 0x30, 0x1a, 0x29, 0x75, 0x93, 0x95, - 0x94, 0x94, 0x96, 0x96, 0x97, 0x97, 0x96, 0x95, 0x95, 0x97, 0x97, 0x96, - 0x97, 0x96, 0x95, 0x96, 0x97, 0x97, 0x95, 0x93, 0x91, 0x8d, 0x87, 0x80, - 0x7a, 0x75, 0x6f, 0x68, 0x5e, 0x59, 0x56, 0x52, 0x51, 0x52, 0x51, 0x51, - 0x52, 0x51, 0x51, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x50, 0x50, 0x4f, 0x50, - 0x4f, 0x50, 0x51, 0x50, 0x52, 0x55, 0x56, 0x56, 0x56, 0x58, 0x59, 0x5b, - 0x5c, 0x5c, 0x5e, 0x5e, 0x5f, 0x61, 0x61, 0x62, 0x66, 0x67, 0x6a, 0x6c, - 0x6d, 0x6f, 0x71, 0x70, 0x71, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x72, - 0x73, 0x73, 0x72, 0x70, 0x6d, 0x69, 0x67, 0x66, 0x63, 0x5d, 0x5a, 0x57, - 0x54, 0x50, 0x4a, 0x42, 0x3c, 0x38, 0x32, 0x26, 0x17, 0x12, 0x10, 0x11, - 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, - 0x12, 0x12, 0x12, 0x11, 0x58, 0x58, 0x58, 0x57, 0x56, 0x56, 0x58, 0x58, - 0x57, 0x57, 0x58, 0x5a, 0x5a, 0x5a, 0x5c, 0x5d, 0x5d, 0x5f, 0x5f, 0x5f, - 0x5f, 0x5f, 0x61, 0x62, 0x63, 0x64, 0x65, 0x65, 0x65, 0x66, 0x67, 0x67, - 0x68, 0x69, 0x69, 0x69, 0x68, 0x68, 0x69, 0x69, 0x68, 0x66, 0x67, 0x67, - 0x67, 0x64, 0x63, 0x63, 0x62, 0x60, 0x5f, 0x5d, 0x5b, 0x5b, 0x5c, 0x5d, - 0x61, 0x65, 0x69, 0x6d, 0x72, 0x77, 0x7a, 0x7d, 0x81, 0x84, 0x86, 0x89, - 0x89, 0x8a, 0x8a, 0x89, 0x87, 0x88, 0x87, 0x86, 0x85, 0x85, 0x85, 0x85, - 0x85, 0x87, 0x88, 0x88, 0x88, 0x89, 0x8a, 0x88, 0x86, 0x85, 0x83, 0x80, - 0x7f, 0x80, 0x80, 0x80, 0x81, 0x84, 0x86, 0x87, 0x89, 0x8b, 0x8c, 0x8d, - 0x8d, 0x8c, 0x89, 0x85, 0x83, 0x81, 0x7f, 0x7c, 0x7b, 0x7a, 0x7a, 0x79, - 0x7a, 0x79, 0x7c, 0x7d, 0x7e, 0x80, 0x83, 0x87, 0x89, 0x8a, 0x8c, 0x8c, - 0x8c, 0x8d, 0x8e, 0x90, 0x95, 0x9c, 0x9f, 0x9f, 0x9b, 0x90, 0x7f, 0x71, - 0x6a, 0x65, 0x5f, 0x5d, 0x5e, 0x61, 0x67, 0x6c, 0x65, 0x68, 0x77, 0x96, - 0xa0, 0xa2, 0xab, 0xa6, 0x8e, 0x81, 0x8d, 0x8b, 0x7c, 0x58, 0x3f, 0x42, - 0x4d, 0x53, 0x58, 0x5a, 0x6a, 0x81, 0x94, 0xa7, 0x92, 0x78, 0x51, 0x47, - 0x51, 0x4c, 0x55, 0x5b, 0x64, 0x77, 0x7d, 0x78, 0x5f, 0x53, 0x50, 0x4f, - 0x38, 0x29, 0x20, 0x17, 0x29, 0x75, 0x94, 0x94, 0x93, 0x94, 0x96, 0x97, - 0x97, 0x98, 0x98, 0x96, 0x96, 0x98, 0x98, 0x96, 0x97, 0x97, 0x97, 0x97, - 0x97, 0x95, 0x93, 0x91, 0x8e, 0x89, 0x83, 0x7c, 0x76, 0x72, 0x6c, 0x64, - 0x5b, 0x56, 0x53, 0x51, 0x50, 0x50, 0x51, 0x51, 0x51, 0x51, 0x51, 0x50, - 0x50, 0x4f, 0x50, 0x4f, 0x50, 0x50, 0x4f, 0x4e, 0x4e, 0x50, 0x51, 0x52, - 0x53, 0x55, 0x56, 0x56, 0x56, 0x58, 0x58, 0x59, 0x5b, 0x5d, 0x5e, 0x5e, - 0x61, 0x62, 0x62, 0x63, 0x66, 0x67, 0x69, 0x6a, 0x6c, 0x6f, 0x71, 0x70, - 0x71, 0x73, 0x73, 0x72, 0x72, 0x72, 0x74, 0x75, 0x74, 0x71, 0x70, 0x6f, - 0x6d, 0x68, 0x66, 0x65, 0x61, 0x5e, 0x5b, 0x58, 0x55, 0x50, 0x4a, 0x42, - 0x3c, 0x37, 0x30, 0x25, 0x17, 0x12, 0x10, 0x10, 0x11, 0x10, 0x10, 0x10, - 0x11, 0x10, 0x11, 0x12, 0x13, 0x13, 0x13, 0x13, 0x12, 0x11, 0x12, 0x11, - 0x59, 0x58, 0x58, 0x57, 0x56, 0x56, 0x59, 0x59, 0x5a, 0x59, 0x59, 0x5b, - 0x5a, 0x5b, 0x5d, 0x5f, 0x5e, 0x5f, 0x60, 0x60, 0x5f, 0x61, 0x62, 0x63, - 0x64, 0x65, 0x65, 0x65, 0x66, 0x67, 0x68, 0x68, 0x69, 0x69, 0x6a, 0x69, - 0x69, 0x69, 0x69, 0x6a, 0x69, 0x67, 0x67, 0x67, 0x66, 0x64, 0x63, 0x62, - 0x61, 0x61, 0x5f, 0x5c, 0x5a, 0x5a, 0x59, 0x5a, 0x5e, 0x61, 0x65, 0x6a, - 0x6f, 0x73, 0x77, 0x79, 0x7d, 0x81, 0x84, 0x87, 0x88, 0x89, 0x89, 0x88, - 0x88, 0x88, 0x87, 0x86, 0x84, 0x85, 0x84, 0x84, 0x85, 0x86, 0x87, 0x87, - 0x87, 0x88, 0x89, 0x88, 0x86, 0x85, 0x83, 0x80, 0x7f, 0x80, 0x80, 0x81, - 0x82, 0x85, 0x86, 0x88, 0x8a, 0x8c, 0x8d, 0x8e, 0x8e, 0x8d, 0x8a, 0x85, - 0x82, 0x81, 0x7e, 0x7c, 0x7b, 0x79, 0x79, 0x7a, 0x7a, 0x79, 0x7b, 0x7d, - 0x7e, 0x80, 0x84, 0x86, 0x88, 0x88, 0x87, 0x86, 0x85, 0x86, 0x88, 0x8b, - 0x90, 0x98, 0x9d, 0x9e, 0x99, 0x8d, 0x7c, 0x6f, 0x68, 0x64, 0x5f, 0x5d, - 0x60, 0x63, 0x67, 0x69, 0x6a, 0x77, 0x86, 0x95, 0x90, 0xa3, 0xa9, 0xa5, - 0x9b, 0x94, 0x98, 0x94, 0x86, 0x65, 0x44, 0x3d, 0x45, 0x4a, 0x4f, 0x57, - 0x65, 0x75, 0x89, 0xa4, 0x8a, 0x66, 0x50, 0x4d, 0x55, 0x51, 0x51, 0x50, - 0x53, 0x5c, 0x65, 0x67, 0x5a, 0x53, 0x50, 0x47, 0x2c, 0x22, 0x1d, 0x18, - 0x2d, 0x78, 0x94, 0x95, 0x94, 0x94, 0x96, 0x97, 0x98, 0x98, 0x98, 0x98, - 0x98, 0x99, 0x99, 0x98, 0x97, 0x97, 0x97, 0x97, 0x96, 0x94, 0x92, 0x8f, - 0x8c, 0x87, 0x80, 0x7a, 0x73, 0x6f, 0x69, 0x60, 0x58, 0x53, 0x51, 0x50, - 0x4f, 0x4f, 0x4f, 0x50, 0x51, 0x4f, 0x4f, 0x4e, 0x4d, 0x4e, 0x4e, 0x4e, - 0x4f, 0x4f, 0x4e, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x55, 0x56, 0x56, - 0x56, 0x58, 0x58, 0x59, 0x5b, 0x5c, 0x5e, 0x5e, 0x61, 0x62, 0x63, 0x63, - 0x66, 0x67, 0x69, 0x6a, 0x6c, 0x6f, 0x71, 0x70, 0x71, 0x73, 0x74, 0x72, - 0x72, 0x73, 0x75, 0x75, 0x74, 0x71, 0x70, 0x70, 0x6d, 0x68, 0x67, 0x64, - 0x61, 0x5d, 0x5b, 0x58, 0x55, 0x50, 0x4a, 0x43, 0x3d, 0x38, 0x2f, 0x24, - 0x18, 0x12, 0x10, 0x10, 0x12, 0x11, 0x10, 0x10, 0x10, 0x11, 0x11, 0x12, - 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x11, 0x59, 0x59, 0x59, 0x58, - 0x57, 0x56, 0x5a, 0x5a, 0x5b, 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5d, 0x5f, - 0x5e, 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x63, 0x63, 0x65, 0x65, 0x65, 0x66, - 0x66, 0x68, 0x68, 0x68, 0x69, 0x6a, 0x6a, 0x69, 0x68, 0x69, 0x69, 0x6a, - 0x69, 0x68, 0x68, 0x67, 0x66, 0x64, 0x64, 0x62, 0x61, 0x61, 0x5f, 0x5d, - 0x5b, 0x5a, 0x58, 0x59, 0x5c, 0x5f, 0x62, 0x67, 0x6c, 0x71, 0x74, 0x76, - 0x7b, 0x80, 0x83, 0x86, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87, 0x86, - 0x83, 0x84, 0x83, 0x84, 0x84, 0x85, 0x87, 0x86, 0x87, 0x87, 0x88, 0x88, - 0x86, 0x85, 0x83, 0x80, 0x7f, 0x80, 0x81, 0x81, 0x82, 0x85, 0x87, 0x88, - 0x8a, 0x8c, 0x8e, 0x8e, 0x8e, 0x8d, 0x8a, 0x85, 0x82, 0x81, 0x7e, 0x7c, - 0x7b, 0x79, 0x79, 0x7a, 0x7a, 0x79, 0x7b, 0x7d, 0x7e, 0x80, 0x83, 0x86, - 0x87, 0x86, 0x85, 0x82, 0x80, 0x80, 0x82, 0x85, 0x8c, 0x95, 0x9b, 0x9c, - 0x97, 0x8b, 0x7a, 0x6d, 0x67, 0x63, 0x5f, 0x5e, 0x61, 0x64, 0x67, 0x69, - 0x6f, 0x82, 0x8c, 0x8e, 0x8f, 0xa7, 0xab, 0xaa, 0xa7, 0x9f, 0x97, 0x8e, - 0x82, 0x66, 0x47, 0x3e, 0x44, 0x48, 0x4d, 0x58, 0x67, 0x71, 0x80, 0x97, - 0x85, 0x60, 0x52, 0x52, 0x5a, 0x58, 0x51, 0x4e, 0x4f, 0x52, 0x59, 0x5c, - 0x55, 0x51, 0x4e, 0x40, 0x26, 0x23, 0x24, 0x25, 0x38, 0x7d, 0x94, 0x95, - 0x95, 0x94, 0x96, 0x97, 0x98, 0x99, 0x99, 0x98, 0x98, 0x99, 0x99, 0x99, - 0x97, 0x97, 0x97, 0x97, 0x95, 0x94, 0x91, 0x8d, 0x8a, 0x85, 0x7e, 0x77, - 0x71, 0x6c, 0x66, 0x5d, 0x55, 0x51, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, - 0x50, 0x4f, 0x4e, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4e, 0x4f, 0x4e, 0x4e, - 0x4f, 0x50, 0x51, 0x52, 0x53, 0x55, 0x56, 0x56, 0x56, 0x58, 0x58, 0x5a, - 0x5b, 0x5c, 0x5e, 0x5e, 0x61, 0x62, 0x63, 0x63, 0x66, 0x67, 0x69, 0x6a, - 0x6c, 0x6f, 0x71, 0x70, 0x71, 0x74, 0x74, 0x73, 0x73, 0x74, 0x75, 0x75, - 0x74, 0x71, 0x70, 0x70, 0x6d, 0x69, 0x67, 0x64, 0x60, 0x5d, 0x5b, 0x58, - 0x55, 0x50, 0x4a, 0x43, 0x3e, 0x39, 0x2f, 0x24, 0x17, 0x12, 0x10, 0x10, - 0x12, 0x11, 0x10, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x12, 0x12, - 0x13, 0x13, 0x12, 0x11, 0x5c, 0x5c, 0x5b, 0x5a, 0x58, 0x58, 0x5b, 0x5c, - 0x5c, 0x5c, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x5e, 0x5f, 0x60, 0x61, - 0x60, 0x62, 0x64, 0x65, 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, - 0x6a, 0x6a, 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x69, 0x68, 0x68, 0x68, - 0x67, 0x64, 0x64, 0x62, 0x61, 0x61, 0x5f, 0x5d, 0x5b, 0x59, 0x57, 0x57, - 0x58, 0x5a, 0x5d, 0x63, 0x68, 0x6e, 0x71, 0x73, 0x76, 0x7c, 0x80, 0x84, - 0x86, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, 0x85, 0x83, 0x82, 0x82, 0x83, - 0x83, 0x85, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x86, 0x85, 0x82, 0x81, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, - 0x8e, 0x8d, 0x89, 0x86, 0x83, 0x81, 0x7e, 0x7c, 0x7a, 0x79, 0x79, 0x7a, - 0x7a, 0x79, 0x7b, 0x7d, 0x7e, 0x7f, 0x82, 0x84, 0x84, 0x83, 0x80, 0x7c, - 0x78, 0x77, 0x78, 0x7b, 0x84, 0x90, 0x97, 0x99, 0x95, 0x88, 0x77, 0x6a, - 0x65, 0x64, 0x60, 0x60, 0x63, 0x66, 0x69, 0x6c, 0x79, 0x8d, 0x8f, 0x85, - 0x99, 0xa6, 0xa5, 0xa7, 0xaa, 0x9c, 0x8d, 0x83, 0x79, 0x63, 0x4a, 0x43, - 0x4a, 0x4e, 0x51, 0x5c, 0x71, 0x72, 0x74, 0x7b, 0x7f, 0x66, 0x59, 0x59, - 0x63, 0x62, 0x52, 0x4e, 0x4f, 0x50, 0x50, 0x51, 0x4d, 0x4b, 0x48, 0x33, - 0x22, 0x2a, 0x34, 0x40, 0x4f, 0x86, 0x95, 0x96, 0x96, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x99, 0x99, 0x99, 0x99, 0x98, 0x98, 0x97, 0x97, 0x96, 0x96, - 0x94, 0x92, 0x8e, 0x8b, 0x88, 0x83, 0x7a, 0x73, 0x6d, 0x69, 0x62, 0x5a, - 0x53, 0x4f, 0x4e, 0x4f, 0x4e, 0x4e, 0x4e, 0x4e, 0x4f, 0x4e, 0x4d, 0x4d, - 0x4d, 0x4e, 0x4d, 0x4d, 0x4d, 0x4e, 0x4f, 0x50, 0x50, 0x50, 0x50, 0x52, - 0x53, 0x55, 0x54, 0x55, 0x56, 0x58, 0x59, 0x5b, 0x5b, 0x5b, 0x5d, 0x5e, - 0x61, 0x62, 0x62, 0x63, 0x65, 0x67, 0x69, 0x6a, 0x6c, 0x6f, 0x71, 0x70, - 0x71, 0x74, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x74, 0x72, 0x71, 0x70, - 0x6e, 0x69, 0x66, 0x64, 0x61, 0x5e, 0x5b, 0x58, 0x55, 0x50, 0x4a, 0x43, - 0x3d, 0x38, 0x2f, 0x25, 0x18, 0x12, 0x11, 0x10, 0x11, 0x10, 0x10, 0x10, - 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, 0x11, 0x12, 0x12, 0x11, 0x11, - 0x5e, 0x5d, 0x5d, 0x5d, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5d, 0x5d, 0x5e, - 0x5e, 0x5f, 0x60, 0x61, 0x60, 0x61, 0x61, 0x61, 0x61, 0x64, 0x65, 0x65, - 0x64, 0x64, 0x66, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6a, 0x69, 0x69, - 0x6a, 0x6b, 0x6b, 0x6b, 0x69, 0x68, 0x67, 0x66, 0x66, 0x64, 0x64, 0x63, - 0x62, 0x61, 0x5f, 0x5d, 0x5b, 0x5a, 0x58, 0x56, 0x55, 0x56, 0x58, 0x5c, - 0x62, 0x69, 0x6c, 0x6e, 0x72, 0x78, 0x7d, 0x82, 0x83, 0x84, 0x85, 0x88, - 0x88, 0x87, 0x87, 0x86, 0x83, 0x82, 0x82, 0x82, 0x83, 0x84, 0x85, 0x86, - 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x82, 0x81, 0x82, 0x81, 0x82, 0x83, - 0x86, 0x88, 0x89, 0x8a, 0x8c, 0x8f, 0x91, 0x90, 0x8f, 0x8c, 0x89, 0x84, - 0x83, 0x81, 0x7e, 0x7c, 0x7c, 0x7a, 0x79, 0x79, 0x79, 0x79, 0x7b, 0x7b, - 0x7c, 0x7e, 0x81, 0x83, 0x83, 0x81, 0x7c, 0x75, 0x70, 0x6b, 0x6a, 0x6e, - 0x7a, 0x89, 0x91, 0x92, 0x8f, 0x81, 0x72, 0x68, 0x65, 0x64, 0x63, 0x63, - 0x67, 0x6b, 0x6e, 0x73, 0x83, 0x85, 0x81, 0x7f, 0x91, 0x90, 0x8f, 0x92, - 0x96, 0x89, 0x8c, 0x8c, 0x85, 0x70, 0x51, 0x4b, 0x5b, 0x63, 0x63, 0x63, - 0x74, 0x72, 0x71, 0x76, 0x80, 0x71, 0x5d, 0x58, 0x5e, 0x5f, 0x51, 0x49, - 0x49, 0x4d, 0x52, 0x50, 0x4b, 0x46, 0x3c, 0x22, 0x1f, 0x2f, 0x3a, 0x45, - 0x5e, 0x8d, 0x96, 0x96, 0x96, 0x97, 0x96, 0x98, 0x99, 0x99, 0x98, 0x9a, - 0x99, 0x99, 0x99, 0x99, 0x99, 0x96, 0x96, 0x94, 0x93, 0x8f, 0x8a, 0x87, - 0x84, 0x7e, 0x75, 0x6c, 0x67, 0x64, 0x5e, 0x56, 0x50, 0x4d, 0x4d, 0x4d, - 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4d, 0x4c, 0x4c, 0x4c, 0x4d, 0x4d, 0x4c, - 0x4e, 0x4e, 0x4e, 0x50, 0x50, 0x4f, 0x50, 0x51, 0x52, 0x54, 0x54, 0x55, - 0x57, 0x59, 0x59, 0x5b, 0x5b, 0x5c, 0x5c, 0x60, 0x61, 0x61, 0x61, 0x63, - 0x65, 0x67, 0x69, 0x6a, 0x6c, 0x6f, 0x71, 0x73, 0x73, 0x74, 0x74, 0x77, - 0x77, 0x76, 0x75, 0x74, 0x74, 0x74, 0x73, 0x72, 0x6d, 0x69, 0x66, 0x65, - 0x63, 0x60, 0x5b, 0x56, 0x54, 0x50, 0x4b, 0x43, 0x3d, 0x38, 0x31, 0x26, - 0x19, 0x14, 0x12, 0x11, 0x10, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 0x12, - 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x12, 0x60, 0x5f, 0x5e, 0x5e, - 0x5c, 0x5c, 0x5d, 0x5e, 0x5e, 0x5d, 0x5d, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, - 0x60, 0x61, 0x61, 0x61, 0x62, 0x64, 0x66, 0x66, 0x65, 0x65, 0x66, 0x66, - 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6a, 0x6a, - 0x6a, 0x69, 0x67, 0x66, 0x66, 0x64, 0x64, 0x64, 0x62, 0x60, 0x5e, 0x5c, - 0x5b, 0x5a, 0x58, 0x56, 0x55, 0x53, 0x54, 0x56, 0x5b, 0x62, 0x67, 0x6a, - 0x6e, 0x73, 0x7a, 0x7f, 0x82, 0x83, 0x84, 0x86, 0x86, 0x88, 0x88, 0x87, - 0x85, 0x83, 0x81, 0x81, 0x82, 0x83, 0x82, 0x83, 0x84, 0x84, 0x83, 0x83, - 0x84, 0x83, 0x82, 0x81, 0x82, 0x82, 0x83, 0x84, 0x87, 0x89, 0x8a, 0x8b, - 0x8c, 0x8f, 0x91, 0x90, 0x90, 0x8d, 0x89, 0x85, 0x83, 0x81, 0x7e, 0x7c, - 0x7c, 0x7a, 0x79, 0x79, 0x79, 0x78, 0x7a, 0x7a, 0x7c, 0x7d, 0x80, 0x81, - 0x81, 0x7e, 0x78, 0x72, 0x6b, 0x67, 0x66, 0x66, 0x71, 0x82, 0x88, 0x89, - 0x84, 0x77, 0x6b, 0x67, 0x65, 0x65, 0x65, 0x66, 0x6c, 0x6e, 0x71, 0x7b, - 0x89, 0x78, 0x70, 0x76, 0x8f, 0x96, 0xad, 0xac, 0x8f, 0x7f, 0x7b, 0x7d, - 0x80, 0x7c, 0x5f, 0x53, 0x5e, 0x6d, 0x7d, 0x73, 0x81, 0x75, 0x7a, 0x92, - 0x7d, 0x6d, 0x61, 0x5a, 0x58, 0x5f, 0x51, 0x45, 0x44, 0x4c, 0x51, 0x4f, - 0x4a, 0x43, 0x33, 0x1c, 0x1f, 0x32, 0x3d, 0x4b, 0x75, 0x93, 0x95, 0x94, - 0x95, 0x97, 0x98, 0x97, 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x99, 0x98, 0x99, - 0x98, 0x96, 0x94, 0x93, 0x91, 0x8c, 0x86, 0x82, 0x7f, 0x79, 0x71, 0x68, - 0x62, 0x5f, 0x58, 0x51, 0x4d, 0x4c, 0x4c, 0x4c, 0x4d, 0x4c, 0x4b, 0x4a, - 0x4a, 0x4b, 0x4a, 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4c, 0x4d, 0x4e, 0x50, - 0x50, 0x50, 0x50, 0x51, 0x52, 0x54, 0x54, 0x55, 0x57, 0x58, 0x59, 0x5b, - 0x5b, 0x5c, 0x5e, 0x60, 0x60, 0x60, 0x61, 0x62, 0x65, 0x67, 0x69, 0x6a, - 0x6b, 0x6e, 0x71, 0x73, 0x73, 0x73, 0x75, 0x77, 0x77, 0x77, 0x77, 0x76, - 0x74, 0x74, 0x74, 0x72, 0x6d, 0x6a, 0x68, 0x67, 0x64, 0x60, 0x5b, 0x56, - 0x54, 0x50, 0x4a, 0x43, 0x3d, 0x39, 0x33, 0x27, 0x19, 0x14, 0x12, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, - 0x11, 0x10, 0x10, 0x12, 0x60, 0x5e, 0x5e, 0x5d, 0x5b, 0x5c, 0x5e, 0x5f, - 0x5e, 0x5d, 0x5c, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x62, 0x62, 0x62, - 0x63, 0x64, 0x66, 0x66, 0x67, 0x66, 0x66, 0x66, 0x67, 0x68, 0x69, 0x6a, - 0x6a, 0x6a, 0x6b, 0x6b, 0x6a, 0x6a, 0x6a, 0x69, 0x69, 0x69, 0x69, 0x68, - 0x67, 0x64, 0x64, 0x63, 0x62, 0x60, 0x5e, 0x5b, 0x5a, 0x59, 0x58, 0x56, - 0x54, 0x53, 0x52, 0x52, 0x57, 0x5d, 0x63, 0x67, 0x6b, 0x71, 0x77, 0x7d, - 0x81, 0x83, 0x84, 0x85, 0x87, 0x89, 0x89, 0x87, 0x84, 0x81, 0x80, 0x80, - 0x81, 0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x83, 0x84, 0x84, 0x83, 0x82, - 0x82, 0x83, 0x84, 0x85, 0x87, 0x8a, 0x8b, 0x8c, 0x8d, 0x8f, 0x90, 0x8f, - 0x8e, 0x8c, 0x89, 0x85, 0x83, 0x81, 0x7f, 0x7c, 0x7b, 0x7a, 0x79, 0x79, - 0x79, 0x78, 0x79, 0x7a, 0x7c, 0x7e, 0x80, 0x81, 0x80, 0x7c, 0x76, 0x6f, - 0x68, 0x65, 0x63, 0x63, 0x6a, 0x79, 0x7f, 0x7f, 0x7a, 0x6e, 0x67, 0x66, - 0x66, 0x65, 0x65, 0x68, 0x6d, 0x70, 0x73, 0x7e, 0x85, 0x6c, 0x60, 0x5f, - 0x64, 0x81, 0xa8, 0xac, 0x8e, 0x76, 0x7a, 0x7f, 0x80, 0x78, 0x62, 0x58, - 0x62, 0x6f, 0x7f, 0x76, 0x85, 0x94, 0x9e, 0xa3, 0x8d, 0x75, 0x6b, 0x64, - 0x5c, 0x63, 0x5a, 0x53, 0x53, 0x58, 0x50, 0x4d, 0x4e, 0x48, 0x34, 0x1c, - 0x1f, 0x34, 0x41, 0x58, 0x87, 0x95, 0x94, 0x94, 0x94, 0x97, 0x99, 0x98, - 0x99, 0x9a, 0x99, 0x9a, 0x9a, 0x99, 0x99, 0x98, 0x97, 0x94, 0x93, 0x92, - 0x8e, 0x89, 0x84, 0x7e, 0x7a, 0x75, 0x6e, 0x65, 0x5f, 0x5b, 0x55, 0x4e, - 0x4b, 0x4b, 0x4b, 0x4b, 0x4c, 0x4b, 0x4a, 0x4a, 0x4b, 0x4b, 0x4a, 0x4b, - 0x4a, 0x4a, 0x4b, 0x4b, 0x4c, 0x4c, 0x4c, 0x4e, 0x50, 0x4f, 0x50, 0x51, - 0x52, 0x54, 0x55, 0x55, 0x55, 0x57, 0x59, 0x5a, 0x5b, 0x5c, 0x5e, 0x5e, - 0x5f, 0x61, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6b, 0x6c, 0x6d, 0x70, 0x72, - 0x72, 0x72, 0x74, 0x76, 0x75, 0x76, 0x77, 0x77, 0x75, 0x75, 0x74, 0x72, - 0x6e, 0x6b, 0x69, 0x68, 0x63, 0x5f, 0x5a, 0x56, 0x53, 0x50, 0x48, 0x43, - 0x3f, 0x3b, 0x33, 0x25, 0x1a, 0x14, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x12, 0x11, 0x11, 0x11, - 0x61, 0x5e, 0x5e, 0x5e, 0x5c, 0x5d, 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5e, - 0x5e, 0x5e, 0x5e, 0x60, 0x60, 0x62, 0x62, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x67, 0x67, 0x67, 0x67, 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, - 0x69, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x69, 0x69, 0x67, 0x65, 0x64, 0x63, - 0x62, 0x60, 0x5e, 0x5c, 0x5a, 0x59, 0x58, 0x56, 0x54, 0x52, 0x51, 0x50, - 0x54, 0x5a, 0x61, 0x65, 0x69, 0x6f, 0x75, 0x7c, 0x80, 0x82, 0x84, 0x84, - 0x87, 0x89, 0x89, 0x88, 0x84, 0x81, 0x80, 0x80, 0x81, 0x82, 0x81, 0x81, - 0x81, 0x82, 0x82, 0x83, 0x84, 0x84, 0x83, 0x81, 0x82, 0x83, 0x84, 0x86, - 0x88, 0x8a, 0x8c, 0x8c, 0x8d, 0x90, 0x90, 0x8f, 0x8e, 0x8b, 0x89, 0x85, - 0x83, 0x82, 0x80, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x79, 0x79, 0x79, 0x7a, - 0x7c, 0x7e, 0x80, 0x80, 0x7f, 0x7b, 0x75, 0x6d, 0x67, 0x65, 0x63, 0x62, - 0x67, 0x73, 0x77, 0x77, 0x72, 0x69, 0x67, 0x6b, 0x6c, 0x6a, 0x65, 0x67, - 0x6c, 0x6f, 0x72, 0x7b, 0x7a, 0x64, 0x57, 0x4d, 0x47, 0x69, 0x8c, 0x90, - 0x79, 0x6e, 0x76, 0x79, 0x78, 0x6f, 0x60, 0x5a, 0x61, 0x6c, 0x79, 0x74, - 0x89, 0xaa, 0xb4, 0xa9, 0x8e, 0x77, 0x71, 0x6b, 0x60, 0x61, 0x5e, 0x5f, - 0x61, 0x60, 0x52, 0x4b, 0x4c, 0x47, 0x33, 0x1d, 0x1f, 0x30, 0x41, 0x62, - 0x8e, 0x95, 0x93, 0x94, 0x95, 0x98, 0x99, 0x98, 0x99, 0x9a, 0x99, 0x9a, - 0x9a, 0x99, 0x99, 0x98, 0x96, 0x94, 0x92, 0x90, 0x8d, 0x87, 0x81, 0x7c, - 0x78, 0x73, 0x6c, 0x62, 0x5d, 0x59, 0x52, 0x4d, 0x4a, 0x4a, 0x4a, 0x4a, - 0x4b, 0x4a, 0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x49, 0x4a, 0x4b, - 0x4c, 0x4c, 0x4c, 0x4d, 0x4f, 0x4f, 0x50, 0x52, 0x52, 0x53, 0x54, 0x54, - 0x54, 0x56, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5d, 0x5f, 0x61, 0x62, 0x64, - 0x66, 0x67, 0x69, 0x6a, 0x6c, 0x6d, 0x70, 0x72, 0x72, 0x72, 0x74, 0x75, - 0x74, 0x75, 0x77, 0x77, 0x76, 0x74, 0x73, 0x72, 0x6f, 0x6b, 0x69, 0x67, - 0x63, 0x5f, 0x5b, 0x56, 0x54, 0x50, 0x48, 0x42, 0x3f, 0x3c, 0x32, 0x24, - 0x1a, 0x14, 0x12, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x10, 0x11, 0x11, - 0x11, 0x11, 0x12, 0x13, 0x12, 0x12, 0x11, 0x11, 0x62, 0x5f, 0x5f, 0x5f, - 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5e, 0x5e, 0x5d, 0x5e, 0x60, - 0x61, 0x62, 0x62, 0x62, 0x64, 0x64, 0x65, 0x66, 0x67, 0x67, 0x67, 0x68, - 0x68, 0x67, 0x68, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6a, 0x6a, 0x6b, 0x6c, - 0x6b, 0x6b, 0x6a, 0x69, 0x67, 0x66, 0x63, 0x62, 0x61, 0x5f, 0x5e, 0x5c, - 0x5a, 0x59, 0x58, 0x56, 0x54, 0x53, 0x52, 0x50, 0x52, 0x57, 0x5d, 0x61, - 0x66, 0x6e, 0x74, 0x7b, 0x7f, 0x81, 0x83, 0x85, 0x87, 0x89, 0x89, 0x89, - 0x86, 0x82, 0x81, 0x80, 0x81, 0x81, 0x80, 0x81, 0x81, 0x80, 0x80, 0x82, - 0x84, 0x83, 0x82, 0x81, 0x81, 0x83, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8d, - 0x8e, 0x90, 0x90, 0x8e, 0x8d, 0x8a, 0x87, 0x84, 0x83, 0x82, 0x80, 0x7d, - 0x7b, 0x79, 0x79, 0x78, 0x79, 0x79, 0x78, 0x79, 0x7b, 0x7e, 0x7f, 0x7e, - 0x7c, 0x79, 0x74, 0x6d, 0x68, 0x64, 0x62, 0x62, 0x65, 0x6b, 0x6d, 0x6b, - 0x67, 0x63, 0x6e, 0x7e, 0x84, 0x7e, 0x6b, 0x64, 0x69, 0x6d, 0x6f, 0x6f, - 0x64, 0x5b, 0x50, 0x3b, 0x2e, 0x42, 0x4e, 0x4b, 0x42, 0x5c, 0x63, 0x5e, - 0x5b, 0x59, 0x5b, 0x58, 0x5d, 0x65, 0x6c, 0x6c, 0x92, 0xbd, 0xc5, 0xad, - 0x84, 0x74, 0x75, 0x70, 0x60, 0x55, 0x59, 0x67, 0x6a, 0x64, 0x5c, 0x4b, - 0x43, 0x3b, 0x2b, 0x1f, 0x22, 0x27, 0x3b, 0x6c, 0x93, 0x95, 0x95, 0x96, - 0x97, 0x97, 0x99, 0x99, 0x9a, 0x9b, 0x99, 0x99, 0x9a, 0x9a, 0x99, 0x96, - 0x94, 0x92, 0x91, 0x8f, 0x8b, 0x84, 0x7e, 0x79, 0x75, 0x6e, 0x67, 0x5d, - 0x56, 0x53, 0x4e, 0x4b, 0x4a, 0x49, 0x49, 0x49, 0x4a, 0x49, 0x48, 0x48, - 0x48, 0x48, 0x48, 0x49, 0x49, 0x48, 0x48, 0x4b, 0x4c, 0x4c, 0x4b, 0x4c, - 0x4f, 0x4f, 0x50, 0x53, 0x53, 0x52, 0x52, 0x53, 0x54, 0x55, 0x58, 0x59, - 0x5a, 0x5b, 0x5c, 0x5c, 0x5e, 0x61, 0x62, 0x63, 0x65, 0x67, 0x68, 0x69, - 0x6b, 0x6c, 0x6f, 0x71, 0x72, 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, - 0x75, 0x74, 0x73, 0x73, 0x70, 0x6c, 0x69, 0x67, 0x63, 0x60, 0x5c, 0x58, - 0x55, 0x50, 0x48, 0x43, 0x3f, 0x3a, 0x31, 0x23, 0x19, 0x14, 0x12, 0x11, - 0x11, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, - 0x13, 0x12, 0x11, 0x11, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x5f, 0x5f, 0x5e, 0x5e, 0x5d, 0x5d, 0x5f, 0x60, 0x62, 0x62, 0x62, - 0x63, 0x64, 0x65, 0x66, 0x67, 0x67, 0x67, 0x68, 0x67, 0x67, 0x69, 0x6b, - 0x6b, 0x6a, 0x69, 0x69, 0x6b, 0x6b, 0x6c, 0x6c, 0x6b, 0x6a, 0x69, 0x68, - 0x67, 0x66, 0x64, 0x62, 0x62, 0x60, 0x5e, 0x5c, 0x5a, 0x58, 0x57, 0x55, - 0x54, 0x53, 0x51, 0x4f, 0x4f, 0x53, 0x58, 0x5c, 0x64, 0x6b, 0x73, 0x7a, - 0x7e, 0x80, 0x83, 0x85, 0x88, 0x89, 0x89, 0x89, 0x86, 0x83, 0x81, 0x81, - 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x82, 0x83, 0x84, 0x82, 0x82, - 0x83, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8d, 0x8e, 0x8e, 0x90, 0x90, 0x8e, - 0x8d, 0x8a, 0x87, 0x84, 0x82, 0x82, 0x81, 0x7e, 0x7c, 0x7a, 0x79, 0x78, - 0x78, 0x79, 0x78, 0x78, 0x7a, 0x7d, 0x7e, 0x7b, 0x79, 0x77, 0x72, 0x6d, - 0x66, 0x63, 0x61, 0x61, 0x61, 0x62, 0x61, 0x60, 0x5e, 0x66, 0x82, 0xa7, - 0xb5, 0xb0, 0x8c, 0x6a, 0x67, 0x68, 0x66, 0x5f, 0x4f, 0x56, 0x58, 0x48, - 0x22, 0x1a, 0x1b, 0x1a, 0x1d, 0x37, 0x41, 0x40, 0x3e, 0x40, 0x55, 0x55, - 0x6b, 0x74, 0x6b, 0x62, 0x94, 0xbf, 0xc8, 0xb5, 0x96, 0x70, 0x6a, 0x64, - 0x52, 0x49, 0x4a, 0x57, 0x5e, 0x67, 0x6e, 0x52, 0x3e, 0x32, 0x23, 0x1e, - 0x24, 0x28, 0x39, 0x66, 0x92, 0x96, 0x95, 0x96, 0x98, 0x99, 0x9b, 0x9a, - 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x99, 0x97, 0x95, 0x94, 0x90, 0x8e, 0x8b, - 0x87, 0x7f, 0x79, 0x74, 0x6f, 0x69, 0x61, 0x57, 0x51, 0x4d, 0x49, 0x48, - 0x48, 0x48, 0x48, 0x48, 0x49, 0x48, 0x46, 0x47, 0x46, 0x47, 0x47, 0x48, - 0x49, 0x47, 0x48, 0x4b, 0x4c, 0x4d, 0x4c, 0x4c, 0x4f, 0x50, 0x51, 0x53, - 0x53, 0x52, 0x53, 0x53, 0x55, 0x56, 0x58, 0x58, 0x59, 0x59, 0x5b, 0x5c, - 0x5e, 0x5f, 0x60, 0x61, 0x63, 0x65, 0x68, 0x6a, 0x6c, 0x6d, 0x6f, 0x71, - 0x73, 0x74, 0x74, 0x75, 0x74, 0x74, 0x76, 0x76, 0x76, 0x75, 0x74, 0x73, - 0x70, 0x6b, 0x69, 0x67, 0x65, 0x60, 0x5b, 0x58, 0x55, 0x51, 0x49, 0x43, - 0x3e, 0x3a, 0x33, 0x26, 0x1a, 0x14, 0x12, 0x11, 0x11, 0x10, 0x10, 0x11, - 0x11, 0x12, 0x12, 0x12, 0x12, 0x11, 0x13, 0x14, 0x13, 0x11, 0x11, 0x11, - 0x61, 0x61, 0x61, 0x62, 0x61, 0x60, 0x61, 0x61, 0x60, 0x5e, 0x5e, 0x5e, - 0x5e, 0x5e, 0x5d, 0x5e, 0x60, 0x61, 0x62, 0x63, 0x63, 0x63, 0x65, 0x66, - 0x68, 0x67, 0x67, 0x66, 0x67, 0x68, 0x6a, 0x6b, 0x6b, 0x6b, 0x6a, 0x6a, - 0x6c, 0x6c, 0x6c, 0x6a, 0x69, 0x6a, 0x6a, 0x69, 0x68, 0x67, 0x65, 0x64, - 0x63, 0x61, 0x5e, 0x5c, 0x5a, 0x59, 0x57, 0x56, 0x55, 0x52, 0x51, 0x4e, - 0x4e, 0x51, 0x56, 0x5a, 0x60, 0x67, 0x70, 0x77, 0x7d, 0x80, 0x83, 0x84, - 0x87, 0x89, 0x89, 0x89, 0x87, 0x84, 0x83, 0x82, 0x81, 0x7f, 0x7e, 0x7f, - 0x7f, 0x7e, 0x80, 0x82, 0x82, 0x82, 0x82, 0x82, 0x84, 0x86, 0x87, 0x88, - 0x89, 0x8c, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x8f, 0x8e, 0x8b, 0x88, 0x85, - 0x82, 0x82, 0x81, 0x7e, 0x7d, 0x7b, 0x7a, 0x79, 0x78, 0x79, 0x78, 0x79, - 0x7a, 0x7c, 0x7e, 0x7b, 0x78, 0x75, 0x71, 0x6c, 0x64, 0x5f, 0x5e, 0x5e, - 0x5e, 0x5d, 0x5b, 0x5b, 0x60, 0x6c, 0x89, 0xb2, 0xc5, 0xc6, 0xa9, 0x78, - 0x66, 0x5f, 0x58, 0x53, 0x4d, 0x57, 0x63, 0x68, 0x37, 0x19, 0x15, 0x19, - 0x24, 0x2d, 0x31, 0x33, 0x34, 0x3a, 0x45, 0x4a, 0x76, 0x89, 0x7f, 0x61, - 0x7d, 0x9a, 0xa8, 0xb4, 0xa7, 0x69, 0x54, 0x50, 0x51, 0x4c, 0x4a, 0x53, - 0x60, 0x77, 0x82, 0x5f, 0x40, 0x30, 0x21, 0x1f, 0x28, 0x30, 0x3d, 0x5d, - 0x90, 0x98, 0x96, 0x97, 0x98, 0x9a, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, - 0x99, 0x96, 0x95, 0x95, 0x92, 0x8d, 0x8a, 0x87, 0x82, 0x7a, 0x73, 0x6d, - 0x69, 0x63, 0x5c, 0x52, 0x4c, 0x48, 0x45, 0x47, 0x47, 0x47, 0x47, 0x47, - 0x47, 0x46, 0x46, 0x46, 0x46, 0x46, 0x47, 0x47, 0x48, 0x49, 0x49, 0x4b, - 0x4c, 0x4d, 0x4e, 0x4e, 0x50, 0x50, 0x51, 0x52, 0x53, 0x53, 0x54, 0x55, - 0x56, 0x56, 0x57, 0x59, 0x59, 0x59, 0x59, 0x5c, 0x5c, 0x5d, 0x5e, 0x61, - 0x63, 0x64, 0x67, 0x69, 0x6b, 0x6b, 0x6d, 0x70, 0x71, 0x72, 0x74, 0x75, - 0x74, 0x74, 0x75, 0x75, 0x76, 0x76, 0x75, 0x72, 0x70, 0x6b, 0x68, 0x67, - 0x64, 0x5f, 0x5b, 0x56, 0x54, 0x50, 0x4a, 0x43, 0x40, 0x3d, 0x35, 0x27, - 0x1a, 0x13, 0x11, 0x11, 0x10, 0x10, 0x11, 0x11, 0x10, 0x11, 0x12, 0x13, - 0x13, 0x12, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x61, 0x62, 0x62, 0x62, - 0x62, 0x61, 0x62, 0x61, 0x60, 0x5f, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, - 0x60, 0x62, 0x62, 0x63, 0x63, 0x63, 0x65, 0x66, 0x67, 0x67, 0x67, 0x66, - 0x67, 0x69, 0x6b, 0x6b, 0x6b, 0x6b, 0x6a, 0x6a, 0x6c, 0x6c, 0x6c, 0x69, - 0x69, 0x6a, 0x6a, 0x69, 0x69, 0x67, 0x64, 0x64, 0x63, 0x61, 0x5f, 0x5c, - 0x59, 0x59, 0x57, 0x56, 0x54, 0x52, 0x50, 0x4e, 0x4d, 0x4f, 0x55, 0x59, - 0x5e, 0x65, 0x6d, 0x75, 0x7b, 0x7f, 0x82, 0x85, 0x88, 0x8a, 0x8b, 0x8a, - 0x88, 0x85, 0x84, 0x83, 0x81, 0x7e, 0x7d, 0x7e, 0x7e, 0x7e, 0x7f, 0x80, - 0x81, 0x82, 0x83, 0x82, 0x84, 0x86, 0x87, 0x88, 0x8a, 0x8d, 0x8f, 0x90, - 0x91, 0x91, 0x8f, 0x8f, 0x8d, 0x8b, 0x88, 0x84, 0x83, 0x82, 0x80, 0x7e, - 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x78, 0x78, 0x78, 0x79, 0x7b, 0x7c, 0x7b, - 0x79, 0x76, 0x71, 0x6a, 0x61, 0x5d, 0x5c, 0x5c, 0x5d, 0x5c, 0x5a, 0x5b, - 0x63, 0x6e, 0x81, 0xa3, 0xb4, 0xbc, 0xab, 0x7e, 0x65, 0x5a, 0x4e, 0x4c, - 0x4f, 0x55, 0x63, 0x79, 0x5d, 0x2d, 0x24, 0x30, 0x4a, 0x48, 0x3b, 0x35, - 0x31, 0x2f, 0x34, 0x3a, 0x5c, 0x6f, 0x73, 0x5e, 0x59, 0x62, 0x7a, 0xac, - 0xb6, 0x6d, 0x51, 0x4e, 0x55, 0x5b, 0x63, 0x79, 0x88, 0x93, 0x79, 0x52, - 0x3c, 0x2f, 0x21, 0x21, 0x2a, 0x36, 0x40, 0x58, 0x8f, 0x99, 0x97, 0x98, - 0x99, 0x9a, 0x9b, 0x9a, 0x9a, 0x9a, 0x9b, 0x9a, 0x98, 0x96, 0x94, 0x93, - 0x90, 0x8a, 0x85, 0x82, 0x7d, 0x76, 0x6f, 0x69, 0x65, 0x60, 0x58, 0x4e, - 0x48, 0x46, 0x45, 0x45, 0x45, 0x45, 0x45, 0x44, 0x45, 0x45, 0x45, 0x45, - 0x45, 0x44, 0x45, 0x46, 0x47, 0x49, 0x49, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, - 0x50, 0x50, 0x51, 0x53, 0x53, 0x53, 0x54, 0x55, 0x55, 0x57, 0x58, 0x5a, - 0x5a, 0x5a, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x62, 0x63, 0x66, 0x67, - 0x69, 0x6c, 0x6d, 0x70, 0x72, 0x73, 0x74, 0x75, 0x74, 0x74, 0x76, 0x76, - 0x76, 0x76, 0x75, 0x72, 0x70, 0x6c, 0x68, 0x67, 0x64, 0x5f, 0x5a, 0x56, - 0x53, 0x50, 0x49, 0x43, 0x3f, 0x3c, 0x34, 0x27, 0x1a, 0x12, 0x11, 0x11, - 0x10, 0x10, 0x11, 0x11, 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x13, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x61, 0x62, 0x63, 0x63, 0x63, 0x62, 0x61, 0x60, - 0x60, 0x5f, 0x5f, 0x5f, 0x5e, 0x5e, 0x5e, 0x5e, 0x60, 0x61, 0x62, 0x64, - 0x63, 0x63, 0x65, 0x66, 0x67, 0x67, 0x67, 0x67, 0x68, 0x69, 0x6b, 0x6b, - 0x6b, 0x6b, 0x6a, 0x6a, 0x6c, 0x6c, 0x6c, 0x69, 0x69, 0x6a, 0x69, 0x69, - 0x68, 0x67, 0x64, 0x63, 0x63, 0x61, 0x5f, 0x5c, 0x5a, 0x59, 0x58, 0x56, - 0x54, 0x52, 0x51, 0x4e, 0x4c, 0x4f, 0x54, 0x58, 0x5d, 0x64, 0x6c, 0x74, - 0x7a, 0x7d, 0x81, 0x86, 0x89, 0x8b, 0x8b, 0x8a, 0x88, 0x86, 0x84, 0x83, - 0x81, 0x7e, 0x7d, 0x7e, 0x7e, 0x7d, 0x7e, 0x7f, 0x81, 0x82, 0x82, 0x82, - 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8c, 0x8f, 0x90, 0x91, 0x90, 0x8f, 0x8e, - 0x8d, 0x8b, 0x89, 0x85, 0x83, 0x82, 0x80, 0x7e, 0x7c, 0x7b, 0x7a, 0x7a, - 0x78, 0x79, 0x78, 0x77, 0x78, 0x7a, 0x7c, 0x7b, 0x79, 0x76, 0x70, 0x68, - 0x5f, 0x5c, 0x5b, 0x5c, 0x5d, 0x5c, 0x5a, 0x5c, 0x64, 0x6f, 0x79, 0x92, - 0xa1, 0xab, 0xa3, 0x7f, 0x64, 0x57, 0x4c, 0x4b, 0x50, 0x53, 0x60, 0x7b, - 0x71, 0x4d, 0x41, 0x49, 0x5f, 0x59, 0x46, 0x3a, 0x34, 0x2d, 0x30, 0x34, - 0x49, 0x57, 0x61, 0x5a, 0x54, 0x57, 0x6d, 0xa3, 0xb4, 0x73, 0x5b, 0x5c, - 0x67, 0x72, 0x7d, 0x90, 0x98, 0x92, 0x67, 0x47, 0x37, 0x2d, 0x22, 0x23, - 0x2b, 0x3a, 0x42, 0x57, 0x8e, 0x9a, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9a, - 0x9a, 0x9a, 0x9b, 0x9a, 0x98, 0x96, 0x94, 0x92, 0x8e, 0x87, 0x82, 0x7f, - 0x7b, 0x73, 0x6d, 0x66, 0x62, 0x5d, 0x54, 0x4b, 0x47, 0x45, 0x45, 0x45, - 0x44, 0x45, 0x45, 0x43, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x46, - 0x46, 0x49, 0x49, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x50, 0x51, 0x52, - 0x53, 0x53, 0x54, 0x55, 0x55, 0x57, 0x59, 0x5a, 0x5a, 0x59, 0x58, 0x59, - 0x5a, 0x5b, 0x5c, 0x5e, 0x61, 0x63, 0x65, 0x67, 0x68, 0x6c, 0x6d, 0x70, - 0x72, 0x73, 0x74, 0x74, 0x74, 0x74, 0x76, 0x76, 0x77, 0x76, 0x75, 0x72, - 0x70, 0x6d, 0x69, 0x67, 0x64, 0x5f, 0x5b, 0x57, 0x54, 0x50, 0x49, 0x44, - 0x3f, 0x3b, 0x34, 0x27, 0x19, 0x13, 0x11, 0x11, 0x10, 0x10, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x12, 0x11, 0x11, 0x11, 0x10, 0x11, - 0x63, 0x62, 0x63, 0x63, 0x63, 0x62, 0x60, 0x60, 0x5f, 0x5e, 0x5f, 0x5f, - 0x5f, 0x5e, 0x5e, 0x5e, 0x60, 0x61, 0x62, 0x63, 0x64, 0x64, 0x65, 0x66, - 0x67, 0x66, 0x66, 0x67, 0x68, 0x68, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, - 0x6c, 0x6c, 0x6b, 0x69, 0x68, 0x69, 0x69, 0x68, 0x68, 0x67, 0x65, 0x63, - 0x63, 0x61, 0x5f, 0x5d, 0x5b, 0x5a, 0x57, 0x55, 0x54, 0x53, 0x51, 0x4d, - 0x4c, 0x4f, 0x53, 0x57, 0x5c, 0x63, 0x6a, 0x73, 0x78, 0x7c, 0x81, 0x86, - 0x89, 0x8b, 0x8b, 0x8b, 0x89, 0x86, 0x85, 0x83, 0x81, 0x7e, 0x7c, 0x7b, - 0x7c, 0x7d, 0x7d, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x83, 0x84, 0x85, 0x87, - 0x8a, 0x8d, 0x8f, 0x8f, 0x90, 0x90, 0x8e, 0x8e, 0x8d, 0x8c, 0x89, 0x86, - 0x83, 0x81, 0x80, 0x7e, 0x7c, 0x7a, 0x7a, 0x7a, 0x78, 0x79, 0x78, 0x77, - 0x77, 0x79, 0x7b, 0x7a, 0x79, 0x76, 0x6e, 0x65, 0x5c, 0x59, 0x59, 0x5b, - 0x5c, 0x5b, 0x5a, 0x5d, 0x66, 0x70, 0x72, 0x7d, 0x85, 0x91, 0x96, 0x80, - 0x66, 0x58, 0x4f, 0x51, 0x53, 0x53, 0x5c, 0x72, 0x7d, 0x7f, 0x76, 0x70, - 0x6c, 0x62, 0x51, 0x45, 0x3e, 0x36, 0x38, 0x35, 0x39, 0x3f, 0x49, 0x53, - 0x64, 0x6f, 0x7b, 0x92, 0x99, 0x73, 0x6d, 0x76, 0x8b, 0x93, 0x94, 0x92, - 0x89, 0x70, 0x48, 0x3c, 0x2f, 0x28, 0x25, 0x26, 0x2e, 0x3f, 0x48, 0x56, - 0x8c, 0x9a, 0x9a, 0x9a, 0x9b, 0x9c, 0x9c, 0x9b, 0x9c, 0x9c, 0x9b, 0x9a, - 0x97, 0x95, 0x93, 0x90, 0x8b, 0x84, 0x7f, 0x7c, 0x78, 0x71, 0x69, 0x61, - 0x5d, 0x57, 0x4e, 0x46, 0x45, 0x44, 0x44, 0x44, 0x43, 0x44, 0x44, 0x43, - 0x43, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x46, 0x47, 0x48, 0x48, 0x49, - 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x50, 0x51, 0x52, 0x52, 0x53, 0x55, 0x55, - 0x55, 0x58, 0x59, 0x59, 0x58, 0x57, 0x57, 0x58, 0x59, 0x5b, 0x5b, 0x5d, - 0x61, 0x63, 0x66, 0x67, 0x68, 0x6c, 0x6e, 0x70, 0x72, 0x73, 0x74, 0x73, - 0x74, 0x74, 0x76, 0x77, 0x77, 0x76, 0x75, 0x72, 0x6f, 0x6d, 0x69, 0x68, - 0x64, 0x60, 0x5c, 0x58, 0x55, 0x50, 0x49, 0x43, 0x3f, 0x3b, 0x34, 0x28, - 0x1a, 0x13, 0x11, 0x11, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x12, 0x11, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x62, 0x62, 0x63, 0x63, - 0x62, 0x61, 0x60, 0x60, 0x60, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x5f, - 0x60, 0x61, 0x62, 0x62, 0x64, 0x64, 0x64, 0x65, 0x66, 0x66, 0x66, 0x68, - 0x68, 0x67, 0x69, 0x6b, 0x6a, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6b, 0x6a, - 0x69, 0x6a, 0x69, 0x68, 0x68, 0x68, 0x67, 0x64, 0x63, 0x62, 0x60, 0x5d, - 0x5b, 0x5a, 0x58, 0x56, 0x53, 0x53, 0x52, 0x4f, 0x4c, 0x4e, 0x54, 0x59, - 0x5e, 0x64, 0x6a, 0x72, 0x78, 0x7b, 0x81, 0x86, 0x88, 0x8a, 0x8a, 0x8b, - 0x89, 0x87, 0x85, 0x84, 0x82, 0x7e, 0x7b, 0x7a, 0x7b, 0x7c, 0x7c, 0x7e, - 0x7f, 0x80, 0x80, 0x81, 0x83, 0x83, 0x84, 0x87, 0x8b, 0x8e, 0x90, 0x90, - 0x91, 0x90, 0x8e, 0x8d, 0x8c, 0x8b, 0x88, 0x86, 0x84, 0x82, 0x81, 0x7f, - 0x7d, 0x7c, 0x7a, 0x7a, 0x78, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7c, 0x7b, - 0x7a, 0x76, 0x6f, 0x64, 0x5b, 0x59, 0x5a, 0x5c, 0x5d, 0x5c, 0x5b, 0x5e, - 0x67, 0x72, 0x73, 0x77, 0x7d, 0x88, 0x97, 0x90, 0x73, 0x63, 0x5c, 0x60, - 0x5e, 0x5c, 0x5e, 0x67, 0x7b, 0x80, 0x86, 0x84, 0x76, 0x64, 0x50, 0x48, - 0x47, 0x4a, 0x48, 0x40, 0x3c, 0x3d, 0x43, 0x45, 0x53, 0x6c, 0x76, 0x78, - 0x78, 0x5e, 0x57, 0x62, 0x7a, 0x72, 0x66, 0x5b, 0x54, 0x49, 0x3a, 0x34, - 0x23, 0x1e, 0x26, 0x2b, 0x32, 0x42, 0x49, 0x55, 0x85, 0x9a, 0x9b, 0x9b, - 0x9b, 0x9c, 0x9c, 0x9d, 0x9c, 0x9b, 0x99, 0x98, 0x95, 0x92, 0x90, 0x8c, - 0x87, 0x81, 0x7b, 0x77, 0x72, 0x6c, 0x63, 0x5c, 0x58, 0x50, 0x48, 0x44, - 0x43, 0x43, 0x43, 0x42, 0x43, 0x43, 0x43, 0x43, 0x43, 0x44, 0x44, 0x44, - 0x45, 0x45, 0x46, 0x47, 0x49, 0x4a, 0x4a, 0x4a, 0x4b, 0x4c, 0x4e, 0x4f, - 0x51, 0x52, 0x52, 0x52, 0x52, 0x56, 0x57, 0x57, 0x56, 0x57, 0x59, 0x57, - 0x56, 0x56, 0x57, 0x59, 0x5a, 0x5b, 0x5d, 0x5e, 0x5f, 0x62, 0x65, 0x66, - 0x67, 0x69, 0x6e, 0x70, 0x71, 0x71, 0x73, 0x73, 0x74, 0x74, 0x75, 0x76, - 0x76, 0x76, 0x75, 0x74, 0x71, 0x6e, 0x6a, 0x67, 0x63, 0x60, 0x5c, 0x58, - 0x56, 0x50, 0x4a, 0x43, 0x40, 0x3c, 0x35, 0x29, 0x1a, 0x13, 0x12, 0x12, - 0x11, 0x10, 0x10, 0x11, 0x12, 0x12, 0x11, 0x12, 0x12, 0x12, 0x12, 0x11, - 0x11, 0x11, 0x12, 0x11, 0x60, 0x61, 0x63, 0x63, 0x61, 0x61, 0x62, 0x61, - 0x61, 0x61, 0x61, 0x5f, 0x60, 0x60, 0x5f, 0x60, 0x61, 0x61, 0x61, 0x62, - 0x63, 0x64, 0x65, 0x65, 0x64, 0x66, 0x67, 0x68, 0x68, 0x68, 0x69, 0x6a, - 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6b, 0x6b, 0x6b, 0x6b, 0x6a, 0x6a, - 0x69, 0x69, 0x67, 0x65, 0x63, 0x61, 0x5f, 0x5c, 0x5a, 0x59, 0x58, 0x55, - 0x53, 0x53, 0x52, 0x50, 0x4e, 0x50, 0x56, 0x5a, 0x5f, 0x65, 0x6a, 0x72, - 0x77, 0x7a, 0x80, 0x85, 0x88, 0x8a, 0x8b, 0x8c, 0x8a, 0x88, 0x86, 0x85, - 0x82, 0x7e, 0x7c, 0x7b, 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7f, 0x81, - 0x83, 0x83, 0x84, 0x87, 0x8a, 0x8e, 0x8f, 0x90, 0x91, 0x91, 0x8e, 0x8d, - 0x8c, 0x8b, 0x88, 0x86, 0x85, 0x84, 0x83, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, - 0x78, 0x78, 0x79, 0x79, 0x78, 0x79, 0x7c, 0x7b, 0x7a, 0x76, 0x6e, 0x63, - 0x5b, 0x5b, 0x5d, 0x60, 0x60, 0x5c, 0x5a, 0x5e, 0x69, 0x72, 0x75, 0x7c, - 0x83, 0x91, 0xa1, 0xa2, 0x84, 0x72, 0x69, 0x6d, 0x6c, 0x6a, 0x67, 0x63, - 0x75, 0x88, 0x8e, 0x8a, 0x7d, 0x6a, 0x41, 0x36, 0x40, 0x57, 0x53, 0x47, - 0x44, 0x43, 0x43, 0x3d, 0x3c, 0x42, 0x46, 0x50, 0x68, 0x4c, 0x41, 0x43, - 0x4a, 0x4a, 0x46, 0x46, 0x46, 0x42, 0x38, 0x2e, 0x1d, 0x1b, 0x28, 0x34, - 0x3b, 0x43, 0x47, 0x51, 0x7d, 0x9b, 0x9d, 0x9c, 0x9d, 0x9e, 0x9e, 0x9d, - 0x9c, 0x9b, 0x98, 0x96, 0x92, 0x8e, 0x8b, 0x89, 0x84, 0x7c, 0x76, 0x72, - 0x6c, 0x64, 0x5b, 0x55, 0x51, 0x4a, 0x44, 0x43, 0x43, 0x43, 0x42, 0x41, - 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, 0x43, 0x43, 0x45, 0x45, 0x45, 0x47, - 0x49, 0x4a, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4f, 0x50, 0x51, 0x52, 0x53, - 0x55, 0x56, 0x56, 0x57, 0x57, 0x56, 0x58, 0x58, 0x57, 0x57, 0x57, 0x59, - 0x5a, 0x5b, 0x5c, 0x5c, 0x5f, 0x63, 0x66, 0x67, 0x67, 0x69, 0x6d, 0x70, - 0x70, 0x71, 0x73, 0x73, 0x74, 0x74, 0x74, 0x76, 0x76, 0x76, 0x74, 0x73, - 0x71, 0x6e, 0x6a, 0x67, 0x63, 0x60, 0x5c, 0x58, 0x56, 0x50, 0x49, 0x44, - 0x40, 0x3d, 0x35, 0x29, 0x1a, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x11, 0x12, 0x12, 0x12, 0x12, - 0x60, 0x60, 0x61, 0x62, 0x62, 0x63, 0x63, 0x62, 0x61, 0x60, 0x60, 0x5f, - 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x62, 0x61, 0x62, 0x65, 0x65, 0x65, - 0x65, 0x66, 0x67, 0x68, 0x68, 0x67, 0x69, 0x69, 0x69, 0x69, 0x6a, 0x6a, - 0x6c, 0x6c, 0x6b, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x69, 0x69, 0x66, 0x65, - 0x64, 0x62, 0x60, 0x5d, 0x5b, 0x59, 0x58, 0x56, 0x53, 0x53, 0x52, 0x50, - 0x4e, 0x52, 0x58, 0x5c, 0x62, 0x67, 0x6b, 0x72, 0x77, 0x7a, 0x7f, 0x85, - 0x89, 0x8a, 0x8b, 0x8c, 0x8b, 0x87, 0x85, 0x84, 0x82, 0x7f, 0x7d, 0x7c, - 0x7b, 0x7b, 0x7b, 0x7b, 0x7c, 0x7d, 0x7e, 0x80, 0x82, 0x83, 0x85, 0x86, - 0x8a, 0x8d, 0x8e, 0x8f, 0x8f, 0x8f, 0x8e, 0x8d, 0x8c, 0x8a, 0x88, 0x86, - 0x85, 0x84, 0x83, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x78, 0x78, 0x79, 0x79, - 0x79, 0x79, 0x7b, 0x7b, 0x7a, 0x76, 0x6f, 0x64, 0x5c, 0x5f, 0x64, 0x6b, - 0x65, 0x5c, 0x5a, 0x5f, 0x69, 0x72, 0x76, 0x80, 0x88, 0x93, 0xa2, 0xa6, - 0x8e, 0x7d, 0x71, 0x77, 0x76, 0x74, 0x70, 0x64, 0x59, 0x66, 0x79, 0x80, - 0x77, 0x4e, 0x3f, 0x44, 0x4f, 0x62, 0x5b, 0x4b, 0x47, 0x46, 0x41, 0x3b, - 0x37, 0x39, 0x41, 0x51, 0x54, 0x3f, 0x3d, 0x3e, 0x40, 0x48, 0x4b, 0x46, - 0x45, 0x45, 0x39, 0x27, 0x1a, 0x19, 0x29, 0x40, 0x48, 0x49, 0x49, 0x50, - 0x78, 0x9b, 0x9e, 0x9d, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9a, 0x98, 0x94, - 0x8f, 0x8b, 0x88, 0x86, 0x7f, 0x77, 0x72, 0x6e, 0x69, 0x60, 0x56, 0x50, - 0x4c, 0x45, 0x42, 0x41, 0x42, 0x42, 0x43, 0x42, 0x41, 0x41, 0x42, 0x42, - 0x43, 0x44, 0x42, 0x42, 0x43, 0x44, 0x46, 0x48, 0x48, 0x48, 0x49, 0x4a, - 0x4b, 0x4b, 0x4d, 0x4e, 0x51, 0x52, 0x52, 0x53, 0x56, 0x57, 0x57, 0x58, - 0x58, 0x57, 0x59, 0x59, 0x59, 0x58, 0x58, 0x5a, 0x5a, 0x5c, 0x5d, 0x5d, - 0x5f, 0x63, 0x65, 0x67, 0x68, 0x6b, 0x6d, 0x6e, 0x6f, 0x70, 0x72, 0x73, - 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x73, 0x71, 0x70, 0x6c, 0x6a, 0x68, - 0x63, 0x5f, 0x5b, 0x58, 0x55, 0x50, 0x49, 0x44, 0x40, 0x3d, 0x36, 0x29, - 0x1b, 0x14, 0x11, 0x11, 0x11, 0x10, 0x10, 0x11, 0x12, 0x12, 0x11, 0x11, - 0x12, 0x13, 0x13, 0x12, 0x13, 0x13, 0x12, 0x13, 0x60, 0x5f, 0x61, 0x62, - 0x63, 0x64, 0x64, 0x62, 0x61, 0x60, 0x60, 0x5e, 0x5e, 0x5f, 0x60, 0x60, - 0x60, 0x61, 0x62, 0x61, 0x62, 0x64, 0x64, 0x64, 0x64, 0x65, 0x66, 0x68, - 0x68, 0x68, 0x68, 0x6a, 0x69, 0x69, 0x69, 0x6a, 0x6b, 0x6c, 0x6b, 0x6a, - 0x69, 0x6a, 0x6a, 0x6a, 0x69, 0x68, 0x66, 0x65, 0x65, 0x63, 0x60, 0x5e, - 0x5a, 0x59, 0x59, 0x56, 0x54, 0x53, 0x52, 0x50, 0x4f, 0x54, 0x59, 0x5d, - 0x63, 0x68, 0x6b, 0x72, 0x76, 0x79, 0x7f, 0x84, 0x88, 0x8a, 0x8b, 0x8c, - 0x8b, 0x87, 0x85, 0x83, 0x81, 0x80, 0x7e, 0x7d, 0x7b, 0x7a, 0x7b, 0x7b, - 0x7c, 0x7c, 0x7d, 0x80, 0x82, 0x83, 0x84, 0x85, 0x8a, 0x8d, 0x8d, 0x8e, - 0x8f, 0x8f, 0x8e, 0x8d, 0x8c, 0x8a, 0x88, 0x87, 0x85, 0x84, 0x83, 0x81, - 0x7f, 0x7d, 0x7c, 0x7a, 0x79, 0x78, 0x78, 0x79, 0x78, 0x78, 0x7a, 0x7b, - 0x7b, 0x76, 0x6e, 0x64, 0x5e, 0x67, 0x70, 0x78, 0x6c, 0x5d, 0x5b, 0x5f, - 0x6a, 0x72, 0x77, 0x83, 0x89, 0x90, 0x9b, 0xa1, 0x90, 0x82, 0x77, 0x7d, - 0x7a, 0x75, 0x71, 0x68, 0x59, 0x56, 0x60, 0x66, 0x62, 0x44, 0x4c, 0x5a, - 0x62, 0x68, 0x5e, 0x4c, 0x49, 0x47, 0x42, 0x3b, 0x37, 0x38, 0x42, 0x56, - 0x4a, 0x37, 0x3a, 0x3e, 0x41, 0x49, 0x4e, 0x47, 0x44, 0x43, 0x39, 0x24, - 0x17, 0x19, 0x29, 0x46, 0x50, 0x50, 0x4e, 0x51, 0x76, 0x9c, 0x9f, 0x9e, - 0x9e, 0x9e, 0x9e, 0x9d, 0x9b, 0x9a, 0x97, 0x93, 0x8d, 0x89, 0x87, 0x83, - 0x7d, 0x74, 0x6f, 0x6b, 0x66, 0x5d, 0x53, 0x4d, 0x49, 0x43, 0x41, 0x40, - 0x42, 0x42, 0x42, 0x41, 0x41, 0x41, 0x41, 0x42, 0x43, 0x44, 0x42, 0x42, - 0x43, 0x44, 0x46, 0x48, 0x48, 0x48, 0x49, 0x4a, 0x4b, 0x4b, 0x4d, 0x4f, - 0x52, 0x52, 0x52, 0x53, 0x56, 0x57, 0x58, 0x58, 0x58, 0x58, 0x5a, 0x59, - 0x58, 0x58, 0x58, 0x5a, 0x5b, 0x5c, 0x5d, 0x5d, 0x60, 0x63, 0x65, 0x66, - 0x69, 0x6c, 0x6d, 0x6e, 0x6f, 0x6f, 0x72, 0x72, 0x74, 0x75, 0x74, 0x74, - 0x74, 0x74, 0x73, 0x71, 0x6f, 0x6c, 0x6a, 0x68, 0x63, 0x5f, 0x5b, 0x57, - 0x55, 0x50, 0x49, 0x44, 0x40, 0x3d, 0x36, 0x29, 0x1c, 0x14, 0x12, 0x11, - 0x11, 0x10, 0x10, 0x11, 0x12, 0x12, 0x12, 0x11, 0x12, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x12, 0x13, 0x60, 0x60, 0x61, 0x61, 0x63, 0x64, 0x63, 0x61, - 0x60, 0x60, 0x60, 0x5e, 0x5d, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x61, - 0x62, 0x62, 0x62, 0x62, 0x63, 0x65, 0x66, 0x67, 0x67, 0x67, 0x68, 0x6a, - 0x6a, 0x6a, 0x69, 0x6a, 0x6c, 0x6c, 0x6b, 0x6a, 0x69, 0x6a, 0x6a, 0x6a, - 0x69, 0x69, 0x66, 0x65, 0x64, 0x62, 0x60, 0x5d, 0x5b, 0x59, 0x59, 0x57, - 0x54, 0x53, 0x52, 0x50, 0x4f, 0x55, 0x5c, 0x5f, 0x63, 0x68, 0x6c, 0x71, - 0x75, 0x78, 0x7e, 0x83, 0x87, 0x88, 0x89, 0x8b, 0x8a, 0x87, 0x84, 0x83, - 0x82, 0x80, 0x7e, 0x7e, 0x7d, 0x7a, 0x7a, 0x7a, 0x7c, 0x7d, 0x7e, 0x80, - 0x82, 0x83, 0x84, 0x86, 0x8a, 0x8d, 0x8d, 0x8e, 0x8f, 0x8e, 0x8f, 0x8d, - 0x8c, 0x8a, 0x88, 0x87, 0x85, 0x84, 0x83, 0x80, 0x7e, 0x7d, 0x7d, 0x7b, - 0x7a, 0x79, 0x79, 0x79, 0x78, 0x78, 0x7b, 0x7c, 0x7b, 0x76, 0x6e, 0x64, - 0x67, 0x7d, 0x8b, 0x91, 0x7b, 0x61, 0x5d, 0x61, 0x6c, 0x74, 0x7b, 0x8a, - 0x8e, 0x88, 0x87, 0x91, 0x8b, 0x84, 0x7c, 0x84, 0x7b, 0x73, 0x71, 0x72, - 0x7a, 0x63, 0x4c, 0x44, 0x47, 0x54, 0x6f, 0x79, 0x79, 0x6e, 0x5f, 0x51, - 0x55, 0x55, 0x4b, 0x40, 0x39, 0x38, 0x41, 0x53, 0x42, 0x30, 0x35, 0x3a, - 0x3f, 0x46, 0x4a, 0x44, 0x40, 0x3d, 0x39, 0x21, 0x16, 0x18, 0x29, 0x4a, - 0x59, 0x5a, 0x56, 0x54, 0x76, 0x9d, 0xa0, 0x9e, 0x9e, 0x9e, 0x9c, 0x9c, - 0x9a, 0x98, 0x94, 0x91, 0x8b, 0x88, 0x84, 0x80, 0x77, 0x6f, 0x6a, 0x67, - 0x61, 0x58, 0x4f, 0x49, 0x45, 0x41, 0x40, 0x41, 0x40, 0x41, 0x41, 0x40, - 0x41, 0x41, 0x41, 0x42, 0x43, 0x43, 0x42, 0x42, 0x43, 0x45, 0x46, 0x48, - 0x49, 0x49, 0x4a, 0x49, 0x4a, 0x4b, 0x4d, 0x50, 0x52, 0x52, 0x52, 0x53, - 0x55, 0x57, 0x57, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, 0x59, 0x5b, - 0x5b, 0x5d, 0x5f, 0x60, 0x61, 0x63, 0x63, 0x65, 0x68, 0x6b, 0x6c, 0x6e, - 0x6e, 0x6f, 0x72, 0x72, 0x74, 0x75, 0x75, 0x75, 0x75, 0x74, 0x74, 0x71, - 0x6f, 0x6c, 0x6a, 0x68, 0x63, 0x5f, 0x5a, 0x58, 0x55, 0x51, 0x4a, 0x44, - 0x41, 0x3d, 0x36, 0x2a, 0x1d, 0x16, 0x12, 0x11, 0x10, 0x10, 0x10, 0x11, - 0x11, 0x12, 0x13, 0x12, 0x12, 0x13, 0x13, 0x12, 0x13, 0x13, 0x12, 0x13, - 0x60, 0x60, 0x60, 0x61, 0x62, 0x63, 0x62, 0x60, 0x60, 0x61, 0x61, 0x5e, - 0x5d, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x61, 0x62, 0x61, 0x62, 0x62, - 0x63, 0x64, 0x65, 0x66, 0x66, 0x66, 0x69, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, - 0x6c, 0x6c, 0x6b, 0x6b, 0x6b, 0x6b, 0x6a, 0x6a, 0x69, 0x69, 0x68, 0x66, - 0x65, 0x62, 0x61, 0x5e, 0x5b, 0x5a, 0x58, 0x56, 0x54, 0x52, 0x50, 0x4f, - 0x51, 0x59, 0x5f, 0x62, 0x65, 0x6b, 0x6f, 0x70, 0x73, 0x76, 0x7c, 0x82, - 0x85, 0x87, 0x88, 0x89, 0x8a, 0x87, 0x85, 0x84, 0x82, 0x80, 0x80, 0x7f, - 0x7d, 0x7c, 0x7b, 0x7b, 0x7b, 0x7c, 0x7e, 0x7f, 0x82, 0x83, 0x84, 0x86, - 0x8a, 0x8c, 0x8e, 0x8e, 0x8f, 0x8f, 0x8d, 0x8c, 0x8b, 0x8b, 0x89, 0x87, - 0x86, 0x85, 0x83, 0x80, 0x7e, 0x7d, 0x7d, 0x7c, 0x7a, 0x78, 0x78, 0x78, - 0x78, 0x78, 0x7a, 0x7c, 0x7b, 0x76, 0x6e, 0x69, 0x7a, 0x99, 0xa8, 0xa9, - 0x8a, 0x67, 0x5f, 0x63, 0x6f, 0x7e, 0x8e, 0x9c, 0x98, 0x7e, 0x6c, 0x78, - 0x7e, 0x7f, 0x82, 0x8b, 0x81, 0x79, 0x76, 0x7d, 0x94, 0x95, 0x84, 0x7c, - 0x79, 0x7f, 0x7b, 0x76, 0x73, 0x6c, 0x67, 0x6a, 0x7b, 0x79, 0x5e, 0x49, - 0x40, 0x3e, 0x3e, 0x3e, 0x33, 0x2c, 0x33, 0x36, 0x37, 0x3c, 0x40, 0x40, - 0x3e, 0x3b, 0x36, 0x1e, 0x19, 0x1f, 0x32, 0x4e, 0x5a, 0x5d, 0x5a, 0x59, - 0x7f, 0x9e, 0xa1, 0x9f, 0x9e, 0x9e, 0x9d, 0x9a, 0x98, 0x96, 0x92, 0x8d, - 0x87, 0x83, 0x80, 0x7a, 0x72, 0x6a, 0x64, 0x60, 0x5a, 0x51, 0x49, 0x45, - 0x42, 0x3f, 0x3f, 0x40, 0x3f, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x42, - 0x43, 0x43, 0x42, 0x41, 0x42, 0x44, 0x45, 0x47, 0x49, 0x49, 0x4b, 0x4b, - 0x4c, 0x4d, 0x4e, 0x50, 0x52, 0x53, 0x53, 0x53, 0x56, 0x57, 0x57, 0x58, - 0x59, 0x58, 0x58, 0x59, 0x5a, 0x5a, 0x5a, 0x5c, 0x5d, 0x5f, 0x60, 0x61, - 0x62, 0x63, 0x63, 0x64, 0x67, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, 0x72, 0x73, - 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x73, 0x70, 0x6c, 0x6a, 0x68, - 0x64, 0x5f, 0x5b, 0x58, 0x55, 0x50, 0x49, 0x44, 0x40, 0x3c, 0x35, 0x29, - 0x1c, 0x15, 0x11, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x13, 0x13, 0x13, 0x13, 0x12, 0x11, 0x13, 0x5e, 0x5f, 0x5f, 0x5f, - 0x60, 0x61, 0x62, 0x60, 0x60, 0x61, 0x61, 0x5f, 0x5d, 0x5e, 0x5f, 0x5f, - 0x60, 0x61, 0x61, 0x60, 0x61, 0x61, 0x63, 0x63, 0x64, 0x63, 0x64, 0x64, - 0x65, 0x66, 0x68, 0x68, 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, - 0x6c, 0x6b, 0x69, 0x69, 0x69, 0x6a, 0x69, 0x68, 0x67, 0x64, 0x61, 0x5d, - 0x5a, 0x59, 0x57, 0x55, 0x52, 0x50, 0x50, 0x50, 0x53, 0x5d, 0x62, 0x64, - 0x68, 0x6d, 0x6f, 0x71, 0x74, 0x76, 0x7a, 0x80, 0x83, 0x86, 0x87, 0x88, - 0x89, 0x88, 0x86, 0x84, 0x81, 0x80, 0x80, 0x7f, 0x7e, 0x7c, 0x7c, 0x7b, - 0x7b, 0x7c, 0x7e, 0x7e, 0x80, 0x83, 0x83, 0x85, 0x89, 0x8b, 0x8d, 0x8d, - 0x8e, 0x8d, 0x8d, 0x8b, 0x8b, 0x8c, 0x8a, 0x87, 0x87, 0x86, 0x84, 0x80, - 0x7e, 0x7e, 0x7e, 0x7d, 0x7a, 0x7a, 0x78, 0x78, 0x78, 0x78, 0x7a, 0x7c, - 0x7b, 0x76, 0x6e, 0x6c, 0x83, 0xa1, 0xae, 0xab, 0x8f, 0x6d, 0x63, 0x66, - 0x72, 0x8a, 0xa4, 0xa7, 0x97, 0x72, 0x62, 0x70, 0x75, 0x79, 0x84, 0x90, - 0x8a, 0x83, 0x80, 0x82, 0x99, 0xa4, 0xa3, 0x9f, 0x96, 0x8a, 0x7e, 0x78, - 0x76, 0x78, 0x84, 0x7b, 0x75, 0x6f, 0x63, 0x52, 0x54, 0x51, 0x4c, 0x41, - 0x36, 0x32, 0x34, 0x32, 0x2e, 0x33, 0x3c, 0x3d, 0x3d, 0x3c, 0x32, 0x1e, - 0x1f, 0x29, 0x3f, 0x54, 0x5b, 0x59, 0x57, 0x5f, 0x90, 0xa2, 0xa1, 0x9e, - 0x9d, 0x9e, 0x9b, 0x97, 0x95, 0x93, 0x8f, 0x88, 0x80, 0x7d, 0x79, 0x74, - 0x6b, 0x63, 0x5c, 0x58, 0x53, 0x4b, 0x45, 0x42, 0x41, 0x3f, 0x3e, 0x3e, - 0x3d, 0x3d, 0x3e, 0x41, 0x42, 0x41, 0x41, 0x41, 0x43, 0x43, 0x42, 0x41, - 0x42, 0x44, 0x45, 0x47, 0x48, 0x48, 0x4a, 0x4c, 0x4d, 0x4e, 0x4e, 0x50, - 0x52, 0x54, 0x54, 0x55, 0x55, 0x57, 0x57, 0x58, 0x59, 0x59, 0x59, 0x5b, - 0x5b, 0x5b, 0x5b, 0x5d, 0x5e, 0x5e, 0x5f, 0x61, 0x62, 0x63, 0x65, 0x66, - 0x69, 0x6c, 0x6d, 0x6d, 0x6d, 0x6e, 0x72, 0x73, 0x72, 0x73, 0x74, 0x73, - 0x73, 0x74, 0x74, 0x73, 0x70, 0x6b, 0x6a, 0x69, 0x65, 0x61, 0x5c, 0x58, - 0x54, 0x4e, 0x48, 0x43, 0x3f, 0x3b, 0x34, 0x29, 0x1c, 0x15, 0x12, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x11, 0x11, 0x12, 0x12, 0x13, - 0x13, 0x12, 0x11, 0x13, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x61, 0x62, 0x60, - 0x60, 0x61, 0x61, 0x5f, 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x61, - 0x61, 0x61, 0x63, 0x63, 0x63, 0x63, 0x63, 0x64, 0x65, 0x67, 0x67, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6b, 0x6a, 0x69, - 0x69, 0x6a, 0x69, 0x68, 0x67, 0x64, 0x61, 0x5e, 0x5a, 0x58, 0x57, 0x55, - 0x51, 0x50, 0x50, 0x51, 0x56, 0x5f, 0x64, 0x66, 0x69, 0x6e, 0x71, 0x73, - 0x75, 0x77, 0x7a, 0x7f, 0x82, 0x85, 0x85, 0x87, 0x89, 0x88, 0x85, 0x83, - 0x81, 0x80, 0x7f, 0x7f, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7c, 0x7d, 0x7e, - 0x80, 0x82, 0x84, 0x85, 0x88, 0x8a, 0x8c, 0x8e, 0x8e, 0x8e, 0x8d, 0x8c, - 0x8c, 0x8c, 0x8b, 0x89, 0x89, 0x88, 0x86, 0x82, 0x80, 0x7e, 0x7e, 0x7d, - 0x7b, 0x79, 0x79, 0x78, 0x78, 0x78, 0x7a, 0x7c, 0x7c, 0x77, 0x6f, 0x6e, - 0x84, 0xa0, 0xaa, 0xa4, 0x87, 0x6e, 0x65, 0x67, 0x75, 0x94, 0xab, 0xa1, - 0x89, 0x62, 0x5e, 0x70, 0x71, 0x74, 0x82, 0x94, 0x94, 0x8c, 0x86, 0x86, - 0x9c, 0xa7, 0xa8, 0xa5, 0x9e, 0x94, 0x8d, 0x8a, 0x8a, 0x92, 0xaa, 0x9a, - 0x98, 0x93, 0x7d, 0x63, 0x64, 0x5f, 0x58, 0x4b, 0x42, 0x40, 0x3c, 0x35, - 0x2b, 0x30, 0x3d, 0x3f, 0x40, 0x3e, 0x31, 0x20, 0x26, 0x33, 0x4a, 0x5a, - 0x5b, 0x53, 0x55, 0x6a, 0x9b, 0xa3, 0x9f, 0x9d, 0x9d, 0x9d, 0x9a, 0x95, - 0x93, 0x91, 0x8c, 0x84, 0x7c, 0x78, 0x74, 0x6f, 0x67, 0x5f, 0x58, 0x55, - 0x4f, 0x48, 0x42, 0x40, 0x3f, 0x3e, 0x3e, 0x3e, 0x3e, 0x3d, 0x3e, 0x41, - 0x42, 0x41, 0x41, 0x42, 0x44, 0x44, 0x42, 0x42, 0x43, 0x45, 0x46, 0x48, - 0x48, 0x49, 0x4a, 0x4c, 0x4d, 0x4d, 0x4e, 0x4f, 0x52, 0x53, 0x54, 0x55, - 0x55, 0x57, 0x57, 0x58, 0x5a, 0x5a, 0x5a, 0x5c, 0x5d, 0x5d, 0x5c, 0x5e, - 0x5f, 0x5f, 0x5f, 0x60, 0x61, 0x63, 0x65, 0x67, 0x68, 0x6c, 0x6d, 0x6d, - 0x6d, 0x6f, 0x72, 0x72, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x72, - 0x6f, 0x6b, 0x6a, 0x69, 0x65, 0x61, 0x5c, 0x58, 0x54, 0x4e, 0x49, 0x43, - 0x3e, 0x3a, 0x34, 0x2a, 0x1c, 0x15, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x12, 0x11, 0x11, 0x11, 0x13, 0x13, 0x12, 0x12, 0x12, 0x11, 0x13, - 0x5e, 0x5e, 0x5d, 0x5d, 0x5e, 0x61, 0x62, 0x61, 0x60, 0x61, 0x61, 0x5f, - 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x61, 0x61, 0x61, 0x63, 0x63, - 0x63, 0x63, 0x64, 0x64, 0x65, 0x66, 0x66, 0x66, 0x67, 0x69, 0x6a, 0x6a, - 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6b, 0x6a, 0x69, 0x69, 0x6a, 0x6a, 0x68, - 0x67, 0x65, 0x61, 0x5e, 0x5a, 0x58, 0x56, 0x55, 0x52, 0x51, 0x50, 0x52, - 0x58, 0x61, 0x65, 0x67, 0x6a, 0x70, 0x73, 0x75, 0x76, 0x77, 0x7a, 0x7e, - 0x81, 0x84, 0x85, 0x86, 0x88, 0x87, 0x85, 0x83, 0x81, 0x7f, 0x7f, 0x80, - 0x80, 0x7f, 0x7e, 0x7d, 0x7c, 0x7d, 0x7e, 0x7f, 0x81, 0x82, 0x83, 0x85, - 0x88, 0x89, 0x8b, 0x8d, 0x8e, 0x8e, 0x8d, 0x8c, 0x8c, 0x8c, 0x8b, 0x89, - 0x88, 0x88, 0x86, 0x83, 0x80, 0x7f, 0x7f, 0x7e, 0x7c, 0x7a, 0x79, 0x79, - 0x78, 0x78, 0x7a, 0x7c, 0x7b, 0x76, 0x70, 0x6e, 0x83, 0xa0, 0xa9, 0xa0, - 0x82, 0x6c, 0x66, 0x68, 0x78, 0x99, 0xa9, 0x98, 0x7f, 0x59, 0x5f, 0x74, - 0x74, 0x76, 0x82, 0x97, 0x9a, 0x93, 0x8d, 0x8c, 0x9e, 0xa1, 0xa5, 0xa5, - 0xa1, 0x9b, 0x97, 0x97, 0x9a, 0xa7, 0xbc, 0xa5, 0xad, 0xad, 0x94, 0x6e, - 0x6a, 0x69, 0x63, 0x56, 0x50, 0x50, 0x47, 0x3d, 0x2d, 0x2e, 0x3b, 0x40, - 0x41, 0x3f, 0x31, 0x26, 0x2f, 0x3c, 0x51, 0x5d, 0x59, 0x51, 0x56, 0x71, - 0x9d, 0xa3, 0x9e, 0x9d, 0x9c, 0x9b, 0x99, 0x94, 0x92, 0x8f, 0x8a, 0x82, - 0x7a, 0x74, 0x71, 0x6c, 0x64, 0x5c, 0x56, 0x52, 0x4c, 0x45, 0x41, 0x3f, - 0x3f, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x40, 0x41, 0x41, 0x41, 0x43, - 0x44, 0x44, 0x43, 0x42, 0x43, 0x46, 0x47, 0x49, 0x49, 0x4a, 0x4b, 0x4c, - 0x4d, 0x4d, 0x4e, 0x50, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x59, 0x5a, 0x5b, 0x5d, 0x5d, 0x5d, 0x5c, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, - 0x61, 0x63, 0x65, 0x67, 0x69, 0x6c, 0x6d, 0x6d, 0x6e, 0x70, 0x71, 0x71, - 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x72, 0x6f, 0x6b, 0x6a, 0x69, - 0x65, 0x61, 0x5c, 0x58, 0x55, 0x4f, 0x49, 0x43, 0x3d, 0x39, 0x33, 0x2a, - 0x1d, 0x14, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x11, 0x11, - 0x12, 0x13, 0x13, 0x12, 0x12, 0x12, 0x11, 0x13, 0x5e, 0x5e, 0x5d, 0x5c, - 0x5c, 0x60, 0x62, 0x62, 0x61, 0x60, 0x5f, 0x5f, 0x5e, 0x5e, 0x5f, 0x60, - 0x61, 0x61, 0x61, 0x60, 0x60, 0x62, 0x63, 0x64, 0x63, 0x63, 0x64, 0x64, - 0x65, 0x66, 0x66, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, - 0x6c, 0x6b, 0x6a, 0x6a, 0x69, 0x6a, 0x69, 0x69, 0x67, 0x65, 0x61, 0x5f, - 0x5b, 0x59, 0x57, 0x56, 0x54, 0x51, 0x51, 0x53, 0x5a, 0x62, 0x66, 0x68, - 0x6c, 0x72, 0x74, 0x76, 0x76, 0x77, 0x79, 0x7d, 0x80, 0x83, 0x84, 0x85, - 0x87, 0x86, 0x85, 0x83, 0x81, 0x7f, 0x7e, 0x7f, 0x80, 0x80, 0x7f, 0x7f, - 0x7e, 0x7f, 0x7f, 0x7f, 0x81, 0x82, 0x82, 0x84, 0x87, 0x88, 0x8a, 0x8b, - 0x8c, 0x8d, 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x89, 0x88, 0x88, 0x86, 0x83, - 0x81, 0x80, 0x80, 0x7f, 0x7e, 0x7b, 0x79, 0x79, 0x79, 0x79, 0x79, 0x7b, - 0x7a, 0x76, 0x70, 0x6e, 0x84, 0xa4, 0xae, 0xa3, 0x80, 0x6a, 0x67, 0x6b, - 0x7b, 0x9a, 0x9d, 0x85, 0x6d, 0x52, 0x62, 0x7e, 0x80, 0x7f, 0x85, 0x98, - 0xa2, 0x9d, 0x98, 0x96, 0x9f, 0x96, 0xa2, 0xa8, 0xa5, 0xa0, 0x9f, 0xa3, - 0xaa, 0xb9, 0xbb, 0x9d, 0xac, 0xb4, 0xa6, 0x7c, 0x71, 0x80, 0x81, 0x73, - 0x70, 0x6d, 0x5d, 0x4d, 0x37, 0x2e, 0x37, 0x3f, 0x43, 0x43, 0x36, 0x32, - 0x41, 0x4e, 0x5c, 0x60, 0x57, 0x51, 0x57, 0x71, 0x98, 0xa0, 0x9e, 0x9d, - 0x9c, 0x9a, 0x97, 0x91, 0x8f, 0x8c, 0x86, 0x7d, 0x76, 0x71, 0x6d, 0x68, - 0x5f, 0x57, 0x51, 0x4d, 0x47, 0x42, 0x40, 0x3e, 0x3d, 0x3d, 0x3d, 0x3d, - 0x3f, 0x3f, 0x3f, 0x40, 0x41, 0x40, 0x41, 0x42, 0x42, 0x43, 0x43, 0x43, - 0x44, 0x47, 0x49, 0x49, 0x49, 0x4a, 0x4c, 0x4c, 0x4d, 0x4e, 0x4f, 0x51, - 0x51, 0x52, 0x53, 0x55, 0x56, 0x58, 0x59, 0x59, 0x59, 0x5a, 0x5b, 0x5e, - 0x5e, 0x5e, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x61, 0x63, 0x63, 0x64, 0x66, - 0x69, 0x6b, 0x6d, 0x6d, 0x6e, 0x70, 0x70, 0x72, 0x72, 0x73, 0x74, 0x74, - 0x74, 0x74, 0x73, 0x70, 0x6f, 0x6b, 0x6a, 0x69, 0x65, 0x61, 0x5b, 0x58, - 0x56, 0x51, 0x49, 0x43, 0x3d, 0x39, 0x33, 0x2a, 0x1d, 0x14, 0x12, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x12, - 0x11, 0x11, 0x12, 0x13, 0x5d, 0x5d, 0x5c, 0x5c, 0x5c, 0x5f, 0x61, 0x61, - 0x60, 0x60, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x60, - 0x60, 0x61, 0x62, 0x62, 0x62, 0x61, 0x62, 0x63, 0x63, 0x65, 0x66, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, 0x6c, 0x6c, 0x6b, 0x6b, - 0x6b, 0x6a, 0x69, 0x68, 0x68, 0x65, 0x62, 0x5f, 0x5b, 0x59, 0x56, 0x56, - 0x54, 0x52, 0x51, 0x53, 0x5e, 0x66, 0x6a, 0x6c, 0x70, 0x74, 0x76, 0x78, - 0x78, 0x79, 0x7a, 0x7c, 0x7d, 0x81, 0x83, 0x84, 0x86, 0x85, 0x83, 0x82, - 0x81, 0x7f, 0x7d, 0x7e, 0x7e, 0x7f, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x81, 0x82, 0x82, 0x83, 0x86, 0x88, 0x88, 0x89, 0x8b, 0x8c, 0x8b, 0x8b, - 0x8b, 0x8c, 0x8b, 0x89, 0x88, 0x87, 0x85, 0x85, 0x82, 0x81, 0x80, 0x80, - 0x7e, 0x7b, 0x79, 0x79, 0x79, 0x78, 0x79, 0x79, 0x78, 0x76, 0x71, 0x6f, - 0x8b, 0xaf, 0xba, 0xac, 0x7f, 0x67, 0x6a, 0x70, 0x7d, 0x8d, 0x80, 0x67, - 0x59, 0x4f, 0x66, 0x87, 0x91, 0x91, 0x8f, 0x97, 0xa6, 0xa2, 0x9e, 0x9d, - 0xa3, 0xa1, 0xa8, 0xaa, 0xa9, 0xa2, 0x9e, 0x9d, 0x9e, 0x9f, 0x9e, 0x8b, - 0x88, 0x8c, 0x91, 0x8a, 0x93, 0xb5, 0xbf, 0xb2, 0xa8, 0x8d, 0x6e, 0x5c, - 0x4a, 0x38, 0x38, 0x47, 0x51, 0x56, 0x44, 0x45, 0x57, 0x62, 0x67, 0x61, - 0x56, 0x4d, 0x4e, 0x5f, 0x8c, 0x9f, 0x9d, 0x9a, 0x99, 0x97, 0x92, 0x8c, - 0x88, 0x86, 0x81, 0x78, 0x70, 0x6b, 0x67, 0x61, 0x58, 0x51, 0x4b, 0x48, - 0x44, 0x41, 0x40, 0x3e, 0x3d, 0x3d, 0x3d, 0x3d, 0x3f, 0x40, 0x41, 0x41, - 0x42, 0x42, 0x42, 0x42, 0x43, 0x44, 0x44, 0x44, 0x45, 0x47, 0x49, 0x49, - 0x49, 0x4a, 0x4c, 0x4c, 0x4d, 0x4e, 0x4f, 0x51, 0x52, 0x52, 0x52, 0x55, - 0x56, 0x58, 0x59, 0x59, 0x58, 0x59, 0x5b, 0x5d, 0x5e, 0x5e, 0x5d, 0x5d, - 0x5f, 0x5f, 0x60, 0x62, 0x63, 0x63, 0x64, 0x67, 0x6a, 0x6c, 0x6d, 0x6e, - 0x6e, 0x6f, 0x70, 0x72, 0x72, 0x73, 0x74, 0x74, 0x74, 0x74, 0x72, 0x70, - 0x6f, 0x6b, 0x6a, 0x69, 0x65, 0x60, 0x5b, 0x57, 0x56, 0x51, 0x49, 0x42, - 0x3d, 0x3a, 0x34, 0x2a, 0x1c, 0x14, 0x12, 0x11, 0x10, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x10, 0x11, 0x11, 0x11, - 0x5c, 0x5d, 0x5d, 0x5d, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x60, 0x60, 0x60, - 0x60, 0x60, 0x61, 0x60, 0x61, 0x61, 0x60, 0x5f, 0x60, 0x60, 0x60, 0x60, - 0x60, 0x60, 0x62, 0x62, 0x62, 0x64, 0x65, 0x64, 0x65, 0x66, 0x68, 0x68, - 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6b, 0x6b, 0x6b, 0x6a, 0x69, 0x69, - 0x68, 0x66, 0x62, 0x5f, 0x5c, 0x59, 0x57, 0x56, 0x54, 0x52, 0x52, 0x56, - 0x61, 0x6a, 0x6e, 0x70, 0x72, 0x77, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7b, - 0x7c, 0x7e, 0x80, 0x82, 0x85, 0x84, 0x82, 0x81, 0x80, 0x7f, 0x7d, 0x7d, - 0x7e, 0x80, 0x82, 0x82, 0x81, 0x80, 0x81, 0x80, 0x81, 0x82, 0x83, 0x84, - 0x85, 0x86, 0x88, 0x88, 0x88, 0x8a, 0x8a, 0x8c, 0x8c, 0x8c, 0x8c, 0x8a, - 0x89, 0x88, 0x86, 0x85, 0x82, 0x80, 0x80, 0x7f, 0x7d, 0x7b, 0x79, 0x79, - 0x79, 0x78, 0x78, 0x79, 0x79, 0x77, 0x73, 0x74, 0x92, 0xb4, 0xbf, 0xaf, - 0x7e, 0x6a, 0x6d, 0x73, 0x7c, 0x80, 0x6a, 0x55, 0x4e, 0x52, 0x64, 0x81, - 0x99, 0xa0, 0x9e, 0x9b, 0xa4, 0x9c, 0x97, 0x99, 0xa2, 0xab, 0xad, 0xad, - 0xac, 0xa0, 0x9a, 0x99, 0x9a, 0x9b, 0x98, 0x93, 0x8f, 0x8f, 0x93, 0x9b, - 0xaa, 0xc2, 0xcc, 0xcb, 0xc2, 0x9d, 0x80, 0x75, 0x6d, 0x55, 0x4c, 0x5c, - 0x69, 0x6e, 0x59, 0x57, 0x63, 0x69, 0x69, 0x60, 0x52, 0x3e, 0x39, 0x4a, - 0x7d, 0x99, 0x9b, 0x99, 0x97, 0x93, 0x8e, 0x87, 0x82, 0x7f, 0x7b, 0x73, - 0x6a, 0x64, 0x61, 0x5a, 0x50, 0x4a, 0x45, 0x43, 0x42, 0x40, 0x3f, 0x3f, - 0x3e, 0x3d, 0x3d, 0x3e, 0x40, 0x41, 0x42, 0x42, 0x43, 0x43, 0x44, 0x44, - 0x44, 0x45, 0x45, 0x46, 0x46, 0x47, 0x47, 0x47, 0x48, 0x4b, 0x4d, 0x4c, - 0x4d, 0x4e, 0x4e, 0x50, 0x51, 0x52, 0x52, 0x55, 0x56, 0x58, 0x59, 0x59, - 0x58, 0x59, 0x5c, 0x5e, 0x5f, 0x5f, 0x5f, 0x5e, 0x60, 0x60, 0x61, 0x62, - 0x63, 0x63, 0x64, 0x66, 0x69, 0x6b, 0x6d, 0x6e, 0x6e, 0x70, 0x70, 0x71, - 0x71, 0x72, 0x73, 0x73, 0x74, 0x74, 0x72, 0x70, 0x6f, 0x6b, 0x6a, 0x69, - 0x66, 0x62, 0x5c, 0x56, 0x53, 0x4f, 0x48, 0x41, 0x3d, 0x3a, 0x36, 0x2a, - 0x1d, 0x15, 0x12, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x11, 0x12, 0x12, - 0x12, 0x12, 0x13, 0x11, 0x11, 0x11, 0x12, 0x12, 0x5c, 0x5d, 0x5e, 0x5d, - 0x5d, 0x5d, 0x5d, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x62, - 0x61, 0x61, 0x61, 0x60, 0x60, 0x60, 0x60, 0x5f, 0x5f, 0x61, 0x61, 0x61, - 0x62, 0x64, 0x65, 0x64, 0x65, 0x66, 0x66, 0x68, 0x68, 0x6a, 0x6b, 0x6b, - 0x6c, 0x6c, 0x6b, 0x6b, 0x6b, 0x6a, 0x69, 0x68, 0x68, 0x66, 0x62, 0x5f, - 0x5c, 0x5b, 0x58, 0x55, 0x53, 0x52, 0x54, 0x58, 0x62, 0x6b, 0x70, 0x72, - 0x75, 0x78, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7d, 0x7e, 0x7f, - 0x82, 0x82, 0x81, 0x81, 0x7f, 0x7e, 0x7d, 0x7d, 0x7d, 0x7f, 0x82, 0x83, - 0x82, 0x81, 0x80, 0x7f, 0x80, 0x81, 0x82, 0x84, 0x86, 0x86, 0x87, 0x87, - 0x88, 0x8a, 0x8b, 0x8c, 0x8c, 0x8c, 0x8c, 0x8a, 0x89, 0x87, 0x86, 0x85, - 0x83, 0x81, 0x80, 0x7f, 0x7d, 0x7c, 0x7b, 0x7a, 0x7a, 0x78, 0x78, 0x7a, - 0x7b, 0x7a, 0x78, 0x7b, 0x93, 0xb1, 0xb9, 0xa9, 0x7b, 0x6b, 0x6d, 0x72, - 0x7c, 0x80, 0x65, 0x4f, 0x4b, 0x53, 0x5b, 0x70, 0x94, 0xa4, 0xa9, 0xa3, - 0xa1, 0x97, 0x91, 0x8e, 0x9c, 0xa8, 0xaa, 0xaa, 0xa8, 0x9f, 0x9c, 0x9d, - 0xa0, 0xa4, 0xa2, 0xa4, 0xa3, 0xa1, 0xa2, 0xaa, 0xb1, 0xbb, 0xbf, 0xbf, - 0xb9, 0xa0, 0x93, 0x90, 0x8d, 0x79, 0x66, 0x6d, 0x73, 0x70, 0x63, 0x60, - 0x67, 0x69, 0x66, 0x59, 0x46, 0x39, 0x36, 0x42, 0x71, 0x92, 0x98, 0x97, - 0x95, 0x91, 0x8b, 0x82, 0x7e, 0x7b, 0x75, 0x6e, 0x65, 0x5f, 0x5b, 0x54, - 0x4d, 0x47, 0x43, 0x41, 0x41, 0x3f, 0x40, 0x40, 0x3f, 0x3e, 0x3e, 0x40, - 0x41, 0x42, 0x43, 0x43, 0x43, 0x44, 0x44, 0x44, 0x44, 0x46, 0x47, 0x48, - 0x47, 0x47, 0x47, 0x48, 0x49, 0x4c, 0x4d, 0x4d, 0x4d, 0x4e, 0x4f, 0x4e, - 0x50, 0x51, 0x52, 0x55, 0x56, 0x58, 0x59, 0x59, 0x58, 0x5b, 0x5c, 0x5f, - 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x62, 0x62, 0x63, 0x63, 0x65, 0x66, - 0x69, 0x6a, 0x6d, 0x6e, 0x6e, 0x70, 0x71, 0x71, 0x70, 0x71, 0x72, 0x72, - 0x74, 0x73, 0x72, 0x70, 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x62, 0x5c, 0x56, - 0x52, 0x4e, 0x49, 0x43, 0x3e, 0x3b, 0x35, 0x29, 0x1e, 0x16, 0x12, 0x11, - 0x11, 0x12, 0x12, 0x12, 0x12, 0x11, 0x12, 0x12, 0x12, 0x13, 0x12, 0x11, - 0x12, 0x12, 0x13, 0x11, 0x5b, 0x5d, 0x5e, 0x5d, 0x5c, 0x5d, 0x5d, 0x5f, - 0x60, 0x61, 0x61, 0x61, 0x62, 0x62, 0x61, 0x61, 0x61, 0x62, 0x61, 0x60, - 0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x60, 0x62, 0x63, 0x65, 0x65, 0x64, - 0x65, 0x66, 0x66, 0x68, 0x68, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6b, 0x6b, - 0x6b, 0x6a, 0x69, 0x68, 0x68, 0x65, 0x61, 0x5f, 0x5c, 0x5b, 0x58, 0x55, - 0x53, 0x53, 0x55, 0x5a, 0x64, 0x6c, 0x71, 0x74, 0x77, 0x7a, 0x7c, 0x7d, - 0x7d, 0x7e, 0x7e, 0x7c, 0x7c, 0x7c, 0x7d, 0x7e, 0x81, 0x80, 0x7f, 0x7f, - 0x7e, 0x7d, 0x7d, 0x7d, 0x7d, 0x7f, 0x82, 0x83, 0x82, 0x82, 0x81, 0x80, - 0x80, 0x81, 0x82, 0x83, 0x86, 0x86, 0x86, 0x87, 0x87, 0x8a, 0x8a, 0x8b, - 0x8c, 0x8c, 0x8c, 0x89, 0x88, 0x88, 0x86, 0x85, 0x83, 0x82, 0x81, 0x7f, - 0x7d, 0x7c, 0x7b, 0x7a, 0x7a, 0x78, 0x78, 0x7a, 0x7b, 0x7c, 0x7d, 0x7f, - 0x91, 0xaa, 0xb0, 0xa1, 0x7a, 0x6e, 0x6e, 0x72, 0x7d, 0x84, 0x67, 0x4e, - 0x4a, 0x51, 0x52, 0x5e, 0x87, 0x9f, 0xac, 0xa9, 0xa2, 0x9a, 0x93, 0x8e, - 0x94, 0x9e, 0xa2, 0xa4, 0xa2, 0x9d, 0x9c, 0x9e, 0xa2, 0xa8, 0xa8, 0xac, - 0xab, 0xaa, 0xa9, 0xad, 0xb1, 0xb2, 0xb2, 0xb2, 0xae, 0xa1, 0x9d, 0x9d, - 0x9c, 0x8c, 0x76, 0x75, 0x74, 0x6c, 0x64, 0x61, 0x64, 0x65, 0x60, 0x4e, - 0x41, 0x3e, 0x3b, 0x40, 0x6a, 0x8b, 0x94, 0x95, 0x94, 0x90, 0x89, 0x80, - 0x7a, 0x77, 0x71, 0x6a, 0x61, 0x5b, 0x57, 0x50, 0x4a, 0x46, 0x42, 0x41, - 0x41, 0x40, 0x41, 0x40, 0x40, 0x3e, 0x3f, 0x41, 0x41, 0x42, 0x43, 0x44, - 0x43, 0x43, 0x44, 0x45, 0x45, 0x46, 0x47, 0x48, 0x48, 0x47, 0x48, 0x49, - 0x4a, 0x4c, 0x4e, 0x4e, 0x4d, 0x4e, 0x4e, 0x4e, 0x50, 0x51, 0x52, 0x55, - 0x56, 0x58, 0x58, 0x58, 0x58, 0x5b, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x60, - 0x60, 0x61, 0x62, 0x62, 0x64, 0x64, 0x66, 0x67, 0x69, 0x6a, 0x6c, 0x6e, - 0x6e, 0x70, 0x71, 0x70, 0x70, 0x71, 0x72, 0x72, 0x74, 0x73, 0x72, 0x70, - 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x61, 0x5c, 0x56, 0x51, 0x4d, 0x4a, 0x44, - 0x3e, 0x3a, 0x34, 0x29, 0x1e, 0x16, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, 0x12, 0x13, 0x13, 0x13, 0x11, - 0x5b, 0x5d, 0x5e, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x61, 0x60, - 0x61, 0x62, 0x62, 0x61, 0x60, 0x61, 0x61, 0x60, 0x60, 0x60, 0x61, 0x61, - 0x60, 0x61, 0x60, 0x61, 0x62, 0x64, 0x65, 0x64, 0x65, 0x66, 0x66, 0x68, - 0x68, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6b, 0x6b, 0x6b, 0x6a, 0x68, 0x68, - 0x67, 0x65, 0x62, 0x60, 0x5e, 0x5c, 0x59, 0x56, 0x53, 0x53, 0x56, 0x5d, - 0x67, 0x70, 0x75, 0x77, 0x7a, 0x7c, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x7e, - 0x7d, 0x7c, 0x7c, 0x7d, 0x7d, 0x7c, 0x7c, 0x7c, 0x7b, 0x7c, 0x7c, 0x7c, - 0x7c, 0x7d, 0x81, 0x83, 0x84, 0x84, 0x83, 0x82, 0x81, 0x81, 0x82, 0x83, - 0x85, 0x86, 0x87, 0x87, 0x87, 0x89, 0x89, 0x8a, 0x8b, 0x8b, 0x8b, 0x89, - 0x89, 0x88, 0x87, 0x86, 0x83, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7a, 0x7a, - 0x7a, 0x78, 0x79, 0x7a, 0x7c, 0x7f, 0x84, 0x83, 0x8b, 0x99, 0x9c, 0x90, - 0x79, 0x70, 0x6e, 0x72, 0x80, 0x8a, 0x6a, 0x4d, 0x48, 0x4d, 0x41, 0x3f, - 0x69, 0x88, 0xa8, 0xb0, 0xa8, 0xa4, 0xa0, 0x98, 0x8d, 0x8d, 0x92, 0x94, - 0x95, 0x94, 0x95, 0x98, 0x9c, 0xa3, 0xa7, 0xa9, 0xa7, 0xa7, 0xa8, 0xa8, - 0xa6, 0xa3, 0xa2, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa3, 0x99, 0x83, 0x74, - 0x6c, 0x63, 0x5f, 0x5d, 0x5e, 0x5b, 0x4e, 0x38, 0x3f, 0x4c, 0x4c, 0x46, - 0x5e, 0x7d, 0x89, 0x8e, 0x90, 0x8f, 0x88, 0x7d, 0x75, 0x71, 0x6b, 0x64, - 0x5c, 0x56, 0x52, 0x4c, 0x47, 0x43, 0x42, 0x41, 0x41, 0x40, 0x41, 0x40, - 0x40, 0x3f, 0x40, 0x41, 0x42, 0x42, 0x43, 0x44, 0x43, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x48, 0x49, 0x49, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, - 0x4f, 0x4f, 0x4e, 0x4e, 0x50, 0x51, 0x52, 0x54, 0x56, 0x58, 0x58, 0x58, - 0x59, 0x5b, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x61, 0x62, 0x63, - 0x65, 0x67, 0x67, 0x67, 0x68, 0x6a, 0x6c, 0x6d, 0x6e, 0x70, 0x71, 0x71, - 0x71, 0x71, 0x72, 0x72, 0x74, 0x73, 0x72, 0x6f, 0x6e, 0x6c, 0x6a, 0x69, - 0x67, 0x61, 0x5c, 0x56, 0x51, 0x4d, 0x4a, 0x43, 0x3d, 0x39, 0x34, 0x29, - 0x1e, 0x16, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x12, - 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x11, 0x13, 0x5b, 0x5d, 0x5c, 0x5c, - 0x5c, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x62, 0x61, 0x61, 0x61, 0x61, 0x61, - 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x61, 0x61, 0x61, 0x62, 0x61, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x64, 0x65, 0x66, 0x68, 0x68, 0x6a, 0x6b, 0x6a, - 0x6b, 0x6b, 0x6a, 0x6b, 0x6b, 0x6a, 0x69, 0x69, 0x68, 0x66, 0x63, 0x60, - 0x5d, 0x5b, 0x59, 0x57, 0x55, 0x55, 0x58, 0x60, 0x6b, 0x73, 0x77, 0x79, - 0x7b, 0x7f, 0x80, 0x84, 0x85, 0x85, 0x84, 0x82, 0x7f, 0x7d, 0x7c, 0x7b, - 0x7b, 0x7a, 0x79, 0x78, 0x77, 0x79, 0x7b, 0x7c, 0x7c, 0x7d, 0x7f, 0x82, - 0x84, 0x84, 0x84, 0x83, 0x82, 0x81, 0x81, 0x82, 0x85, 0x86, 0x87, 0x87, - 0x87, 0x88, 0x88, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x87, - 0x84, 0x83, 0x82, 0x80, 0x7d, 0x7b, 0x7a, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, - 0x7c, 0x82, 0x89, 0x88, 0x81, 0x81, 0x82, 0x80, 0x77, 0x71, 0x6f, 0x75, - 0x83, 0x85, 0x61, 0x4b, 0x46, 0x45, 0x30, 0x25, 0x40, 0x61, 0x95, 0xb1, - 0xb1, 0xaa, 0xa4, 0x9c, 0x95, 0x8e, 0x88, 0x87, 0x85, 0x84, 0x85, 0x86, - 0x89, 0x8d, 0x8e, 0x8a, 0x88, 0x89, 0x8d, 0x91, 0x91, 0x91, 0x90, 0x90, - 0x95, 0x9a, 0x99, 0x97, 0x94, 0x87, 0x71, 0x61, 0x5b, 0x58, 0x59, 0x59, - 0x52, 0x45, 0x2e, 0x29, 0x45, 0x5f, 0x62, 0x53, 0x53, 0x67, 0x76, 0x80, - 0x86, 0x8a, 0x88, 0x7e, 0x74, 0x6e, 0x65, 0x5c, 0x53, 0x4e, 0x4b, 0x47, - 0x44, 0x42, 0x41, 0x40, 0x40, 0x40, 0x41, 0x41, 0x40, 0x40, 0x42, 0x42, - 0x43, 0x43, 0x43, 0x44, 0x44, 0x44, 0x45, 0x45, 0x46, 0x47, 0x48, 0x48, - 0x48, 0x49, 0x4a, 0x4c, 0x4d, 0x4d, 0x4d, 0x4e, 0x50, 0x50, 0x50, 0x50, - 0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x57, 0x58, 0x59, 0x5c, 0x5c, 0x5e, - 0x5d, 0x5e, 0x5f, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x66, 0x67, 0x67, 0x67, - 0x68, 0x69, 0x6c, 0x6d, 0x6e, 0x70, 0x71, 0x72, 0x71, 0x71, 0x72, 0x73, - 0x73, 0x74, 0x73, 0x71, 0x6e, 0x6c, 0x6b, 0x69, 0x66, 0x61, 0x5b, 0x56, - 0x53, 0x50, 0x4a, 0x42, 0x3b, 0x39, 0x34, 0x2a, 0x1e, 0x16, 0x12, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x12, - 0x11, 0x11, 0x12, 0x12, 0x5a, 0x5b, 0x5b, 0x5c, 0x5d, 0x5f, 0x5f, 0x60, - 0x61, 0x61, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, - 0x61, 0x60, 0x61, 0x62, 0x61, 0x61, 0x61, 0x63, 0x63, 0x63, 0x63, 0x62, - 0x63, 0x64, 0x66, 0x67, 0x69, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, 0x6a, 0x6b, - 0x6b, 0x6a, 0x6a, 0x6a, 0x69, 0x67, 0x63, 0x61, 0x5e, 0x5c, 0x5b, 0x58, - 0x56, 0x57, 0x5b, 0x63, 0x6e, 0x75, 0x79, 0x7b, 0x7d, 0x80, 0x85, 0x87, - 0x88, 0x88, 0x87, 0x85, 0x82, 0x7f, 0x7e, 0x7b, 0x78, 0x78, 0x77, 0x75, - 0x72, 0x75, 0x7a, 0x7d, 0x7d, 0x7d, 0x7f, 0x82, 0x84, 0x85, 0x85, 0x84, - 0x82, 0x83, 0x83, 0x82, 0x83, 0x85, 0x86, 0x86, 0x87, 0x89, 0x89, 0x89, - 0x89, 0x88, 0x88, 0x88, 0x89, 0x89, 0x88, 0x86, 0x85, 0x83, 0x82, 0x81, - 0x7f, 0x7c, 0x7c, 0x7c, 0x7a, 0x7a, 0x7b, 0x7c, 0x7d, 0x80, 0x89, 0x8c, - 0x84, 0x7e, 0x7c, 0x7a, 0x72, 0x6d, 0x6e, 0x77, 0x8a, 0x80, 0x54, 0x44, - 0x40, 0x3a, 0x27, 0x1e, 0x2a, 0x44, 0x79, 0xa4, 0xb0, 0xb0, 0xaa, 0x9d, - 0x8d, 0x84, 0x82, 0x83, 0x87, 0x8e, 0x8f, 0x8f, 0x90, 0x91, 0x8e, 0x88, - 0x81, 0x7c, 0x77, 0x73, 0x72, 0x72, 0x73, 0x76, 0x76, 0x76, 0x75, 0x72, - 0x6b, 0x61, 0x5a, 0x5b, 0x5d, 0x61, 0x61, 0x4e, 0x33, 0x25, 0x22, 0x2b, - 0x47, 0x65, 0x6c, 0x5e, 0x48, 0x4f, 0x66, 0x79, 0x81, 0x86, 0x84, 0x7e, - 0x75, 0x6e, 0x62, 0x55, 0x4b, 0x47, 0x45, 0x43, 0x41, 0x40, 0x3f, 0x40, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x42, 0x43, 0x43, 0x44, - 0x45, 0x45, 0x45, 0x46, 0x47, 0x48, 0x49, 0x49, 0x48, 0x49, 0x4b, 0x4d, - 0x4d, 0x4e, 0x4d, 0x4e, 0x50, 0x50, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, - 0x56, 0x58, 0x58, 0x58, 0x59, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x60, - 0x60, 0x63, 0x63, 0x63, 0x65, 0x67, 0x66, 0x67, 0x68, 0x69, 0x6b, 0x6d, - 0x6e, 0x70, 0x71, 0x72, 0x71, 0x72, 0x73, 0x74, 0x74, 0x74, 0x73, 0x72, - 0x6e, 0x6c, 0x6b, 0x69, 0x66, 0x60, 0x5b, 0x56, 0x53, 0x50, 0x49, 0x41, - 0x3d, 0x3a, 0x34, 0x2a, 0x1d, 0x17, 0x14, 0x11, 0x11, 0x12, 0x12, 0x11, - 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, - 0x5a, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x61, 0x61, 0x61, - 0x61, 0x61, 0x62, 0x63, 0x63, 0x62, 0x62, 0x62, 0x61, 0x61, 0x63, 0x63, - 0x61, 0x61, 0x61, 0x63, 0x63, 0x63, 0x63, 0x64, 0x63, 0x64, 0x66, 0x67, - 0x68, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6a, 0x6b, 0x6b, 0x6a, 0x6a, 0x6a, - 0x69, 0x67, 0x64, 0x60, 0x5e, 0x5d, 0x5c, 0x5a, 0x57, 0x5a, 0x5e, 0x67, - 0x70, 0x77, 0x7b, 0x7d, 0x80, 0x83, 0x86, 0x89, 0x8a, 0x8a, 0x89, 0x87, - 0x84, 0x81, 0x7f, 0x7a, 0x76, 0x76, 0x74, 0x71, 0x6f, 0x73, 0x78, 0x7c, - 0x7e, 0x80, 0x81, 0x83, 0x85, 0x85, 0x85, 0x85, 0x83, 0x84, 0x84, 0x83, - 0x83, 0x84, 0x85, 0x86, 0x87, 0x89, 0x8a, 0x89, 0x89, 0x89, 0x89, 0x88, - 0x8a, 0x89, 0x88, 0x86, 0x84, 0x83, 0x82, 0x81, 0x7f, 0x7d, 0x7d, 0x7d, - 0x7c, 0x79, 0x7b, 0x7b, 0x7c, 0x7d, 0x86, 0x8d, 0x8b, 0x85, 0x80, 0x78, - 0x6b, 0x68, 0x6c, 0x78, 0x8e, 0x7e, 0x4e, 0x3f, 0x3b, 0x34, 0x26, 0x20, - 0x26, 0x39, 0x65, 0x93, 0xa8, 0xae, 0xae, 0xa8, 0x9c, 0x90, 0x86, 0x7d, - 0x72, 0x6d, 0x6e, 0x6f, 0x71, 0x76, 0x7e, 0x80, 0x7c, 0x78, 0x75, 0x74, - 0x78, 0x7a, 0x7c, 0x7e, 0x78, 0x6e, 0x65, 0x60, 0x5b, 0x5b, 0x61, 0x67, - 0x6b, 0x6b, 0x57, 0x32, 0x1f, 0x1d, 0x26, 0x31, 0x47, 0x62, 0x6b, 0x60, - 0x45, 0x46, 0x63, 0x7c, 0x86, 0x86, 0x81, 0x7d, 0x77, 0x70, 0x63, 0x53, - 0x48, 0x44, 0x42, 0x40, 0x3d, 0x3d, 0x3e, 0x40, 0x42, 0x44, 0x46, 0x45, - 0x43, 0x42, 0x40, 0x40, 0x42, 0x43, 0x45, 0x46, 0x46, 0x45, 0x45, 0x45, - 0x48, 0x49, 0x4a, 0x4a, 0x49, 0x49, 0x4c, 0x4d, 0x4e, 0x4f, 0x4f, 0x4f, - 0x50, 0x50, 0x50, 0x51, 0x52, 0x52, 0x53, 0x55, 0x55, 0x58, 0x58, 0x58, - 0x5a, 0x5b, 0x5c, 0x5e, 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x66, 0x67, 0x68, 0x68, 0x6c, 0x6e, 0x6e, 0x70, 0x70, 0x71, - 0x71, 0x71, 0x73, 0x74, 0x74, 0x74, 0x73, 0x72, 0x6e, 0x6d, 0x6b, 0x69, - 0x66, 0x61, 0x5c, 0x56, 0x54, 0x4f, 0x48, 0x41, 0x3d, 0x3a, 0x35, 0x2b, - 0x1e, 0x17, 0x14, 0x12, 0x11, 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x12, 0x13, 0x12, 0x11, 0x11, 0x12, 0x11, 0x5a, 0x5c, 0x5d, 0x5d, - 0x5d, 0x5f, 0x5f, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x62, 0x64, - 0x63, 0x62, 0x62, 0x62, 0x61, 0x62, 0x63, 0x63, 0x62, 0x61, 0x61, 0x63, - 0x63, 0x62, 0x62, 0x64, 0x63, 0x64, 0x66, 0x66, 0x68, 0x69, 0x6a, 0x6a, - 0x6b, 0x6b, 0x6a, 0x6b, 0x6b, 0x6a, 0x6a, 0x6a, 0x69, 0x67, 0x64, 0x61, - 0x5f, 0x5e, 0x5d, 0x59, 0x58, 0x5b, 0x60, 0x68, 0x71, 0x77, 0x7b, 0x7e, - 0x80, 0x85, 0x87, 0x8b, 0x8c, 0x8c, 0x8b, 0x88, 0x86, 0x82, 0x80, 0x7b, - 0x76, 0x74, 0x71, 0x70, 0x6e, 0x72, 0x78, 0x7d, 0x7f, 0x80, 0x82, 0x84, - 0x85, 0x85, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x83, 0x84, 0x84, 0x85, - 0x86, 0x88, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x89, 0x89, 0x88, 0x87, - 0x85, 0x83, 0x82, 0x81, 0x7f, 0x7d, 0x7d, 0x7d, 0x7c, 0x79, 0x7b, 0x7c, - 0x7c, 0x7d, 0x83, 0x8b, 0x8c, 0x87, 0x82, 0x74, 0x65, 0x66, 0x6c, 0x7a, - 0x92, 0x7e, 0x4b, 0x3b, 0x39, 0x35, 0x2a, 0x23, 0x26, 0x34, 0x59, 0x84, - 0x9d, 0xa8, 0xac, 0xac, 0xa4, 0x99, 0x8b, 0x7f, 0x6c, 0x5e, 0x5b, 0x5b, - 0x5e, 0x64, 0x6f, 0x74, 0x72, 0x71, 0x6f, 0x71, 0x74, 0x75, 0x76, 0x78, - 0x75, 0x6d, 0x65, 0x60, 0x5e, 0x61, 0x68, 0x6b, 0x6a, 0x61, 0x47, 0x25, - 0x1b, 0x1e, 0x29, 0x34, 0x49, 0x65, 0x6e, 0x64, 0x47, 0x44, 0x65, 0x7f, - 0x88, 0x88, 0x7f, 0x7a, 0x76, 0x71, 0x65, 0x54, 0x47, 0x42, 0x40, 0x40, - 0x43, 0x4a, 0x4f, 0x52, 0x55, 0x5b, 0x5e, 0x5c, 0x5b, 0x58, 0x4f, 0x45, - 0x42, 0x42, 0x44, 0x45, 0x45, 0x45, 0x44, 0x45, 0x48, 0x49, 0x4a, 0x4a, - 0x49, 0x4a, 0x4d, 0x4e, 0x4e, 0x4f, 0x50, 0x4f, 0x50, 0x50, 0x50, 0x51, - 0x52, 0x53, 0x54, 0x55, 0x55, 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5e, - 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x63, 0x65, 0x66, 0x67, 0x67, 0x67, 0x68, - 0x69, 0x69, 0x6c, 0x6d, 0x6e, 0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, - 0x74, 0x74, 0x73, 0x72, 0x6e, 0x6d, 0x6b, 0x69, 0x66, 0x60, 0x5b, 0x56, - 0x53, 0x4f, 0x48, 0x41, 0x3d, 0x3a, 0x34, 0x2a, 0x1e, 0x18, 0x14, 0x12, - 0x11, 0x12, 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x12, - 0x11, 0x11, 0x12, 0x11, 0x59, 0x5b, 0x5c, 0x5c, 0x5e, 0x5e, 0x60, 0x60, - 0x60, 0x61, 0x61, 0x61, 0x61, 0x62, 0x63, 0x64, 0x64, 0x62, 0x62, 0x62, - 0x61, 0x61, 0x62, 0x62, 0x61, 0x61, 0x61, 0x62, 0x62, 0x61, 0x62, 0x63, - 0x63, 0x64, 0x66, 0x67, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6b, 0x6a, 0x6a, - 0x6a, 0x6b, 0x6b, 0x6a, 0x69, 0x67, 0x64, 0x61, 0x60, 0x5f, 0x5d, 0x59, - 0x58, 0x5c, 0x61, 0x6a, 0x73, 0x77, 0x7c, 0x7e, 0x81, 0x85, 0x87, 0x8b, - 0x8c, 0x8c, 0x8b, 0x89, 0x86, 0x84, 0x81, 0x7c, 0x77, 0x71, 0x6e, 0x6c, - 0x6d, 0x73, 0x79, 0x7e, 0x7f, 0x81, 0x83, 0x85, 0x86, 0x86, 0x85, 0x84, - 0x84, 0x83, 0x83, 0x83, 0x83, 0x84, 0x84, 0x85, 0x86, 0x86, 0x89, 0x89, - 0x89, 0x88, 0x88, 0x88, 0x87, 0x87, 0x88, 0x88, 0x85, 0x83, 0x83, 0x81, - 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x79, 0x7b, 0x7d, 0x7e, 0x7f, 0x7f, 0x82, - 0x84, 0x82, 0x7b, 0x6b, 0x5e, 0x65, 0x6e, 0x7e, 0x98, 0x7c, 0x46, 0x37, - 0x38, 0x40, 0x3a, 0x2b, 0x24, 0x2d, 0x4a, 0x6d, 0x86, 0x98, 0xa0, 0xa7, - 0xa6, 0x9f, 0x96, 0x8c, 0x78, 0x61, 0x56, 0x53, 0x53, 0x55, 0x5b, 0x60, - 0x61, 0x62, 0x62, 0x62, 0x60, 0x5b, 0x5a, 0x5b, 0x62, 0x65, 0x65, 0x65, - 0x65, 0x65, 0x62, 0x5a, 0x51, 0x3e, 0x2f, 0x25, 0x23, 0x24, 0x2b, 0x37, - 0x50, 0x70, 0x7a, 0x70, 0x4e, 0x48, 0x67, 0x7f, 0x88, 0x8a, 0x7d, 0x76, - 0x74, 0x72, 0x68, 0x58, 0x49, 0x43, 0x43, 0x4b, 0x60, 0x74, 0x7e, 0x83, - 0x89, 0x90, 0x92, 0x92, 0x91, 0x8b, 0x79, 0x5a, 0x48, 0x43, 0x43, 0x44, - 0x46, 0x45, 0x45, 0x47, 0x48, 0x48, 0x4a, 0x4a, 0x49, 0x4c, 0x4e, 0x4f, - 0x4f, 0x50, 0x50, 0x50, 0x50, 0x51, 0x52, 0x53, 0x52, 0x53, 0x54, 0x54, - 0x55, 0x57, 0x59, 0x5a, 0x5a, 0x5c, 0x5c, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, - 0x60, 0x62, 0x64, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, 0x6b, 0x6d, 0x6d, - 0x6e, 0x6f, 0x71, 0x71, 0x71, 0x71, 0x72, 0x73, 0x73, 0x73, 0x73, 0x72, - 0x6e, 0x6d, 0x6b, 0x69, 0x65, 0x5f, 0x5a, 0x55, 0x52, 0x4e, 0x47, 0x41, - 0x3b, 0x38, 0x31, 0x29, 0x1e, 0x17, 0x14, 0x12, 0x12, 0x11, 0x11, 0x11, - 0x11, 0x12, 0x12, 0x12, 0x12, 0x11, 0x12, 0x11, 0x12, 0x12, 0x12, 0x11, - 0x59, 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, - 0x61, 0x62, 0x63, 0x64, 0x62, 0x61, 0x61, 0x63, 0x63, 0x62, 0x63, 0x63, - 0x61, 0x60, 0x61, 0x62, 0x63, 0x63, 0x62, 0x64, 0x63, 0x64, 0x66, 0x66, - 0x66, 0x68, 0x69, 0x6a, 0x6b, 0x6b, 0x6a, 0x6a, 0x6a, 0x6b, 0x6a, 0x6a, - 0x69, 0x67, 0x64, 0x61, 0x5f, 0x5e, 0x5c, 0x59, 0x5a, 0x5f, 0x64, 0x6c, - 0x75, 0x79, 0x7e, 0x81, 0x84, 0x88, 0x89, 0x8d, 0x8f, 0x8f, 0x8e, 0x8c, - 0x89, 0x86, 0x83, 0x7e, 0x78, 0x6f, 0x69, 0x68, 0x6c, 0x73, 0x79, 0x7e, - 0x81, 0x81, 0x83, 0x85, 0x87, 0x87, 0x86, 0x85, 0x85, 0x84, 0x84, 0x84, - 0x83, 0x84, 0x84, 0x84, 0x85, 0x85, 0x87, 0x87, 0x87, 0x86, 0x87, 0x86, - 0x87, 0x87, 0x87, 0x88, 0x86, 0x85, 0x83, 0x82, 0x81, 0x7f, 0x7e, 0x7d, - 0x7d, 0x7a, 0x7b, 0x7f, 0x81, 0x81, 0x78, 0x71, 0x6e, 0x6b, 0x65, 0x58, - 0x55, 0x64, 0x74, 0x86, 0x9c, 0x74, 0x3f, 0x35, 0x40, 0x57, 0x56, 0x37, - 0x23, 0x23, 0x35, 0x53, 0x67, 0x78, 0x84, 0x95, 0xa0, 0xa0, 0x9b, 0x93, - 0x81, 0x6a, 0x5d, 0x58, 0x56, 0x54, 0x50, 0x53, 0x58, 0x5c, 0x5f, 0x60, - 0x5e, 0x59, 0x54, 0x4d, 0x47, 0x43, 0x43, 0x46, 0x49, 0x3f, 0x2e, 0x25, - 0x22, 0x24, 0x35, 0x38, 0x31, 0x2c, 0x2c, 0x38, 0x59, 0x77, 0x80, 0x76, - 0x56, 0x4d, 0x65, 0x7b, 0x86, 0x87, 0x77, 0x70, 0x73, 0x73, 0x6d, 0x5f, - 0x56, 0x5b, 0x66, 0x7c, 0x96, 0xa0, 0xa2, 0xa4, 0xa7, 0xa8, 0xaa, 0xaa, - 0xa9, 0xa6, 0x98, 0x7a, 0x5d, 0x4f, 0x45, 0x44, 0x44, 0x45, 0x45, 0x47, - 0x48, 0x49, 0x4a, 0x4a, 0x4a, 0x4d, 0x4d, 0x4e, 0x4f, 0x4f, 0x4f, 0x51, - 0x53, 0x53, 0x53, 0x53, 0x53, 0x54, 0x55, 0x55, 0x55, 0x56, 0x59, 0x5a, - 0x5a, 0x5c, 0x5b, 0x5d, 0x60, 0x60, 0x61, 0x61, 0x62, 0x64, 0x65, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x69, 0x6b, 0x6d, 0x6d, 0x6e, 0x6f, 0x70, 0x71, - 0x71, 0x72, 0x74, 0x72, 0x73, 0x74, 0x73, 0x72, 0x6e, 0x6c, 0x6b, 0x69, - 0x65, 0x5e, 0x59, 0x54, 0x52, 0x4e, 0x47, 0x40, 0x3b, 0x38, 0x31, 0x29, - 0x1e, 0x18, 0x14, 0x12, 0x12, 0x11, 0x12, 0x11, 0x11, 0x11, 0x12, 0x12, - 0x12, 0x11, 0x12, 0x11, 0x12, 0x12, 0x11, 0x12, 0x59, 0x5b, 0x5c, 0x5c, - 0x5d, 0x5e, 0x60, 0x61, 0x61, 0x61, 0x62, 0x61, 0x61, 0x62, 0x63, 0x62, - 0x62, 0x62, 0x62, 0x63, 0x63, 0x63, 0x64, 0x64, 0x63, 0x62, 0x62, 0x63, - 0x63, 0x64, 0x63, 0x64, 0x64, 0x65, 0x66, 0x67, 0x67, 0x68, 0x68, 0x6a, - 0x6b, 0x6b, 0x6a, 0x6b, 0x6b, 0x6a, 0x6a, 0x69, 0x68, 0x66, 0x65, 0x63, - 0x61, 0x60, 0x5d, 0x59, 0x5c, 0x61, 0x66, 0x6e, 0x76, 0x7d, 0x82, 0x84, - 0x86, 0x8a, 0x8b, 0x8f, 0x90, 0x91, 0x90, 0x8e, 0x8b, 0x87, 0x84, 0x80, - 0x79, 0x6e, 0x67, 0x66, 0x6b, 0x73, 0x7a, 0x7e, 0x80, 0x80, 0x81, 0x84, - 0x86, 0x86, 0x86, 0x87, 0x85, 0x84, 0x84, 0x84, 0x85, 0x85, 0x84, 0x83, - 0x84, 0x84, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x87, 0x87, 0x87, 0x88, - 0x87, 0x86, 0x85, 0x84, 0x82, 0x80, 0x7e, 0x7d, 0x7c, 0x7b, 0x7b, 0x81, - 0x86, 0x88, 0x7b, 0x65, 0x55, 0x4b, 0x45, 0x40, 0x4d, 0x62, 0x75, 0x87, - 0x94, 0x66, 0x3d, 0x3a, 0x49, 0x6a, 0x65, 0x3c, 0x25, 0x21, 0x29, 0x42, - 0x53, 0x5c, 0x65, 0x75, 0x88, 0x91, 0x91, 0x8c, 0x7e, 0x69, 0x5d, 0x59, - 0x58, 0x55, 0x4f, 0x4b, 0x4a, 0x4a, 0x4b, 0x4c, 0x4b, 0x47, 0x42, 0x37, - 0x2b, 0x22, 0x1e, 0x1e, 0x1f, 0x1c, 0x16, 0x16, 0x19, 0x23, 0x3a, 0x3d, - 0x35, 0x2f, 0x2d, 0x3a, 0x59, 0x6f, 0x74, 0x6c, 0x58, 0x4f, 0x59, 0x72, - 0x7d, 0x7d, 0x6e, 0x6b, 0x71, 0x73, 0x70, 0x6d, 0x7a, 0x8d, 0x99, 0xa3, - 0xac, 0xac, 0xaa, 0xaa, 0xab, 0xae, 0xab, 0xa9, 0xa4, 0x98, 0x8a, 0x7d, - 0x6f, 0x61, 0x4c, 0x44, 0x44, 0x46, 0x46, 0x47, 0x48, 0x4a, 0x49, 0x49, - 0x4a, 0x4d, 0x4e, 0x4e, 0x4e, 0x4e, 0x4f, 0x51, 0x53, 0x53, 0x53, 0x54, - 0x54, 0x55, 0x56, 0x56, 0x56, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5c, 0x5e, - 0x60, 0x61, 0x61, 0x61, 0x63, 0x65, 0x65, 0x65, 0x66, 0x68, 0x69, 0x69, - 0x6a, 0x6a, 0x6c, 0x6e, 0x6f, 0x70, 0x71, 0x6f, 0x70, 0x71, 0x74, 0x73, - 0x73, 0x74, 0x74, 0x72, 0x6e, 0x6c, 0x6a, 0x68, 0x64, 0x5f, 0x5a, 0x54, - 0x52, 0x4d, 0x46, 0x40, 0x3d, 0x39, 0x33, 0x29, 0x1e, 0x18, 0x15, 0x12, - 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, - 0x11, 0x11, 0x11, 0x12, 0x58, 0x5b, 0x5c, 0x5c, 0x5c, 0x5e, 0x5f, 0x60, - 0x60, 0x60, 0x62, 0x61, 0x62, 0x63, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, - 0x64, 0x63, 0x64, 0x64, 0x64, 0x63, 0x63, 0x62, 0x63, 0x64, 0x64, 0x63, - 0x64, 0x65, 0x66, 0x66, 0x66, 0x68, 0x69, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, - 0x6b, 0x6b, 0x6b, 0x6a, 0x69, 0x67, 0x66, 0x64, 0x62, 0x60, 0x5e, 0x5c, - 0x5f, 0x65, 0x6b, 0x72, 0x79, 0x80, 0x84, 0x85, 0x87, 0x8b, 0x8d, 0x90, - 0x92, 0x92, 0x90, 0x8d, 0x8b, 0x88, 0x86, 0x81, 0x79, 0x6f, 0x68, 0x66, - 0x6a, 0x72, 0x79, 0x7d, 0x7e, 0x7f, 0x80, 0x83, 0x85, 0x86, 0x88, 0x89, - 0x87, 0x85, 0x85, 0x85, 0x86, 0x85, 0x84, 0x83, 0x84, 0x84, 0x85, 0x85, - 0x86, 0x87, 0x87, 0x88, 0x87, 0x87, 0x87, 0x87, 0x87, 0x85, 0x84, 0x84, - 0x82, 0x80, 0x7f, 0x7e, 0x7d, 0x7a, 0x7d, 0x87, 0x8d, 0x91, 0x84, 0x64, - 0x47, 0x34, 0x2d, 0x31, 0x53, 0x67, 0x78, 0x84, 0x8a, 0x6b, 0x4e, 0x47, - 0x53, 0x6d, 0x5e, 0x3a, 0x2e, 0x2c, 0x30, 0x3a, 0x48, 0x4d, 0x50, 0x56, - 0x65, 0x73, 0x73, 0x71, 0x69, 0x5d, 0x57, 0x54, 0x53, 0x50, 0x4f, 0x4c, - 0x4a, 0x49, 0x47, 0x3f, 0x38, 0x34, 0x2f, 0x25, 0x1b, 0x16, 0x16, 0x17, - 0x17, 0x16, 0x14, 0x16, 0x19, 0x1f, 0x2d, 0x34, 0x34, 0x32, 0x30, 0x3d, - 0x56, 0x63, 0x65, 0x61, 0x5a, 0x52, 0x56, 0x6e, 0x7a, 0x78, 0x67, 0x64, - 0x6b, 0x71, 0x78, 0x86, 0x9c, 0xa8, 0xac, 0xb0, 0xb4, 0xb5, 0xb4, 0xb2, - 0xb1, 0xb2, 0xaa, 0xa1, 0x97, 0x83, 0x72, 0x6c, 0x6d, 0x68, 0x56, 0x47, - 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4a, 0x49, 0x4a, 0x4b, 0x4d, 0x4d, 0x4f, - 0x4f, 0x4f, 0x50, 0x50, 0x52, 0x53, 0x53, 0x53, 0x53, 0x55, 0x56, 0x57, - 0x56, 0x57, 0x59, 0x5b, 0x5c, 0x5e, 0x5e, 0x60, 0x60, 0x60, 0x61, 0x62, - 0x63, 0x64, 0x65, 0x64, 0x67, 0x69, 0x6a, 0x6b, 0x6b, 0x6b, 0x6c, 0x6f, - 0x70, 0x71, 0x71, 0x70, 0x71, 0x72, 0x74, 0x75, 0x75, 0x75, 0x74, 0x72, - 0x6e, 0x6b, 0x69, 0x67, 0x63, 0x60, 0x5b, 0x55, 0x52, 0x4e, 0x46, 0x40, - 0x3d, 0x3a, 0x33, 0x29, 0x1e, 0x18, 0x15, 0x13, 0x11, 0x10, 0x10, 0x10, - 0x10, 0x11, 0x11, 0x12, 0x13, 0x12, 0x13, 0x12, 0x11, 0x11, 0x11, 0x12, - 0x59, 0x5b, 0x5c, 0x5c, 0x5c, 0x5d, 0x5f, 0x60, 0x61, 0x61, 0x62, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x65, 0x64, 0x64, 0x65, 0x64, 0x64, 0x65, - 0x65, 0x64, 0x63, 0x62, 0x63, 0x64, 0x64, 0x63, 0x64, 0x65, 0x65, 0x65, - 0x67, 0x69, 0x69, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6b, 0x6c, 0x6b, - 0x6a, 0x68, 0x67, 0x64, 0x61, 0x5f, 0x5f, 0x5e, 0x63, 0x69, 0x6e, 0x76, - 0x7c, 0x81, 0x84, 0x86, 0x87, 0x8b, 0x8d, 0x91, 0x92, 0x93, 0x92, 0x8e, - 0x8c, 0x89, 0x87, 0x83, 0x7b, 0x71, 0x6a, 0x69, 0x6b, 0x72, 0x79, 0x7c, - 0x7d, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x89, 0x88, 0x86, 0x86, 0x86, - 0x86, 0x85, 0x84, 0x83, 0x84, 0x84, 0x85, 0x85, 0x86, 0x87, 0x87, 0x88, - 0x88, 0x88, 0x87, 0x87, 0x87, 0x85, 0x84, 0x84, 0x82, 0x81, 0x80, 0x7f, - 0x7c, 0x7b, 0x80, 0x8a, 0x90, 0x93, 0x88, 0x69, 0x48, 0x2f, 0x28, 0x34, - 0x61, 0x78, 0x85, 0x8b, 0x8d, 0x7b, 0x63, 0x54, 0x57, 0x63, 0x4f, 0x36, - 0x38, 0x3c, 0x3f, 0x40, 0x46, 0x48, 0x48, 0x49, 0x55, 0x63, 0x5f, 0x59, - 0x51, 0x4b, 0x49, 0x47, 0x46, 0x45, 0x45, 0x48, 0x49, 0x48, 0x44, 0x38, - 0x2c, 0x26, 0x22, 0x1a, 0x14, 0x13, 0x15, 0x16, 0x15, 0x14, 0x14, 0x17, - 0x1a, 0x1f, 0x26, 0x2f, 0x33, 0x33, 0x32, 0x3e, 0x55, 0x5f, 0x61, 0x5e, - 0x5a, 0x52, 0x57, 0x6e, 0x78, 0x75, 0x61, 0x5d, 0x65, 0x70, 0x82, 0x95, - 0xa7, 0xb2, 0xb4, 0xb2, 0xb5, 0xba, 0xb9, 0xb7, 0xb3, 0xb1, 0xa7, 0x98, - 0x88, 0x6d, 0x5f, 0x5d, 0x62, 0x63, 0x5c, 0x4a, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x4a, 0x4a, 0x4a, 0x4c, 0x4e, 0x4d, 0x4e, 0x4e, 0x4e, 0x50, 0x50, - 0x51, 0x53, 0x53, 0x53, 0x53, 0x55, 0x56, 0x56, 0x58, 0x58, 0x59, 0x5a, - 0x5b, 0x5e, 0x5e, 0x61, 0x62, 0x62, 0x62, 0x63, 0x64, 0x65, 0x65, 0x64, - 0x67, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6e, 0x6f, 0x6f, 0x70, 0x71, 0x70, - 0x71, 0x71, 0x74, 0x75, 0x75, 0x74, 0x73, 0x72, 0x6e, 0x6b, 0x6a, 0x67, - 0x63, 0x60, 0x5b, 0x56, 0x52, 0x4e, 0x46, 0x40, 0x3b, 0x38, 0x31, 0x28, - 0x1e, 0x18, 0x14, 0x12, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x13, 0x13, 0x13, 0x11, 0x11, 0x11, 0x12, 0x11, 0x58, 0x5b, 0x5b, 0x5c, - 0x5c, 0x5d, 0x5f, 0x61, 0x61, 0x61, 0x63, 0x63, 0x63, 0x64, 0x65, 0x66, - 0x66, 0x66, 0x65, 0x65, 0x66, 0x65, 0x65, 0x65, 0x66, 0x65, 0x62, 0x62, - 0x63, 0x64, 0x64, 0x63, 0x64, 0x64, 0x64, 0x65, 0x67, 0x68, 0x68, 0x69, - 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6b, 0x69, 0x67, 0x64, - 0x61, 0x60, 0x60, 0x5f, 0x64, 0x6c, 0x71, 0x78, 0x7e, 0x82, 0x86, 0x87, - 0x88, 0x8c, 0x8e, 0x92, 0x93, 0x93, 0x93, 0x8f, 0x8c, 0x8a, 0x87, 0x83, - 0x7c, 0x73, 0x6d, 0x6b, 0x6c, 0x72, 0x78, 0x7b, 0x7c, 0x7d, 0x7f, 0x82, - 0x84, 0x86, 0x88, 0x89, 0x88, 0x87, 0x87, 0x86, 0x86, 0x85, 0x84, 0x83, - 0x84, 0x84, 0x86, 0x85, 0x86, 0x87, 0x87, 0x87, 0x88, 0x88, 0x87, 0x87, - 0x87, 0x86, 0x85, 0x84, 0x83, 0x81, 0x80, 0x7f, 0x7d, 0x7c, 0x81, 0x8b, - 0x91, 0x95, 0x8a, 0x6e, 0x4c, 0x30, 0x29, 0x39, 0x6b, 0x83, 0x8c, 0x92, - 0x94, 0x86, 0x6d, 0x5a, 0x57, 0x59, 0x45, 0x35, 0x40, 0x48, 0x4b, 0x49, - 0x4b, 0x4c, 0x4c, 0x4a, 0x54, 0x60, 0x59, 0x51, 0x46, 0x3d, 0x39, 0x37, - 0x36, 0x36, 0x38, 0x3c, 0x40, 0x3f, 0x3a, 0x2e, 0x23, 0x1e, 0x1a, 0x15, - 0x12, 0x13, 0x15, 0x16, 0x15, 0x14, 0x15, 0x19, 0x1b, 0x20, 0x26, 0x2e, - 0x33, 0x34, 0x32, 0x3e, 0x54, 0x5d, 0x5e, 0x5a, 0x59, 0x51, 0x55, 0x6d, - 0x78, 0x75, 0x5f, 0x5a, 0x67, 0x74, 0x89, 0x9b, 0xaa, 0xb5, 0xb7, 0xb4, - 0xb7, 0xbb, 0xbc, 0xbb, 0xb4, 0xad, 0xa1, 0x8e, 0x7c, 0x61, 0x5b, 0x53, - 0x53, 0x56, 0x58, 0x4b, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, - 0x4d, 0x4e, 0x4d, 0x4f, 0x4f, 0x4f, 0x50, 0x50, 0x52, 0x53, 0x53, 0x53, - 0x54, 0x55, 0x56, 0x56, 0x58, 0x58, 0x58, 0x59, 0x5a, 0x5d, 0x5f, 0x61, - 0x62, 0x62, 0x62, 0x63, 0x64, 0x65, 0x65, 0x65, 0x67, 0x69, 0x6a, 0x6b, - 0x6c, 0x6d, 0x6e, 0x6f, 0x6f, 0x70, 0x71, 0x70, 0x71, 0x72, 0x74, 0x75, - 0x75, 0x74, 0x73, 0x71, 0x6e, 0x6c, 0x6a, 0x68, 0x63, 0x60, 0x5b, 0x56, - 0x52, 0x4d, 0x46, 0x41, 0x3a, 0x37, 0x31, 0x28, 0x1e, 0x18, 0x14, 0x12, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x11, - 0x11, 0x11, 0x12, 0x12, 0x58, 0x5a, 0x5c, 0x5c, 0x5d, 0x5d, 0x60, 0x61, - 0x61, 0x62, 0x63, 0x63, 0x64, 0x64, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, - 0x68, 0x68, 0x68, 0x67, 0x65, 0x65, 0x63, 0x62, 0x63, 0x64, 0x64, 0x64, - 0x63, 0x63, 0x63, 0x65, 0x65, 0x67, 0x67, 0x68, 0x6a, 0x6a, 0x6b, 0x6b, - 0x6b, 0x6c, 0x6c, 0x6c, 0x6b, 0x69, 0x67, 0x65, 0x62, 0x61, 0x61, 0x61, - 0x67, 0x70, 0x75, 0x7b, 0x80, 0x85, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x92, - 0x94, 0x94, 0x94, 0x91, 0x8e, 0x8a, 0x87, 0x84, 0x7e, 0x75, 0x70, 0x6f, - 0x6e, 0x72, 0x77, 0x79, 0x7a, 0x7b, 0x7e, 0x81, 0x83, 0x85, 0x88, 0x8a, - 0x8a, 0x89, 0x88, 0x87, 0x86, 0x84, 0x84, 0x85, 0x86, 0x86, 0x86, 0x86, - 0x86, 0x87, 0x86, 0x85, 0x87, 0x87, 0x86, 0x86, 0x85, 0x86, 0x86, 0x86, - 0x83, 0x81, 0x80, 0x7f, 0x7c, 0x7e, 0x83, 0x8c, 0x92, 0x96, 0x8e, 0x75, - 0x53, 0x36, 0x30, 0x43, 0x77, 0x8b, 0x8f, 0x95, 0x9f, 0x96, 0x78, 0x60, - 0x56, 0x4c, 0x3a, 0x3b, 0x4f, 0x59, 0x5c, 0x5b, 0x5d, 0x5e, 0x5c, 0x59, - 0x5d, 0x62, 0x59, 0x50, 0x41, 0x2d, 0x1f, 0x1c, 0x1c, 0x1d, 0x1f, 0x23, - 0x28, 0x28, 0x23, 0x1c, 0x16, 0x15, 0x14, 0x14, 0x13, 0x14, 0x15, 0x15, - 0x15, 0x15, 0x17, 0x1b, 0x1f, 0x24, 0x2a, 0x30, 0x34, 0x35, 0x34, 0x40, - 0x53, 0x5a, 0x59, 0x52, 0x52, 0x4f, 0x52, 0x6a, 0x76, 0x75, 0x5f, 0x5e, - 0x72, 0x82, 0x94, 0xa0, 0xae, 0xb7, 0xb9, 0xba, 0xbe, 0xbd, 0xc3, 0xc1, - 0xb5, 0xa5, 0x92, 0x7b, 0x6a, 0x5a, 0x5b, 0x46, 0x3e, 0x42, 0x4e, 0x4b, - 0x47, 0x48, 0x49, 0x49, 0x4a, 0x4b, 0x4c, 0x4c, 0x4c, 0x4e, 0x4e, 0x50, - 0x50, 0x50, 0x52, 0x52, 0x53, 0x53, 0x53, 0x56, 0x56, 0x56, 0x57, 0x58, - 0x59, 0x58, 0x59, 0x59, 0x5a, 0x5d, 0x5e, 0x61, 0x62, 0x62, 0x62, 0x64, - 0x63, 0x65, 0x65, 0x66, 0x67, 0x69, 0x6a, 0x6b, 0x6c, 0x6e, 0x6e, 0x6f, - 0x71, 0x71, 0x71, 0x72, 0x72, 0x73, 0x74, 0x74, 0x74, 0x73, 0x72, 0x70, - 0x6e, 0x6b, 0x6a, 0x68, 0x65, 0x5f, 0x5a, 0x55, 0x50, 0x4c, 0x48, 0x41, - 0x3a, 0x37, 0x31, 0x29, 0x20, 0x18, 0x14, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x12, 0x11, 0x12, 0x12, 0x11, 0x13, 0x12, 0x12, 0x12, 0x11, 0x13, - 0x59, 0x5b, 0x5b, 0x5c, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x62, 0x63, 0x64, - 0x64, 0x65, 0x67, 0x68, 0x67, 0x66, 0x67, 0x68, 0x69, 0x69, 0x69, 0x69, - 0x68, 0x66, 0x64, 0x63, 0x62, 0x63, 0x64, 0x64, 0x63, 0x63, 0x63, 0x65, - 0x66, 0x66, 0x67, 0x68, 0x6a, 0x6b, 0x6c, 0x6c, 0x6c, 0x6b, 0x6c, 0x6c, - 0x6b, 0x69, 0x67, 0x65, 0x64, 0x63, 0x63, 0x64, 0x6b, 0x73, 0x78, 0x7e, - 0x84, 0x88, 0x8b, 0x8c, 0x8e, 0x90, 0x91, 0x94, 0x95, 0x96, 0x96, 0x93, - 0x8f, 0x8c, 0x89, 0x87, 0x80, 0x79, 0x75, 0x74, 0x73, 0x73, 0x74, 0x76, - 0x77, 0x78, 0x7a, 0x7f, 0x82, 0x85, 0x87, 0x89, 0x8a, 0x89, 0x89, 0x8a, - 0x88, 0x86, 0x86, 0x85, 0x86, 0x86, 0x86, 0x85, 0x86, 0x87, 0x86, 0x85, - 0x87, 0x87, 0x87, 0x86, 0x86, 0x87, 0x86, 0x86, 0x83, 0x82, 0x81, 0x7f, - 0x7e, 0x82, 0x88, 0x90, 0x96, 0x99, 0x94, 0x80, 0x5e, 0x42, 0x3d, 0x52, - 0x81, 0x8a, 0x86, 0x8e, 0xa6, 0xad, 0x88, 0x69, 0x59, 0x49, 0x3d, 0x4e, - 0x65, 0x71, 0x7a, 0x79, 0x75, 0x74, 0x73, 0x6e, 0x69, 0x60, 0x58, 0x52, - 0x46, 0x2d, 0x18, 0x12, 0x11, 0x13, 0x14, 0x14, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x15, 0x16, 0x17, 0x17, 0x19, 0x1b, 0x1a, 0x19, 0x19, 0x1c, 0x20, - 0x24, 0x29, 0x2e, 0x34, 0x37, 0x38, 0x3b, 0x4a, 0x56, 0x58, 0x56, 0x51, - 0x50, 0x4f, 0x54, 0x69, 0x74, 0x76, 0x67, 0x6f, 0x85, 0x92, 0x9c, 0xa7, - 0xb3, 0xb6, 0xba, 0xc2, 0xc6, 0xc7, 0xca, 0xc4, 0xb1, 0x97, 0x79, 0x63, - 0x5d, 0x5a, 0x44, 0x3f, 0x55, 0x61, 0x62, 0x57, 0x4f, 0x4d, 0x4c, 0x4d, - 0x4d, 0x4d, 0x4e, 0x4d, 0x4d, 0x4f, 0x4f, 0x50, 0x50, 0x51, 0x53, 0x53, - 0x54, 0x55, 0x55, 0x56, 0x56, 0x56, 0x56, 0x58, 0x5a, 0x5a, 0x5b, 0x5b, - 0x5c, 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x63, 0x65, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x71, 0x72, - 0x72, 0x73, 0x74, 0x74, 0x74, 0x73, 0x72, 0x70, 0x6e, 0x6b, 0x6a, 0x68, - 0x65, 0x5f, 0x5a, 0x54, 0x50, 0x4b, 0x47, 0x41, 0x3c, 0x38, 0x32, 0x2a, - 0x20, 0x17, 0x13, 0x11, 0x10, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x12, - 0x12, 0x11, 0x13, 0x12, 0x11, 0x12, 0x13, 0x12, 0x59, 0x5c, 0x5c, 0x5c, - 0x5e, 0x5f, 0x5f, 0x61, 0x62, 0x62, 0x62, 0x63, 0x64, 0x65, 0x67, 0x68, - 0x66, 0x66, 0x67, 0x69, 0x69, 0x68, 0x68, 0x68, 0x68, 0x67, 0x66, 0x64, - 0x63, 0x63, 0x64, 0x64, 0x63, 0x63, 0x64, 0x65, 0x65, 0x67, 0x68, 0x69, - 0x6a, 0x6a, 0x6c, 0x6d, 0x6d, 0x6c, 0x6c, 0x6c, 0x6b, 0x6a, 0x68, 0x66, - 0x65, 0x64, 0x64, 0x67, 0x6e, 0x75, 0x7a, 0x81, 0x86, 0x8a, 0x8c, 0x8e, - 0x90, 0x92, 0x92, 0x95, 0x97, 0x97, 0x96, 0x94, 0x90, 0x8d, 0x8b, 0x88, - 0x82, 0x7c, 0x78, 0x77, 0x76, 0x74, 0x74, 0x74, 0x74, 0x75, 0x78, 0x7c, - 0x81, 0x83, 0x85, 0x89, 0x8a, 0x89, 0x8a, 0x8b, 0x8b, 0x88, 0x87, 0x87, - 0x85, 0x84, 0x86, 0x86, 0x86, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x87, - 0x87, 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x82, 0x84, 0x8b, 0x91, 0x97, - 0x9b, 0x9e, 0x9a, 0x88, 0x6a, 0x52, 0x50, 0x64, 0x88, 0x88, 0x84, 0x8d, - 0xa8, 0xba, 0x99, 0x7f, 0x74, 0x6a, 0x61, 0x71, 0x84, 0x92, 0xa1, 0x95, - 0x7a, 0x71, 0x6d, 0x69, 0x60, 0x53, 0x53, 0x54, 0x50, 0x36, 0x1d, 0x14, - 0x15, 0x1b, 0x21, 0x20, 0x20, 0x20, 0x20, 0x21, 0x20, 0x21, 0x21, 0x21, - 0x23, 0x24, 0x25, 0x24, 0x22, 0x21, 0x23, 0x25, 0x27, 0x2b, 0x30, 0x34, - 0x38, 0x3c, 0x47, 0x5b, 0x62, 0x5c, 0x5b, 0x5d, 0x5c, 0x59, 0x60, 0x72, - 0x79, 0x77, 0x74, 0x81, 0x91, 0x9a, 0xa2, 0xaf, 0xb9, 0xbb, 0xc0, 0xca, - 0xd1, 0xd3, 0xca, 0xbd, 0xa4, 0x86, 0x70, 0x65, 0x5d, 0x49, 0x3a, 0x5e, - 0x81, 0x8b, 0x81, 0x64, 0x58, 0x4e, 0x4d, 0x53, 0x54, 0x53, 0x52, 0x50, - 0x4f, 0x50, 0x50, 0x50, 0x50, 0x50, 0x52, 0x54, 0x55, 0x55, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x58, 0x5a, 0x5a, 0x5c, 0x5c, 0x5c, 0x5e, 0x5e, 0x60, - 0x61, 0x62, 0x63, 0x65, 0x66, 0x66, 0x67, 0x68, 0x6a, 0x6b, 0x6d, 0x6e, - 0x6e, 0x70, 0x71, 0x71, 0x71, 0x70, 0x71, 0x73, 0x73, 0x73, 0x73, 0x74, - 0x74, 0x74, 0x74, 0x72, 0x6f, 0x6b, 0x6a, 0x68, 0x64, 0x5e, 0x5a, 0x55, - 0x51, 0x4c, 0x46, 0x40, 0x3c, 0x38, 0x32, 0x2a, 0x20, 0x17, 0x13, 0x11, - 0x10, 0x11, 0x11, 0x11, 0x12, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, - 0x12, 0x12, 0x13, 0x14, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x5f, 0x60, - 0x61, 0x62, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x67, 0x67, 0x68, 0x69, - 0x69, 0x68, 0x67, 0x67, 0x67, 0x67, 0x67, 0x64, 0x64, 0x63, 0x63, 0x63, - 0x63, 0x64, 0x64, 0x65, 0x65, 0x67, 0x68, 0x6a, 0x6b, 0x6a, 0x6b, 0x6c, - 0x6c, 0x6d, 0x6d, 0x6c, 0x6c, 0x6b, 0x68, 0x68, 0x66, 0x65, 0x65, 0x69, - 0x70, 0x78, 0x7c, 0x82, 0x87, 0x8a, 0x8c, 0x8e, 0x91, 0x93, 0x94, 0x96, - 0x97, 0x97, 0x96, 0x94, 0x90, 0x8e, 0x8d, 0x8a, 0x84, 0x7f, 0x7b, 0x78, - 0x77, 0x76, 0x74, 0x74, 0x73, 0x73, 0x75, 0x7a, 0x7e, 0x81, 0x84, 0x87, - 0x89, 0x8a, 0x8b, 0x8c, 0x8b, 0x89, 0x88, 0x87, 0x86, 0x84, 0x86, 0x87, - 0x87, 0x88, 0x87, 0x86, 0x86, 0x86, 0x87, 0x87, 0x87, 0x87, 0x87, 0x86, - 0x84, 0x83, 0x85, 0x88, 0x8e, 0x95, 0x9a, 0x9e, 0xa0, 0xa1, 0x9c, 0x8f, - 0x76, 0x65, 0x65, 0x77, 0x90, 0x8b, 0x89, 0x8f, 0xa5, 0xb4, 0x97, 0x8b, - 0x8f, 0x9c, 0x90, 0x85, 0x92, 0xa3, 0xb5, 0x9d, 0x6e, 0x5f, 0x5b, 0x57, - 0x4e, 0x4a, 0x55, 0x5b, 0x59, 0x3f, 0x24, 0x1c, 0x20, 0x2c, 0x35, 0x33, - 0x32, 0x32, 0x31, 0x30, 0x2e, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, - 0x2c, 0x29, 0x28, 0x2a, 0x2a, 0x2d, 0x2f, 0x33, 0x37, 0x3e, 0x4e, 0x65, - 0x67, 0x61, 0x5f, 0x63, 0x63, 0x5b, 0x63, 0x71, 0x77, 0x76, 0x7a, 0x88, - 0x94, 0x9b, 0xa6, 0xb5, 0xbd, 0xbf, 0xc3, 0xcc, 0xd6, 0xd3, 0xc8, 0xb9, - 0x99, 0x7a, 0x75, 0x70, 0x5e, 0x3c, 0x47, 0x71, 0x96, 0x9a, 0x7e, 0x58, - 0x4f, 0x4a, 0x4d, 0x58, 0x5c, 0x59, 0x58, 0x57, 0x54, 0x51, 0x50, 0x50, - 0x51, 0x51, 0x51, 0x53, 0x54, 0x54, 0x55, 0x54, 0x56, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x5b, 0x5c, 0x5c, 0x5f, 0x5e, 0x60, 0x61, 0x61, 0x62, 0x65, - 0x65, 0x66, 0x67, 0x68, 0x69, 0x6c, 0x6e, 0x6e, 0x6e, 0x6f, 0x71, 0x70, - 0x70, 0x70, 0x72, 0x73, 0x72, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x72, - 0x6f, 0x6b, 0x69, 0x68, 0x64, 0x5f, 0x58, 0x54, 0x51, 0x4c, 0x46, 0x40, - 0x3c, 0x38, 0x32, 0x2b, 0x21, 0x18, 0x14, 0x11, 0x10, 0x11, 0x10, 0x11, - 0x12, 0x11, 0x11, 0x11, 0x12, 0x13, 0x12, 0x13, 0x12, 0x11, 0x12, 0x13, - 0x58, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x5f, 0x60, 0x61, 0x62, 0x62, 0x64, - 0x64, 0x65, 0x66, 0x66, 0x67, 0x67, 0x68, 0x69, 0x69, 0x68, 0x67, 0x67, - 0x67, 0x67, 0x67, 0x65, 0x64, 0x64, 0x64, 0x63, 0x63, 0x64, 0x64, 0x65, - 0x65, 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6b, 0x6c, 0x6c, 0x6e, 0x6d, 0x6c, - 0x6b, 0x6a, 0x68, 0x68, 0x67, 0x66, 0x65, 0x6a, 0x72, 0x7a, 0x7e, 0x83, - 0x87, 0x8a, 0x8d, 0x8f, 0x91, 0x93, 0x94, 0x96, 0x97, 0x97, 0x96, 0x94, - 0x90, 0x8f, 0x8e, 0x8c, 0x86, 0x81, 0x7d, 0x7a, 0x79, 0x78, 0x75, 0x73, - 0x72, 0x72, 0x74, 0x79, 0x7d, 0x7f, 0x83, 0x86, 0x88, 0x8a, 0x8b, 0x8c, - 0x8c, 0x8a, 0x89, 0x88, 0x86, 0x84, 0x85, 0x87, 0x87, 0x87, 0x87, 0x86, - 0x86, 0x86, 0x87, 0x88, 0x87, 0x87, 0x86, 0x85, 0x85, 0x8b, 0x93, 0x98, - 0x9f, 0xa3, 0xa4, 0xa6, 0xa6, 0xa5, 0xa0, 0x96, 0x85, 0x78, 0x78, 0x85, - 0x97, 0x91, 0x8d, 0x91, 0xa1, 0xad, 0x91, 0x89, 0x95, 0xb2, 0xaa, 0x8b, - 0x8f, 0x9f, 0xb5, 0x9d, 0x69, 0x58, 0x54, 0x4e, 0x44, 0x45, 0x56, 0x5f, - 0x5d, 0x44, 0x2c, 0x27, 0x2b, 0x38, 0x40, 0x3f, 0x3e, 0x3e, 0x3c, 0x3a, - 0x38, 0x36, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34, 0x32, 0x2f, 0x2d, 0x2d, - 0x2e, 0x2f, 0x31, 0x34, 0x38, 0x3e, 0x4f, 0x65, 0x67, 0x61, 0x61, 0x67, - 0x69, 0x5f, 0x65, 0x70, 0x74, 0x75, 0x7c, 0x8c, 0x97, 0x9e, 0xa9, 0xb8, - 0xbe, 0xc1, 0xc4, 0xcd, 0xd6, 0xcf, 0xc4, 0xb4, 0x92, 0x74, 0x74, 0x6e, - 0x5a, 0x3b, 0x51, 0x71, 0x8d, 0x8c, 0x6d, 0x52, 0x55, 0x55, 0x56, 0x5c, - 0x61, 0x5f, 0x5d, 0x5b, 0x57, 0x53, 0x50, 0x50, 0x50, 0x51, 0x51, 0x53, - 0x53, 0x53, 0x54, 0x54, 0x56, 0x57, 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5b, - 0x5c, 0x5f, 0x5e, 0x60, 0x60, 0x61, 0x62, 0x65, 0x66, 0x67, 0x67, 0x67, - 0x69, 0x6c, 0x6e, 0x6e, 0x6d, 0x6f, 0x70, 0x70, 0x70, 0x70, 0x72, 0x73, - 0x73, 0x72, 0x72, 0x73, 0x74, 0x74, 0x73, 0x71, 0x6f, 0x6b, 0x69, 0x68, - 0x64, 0x5f, 0x58, 0x54, 0x51, 0x4c, 0x46, 0x40, 0x3b, 0x37, 0x32, 0x2a, - 0x20, 0x18, 0x14, 0x11, 0x10, 0x10, 0x11, 0x11, 0x12, 0x10, 0x11, 0x11, - 0x11, 0x12, 0x12, 0x13, 0x12, 0x11, 0x11, 0x12, 0x57, 0x59, 0x5c, 0x5d, - 0x5e, 0x5f, 0x5f, 0x60, 0x61, 0x61, 0x61, 0x63, 0x64, 0x65, 0x66, 0x66, - 0x66, 0x67, 0x68, 0x69, 0x69, 0x68, 0x68, 0x68, 0x67, 0x68, 0x67, 0x66, - 0x65, 0x65, 0x63, 0x63, 0x64, 0x64, 0x64, 0x65, 0x66, 0x67, 0x68, 0x68, - 0x69, 0x69, 0x6b, 0x6b, 0x6b, 0x6d, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x68, - 0x68, 0x67, 0x66, 0x6b, 0x74, 0x7b, 0x7f, 0x83, 0x88, 0x8a, 0x8e, 0x90, - 0x92, 0x94, 0x95, 0x97, 0x98, 0x97, 0x96, 0x94, 0x91, 0x90, 0x8f, 0x8d, - 0x88, 0x82, 0x7f, 0x7e, 0x7b, 0x7a, 0x76, 0x74, 0x72, 0x70, 0x71, 0x76, - 0x7a, 0x7d, 0x80, 0x85, 0x87, 0x8a, 0x8b, 0x8c, 0x8c, 0x8b, 0x8a, 0x88, - 0x85, 0x83, 0x84, 0x86, 0x86, 0x86, 0x87, 0x86, 0x87, 0x88, 0x87, 0x87, - 0x88, 0x87, 0x86, 0x86, 0x90, 0xa3, 0xb5, 0xbc, 0xc0, 0xbd, 0xb8, 0xb4, - 0xb1, 0xae, 0xa9, 0xa4, 0xa0, 0x98, 0x94, 0x95, 0x9d, 0x97, 0x91, 0x91, - 0x99, 0xa6, 0x8d, 0x7c, 0x8b, 0xb8, 0xbe, 0x94, 0x80, 0x88, 0xa2, 0x97, - 0x6c, 0x5a, 0x53, 0x49, 0x3d, 0x43, 0x58, 0x61, 0x60, 0x4f, 0x3f, 0x3c, - 0x3f, 0x49, 0x4e, 0x4c, 0x4b, 0x4a, 0x48, 0x45, 0x43, 0x40, 0x3f, 0x3d, - 0x3c, 0x3c, 0x3d, 0x3c, 0x3a, 0x35, 0x34, 0x33, 0x33, 0x33, 0x35, 0x37, - 0x39, 0x3c, 0x49, 0x5e, 0x62, 0x5e, 0x60, 0x6a, 0x71, 0x69, 0x69, 0x6f, - 0x71, 0x75, 0x81, 0x94, 0x9d, 0xa4, 0xaf, 0xba, 0xc1, 0xc4, 0xc7, 0xce, - 0xd3, 0xc9, 0xbc, 0xaa, 0x87, 0x74, 0x6c, 0x5a, 0x4b, 0x42, 0x62, 0x6f, - 0x76, 0x6e, 0x55, 0x5c, 0x74, 0x77, 0x70, 0x63, 0x66, 0x68, 0x64, 0x61, - 0x5c, 0x56, 0x51, 0x50, 0x50, 0x51, 0x51, 0x53, 0x53, 0x54, 0x54, 0x54, - 0x56, 0x56, 0x57, 0x58, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5e, 0x5e, 0x60, - 0x60, 0x61, 0x62, 0x65, 0x67, 0x68, 0x68, 0x68, 0x6a, 0x6b, 0x6d, 0x6e, - 0x6d, 0x6e, 0x70, 0x70, 0x6f, 0x6f, 0x71, 0x72, 0x72, 0x72, 0x72, 0x74, - 0x73, 0x73, 0x72, 0x70, 0x6f, 0x6b, 0x69, 0x68, 0x64, 0x5f, 0x58, 0x54, - 0x51, 0x4c, 0x46, 0x40, 0x3b, 0x37, 0x31, 0x29, 0x1e, 0x18, 0x14, 0x11, - 0x10, 0x10, 0x12, 0x12, 0x10, 0x10, 0x10, 0x10, 0x11, 0x12, 0x12, 0x13, - 0x12, 0x11, 0x12, 0x11, 0x57, 0x59, 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, - 0x60, 0x61, 0x61, 0x63, 0x64, 0x65, 0x67, 0x67, 0x67, 0x69, 0x69, 0x6a, - 0x6a, 0x69, 0x69, 0x69, 0x67, 0x67, 0x66, 0x65, 0x65, 0x66, 0x65, 0x63, - 0x63, 0x63, 0x66, 0x66, 0x66, 0x67, 0x68, 0x68, 0x69, 0x6b, 0x6a, 0x6b, - 0x6c, 0x6d, 0x6d, 0x6b, 0x6a, 0x6a, 0x69, 0x69, 0x69, 0x68, 0x68, 0x6e, - 0x77, 0x7d, 0x80, 0x84, 0x89, 0x8d, 0x8f, 0x90, 0x93, 0x95, 0x95, 0x97, - 0x97, 0x97, 0x97, 0x95, 0x93, 0x93, 0x92, 0x8f, 0x8a, 0x86, 0x83, 0x81, - 0x7e, 0x7b, 0x79, 0x75, 0x73, 0x70, 0x6d, 0x72, 0x78, 0x7b, 0x7e, 0x82, - 0x87, 0x89, 0x8a, 0x8a, 0x8b, 0x8c, 0x8b, 0x8a, 0x88, 0x84, 0x83, 0x85, - 0x86, 0x87, 0x86, 0x86, 0x87, 0x88, 0x87, 0x87, 0x87, 0x86, 0x8a, 0x99, - 0xb8, 0xca, 0xd0, 0xd2, 0xd1, 0xd1, 0xce, 0xc8, 0xc2, 0xbb, 0xb5, 0xaf, - 0xac, 0xa8, 0xa6, 0xa2, 0x9b, 0x95, 0x90, 0x8f, 0x95, 0xb0, 0x9e, 0x78, - 0x79, 0xa5, 0xca, 0xb5, 0x8a, 0x7a, 0x80, 0x8f, 0x7b, 0x60, 0x53, 0x4a, - 0x43, 0x4c, 0x5d, 0x63, 0x63, 0x5b, 0x55, 0x54, 0x55, 0x59, 0x5b, 0x58, - 0x58, 0x57, 0x54, 0x51, 0x4e, 0x4b, 0x49, 0x46, 0x44, 0x44, 0x48, 0x48, - 0x44, 0x3e, 0x3b, 0x3a, 0x39, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x41, 0x4f, - 0x57, 0x58, 0x5c, 0x65, 0x70, 0x71, 0x70, 0x72, 0x75, 0x7e, 0x8d, 0x9d, - 0xa7, 0xab, 0xb3, 0xbd, 0xc3, 0xc7, 0xcb, 0xce, 0xd2, 0xc3, 0xac, 0x98, - 0x80, 0x89, 0x70, 0x3e, 0x31, 0x4a, 0x7c, 0x92, 0x8b, 0x81, 0x77, 0x88, - 0x92, 0x8d, 0x82, 0x6e, 0x66, 0x71, 0x70, 0x6c, 0x65, 0x5b, 0x54, 0x51, - 0x50, 0x51, 0x51, 0x52, 0x54, 0x55, 0x56, 0x56, 0x57, 0x58, 0x58, 0x59, - 0x5a, 0x5c, 0x5c, 0x5c, 0x5e, 0x60, 0x60, 0x61, 0x61, 0x63, 0x64, 0x65, - 0x68, 0x69, 0x69, 0x69, 0x6b, 0x6c, 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x70, - 0x70, 0x70, 0x71, 0x71, 0x71, 0x71, 0x72, 0x73, 0x73, 0x72, 0x70, 0x6f, - 0x6d, 0x6a, 0x69, 0x68, 0x64, 0x5e, 0x56, 0x52, 0x50, 0x4c, 0x46, 0x40, - 0x3a, 0x37, 0x33, 0x2b, 0x1e, 0x16, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, - 0x10, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x13, 0x12, 0x11, 0x12, - 0x59, 0x5b, 0x5c, 0x5c, 0x5c, 0x5e, 0x5e, 0x60, 0x60, 0x61, 0x60, 0x63, - 0x64, 0x65, 0x66, 0x66, 0x68, 0x69, 0x6a, 0x6b, 0x6a, 0x6a, 0x6a, 0x6a, - 0x69, 0x68, 0x68, 0x67, 0x67, 0x67, 0x67, 0x64, 0x64, 0x65, 0x66, 0x66, - 0x66, 0x67, 0x68, 0x68, 0x6a, 0x6b, 0x6a, 0x6b, 0x6d, 0x6e, 0x6d, 0x6b, - 0x6b, 0x6b, 0x6a, 0x6b, 0x6a, 0x6a, 0x6b, 0x70, 0x79, 0x7e, 0x81, 0x85, - 0x89, 0x8d, 0x8e, 0x8f, 0x93, 0x95, 0x95, 0x98, 0x98, 0x98, 0x98, 0x96, - 0x95, 0x95, 0x94, 0x90, 0x8b, 0x88, 0x84, 0x82, 0x80, 0x7d, 0x7b, 0x78, - 0x76, 0x72, 0x6f, 0x72, 0x75, 0x78, 0x7b, 0x80, 0x85, 0x88, 0x89, 0x8a, - 0x8b, 0x8c, 0x8b, 0x8a, 0x8a, 0x86, 0x84, 0x83, 0x84, 0x85, 0x86, 0x86, - 0x88, 0x88, 0x87, 0x87, 0x88, 0x93, 0xa3, 0xbe, 0xce, 0xd1, 0xd1, 0xd0, - 0xd1, 0xd3, 0xd6, 0xdb, 0xd9, 0xd1, 0xc2, 0xb8, 0xb2, 0xaf, 0xab, 0xa5, - 0xa0, 0x93, 0x8b, 0x88, 0x8c, 0xad, 0xaf, 0x88, 0x78, 0x86, 0xbe, 0xc9, - 0xad, 0x96, 0x81, 0x83, 0x7a, 0x67, 0x5f, 0x5d, 0x5f, 0x64, 0x68, 0x68, - 0x64, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x61, 0x60, 0x5f, 0x5e, 0x5c, 0x5a, - 0x57, 0x54, 0x51, 0x4f, 0x4c, 0x4c, 0x50, 0x51, 0x4c, 0x48, 0x45, 0x43, - 0x40, 0x3f, 0x3f, 0x3f, 0x40, 0x41, 0x41, 0x46, 0x4d, 0x50, 0x51, 0x54, - 0x60, 0x6e, 0x75, 0x7b, 0x80, 0x89, 0x96, 0xa2, 0xac, 0xb3, 0xba, 0xc0, - 0xc4, 0xc9, 0xcb, 0xcd, 0xcc, 0xba, 0x9c, 0x8d, 0x89, 0x95, 0x76, 0x49, - 0x42, 0x5a, 0x70, 0x71, 0x6c, 0x74, 0x8c, 0x93, 0x8b, 0x88, 0x83, 0x74, - 0x62, 0x72, 0x7a, 0x78, 0x6f, 0x63, 0x5a, 0x54, 0x53, 0x52, 0x52, 0x52, - 0x54, 0x55, 0x55, 0x57, 0x57, 0x59, 0x5a, 0x5a, 0x5c, 0x5e, 0x5e, 0x5e, - 0x5f, 0x5f, 0x5f, 0x61, 0x61, 0x62, 0x63, 0x65, 0x67, 0x69, 0x69, 0x69, - 0x6b, 0x6d, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x70, 0x70, 0x71, 0x71, 0x70, - 0x70, 0x71, 0x72, 0x73, 0x73, 0x72, 0x71, 0x6f, 0x6d, 0x6a, 0x69, 0x67, - 0x63, 0x5d, 0x56, 0x52, 0x50, 0x4c, 0x46, 0x40, 0x3b, 0x38, 0x34, 0x2d, - 0x1f, 0x18, 0x14, 0x12, 0x11, 0x10, 0x11, 0x11, 0x10, 0x10, 0x11, 0x11, - 0x11, 0x13, 0x13, 0x12, 0x13, 0x12, 0x11, 0x12, 0x59, 0x5b, 0x5b, 0x5b, - 0x5b, 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x60, 0x63, 0x64, 0x65, 0x66, 0x68, - 0x69, 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x69, 0x69, 0x69, 0x68, - 0x68, 0x68, 0x67, 0x65, 0x66, 0x66, 0x65, 0x65, 0x65, 0x67, 0x68, 0x68, - 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6e, 0x6e, 0x6d, 0x6d, 0x6c, 0x6c, 0x6c, - 0x6b, 0x6b, 0x6d, 0x72, 0x7a, 0x80, 0x83, 0x86, 0x8a, 0x8d, 0x8f, 0x90, - 0x93, 0x94, 0x95, 0x98, 0x9a, 0x9a, 0x99, 0x97, 0x97, 0x96, 0x95, 0x92, - 0x8c, 0x88, 0x87, 0x85, 0x83, 0x80, 0x7e, 0x7a, 0x78, 0x74, 0x70, 0x72, - 0x74, 0x77, 0x79, 0x7e, 0x84, 0x86, 0x88, 0x8a, 0x8b, 0x8b, 0x8b, 0x8b, - 0x8b, 0x88, 0x86, 0x84, 0x83, 0x84, 0x86, 0x87, 0x87, 0x87, 0x87, 0x87, - 0x90, 0xad, 0xbe, 0xcb, 0xce, 0xd0, 0xcf, 0xcd, 0xcc, 0xcd, 0xd2, 0xd9, - 0xdc, 0xdd, 0xd2, 0xbf, 0xb6, 0xb1, 0xad, 0xa7, 0xa2, 0x96, 0x8b, 0x85, - 0x83, 0x9f, 0xb6, 0xa0, 0x8c, 0x7e, 0xa1, 0xb8, 0xbf, 0xb9, 0x9f, 0x7e, - 0x77, 0x77, 0x76, 0x74, 0x72, 0x73, 0x6f, 0x6c, 0x67, 0x5f, 0x5d, 0x5d, - 0x5e, 0x5f, 0x61, 0x61, 0x61, 0x61, 0x60, 0x5f, 0x5d, 0x5a, 0x58, 0x57, - 0x55, 0x55, 0x56, 0x55, 0x52, 0x51, 0x4e, 0x4b, 0x48, 0x46, 0x45, 0x44, - 0x44, 0x45, 0x46, 0x47, 0x4b, 0x4e, 0x4f, 0x50, 0x5c, 0x70, 0x7b, 0x82, - 0x86, 0x8f, 0x9b, 0xa7, 0xb1, 0xb8, 0xc0, 0xc2, 0xc5, 0xc6, 0xc9, 0xcc, - 0xca, 0xb3, 0x90, 0x88, 0x8e, 0x82, 0x87, 0x81, 0x7f, 0x8a, 0x97, 0x7b, - 0x85, 0x92, 0x9e, 0x9a, 0x86, 0x68, 0x61, 0x67, 0x60, 0x6b, 0x7d, 0x81, - 0x77, 0x69, 0x5f, 0x58, 0x55, 0x54, 0x53, 0x53, 0x54, 0x55, 0x55, 0x57, - 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x61, - 0x62, 0x63, 0x65, 0x66, 0x67, 0x68, 0x69, 0x69, 0x6b, 0x6d, 0x6f, 0x6f, - 0x70, 0x70, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x71, 0x72, 0x73, 0x74, - 0x73, 0x72, 0x71, 0x6f, 0x6e, 0x6b, 0x69, 0x67, 0x62, 0x5e, 0x57, 0x52, - 0x50, 0x4d, 0x47, 0x40, 0x3c, 0x39, 0x35, 0x2d, 0x20, 0x18, 0x14, 0x12, - 0x12, 0x12, 0x12, 0x12, 0x10, 0x11, 0x12, 0x11, 0x11, 0x12, 0x12, 0x13, - 0x12, 0x12, 0x12, 0x11, 0x59, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5f, 0x60, - 0x60, 0x61, 0x61, 0x62, 0x64, 0x65, 0x66, 0x68, 0x69, 0x69, 0x6a, 0x6a, - 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x69, 0x69, 0x68, 0x68, 0x67, 0x66, - 0x66, 0x66, 0x64, 0x64, 0x66, 0x68, 0x68, 0x68, 0x6a, 0x6a, 0x6b, 0x6b, - 0x6c, 0x6d, 0x6e, 0x6d, 0x6d, 0x6d, 0x6c, 0x6c, 0x6b, 0x6b, 0x6d, 0x73, - 0x7b, 0x81, 0x83, 0x87, 0x8a, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x98, - 0x9a, 0x9a, 0x9a, 0x98, 0x98, 0x98, 0x96, 0x92, 0x8c, 0x88, 0x87, 0x86, - 0x84, 0x82, 0x7f, 0x7c, 0x79, 0x76, 0x71, 0x72, 0x74, 0x76, 0x79, 0x7d, - 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8b, 0x8b, 0x8c, 0x8b, 0x88, 0x86, 0x84, - 0x83, 0x84, 0x86, 0x87, 0x87, 0x87, 0x87, 0x89, 0x9b, 0xbc, 0xca, 0xcb, - 0xc8, 0xc8, 0xc6, 0xc5, 0xc4, 0xc4, 0xcd, 0xd5, 0xda, 0xde, 0xda, 0xc7, - 0xbd, 0xb4, 0xb0, 0xaa, 0xa2, 0x98, 0x8f, 0x87, 0x81, 0x96, 0xb7, 0xae, - 0x9c, 0x85, 0x93, 0xa7, 0xc0, 0xc4, 0xac, 0x82, 0x7d, 0x85, 0x85, 0x7e, - 0x7a, 0x78, 0x73, 0x6f, 0x69, 0x60, 0x5c, 0x5b, 0x5c, 0x5e, 0x60, 0x62, - 0x62, 0x62, 0x61, 0x61, 0x61, 0x5f, 0x5e, 0x5e, 0x5d, 0x5b, 0x5b, 0x5b, - 0x58, 0x57, 0x54, 0x51, 0x4f, 0x4c, 0x49, 0x48, 0x49, 0x4a, 0x4b, 0x4c, - 0x4e, 0x50, 0x51, 0x53, 0x61, 0x75, 0x80, 0x87, 0x8b, 0x93, 0x9f, 0xac, - 0xb5, 0xbc, 0xc3, 0xc4, 0xc6, 0xc6, 0xc8, 0xcb, 0xc8, 0xac, 0x8a, 0x87, - 0x95, 0x7b, 0x96, 0xa5, 0xa8, 0xab, 0xae, 0x83, 0x94, 0xa3, 0xa3, 0x94, - 0x7d, 0x5b, 0x55, 0x65, 0x64, 0x67, 0x7d, 0x83, 0x7b, 0x6e, 0x61, 0x5a, - 0x57, 0x55, 0x54, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, - 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x62, 0x63, 0x64, 0x65, 0x66, - 0x66, 0x68, 0x6a, 0x6a, 0x6c, 0x6d, 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x70, - 0x70, 0x70, 0x71, 0x71, 0x72, 0x73, 0x73, 0x74, 0x73, 0x72, 0x72, 0x70, - 0x6e, 0x6a, 0x69, 0x67, 0x62, 0x5e, 0x58, 0x53, 0x51, 0x4d, 0x46, 0x40, - 0x3c, 0x39, 0x35, 0x2c, 0x20, 0x18, 0x15, 0x12, 0x12, 0x12, 0x12, 0x12, - 0x11, 0x11, 0x12, 0x11, 0x11, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x11, - 0x59, 0x5b, 0x5b, 0x5b, 0x5c, 0x5e, 0x5e, 0x5f, 0x60, 0x62, 0x63, 0x63, - 0x64, 0x65, 0x66, 0x67, 0x69, 0x6a, 0x6a, 0x6b, 0x6a, 0x6a, 0x6b, 0x6b, - 0x6b, 0x6b, 0x6a, 0x69, 0x69, 0x69, 0x67, 0x68, 0x67, 0x67, 0x65, 0x65, - 0x67, 0x68, 0x68, 0x68, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6d, 0x6d, 0x6d, - 0x6d, 0x6c, 0x6d, 0x6c, 0x6c, 0x6d, 0x6f, 0x75, 0x7c, 0x81, 0x84, 0x88, - 0x8b, 0x8f, 0x91, 0x92, 0x92, 0x94, 0x96, 0x99, 0x9a, 0x9a, 0x99, 0x99, - 0x99, 0x98, 0x97, 0x92, 0x8e, 0x8b, 0x8a, 0x88, 0x86, 0x83, 0x81, 0x7e, - 0x7c, 0x78, 0x73, 0x73, 0x75, 0x77, 0x79, 0x7d, 0x80, 0x83, 0x85, 0x88, - 0x8a, 0x8b, 0x8c, 0x8c, 0x8c, 0x89, 0x86, 0x85, 0x84, 0x84, 0x85, 0x86, - 0x86, 0x86, 0x86, 0x8e, 0xad, 0xc6, 0xcc, 0xc2, 0xb5, 0xb0, 0xb1, 0xb3, - 0xb5, 0xb8, 0xc5, 0xce, 0xd1, 0xd7, 0xdb, 0xd7, 0xc9, 0xbb, 0xb5, 0xae, - 0xa1, 0x9a, 0x96, 0x90, 0x84, 0x89, 0xaf, 0xb7, 0xae, 0x98, 0x8e, 0x91, - 0xb0, 0xb7, 0xa4, 0x8d, 0x90, 0x95, 0x91, 0x83, 0x7b, 0x7b, 0x79, 0x75, - 0x6d, 0x62, 0x5b, 0x5a, 0x5b, 0x5e, 0x61, 0x63, 0x65, 0x65, 0x63, 0x64, - 0x67, 0x66, 0x65, 0x67, 0x66, 0x62, 0x63, 0x63, 0x61, 0x5e, 0x5a, 0x5a, - 0x58, 0x55, 0x52, 0x52, 0x53, 0x54, 0x56, 0x56, 0x57, 0x57, 0x58, 0x5d, - 0x6e, 0x7e, 0x86, 0x8d, 0x92, 0x9a, 0xa7, 0xb4, 0xbd, 0xc0, 0xc3, 0xc5, - 0xc8, 0xc7, 0xc8, 0xca, 0xc4, 0xa2, 0x81, 0x85, 0x9e, 0x82, 0xa1, 0xbc, - 0xc4, 0xc3, 0xb4, 0x82, 0x97, 0xa5, 0x9e, 0x82, 0x6f, 0x64, 0x64, 0x6c, - 0x66, 0x5c, 0x71, 0x7c, 0x7e, 0x72, 0x66, 0x5e, 0x5a, 0x57, 0x55, 0x54, - 0x54, 0x55, 0x57, 0x57, 0x59, 0x59, 0x5a, 0x5b, 0x5c, 0x5e, 0x5f, 0x5f, - 0x5e, 0x5f, 0x60, 0x63, 0x65, 0x65, 0x65, 0x66, 0x66, 0x68, 0x69, 0x6b, - 0x6d, 0x6e, 0x6f, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x73, - 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x71, 0x6e, 0x6a, 0x68, 0x66, - 0x63, 0x5e, 0x58, 0x54, 0x52, 0x4d, 0x47, 0x3f, 0x3d, 0x3b, 0x36, 0x2c, - 0x21, 0x1a, 0x16, 0x13, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x10, - 0x11, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x11, 0x59, 0x5b, 0x5a, 0x5b, - 0x5c, 0x5d, 0x5d, 0x5f, 0x60, 0x61, 0x63, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x69, 0x69, 0x6a, 0x6b, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6b, 0x69, - 0x68, 0x68, 0x68, 0x68, 0x67, 0x67, 0x68, 0x67, 0x67, 0x68, 0x68, 0x68, - 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6c, - 0x6c, 0x6d, 0x70, 0x77, 0x7f, 0x83, 0x85, 0x89, 0x8d, 0x91, 0x92, 0x92, - 0x93, 0x94, 0x96, 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x98, 0x98, 0x96, 0x92, - 0x8e, 0x8d, 0x8b, 0x89, 0x88, 0x85, 0x83, 0x80, 0x7d, 0x7a, 0x76, 0x77, - 0x77, 0x78, 0x7a, 0x7c, 0x7f, 0x81, 0x83, 0x86, 0x88, 0x8b, 0x8c, 0x8c, - 0x8c, 0x89, 0x87, 0x85, 0x84, 0x84, 0x83, 0x83, 0x85, 0x85, 0x88, 0x9b, - 0xbf, 0xc4, 0xba, 0xa0, 0x86, 0x88, 0x92, 0x9b, 0xa9, 0xbe, 0xbe, 0xbb, - 0xbe, 0xca, 0xd3, 0xd9, 0xd2, 0xc5, 0xbc, 0xb1, 0xa6, 0x99, 0x99, 0x96, - 0x8b, 0x82, 0x94, 0xa9, 0xaf, 0xa7, 0x95, 0x88, 0x86, 0x80, 0x74, 0x82, - 0x96, 0x9b, 0x96, 0x85, 0x75, 0x80, 0x81, 0x7d, 0x73, 0x68, 0x60, 0x5e, - 0x5e, 0x61, 0x64, 0x67, 0x6a, 0x6c, 0x6c, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, - 0x6d, 0x69, 0x68, 0x68, 0x67, 0x65, 0x61, 0x61, 0x61, 0x5e, 0x5b, 0x5e, - 0x61, 0x62, 0x62, 0x61, 0x63, 0x63, 0x64, 0x69, 0x77, 0x83, 0x8a, 0x90, - 0x97, 0xa3, 0xae, 0xba, 0xc1, 0xc4, 0xc6, 0xc8, 0xca, 0xc8, 0xc8, 0xca, - 0xc0, 0x9e, 0x7c, 0x7d, 0x95, 0x7c, 0x73, 0x93, 0xa1, 0xa3, 0xa3, 0x91, - 0xa1, 0xa6, 0x97, 0x87, 0x80, 0x8a, 0x81, 0x5b, 0x34, 0x34, 0x4e, 0x65, - 0x7e, 0x7a, 0x6d, 0x64, 0x5f, 0x59, 0x56, 0x56, 0x55, 0x56, 0x57, 0x57, - 0x59, 0x5a, 0x5a, 0x5b, 0x5d, 0x5f, 0x60, 0x60, 0x5e, 0x5f, 0x60, 0x63, - 0x64, 0x64, 0x64, 0x66, 0x66, 0x68, 0x69, 0x6b, 0x6d, 0x6e, 0x6e, 0x6f, - 0x6f, 0x71, 0x70, 0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x72, - 0x73, 0x73, 0x73, 0x71, 0x6e, 0x6a, 0x68, 0x67, 0x63, 0x5d, 0x57, 0x53, - 0x51, 0x4d, 0x47, 0x40, 0x3d, 0x3b, 0x36, 0x2c, 0x22, 0x1a, 0x16, 0x12, - 0x10, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x10, 0x11, 0x12, 0x11, 0x11, - 0x13, 0x13, 0x13, 0x11, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5c, 0x5c, 0x5d, - 0x5f, 0x5f, 0x62, 0x63, 0x63, 0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6a, - 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6b, 0x6a, 0x69, 0x69, 0x69, 0x67, - 0x66, 0x67, 0x68, 0x67, 0x69, 0x69, 0x69, 0x68, 0x68, 0x6a, 0x6b, 0x6b, - 0x6b, 0x6a, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6e, 0x72, 0x78, - 0x80, 0x84, 0x87, 0x8a, 0x8e, 0x91, 0x92, 0x92, 0x92, 0x93, 0x97, 0x99, - 0x9b, 0x9b, 0x9b, 0x9a, 0x98, 0x97, 0x96, 0x92, 0x8f, 0x8e, 0x8c, 0x8b, - 0x89, 0x87, 0x85, 0x82, 0x80, 0x7c, 0x79, 0x7a, 0x7c, 0x7c, 0x7d, 0x7c, - 0x7f, 0x81, 0x82, 0x84, 0x86, 0x8a, 0x8b, 0x8b, 0x8b, 0x88, 0x87, 0x85, - 0x84, 0x83, 0x81, 0x81, 0x84, 0x87, 0x90, 0xad, 0xbb, 0xa4, 0x8d, 0x71, - 0x61, 0x68, 0x5e, 0x66, 0x91, 0xcb, 0xc9, 0xb5, 0xaf, 0xb7, 0xc9, 0xd1, - 0xd0, 0xcd, 0xc6, 0xb7, 0xab, 0x9f, 0x99, 0x95, 0x8f, 0x8b, 0x80, 0x85, - 0x91, 0xa3, 0x9f, 0x93, 0x87, 0x75, 0x5a, 0x67, 0x85, 0x92, 0x97, 0x97, - 0x83, 0x86, 0x89, 0x86, 0x7b, 0x6e, 0x68, 0x66, 0x65, 0x64, 0x65, 0x68, - 0x6c, 0x6f, 0x73, 0x72, 0x6e, 0x6e, 0x6f, 0x72, 0x72, 0x70, 0x6d, 0x6c, - 0x6a, 0x6a, 0x69, 0x69, 0x69, 0x67, 0x66, 0x6a, 0x6c, 0x6c, 0x6c, 0x6e, - 0x6f, 0x6e, 0x6f, 0x76, 0x82, 0x89, 0x8e, 0x95, 0x9d, 0xa9, 0xb5, 0xbf, - 0xc4, 0xc6, 0xc8, 0xcc, 0xcc, 0xca, 0xcb, 0xcd, 0xbe, 0x96, 0x74, 0x77, - 0x8c, 0x5b, 0x54, 0x76, 0x85, 0x8d, 0x9a, 0x89, 0x99, 0x9b, 0x83, 0x70, - 0x8b, 0x75, 0x59, 0x33, 0x19, 0x1c, 0x2c, 0x47, 0x78, 0x7f, 0x72, 0x69, - 0x63, 0x5c, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x5a, 0x5c, 0x5c, 0x5d, - 0x5f, 0x60, 0x5f, 0x5f, 0x60, 0x60, 0x62, 0x61, 0x62, 0x63, 0x66, 0x68, - 0x68, 0x6a, 0x6b, 0x6c, 0x6c, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x71, - 0x71, 0x71, 0x70, 0x72, 0x71, 0x72, 0x72, 0x72, 0x73, 0x73, 0x72, 0x70, - 0x6f, 0x6b, 0x68, 0x66, 0x62, 0x5d, 0x57, 0x54, 0x51, 0x4d, 0x47, 0x40, - 0x3d, 0x3a, 0x35, 0x2d, 0x24, 0x1c, 0x16, 0x13, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x11, 0x12, 0x12, 0x12, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, - 0x5a, 0x5a, 0x59, 0x59, 0x5a, 0x5b, 0x5d, 0x5e, 0x5f, 0x5f, 0x60, 0x62, - 0x63, 0x64, 0x65, 0x67, 0x68, 0x68, 0x68, 0x69, 0x6b, 0x6b, 0x6b, 0x6b, - 0x6b, 0x6c, 0x6b, 0x6a, 0x6a, 0x6a, 0x6a, 0x68, 0x67, 0x66, 0x67, 0x67, - 0x69, 0x69, 0x68, 0x68, 0x68, 0x69, 0x6a, 0x6b, 0x6a, 0x6a, 0x6b, 0x6d, - 0x6d, 0x6c, 0x6d, 0x6d, 0x6e, 0x70, 0x74, 0x7b, 0x82, 0x85, 0x87, 0x8b, - 0x8e, 0x90, 0x91, 0x91, 0x91, 0x93, 0x97, 0x99, 0x9b, 0x9b, 0x9b, 0x9b, - 0x98, 0x97, 0x96, 0x92, 0x8f, 0x8e, 0x8c, 0x8b, 0x8a, 0x88, 0x86, 0x84, - 0x83, 0x80, 0x7c, 0x7d, 0x7e, 0x7f, 0x7f, 0x7e, 0x7f, 0x81, 0x82, 0x84, - 0x86, 0x89, 0x89, 0x89, 0x89, 0x87, 0x86, 0x85, 0x83, 0x82, 0x81, 0x82, - 0x87, 0x8c, 0x98, 0xb7, 0xaa, 0x8b, 0x86, 0x97, 0x96, 0x8d, 0x74, 0x7b, - 0xad, 0xcd, 0xb6, 0xaf, 0xaf, 0xb0, 0xc0, 0xce, 0xcf, 0xce, 0xc9, 0xbb, - 0xb1, 0xa6, 0x9c, 0x98, 0x95, 0x93, 0x80, 0x72, 0x76, 0x8c, 0xa0, 0xa3, - 0x9f, 0x8f, 0x6d, 0x5e, 0x70, 0x8c, 0x9e, 0xab, 0x9a, 0x8c, 0x8b, 0x8b, - 0x86, 0x74, 0x6a, 0x68, 0x67, 0x67, 0x64, 0x65, 0x6c, 0x71, 0x75, 0x73, - 0x6f, 0x6f, 0x71, 0x75, 0x75, 0x75, 0x74, 0x73, 0x71, 0x72, 0x74, 0x74, - 0x73, 0x72, 0x72, 0x75, 0x77, 0x77, 0x75, 0x75, 0x75, 0x77, 0x79, 0x7e, - 0x88, 0x8c, 0x92, 0x9b, 0xa3, 0xaf, 0xbb, 0xc1, 0xc3, 0xc5, 0xc9, 0xce, - 0xcb, 0xcb, 0xcd, 0xce, 0xbb, 0x8f, 0x6f, 0x77, 0x8f, 0x4c, 0x5a, 0x80, - 0x8f, 0x8e, 0x82, 0x83, 0x8a, 0x84, 0x6e, 0x69, 0x71, 0x4a, 0x37, 0x30, - 0x19, 0x16, 0x21, 0x3a, 0x6c, 0x7f, 0x76, 0x6d, 0x68, 0x60, 0x5a, 0x58, - 0x57, 0x57, 0x57, 0x57, 0x5b, 0x5c, 0x5d, 0x5d, 0x5f, 0x60, 0x5f, 0x5f, - 0x60, 0x60, 0x61, 0x61, 0x61, 0x63, 0x66, 0x68, 0x68, 0x6a, 0x6b, 0x6b, - 0x6c, 0x6e, 0x70, 0x70, 0x70, 0x6f, 0x70, 0x71, 0x71, 0x71, 0x70, 0x71, - 0x70, 0x71, 0x72, 0x72, 0x73, 0x73, 0x72, 0x70, 0x6f, 0x6b, 0x68, 0x66, - 0x62, 0x5d, 0x57, 0x53, 0x50, 0x4c, 0x47, 0x40, 0x3c, 0x39, 0x34, 0x2b, - 0x24, 0x1c, 0x18, 0x13, 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x12, - 0x12, 0x12, 0x11, 0x13, 0x13, 0x13, 0x13, 0x12, 0x5a, 0x5a, 0x5a, 0x5a, - 0x59, 0x5b, 0x5d, 0x5e, 0x5f, 0x5f, 0x60, 0x61, 0x63, 0x64, 0x65, 0x67, - 0x68, 0x68, 0x68, 0x69, 0x6b, 0x6b, 0x6b, 0x6a, 0x6b, 0x6c, 0x6b, 0x6b, - 0x6a, 0x6b, 0x6a, 0x69, 0x68, 0x67, 0x66, 0x67, 0x69, 0x69, 0x69, 0x68, - 0x68, 0x69, 0x6a, 0x6a, 0x6b, 0x6a, 0x6c, 0x6d, 0x6d, 0x6c, 0x6d, 0x6e, - 0x6f, 0x71, 0x75, 0x7d, 0x83, 0x86, 0x88, 0x8b, 0x8e, 0x90, 0x91, 0x91, - 0x91, 0x93, 0x97, 0x99, 0x9b, 0x9b, 0x9a, 0x9b, 0x99, 0x98, 0x96, 0x92, - 0x8f, 0x8e, 0x8c, 0x8b, 0x8a, 0x88, 0x87, 0x85, 0x83, 0x81, 0x7d, 0x7e, - 0x80, 0x81, 0x80, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x86, 0x87, 0x88, 0x88, - 0x88, 0x86, 0x85, 0x84, 0x83, 0x81, 0x81, 0x85, 0x8b, 0x90, 0x9e, 0xba, - 0xaa, 0x94, 0x99, 0xb4, 0xb5, 0xab, 0x96, 0x9d, 0xc2, 0xc3, 0x9c, 0xab, - 0xb4, 0xb1, 0xba, 0xcb, 0xcf, 0xce, 0xcb, 0xc1, 0xb4, 0xa9, 0x9f, 0x9a, - 0x95, 0x94, 0x84, 0x72, 0x70, 0x80, 0x99, 0xa6, 0xa6, 0x9b, 0x7f, 0x66, - 0x6b, 0x8a, 0xa1, 0xb3, 0xa2, 0x8e, 0x8b, 0x8d, 0x8c, 0x74, 0x68, 0x66, - 0x65, 0x64, 0x61, 0x62, 0x69, 0x6e, 0x75, 0x73, 0x70, 0x70, 0x71, 0x76, - 0x78, 0x78, 0x79, 0x78, 0x75, 0x77, 0x7a, 0x7a, 0x79, 0x78, 0x79, 0x7b, - 0x7c, 0x7d, 0x7c, 0x7a, 0x7a, 0x7d, 0x80, 0x84, 0x8c, 0x8f, 0x95, 0x9e, - 0xa6, 0xb1, 0xbb, 0xc1, 0xc3, 0xc4, 0xc8, 0xce, 0xcc, 0xca, 0xcb, 0xcc, - 0xb8, 0x89, 0x6f, 0x77, 0x88, 0x47, 0x61, 0x87, 0x91, 0x89, 0x7e, 0x8c, - 0x88, 0x7c, 0x6a, 0x6b, 0x59, 0x36, 0x2e, 0x34, 0x1c, 0x14, 0x1f, 0x35, - 0x61, 0x7f, 0x79, 0x71, 0x6b, 0x63, 0x5b, 0x59, 0x58, 0x57, 0x56, 0x57, - 0x5b, 0x5c, 0x5d, 0x5d, 0x5f, 0x60, 0x5f, 0x5f, 0x60, 0x60, 0x61, 0x61, - 0x62, 0x63, 0x66, 0x68, 0x68, 0x6a, 0x6b, 0x6b, 0x6c, 0x6e, 0x70, 0x70, - 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x70, 0x70, 0x70, 0x71, 0x72, 0x72, - 0x73, 0x73, 0x72, 0x70, 0x6f, 0x6b, 0x68, 0x66, 0x63, 0x5e, 0x57, 0x53, - 0x50, 0x4c, 0x47, 0x3f, 0x3b, 0x38, 0x35, 0x2b, 0x24, 0x1c, 0x18, 0x13, - 0x11, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x12, 0x12, 0x12, 0x11, 0x13, - 0x13, 0x13, 0x13, 0x12, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5c, 0x5d, - 0x5e, 0x5f, 0x5f, 0x61, 0x63, 0x64, 0x66, 0x66, 0x67, 0x67, 0x68, 0x69, - 0x6b, 0x6c, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c, 0x6b, 0x6b, 0x6c, 0x6b, 0x6a, - 0x68, 0x67, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x69, 0x69, 0x6a, 0x6a, 0x6b, - 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6c, 0x6d, 0x6e, 0x71, 0x74, 0x77, 0x7e, - 0x84, 0x87, 0x89, 0x8c, 0x8e, 0x91, 0x91, 0x91, 0x91, 0x93, 0x96, 0x99, - 0x9a, 0x9b, 0x9b, 0x9b, 0x99, 0x97, 0x95, 0x92, 0x8f, 0x8d, 0x8b, 0x8a, - 0x88, 0x88, 0x88, 0x86, 0x85, 0x82, 0x80, 0x81, 0x82, 0x82, 0x82, 0x81, - 0x81, 0x81, 0x82, 0x84, 0x84, 0x86, 0x86, 0x86, 0x87, 0x86, 0x84, 0x83, - 0x82, 0x80, 0x83, 0x8b, 0x92, 0x98, 0xa4, 0xb5, 0xb1, 0xb2, 0xb9, 0xc5, - 0xc0, 0xc4, 0xc4, 0xc9, 0xce, 0xb0, 0x85, 0xa6, 0xb5, 0xac, 0xb1, 0xc3, - 0xcd, 0xd0, 0xd0, 0xcb, 0xb9, 0xab, 0xa4, 0x9d, 0x92, 0x90, 0x8c, 0x7f, - 0x78, 0x78, 0x88, 0x9d, 0x9c, 0x96, 0x8d, 0x81, 0x77, 0x8e, 0xa4, 0xb8, - 0xa4, 0x92, 0x90, 0x91, 0x8f, 0x6e, 0x60, 0x5f, 0x5f, 0x5e, 0x5b, 0x5b, - 0x60, 0x66, 0x6e, 0x73, 0x70, 0x70, 0x71, 0x76, 0x79, 0x7c, 0x7c, 0x7b, - 0x79, 0x7c, 0x7f, 0x7e, 0x7e, 0x7e, 0x81, 0x81, 0x82, 0x84, 0x85, 0x83, - 0x84, 0x89, 0x8c, 0x8f, 0x91, 0x92, 0x99, 0xa3, 0xaa, 0xb2, 0xba, 0xc1, - 0xc3, 0xc4, 0xc6, 0xcb, 0xcc, 0xca, 0xc8, 0xc6, 0xb1, 0x82, 0x74, 0x78, - 0x76, 0x43, 0x6d, 0x88, 0x87, 0x7d, 0x92, 0xa1, 0x8d, 0x7e, 0x73, 0x68, - 0x3a, 0x2e, 0x32, 0x37, 0x1d, 0x15, 0x1e, 0x2d, 0x4e, 0x7c, 0x7d, 0x75, - 0x6f, 0x68, 0x5e, 0x5a, 0x59, 0x58, 0x58, 0x58, 0x5a, 0x5c, 0x5c, 0x5d, - 0x5f, 0x60, 0x5f, 0x60, 0x61, 0x60, 0x62, 0x61, 0x63, 0x64, 0x66, 0x67, - 0x67, 0x69, 0x6b, 0x6b, 0x6b, 0x6d, 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x71, - 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x71, 0x70, - 0x6f, 0x6b, 0x68, 0x66, 0x63, 0x5e, 0x57, 0x53, 0x51, 0x4b, 0x46, 0x3f, - 0x3b, 0x39, 0x35, 0x2d, 0x24, 0x1b, 0x16, 0x13, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x11, 0x12, 0x12, 0x11, 0x13, 0x13, 0x13, 0x13, 0x12, - 0x59, 0x5a, 0x5a, 0x5a, 0x59, 0x59, 0x5a, 0x5d, 0x5d, 0x5e, 0x60, 0x61, - 0x63, 0x64, 0x65, 0x67, 0x68, 0x68, 0x69, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, - 0x6d, 0x6d, 0x6b, 0x6c, 0x6c, 0x6c, 0x6b, 0x6b, 0x69, 0x69, 0x68, 0x68, - 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6d, 0x6c, 0x6d, 0x6d, - 0x6d, 0x6d, 0x6e, 0x6f, 0x73, 0x76, 0x79, 0x80, 0x85, 0x89, 0x8b, 0x8d, - 0x8e, 0x91, 0x92, 0x92, 0x92, 0x95, 0x96, 0x97, 0x9a, 0x9b, 0x9c, 0x9b, - 0x99, 0x96, 0x94, 0x91, 0x8e, 0x8d, 0x8b, 0x8a, 0x89, 0x89, 0x88, 0x87, - 0x86, 0x83, 0x83, 0x85, 0x85, 0x85, 0x85, 0x84, 0x83, 0x83, 0x84, 0x85, - 0x85, 0x86, 0x86, 0x85, 0x84, 0x84, 0x82, 0x81, 0x7f, 0x80, 0x88, 0x93, - 0x9a, 0xa2, 0xad, 0xab, 0xa1, 0x9c, 0xa4, 0xb9, 0xba, 0xcb, 0xd3, 0xcd, - 0xbe, 0xc0, 0xb4, 0x98, 0x85, 0x79, 0x98, 0xb4, 0xc5, 0xcf, 0xd3, 0xd2, - 0xc0, 0xad, 0xac, 0xa8, 0x9c, 0x97, 0x9a, 0x90, 0x86, 0x7b, 0x7e, 0x84, - 0x7f, 0x7f, 0x88, 0x95, 0x96, 0x9a, 0xa5, 0xb6, 0xad, 0xa0, 0x9b, 0x94, - 0x7e, 0x5a, 0x58, 0x5d, 0x5f, 0x60, 0x5b, 0x58, 0x5a, 0x5c, 0x62, 0x6a, - 0x6c, 0x6d, 0x6f, 0x75, 0x7a, 0x7b, 0x7a, 0x79, 0x7a, 0x7f, 0x81, 0x81, - 0x83, 0x86, 0x87, 0x85, 0x88, 0x8b, 0x8b, 0x89, 0x8e, 0x95, 0x97, 0x97, - 0x93, 0x96, 0x9e, 0xab, 0xb2, 0xb9, 0xbf, 0xc1, 0xc2, 0xc2, 0xc6, 0xc9, - 0xca, 0xcb, 0xca, 0xc4, 0xaa, 0x7a, 0x84, 0x8a, 0x77, 0x46, 0x78, 0x86, - 0x87, 0x8e, 0x9f, 0x9d, 0x86, 0x7e, 0x77, 0x3f, 0x25, 0x33, 0x38, 0x31, - 0x1c, 0x14, 0x19, 0x21, 0x3a, 0x76, 0x7e, 0x77, 0x73, 0x6c, 0x62, 0x5d, - 0x5c, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x5b, 0x5d, 0x5f, 0x61, 0x62, 0x62, - 0x61, 0x61, 0x63, 0x63, 0x64, 0x64, 0x64, 0x66, 0x66, 0x67, 0x68, 0x6a, - 0x6b, 0x6d, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x71, 0x71, 0x72, 0x73, 0x73, - 0x73, 0x73, 0x72, 0x72, 0x73, 0x72, 0x71, 0x70, 0x6e, 0x6a, 0x68, 0x66, - 0x63, 0x5e, 0x57, 0x53, 0x51, 0x4b, 0x45, 0x40, 0x3c, 0x39, 0x35, 0x2f, - 0x24, 0x1c, 0x17, 0x13, 0x11, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, - 0x12, 0x11, 0x13, 0x13, 0x13, 0x13, 0x13, 0x11, 0x58, 0x58, 0x58, 0x59, - 0x59, 0x59, 0x59, 0x5b, 0x5c, 0x5c, 0x5f, 0x61, 0x63, 0x64, 0x65, 0x67, - 0x68, 0x69, 0x69, 0x6b, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6c, 0x6d, - 0x6d, 0x6d, 0x6c, 0x6c, 0x6b, 0x6a, 0x6b, 0x6b, 0x6a, 0x6a, 0x6b, 0x6b, - 0x6c, 0x6c, 0x6c, 0x6d, 0x6c, 0x6d, 0x6d, 0x6e, 0x6e, 0x6f, 0x71, 0x72, - 0x76, 0x78, 0x7c, 0x81, 0x86, 0x89, 0x8b, 0x8d, 0x8e, 0x91, 0x92, 0x93, - 0x93, 0x95, 0x96, 0x97, 0x9a, 0x9c, 0x9c, 0x9a, 0x99, 0x96, 0x94, 0x90, - 0x8d, 0x8c, 0x8d, 0x8c, 0x8b, 0x8a, 0x8a, 0x88, 0x87, 0x85, 0x85, 0x88, - 0x89, 0x89, 0x89, 0x88, 0x87, 0x87, 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, - 0x82, 0x81, 0x7f, 0x7d, 0x7d, 0x83, 0x90, 0x9b, 0xa2, 0xa9, 0xb3, 0xb4, - 0xbf, 0xaf, 0xa2, 0x97, 0x97, 0xc7, 0xd3, 0xc5, 0xab, 0xc2, 0xb8, 0x82, - 0x64, 0x59, 0x78, 0xa4, 0xbf, 0xcc, 0xd2, 0xd4, 0xc4, 0xb1, 0xae, 0xad, - 0xa8, 0x9f, 0x9d, 0x95, 0x8c, 0x7f, 0x7c, 0x7a, 0x80, 0x85, 0x8b, 0x96, - 0x9e, 0xa2, 0xa6, 0xab, 0xa8, 0x9c, 0x8c, 0x7a, 0x5c, 0x52, 0x61, 0x69, - 0x6c, 0x6c, 0x63, 0x5d, 0x5b, 0x5b, 0x5d, 0x63, 0x68, 0x6c, 0x6f, 0x73, - 0x79, 0x79, 0x77, 0x77, 0x79, 0x7e, 0x81, 0x81, 0x81, 0x84, 0x87, 0x85, - 0x8a, 0x8d, 0x90, 0x91, 0x97, 0x9c, 0x9c, 0x99, 0x95, 0x99, 0xa2, 0xac, - 0xb3, 0xbd, 0xc4, 0xc2, 0xc1, 0xc3, 0xc8, 0xc8, 0xc9, 0xd1, 0xd0, 0xc4, - 0xa7, 0x78, 0x8f, 0x94, 0x72, 0x43, 0x76, 0x91, 0x95, 0x8c, 0x79, 0x94, - 0x91, 0x81, 0x5f, 0x28, 0x28, 0x33, 0x33, 0x27, 0x1a, 0x12, 0x12, 0x16, - 0x2c, 0x6b, 0x7e, 0x79, 0x74, 0x6f, 0x66, 0x60, 0x5e, 0x5d, 0x5c, 0x5b, - 0x59, 0x5a, 0x5a, 0x5d, 0x5f, 0x61, 0x62, 0x61, 0x60, 0x60, 0x63, 0x63, - 0x64, 0x65, 0x64, 0x66, 0x66, 0x67, 0x68, 0x6b, 0x6d, 0x6e, 0x6d, 0x6e, - 0x6f, 0x6f, 0x71, 0x71, 0x71, 0x72, 0x73, 0x74, 0x74, 0x73, 0x73, 0x72, - 0x73, 0x74, 0x73, 0x71, 0x6f, 0x6a, 0x68, 0x67, 0x64, 0x5e, 0x57, 0x54, - 0x51, 0x4d, 0x46, 0x40, 0x3d, 0x3a, 0x36, 0x2e, 0x23, 0x1d, 0x18, 0x14, - 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, - 0x12, 0x12, 0x12, 0x12, 0x58, 0x57, 0x59, 0x59, 0x5a, 0x58, 0x59, 0x5a, - 0x5b, 0x5c, 0x5e, 0x61, 0x62, 0x63, 0x65, 0x67, 0x68, 0x68, 0x69, 0x6b, - 0x6c, 0x6c, 0x6d, 0x6e, 0x6d, 0x6d, 0x6b, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, - 0x6c, 0x6c, 0x6c, 0x6c, 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6d, - 0x6c, 0x6d, 0x6d, 0x6e, 0x6f, 0x70, 0x72, 0x74, 0x78, 0x7a, 0x7d, 0x83, - 0x87, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x93, 0x94, 0x95, 0x95, 0x98, - 0x99, 0x9a, 0x9a, 0x99, 0x98, 0x96, 0x94, 0x90, 0x8d, 0x8d, 0x8d, 0x8d, - 0x8c, 0x8c, 0x8c, 0x8a, 0x89, 0x87, 0x88, 0x8a, 0x8b, 0x8b, 0x8b, 0x8b, - 0x8a, 0x8a, 0x88, 0x87, 0x85, 0x82, 0x82, 0x81, 0x80, 0x7e, 0x7b, 0x7b, - 0x7e, 0x87, 0x96, 0xa1, 0xa6, 0xad, 0xb7, 0xb4, 0xc9, 0xbb, 0xb4, 0xb9, - 0xc2, 0xd6, 0xcc, 0xc5, 0xc5, 0xc4, 0x9d, 0x82, 0x78, 0x6e, 0x5b, 0x96, - 0xc3, 0xc7, 0xcc, 0xd4, 0xc6, 0xb6, 0xb0, 0xae, 0xab, 0xa5, 0x9e, 0x98, - 0x90, 0x83, 0x81, 0x84, 0x86, 0x87, 0x8c, 0x92, 0x9b, 0xa3, 0xa4, 0xa1, - 0x97, 0x85, 0x76, 0x6a, 0x5a, 0x5d, 0x6d, 0x74, 0x76, 0x74, 0x69, 0x61, - 0x5e, 0x5c, 0x5d, 0x61, 0x66, 0x6b, 0x6d, 0x72, 0x79, 0x7a, 0x78, 0x77, - 0x77, 0x7c, 0x7f, 0x7f, 0x7f, 0x81, 0x85, 0x81, 0x85, 0x8b, 0x92, 0x96, - 0x9b, 0x9e, 0x9e, 0x9a, 0x98, 0xa0, 0xa6, 0xab, 0xb2, 0xbd, 0xc3, 0xbf, - 0xc1, 0xc5, 0xcb, 0xcc, 0xcb, 0xce, 0xcc, 0xc1, 0xa4, 0x76, 0x8a, 0x8b, - 0x66, 0x48, 0x78, 0x98, 0x9f, 0x99, 0x86, 0x97, 0x99, 0x80, 0x40, 0x1b, - 0x25, 0x30, 0x2f, 0x23, 0x18, 0x11, 0x10, 0x13, 0x25, 0x61, 0x7d, 0x7a, - 0x76, 0x71, 0x69, 0x63, 0x61, 0x5f, 0x5f, 0x5b, 0x59, 0x5a, 0x5b, 0x5c, - 0x5e, 0x60, 0x61, 0x61, 0x5f, 0x60, 0x63, 0x64, 0x64, 0x65, 0x66, 0x65, - 0x67, 0x69, 0x69, 0x6a, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f, 0x70, 0x70, 0x72, - 0x72, 0x72, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, 0x75, 0x74, 0x72, - 0x6f, 0x6c, 0x68, 0x66, 0x63, 0x5d, 0x58, 0x54, 0x51, 0x4d, 0x47, 0x41, - 0x3d, 0x3a, 0x36, 0x2f, 0x25, 0x1c, 0x19, 0x13, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x12, 0x12, 0x12, 0x11, 0x13, 0x13, 0x13, 0x12, 0x12, 0x13, - 0x58, 0x58, 0x59, 0x59, 0x59, 0x58, 0x58, 0x5a, 0x5a, 0x5c, 0x5e, 0x61, - 0x62, 0x63, 0x64, 0x66, 0x68, 0x68, 0x69, 0x6a, 0x6c, 0x6c, 0x6e, 0x6e, - 0x6d, 0x6d, 0x6c, 0x6b, 0x6c, 0x6d, 0x6d, 0x6e, 0x6d, 0x6d, 0x6c, 0x6d, - 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, 0x6d, 0x6c, 0x6d, 0x6d, 0x6e, - 0x6f, 0x71, 0x73, 0x76, 0x79, 0x7c, 0x7e, 0x83, 0x87, 0x8a, 0x8c, 0x8e, - 0x8f, 0x91, 0x91, 0x92, 0x94, 0x96, 0x95, 0x98, 0x99, 0x9a, 0x9a, 0x98, - 0x98, 0x96, 0x94, 0x91, 0x8d, 0x8c, 0x8d, 0x8d, 0x8c, 0x8d, 0x8c, 0x8b, - 0x8a, 0x89, 0x8a, 0x8c, 0x8c, 0x8d, 0x8c, 0x8d, 0x8c, 0x8b, 0x89, 0x87, - 0x86, 0x82, 0x81, 0x81, 0x7f, 0x7c, 0x79, 0x7a, 0x7f, 0x8b, 0x9a, 0xa4, - 0xa9, 0xb0, 0xb9, 0xb3, 0xc9, 0xc0, 0xbd, 0xc9, 0xda, 0xdc, 0xc5, 0xc2, - 0xd2, 0xca, 0xa3, 0x96, 0x8f, 0x7b, 0x57, 0x95, 0xc3, 0xc2, 0xc6, 0xd3, - 0xc9, 0xbb, 0xb2, 0xae, 0xac, 0xa9, 0x9f, 0x9a, 0x94, 0x88, 0x83, 0x88, - 0x88, 0x89, 0x8b, 0x90, 0x97, 0x9f, 0x9f, 0x99, 0x8f, 0x7e, 0x70, 0x68, - 0x5f, 0x62, 0x70, 0x78, 0x7a, 0x78, 0x6d, 0x66, 0x61, 0x5f, 0x5e, 0x61, - 0x63, 0x67, 0x6b, 0x6f, 0x79, 0x7c, 0x7a, 0x78, 0x76, 0x7b, 0x7f, 0x7f, - 0x7e, 0x7f, 0x85, 0x82, 0x84, 0x89, 0x91, 0x96, 0x9c, 0x9d, 0x9c, 0x99, - 0x99, 0xa0, 0xa9, 0xad, 0xb3, 0xbd, 0xc2, 0xbf, 0xc1, 0xc6, 0xcc, 0xce, - 0xca, 0xc9, 0xc6, 0xbd, 0xa0, 0x75, 0x8c, 0x89, 0x5c, 0x48, 0x7a, 0x99, - 0xa0, 0x9a, 0x92, 0x92, 0x8e, 0x71, 0x31, 0x18, 0x21, 0x2e, 0x2e, 0x21, - 0x17, 0x11, 0x10, 0x12, 0x22, 0x5a, 0x7d, 0x7c, 0x77, 0x71, 0x6a, 0x65, - 0x62, 0x61, 0x60, 0x5c, 0x5a, 0x5a, 0x5b, 0x5c, 0x5e, 0x5f, 0x61, 0x61, - 0x60, 0x61, 0x63, 0x64, 0x64, 0x65, 0x66, 0x66, 0x68, 0x6a, 0x6a, 0x6a, - 0x6c, 0x6e, 0x6e, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x72, 0x72, 0x73, 0x73, - 0x73, 0x73, 0x74, 0x74, 0x74, 0x75, 0x74, 0x72, 0x6f, 0x6b, 0x68, 0x65, - 0x62, 0x5d, 0x58, 0x53, 0x50, 0x4d, 0x47, 0x40, 0x3d, 0x3b, 0x36, 0x30, - 0x25, 0x1d, 0x19, 0x14, 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x12, 0x12, - 0x12, 0x11, 0x13, 0x13, 0x13, 0x12, 0x12, 0x13, 0x58, 0x58, 0x59, 0x59, - 0x59, 0x58, 0x58, 0x5a, 0x5a, 0x5c, 0x5e, 0x60, 0x62, 0x63, 0x64, 0x65, - 0x66, 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e, 0x6f, 0x6d, 0x6d, 0x6d, 0x6d, - 0x6d, 0x6e, 0x6e, 0x6e, 0x6d, 0x6d, 0x6c, 0x6c, 0x6b, 0x6c, 0x6c, 0x6b, - 0x6d, 0x6d, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, - 0x7a, 0x7c, 0x7f, 0x82, 0x86, 0x89, 0x8b, 0x8d, 0x8f, 0x90, 0x91, 0x92, - 0x94, 0x95, 0x95, 0x97, 0x99, 0x99, 0x99, 0x98, 0x97, 0x95, 0x93, 0x91, - 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8d, 0x8c, 0x8c, 0x8b, 0x8b, 0x8d, 0x8e, - 0x8f, 0x8f, 0x8e, 0x8f, 0x8e, 0x8c, 0x8b, 0x8a, 0x87, 0x84, 0x81, 0x7f, - 0x7d, 0x78, 0x77, 0x7c, 0x83, 0x91, 0xa0, 0xa8, 0xad, 0xb3, 0xb8, 0xb6, - 0xc7, 0xc4, 0xbf, 0xc1, 0xdb, 0xd8, 0xbf, 0xbd, 0xd0, 0xd1, 0xcb, 0xc3, - 0xb4, 0x8e, 0x73, 0xa3, 0xbd, 0xb9, 0xbc, 0xcb, 0xcd, 0xc1, 0xb3, 0xae, - 0xad, 0xac, 0xa3, 0x9f, 0x99, 0x8d, 0x83, 0x89, 0x8b, 0x8c, 0x8d, 0x8d, - 0x8f, 0x93, 0x93, 0x8f, 0x8d, 0x83, 0x77, 0x70, 0x69, 0x66, 0x6f, 0x76, - 0x79, 0x7a, 0x73, 0x6d, 0x68, 0x65, 0x61, 0x62, 0x61, 0x60, 0x62, 0x69, - 0x75, 0x7c, 0x7d, 0x7a, 0x77, 0x7a, 0x80, 0x7f, 0x7e, 0x7f, 0x85, 0x89, - 0x87, 0x88, 0x8d, 0x93, 0x99, 0x99, 0x98, 0x98, 0x99, 0x9d, 0xa9, 0xb2, - 0xb7, 0xbe, 0xc5, 0xc3, 0xc3, 0xc6, 0xcc, 0xce, 0xc6, 0xc2, 0xbf, 0xb4, - 0x98, 0x77, 0x96, 0x8e, 0x4f, 0x43, 0x7a, 0x98, 0x99, 0x8e, 0x97, 0x85, - 0x68, 0x4c, 0x23, 0x19, 0x1e, 0x2d, 0x2e, 0x20, 0x14, 0x10, 0x10, 0x12, - 0x1e, 0x4d, 0x7c, 0x7e, 0x79, 0x72, 0x6b, 0x68, 0x65, 0x64, 0x62, 0x5e, - 0x5a, 0x5a, 0x5a, 0x5b, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x63, 0x64, - 0x65, 0x66, 0x66, 0x65, 0x66, 0x69, 0x6a, 0x6a, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, 0x73, - 0x74, 0x74, 0x73, 0x72, 0x6d, 0x6b, 0x68, 0x66, 0x62, 0x5d, 0x57, 0x52, - 0x50, 0x4b, 0x46, 0x40, 0x3d, 0x3a, 0x37, 0x2f, 0x25, 0x1d, 0x19, 0x14, - 0x12, 0x11, 0x11, 0x10, 0x10, 0x10, 0x12, 0x12, 0x12, 0x11, 0x12, 0x14, - 0x13, 0x13, 0x12, 0x14, 0x57, 0x57, 0x58, 0x58, 0x57, 0x59, 0x59, 0x5a, - 0x5b, 0x5b, 0x5c, 0x5e, 0x60, 0x62, 0x63, 0x63, 0x65, 0x67, 0x68, 0x69, - 0x6b, 0x6c, 0x6e, 0x6f, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6e, 0x6e, - 0x6d, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6c, 0x6c, - 0x6c, 0x6c, 0x6c, 0x6e, 0x70, 0x72, 0x76, 0x79, 0x7c, 0x7f, 0x80, 0x83, - 0x86, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x91, 0x92, 0x92, 0x93, 0x93, 0x96, - 0x97, 0x98, 0x99, 0x99, 0x97, 0x95, 0x93, 0x90, 0x8e, 0x8c, 0x8c, 0x8c, - 0x8b, 0x8d, 0x8d, 0x8c, 0x8c, 0x8d, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x93, - 0x91, 0x8e, 0x8d, 0x8c, 0x89, 0x85, 0x81, 0x7e, 0x7a, 0x75, 0x79, 0x83, - 0x8c, 0x99, 0xa5, 0xab, 0xb3, 0xb5, 0xb3, 0xb5, 0xba, 0xb7, 0xb8, 0xc1, - 0xd3, 0xd0, 0xce, 0xc7, 0xb6, 0xbc, 0xcd, 0xda, 0xd8, 0xc8, 0xb9, 0xab, - 0xa5, 0xa6, 0xae, 0xc0, 0xd1, 0xc8, 0xb7, 0xaf, 0xa9, 0xaa, 0xab, 0xa4, - 0x9a, 0x8a, 0x84, 0x8c, 0x91, 0x90, 0x8c, 0x8d, 0x8b, 0x8b, 0x8a, 0x88, - 0x88, 0x85, 0x80, 0x7b, 0x74, 0x6f, 0x74, 0x78, 0x7a, 0x7b, 0x77, 0x74, - 0x6e, 0x69, 0x66, 0x65, 0x61, 0x5b, 0x5b, 0x60, 0x6a, 0x72, 0x77, 0x78, - 0x78, 0x7b, 0x81, 0x81, 0x7f, 0x80, 0x85, 0x8a, 0x87, 0x88, 0x8e, 0x94, - 0x97, 0x96, 0x96, 0x98, 0x9b, 0xa0, 0xaa, 0xb3, 0xb8, 0xbf, 0xc7, 0xcb, - 0xc9, 0xc9, 0xc9, 0xc8, 0xc3, 0xc1, 0xbe, 0xb0, 0x8e, 0x77, 0x97, 0x8c, - 0x4b, 0x46, 0x80, 0x8e, 0x8b, 0x85, 0x93, 0x82, 0x49, 0x29, 0x17, 0x15, - 0x1c, 0x26, 0x29, 0x22, 0x15, 0x10, 0x11, 0x12, 0x1a, 0x42, 0x79, 0x7e, - 0x7a, 0x74, 0x6e, 0x6b, 0x69, 0x67, 0x65, 0x60, 0x5d, 0x5b, 0x5b, 0x5c, - 0x5d, 0x5e, 0x5f, 0x61, 0x63, 0x63, 0x63, 0x64, 0x65, 0x65, 0x66, 0x66, - 0x67, 0x69, 0x69, 0x69, 0x6a, 0x6b, 0x6d, 0x6e, 0x70, 0x71, 0x73, 0x72, - 0x72, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, 0x73, 0x74, 0x74, 0x73, 0x72, - 0x6e, 0x6b, 0x68, 0x66, 0x64, 0x5e, 0x58, 0x52, 0x50, 0x4c, 0x45, 0x40, - 0x3c, 0x3a, 0x36, 0x2e, 0x25, 0x1f, 0x1a, 0x14, 0x13, 0x12, 0x11, 0x10, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x13, 0x14, 0x13, 0x13, 0x12, 0x13, - 0x55, 0x56, 0x56, 0x56, 0x56, 0x57, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5e, - 0x60, 0x60, 0x62, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e, - 0x6e, 0x6f, 0x70, 0x70, 0x70, 0x6f, 0x70, 0x6f, 0x6e, 0x6e, 0x6d, 0x6e, - 0x6d, 0x6d, 0x6e, 0x6e, 0x6d, 0x6d, 0x6d, 0x6c, 0x6d, 0x6d, 0x6c, 0x6e, - 0x71, 0x75, 0x77, 0x7a, 0x7d, 0x7f, 0x81, 0x83, 0x86, 0x88, 0x8a, 0x8c, - 0x8d, 0x8f, 0x90, 0x91, 0x91, 0x92, 0x92, 0x94, 0x97, 0x98, 0x99, 0x99, - 0x96, 0x93, 0x91, 0x90, 0x8f, 0x8e, 0x8d, 0x8d, 0x8d, 0x8b, 0x8b, 0x8d, - 0x8d, 0x8e, 0x8f, 0x91, 0x93, 0x93, 0x94, 0x94, 0x92, 0x91, 0x90, 0x8d, - 0x89, 0x85, 0x80, 0x7d, 0x7a, 0x77, 0x7e, 0x8b, 0x94, 0xa0, 0xa8, 0xac, - 0xb5, 0xb7, 0xaf, 0xa2, 0xa4, 0x96, 0x9c, 0xbb, 0xc8, 0xc9, 0xc8, 0xb9, - 0x9c, 0xa7, 0xb0, 0xcd, 0xd9, 0xda, 0xd1, 0x99, 0x70, 0x91, 0xa8, 0xb7, - 0xcc, 0xc9, 0xb9, 0xae, 0xa7, 0xab, 0xb1, 0xa3, 0x97, 0x8d, 0x8b, 0x91, - 0x92, 0x93, 0x95, 0x95, 0x8f, 0x89, 0x86, 0x87, 0x89, 0x87, 0x83, 0x80, - 0x7c, 0x7a, 0x7d, 0x7e, 0x7f, 0x7e, 0x79, 0x79, 0x73, 0x70, 0x70, 0x70, - 0x69, 0x60, 0x5d, 0x5e, 0x64, 0x6d, 0x70, 0x71, 0x74, 0x79, 0x7f, 0x80, - 0x80, 0x83, 0x87, 0x8b, 0x8d, 0x8d, 0x90, 0x95, 0x95, 0x90, 0x90, 0x95, - 0x9b, 0xa3, 0xab, 0xb2, 0xb6, 0xbc, 0xc9, 0xcd, 0xc9, 0xc6, 0xc6, 0xc6, - 0xc1, 0xc1, 0xbe, 0xad, 0x85, 0x82, 0x9d, 0x8d, 0x4b, 0x4c, 0x81, 0x81, - 0x7b, 0x81, 0x93, 0x6f, 0x40, 0x28, 0x17, 0x14, 0x1b, 0x1d, 0x1f, 0x23, - 0x16, 0x10, 0x10, 0x10, 0x17, 0x3c, 0x76, 0x7d, 0x78, 0x73, 0x70, 0x6f, - 0x6d, 0x6c, 0x6a, 0x64, 0x60, 0x5e, 0x5d, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, - 0x61, 0x63, 0x64, 0x66, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6a, - 0x6a, 0x6b, 0x6c, 0x6d, 0x6f, 0x70, 0x71, 0x70, 0x71, 0x72, 0x73, 0x74, - 0x73, 0x73, 0x73, 0x74, 0x74, 0x73, 0x72, 0x70, 0x6e, 0x6b, 0x69, 0x67, - 0x64, 0x5f, 0x59, 0x53, 0x4f, 0x4b, 0x47, 0x41, 0x3c, 0x39, 0x36, 0x2d, - 0x26, 0x1f, 0x1a, 0x14, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x12, 0x12, 0x13, 0x12, 0x13, 0x12, 0x11, 0x12, 0x54, 0x56, 0x55, 0x55, - 0x56, 0x58, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5d, 0x5f, 0x60, 0x62, 0x63, - 0x64, 0x66, 0x68, 0x69, 0x6b, 0x6c, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, - 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x6f, 0x6f, 0x6f, 0x6e, 0x6e, 0x6e, 0x6f, - 0x6e, 0x6e, 0x6d, 0x6d, 0x6d, 0x6d, 0x6c, 0x6d, 0x70, 0x75, 0x78, 0x7b, - 0x7d, 0x7e, 0x81, 0x83, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, - 0x90, 0x91, 0x91, 0x94, 0x97, 0x98, 0x98, 0x99, 0x96, 0x92, 0x91, 0x8f, - 0x90, 0x8f, 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8e, 0x8e, 0x8f, 0x90, 0x93, - 0x95, 0x95, 0x96, 0x96, 0x94, 0x93, 0x92, 0x8e, 0x89, 0x85, 0x80, 0x7e, - 0x7a, 0x7a, 0x85, 0x92, 0x9a, 0xa3, 0xa9, 0xaa, 0xac, 0xae, 0xb1, 0xab, - 0x90, 0x80, 0x89, 0xab, 0xbd, 0xc9, 0xc6, 0xc0, 0xb6, 0xac, 0xae, 0xbf, - 0xc5, 0xc5, 0xd4, 0xa6, 0x5b, 0x81, 0x9e, 0xaf, 0xc6, 0xca, 0xbb, 0xb1, - 0xaa, 0xb3, 0xb3, 0xa7, 0x9d, 0x93, 0x91, 0x96, 0x94, 0x97, 0xa0, 0x9e, - 0x92, 0x89, 0x86, 0x85, 0x86, 0x87, 0x84, 0x82, 0x80, 0x81, 0x80, 0x80, - 0x80, 0x80, 0x7c, 0x78, 0x75, 0x73, 0x75, 0x77, 0x71, 0x6a, 0x65, 0x60, - 0x65, 0x6f, 0x6f, 0x6f, 0x72, 0x76, 0x7d, 0x80, 0x81, 0x84, 0x89, 0x8b, - 0x90, 0x91, 0x91, 0x94, 0x93, 0x8d, 0x8e, 0x94, 0x99, 0xa3, 0xa9, 0xaf, - 0xb5, 0xc0, 0xcb, 0xcb, 0xc6, 0xc4, 0xc3, 0xc3, 0xbe, 0xbd, 0xba, 0xa7, - 0x7d, 0x85, 0xa3, 0x90, 0x4a, 0x4b, 0x74, 0x7c, 0x7b, 0x81, 0x90, 0x4c, - 0x2b, 0x20, 0x1a, 0x18, 0x1d, 0x1b, 0x1d, 0x23, 0x16, 0x11, 0x10, 0x10, - 0x16, 0x39, 0x75, 0x7c, 0x79, 0x74, 0x72, 0x71, 0x70, 0x70, 0x6d, 0x67, - 0x62, 0x5e, 0x5d, 0x5d, 0x5e, 0x5f, 0x61, 0x61, 0x62, 0x63, 0x64, 0x66, - 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, 0x6a, 0x6c, 0x6c, 0x6d, - 0x6e, 0x6f, 0x70, 0x70, 0x71, 0x73, 0x74, 0x74, 0x73, 0x73, 0x72, 0x72, - 0x73, 0x73, 0x72, 0x70, 0x6e, 0x6b, 0x69, 0x68, 0x64, 0x5f, 0x59, 0x53, - 0x4f, 0x4b, 0x47, 0x42, 0x3d, 0x39, 0x36, 0x2e, 0x27, 0x20, 0x1b, 0x14, - 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, - 0x12, 0x11, 0x11, 0x13, 0x55, 0x56, 0x55, 0x55, 0x55, 0x58, 0x59, 0x59, - 0x59, 0x5a, 0x5b, 0x5d, 0x5f, 0x60, 0x62, 0x62, 0x63, 0x65, 0x67, 0x69, - 0x6b, 0x6c, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x70, - 0x70, 0x70, 0x6f, 0x70, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6d, 0x6d, - 0x6d, 0x6d, 0x6c, 0x6d, 0x70, 0x75, 0x79, 0x7c, 0x7d, 0x7e, 0x81, 0x83, - 0x86, 0x88, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x91, 0x94, - 0x96, 0x97, 0x97, 0x97, 0x95, 0x91, 0x91, 0x8f, 0x90, 0x8f, 0x8d, 0x8d, - 0x8d, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x92, 0x95, 0x97, 0x97, 0x96, 0x96, - 0x94, 0x93, 0x92, 0x8e, 0x89, 0x85, 0x81, 0x7e, 0x7b, 0x7c, 0x89, 0x97, - 0x9e, 0xa5, 0xa9, 0xaa, 0xaa, 0xad, 0xb8, 0xb8, 0x99, 0x8c, 0x90, 0xa1, - 0xac, 0xbc, 0xc3, 0xc5, 0xc2, 0xae, 0xb4, 0xbb, 0xb7, 0xb1, 0xcb, 0xad, - 0x5a, 0x73, 0x8f, 0xa8, 0xc2, 0xcb, 0xbf, 0xb6, 0xaf, 0xb6, 0xb3, 0xaa, - 0xa2, 0x97, 0x95, 0x98, 0x95, 0x99, 0xa5, 0xa2, 0x93, 0x88, 0x85, 0x83, - 0x83, 0x87, 0x85, 0x82, 0x81, 0x82, 0x81, 0x80, 0x80, 0x80, 0x7e, 0x79, - 0x77, 0x77, 0x77, 0x79, 0x75, 0x6f, 0x6a, 0x64, 0x67, 0x70, 0x71, 0x70, - 0x72, 0x75, 0x7b, 0x80, 0x82, 0x84, 0x88, 0x8b, 0x91, 0x93, 0x92, 0x94, - 0x92, 0x8e, 0x8f, 0x93, 0x98, 0xa0, 0xa7, 0xae, 0xb6, 0xc1, 0xc9, 0xc9, - 0xc4, 0xc2, 0xbf, 0xbd, 0xba, 0xb9, 0xb6, 0xa5, 0x7c, 0x85, 0xa2, 0x8e, - 0x48, 0x49, 0x6f, 0x7c, 0x7e, 0x82, 0x84, 0x39, 0x20, 0x1d, 0x1c, 0x1d, - 0x22, 0x1e, 0x1e, 0x22, 0x16, 0x11, 0x10, 0x10, 0x16, 0x39, 0x74, 0x7c, - 0x79, 0x73, 0x72, 0x73, 0x72, 0x71, 0x6f, 0x69, 0x63, 0x5f, 0x5d, 0x5d, - 0x5f, 0x60, 0x61, 0x61, 0x62, 0x64, 0x65, 0x67, 0x67, 0x68, 0x69, 0x69, - 0x6b, 0x6b, 0x6b, 0x6b, 0x6a, 0x6c, 0x6c, 0x6d, 0x6e, 0x6e, 0x70, 0x70, - 0x71, 0x72, 0x73, 0x74, 0x73, 0x73, 0x72, 0x72, 0x73, 0x73, 0x72, 0x70, - 0x6e, 0x6b, 0x69, 0x68, 0x64, 0x5f, 0x59, 0x53, 0x50, 0x4c, 0x47, 0x42, - 0x3d, 0x3a, 0x37, 0x2f, 0x27, 0x20, 0x1b, 0x14, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x12, 0x11, 0x11, 0x13, - 0x56, 0x57, 0x56, 0x55, 0x55, 0x57, 0x58, 0x58, 0x58, 0x5a, 0x5b, 0x5d, - 0x5e, 0x60, 0x61, 0x61, 0x63, 0x64, 0x66, 0x69, 0x6b, 0x6c, 0x6d, 0x6d, - 0x6e, 0x6f, 0x70, 0x70, 0x70, 0x70, 0x6f, 0x70, 0x70, 0x70, 0x6f, 0x70, - 0x6f, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6e, 0x6d, 0x6c, 0x6d, 0x6c, 0x6e, - 0x71, 0x75, 0x7a, 0x7c, 0x7d, 0x7f, 0x81, 0x83, 0x85, 0x87, 0x88, 0x8a, - 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x90, 0x91, 0x95, 0x97, 0x97, 0x98, 0x96, - 0x93, 0x91, 0x90, 0x8f, 0x8f, 0x8e, 0x8d, 0x8d, 0x8e, 0x8d, 0x8d, 0x8f, - 0x8f, 0x90, 0x92, 0x96, 0x98, 0x98, 0x96, 0x97, 0x95, 0x93, 0x92, 0x8f, - 0x89, 0x85, 0x82, 0x80, 0x7d, 0x81, 0x8f, 0x9c, 0xa2, 0xa6, 0xa9, 0xab, - 0xaa, 0xac, 0xb4, 0xb5, 0xab, 0xa8, 0xa6, 0x9f, 0x94, 0x9d, 0xb6, 0xbe, - 0xb5, 0xa7, 0xbd, 0xbf, 0xb4, 0xa2, 0xb4, 0xad, 0x64, 0x5a, 0x6e, 0x9c, - 0xb9, 0xca, 0xc5, 0xbe, 0xb5, 0xb8, 0xb6, 0xb0, 0xa8, 0x9d, 0x9b, 0x9a, - 0x97, 0x9c, 0xa9, 0xa6, 0x94, 0x87, 0x82, 0x7f, 0x7e, 0x88, 0x87, 0x83, - 0x81, 0x81, 0x80, 0x80, 0x81, 0x81, 0x7e, 0x7d, 0x7e, 0x7d, 0x7a, 0x7a, - 0x78, 0x74, 0x71, 0x6c, 0x6a, 0x6f, 0x74, 0x75, 0x74, 0x75, 0x7a, 0x80, - 0x82, 0x84, 0x86, 0x8a, 0x90, 0x92, 0x91, 0x91, 0x90, 0x91, 0x91, 0x93, - 0x98, 0x9e, 0xa2, 0xaf, 0xb8, 0xbf, 0xc4, 0xc5, 0xc3, 0xbf, 0xb9, 0xb5, - 0xb5, 0xb5, 0xb3, 0xa5, 0x80, 0x84, 0x9a, 0x87, 0x45, 0x49, 0x72, 0x81, - 0x85, 0x83, 0x64, 0x28, 0x1d, 0x1e, 0x22, 0x23, 0x27, 0x21, 0x21, 0x22, - 0x15, 0x10, 0x10, 0x10, 0x17, 0x3a, 0x73, 0x7c, 0x79, 0x74, 0x74, 0x74, - 0x74, 0x74, 0x73, 0x6d, 0x64, 0x5f, 0x5d, 0x5c, 0x5e, 0x60, 0x61, 0x62, - 0x63, 0x65, 0x66, 0x68, 0x68, 0x69, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6b, - 0x6b, 0x6c, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x70, 0x71, 0x72, 0x73, 0x74, - 0x73, 0x73, 0x72, 0x72, 0x73, 0x72, 0x72, 0x70, 0x6e, 0x6a, 0x69, 0x68, - 0x64, 0x5e, 0x5a, 0x56, 0x52, 0x4d, 0x47, 0x41, 0x3d, 0x3a, 0x37, 0x2e, - 0x26, 0x1e, 0x19, 0x14, 0x11, 0x11, 0x11, 0x12, 0x12, 0x11, 0x11, 0x11, - 0x11, 0x13, 0x13, 0x12, 0x12, 0x12, 0x12, 0x13, 0x57, 0x57, 0x57, 0x57, - 0x57, 0x57, 0x56, 0x56, 0x58, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x61, 0x61, - 0x64, 0x65, 0x66, 0x67, 0x69, 0x6a, 0x6c, 0x6d, 0x6d, 0x6f, 0x70, 0x71, - 0x71, 0x71, 0x70, 0x71, 0x70, 0x70, 0x6f, 0x70, 0x6f, 0x6f, 0x6f, 0x70, - 0x70, 0x6f, 0x6e, 0x6d, 0x6c, 0x6c, 0x6d, 0x70, 0x72, 0x76, 0x7a, 0x7d, - 0x7e, 0x7f, 0x82, 0x83, 0x85, 0x88, 0x8a, 0x8b, 0x8b, 0x8d, 0x8e, 0x8e, - 0x8f, 0x8f, 0x91, 0x94, 0x96, 0x97, 0x98, 0x96, 0x93, 0x92, 0x91, 0x8f, - 0x8d, 0x8c, 0x8d, 0x8d, 0x8e, 0x8d, 0x8d, 0x8f, 0x90, 0x93, 0x94, 0x98, - 0x99, 0x99, 0x99, 0x98, 0x96, 0x93, 0x91, 0x8d, 0x8b, 0x87, 0x85, 0x83, - 0x83, 0x89, 0x96, 0xa2, 0xa6, 0xa7, 0xaa, 0xa9, 0x93, 0x7f, 0x66, 0x58, - 0x53, 0x68, 0x7f, 0x9e, 0xa5, 0x97, 0x95, 0x97, 0x9c, 0xa2, 0xb4, 0xcb, - 0xcc, 0xb6, 0xa7, 0xb7, 0x84, 0x4a, 0x50, 0x8e, 0xab, 0xc5, 0xc5, 0xbf, - 0xb4, 0xb4, 0xb6, 0xb2, 0xae, 0xa5, 0x9f, 0xa0, 0xa3, 0xa6, 0xaa, 0xa8, - 0x9e, 0x8e, 0x86, 0x80, 0x7d, 0x84, 0x88, 0x87, 0x82, 0x82, 0x81, 0x82, - 0x83, 0x85, 0x81, 0x7f, 0x81, 0x83, 0x82, 0x81, 0x7f, 0x7b, 0x78, 0x74, - 0x6f, 0x71, 0x77, 0x79, 0x77, 0x76, 0x79, 0x7e, 0x82, 0x87, 0x8a, 0x8b, - 0x8b, 0x8a, 0x8a, 0x8b, 0x8c, 0x90, 0x92, 0x93, 0x99, 0xa1, 0xa6, 0xac, - 0xb1, 0xba, 0xc0, 0xbf, 0xbf, 0xbc, 0xb5, 0xae, 0xaa, 0xaf, 0xb0, 0xa6, - 0x87, 0x7e, 0x91, 0x7d, 0x3e, 0x47, 0x74, 0x8a, 0x8d, 0x7b, 0x3c, 0x19, - 0x1c, 0x23, 0x28, 0x23, 0x22, 0x23, 0x23, 0x20, 0x14, 0x10, 0x10, 0x11, - 0x17, 0x3c, 0x72, 0x7a, 0x78, 0x74, 0x75, 0x76, 0x79, 0x7a, 0x79, 0x71, - 0x67, 0x61, 0x5f, 0x5c, 0x5f, 0x61, 0x62, 0x63, 0x64, 0x66, 0x67, 0x69, - 0x6a, 0x6a, 0x6a, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, - 0x6f, 0x6f, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x73, 0x74, 0x73, 0x74, - 0x74, 0x73, 0x72, 0x70, 0x6f, 0x6d, 0x6a, 0x68, 0x64, 0x5e, 0x5a, 0x56, - 0x53, 0x4e, 0x47, 0x41, 0x3c, 0x3a, 0x37, 0x2f, 0x26, 0x1e, 0x1a, 0x15, - 0x12, 0x11, 0x12, 0x12, 0x12, 0x11, 0x10, 0x11, 0x11, 0x13, 0x13, 0x13, - 0x12, 0x12, 0x12, 0x11, 0x57, 0x58, 0x58, 0x58, 0x58, 0x57, 0x56, 0x57, - 0x58, 0x5a, 0x5c, 0x5d, 0x5e, 0x5e, 0x60, 0x61, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x6f, 0x70, 0x71, 0x70, 0x71, 0x72, - 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x72, 0x72, 0x71, 0x71, 0x70, 0x6f, - 0x6e, 0x6d, 0x6e, 0x71, 0x73, 0x76, 0x7a, 0x7d, 0x7e, 0x7f, 0x82, 0x83, - 0x85, 0x88, 0x8a, 0x8a, 0x8a, 0x8b, 0x8c, 0x8e, 0x90, 0x90, 0x91, 0x94, - 0x96, 0x96, 0x96, 0x94, 0x94, 0x92, 0x91, 0x90, 0x8d, 0x8d, 0x8e, 0x8e, - 0x8e, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x95, 0x99, 0x9a, 0x9a, 0x99, 0x98, - 0x96, 0x93, 0x90, 0x8d, 0x8b, 0x8a, 0x88, 0x87, 0x87, 0x8f, 0x9c, 0xa5, - 0xa8, 0xaa, 0xa5, 0x88, 0x5b, 0x48, 0x43, 0x3b, 0x36, 0x5e, 0x6a, 0x65, - 0x8d, 0xb0, 0xa0, 0x8b, 0x77, 0x95, 0xb5, 0xcf, 0xd5, 0xc8, 0xb9, 0xb7, - 0x97, 0x4f, 0x4c, 0x8c, 0xa6, 0xc0, 0xc6, 0xc0, 0xb4, 0xae, 0xb1, 0xb5, - 0xb4, 0xad, 0xa4, 0xa5, 0xab, 0xad, 0xac, 0xad, 0xaa, 0x97, 0x8b, 0x80, - 0x7c, 0x7c, 0x83, 0x85, 0x86, 0x83, 0x7e, 0x7f, 0x81, 0x86, 0x85, 0x81, - 0x7f, 0x7f, 0x82, 0x88, 0x89, 0x83, 0x7e, 0x77, 0x70, 0x73, 0x78, 0x7a, - 0x7c, 0x7d, 0x7f, 0x81, 0x85, 0x8c, 0x8e, 0x8d, 0x8a, 0x88, 0x87, 0x89, - 0x8b, 0x8c, 0x8e, 0x93, 0x9e, 0xab, 0xab, 0xaa, 0xae, 0xb8, 0xc0, 0xbc, - 0xb9, 0xb5, 0xaf, 0xa6, 0xa0, 0xa4, 0xa7, 0xa6, 0x8f, 0x78, 0x81, 0x6e, - 0x37, 0x3b, 0x70, 0x82, 0x84, 0x72, 0x2c, 0x15, 0x1d, 0x24, 0x2b, 0x28, - 0x22, 0x22, 0x23, 0x20, 0x14, 0x10, 0x10, 0x11, 0x19, 0x40, 0x70, 0x78, - 0x77, 0x74, 0x74, 0x78, 0x7c, 0x7e, 0x7d, 0x76, 0x6b, 0x63, 0x5f, 0x5d, - 0x5f, 0x61, 0x62, 0x63, 0x65, 0x67, 0x69, 0x6b, 0x6a, 0x6b, 0x6b, 0x6d, - 0x6f, 0x6f, 0x6f, 0x6e, 0x6f, 0x70, 0x71, 0x70, 0x6f, 0x6f, 0x6e, 0x6f, - 0x70, 0x70, 0x70, 0x73, 0x73, 0x74, 0x73, 0x74, 0x73, 0x73, 0x72, 0x70, - 0x6f, 0x6c, 0x69, 0x67, 0x64, 0x5e, 0x59, 0x55, 0x52, 0x4e, 0x47, 0x41, - 0x3d, 0x3b, 0x38, 0x2f, 0x28, 0x20, 0x1b, 0x15, 0x12, 0x11, 0x11, 0x11, - 0x12, 0x11, 0x11, 0x11, 0x12, 0x13, 0x12, 0x13, 0x13, 0x13, 0x12, 0x11, - 0x58, 0x58, 0x58, 0x58, 0x58, 0x57, 0x57, 0x57, 0x58, 0x59, 0x5b, 0x5d, - 0x5d, 0x5e, 0x60, 0x61, 0x64, 0x66, 0x66, 0x66, 0x68, 0x6b, 0x6c, 0x6d, - 0x6e, 0x6f, 0x6f, 0x70, 0x71, 0x70, 0x71, 0x72, 0x72, 0x72, 0x71, 0x71, - 0x71, 0x72, 0x71, 0x71, 0x71, 0x71, 0x70, 0x6f, 0x6e, 0x6d, 0x6e, 0x71, - 0x74, 0x76, 0x7a, 0x7d, 0x7e, 0x7f, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8a, - 0x8a, 0x8c, 0x8c, 0x8d, 0x8f, 0x90, 0x90, 0x94, 0x95, 0x95, 0x96, 0x94, - 0x93, 0x92, 0x91, 0x90, 0x8e, 0x8d, 0x8e, 0x8e, 0x8d, 0x8d, 0x8f, 0x91, - 0x93, 0x94, 0x96, 0x99, 0x9b, 0x9a, 0x99, 0x98, 0x95, 0x92, 0x90, 0x8d, - 0x8b, 0x8b, 0x8a, 0x89, 0x8a, 0x92, 0x9e, 0xa6, 0xa9, 0xaa, 0x9f, 0x6f, - 0x41, 0x35, 0x3f, 0x3f, 0x43, 0x6e, 0x6d, 0x46, 0x6e, 0xaf, 0xac, 0x94, - 0x73, 0x91, 0xb9, 0xcd, 0xcf, 0xc8, 0xc3, 0xb6, 0xa2, 0x5f, 0x58, 0x8c, - 0xa4, 0xbd, 0xc4, 0xc0, 0xb3, 0xab, 0xaf, 0xb7, 0xb7, 0xb0, 0xa9, 0xa7, - 0xac, 0xaf, 0xae, 0xb0, 0xad, 0x9b, 0x8e, 0x7f, 0x7b, 0x7b, 0x81, 0x84, - 0x86, 0x84, 0x7e, 0x7d, 0x80, 0x85, 0x86, 0x82, 0x7e, 0x7e, 0x83, 0x8a, - 0x8c, 0x87, 0x81, 0x79, 0x72, 0x75, 0x79, 0x7b, 0x7f, 0x82, 0x84, 0x86, - 0x89, 0x8f, 0x8f, 0x8d, 0x89, 0x88, 0x87, 0x89, 0x8c, 0x8c, 0x8e, 0x95, - 0xa1, 0xae, 0xac, 0xaa, 0xad, 0xb6, 0xbf, 0xbc, 0xb6, 0xb2, 0xac, 0xa1, - 0x9c, 0x9f, 0xa3, 0xa5, 0x91, 0x76, 0x7c, 0x6a, 0x36, 0x38, 0x6f, 0x7d, - 0x7c, 0x6c, 0x28, 0x15, 0x1d, 0x25, 0x2a, 0x2b, 0x25, 0x24, 0x23, 0x1f, - 0x14, 0x10, 0x11, 0x11, 0x1a, 0x43, 0x70, 0x77, 0x76, 0x74, 0x74, 0x78, - 0x7d, 0x7f, 0x7f, 0x79, 0x6d, 0x64, 0x60, 0x5e, 0x60, 0x62, 0x63, 0x64, - 0x66, 0x68, 0x6b, 0x6c, 0x6b, 0x6b, 0x6b, 0x6f, 0x70, 0x71, 0x71, 0x70, - 0x70, 0x71, 0x72, 0x71, 0x6f, 0x6e, 0x6e, 0x70, 0x70, 0x71, 0x70, 0x72, - 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x72, 0x70, 0x6f, 0x6c, 0x69, 0x67, - 0x64, 0x5e, 0x59, 0x55, 0x52, 0x4e, 0x47, 0x41, 0x3e, 0x3c, 0x37, 0x30, - 0x28, 0x21, 0x1c, 0x15, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x13, 0x13, 0x13, 0x14, 0x14, 0x13, 0x13, 0x11, 0x59, 0x58, 0x58, 0x58, - 0x58, 0x57, 0x57, 0x57, 0x58, 0x59, 0x5b, 0x5d, 0x5d, 0x5e, 0x5f, 0x61, - 0x63, 0x65, 0x66, 0x66, 0x68, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x6f, 0x71, - 0x71, 0x70, 0x71, 0x72, 0x72, 0x71, 0x71, 0x71, 0x70, 0x71, 0x71, 0x71, - 0x72, 0x71, 0x70, 0x6f, 0x6f, 0x6d, 0x6e, 0x72, 0x74, 0x77, 0x7a, 0x7d, - 0x7e, 0x7f, 0x82, 0x84, 0x85, 0x88, 0x89, 0x8a, 0x89, 0x8b, 0x8c, 0x8d, - 0x8f, 0x90, 0x91, 0x94, 0x95, 0x95, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, - 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8f, 0x91, 0x93, 0x94, 0x96, 0x99, - 0x9b, 0x9b, 0x99, 0x98, 0x94, 0x93, 0x90, 0x8e, 0x8c, 0x8c, 0x8b, 0x8a, - 0x8c, 0x94, 0xa0, 0xa7, 0xaa, 0xab, 0x98, 0x5f, 0x3c, 0x35, 0x3f, 0x42, - 0x56, 0x7d, 0x74, 0x40, 0x56, 0x9a, 0xb1, 0xa5, 0x85, 0x94, 0xbb, 0xc7, - 0xc6, 0xc1, 0xc6, 0xb7, 0xad, 0x76, 0x6a, 0x89, 0x9f, 0xba, 0xc1, 0xbe, - 0xb1, 0xaa, 0xb2, 0xba, 0xba, 0xb3, 0xae, 0xaa, 0xae, 0xb0, 0xb1, 0xb0, - 0xad, 0x9e, 0x90, 0x7d, 0x7a, 0x7d, 0x82, 0x85, 0x85, 0x84, 0x7f, 0x7f, - 0x80, 0x85, 0x86, 0x82, 0x7f, 0x81, 0x85, 0x8b, 0x8d, 0x89, 0x84, 0x7b, - 0x75, 0x78, 0x7a, 0x7c, 0x81, 0x84, 0x88, 0x8a, 0x8d, 0x90, 0x8f, 0x8d, - 0x88, 0x87, 0x88, 0x89, 0x8e, 0x8e, 0x91, 0x97, 0xa3, 0xae, 0xac, 0xac, - 0xae, 0xb5, 0xbb, 0xbb, 0xb6, 0xb1, 0xa9, 0x9e, 0x99, 0x9c, 0xa0, 0xa3, - 0x90, 0x77, 0x7f, 0x6d, 0x38, 0x3a, 0x71, 0x7c, 0x79, 0x64, 0x25, 0x14, - 0x1e, 0x25, 0x29, 0x29, 0x26, 0x25, 0x23, 0x1e, 0x14, 0x11, 0x11, 0x11, - 0x1b, 0x46, 0x70, 0x78, 0x77, 0x74, 0x75, 0x7a, 0x7f, 0x81, 0x80, 0x7a, - 0x6e, 0x65, 0x61, 0x5e, 0x60, 0x63, 0x64, 0x65, 0x67, 0x69, 0x6b, 0x6c, - 0x6b, 0x6b, 0x6c, 0x6f, 0x71, 0x71, 0x71, 0x70, 0x71, 0x72, 0x72, 0x71, - 0x70, 0x6f, 0x6e, 0x70, 0x70, 0x71, 0x70, 0x72, 0x72, 0x73, 0x73, 0x73, - 0x73, 0x73, 0x72, 0x70, 0x6f, 0x6c, 0x69, 0x67, 0x64, 0x5e, 0x5a, 0x56, - 0x53, 0x4f, 0x47, 0x42, 0x3e, 0x3c, 0x38, 0x31, 0x29, 0x22, 0x1d, 0x16, - 0x12, 0x11, 0x11, 0x11, 0x12, 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, - 0x14, 0x14, 0x13, 0x11, 0x5a, 0x58, 0x58, 0x58, 0x58, 0x57, 0x58, 0x58, - 0x59, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x63, 0x65, 0x66, 0x66, - 0x68, 0x6a, 0x6c, 0x6c, 0x6d, 0x6f, 0x70, 0x71, 0x71, 0x70, 0x70, 0x71, - 0x71, 0x70, 0x70, 0x70, 0x71, 0x71, 0x70, 0x70, 0x71, 0x70, 0x70, 0x70, - 0x6f, 0x6d, 0x6e, 0x71, 0x74, 0x76, 0x7a, 0x7d, 0x7d, 0x7f, 0x82, 0x84, - 0x86, 0x86, 0x87, 0x89, 0x8a, 0x8a, 0x8c, 0x8c, 0x8d, 0x8f, 0x90, 0x93, - 0x94, 0x94, 0x94, 0x93, 0x92, 0x90, 0x8f, 0x8e, 0x8e, 0x8d, 0x8d, 0x8d, - 0x8d, 0x8f, 0x8f, 0x91, 0x92, 0x93, 0x97, 0x9a, 0x9a, 0x9a, 0x9a, 0x97, - 0x94, 0x92, 0x92, 0x8f, 0x8e, 0x8e, 0x8e, 0x8d, 0x8f, 0x98, 0xa2, 0xa8, - 0xac, 0xab, 0x85, 0x47, 0x40, 0x41, 0x3d, 0x43, 0x78, 0x95, 0x83, 0x43, - 0x34, 0x71, 0xb2, 0xc2, 0xad, 0x98, 0xb9, 0xbf, 0xbb, 0xb9, 0xc6, 0xbe, - 0xbe, 0x9c, 0x86, 0x7d, 0x94, 0xb0, 0xbb, 0xba, 0xae, 0xab, 0xb9, 0xbe, - 0xbe, 0xb9, 0xb8, 0xb0, 0xb1, 0xb3, 0xb5, 0xb3, 0xae, 0xa3, 0x95, 0x7e, - 0x7a, 0x81, 0x85, 0x84, 0x83, 0x85, 0x82, 0x81, 0x82, 0x84, 0x86, 0x82, - 0x82, 0x84, 0x89, 0x89, 0x8d, 0x8d, 0x89, 0x80, 0x7b, 0x7d, 0x7d, 0x7f, - 0x82, 0x85, 0x8b, 0x8e, 0x90, 0x90, 0x8d, 0x8a, 0x88, 0x88, 0x89, 0x8b, - 0x8f, 0x93, 0x97, 0x9e, 0xa6, 0xac, 0xac, 0xaf, 0xb0, 0xb2, 0xb5, 0xb8, - 0xb5, 0xb0, 0xa6, 0x9a, 0x95, 0x98, 0x9b, 0x9d, 0x8c, 0x7c, 0x86, 0x74, - 0x3c, 0x3e, 0x75, 0x80, 0x74, 0x51, 0x1f, 0x15, 0x21, 0x27, 0x26, 0x25, - 0x27, 0x27, 0x24, 0x1c, 0x14, 0x11, 0x10, 0x11, 0x1c, 0x49, 0x72, 0x78, - 0x77, 0x74, 0x76, 0x7b, 0x81, 0x83, 0x83, 0x7c, 0x71, 0x66, 0x62, 0x60, - 0x61, 0x64, 0x65, 0x66, 0x68, 0x6a, 0x6b, 0x6c, 0x6c, 0x6d, 0x6f, 0x6f, - 0x71, 0x72, 0x72, 0x71, 0x73, 0x74, 0x73, 0x72, 0x72, 0x71, 0x70, 0x71, - 0x71, 0x70, 0x70, 0x71, 0x71, 0x71, 0x72, 0x72, 0x73, 0x74, 0x74, 0x72, - 0x70, 0x6c, 0x6a, 0x69, 0x64, 0x60, 0x5c, 0x57, 0x54, 0x4f, 0x48, 0x43, - 0x3e, 0x3b, 0x38, 0x31, 0x29, 0x22, 0x1d, 0x16, 0x11, 0x11, 0x12, 0x12, - 0x11, 0x11, 0x11, 0x12, 0x12, 0x13, 0x14, 0x15, 0x14, 0x14, 0x12, 0x11, - 0x59, 0x57, 0x57, 0x57, 0x57, 0x57, 0x59, 0x59, 0x59, 0x59, 0x5b, 0x5c, - 0x5c, 0x5d, 0x60, 0x61, 0x63, 0x63, 0x64, 0x65, 0x67, 0x69, 0x6a, 0x6a, - 0x6c, 0x6d, 0x6f, 0x71, 0x71, 0x70, 0x71, 0x70, 0x70, 0x70, 0x71, 0x72, - 0x71, 0x70, 0x71, 0x72, 0x71, 0x71, 0x70, 0x70, 0x70, 0x6f, 0x70, 0x72, - 0x74, 0x76, 0x79, 0x7c, 0x7d, 0x7f, 0x82, 0x85, 0x86, 0x87, 0x87, 0x89, - 0x89, 0x89, 0x8b, 0x8b, 0x8c, 0x8e, 0x91, 0x93, 0x93, 0x93, 0x93, 0x92, - 0x90, 0x8f, 0x8e, 0x8f, 0x8e, 0x8d, 0x8d, 0x8d, 0x8d, 0x8e, 0x8f, 0x91, - 0x92, 0x94, 0x97, 0x9a, 0x9b, 0x9b, 0x9a, 0x97, 0x94, 0x93, 0x92, 0x92, - 0x90, 0x91, 0x90, 0x90, 0x95, 0x9e, 0xa7, 0xab, 0xaf, 0xa9, 0x6c, 0x37, - 0x43, 0x45, 0x33, 0x3f, 0x88, 0xa4, 0x8d, 0x44, 0x30, 0x7b, 0xb4, 0xc7, - 0xbf, 0x94, 0xa9, 0xbc, 0xc1, 0xc1, 0xc1, 0xc8, 0xb9, 0xa0, 0x82, 0x5f, - 0x8d, 0xa3, 0xb5, 0xb7, 0xad, 0xb3, 0xbc, 0xc2, 0xc3, 0xc1, 0xc3, 0xbc, - 0xb8, 0xb9, 0xb9, 0xba, 0xb6, 0xae, 0xa2, 0x8c, 0x7e, 0x7d, 0x80, 0x82, - 0x86, 0x89, 0x86, 0x84, 0x83, 0x82, 0x84, 0x80, 0x81, 0x84, 0x89, 0x8a, - 0x8b, 0x8c, 0x8a, 0x85, 0x83, 0x83, 0x82, 0x83, 0x84, 0x82, 0x85, 0x87, - 0x8a, 0x8c, 0x89, 0x86, 0x87, 0x89, 0x8b, 0x8d, 0x90, 0x97, 0x9d, 0xa5, - 0xa9, 0xad, 0xae, 0xb2, 0xb4, 0xb5, 0xb6, 0xb3, 0xb2, 0xae, 0xa4, 0x97, - 0x8d, 0x8d, 0x91, 0x98, 0x8e, 0x84, 0x82, 0x6d, 0x3b, 0x3b, 0x75, 0x7b, - 0x65, 0x36, 0x16, 0x18, 0x28, 0x2c, 0x24, 0x1f, 0x22, 0x23, 0x21, 0x1a, - 0x14, 0x11, 0x10, 0x13, 0x20, 0x4f, 0x73, 0x78, 0x76, 0x74, 0x77, 0x7e, - 0x84, 0x87, 0x87, 0x81, 0x74, 0x6b, 0x65, 0x61, 0x62, 0x64, 0x65, 0x66, - 0x68, 0x6b, 0x6c, 0x6e, 0x70, 0x70, 0x71, 0x70, 0x71, 0x72, 0x73, 0x75, - 0x75, 0x75, 0x75, 0x75, 0x74, 0x73, 0x71, 0x71, 0x70, 0x6f, 0x71, 0x70, - 0x71, 0x71, 0x71, 0x73, 0x73, 0x74, 0x74, 0x72, 0x70, 0x6d, 0x6a, 0x68, - 0x64, 0x60, 0x5c, 0x58, 0x54, 0x4e, 0x48, 0x44, 0x3f, 0x3d, 0x39, 0x32, - 0x28, 0x22, 0x1d, 0x16, 0x12, 0x11, 0x12, 0x12, 0x11, 0x11, 0x11, 0x12, - 0x13, 0x14, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x59, 0x58, 0x59, 0x59, - 0x58, 0x58, 0x58, 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x61, - 0x63, 0x63, 0x64, 0x65, 0x67, 0x67, 0x69, 0x6a, 0x6c, 0x6d, 0x6e, 0x70, - 0x70, 0x71, 0x71, 0x72, 0x71, 0x72, 0x73, 0x74, 0x72, 0x72, 0x73, 0x73, - 0x73, 0x73, 0x73, 0x72, 0x71, 0x6f, 0x70, 0x72, 0x73, 0x75, 0x79, 0x7d, - 0x7e, 0x80, 0x83, 0x85, 0x86, 0x86, 0x87, 0x88, 0x89, 0x89, 0x89, 0x8a, - 0x8b, 0x8c, 0x90, 0x93, 0x93, 0x93, 0x93, 0x91, 0x8f, 0x8f, 0x8e, 0x8e, - 0x8d, 0x8c, 0x8d, 0x8d, 0x8d, 0x8f, 0x8f, 0x91, 0x92, 0x94, 0x98, 0x9b, - 0x9b, 0x9b, 0x99, 0x97, 0x94, 0x94, 0x94, 0x93, 0x92, 0x92, 0x94, 0x97, - 0x9e, 0xa8, 0xaf, 0xb3, 0xb6, 0xa9, 0x5b, 0x33, 0x3e, 0x3c, 0x28, 0x3a, - 0x8c, 0xab, 0x92, 0x49, 0x4c, 0xa3, 0xb8, 0xba, 0xb9, 0xa9, 0x98, 0xa0, - 0xaa, 0xb3, 0xb2, 0xba, 0xaa, 0x9a, 0x7a, 0x4f, 0x87, 0x9c, 0xb2, 0xb6, - 0xae, 0xb7, 0xba, 0xc0, 0xc3, 0xc5, 0xcb, 0xc6, 0xc0, 0xbe, 0xbb, 0xb7, - 0xb5, 0xb0, 0xa7, 0x97, 0x85, 0x7c, 0x7c, 0x7e, 0x84, 0x8c, 0x8b, 0x89, - 0x87, 0x85, 0x84, 0x81, 0x82, 0x83, 0x86, 0x8b, 0x8a, 0x88, 0x88, 0x88, - 0x85, 0x84, 0x87, 0x89, 0x8b, 0x87, 0x86, 0x85, 0x85, 0x86, 0x87, 0x85, - 0x87, 0x89, 0x8b, 0x8f, 0x96, 0x9b, 0x9e, 0xa3, 0xaa, 0xad, 0xaf, 0xb4, - 0xb5, 0xb4, 0xb2, 0xb0, 0xb0, 0xab, 0x9d, 0x8c, 0x80, 0x7f, 0x84, 0x91, - 0x95, 0x8c, 0x7b, 0x63, 0x38, 0x34, 0x67, 0x67, 0x52, 0x29, 0x15, 0x1c, - 0x2d, 0x30, 0x25, 0x19, 0x1a, 0x1b, 0x1c, 0x1a, 0x16, 0x12, 0x12, 0x19, - 0x31, 0x57, 0x74, 0x77, 0x76, 0x75, 0x79, 0x80, 0x85, 0x88, 0x89, 0x83, - 0x77, 0x6e, 0x68, 0x62, 0x62, 0x65, 0x67, 0x68, 0x69, 0x6c, 0x6c, 0x6e, - 0x71, 0x71, 0x72, 0x71, 0x72, 0x74, 0x75, 0x76, 0x77, 0x77, 0x76, 0x76, - 0x76, 0x76, 0x73, 0x71, 0x71, 0x70, 0x70, 0x71, 0x71, 0x71, 0x71, 0x73, - 0x73, 0x74, 0x74, 0x72, 0x70, 0x6d, 0x6a, 0x69, 0x65, 0x60, 0x5b, 0x57, - 0x54, 0x4e, 0x4a, 0x45, 0x41, 0x3e, 0x39, 0x32, 0x28, 0x21, 0x1d, 0x17, - 0x12, 0x12, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, - 0x14, 0x14, 0x13, 0x14, 0x5a, 0x59, 0x5a, 0x5a, 0x59, 0x59, 0x57, 0x57, - 0x57, 0x59, 0x5a, 0x5b, 0x5b, 0x5c, 0x5d, 0x60, 0x62, 0x62, 0x63, 0x64, - 0x65, 0x67, 0x6a, 0x6b, 0x6c, 0x6c, 0x6e, 0x6f, 0x70, 0x71, 0x71, 0x72, - 0x72, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x73, - 0x70, 0x6f, 0x71, 0x72, 0x73, 0x75, 0x79, 0x7d, 0x7f, 0x80, 0x82, 0x84, - 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x89, 0x89, 0x89, 0x8b, 0x8f, 0x92, - 0x92, 0x92, 0x92, 0x90, 0x8f, 0x8f, 0x8f, 0x8d, 0x8c, 0x8c, 0x8d, 0x8d, - 0x8d, 0x8e, 0x91, 0x92, 0x93, 0x95, 0x98, 0x9c, 0x9b, 0x9a, 0x98, 0x96, - 0x95, 0x94, 0x94, 0x94, 0x93, 0x94, 0x99, 0x9e, 0xa6, 0xb0, 0xb6, 0xb9, - 0xba, 0xa8, 0x55, 0x33, 0x3e, 0x3c, 0x2a, 0x3a, 0x8f, 0xae, 0x96, 0x57, - 0x73, 0xb4, 0xbd, 0xb6, 0xa8, 0x98, 0xa7, 0xa3, 0xa7, 0xbb, 0xbe, 0xb3, - 0xae, 0xa9, 0x88, 0x4e, 0x7a, 0x92, 0xad, 0xb5, 0xb0, 0xb8, 0xb8, 0xbe, - 0xc2, 0xc8, 0xd1, 0xd0, 0xcb, 0xc6, 0xc1, 0xb9, 0xb2, 0xae, 0xa8, 0x9d, - 0x8c, 0x7d, 0x7c, 0x7e, 0x83, 0x8a, 0x8c, 0x8c, 0x8b, 0x87, 0x86, 0x85, - 0x84, 0x83, 0x85, 0x8a, 0x8c, 0x8a, 0x89, 0x88, 0x87, 0x87, 0x89, 0x8a, - 0x8c, 0x89, 0x88, 0x87, 0x85, 0x84, 0x87, 0x86, 0x88, 0x8b, 0x90, 0x92, - 0x97, 0x9e, 0xa0, 0xa2, 0xa9, 0xab, 0xae, 0xb0, 0xb1, 0xb1, 0xb0, 0xad, - 0xad, 0xa8, 0x97, 0x7f, 0x75, 0x72, 0x78, 0x89, 0x95, 0x8a, 0x74, 0x5d, - 0x39, 0x33, 0x5b, 0x59, 0x48, 0x2a, 0x16, 0x1d, 0x2b, 0x2d, 0x24, 0x17, - 0x16, 0x17, 0x18, 0x1b, 0x1a, 0x13, 0x15, 0x24, 0x46, 0x5c, 0x72, 0x75, - 0x75, 0x77, 0x7b, 0x80, 0x85, 0x87, 0x89, 0x85, 0x79, 0x70, 0x6a, 0x64, - 0x63, 0x65, 0x67, 0x68, 0x6a, 0x6c, 0x6d, 0x6f, 0x71, 0x71, 0x72, 0x73, - 0x74, 0x76, 0x77, 0x78, 0x77, 0x78, 0x77, 0x76, 0x76, 0x76, 0x73, 0x73, - 0x72, 0x71, 0x70, 0x6f, 0x70, 0x70, 0x71, 0x72, 0x73, 0x74, 0x74, 0x72, - 0x70, 0x6c, 0x6a, 0x69, 0x65, 0x5f, 0x5b, 0x57, 0x54, 0x4e, 0x4a, 0x46, - 0x42, 0x3f, 0x3b, 0x32, 0x29, 0x23, 0x1e, 0x17, 0x11, 0x12, 0x12, 0x12, - 0x12, 0x10, 0x11, 0x12, 0x12, 0x12, 0x13, 0x14, 0x13, 0x13, 0x13, 0x13, - 0x5a, 0x59, 0x5a, 0x5a, 0x5a, 0x59, 0x57, 0x56, 0x57, 0x59, 0x5a, 0x5a, - 0x5b, 0x5b, 0x5d, 0x60, 0x62, 0x62, 0x62, 0x63, 0x65, 0x66, 0x6a, 0x6b, - 0x6b, 0x6c, 0x6e, 0x6f, 0x6f, 0x70, 0x71, 0x72, 0x72, 0x73, 0x74, 0x74, - 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x73, 0x70, 0x6f, 0x71, 0x73, - 0x74, 0x75, 0x79, 0x7c, 0x7f, 0x80, 0x81, 0x83, 0x85, 0x86, 0x86, 0x87, - 0x89, 0x8a, 0x89, 0x89, 0x88, 0x8b, 0x8e, 0x92, 0x92, 0x92, 0x92, 0x90, - 0x8f, 0x8f, 0x8e, 0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8d, 0x91, 0x92, - 0x93, 0x95, 0x99, 0x9b, 0x9a, 0x99, 0x98, 0x96, 0x95, 0x94, 0x94, 0x94, - 0x94, 0x98, 0x9f, 0xa5, 0xad, 0xb5, 0xb9, 0xbc, 0xbc, 0xa7, 0x51, 0x32, - 0x3b, 0x39, 0x29, 0x3a, 0x93, 0xb1, 0x98, 0x60, 0x8c, 0xbb, 0xbf, 0xb1, - 0x8e, 0x7a, 0xaa, 0xac, 0xae, 0xbe, 0xc4, 0xb5, 0xb4, 0xb2, 0x90, 0x4e, - 0x71, 0x8d, 0xa9, 0xb4, 0xb5, 0xba, 0xb6, 0xbc, 0xc1, 0xc7, 0xd0, 0xd4, - 0xd1, 0xcd, 0xc5, 0xbb, 0xb2, 0xaf, 0xab, 0xa1, 0x91, 0x81, 0x7e, 0x80, - 0x84, 0x88, 0x8b, 0x8b, 0x8b, 0x88, 0x87, 0x86, 0x85, 0x84, 0x85, 0x88, - 0x8c, 0x8c, 0x8c, 0x8b, 0x8a, 0x87, 0x87, 0x89, 0x8c, 0x8a, 0x88, 0x87, - 0x86, 0x86, 0x8a, 0x89, 0x8b, 0x8d, 0x93, 0x94, 0x99, 0x9e, 0xa1, 0xa5, - 0xa9, 0xab, 0xae, 0xaf, 0xaf, 0xb0, 0xaf, 0xaa, 0xa9, 0xa3, 0x91, 0x78, - 0x6d, 0x6a, 0x71, 0x84, 0x94, 0x87, 0x70, 0x59, 0x36, 0x2f, 0x52, 0x57, - 0x4d, 0x36, 0x1b, 0x1c, 0x25, 0x26, 0x1f, 0x15, 0x15, 0x15, 0x17, 0x1c, - 0x1a, 0x14, 0x1b, 0x2c, 0x4e, 0x5e, 0x72, 0x75, 0x75, 0x77, 0x7c, 0x80, - 0x85, 0x88, 0x8a, 0x86, 0x7b, 0x71, 0x6c, 0x65, 0x63, 0x65, 0x68, 0x69, - 0x6a, 0x6c, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75, 0x77, 0x78, 0x79, - 0x78, 0x78, 0x77, 0x77, 0x77, 0x77, 0x74, 0x73, 0x73, 0x72, 0x70, 0x6f, - 0x6f, 0x70, 0x70, 0x72, 0x73, 0x74, 0x73, 0x72, 0x70, 0x6c, 0x6a, 0x69, - 0x65, 0x5f, 0x5b, 0x57, 0x54, 0x4e, 0x4a, 0x46, 0x42, 0x3f, 0x3b, 0x32, - 0x29, 0x23, 0x1e, 0x17, 0x11, 0x12, 0x12, 0x12, 0x12, 0x10, 0x11, 0x12, - 0x12, 0x12, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x5b, 0x5a, 0x5a, 0x5a, - 0x59, 0x59, 0x57, 0x57, 0x57, 0x58, 0x59, 0x5a, 0x5a, 0x5a, 0x5c, 0x5f, - 0x61, 0x60, 0x61, 0x63, 0x64, 0x66, 0x68, 0x6a, 0x6b, 0x6b, 0x6d, 0x6d, - 0x6e, 0x70, 0x71, 0x72, 0x72, 0x73, 0x74, 0x74, 0x73, 0x74, 0x74, 0x73, - 0x73, 0x74, 0x74, 0x73, 0x70, 0x6f, 0x72, 0x73, 0x75, 0x76, 0x78, 0x7a, - 0x7d, 0x7f, 0x80, 0x82, 0x84, 0x85, 0x85, 0x86, 0x87, 0x88, 0x88, 0x87, - 0x87, 0x89, 0x8d, 0x90, 0x90, 0x90, 0x90, 0x8e, 0x8d, 0x8e, 0x8e, 0x8c, - 0x8c, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x91, 0x92, 0x93, 0x94, 0x98, 0x9a, - 0x99, 0x98, 0x97, 0x95, 0x95, 0x95, 0x95, 0x95, 0x98, 0xa1, 0xaa, 0xb0, - 0xb6, 0xbb, 0xbd, 0xbf, 0xbd, 0xa4, 0x4e, 0x30, 0x33, 0x30, 0x24, 0x39, - 0x93, 0xad, 0x94, 0x62, 0xa3, 0xc0, 0xbc, 0x9e, 0x59, 0x48, 0x90, 0xb4, - 0xb9, 0xb7, 0xc3, 0xbe, 0xb8, 0xb6, 0x92, 0x4b, 0x6a, 0x8d, 0xa9, 0xb8, - 0xc1, 0xbd, 0xb3, 0xb9, 0xc0, 0xc7, 0xcc, 0xd5, 0xd8, 0xd6, 0xcd, 0xbf, - 0xb5, 0xb4, 0xb2, 0xa7, 0x97, 0x8a, 0x85, 0x84, 0x86, 0x88, 0x8a, 0x8a, - 0x89, 0x88, 0x89, 0x87, 0x87, 0x87, 0x86, 0x86, 0x8b, 0x8e, 0x90, 0x94, - 0x92, 0x85, 0x84, 0x86, 0x8c, 0x8b, 0x88, 0x88, 0x89, 0x8b, 0x8e, 0x8f, - 0x8e, 0x8f, 0x94, 0x97, 0x9c, 0xa0, 0xa3, 0xa7, 0xaa, 0xac, 0xaf, 0xb0, - 0xb0, 0xaf, 0xae, 0xa5, 0xa0, 0x99, 0x86, 0x72, 0x64, 0x63, 0x6a, 0x7f, - 0x92, 0x84, 0x6c, 0x53, 0x2e, 0x25, 0x4a, 0x5a, 0x5c, 0x52, 0x31, 0x1f, - 0x1b, 0x19, 0x16, 0x12, 0x12, 0x14, 0x18, 0x1d, 0x17, 0x19, 0x2b, 0x3b, - 0x4e, 0x5f, 0x71, 0x75, 0x75, 0x77, 0x7c, 0x80, 0x85, 0x87, 0x8a, 0x87, - 0x7c, 0x73, 0x6e, 0x67, 0x64, 0x66, 0x68, 0x6a, 0x6b, 0x6d, 0x6f, 0x70, - 0x70, 0x71, 0x72, 0x74, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7a, 0x79, 0x78, - 0x78, 0x76, 0x75, 0x75, 0x74, 0x72, 0x71, 0x6f, 0x6f, 0x70, 0x70, 0x72, - 0x72, 0x73, 0x73, 0x72, 0x70, 0x6c, 0x6a, 0x69, 0x65, 0x5f, 0x5b, 0x56, - 0x53, 0x4e, 0x4a, 0x45, 0x42, 0x3f, 0x3b, 0x32, 0x28, 0x22, 0x1e, 0x17, - 0x12, 0x12, 0x12, 0x12, 0x12, 0x10, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, - 0x13, 0x13, 0x12, 0x12, 0x5b, 0x5a, 0x5a, 0x5a, 0x59, 0x57, 0x58, 0x58, - 0x58, 0x58, 0x59, 0x5a, 0x5a, 0x59, 0x5b, 0x5e, 0x60, 0x61, 0x61, 0x61, - 0x63, 0x64, 0x66, 0x67, 0x69, 0x6b, 0x6c, 0x6c, 0x6d, 0x6e, 0x6f, 0x72, - 0x74, 0x74, 0x73, 0x74, 0x73, 0x74, 0x74, 0x73, 0x73, 0x74, 0x73, 0x73, - 0x72, 0x70, 0x72, 0x75, 0x76, 0x76, 0x77, 0x7a, 0x7b, 0x7c, 0x7f, 0x81, - 0x83, 0x84, 0x85, 0x85, 0x85, 0x86, 0x86, 0x86, 0x86, 0x88, 0x8d, 0x90, - 0x8f, 0x8e, 0x8d, 0x8d, 0x8b, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8c, 0x8c, - 0x8c, 0x8d, 0x90, 0x92, 0x93, 0x95, 0x98, 0x99, 0x98, 0x97, 0x96, 0x95, - 0x96, 0x96, 0x97, 0x9a, 0xa1, 0xac, 0xb4, 0xb9, 0xbe, 0xbf, 0xbd, 0xbf, - 0xbd, 0xa3, 0x4f, 0x30, 0x30, 0x2c, 0x22, 0x37, 0x7c, 0x7e, 0x65, 0x4a, - 0x92, 0xb7, 0x98, 0x6f, 0x33, 0x27, 0x4f, 0x96, 0xb1, 0xb3, 0xc0, 0xba, - 0xb1, 0xae, 0x8c, 0x49, 0x6a, 0x97, 0xc0, 0xd1, 0xd3, 0xc2, 0xb7, 0xbe, - 0xc5, 0xcb, 0xcc, 0xd3, 0xdc, 0xdf, 0xda, 0xca, 0xba, 0xb5, 0xb2, 0xab, - 0xa0, 0x94, 0x8d, 0x8d, 0x8d, 0x8a, 0x8a, 0x8b, 0x8c, 0x8e, 0x8e, 0x8c, - 0x88, 0x87, 0x88, 0x8a, 0x8d, 0x90, 0x95, 0x9f, 0x9d, 0x8a, 0x87, 0x89, - 0x8d, 0x8f, 0x8d, 0x8e, 0x8d, 0x8d, 0x90, 0x93, 0x92, 0x92, 0x95, 0x9a, - 0xa0, 0xa2, 0xa3, 0xa6, 0xac, 0xb1, 0xb0, 0xb0, 0xb0, 0xaf, 0xad, 0xa4, - 0x98, 0x8d, 0x7b, 0x68, 0x5e, 0x5e, 0x65, 0x77, 0x8c, 0x7f, 0x65, 0x52, - 0x38, 0x2b, 0x52, 0x53, 0x59, 0x6d, 0x63, 0x47, 0x32, 0x27, 0x1b, 0x14, - 0x14, 0x17, 0x1a, 0x1d, 0x1b, 0x2f, 0x4a, 0x51, 0x4e, 0x66, 0x73, 0x74, - 0x74, 0x77, 0x7d, 0x82, 0x86, 0x88, 0x89, 0x88, 0x80, 0x76, 0x70, 0x6a, - 0x65, 0x66, 0x68, 0x6a, 0x6d, 0x6f, 0x70, 0x72, 0x72, 0x73, 0x74, 0x75, - 0x77, 0x79, 0x79, 0x79, 0x7b, 0x7b, 0x7b, 0x7a, 0x79, 0x77, 0x75, 0x75, - 0x75, 0x72, 0x71, 0x71, 0x70, 0x6f, 0x70, 0x71, 0x71, 0x72, 0x72, 0x72, - 0x71, 0x6d, 0x6b, 0x69, 0x66, 0x60, 0x5b, 0x56, 0x53, 0x4f, 0x49, 0x45, - 0x41, 0x3e, 0x39, 0x32, 0x27, 0x21, 0x1d, 0x16, 0x12, 0x10, 0x11, 0x11, - 0x12, 0x10, 0x10, 0x11, 0x11, 0x13, 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, - 0x5c, 0x5a, 0x5a, 0x5a, 0x59, 0x58, 0x58, 0x59, 0x58, 0x57, 0x59, 0x5a, - 0x5a, 0x59, 0x5b, 0x5d, 0x5f, 0x60, 0x60, 0x5f, 0x60, 0x64, 0x65, 0x66, - 0x68, 0x6a, 0x6c, 0x6c, 0x6d, 0x6f, 0x6f, 0x72, 0x74, 0x74, 0x73, 0x74, - 0x74, 0x75, 0x75, 0x74, 0x74, 0x74, 0x73, 0x73, 0x74, 0x73, 0x73, 0x76, - 0x77, 0x75, 0x75, 0x78, 0x79, 0x7a, 0x7d, 0x7f, 0x81, 0x82, 0x83, 0x84, - 0x85, 0x85, 0x85, 0x85, 0x85, 0x88, 0x8c, 0x8f, 0x8e, 0x8c, 0x8b, 0x8b, - 0x8b, 0x8b, 0x8b, 0x8b, 0x8c, 0x8b, 0x8c, 0x8c, 0x8c, 0x8e, 0x91, 0x92, - 0x92, 0x95, 0x96, 0x97, 0x97, 0x96, 0x95, 0x95, 0x97, 0x99, 0x9b, 0xa1, - 0xa8, 0xb3, 0xbb, 0xbe, 0xbf, 0xbd, 0xb9, 0xb9, 0xb8, 0xa2, 0x51, 0x30, - 0x2e, 0x2b, 0x24, 0x33, 0x4b, 0x45, 0x37, 0x29, 0x4d, 0x84, 0x5a, 0x39, - 0x27, 0x22, 0x29, 0x53, 0x79, 0xa9, 0xbb, 0xb0, 0xb5, 0xb4, 0x8f, 0x43, - 0x55, 0x8f, 0xc7, 0xdc, 0xda, 0xc7, 0xbb, 0xc7, 0xcd, 0xcd, 0xcb, 0xd3, - 0xde, 0xe2, 0xe1, 0xd8, 0xc8, 0xba, 0xb3, 0xad, 0xa7, 0x9a, 0x92, 0x91, - 0x91, 0x90, 0x8d, 0x8d, 0x8e, 0x8f, 0x92, 0x90, 0x8e, 0x8c, 0x8a, 0x8b, - 0x8c, 0x8e, 0x91, 0x95, 0x97, 0x8f, 0x8c, 0x8d, 0x8e, 0x91, 0x93, 0x92, - 0x91, 0x90, 0x92, 0x96, 0x95, 0x97, 0x9b, 0x9e, 0x9f, 0x9f, 0xa2, 0xa8, - 0xb1, 0xb4, 0xb4, 0xb3, 0xb0, 0xab, 0xa7, 0xa0, 0x8f, 0x82, 0x71, 0x62, - 0x64, 0x62, 0x63, 0x6c, 0x7f, 0x7c, 0x66, 0x57, 0x43, 0x2f, 0x57, 0x5f, - 0x63, 0x6d, 0x6a, 0x73, 0x6c, 0x5f, 0x48, 0x33, 0x29, 0x25, 0x26, 0x2c, - 0x42, 0x55, 0x49, 0x46, 0x54, 0x70, 0x73, 0x72, 0x74, 0x7a, 0x80, 0x85, - 0x88, 0x8a, 0x8a, 0x88, 0x81, 0x78, 0x72, 0x6b, 0x66, 0x66, 0x68, 0x6a, - 0x6d, 0x6f, 0x70, 0x72, 0x74, 0x75, 0x77, 0x77, 0x78, 0x7a, 0x7a, 0x7a, - 0x7c, 0x7c, 0x7c, 0x7b, 0x7a, 0x7a, 0x78, 0x76, 0x75, 0x74, 0x73, 0x72, - 0x70, 0x6f, 0x6f, 0x71, 0x71, 0x72, 0x73, 0x72, 0x71, 0x6d, 0x6a, 0x69, - 0x66, 0x60, 0x5c, 0x57, 0x54, 0x51, 0x4a, 0x45, 0x40, 0x3d, 0x39, 0x33, - 0x28, 0x20, 0x1b, 0x15, 0x11, 0x10, 0x11, 0x11, 0x12, 0x10, 0x10, 0x11, - 0x11, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x12, 0x5d, 0x5b, 0x5a, 0x59, - 0x5a, 0x5a, 0x5a, 0x59, 0x57, 0x56, 0x57, 0x59, 0x5a, 0x5a, 0x5c, 0x5d, - 0x5e, 0x5e, 0x5f, 0x60, 0x60, 0x63, 0x64, 0x65, 0x67, 0x69, 0x6b, 0x6d, - 0x6d, 0x6e, 0x71, 0x72, 0x73, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, 0x75, - 0x75, 0x74, 0x73, 0x73, 0x74, 0x74, 0x75, 0x77, 0x77, 0x75, 0x75, 0x77, - 0x79, 0x7a, 0x7b, 0x7e, 0x80, 0x80, 0x81, 0x83, 0x84, 0x85, 0x84, 0x84, - 0x83, 0x88, 0x8c, 0x8e, 0x8d, 0x8c, 0x8b, 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, - 0x8a, 0x8c, 0x8d, 0x8d, 0x8c, 0x8e, 0x91, 0x92, 0x93, 0x93, 0x95, 0x95, - 0x96, 0x96, 0x96, 0x96, 0x98, 0x9d, 0xa0, 0xa4, 0xad, 0xb6, 0xbc, 0xbd, - 0xbd, 0xba, 0xb6, 0xb5, 0xb4, 0xa2, 0x5a, 0x32, 0x2a, 0x27, 0x24, 0x31, - 0x38, 0x2d, 0x25, 0x1e, 0x27, 0x3f, 0x2f, 0x2a, 0x32, 0x2e, 0x21, 0x2d, - 0x52, 0x9a, 0xac, 0xa6, 0xbd, 0xbc, 0x95, 0x48, 0x5e, 0x95, 0xca, 0xde, - 0xdd, 0xc8, 0xbf, 0xce, 0xd4, 0xcf, 0xcb, 0xcf, 0xd9, 0xdf, 0xe2, 0xe0, - 0xd6, 0xc4, 0xbb, 0xb4, 0xab, 0x9e, 0x96, 0x92, 0x92, 0x91, 0x90, 0x8f, - 0x8f, 0x90, 0x93, 0x94, 0x92, 0x91, 0x8f, 0x8d, 0x8d, 0x90, 0x91, 0x8f, - 0x8f, 0x8f, 0x8d, 0x8d, 0x8f, 0x91, 0x95, 0x95, 0x95, 0x94, 0x94, 0x97, - 0x9a, 0x9b, 0x9b, 0x9a, 0x9d, 0xa3, 0xa7, 0xae, 0xb2, 0xb3, 0xb7, 0xb4, - 0xb0, 0xa8, 0xa3, 0x99, 0x84, 0x77, 0x6c, 0x64, 0x67, 0x64, 0x64, 0x68, - 0x79, 0x7a, 0x66, 0x58, 0x45, 0x2f, 0x57, 0x69, 0x6e, 0x70, 0x68, 0x7a, - 0x6e, 0x6c, 0x76, 0x75, 0x62, 0x55, 0x55, 0x64, 0x7d, 0x5d, 0x41, 0x42, - 0x5f, 0x77, 0x74, 0x73, 0x76, 0x7c, 0x83, 0x86, 0x8a, 0x8c, 0x8c, 0x89, - 0x83, 0x79, 0x73, 0x6c, 0x68, 0x68, 0x69, 0x6b, 0x6d, 0x6f, 0x6f, 0x72, - 0x75, 0x76, 0x77, 0x79, 0x79, 0x7b, 0x7b, 0x7b, 0x7d, 0x7d, 0x7c, 0x7d, - 0x7b, 0x7b, 0x79, 0x78, 0x77, 0x75, 0x74, 0x73, 0x71, 0x70, 0x70, 0x72, - 0x71, 0x72, 0x72, 0x72, 0x70, 0x6c, 0x6b, 0x69, 0x66, 0x61, 0x5c, 0x57, - 0x54, 0x51, 0x4a, 0x45, 0x3f, 0x3b, 0x38, 0x34, 0x2a, 0x22, 0x1c, 0x16, - 0x12, 0x10, 0x11, 0x11, 0x11, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, - 0x14, 0x14, 0x13, 0x12, 0x5d, 0x5c, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x58, - 0x57, 0x56, 0x57, 0x59, 0x59, 0x5a, 0x5c, 0x5c, 0x5d, 0x5d, 0x5e, 0x60, - 0x61, 0x62, 0x64, 0x64, 0x66, 0x68, 0x6b, 0x6d, 0x6d, 0x6e, 0x70, 0x71, - 0x72, 0x72, 0x73, 0x74, 0x74, 0x75, 0x75, 0x75, 0x75, 0x74, 0x73, 0x73, - 0x74, 0x74, 0x75, 0x77, 0x77, 0x76, 0x76, 0x77, 0x78, 0x79, 0x79, 0x7d, - 0x7f, 0x7f, 0x80, 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x88, 0x8c, 0x8d, - 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x89, 0x89, 0x89, 0x8a, 0x8c, 0x8d, 0x8d, - 0x8c, 0x8e, 0x91, 0x93, 0x93, 0x93, 0x95, 0x95, 0x96, 0x96, 0x97, 0x98, - 0x9a, 0x9f, 0xa2, 0xa6, 0xaf, 0xb8, 0xbb, 0xbc, 0xbb, 0xb7, 0xb3, 0xb1, - 0xb0, 0xa1, 0x62, 0x34, 0x28, 0x25, 0x24, 0x2f, 0x32, 0x27, 0x21, 0x1e, - 0x1d, 0x26, 0x29, 0x2f, 0x38, 0x34, 0x20, 0x20, 0x3e, 0x81, 0xa1, 0x9c, - 0xb9, 0xb9, 0x92, 0x48, 0x62, 0x9c, 0xcc, 0xde, 0xdc, 0xc5, 0xbe, 0xcf, - 0xd5, 0xd0, 0xcb, 0xcc, 0xd3, 0xd8, 0xde, 0xe1, 0xdc, 0xcc, 0xc3, 0xba, - 0xae, 0xa3, 0x9a, 0x96, 0x93, 0x92, 0x92, 0x92, 0x90, 0x91, 0x92, 0x94, - 0x93, 0x93, 0x92, 0x90, 0x8f, 0x91, 0x91, 0x8d, 0x8d, 0x8f, 0x8d, 0x8c, - 0x90, 0x92, 0x95, 0x97, 0x97, 0x97, 0x96, 0x9a, 0x9d, 0x9e, 0x9d, 0x9a, - 0x9f, 0xa6, 0xaa, 0xb0, 0xb2, 0xb3, 0xb8, 0xb4, 0xaf, 0xa6, 0x9f, 0x92, - 0x7d, 0x71, 0x69, 0x63, 0x66, 0x64, 0x64, 0x68, 0x74, 0x77, 0x67, 0x5b, - 0x48, 0x2d, 0x51, 0x65, 0x6a, 0x6b, 0x68, 0x77, 0x67, 0x65, 0x77, 0x7f, - 0x78, 0x6e, 0x6d, 0x7b, 0x84, 0x52, 0x3e, 0x47, 0x67, 0x7c, 0x76, 0x75, - 0x78, 0x7e, 0x84, 0x88, 0x8a, 0x8c, 0x8c, 0x8a, 0x83, 0x7a, 0x74, 0x6d, - 0x69, 0x68, 0x6a, 0x6b, 0x6e, 0x70, 0x70, 0x72, 0x75, 0x76, 0x78, 0x7a, - 0x7a, 0x7c, 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7c, 0x7c, 0x7a, 0x79, - 0x78, 0x76, 0x75, 0x74, 0x72, 0x71, 0x70, 0x72, 0x71, 0x71, 0x72, 0x72, - 0x6f, 0x6c, 0x6a, 0x69, 0x66, 0x61, 0x5b, 0x57, 0x54, 0x51, 0x4a, 0x45, - 0x3f, 0x3b, 0x38, 0x34, 0x2a, 0x23, 0x1e, 0x17, 0x12, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x14, 0x14, 0x13, 0x12, - 0x5c, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x5a, 0x58, 0x57, 0x57, 0x57, 0x57, - 0x58, 0x59, 0x5b, 0x5c, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x62, - 0x65, 0x66, 0x68, 0x6b, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x71, 0x74, 0x75, - 0x74, 0x75, 0x75, 0x74, 0x74, 0x75, 0x74, 0x74, 0x74, 0x73, 0x74, 0x76, - 0x77, 0x76, 0x75, 0x76, 0x76, 0x77, 0x78, 0x7a, 0x7d, 0x7e, 0x7f, 0x80, - 0x81, 0x80, 0x80, 0x80, 0x82, 0x86, 0x8b, 0x8c, 0x8c, 0x8b, 0x89, 0x88, - 0x89, 0x89, 0x89, 0x88, 0x89, 0x8c, 0x8d, 0x8d, 0x8c, 0x8e, 0x91, 0x93, - 0x93, 0x93, 0x94, 0x94, 0x95, 0x96, 0x97, 0x99, 0x9b, 0xa0, 0xa3, 0xa8, - 0xb1, 0xb7, 0xb8, 0xb7, 0xb6, 0xb3, 0xae, 0xaa, 0xa8, 0x9f, 0x70, 0x37, - 0x27, 0x24, 0x23, 0x29, 0x2b, 0x25, 0x22, 0x20, 0x1e, 0x25, 0x36, 0x3d, - 0x3b, 0x34, 0x21, 0x1b, 0x26, 0x4f, 0x91, 0x91, 0xab, 0xac, 0x88, 0x41, - 0x59, 0xa4, 0xce, 0xdb, 0xd7, 0xbd, 0xb8, 0xc9, 0xd2, 0xd1, 0xc9, 0xc6, - 0xc9, 0xcd, 0xd7, 0xde, 0xde, 0xd7, 0xd0, 0xc3, 0xb4, 0xac, 0xa4, 0x9f, - 0x99, 0x95, 0x95, 0x95, 0x95, 0x92, 0x8f, 0x90, 0x92, 0x94, 0x96, 0x95, - 0x93, 0x93, 0x92, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x91, 0x94, 0x95, 0x97, - 0x98, 0x99, 0x9a, 0x9e, 0x9f, 0xa0, 0x9f, 0xa1, 0xa4, 0xaa, 0xad, 0xb0, - 0xb3, 0xb5, 0xb7, 0xb5, 0xb0, 0xa5, 0x99, 0x86, 0x74, 0x6a, 0x63, 0x5f, - 0x61, 0x62, 0x64, 0x68, 0x6e, 0x71, 0x68, 0x60, 0x4d, 0x2a, 0x40, 0x5a, - 0x5f, 0x5e, 0x6e, 0x70, 0x60, 0x57, 0x55, 0x5d, 0x6c, 0x72, 0x72, 0x70, - 0x60, 0x39, 0x42, 0x55, 0x71, 0x80, 0x7b, 0x7a, 0x7d, 0x82, 0x86, 0x88, - 0x8a, 0x8b, 0x8c, 0x89, 0x83, 0x7b, 0x75, 0x6d, 0x6a, 0x69, 0x6b, 0x6c, - 0x6e, 0x70, 0x72, 0x74, 0x76, 0x77, 0x78, 0x7b, 0x7b, 0x7d, 0x7d, 0x7e, - 0x7e, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, 0x7a, 0x79, 0x78, 0x76, 0x75, 0x74, - 0x73, 0x72, 0x71, 0x71, 0x70, 0x70, 0x71, 0x71, 0x6f, 0x6b, 0x6a, 0x68, - 0x64, 0x61, 0x5c, 0x57, 0x55, 0x51, 0x4a, 0x45, 0x3f, 0x3d, 0x39, 0x33, - 0x29, 0x23, 0x1e, 0x17, 0x12, 0x11, 0x10, 0x10, 0x10, 0x11, 0x10, 0x11, - 0x11, 0x12, 0x13, 0x14, 0x14, 0x14, 0x14, 0x12, 0x5c, 0x5b, 0x5b, 0x5a, - 0x5a, 0x5a, 0x5a, 0x59, 0x58, 0x57, 0x58, 0x57, 0x58, 0x59, 0x5a, 0x5a, - 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x5f, 0x61, 0x61, 0x63, 0x65, 0x67, 0x6a, - 0x6b, 0x6c, 0x6e, 0x70, 0x71, 0x71, 0x74, 0x75, 0x73, 0x74, 0x74, 0x74, - 0x74, 0x74, 0x74, 0x74, 0x73, 0x71, 0x71, 0x74, 0x75, 0x76, 0x75, 0x75, - 0x75, 0x74, 0x75, 0x77, 0x7a, 0x7a, 0x7b, 0x7d, 0x7e, 0x7d, 0x7d, 0x7e, - 0x80, 0x86, 0x8a, 0x8a, 0x8b, 0x8a, 0x88, 0x87, 0x88, 0x88, 0x88, 0x87, - 0x88, 0x8b, 0x8c, 0x8c, 0x8c, 0x8d, 0x90, 0x92, 0x92, 0x92, 0x93, 0x93, - 0x95, 0x96, 0x99, 0x9a, 0x9e, 0xa1, 0xa3, 0xa8, 0xb0, 0xb2, 0xb0, 0xaf, - 0xad, 0xa9, 0xa5, 0x9f, 0x9d, 0x9b, 0x81, 0x3a, 0x26, 0x24, 0x25, 0x22, - 0x23, 0x23, 0x21, 0x20, 0x20, 0x22, 0x29, 0x2c, 0x2d, 0x31, 0x25, 0x1c, - 0x1c, 0x2d, 0x6f, 0x94, 0xb3, 0xb4, 0x8f, 0x45, 0x57, 0xab, 0xd1, 0xd9, - 0xcc, 0xb2, 0xb9, 0xcb, 0xd1, 0xd1, 0xc6, 0xbd, 0xc0, 0xc5, 0xce, 0xd7, - 0xdc, 0xdb, 0xd7, 0xce, 0xc0, 0xb6, 0xb0, 0xac, 0xa6, 0x9d, 0x9c, 0x9c, - 0x9b, 0x96, 0x91, 0x8f, 0x92, 0x94, 0x94, 0x94, 0x95, 0x96, 0x96, 0x92, - 0x94, 0x93, 0x93, 0x94, 0x96, 0x99, 0x9a, 0x9a, 0x9a, 0x9a, 0x9b, 0x9c, - 0xa0, 0xa1, 0xa4, 0xa8, 0xac, 0xb3, 0xb5, 0xb6, 0xb6, 0xb4, 0xb1, 0xb1, - 0xae, 0xa4, 0x91, 0x78, 0x68, 0x61, 0x5d, 0x5c, 0x5e, 0x62, 0x66, 0x6b, - 0x69, 0x6c, 0x68, 0x5f, 0x49, 0x26, 0x34, 0x5d, 0x6c, 0x6d, 0x77, 0x69, - 0x60, 0x5a, 0x58, 0x66, 0x53, 0x5c, 0x5c, 0x50, 0x59, 0x45, 0x53, 0x67, - 0x83, 0x8b, 0x86, 0x84, 0x84, 0x85, 0x88, 0x89, 0x8b, 0x8b, 0x8b, 0x87, - 0x81, 0x7b, 0x75, 0x6d, 0x6a, 0x69, 0x6a, 0x6c, 0x6f, 0x71, 0x73, 0x75, - 0x77, 0x78, 0x79, 0x7b, 0x7d, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, - 0x7d, 0x7d, 0x7b, 0x7a, 0x7a, 0x78, 0x76, 0x75, 0x74, 0x73, 0x71, 0x71, - 0x70, 0x70, 0x70, 0x71, 0x6f, 0x6b, 0x6a, 0x68, 0x64, 0x61, 0x5a, 0x57, - 0x54, 0x50, 0x4a, 0x45, 0x40, 0x3d, 0x39, 0x32, 0x2a, 0x22, 0x1d, 0x16, - 0x12, 0x11, 0x10, 0x10, 0x10, 0x11, 0x10, 0x11, 0x11, 0x12, 0x13, 0x14, - 0x14, 0x14, 0x14, 0x12, 0x5d, 0x5c, 0x5b, 0x5b, 0x5b, 0x5a, 0x58, 0x58, - 0x58, 0x58, 0x59, 0x58, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5c, 0x5c, - 0x5d, 0x5e, 0x60, 0x62, 0x63, 0x65, 0x66, 0x69, 0x6b, 0x6c, 0x6d, 0x6f, - 0x71, 0x71, 0x72, 0x74, 0x73, 0x73, 0x74, 0x75, 0x74, 0x74, 0x74, 0x74, - 0x73, 0x71, 0x71, 0x74, 0x75, 0x75, 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, - 0x77, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7c, 0x7d, 0x80, 0x87, 0x89, 0x89, - 0x8a, 0x8a, 0x88, 0x88, 0x88, 0x88, 0x89, 0x89, 0x8c, 0x8e, 0x8f, 0x8f, - 0x8f, 0x8f, 0x90, 0x91, 0x91, 0x91, 0x92, 0x93, 0x96, 0x98, 0x9a, 0x9c, - 0x9e, 0xa0, 0xa2, 0xa7, 0xac, 0xaa, 0xa8, 0xa6, 0xa4, 0x9f, 0x97, 0x91, - 0x90, 0x99, 0x9a, 0x4e, 0x28, 0x23, 0x29, 0x22, 0x21, 0x21, 0x21, 0x20, - 0x21, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x23, 0x1e, 0x1d, 0x22, 0x4c, 0x86, - 0xa6, 0xae, 0x92, 0x4e, 0x59, 0xa4, 0xc4, 0xc7, 0xb8, 0xa8, 0xbc, 0xcc, - 0xd0, 0xcb, 0xbe, 0xb2, 0xbb, 0xc1, 0xc5, 0xcf, 0xd8, 0xdc, 0xdd, 0xdb, - 0xd3, 0xc6, 0xbd, 0xb8, 0xb1, 0xa8, 0xa7, 0xa6, 0xa4, 0xa1, 0x9f, 0x98, - 0x94, 0x93, 0x92, 0x92, 0x92, 0x93, 0x93, 0x93, 0x95, 0x97, 0x97, 0x98, - 0x97, 0x99, 0x99, 0x9c, 0x9d, 0x9c, 0x9c, 0x9e, 0xa1, 0xa3, 0xa7, 0xae, - 0xb2, 0xb4, 0xb5, 0xb6, 0xb8, 0xb6, 0xaf, 0xac, 0xa8, 0x9d, 0x85, 0x6f, - 0x62, 0x5e, 0x5b, 0x5a, 0x59, 0x60, 0x66, 0x6d, 0x67, 0x66, 0x6a, 0x64, - 0x4d, 0x2e, 0x2e, 0x52, 0x62, 0x60, 0x5c, 0x61, 0x7f, 0x7c, 0x5d, 0x61, - 0x5e, 0x61, 0x5b, 0x4c, 0x4e, 0x5b, 0x6c, 0x7c, 0x92, 0x96, 0x91, 0x8e, - 0x8b, 0x89, 0x8b, 0x8b, 0x8b, 0x8a, 0x8a, 0x86, 0x80, 0x7a, 0x74, 0x6c, - 0x68, 0x6a, 0x6b, 0x6c, 0x6e, 0x71, 0x75, 0x77, 0x79, 0x79, 0x79, 0x7b, - 0x7e, 0x81, 0x81, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7d, 0x7c, 0x7c, - 0x7b, 0x7a, 0x77, 0x76, 0x74, 0x73, 0x72, 0x71, 0x72, 0x71, 0x71, 0x71, - 0x70, 0x6b, 0x69, 0x67, 0x64, 0x60, 0x5b, 0x58, 0x55, 0x51, 0x4c, 0x46, - 0x40, 0x3d, 0x38, 0x31, 0x29, 0x22, 0x1d, 0x16, 0x13, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x12, 0x13, 0x13, 0x14, 0x14, 0x14, 0x13, 0x12, - 0x5d, 0x5c, 0x5b, 0x5b, 0x5b, 0x5a, 0x58, 0x57, 0x58, 0x58, 0x58, 0x58, - 0x58, 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5e, 0x60, 0x61, - 0x62, 0x63, 0x65, 0x68, 0x6a, 0x6b, 0x6d, 0x6e, 0x70, 0x71, 0x72, 0x73, - 0x74, 0x74, 0x75, 0x75, 0x74, 0x74, 0x74, 0x74, 0x74, 0x72, 0x72, 0x74, - 0x75, 0x75, 0x74, 0x74, 0x74, 0x73, 0x73, 0x73, 0x75, 0x76, 0x77, 0x77, - 0x79, 0x7a, 0x7b, 0x7c, 0x80, 0x87, 0x88, 0x88, 0x89, 0x89, 0x88, 0x88, - 0x89, 0x8b, 0x8c, 0x8f, 0x93, 0x96, 0x97, 0x97, 0x97, 0x95, 0x93, 0x92, - 0x91, 0x91, 0x92, 0x93, 0x96, 0x98, 0x99, 0x9c, 0x9f, 0xa1, 0xa2, 0xa7, - 0xa8, 0xa5, 0xa2, 0x9f, 0x9b, 0x95, 0x8f, 0x8a, 0x8a, 0x94, 0x9e, 0x6b, - 0x32, 0x22, 0x29, 0x25, 0x21, 0x20, 0x1f, 0x1f, 0x21, 0x20, 0x1f, 0x20, - 0x21, 0x26, 0x1f, 0x1d, 0x1b, 0x1f, 0x49, 0x7b, 0x98, 0xa1, 0x86, 0x46, - 0x54, 0xa1, 0xbd, 0xbe, 0xb2, 0xa7, 0xbe, 0xcb, 0xcc, 0xc7, 0xb9, 0xa8, - 0xb6, 0xbd, 0xbd, 0xc9, 0xd5, 0xdc, 0xde, 0xdd, 0xdc, 0xd7, 0xce, 0xc6, - 0xbb, 0xae, 0xaa, 0xa9, 0xa8, 0xa6, 0xa7, 0xa1, 0x9c, 0x98, 0x95, 0x94, - 0x91, 0x91, 0x93, 0x95, 0x96, 0x99, 0x9a, 0x98, 0x96, 0x98, 0x98, 0x9a, - 0x9b, 0x9c, 0x9f, 0xa0, 0xa1, 0xa3, 0xa6, 0xab, 0xb1, 0xb3, 0xb4, 0xb7, - 0xba, 0xb7, 0xad, 0xa5, 0xa0, 0x95, 0x7e, 0x6a, 0x5f, 0x5b, 0x58, 0x57, - 0x56, 0x5c, 0x61, 0x69, 0x68, 0x62, 0x68, 0x66, 0x53, 0x2f, 0x27, 0x4b, - 0x5d, 0x65, 0x68, 0x5e, 0x82, 0x86, 0x65, 0x4a, 0x5a, 0x67, 0x67, 0x58, - 0x44, 0x5e, 0x7a, 0x8a, 0x98, 0x99, 0x97, 0x93, 0x90, 0x8d, 0x8d, 0x8c, - 0x8a, 0x89, 0x88, 0x84, 0x7e, 0x78, 0x73, 0x6b, 0x66, 0x6a, 0x6c, 0x6d, - 0x6f, 0x72, 0x76, 0x78, 0x7a, 0x7b, 0x7a, 0x7d, 0x80, 0x82, 0x82, 0x81, - 0x82, 0x81, 0x80, 0x80, 0x80, 0x7f, 0x7d, 0x7d, 0x7d, 0x7b, 0x79, 0x76, - 0x75, 0x74, 0x73, 0x71, 0x71, 0x72, 0x71, 0x71, 0x6f, 0x6b, 0x69, 0x67, - 0x63, 0x60, 0x5c, 0x59, 0x56, 0x50, 0x4c, 0x46, 0x40, 0x3d, 0x38, 0x30, - 0x2a, 0x22, 0x1d, 0x17, 0x13, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x12, 0x13, 0x12, 0x13, 0x14, 0x14, 0x13, 0x12, 0x5d, 0x5c, 0x5b, 0x5b, - 0x5b, 0x5a, 0x58, 0x58, 0x58, 0x59, 0x58, 0x58, 0x57, 0x57, 0x57, 0x58, - 0x5a, 0x5a, 0x5b, 0x5b, 0x5c, 0x5d, 0x5f, 0x60, 0x61, 0x62, 0x65, 0x68, - 0x69, 0x6b, 0x6c, 0x6d, 0x6f, 0x70, 0x71, 0x73, 0x74, 0x74, 0x75, 0x75, - 0x74, 0x74, 0x74, 0x74, 0x74, 0x72, 0x71, 0x73, 0x75, 0x75, 0x74, 0x73, - 0x73, 0x73, 0x72, 0x73, 0x74, 0x75, 0x76, 0x76, 0x78, 0x79, 0x7a, 0x7c, - 0x80, 0x87, 0x88, 0x88, 0x88, 0x89, 0x88, 0x8a, 0x8d, 0x90, 0x92, 0x94, - 0x99, 0x9c, 0x9c, 0x9c, 0x9c, 0x9a, 0x97, 0x94, 0x93, 0x91, 0x92, 0x93, - 0x96, 0x97, 0x99, 0x9c, 0x9f, 0xa2, 0xa3, 0xa6, 0xa5, 0xa1, 0x9d, 0x9a, - 0x95, 0x90, 0x8c, 0x88, 0x89, 0x90, 0x9b, 0x7e, 0x3d, 0x25, 0x27, 0x25, - 0x20, 0x20, 0x20, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x1d, 0x1b, - 0x1b, 0x25, 0x55, 0x78, 0x94, 0x9c, 0x80, 0x40, 0x53, 0xa1, 0xba, 0xb9, - 0xad, 0xa7, 0xc1, 0xcb, 0xcb, 0xc5, 0xb7, 0xa7, 0xb6, 0xbd, 0xbc, 0xc7, - 0xd2, 0xd9, 0xdc, 0xdb, 0xdd, 0xdd, 0xd7, 0xd0, 0xc2, 0xb3, 0xac, 0xaa, - 0xa9, 0xa7, 0xa8, 0xa4, 0xa0, 0x9d, 0x98, 0x95, 0x93, 0x92, 0x93, 0x97, - 0x96, 0x98, 0x99, 0x98, 0x95, 0x97, 0x99, 0x9a, 0x9b, 0x9d, 0xa1, 0xa2, - 0xa3, 0xa4, 0xa6, 0xab, 0xb1, 0xb3, 0xb4, 0xb8, 0xba, 0xb6, 0xab, 0xa1, - 0x9a, 0x8e, 0x78, 0x68, 0x5e, 0x59, 0x56, 0x55, 0x54, 0x59, 0x5e, 0x64, - 0x68, 0x62, 0x67, 0x67, 0x57, 0x2f, 0x23, 0x43, 0x56, 0x67, 0x70, 0x5f, - 0x7a, 0x83, 0x6e, 0x4d, 0x56, 0x67, 0x6a, 0x5d, 0x48, 0x62, 0x80, 0x8f, - 0x99, 0x9a, 0x9a, 0x97, 0x93, 0x8f, 0x8d, 0x8b, 0x8a, 0x89, 0x87, 0x83, - 0x7d, 0x77, 0x72, 0x6a, 0x66, 0x69, 0x6c, 0x6d, 0x6f, 0x73, 0x76, 0x79, - 0x7b, 0x7b, 0x7b, 0x7d, 0x80, 0x82, 0x82, 0x82, 0x82, 0x81, 0x81, 0x81, - 0x81, 0x80, 0x7e, 0x7e, 0x7d, 0x7c, 0x79, 0x77, 0x75, 0x75, 0x73, 0x71, - 0x70, 0x71, 0x71, 0x71, 0x6f, 0x6b, 0x69, 0x67, 0x63, 0x60, 0x5c, 0x59, - 0x56, 0x50, 0x4c, 0x46, 0x41, 0x3d, 0x37, 0x30, 0x2a, 0x22, 0x1d, 0x18, - 0x13, 0x11, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x13, 0x11, 0x12, - 0x14, 0x14, 0x12, 0x12, 0x5d, 0x5c, 0x5b, 0x5b, 0x5b, 0x5b, 0x59, 0x59, - 0x58, 0x59, 0x59, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, 0x59, 0x59, 0x5a, - 0x5c, 0x5d, 0x5e, 0x5f, 0x61, 0x61, 0x63, 0x66, 0x68, 0x69, 0x6b, 0x6d, - 0x6f, 0x6f, 0x70, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x75, - 0x74, 0x71, 0x70, 0x72, 0x73, 0x74, 0x74, 0x72, 0x72, 0x72, 0x72, 0x73, - 0x73, 0x74, 0x75, 0x76, 0x76, 0x77, 0x79, 0x7a, 0x80, 0x86, 0x87, 0x87, - 0x88, 0x88, 0x8a, 0x8e, 0x93, 0x98, 0x9b, 0x9f, 0xa1, 0xa3, 0xa4, 0xa3, - 0xa4, 0xa4, 0xa1, 0x9d, 0x98, 0x94, 0x92, 0x93, 0x96, 0x97, 0x98, 0x9b, - 0xa0, 0xa3, 0xa4, 0xa4, 0xa0, 0x9b, 0x96, 0x93, 0x8f, 0x8c, 0x8c, 0x8b, - 0x8c, 0x91, 0x99, 0x8f, 0x5c, 0x3d, 0x29, 0x21, 0x20, 0x24, 0x23, 0x1f, - 0x1e, 0x1e, 0x1e, 0x1f, 0x1e, 0x1c, 0x1a, 0x1a, 0x23, 0x43, 0x75, 0x7e, - 0x94, 0x9b, 0x7d, 0x3d, 0x58, 0xa4, 0xb5, 0xb0, 0xa3, 0xaa, 0xc6, 0xce, - 0xcc, 0xc4, 0xb6, 0xaf, 0xbb, 0xc0, 0xc0, 0xc7, 0xcd, 0xd3, 0xd5, 0xd5, - 0xda, 0xdd, 0xdc, 0xd8, 0xcd, 0xbf, 0xb4, 0xaf, 0xab, 0xa6, 0xa3, 0xa3, - 0xa3, 0xa1, 0x9c, 0x99, 0x95, 0x96, 0x97, 0x9a, 0x98, 0x99, 0x99, 0x98, - 0x97, 0x98, 0x9c, 0x9d, 0x9d, 0x9d, 0xa2, 0xa6, 0xa9, 0xaa, 0xab, 0xae, - 0xb3, 0xb5, 0xb6, 0xba, 0xba, 0xb5, 0xa9, 0x9b, 0x91, 0x81, 0x6f, 0x63, - 0x5a, 0x57, 0x54, 0x53, 0x53, 0x58, 0x5b, 0x5e, 0x67, 0x63, 0x66, 0x67, - 0x5c, 0x35, 0x20, 0x33, 0x46, 0x5e, 0x6d, 0x63, 0x67, 0x70, 0x79, 0x6a, - 0x54, 0x5e, 0x61, 0x59, 0x55, 0x6f, 0x86, 0x90, 0x98, 0x9b, 0x9d, 0x9a, - 0x97, 0x90, 0x8c, 0x8a, 0x89, 0x88, 0x86, 0x81, 0x7b, 0x75, 0x71, 0x6a, - 0x66, 0x6a, 0x6c, 0x6e, 0x70, 0x74, 0x78, 0x7a, 0x7b, 0x7c, 0x7c, 0x7e, - 0x81, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x83, 0x82, 0x80, 0x7f, - 0x7e, 0x7d, 0x7a, 0x78, 0x76, 0x75, 0x72, 0x71, 0x70, 0x70, 0x70, 0x71, - 0x6f, 0x6b, 0x69, 0x67, 0x63, 0x60, 0x5c, 0x59, 0x56, 0x50, 0x4b, 0x44, - 0x41, 0x3e, 0x38, 0x30, 0x29, 0x22, 0x1d, 0x18, 0x12, 0x10, 0x11, 0x11, - 0x11, 0x10, 0x11, 0x12, 0x12, 0x13, 0x12, 0x14, 0x14, 0x14, 0x12, 0x13, - 0x5d, 0x5c, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x59, 0x57, - 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x5a, 0x5c, 0x5d, 0x5f, 0x5f, - 0x60, 0x62, 0x62, 0x63, 0x64, 0x66, 0x69, 0x6c, 0x6d, 0x6e, 0x6f, 0x71, - 0x71, 0x71, 0x72, 0x73, 0x74, 0x73, 0x74, 0x75, 0x74, 0x72, 0x70, 0x72, - 0x72, 0x72, 0x72, 0x72, 0x71, 0x71, 0x71, 0x72, 0x72, 0x73, 0x74, 0x74, - 0x74, 0x77, 0x78, 0x7b, 0x81, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x90, 0x96, - 0x9e, 0xa6, 0xa9, 0xad, 0xaf, 0xb0, 0xaf, 0xae, 0xae, 0xb0, 0xaf, 0xac, - 0xa8, 0x9f, 0x98, 0x97, 0x98, 0x98, 0x98, 0x9b, 0xa2, 0xa5, 0xa6, 0xa3, - 0x9e, 0x98, 0x93, 0x91, 0x90, 0x90, 0x93, 0x95, 0x97, 0x9b, 0x9e, 0x86, - 0x91, 0x84, 0x4d, 0x25, 0x21, 0x28, 0x28, 0x1f, 0x1c, 0x1d, 0x1d, 0x1c, - 0x1c, 0x1d, 0x2c, 0x3f, 0x57, 0x84, 0x99, 0x94, 0x8d, 0x97, 0x7e, 0x3f, - 0x5e, 0xa5, 0xad, 0xa7, 0xa4, 0xba, 0xcb, 0xcd, 0xca, 0xc1, 0xba, 0xbb, - 0xc1, 0xc2, 0xc1, 0xc3, 0xc9, 0xcb, 0xcd, 0xd0, 0xd6, 0xd9, 0xd9, 0xd8, - 0xd6, 0xd1, 0xc7, 0xc2, 0xbd, 0xb3, 0xa9, 0xa4, 0xa4, 0xa4, 0xa3, 0xa1, - 0x9b, 0x9a, 0x9b, 0x9c, 0x9c, 0x9e, 0x9b, 0x9b, 0x9b, 0x9b, 0xa0, 0xa2, - 0xa1, 0xa0, 0xa3, 0xa8, 0xad, 0xae, 0xae, 0xb1, 0xb5, 0xb9, 0xba, 0xbb, - 0xb9, 0xb4, 0xa6, 0x96, 0x89, 0x76, 0x67, 0x5b, 0x58, 0x56, 0x55, 0x51, - 0x52, 0x57, 0x59, 0x5c, 0x66, 0x64, 0x65, 0x66, 0x60, 0x40, 0x20, 0x28, - 0x38, 0x52, 0x5b, 0x5c, 0x4b, 0x4f, 0x6b, 0x6d, 0x59, 0x4e, 0x4b, 0x4d, - 0x56, 0x76, 0x89, 0x92, 0x9c, 0xa0, 0x9f, 0x9a, 0x96, 0x8f, 0x8b, 0x8a, - 0x89, 0x88, 0x85, 0x7f, 0x77, 0x72, 0x6e, 0x69, 0x65, 0x69, 0x6d, 0x6e, - 0x71, 0x75, 0x79, 0x7b, 0x7d, 0x7f, 0x80, 0x80, 0x83, 0x84, 0x84, 0x85, - 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x81, 0x81, 0x80, 0x7e, 0x7d, 0x7a, - 0x77, 0x76, 0x74, 0x72, 0x70, 0x70, 0x70, 0x71, 0x6f, 0x6b, 0x69, 0x67, - 0x63, 0x60, 0x5b, 0x57, 0x55, 0x50, 0x4b, 0x44, 0x40, 0x3d, 0x38, 0x31, - 0x29, 0x23, 0x1e, 0x17, 0x12, 0x11, 0x11, 0x11, 0x10, 0x12, 0x12, 0x11, - 0x11, 0x13, 0x13, 0x14, 0x13, 0x13, 0x13, 0x13, 0x5e, 0x5d, 0x5b, 0x5a, - 0x5b, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x59, 0x58, 0x57, 0x56, 0x57, 0x58, - 0x59, 0x58, 0x58, 0x58, 0x5a, 0x5c, 0x5d, 0x5e, 0x5e, 0x60, 0x61, 0x62, - 0x62, 0x65, 0x68, 0x6b, 0x6c, 0x6d, 0x6f, 0x71, 0x71, 0x71, 0x72, 0x73, - 0x73, 0x73, 0x73, 0x73, 0x73, 0x72, 0x70, 0x71, 0x71, 0x71, 0x72, 0x72, - 0x71, 0x70, 0x71, 0x70, 0x71, 0x72, 0x73, 0x73, 0x74, 0x77, 0x79, 0x7b, - 0x81, 0x86, 0x89, 0x8d, 0x90, 0x93, 0x98, 0xa1, 0xaa, 0xb1, 0xb5, 0xb8, - 0xba, 0xb9, 0xb8, 0xb7, 0xb7, 0xb9, 0xb9, 0xb8, 0xb6, 0xaf, 0xa4, 0x9d, - 0x9d, 0x9d, 0x9d, 0xa0, 0xa5, 0xa7, 0xa7, 0xa3, 0x9e, 0x9b, 0x98, 0x97, - 0x97, 0x99, 0x9e, 0xa0, 0xa1, 0xa4, 0xa8, 0x92, 0x92, 0x96, 0x90, 0x52, - 0x2f, 0x25, 0x22, 0x20, 0x1d, 0x1d, 0x1f, 0x23, 0x2d, 0x49, 0x7c, 0x97, - 0x9a, 0x90, 0x98, 0x98, 0x91, 0x99, 0x7e, 0x3e, 0x5d, 0xa8, 0xb2, 0xb0, - 0xb4, 0xc6, 0xca, 0xc9, 0xc7, 0xc1, 0xbd, 0xbe, 0xbf, 0xbf, 0xbd, 0xbf, - 0xc3, 0xc6, 0xc8, 0xcb, 0xcf, 0xd2, 0xd3, 0xd4, 0xd7, 0xd9, 0xd6, 0xd3, - 0xcf, 0xc6, 0xb8, 0xaa, 0xa6, 0xa7, 0xa8, 0xa7, 0xa5, 0xa1, 0xa0, 0x9e, - 0x9e, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0xa3, 0xa6, 0xa8, 0xa8, 0xa9, 0xac, - 0xaf, 0xb1, 0xb3, 0xb7, 0xba, 0xbd, 0xbf, 0xbf, 0xba, 0xaf, 0x9c, 0x8b, - 0x7e, 0x6d, 0x5d, 0x57, 0x57, 0x57, 0x55, 0x50, 0x53, 0x57, 0x5a, 0x5f, - 0x67, 0x6c, 0x6d, 0x6c, 0x67, 0x4d, 0x23, 0x1b, 0x28, 0x49, 0x5c, 0x61, - 0x58, 0x50, 0x4a, 0x5c, 0x5b, 0x47, 0x45, 0x56, 0x69, 0x7e, 0x8e, 0x97, - 0xa3, 0xa6, 0x9f, 0x98, 0x92, 0x8e, 0x8a, 0x8a, 0x8a, 0x89, 0x85, 0x7d, - 0x75, 0x6f, 0x6c, 0x68, 0x64, 0x68, 0x6c, 0x6e, 0x71, 0x77, 0x7b, 0x7d, - 0x7f, 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x87, 0x86, 0x87, 0x86, 0x86, - 0x86, 0x85, 0x82, 0x82, 0x82, 0x80, 0x80, 0x7d, 0x79, 0x77, 0x75, 0x72, - 0x70, 0x70, 0x70, 0x70, 0x6f, 0x6b, 0x69, 0x67, 0x64, 0x60, 0x5b, 0x57, - 0x55, 0x50, 0x4b, 0x44, 0x40, 0x3d, 0x37, 0x31, 0x29, 0x23, 0x1f, 0x18, - 0x12, 0x10, 0x11, 0x11, 0x10, 0x12, 0x12, 0x11, 0x11, 0x12, 0x12, 0x14, - 0x15, 0x14, 0x13, 0x12, 0x5d, 0x5c, 0x5b, 0x5a, 0x5b, 0x5b, 0x5a, 0x5b, - 0x5b, 0x59, 0x58, 0x57, 0x57, 0x57, 0x57, 0x59, 0x59, 0x58, 0x58, 0x58, - 0x59, 0x5a, 0x5c, 0x5c, 0x5d, 0x60, 0x61, 0x61, 0x62, 0x64, 0x67, 0x6a, - 0x6b, 0x6c, 0x6e, 0x70, 0x71, 0x72, 0x72, 0x73, 0x72, 0x72, 0x72, 0x72, - 0x71, 0x71, 0x70, 0x70, 0x70, 0x70, 0x71, 0x72, 0x71, 0x71, 0x71, 0x70, - 0x71, 0x71, 0x72, 0x72, 0x73, 0x75, 0x78, 0x7b, 0x80, 0x85, 0x8a, 0x91, - 0x95, 0x99, 0x9f, 0xa9, 0xb4, 0xba, 0xbc, 0xbe, 0xbf, 0xbf, 0xbe, 0xbd, - 0xbc, 0xbc, 0xbd, 0xbd, 0xbc, 0xb9, 0xaf, 0xa3, 0xa0, 0xa0, 0xa3, 0xa7, - 0xaa, 0xa9, 0xa7, 0xa4, 0xa1, 0x9e, 0x9d, 0x9d, 0x9e, 0xa2, 0xa6, 0xa6, - 0xa6, 0xa7, 0xae, 0x9f, 0x7c, 0x7c, 0x9c, 0x93, 0x61, 0x39, 0x2a, 0x26, - 0x23, 0x28, 0x34, 0x46, 0x6b, 0x99, 0xab, 0x9e, 0x95, 0x94, 0xa3, 0xa1, - 0xa9, 0x99, 0x76, 0x3e, 0x68, 0xae, 0xba, 0xbd, 0xc4, 0xca, 0xca, 0xca, - 0xc8, 0xc3, 0xbf, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbe, 0xc3, 0xc7, 0xca, - 0xcb, 0xce, 0xd0, 0xd2, 0xd5, 0xd9, 0xd9, 0xd9, 0xd7, 0xd2, 0xc4, 0xb4, - 0xad, 0xab, 0xab, 0xa9, 0xa9, 0xa6, 0xa3, 0x9f, 0x9f, 0xa0, 0xa1, 0xa2, - 0xa4, 0xa4, 0xa4, 0xa8, 0xab, 0xaf, 0xb0, 0xb1, 0xb4, 0xb6, 0xb8, 0xbd, - 0xbe, 0xbe, 0xc0, 0xc3, 0xbc, 0xae, 0x97, 0x81, 0x74, 0x64, 0x52, 0x54, - 0x56, 0x55, 0x53, 0x4f, 0x53, 0x57, 0x5b, 0x61, 0x6f, 0x79, 0x75, 0x71, - 0x6d, 0x59, 0x2e, 0x1a, 0x20, 0x3e, 0x59, 0x5f, 0x62, 0x56, 0x3b, 0x45, - 0x57, 0x4f, 0x50, 0x61, 0x73, 0x84, 0x94, 0x9d, 0xa5, 0xa6, 0x9e, 0x95, - 0x90, 0x8c, 0x8a, 0x89, 0x88, 0x88, 0x84, 0x7c, 0x73, 0x6d, 0x6a, 0x66, - 0x62, 0x67, 0x6c, 0x6f, 0x72, 0x77, 0x7c, 0x7e, 0x81, 0x82, 0x82, 0x84, - 0x84, 0x86, 0x86, 0x87, 0x87, 0x89, 0x88, 0x88, 0x87, 0x85, 0x83, 0x83, - 0x82, 0x82, 0x81, 0x7e, 0x7b, 0x79, 0x77, 0x73, 0x71, 0x71, 0x71, 0x70, - 0x6d, 0x6b, 0x6a, 0x68, 0x65, 0x60, 0x5b, 0x57, 0x55, 0x51, 0x4b, 0x44, - 0x40, 0x3d, 0x37, 0x30, 0x29, 0x23, 0x1f, 0x18, 0x12, 0x11, 0x11, 0x11, - 0x10, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x14, 0x15, 0x15, 0x13, 0x12, - 0x5e, 0x5c, 0x5b, 0x5a, 0x5b, 0x5b, 0x5a, 0x5b, 0x5a, 0x59, 0x58, 0x57, - 0x57, 0x57, 0x57, 0x59, 0x58, 0x58, 0x58, 0x58, 0x5a, 0x5a, 0x5b, 0x5b, - 0x5d, 0x5f, 0x60, 0x61, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6d, 0x70, - 0x71, 0x72, 0x72, 0x73, 0x71, 0x71, 0x72, 0x72, 0x70, 0x70, 0x70, 0x6f, - 0x6f, 0x6f, 0x70, 0x71, 0x71, 0x71, 0x71, 0x70, 0x70, 0x71, 0x71, 0x72, - 0x72, 0x74, 0x78, 0x7a, 0x7f, 0x86, 0x8c, 0x93, 0x98, 0x9c, 0xa3, 0xae, - 0xb9, 0xbe, 0xc0, 0xc2, 0xc3, 0xc2, 0xc1, 0xc0, 0xbf, 0xbf, 0xbf, 0xbf, - 0xbf, 0xbd, 0xb5, 0xa9, 0xa4, 0xa3, 0xa6, 0xab, 0xad, 0xaa, 0xa8, 0xa5, - 0xa3, 0xa2, 0xa2, 0xa1, 0xa2, 0xa6, 0xa9, 0xa9, 0xa8, 0xa8, 0xae, 0xa4, - 0x7a, 0x74, 0x90, 0x9f, 0x86, 0x64, 0x56, 0x51, 0x4f, 0x54, 0x63, 0x75, - 0x94, 0xab, 0xa4, 0x97, 0x93, 0x99, 0x9f, 0x9f, 0xaf, 0x95, 0x6e, 0x40, - 0x73, 0xb2, 0xbe, 0xc1, 0xc8, 0xcb, 0xca, 0xcc, 0xca, 0xc4, 0xc0, 0xbd, - 0xba, 0xba, 0xbb, 0xba, 0xbc, 0xc2, 0xc5, 0xc8, 0xc9, 0xcb, 0xce, 0xd0, - 0xd3, 0xd6, 0xd9, 0xd9, 0xd9, 0xd6, 0xca, 0xbb, 0xb3, 0xb0, 0xae, 0xab, - 0xab, 0xa9, 0xa7, 0xa3, 0xa1, 0xa1, 0xa2, 0xa4, 0xa7, 0xa7, 0xa6, 0xa8, - 0xac, 0xb1, 0xb5, 0xb5, 0xb7, 0xb8, 0xbb, 0xbf, 0xc1, 0xc2, 0xc3, 0xc7, - 0xbe, 0xb0, 0x99, 0x7f, 0x70, 0x5e, 0x4f, 0x54, 0x54, 0x53, 0x51, 0x4f, - 0x54, 0x59, 0x5c, 0x64, 0x75, 0x7d, 0x77, 0x72, 0x6d, 0x5f, 0x3a, 0x1e, - 0x1d, 0x34, 0x51, 0x59, 0x5e, 0x57, 0x42, 0x49, 0x57, 0x56, 0x59, 0x66, - 0x75, 0x86, 0x96, 0x9f, 0xa5, 0xa6, 0x9e, 0x94, 0x8f, 0x8c, 0x89, 0x88, - 0x87, 0x86, 0x83, 0x7c, 0x72, 0x6c, 0x69, 0x66, 0x62, 0x66, 0x6c, 0x6e, - 0x72, 0x77, 0x7c, 0x7f, 0x81, 0x82, 0x83, 0x85, 0x85, 0x86, 0x87, 0x87, - 0x87, 0x89, 0x89, 0x89, 0x88, 0x86, 0x84, 0x83, 0x83, 0x83, 0x81, 0x7f, - 0x7c, 0x7a, 0x77, 0x73, 0x71, 0x71, 0x70, 0x6f, 0x6d, 0x6b, 0x6a, 0x68, - 0x64, 0x60, 0x5b, 0x58, 0x55, 0x51, 0x4b, 0x44, 0x40, 0x3d, 0x38, 0x32, - 0x2a, 0x23, 0x1f, 0x18, 0x13, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x12, 0x12, 0x13, 0x14, 0x15, 0x15, 0x13, 0x12, 0x60, 0x5d, 0x5b, 0x5b, - 0x5a, 0x5b, 0x5a, 0x5b, 0x5a, 0x58, 0x58, 0x57, 0x57, 0x57, 0x57, 0x59, - 0x58, 0x57, 0x57, 0x57, 0x59, 0x59, 0x59, 0x5a, 0x5c, 0x5f, 0x60, 0x60, - 0x62, 0x63, 0x65, 0x67, 0x69, 0x6a, 0x6c, 0x6f, 0x70, 0x70, 0x71, 0x71, - 0x70, 0x71, 0x71, 0x71, 0x6f, 0x6f, 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x71, - 0x71, 0x71, 0x70, 0x70, 0x6f, 0x6f, 0x70, 0x71, 0x71, 0x73, 0x77, 0x7a, - 0x7f, 0x88, 0x90, 0x98, 0x9d, 0xa1, 0xa9, 0xb4, 0xbc, 0xc2, 0xc5, 0xc7, - 0xc9, 0xc7, 0xc4, 0xc2, 0xc1, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xbc, 0xb2, - 0xab, 0xa9, 0xab, 0xb0, 0xb2, 0xae, 0xab, 0xa8, 0xa7, 0xa8, 0xa9, 0xa9, - 0xa8, 0xa9, 0xab, 0xaa, 0xa9, 0xa7, 0xa8, 0xa5, 0x8f, 0x82, 0x7a, 0x83, - 0xa4, 0xa9, 0xa8, 0xa9, 0xab, 0xa7, 0xb0, 0xb6, 0xb0, 0x8c, 0x7a, 0x99, - 0xa8, 0xa3, 0x88, 0x90, 0xa1, 0x80, 0x5f, 0x45, 0x80, 0xb6, 0xbf, 0xc0, - 0xc6, 0xca, 0xcb, 0xcd, 0xcd, 0xc8, 0xc0, 0xbc, 0xb9, 0xb8, 0xba, 0xba, - 0xba, 0xc0, 0xc3, 0xc4, 0xc7, 0xc7, 0xc9, 0xcc, 0xce, 0xd1, 0xd5, 0xd7, - 0xd8, 0xd7, 0xd1, 0xc7, 0xbe, 0xb9, 0xb5, 0xb1, 0xaf, 0xae, 0xad, 0xaa, - 0xa5, 0xa4, 0xa5, 0xa7, 0xaa, 0xad, 0xac, 0xab, 0xac, 0xb3, 0xb9, 0xb9, - 0xb9, 0xb9, 0xbe, 0xc2, 0xc6, 0xc9, 0xcb, 0xcd, 0xc2, 0xb6, 0xa1, 0x82, - 0x6f, 0x5d, 0x53, 0x57, 0x54, 0x52, 0x52, 0x52, 0x58, 0x5e, 0x61, 0x67, - 0x77, 0x7e, 0x76, 0x6f, 0x67, 0x63, 0x4f, 0x2d, 0x1f, 0x23, 0x42, 0x4e, - 0x4f, 0x52, 0x5c, 0x67, 0x5f, 0x5d, 0x60, 0x67, 0x73, 0x88, 0x98, 0x9f, - 0xa5, 0xa6, 0x9f, 0x94, 0x8f, 0x8b, 0x89, 0x87, 0x86, 0x85, 0x83, 0x7c, - 0x72, 0x6b, 0x68, 0x65, 0x61, 0x65, 0x6a, 0x6e, 0x72, 0x79, 0x7e, 0x80, - 0x82, 0x83, 0x84, 0x86, 0x87, 0x88, 0x88, 0x88, 0x89, 0x8a, 0x89, 0x89, - 0x88, 0x86, 0x84, 0x84, 0x84, 0x84, 0x82, 0x80, 0x7d, 0x7b, 0x78, 0x74, - 0x72, 0x71, 0x71, 0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x64, 0x5f, 0x5b, 0x57, - 0x54, 0x50, 0x4a, 0x43, 0x3f, 0x3d, 0x39, 0x33, 0x2c, 0x25, 0x20, 0x18, - 0x13, 0x12, 0x11, 0x11, 0x11, 0x11, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, - 0x15, 0x15, 0x13, 0x12, 0x66, 0x60, 0x5d, 0x5c, 0x5b, 0x5b, 0x5b, 0x5b, - 0x5a, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, - 0x58, 0x58, 0x58, 0x59, 0x5b, 0x5e, 0x60, 0x61, 0x62, 0x63, 0x64, 0x67, - 0x68, 0x69, 0x6b, 0x6e, 0x6e, 0x6f, 0x70, 0x71, 0x71, 0x71, 0x71, 0x70, - 0x6f, 0x6e, 0x6d, 0x6d, 0x6d, 0x6c, 0x6d, 0x6f, 0x6f, 0x6f, 0x6f, 0x6e, - 0x6d, 0x6e, 0x6f, 0x6f, 0x70, 0x73, 0x77, 0x7b, 0x82, 0x8d, 0x96, 0x9f, - 0xa4, 0xa8, 0xb1, 0xb9, 0xc0, 0xc6, 0xc8, 0xca, 0xcb, 0xca, 0xc8, 0xc7, - 0xc5, 0xc6, 0xc6, 0xc6, 0xc6, 0xc4, 0xc1, 0xbc, 0xb5, 0xb2, 0xb1, 0xb6, - 0xb7, 0xb3, 0xb0, 0xac, 0xab, 0xad, 0xae, 0xae, 0xae, 0xac, 0xac, 0xab, - 0xab, 0xa8, 0xa7, 0xaa, 0xa2, 0x96, 0x88, 0x8c, 0x8c, 0x8a, 0x90, 0xa1, - 0xa4, 0x95, 0x9f, 0xa2, 0x9a, 0x8e, 0x89, 0xab, 0xba, 0xaf, 0x8b, 0x99, - 0x96, 0x5d, 0x41, 0x47, 0x86, 0xb7, 0xbe, 0xc0, 0xc4, 0xc9, 0xca, 0xcc, - 0xcc, 0xc9, 0xbe, 0xb8, 0xb6, 0xb6, 0xb8, 0xb8, 0xb8, 0xbb, 0xbe, 0xbf, - 0xc2, 0xc2, 0xc4, 0xc5, 0xc8, 0xcd, 0xd1, 0xd2, 0xd3, 0xd5, 0xd8, 0xd3, - 0xc9, 0xc2, 0xbb, 0xb7, 0xb7, 0xb6, 0xb5, 0xb3, 0xac, 0xa7, 0xa7, 0xa8, - 0xad, 0xb1, 0xb1, 0xb0, 0xb0, 0xb3, 0xba, 0xbd, 0xbb, 0xbc, 0xc1, 0xc5, - 0xcb, 0xd0, 0xd2, 0xd1, 0xc4, 0xbb, 0xa6, 0x84, 0x6f, 0x5f, 0x5a, 0x5a, - 0x54, 0x51, 0x52, 0x55, 0x5a, 0x5f, 0x60, 0x62, 0x71, 0x7c, 0x74, 0x6a, - 0x60, 0x61, 0x60, 0x48, 0x33, 0x1e, 0x29, 0x3e, 0x41, 0x4b, 0x63, 0x6d, - 0x5f, 0x56, 0x58, 0x66, 0x74, 0x88, 0x97, 0x9f, 0xa5, 0xa5, 0x9c, 0x91, - 0x8c, 0x88, 0x86, 0x86, 0x86, 0x85, 0x82, 0x7c, 0x72, 0x6c, 0x69, 0x66, - 0x60, 0x62, 0x69, 0x6d, 0x72, 0x7a, 0x80, 0x82, 0x83, 0x84, 0x87, 0x88, - 0x89, 0x8b, 0x8b, 0x8b, 0x8b, 0x8c, 0x8b, 0x8a, 0x8a, 0x88, 0x86, 0x86, - 0x85, 0x85, 0x83, 0x81, 0x7f, 0x7c, 0x79, 0x76, 0x74, 0x72, 0x71, 0x6f, - 0x6c, 0x6b, 0x69, 0x67, 0x64, 0x5e, 0x5b, 0x57, 0x54, 0x51, 0x4b, 0x43, - 0x3f, 0x3d, 0x38, 0x32, 0x2b, 0x25, 0x20, 0x18, 0x13, 0x11, 0x11, 0x11, - 0x12, 0x11, 0x10, 0x11, 0x12, 0x12, 0x12, 0x13, 0x15, 0x14, 0x13, 0x12, - 0x6b, 0x64, 0x5f, 0x5c, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x59, 0x56, - 0x56, 0x56, 0x57, 0x57, 0x56, 0x57, 0x57, 0x58, 0x58, 0x58, 0x58, 0x5a, - 0x5b, 0x5c, 0x5e, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67, 0x69, 0x69, 0x6b, - 0x6c, 0x6e, 0x70, 0x72, 0x72, 0x71, 0x71, 0x70, 0x6f, 0x6d, 0x6c, 0x6c, - 0x6c, 0x6c, 0x6c, 0x6d, 0x6c, 0x6c, 0x6d, 0x6d, 0x6c, 0x6d, 0x6d, 0x6d, - 0x6d, 0x70, 0x77, 0x7d, 0x86, 0x93, 0x9c, 0xa6, 0xac, 0xb0, 0xb7, 0xbd, - 0xc3, 0xc8, 0xca, 0xca, 0xca, 0xcb, 0xca, 0xc9, 0xc8, 0xc6, 0xc7, 0xc8, - 0xc7, 0xc6, 0xc3, 0xbf, 0xbb, 0xb8, 0xb6, 0xb9, 0xba, 0xb8, 0xb6, 0xb1, - 0xae, 0xb0, 0xb1, 0xb1, 0xb0, 0xad, 0xad, 0xad, 0xac, 0xaa, 0xa8, 0xa7, - 0x98, 0x91, 0x92, 0x9b, 0x95, 0x8e, 0x92, 0x9e, 0x90, 0x98, 0x92, 0x90, - 0x95, 0x91, 0xa0, 0xb5, 0xba, 0xb0, 0x9b, 0xad, 0x8f, 0x45, 0x31, 0x51, - 0x8f, 0xb7, 0xc2, 0xc3, 0xc3, 0xc7, 0xc4, 0xc7, 0xc7, 0xc2, 0xba, 0xb5, - 0xb5, 0xb7, 0xb9, 0xb5, 0xb8, 0xb9, 0xb9, 0xbd, 0xc0, 0xbe, 0xbe, 0xbf, - 0xc2, 0xc8, 0xcb, 0xcc, 0xcd, 0xd0, 0xd9, 0xda, 0xd2, 0xcb, 0xc1, 0xb9, - 0xbd, 0xbe, 0xbe, 0xbb, 0xb5, 0xb0, 0xae, 0xae, 0xb1, 0xb5, 0xb6, 0xb3, - 0xb3, 0xb6, 0xbd, 0xc2, 0xc1, 0xc2, 0xc5, 0xc4, 0xc7, 0xca, 0xcc, 0xcc, - 0xc4, 0xbc, 0xa5, 0x85, 0x72, 0x60, 0x5e, 0x5b, 0x55, 0x52, 0x53, 0x57, - 0x5b, 0x5b, 0x5b, 0x5d, 0x6d, 0x7c, 0x7c, 0x77, 0x6d, 0x64, 0x65, 0x5d, - 0x4b, 0x2b, 0x1f, 0x2c, 0x3f, 0x4c, 0x5b, 0x5f, 0x58, 0x55, 0x5a, 0x68, - 0x74, 0x86, 0x93, 0x9a, 0xa2, 0xa1, 0x98, 0x8e, 0x89, 0x85, 0x83, 0x84, - 0x85, 0x84, 0x81, 0x79, 0x70, 0x6a, 0x67, 0x64, 0x5f, 0x60, 0x67, 0x6b, - 0x71, 0x7a, 0x80, 0x84, 0x85, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8c, 0x8c, - 0x8c, 0x8d, 0x8c, 0x8c, 0x8b, 0x89, 0x88, 0x87, 0x87, 0x86, 0x85, 0x82, - 0x81, 0x7f, 0x7b, 0x78, 0x75, 0x73, 0x72, 0x70, 0x6d, 0x6b, 0x68, 0x66, - 0x63, 0x5d, 0x5a, 0x55, 0x52, 0x50, 0x4a, 0x44, 0x40, 0x3d, 0x37, 0x30, - 0x2b, 0x22, 0x1d, 0x18, 0x13, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x13, 0x13, 0x12, 0x13, 0x15, 0x15, 0x13, 0x12, 0x6f, 0x68, 0x62, 0x5f, - 0x5c, 0x5b, 0x5b, 0x5b, 0x5b, 0x59, 0x59, 0x57, 0x57, 0x56, 0x56, 0x57, - 0x58, 0x57, 0x58, 0x59, 0x58, 0x57, 0x58, 0x59, 0x5b, 0x5c, 0x5d, 0x5f, - 0x60, 0x61, 0x63, 0x64, 0x66, 0x67, 0x6a, 0x6c, 0x6d, 0x6e, 0x70, 0x72, - 0x72, 0x71, 0x71, 0x71, 0x70, 0x6d, 0x6c, 0x6c, 0x6b, 0x6c, 0x6b, 0x6c, - 0x6b, 0x6b, 0x6c, 0x6c, 0x6b, 0x6c, 0x6c, 0x6b, 0x6d, 0x71, 0x79, 0x80, - 0x8c, 0x98, 0xa0, 0xaa, 0xb1, 0xb5, 0xb9, 0xbf, 0xc5, 0xc9, 0xca, 0xcb, - 0xcc, 0xcd, 0xcc, 0xcb, 0xc9, 0xc7, 0xc5, 0xc6, 0xc6, 0xc6, 0xc2, 0xbf, - 0xbd, 0xbc, 0xba, 0xbb, 0xbd, 0xbd, 0xba, 0xb5, 0xb1, 0xb0, 0xb2, 0xb2, - 0xb1, 0xae, 0xad, 0xad, 0xad, 0xab, 0xa9, 0xa8, 0xa2, 0x9f, 0xa1, 0xa5, - 0x8e, 0x8f, 0x8f, 0x8b, 0x99, 0xa8, 0xa5, 0x9e, 0x97, 0xa8, 0xb4, 0xb3, - 0xa5, 0x8e, 0xa1, 0xa7, 0x78, 0x36, 0x2a, 0x53, 0x99, 0xbb, 0xc4, 0xc4, - 0xc4, 0xc5, 0xc2, 0xc3, 0xc2, 0xbb, 0xbb, 0xb8, 0xb7, 0xb8, 0xb9, 0xb7, - 0xba, 0xb8, 0xb8, 0xbb, 0xbf, 0xbe, 0xbd, 0xbd, 0xbf, 0xc3, 0xc6, 0xc6, - 0xc7, 0xcc, 0xd9, 0xde, 0xd9, 0xd2, 0xc5, 0xbb, 0xc0, 0xc5, 0xc5, 0xc3, - 0xbd, 0xb8, 0xb5, 0xb4, 0xb3, 0xb8, 0xba, 0xb7, 0xb8, 0xbc, 0xc2, 0xc6, - 0xc6, 0xc6, 0xc4, 0xc1, 0xc0, 0xc4, 0xc6, 0xc7, 0xc3, 0xb8, 0xa1, 0x8b, - 0x79, 0x63, 0x60, 0x5d, 0x57, 0x54, 0x53, 0x59, 0x5d, 0x5a, 0x5a, 0x61, - 0x73, 0x82, 0x85, 0x82, 0x76, 0x68, 0x66, 0x63, 0x5a, 0x44, 0x32, 0x31, - 0x43, 0x4c, 0x4f, 0x55, 0x5b, 0x5a, 0x5c, 0x68, 0x74, 0x83, 0x8f, 0x95, - 0x9b, 0x9a, 0x93, 0x8c, 0x88, 0x84, 0x82, 0x83, 0x84, 0x83, 0x80, 0x78, - 0x6f, 0x69, 0x67, 0x63, 0x5e, 0x5f, 0x66, 0x6b, 0x71, 0x7b, 0x82, 0x85, - 0x86, 0x87, 0x88, 0x8b, 0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8d, 0x8d, 0x8c, - 0x8c, 0x8a, 0x89, 0x89, 0x89, 0x88, 0x86, 0x85, 0x83, 0x81, 0x7c, 0x78, - 0x75, 0x73, 0x72, 0x70, 0x6d, 0x6b, 0x68, 0x66, 0x63, 0x5e, 0x5a, 0x55, - 0x52, 0x4f, 0x48, 0x44, 0x40, 0x3c, 0x36, 0x30, 0x2a, 0x22, 0x1d, 0x18, - 0x13, 0x12, 0x11, 0x11, 0x11, 0x12, 0x11, 0x12, 0x13, 0x13, 0x12, 0x13, - 0x15, 0x16, 0x14, 0x12, 0x73, 0x6b, 0x64, 0x60, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5b, 0x5a, 0x59, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x59, - 0x58, 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5e, 0x5f, 0x60, 0x62, 0x63, - 0x66, 0x67, 0x6a, 0x6c, 0x6d, 0x6f, 0x70, 0x72, 0x71, 0x71, 0x71, 0x71, - 0x70, 0x6d, 0x6c, 0x6c, 0x6b, 0x6b, 0x6a, 0x6b, 0x6a, 0x6b, 0x6c, 0x6c, - 0x6a, 0x6b, 0x6b, 0x6a, 0x6c, 0x72, 0x7b, 0x83, 0x8f, 0x9b, 0xa3, 0xad, - 0xb3, 0xb7, 0xba, 0xc0, 0xc6, 0xc9, 0xca, 0xcb, 0xcc, 0xce, 0xce, 0xcd, - 0xca, 0xc7, 0xc4, 0xc4, 0xc5, 0xc5, 0xc2, 0xbe, 0xbd, 0xbc, 0xba, 0xbb, - 0xbe, 0xbf, 0xbd, 0xb8, 0xb3, 0xb2, 0xb3, 0xb4, 0xb2, 0xaf, 0xae, 0xae, - 0xae, 0xad, 0xaa, 0xa9, 0xab, 0xa9, 0xa6, 0xa3, 0x94, 0x98, 0x95, 0x8c, - 0xa6, 0xac, 0xa1, 0x9b, 0x9f, 0xb3, 0xb8, 0xab, 0x9b, 0x8a, 0xa2, 0xa2, - 0x6a, 0x2f, 0x29, 0x58, 0xa0, 0xbe, 0xc4, 0xc5, 0xc4, 0xc6, 0xc4, 0xc4, - 0xc0, 0xb9, 0xbb, 0xba, 0xb7, 0xb7, 0xb9, 0xb8, 0xba, 0xb8, 0xb7, 0xba, - 0xbe, 0xbe, 0xbe, 0xbe, 0xbd, 0xc0, 0xc1, 0xc2, 0xc4, 0xc9, 0xd7, 0xde, - 0xda, 0xd4, 0xc6, 0xbc, 0xc0, 0xc7, 0xc8, 0xc8, 0xc3, 0xbe, 0xbb, 0xb8, - 0xb6, 0xb9, 0xbc, 0xba, 0xbb, 0xbf, 0xc3, 0xc7, 0xc8, 0xc6, 0xc2, 0xbe, - 0xbe, 0xc0, 0xc3, 0xc6, 0xc3, 0xb3, 0x9e, 0x8f, 0x80, 0x68, 0x62, 0x5f, - 0x59, 0x55, 0x54, 0x5a, 0x5f, 0x5c, 0x5c, 0x66, 0x75, 0x80, 0x86, 0x85, - 0x7a, 0x6c, 0x67, 0x65, 0x60, 0x53, 0x41, 0x3b, 0x48, 0x4f, 0x51, 0x57, - 0x5f, 0x5a, 0x5c, 0x67, 0x73, 0x80, 0x8b, 0x91, 0x96, 0x96, 0x90, 0x8b, - 0x88, 0x83, 0x82, 0x83, 0x83, 0x82, 0x7f, 0x77, 0x6e, 0x68, 0x66, 0x63, - 0x5e, 0x5e, 0x65, 0x6a, 0x71, 0x7b, 0x82, 0x85, 0x87, 0x87, 0x89, 0x8b, - 0x8d, 0x8d, 0x8e, 0x8f, 0x8f, 0x8e, 0x8d, 0x8d, 0x8d, 0x8b, 0x8a, 0x8a, - 0x8a, 0x89, 0x87, 0x86, 0x84, 0x82, 0x7d, 0x78, 0x75, 0x74, 0x72, 0x70, - 0x6d, 0x6a, 0x68, 0x66, 0x64, 0x5f, 0x5a, 0x55, 0x52, 0x4e, 0x48, 0x43, - 0x40, 0x3c, 0x36, 0x31, 0x2a, 0x23, 0x1e, 0x18, 0x14, 0x12, 0x11, 0x11, - 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x15, 0x14, 0x12, - 0x78, 0x6f, 0x68, 0x64, 0x5f, 0x5c, 0x5d, 0x5d, 0x5c, 0x5b, 0x59, 0x59, - 0x58, 0x57, 0x57, 0x57, 0x58, 0x59, 0x59, 0x58, 0x59, 0x59, 0x59, 0x59, - 0x59, 0x5b, 0x5c, 0x5e, 0x5f, 0x61, 0x62, 0x64, 0x66, 0x68, 0x69, 0x6b, - 0x6d, 0x6f, 0x70, 0x71, 0x71, 0x70, 0x70, 0x71, 0x70, 0x6d, 0x6b, 0x6b, - 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x69, 0x6a, 0x6a, 0x6a, - 0x6b, 0x73, 0x7f, 0x88, 0x94, 0xa1, 0xa9, 0xb0, 0xb5, 0xb7, 0xbb, 0xc0, - 0xc6, 0xc8, 0xc9, 0xcb, 0xce, 0xd0, 0xd0, 0xd0, 0xcd, 0xc8, 0xc4, 0xc3, - 0xc2, 0xc2, 0xc1, 0xbe, 0xbc, 0xbb, 0xb9, 0xba, 0xbf, 0xc0, 0xbf, 0xbb, - 0xb6, 0xb4, 0xb5, 0xb5, 0xb3, 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xaa, 0xab, - 0xb2, 0xb0, 0xa3, 0x9b, 0xad, 0xb1, 0xad, 0xa8, 0xb3, 0xa2, 0x87, 0x8c, - 0xad, 0xb1, 0xab, 0x99, 0x98, 0xa4, 0xa1, 0xa0, 0x5e, 0x2e, 0x32, 0x6a, - 0xab, 0xc0, 0xc5, 0xc6, 0xc5, 0xca, 0xca, 0xc7, 0xc1, 0xb9, 0xbc, 0xb9, - 0xb4, 0xb4, 0xb8, 0xba, 0xb8, 0xb6, 0xb6, 0xb8, 0xbd, 0xbe, 0xbe, 0xbd, - 0xbb, 0xbc, 0xbc, 0xbc, 0xbe, 0xc5, 0xd3, 0xdb, 0xd8, 0xd1, 0xc6, 0xbe, - 0xc1, 0xc6, 0xc9, 0xca, 0xc7, 0xc4, 0xc2, 0xc0, 0xbc, 0xbb, 0xbe, 0xbe, - 0xbf, 0xc2, 0xc3, 0xc5, 0xc7, 0xc5, 0xbd, 0xba, 0xbb, 0xbe, 0xc2, 0xc6, - 0xc1, 0xac, 0x9b, 0x94, 0x89, 0x72, 0x66, 0x61, 0x5b, 0x57, 0x55, 0x5a, - 0x5e, 0x61, 0x64, 0x6a, 0x70, 0x76, 0x81, 0x82, 0x7b, 0x73, 0x6a, 0x65, - 0x62, 0x5c, 0x52, 0x4b, 0x4f, 0x56, 0x60, 0x63, 0x5f, 0x55, 0x57, 0x65, - 0x73, 0x7c, 0x84, 0x8a, 0x90, 0x91, 0x8e, 0x8a, 0x87, 0x83, 0x81, 0x82, - 0x82, 0x81, 0x7e, 0x76, 0x6e, 0x67, 0x64, 0x61, 0x5e, 0x5d, 0x64, 0x69, - 0x71, 0x7b, 0x83, 0x86, 0x87, 0x88, 0x8a, 0x8d, 0x8f, 0x8f, 0x8f, 0x90, - 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8b, 0x8b, 0x8b, 0x89, 0x88, 0x87, - 0x85, 0x83, 0x7f, 0x7b, 0x77, 0x75, 0x73, 0x71, 0x6c, 0x6a, 0x68, 0x66, - 0x63, 0x5e, 0x5a, 0x56, 0x53, 0x4e, 0x49, 0x42, 0x3e, 0x3b, 0x36, 0x31, - 0x2c, 0x27, 0x22, 0x1a, 0x13, 0x12, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, - 0x12, 0x12, 0x14, 0x14, 0x15, 0x16, 0x15, 0x14, 0x80, 0x76, 0x6e, 0x6a, - 0x64, 0x5f, 0x5c, 0x5d, 0x5d, 0x5c, 0x5a, 0x5a, 0x58, 0x57, 0x57, 0x58, - 0x5a, 0x59, 0x59, 0x58, 0x58, 0x5a, 0x5a, 0x5a, 0x59, 0x5b, 0x5d, 0x5e, - 0x5f, 0x60, 0x61, 0x64, 0x65, 0x67, 0x67, 0x6a, 0x6d, 0x6e, 0x6e, 0x6f, - 0x71, 0x70, 0x71, 0x71, 0x6f, 0x6d, 0x6b, 0x6b, 0x6a, 0x69, 0x69, 0x69, - 0x6a, 0x6a, 0x69, 0x69, 0x66, 0x67, 0x68, 0x68, 0x6c, 0x79, 0x87, 0x8f, - 0x9a, 0xa5, 0xac, 0xb2, 0xb7, 0xba, 0xbd, 0xc2, 0xc6, 0xc7, 0xc8, 0xcb, - 0xcf, 0xd1, 0xd2, 0xd2, 0xcf, 0xca, 0xc5, 0xc2, 0xc0, 0xbe, 0xbf, 0xbd, - 0xbb, 0xb9, 0xb7, 0xb9, 0xbe, 0xc1, 0xc0, 0xbd, 0xb9, 0xb6, 0xb6, 0xb6, - 0xb4, 0xb0, 0xae, 0xaf, 0xb0, 0xaf, 0xac, 0xac, 0xaf, 0xae, 0xa9, 0xaa, - 0xaf, 0xb8, 0xbc, 0xb9, 0x9d, 0x84, 0x93, 0xa3, 0xae, 0x9d, 0x97, 0x92, - 0x9c, 0xb2, 0xa2, 0x99, 0x4f, 0x37, 0x4c, 0x89, 0xb3, 0xc1, 0xc7, 0xc9, - 0xcb, 0xcf, 0xcf, 0xca, 0xc5, 0xbe, 0xbe, 0xbd, 0xbb, 0xb9, 0xb7, 0xbb, - 0xb8, 0xb6, 0xb6, 0xb7, 0xbb, 0xbc, 0xba, 0xb9, 0xba, 0xbc, 0xb9, 0xb8, - 0xba, 0xbf, 0xcb, 0xd1, 0xcb, 0xc6, 0xc1, 0xbd, 0xc0, 0xc4, 0xc7, 0xc9, - 0xc8, 0xc6, 0xc7, 0xc6, 0xc1, 0xbd, 0xbe, 0xc0, 0xc1, 0xc1, 0xc1, 0xc1, - 0xc1, 0xbf, 0xba, 0xba, 0xbd, 0xc0, 0xc3, 0xc6, 0xba, 0xa3, 0x97, 0x95, - 0x8e, 0x7b, 0x6b, 0x64, 0x60, 0x5d, 0x5a, 0x5e, 0x63, 0x65, 0x67, 0x6b, - 0x6e, 0x75, 0x7f, 0x81, 0x7d, 0x78, 0x6c, 0x66, 0x63, 0x5e, 0x5b, 0x55, - 0x52, 0x54, 0x5d, 0x5c, 0x55, 0x4c, 0x4f, 0x63, 0x73, 0x79, 0x7e, 0x81, - 0x87, 0x8a, 0x89, 0x86, 0x84, 0x82, 0x81, 0x83, 0x83, 0x82, 0x7d, 0x75, - 0x6c, 0x65, 0x63, 0x60, 0x5c, 0x5b, 0x61, 0x67, 0x70, 0x7c, 0x84, 0x87, - 0x89, 0x8a, 0x8c, 0x8e, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, - 0x90, 0x8f, 0x8d, 0x8d, 0x8d, 0x8b, 0x8a, 0x88, 0x86, 0x84, 0x82, 0x7d, - 0x79, 0x77, 0x76, 0x72, 0x6e, 0x6a, 0x67, 0x65, 0x61, 0x5d, 0x5a, 0x55, - 0x53, 0x4e, 0x47, 0x41, 0x3d, 0x3a, 0x35, 0x31, 0x2b, 0x27, 0x22, 0x1a, - 0x13, 0x12, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, - 0x16, 0x16, 0x14, 0x15, 0x85, 0x7d, 0x76, 0x71, 0x69, 0x61, 0x5c, 0x5d, - 0x5d, 0x5b, 0x5a, 0x5a, 0x58, 0x58, 0x58, 0x5b, 0x5c, 0x5b, 0x5b, 0x59, - 0x58, 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x64, - 0x64, 0x65, 0x67, 0x68, 0x6b, 0x6c, 0x6d, 0x6e, 0x70, 0x70, 0x70, 0x70, - 0x6f, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x68, 0x69, 0x69, 0x69, 0x67, 0x66, - 0x64, 0x64, 0x64, 0x66, 0x6e, 0x7e, 0x8e, 0x96, 0xa0, 0xaa, 0xb0, 0xb4, - 0xb8, 0xbb, 0xbd, 0xc3, 0xc6, 0xc7, 0xc8, 0xcb, 0xd0, 0xd3, 0xd3, 0xd3, - 0xd1, 0xcd, 0xc8, 0xc4, 0xc1, 0xbd, 0xbb, 0xbb, 0xb9, 0xb8, 0xb7, 0xb9, - 0xbe, 0xc1, 0xc2, 0xc1, 0xbd, 0xb8, 0xb7, 0xb7, 0xb5, 0xb1, 0xae, 0xaf, - 0xaf, 0xae, 0xae, 0xae, 0xae, 0xb1, 0xb4, 0xb3, 0xb2, 0xb8, 0xb1, 0x99, - 0x91, 0xa3, 0xb5, 0xbb, 0xb1, 0x8d, 0xad, 0xb4, 0xb3, 0xb3, 0xa8, 0x89, - 0x46, 0x51, 0x6f, 0x9e, 0xb8, 0xc3, 0xc8, 0xca, 0xcd, 0xcf, 0xce, 0xc9, - 0xc6, 0xc1, 0xbc, 0xbd, 0xbd, 0xbb, 0xb7, 0xb6, 0xb5, 0xb5, 0xb5, 0xb5, - 0xba, 0xbc, 0xbb, 0xbb, 0xbe, 0xbe, 0xbb, 0xb9, 0xba, 0xbf, 0xc5, 0xc4, - 0xc0, 0xbe, 0xbe, 0xbe, 0xc0, 0xc4, 0xc6, 0xc7, 0xc7, 0xc7, 0xc6, 0xc5, - 0xc3, 0xc0, 0xbf, 0xc0, 0xc0, 0xbf, 0xbc, 0xbc, 0xbb, 0xba, 0xb9, 0xbc, - 0xc0, 0xc4, 0xc5, 0xc2, 0xaf, 0x9c, 0x95, 0x94, 0x8f, 0x81, 0x71, 0x6c, - 0x68, 0x63, 0x5b, 0x5f, 0x65, 0x67, 0x67, 0x68, 0x6f, 0x74, 0x7c, 0x80, - 0x80, 0x7d, 0x75, 0x6e, 0x68, 0x60, 0x5c, 0x58, 0x50, 0x50, 0x58, 0x58, - 0x4e, 0x47, 0x4c, 0x5f, 0x73, 0x77, 0x78, 0x7a, 0x7f, 0x82, 0x81, 0x80, - 0x7f, 0x7d, 0x7c, 0x7e, 0x7f, 0x7e, 0x7a, 0x73, 0x6a, 0x65, 0x62, 0x5f, - 0x5b, 0x59, 0x5e, 0x64, 0x6e, 0x7c, 0x85, 0x89, 0x8b, 0x8c, 0x8d, 0x90, - 0x92, 0x92, 0x92, 0x92, 0x92, 0x94, 0x93, 0x92, 0x91, 0x91, 0x8f, 0x90, - 0x8f, 0x8e, 0x8c, 0x8b, 0x88, 0x87, 0x84, 0x81, 0x7c, 0x79, 0x77, 0x74, - 0x70, 0x6c, 0x67, 0x64, 0x60, 0x5c, 0x59, 0x55, 0x52, 0x4c, 0x47, 0x40, - 0x3b, 0x38, 0x33, 0x2f, 0x29, 0x24, 0x20, 0x19, 0x13, 0x12, 0x11, 0x11, - 0x12, 0x12, 0x11, 0x13, 0x13, 0x13, 0x14, 0x13, 0x14, 0x14, 0x13, 0x14, - 0x8a, 0x82, 0x7b, 0x75, 0x6d, 0x64, 0x5e, 0x5b, 0x5a, 0x5a, 0x5a, 0x59, - 0x58, 0x58, 0x58, 0x5b, 0x5c, 0x5b, 0x5b, 0x59, 0x59, 0x58, 0x59, 0x59, - 0x59, 0x5a, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x64, 0x65, 0x65, 0x66, 0x67, - 0x6a, 0x6d, 0x6e, 0x6e, 0x70, 0x6f, 0x6e, 0x6e, 0x6d, 0x6c, 0x6b, 0x6b, - 0x6a, 0x69, 0x67, 0x67, 0x67, 0x67, 0x66, 0x66, 0x63, 0x63, 0x63, 0x65, - 0x70, 0x84, 0x94, 0x9d, 0xa5, 0xac, 0xb2, 0xb5, 0xb8, 0xbb, 0xbf, 0xc3, - 0xc6, 0xc7, 0xc8, 0xcc, 0xd0, 0xd3, 0xd3, 0xd3, 0xd3, 0xd0, 0xca, 0xc7, - 0xc3, 0xbe, 0xba, 0xb9, 0xb8, 0xb8, 0xb6, 0xb9, 0xbe, 0xc1, 0xc2, 0xc3, - 0xbf, 0xba, 0xb7, 0xb7, 0xb6, 0xb2, 0xaf, 0xae, 0xae, 0xae, 0xaf, 0xaf, - 0xaf, 0xb1, 0xb4, 0xaf, 0xb6, 0xb3, 0x9c, 0x76, 0xa1, 0xc0, 0xc2, 0xc0, - 0xaf, 0x7f, 0xac, 0xbd, 0xba, 0xaf, 0xa7, 0x79, 0x47, 0x6b, 0x8c, 0xaa, - 0xbc, 0xc4, 0xca, 0xcc, 0xcc, 0xcc, 0xcb, 0xc9, 0xc6, 0xc1, 0xbb, 0xbc, - 0xbc, 0xbb, 0xba, 0xb6, 0xb3, 0xb3, 0xb3, 0xb5, 0xb9, 0xbd, 0xbe, 0xbe, - 0xc1, 0xbf, 0xbb, 0xbc, 0xbf, 0xc7, 0xcb, 0xc6, 0xc1, 0xbf, 0xbf, 0xc0, - 0xc3, 0xc5, 0xc6, 0xc5, 0xc6, 0xc6, 0xc5, 0xc4, 0xc3, 0xc1, 0xc0, 0xc0, - 0xbf, 0xbd, 0xbb, 0xbb, 0xba, 0xb8, 0xb8, 0xbc, 0xc2, 0xc5, 0xc4, 0xbd, - 0xa8, 0x98, 0x92, 0x91, 0x8d, 0x80, 0x71, 0x6e, 0x6c, 0x66, 0x5b, 0x60, - 0x66, 0x67, 0x67, 0x66, 0x6f, 0x75, 0x7a, 0x7e, 0x81, 0x80, 0x7e, 0x76, - 0x6f, 0x66, 0x5d, 0x59, 0x51, 0x51, 0x56, 0x58, 0x4e, 0x48, 0x4c, 0x5e, - 0x74, 0x76, 0x75, 0x76, 0x7a, 0x7d, 0x7b, 0x7a, 0x78, 0x76, 0x75, 0x77, - 0x7a, 0x7b, 0x78, 0x71, 0x6a, 0x65, 0x63, 0x60, 0x5a, 0x58, 0x5c, 0x62, - 0x6d, 0x7b, 0x84, 0x89, 0x8b, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x94, 0x94, - 0x95, 0x95, 0x95, 0x94, 0x93, 0x91, 0x91, 0x92, 0x91, 0x90, 0x8e, 0x8c, - 0x8b, 0x8a, 0x87, 0x84, 0x7f, 0x7b, 0x78, 0x75, 0x71, 0x6c, 0x68, 0x65, - 0x61, 0x5c, 0x59, 0x56, 0x52, 0x4d, 0x48, 0x40, 0x3c, 0x39, 0x32, 0x2e, - 0x28, 0x23, 0x20, 0x1a, 0x14, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, - 0x13, 0x13, 0x15, 0x13, 0x13, 0x14, 0x13, 0x15, 0x8c, 0x85, 0x7e, 0x79, - 0x70, 0x67, 0x5f, 0x5c, 0x5a, 0x5a, 0x5a, 0x58, 0x58, 0x58, 0x58, 0x5b, - 0x5c, 0x5b, 0x5b, 0x59, 0x59, 0x58, 0x59, 0x59, 0x58, 0x59, 0x5c, 0x5d, - 0x5f, 0x60, 0x61, 0x63, 0x64, 0x64, 0x64, 0x66, 0x69, 0x6c, 0x6e, 0x6e, - 0x70, 0x6f, 0x6e, 0x6d, 0x6d, 0x6c, 0x6b, 0x6b, 0x6a, 0x69, 0x66, 0x66, - 0x66, 0x66, 0x65, 0x64, 0x63, 0x62, 0x62, 0x65, 0x73, 0x88, 0x98, 0x9f, - 0xa7, 0xad, 0xb2, 0xb6, 0xb9, 0xbc, 0xc0, 0xc4, 0xc6, 0xc7, 0xc8, 0xcd, - 0xd0, 0xd3, 0xd4, 0xd4, 0xd4, 0xd2, 0xcc, 0xc8, 0xc5, 0xbf, 0xba, 0xb8, - 0xb8, 0xb8, 0xb6, 0xb9, 0xbd, 0xc1, 0xc3, 0xc4, 0xc0, 0xbb, 0xb8, 0xb8, - 0xb7, 0xb2, 0xb0, 0xad, 0xad, 0xae, 0xb0, 0xb0, 0xb0, 0xb1, 0xb3, 0xb1, - 0xb8, 0xae, 0x96, 0x77, 0xb0, 0xc5, 0xb5, 0xac, 0xa1, 0x7e, 0xa0, 0xb6, - 0xb7, 0xad, 0xa1, 0x6a, 0x51, 0x7b, 0x98, 0xb0, 0xbe, 0xc4, 0xc8, 0xc9, - 0xc7, 0xc8, 0xc8, 0xc7, 0xc4, 0xbe, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xb6, - 0xb2, 0xb3, 0xb4, 0xb5, 0xb8, 0xbc, 0xbd, 0xbf, 0xc1, 0xbf, 0xbd, 0xbf, - 0xc2, 0xcb, 0xd1, 0xcb, 0xc7, 0xc5, 0xc3, 0xc2, 0xc3, 0xc5, 0xc5, 0xc5, - 0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0, 0xbf, 0xbc, 0xbb, 0xba, - 0xb9, 0xb9, 0xb8, 0xbb, 0xc1, 0xc3, 0xc1, 0xb8, 0xa3, 0x95, 0x90, 0x8f, - 0x8b, 0x7e, 0x6e, 0x6b, 0x6c, 0x67, 0x5b, 0x60, 0x66, 0x66, 0x65, 0x66, - 0x6d, 0x75, 0x7b, 0x7f, 0x82, 0x81, 0x80, 0x79, 0x73, 0x6a, 0x60, 0x5b, - 0x54, 0x52, 0x56, 0x57, 0x4e, 0x47, 0x4b, 0x5d, 0x74, 0x75, 0x72, 0x73, - 0x77, 0x7a, 0x78, 0x76, 0x75, 0x73, 0x71, 0x73, 0x76, 0x77, 0x76, 0x70, - 0x68, 0x64, 0x62, 0x5f, 0x5a, 0x58, 0x5b, 0x60, 0x6b, 0x7a, 0x83, 0x89, - 0x8b, 0x8c, 0x8e, 0x91, 0x93, 0x95, 0x95, 0x96, 0x96, 0x96, 0x95, 0x95, - 0x94, 0x92, 0x93, 0x93, 0x92, 0x91, 0x8f, 0x8d, 0x8c, 0x8b, 0x8a, 0x86, - 0x81, 0x7d, 0x7a, 0x76, 0x72, 0x6c, 0x69, 0x66, 0x62, 0x5d, 0x59, 0x55, - 0x52, 0x4e, 0x49, 0x41, 0x3d, 0x3a, 0x33, 0x30, 0x29, 0x24, 0x20, 0x1b, - 0x15, 0x12, 0x11, 0x11, 0x10, 0x10, 0x10, 0x12, 0x13, 0x13, 0x14, 0x13, - 0x13, 0x14, 0x13, 0x15, 0x90, 0x89, 0x83, 0x7d, 0x75, 0x6b, 0x62, 0x5e, - 0x5c, 0x5a, 0x59, 0x58, 0x58, 0x58, 0x58, 0x5b, 0x5c, 0x5b, 0x5a, 0x58, - 0x58, 0x58, 0x59, 0x59, 0x58, 0x58, 0x5b, 0x5c, 0x5d, 0x5f, 0x60, 0x62, - 0x63, 0x64, 0x65, 0x65, 0x69, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e, 0x6d, 0x6d, - 0x6d, 0x6c, 0x6b, 0x6b, 0x6a, 0x68, 0x65, 0x65, 0x64, 0x64, 0x64, 0x63, - 0x61, 0x61, 0x62, 0x67, 0x77, 0x8d, 0x9b, 0xa2, 0xa8, 0xae, 0xb2, 0xb6, - 0xba, 0xbc, 0xc0, 0xc4, 0xc6, 0xc6, 0xc8, 0xcc, 0xd0, 0xd4, 0xd5, 0xd5, - 0xd5, 0xd3, 0xce, 0xca, 0xc7, 0xc2, 0xbc, 0xb8, 0xb9, 0xb8, 0xb6, 0xb8, - 0xbc, 0xc0, 0xc3, 0xc6, 0xc3, 0xbe, 0xbb, 0xb9, 0xb8, 0xb3, 0xaf, 0xac, - 0xac, 0xae, 0xb1, 0xb1, 0xaf, 0xaf, 0xb3, 0xbd, 0xb9, 0xa9, 0x9e, 0x9c, - 0xbd, 0xb4, 0x8e, 0x82, 0x8b, 0x91, 0x91, 0xa2, 0xab, 0xaa, 0x8e, 0x54, - 0x69, 0x8e, 0xa2, 0xb4, 0xbf, 0xc0, 0xc1, 0xc0, 0xc0, 0xc4, 0xc5, 0xc3, - 0xc1, 0xba, 0xb9, 0xb8, 0xba, 0xba, 0xb9, 0xb5, 0xb4, 0xb6, 0xb6, 0xb6, - 0xb7, 0xba, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0, 0xc2, 0xc7, 0xcf, 0xd6, 0xd5, - 0xd3, 0xd1, 0xcd, 0xc5, 0xc3, 0xc4, 0xc5, 0xc5, 0xc7, 0xc7, 0xc5, 0xc4, - 0xc3, 0xc1, 0xc0, 0xbf, 0xbe, 0xbe, 0xbb, 0xba, 0xb9, 0xb7, 0xb6, 0xb8, - 0xbc, 0xbe, 0xbb, 0xaf, 0x9c, 0x91, 0x8e, 0x8c, 0x87, 0x79, 0x67, 0x63, - 0x6a, 0x69, 0x5f, 0x60, 0x64, 0x64, 0x63, 0x66, 0x6d, 0x74, 0x7d, 0x81, - 0x82, 0x82, 0x81, 0x7c, 0x78, 0x6f, 0x65, 0x5e, 0x57, 0x54, 0x54, 0x55, - 0x4c, 0x46, 0x4a, 0x5b, 0x72, 0x73, 0x70, 0x70, 0x73, 0x76, 0x74, 0x72, - 0x71, 0x70, 0x6e, 0x6e, 0x70, 0x71, 0x71, 0x6d, 0x66, 0x62, 0x60, 0x5d, - 0x58, 0x56, 0x5a, 0x5f, 0x69, 0x77, 0x82, 0x88, 0x8a, 0x8b, 0x8d, 0x91, - 0x93, 0x96, 0x96, 0x96, 0x97, 0x97, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95, - 0x94, 0x93, 0x92, 0x8f, 0x8e, 0x8d, 0x8b, 0x88, 0x84, 0x7f, 0x7c, 0x78, - 0x74, 0x6e, 0x6a, 0x68, 0x63, 0x5e, 0x59, 0x55, 0x52, 0x4f, 0x49, 0x43, - 0x3f, 0x3c, 0x37, 0x33, 0x2c, 0x27, 0x24, 0x1f, 0x17, 0x14, 0x13, 0x12, - 0x11, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x13, 0x14, 0x14, 0x13, 0x13, - 0x93, 0x8d, 0x88, 0x84, 0x7b, 0x6f, 0x66, 0x61, 0x5e, 0x5b, 0x5a, 0x59, - 0x59, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x59, 0x58, 0x58, 0x58, 0x59, - 0x59, 0x59, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x64, 0x65, - 0x67, 0x6a, 0x6c, 0x6c, 0x6e, 0x6e, 0x6d, 0x6e, 0x6e, 0x6e, 0x6c, 0x6a, - 0x69, 0x68, 0x65, 0x64, 0x63, 0x63, 0x64, 0x62, 0x61, 0x61, 0x62, 0x69, - 0x7d, 0x93, 0xa0, 0xa6, 0xab, 0xb0, 0xb3, 0xb7, 0xbb, 0xbe, 0xc1, 0xc4, - 0xc5, 0xc6, 0xc8, 0xc9, 0xce, 0xd3, 0xd5, 0xd6, 0xd6, 0xd4, 0xd1, 0xcd, - 0xca, 0xc5, 0xbe, 0xb9, 0xb8, 0xb8, 0xb7, 0xb6, 0xbb, 0xc0, 0xc4, 0xc8, - 0xc7, 0xc1, 0xbc, 0xba, 0xb9, 0xb5, 0xaf, 0xac, 0xab, 0xad, 0xb1, 0xb2, - 0xb0, 0xae, 0xb1, 0xbb, 0xb7, 0xa3, 0xa3, 0xb4, 0xb1, 0x91, 0x91, 0x9b, - 0xa9, 0xae, 0xa2, 0x93, 0x93, 0x96, 0x67, 0x58, 0x82, 0xa2, 0xb0, 0xb9, - 0xc0, 0xc3, 0xc3, 0xc4, 0xc7, 0xc7, 0xc3, 0xc1, 0xbe, 0xb9, 0xb8, 0xb8, - 0xb9, 0xb9, 0xb9, 0xb7, 0xb8, 0xb9, 0xb9, 0xb7, 0xb6, 0xb9, 0xbc, 0xbd, - 0xbd, 0xc0, 0xc5, 0xc8, 0xcb, 0xcf, 0xd6, 0xd8, 0xd9, 0xda, 0xd7, 0xcd, - 0xc4, 0xc2, 0xc3, 0xc5, 0xc6, 0xc9, 0xc7, 0xc6, 0xc3, 0xc2, 0xc0, 0xbe, - 0xbf, 0xbf, 0xbc, 0xbb, 0xb8, 0xb7, 0xb5, 0xb3, 0xb8, 0xba, 0xb5, 0xa6, - 0x94, 0x8e, 0x89, 0x84, 0x7f, 0x74, 0x63, 0x62, 0x6c, 0x6f, 0x67, 0x60, - 0x63, 0x64, 0x65, 0x69, 0x6d, 0x72, 0x7c, 0x81, 0x83, 0x84, 0x81, 0x80, - 0x7d, 0x75, 0x6a, 0x62, 0x5b, 0x57, 0x53, 0x52, 0x49, 0x44, 0x48, 0x59, - 0x71, 0x73, 0x6f, 0x6e, 0x6f, 0x72, 0x72, 0x71, 0x72, 0x72, 0x71, 0x70, - 0x70, 0x6f, 0x6e, 0x6a, 0x63, 0x60, 0x5d, 0x5b, 0x57, 0x56, 0x59, 0x5e, - 0x67, 0x76, 0x81, 0x87, 0x89, 0x8a, 0x8c, 0x91, 0x95, 0x97, 0x97, 0x96, - 0x98, 0x98, 0x97, 0x96, 0x96, 0x96, 0x97, 0x96, 0x96, 0x95, 0x94, 0x92, - 0x90, 0x8f, 0x8d, 0x8a, 0x86, 0x83, 0x80, 0x7b, 0x76, 0x70, 0x6c, 0x69, - 0x65, 0x60, 0x5d, 0x59, 0x57, 0x53, 0x4d, 0x46, 0x43, 0x42, 0x3f, 0x3b, - 0x35, 0x30, 0x2c, 0x27, 0x20, 0x1b, 0x19, 0x18, 0x15, 0x12, 0x11, 0x12, - 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x13, 0x98, 0x92, 0x8c, 0x87, - 0x7f, 0x75, 0x69, 0x63, 0x60, 0x5d, 0x5a, 0x5a, 0x5a, 0x59, 0x59, 0x5a, - 0x5a, 0x5b, 0x5b, 0x5a, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, 0x5b, 0x5c, - 0x5c, 0x5c, 0x5f, 0x5f, 0x62, 0x63, 0x64, 0x66, 0x67, 0x6a, 0x6a, 0x6b, - 0x6d, 0x6e, 0x6f, 0x6f, 0x6f, 0x6e, 0x6c, 0x69, 0x68, 0x68, 0x66, 0x64, - 0x63, 0x62, 0x63, 0x61, 0x5f, 0x60, 0x61, 0x6b, 0x82, 0x98, 0xa3, 0xa9, - 0xae, 0xb1, 0xb3, 0xb7, 0xbc, 0xbf, 0xc2, 0xc4, 0xc5, 0xc6, 0xc7, 0xc9, - 0xce, 0xd2, 0xd4, 0xd5, 0xd5, 0xd4, 0xd2, 0xcf, 0xcb, 0xc5, 0xbe, 0xb9, - 0xb8, 0xb8, 0xb7, 0xb6, 0xbb, 0xc2, 0xc7, 0xcc, 0xcb, 0xc5, 0xbf, 0xbd, - 0xbb, 0xb6, 0xb0, 0xae, 0xad, 0xae, 0xb0, 0xb2, 0xb1, 0xaf, 0xaf, 0xb6, - 0xba, 0xa5, 0x9b, 0x9b, 0x97, 0x93, 0xaa, 0xb5, 0xb1, 0xa6, 0xa4, 0x9a, - 0x8d, 0x73, 0x56, 0x75, 0x8d, 0xac, 0xb9, 0xbe, 0xc2, 0xc7, 0xca, 0xcb, - 0xc9, 0xc8, 0xc4, 0xc1, 0xbe, 0xba, 0xb8, 0xb9, 0xba, 0xba, 0xba, 0xb8, - 0xba, 0xba, 0xb9, 0xb7, 0xb7, 0xba, 0xbf, 0xc0, 0xbe, 0xbf, 0xc5, 0xc7, - 0xc8, 0xca, 0xce, 0xd3, 0xda, 0xdd, 0xdd, 0xd3, 0xc4, 0xbf, 0xbf, 0xc4, - 0xc6, 0xca, 0xc9, 0xc7, 0xc5, 0xc3, 0xc1, 0xc0, 0xc0, 0xc0, 0xbc, 0xb9, - 0xb8, 0xb8, 0xb5, 0xb2, 0xb3, 0xb2, 0xad, 0x9f, 0x92, 0x8e, 0x87, 0x81, - 0x7c, 0x74, 0x63, 0x61, 0x6c, 0x6f, 0x69, 0x61, 0x62, 0x67, 0x6a, 0x6e, - 0x6f, 0x72, 0x79, 0x7e, 0x83, 0x84, 0x83, 0x86, 0x86, 0x81, 0x71, 0x66, - 0x60, 0x5b, 0x54, 0x51, 0x48, 0x45, 0x48, 0x57, 0x6f, 0x72, 0x6c, 0x6b, - 0x6e, 0x74, 0x76, 0x78, 0x79, 0x7a, 0x78, 0x74, 0x71, 0x70, 0x6e, 0x69, - 0x62, 0x5e, 0x5c, 0x5a, 0x57, 0x55, 0x59, 0x5e, 0x66, 0x74, 0x7e, 0x83, - 0x87, 0x89, 0x8b, 0x91, 0x95, 0x97, 0x97, 0x98, 0x9a, 0x9a, 0x99, 0x99, - 0x98, 0x97, 0x98, 0x97, 0x96, 0x96, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8d, - 0x88, 0x86, 0x84, 0x7f, 0x78, 0x73, 0x6e, 0x6b, 0x67, 0x64, 0x61, 0x5e, - 0x5b, 0x56, 0x52, 0x4c, 0x4a, 0x48, 0x46, 0x43, 0x3e, 0x39, 0x36, 0x31, - 0x2a, 0x25, 0x24, 0x23, 0x1f, 0x18, 0x15, 0x15, 0x14, 0x13, 0x14, 0x14, - 0x13, 0x13, 0x14, 0x14, 0x9c, 0x95, 0x8e, 0x8a, 0x83, 0x78, 0x6c, 0x65, - 0x62, 0x5e, 0x5b, 0x5a, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x59, 0x59, 0x5a, - 0x59, 0x58, 0x58, 0x58, 0x59, 0x59, 0x5b, 0x5a, 0x5a, 0x5c, 0x5e, 0x60, - 0x62, 0x63, 0x64, 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6c, 0x6d, 0x6f, 0x6f, - 0x6f, 0x6c, 0x6b, 0x69, 0x68, 0x68, 0x66, 0x64, 0x62, 0x61, 0x61, 0x60, - 0x5e, 0x5f, 0x62, 0x6f, 0x87, 0x9c, 0xa8, 0xad, 0xb1, 0xb2, 0xb4, 0xb9, - 0xbe, 0xc1, 0xc4, 0xc5, 0xc5, 0xc6, 0xc7, 0xc9, 0xcd, 0xd1, 0xd3, 0xd4, - 0xd3, 0xd4, 0xd2, 0xce, 0xcb, 0xc6, 0xbf, 0xbb, 0xb7, 0xb6, 0xb7, 0xb6, - 0xba, 0xc2, 0xc8, 0xce, 0xcf, 0xca, 0xc3, 0xbf, 0xbc, 0xb7, 0xb2, 0xaf, - 0xaf, 0xaf, 0xb1, 0xb2, 0xb1, 0xaf, 0xaf, 0xb4, 0xba, 0xb7, 0xa8, 0x8d, - 0x91, 0x96, 0x92, 0x94, 0x9e, 0xa0, 0x8d, 0x7b, 0x6c, 0x5a, 0x6e, 0x82, - 0x97, 0xb1, 0xbc, 0xc1, 0xc3, 0xc6, 0xca, 0xca, 0xc9, 0xc8, 0xc0, 0xbd, - 0xbc, 0xbb, 0xba, 0xb9, 0xba, 0xba, 0xb9, 0xb7, 0xb9, 0xb9, 0xb9, 0xb9, - 0xb9, 0xbd, 0xc2, 0xc2, 0xbf, 0xbf, 0xc1, 0xc3, 0xc4, 0xc2, 0xc3, 0xce, - 0xd9, 0xdd, 0xdc, 0xd8, 0xc9, 0xc1, 0xc0, 0xc3, 0xc5, 0xc7, 0xc8, 0xc7, - 0xc6, 0xc4, 0xc2, 0xc1, 0xc1, 0xc0, 0xbb, 0xba, 0xba, 0xb9, 0xb6, 0xb0, - 0xac, 0xa9, 0xa4, 0x9a, 0x92, 0x8f, 0x88, 0x84, 0x81, 0x79, 0x6a, 0x64, - 0x6a, 0x6d, 0x6a, 0x66, 0x65, 0x6a, 0x6e, 0x70, 0x72, 0x76, 0x7b, 0x7f, - 0x85, 0x86, 0x88, 0x90, 0x92, 0x8b, 0x7a, 0x6c, 0x67, 0x63, 0x59, 0x52, - 0x47, 0x45, 0x48, 0x55, 0x6d, 0x6f, 0x69, 0x69, 0x70, 0x78, 0x7d, 0x80, - 0x81, 0x83, 0x80, 0x7b, 0x76, 0x74, 0x71, 0x6a, 0x61, 0x5c, 0x59, 0x57, - 0x56, 0x54, 0x57, 0x5d, 0x66, 0x72, 0x7b, 0x80, 0x84, 0x87, 0x8b, 0x8f, - 0x95, 0x99, 0x9b, 0x9b, 0x9d, 0x9d, 0x9c, 0x9c, 0x9b, 0x9a, 0x99, 0x99, - 0x98, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x8f, 0x8b, 0x89, 0x87, 0x83, - 0x7d, 0x78, 0x73, 0x6f, 0x6b, 0x67, 0x65, 0x62, 0x60, 0x5c, 0x59, 0x54, - 0x51, 0x4f, 0x4d, 0x49, 0x44, 0x42, 0x3f, 0x3a, 0x33, 0x2f, 0x2e, 0x2d, - 0x2a, 0x24, 0x1e, 0x1b, 0x19, 0x16, 0x14, 0x14, 0x13, 0x13, 0x12, 0x12, - 0x9d, 0x95, 0x8f, 0x8a, 0x84, 0x79, 0x6d, 0x67, 0x64, 0x5f, 0x5c, 0x5a, - 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5a, 0x5a, 0x59, 0x5a, 0x59, 0x59, 0x5a, - 0x5a, 0x5a, 0x5b, 0x5a, 0x59, 0x5a, 0x5e, 0x61, 0x63, 0x64, 0x65, 0x67, - 0x67, 0x69, 0x69, 0x6a, 0x6d, 0x6e, 0x6e, 0x6e, 0x6e, 0x6c, 0x6b, 0x69, - 0x68, 0x68, 0x66, 0x64, 0x62, 0x61, 0x61, 0x60, 0x5e, 0x60, 0x64, 0x71, - 0x8b, 0x9f, 0xaa, 0xae, 0xb2, 0xb2, 0xb5, 0xb9, 0xbe, 0xc0, 0xc3, 0xc4, - 0xc5, 0xc5, 0xc6, 0xc9, 0xcd, 0xd0, 0xd2, 0xd3, 0xd2, 0xd3, 0xd1, 0xcf, - 0xcd, 0xc7, 0xc1, 0xbd, 0xb9, 0xb7, 0xb6, 0xb5, 0xb9, 0xc1, 0xc7, 0xcd, - 0xd0, 0xcd, 0xc7, 0xc2, 0xbd, 0xba, 0xb6, 0xb2, 0xaf, 0xaf, 0xb2, 0xb4, - 0xb2, 0xb0, 0xb0, 0xb4, 0xb7, 0xc0, 0xb9, 0x99, 0x79, 0x79, 0x7a, 0x7a, - 0x7c, 0x80, 0x5b, 0x4c, 0x52, 0x69, 0x79, 0x84, 0xa7, 0xb7, 0xbc, 0xc1, - 0xc5, 0xc6, 0xc5, 0xc7, 0xc9, 0xc7, 0xbf, 0xbd, 0xbc, 0xba, 0xba, 0xb9, - 0xb8, 0xb9, 0xb9, 0xb8, 0xb7, 0xba, 0xba, 0xba, 0xba, 0xbe, 0xc2, 0xc3, - 0xc0, 0xbe, 0xbf, 0xc1, 0xc0, 0xbd, 0xbc, 0xcb, 0xd8, 0xdb, 0xdb, 0xd9, - 0xcf, 0xc7, 0xc4, 0xc4, 0xc5, 0xc7, 0xc9, 0xc9, 0xc8, 0xc4, 0xc2, 0xc1, - 0xc0, 0xbf, 0xbd, 0xba, 0xbb, 0xbb, 0xb7, 0xaf, 0xa8, 0xa3, 0x9f, 0x97, - 0x93, 0x8f, 0x8b, 0x89, 0x86, 0x7d, 0x6e, 0x69, 0x6b, 0x6c, 0x6b, 0x68, - 0x68, 0x6b, 0x6e, 0x71, 0x74, 0x7a, 0x7e, 0x82, 0x89, 0x8c, 0x8c, 0x8f, - 0x90, 0x8e, 0x83, 0x73, 0x6e, 0x68, 0x5d, 0x51, 0x46, 0x44, 0x47, 0x54, - 0x6b, 0x6d, 0x65, 0x65, 0x6d, 0x77, 0x7f, 0x84, 0x86, 0x89, 0x87, 0x83, - 0x7d, 0x79, 0x74, 0x6b, 0x61, 0x5a, 0x58, 0x56, 0x55, 0x53, 0x57, 0x5c, - 0x66, 0x70, 0x79, 0x7e, 0x81, 0x84, 0x89, 0x8f, 0x95, 0x9a, 0x9c, 0x9d, - 0x9f, 0x9f, 0x9d, 0x9d, 0x9d, 0x9b, 0x99, 0x99, 0x99, 0x98, 0x96, 0x96, - 0x95, 0x94, 0x91, 0x8f, 0x8e, 0x8c, 0x8b, 0x87, 0x80, 0x7b, 0x77, 0x73, - 0x6f, 0x6a, 0x67, 0x64, 0x62, 0x60, 0x5c, 0x59, 0x56, 0x54, 0x51, 0x4c, - 0x49, 0x46, 0x44, 0x3f, 0x38, 0x35, 0x34, 0x33, 0x31, 0x2c, 0x27, 0x23, - 0x20, 0x1d, 0x19, 0x17, 0x15, 0x14, 0x12, 0x12, 0x9d, 0x95, 0x8f, 0x8b, - 0x83, 0x79, 0x6d, 0x68, 0x64, 0x60, 0x5c, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, - 0x5b, 0x5b, 0x5a, 0x59, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5a, - 0x5a, 0x5a, 0x5d, 0x61, 0x63, 0x64, 0x65, 0x67, 0x67, 0x69, 0x6a, 0x6a, - 0x6d, 0x6e, 0x6e, 0x6d, 0x6d, 0x6b, 0x6b, 0x69, 0x68, 0x67, 0x65, 0x64, - 0x62, 0x62, 0x61, 0x60, 0x5f, 0x60, 0x65, 0x73, 0x8d, 0xa0, 0xaa, 0xae, - 0xb1, 0xb3, 0xb6, 0xba, 0xbe, 0xc1, 0xc3, 0xc4, 0xc4, 0xc5, 0xc6, 0xc9, - 0xcd, 0xd0, 0xd2, 0xd2, 0xd1, 0xd3, 0xd2, 0xd0, 0xce, 0xc8, 0xc2, 0xbe, - 0xb9, 0xb7, 0xb5, 0xb4, 0xb8, 0xc0, 0xc6, 0xce, 0xd1, 0xce, 0xc8, 0xc4, - 0xbe, 0xbb, 0xb7, 0xb3, 0xb1, 0xb0, 0xb2, 0xb4, 0xb2, 0xb1, 0xb1, 0xb4, - 0xb5, 0xbf, 0xbe, 0xa8, 0x7b, 0x6e, 0x6e, 0x6c, 0x69, 0x6f, 0x52, 0x48, - 0x55, 0x79, 0x86, 0x8f, 0xb0, 0xba, 0xbc, 0xc0, 0xc7, 0xc6, 0xc4, 0xc5, - 0xc8, 0xc6, 0xbf, 0xbd, 0xbc, 0xba, 0xba, 0xb9, 0xb8, 0xb8, 0xb9, 0xb9, - 0xb7, 0xb9, 0xba, 0xba, 0xba, 0xbe, 0xc2, 0xc3, 0xc1, 0xbd, 0xbf, 0xbf, - 0xbe, 0xba, 0xbb, 0xcb, 0xd6, 0xd9, 0xd9, 0xd9, 0xd2, 0xcb, 0xc8, 0xc5, - 0xc6, 0xc7, 0xc9, 0xca, 0xc8, 0xc5, 0xc2, 0xc1, 0xc0, 0xc0, 0xbd, 0xbb, - 0xbb, 0xbb, 0xb7, 0xaf, 0xa6, 0xa2, 0x9d, 0x97, 0x92, 0x8f, 0x8d, 0x8c, - 0x88, 0x7f, 0x71, 0x6a, 0x6b, 0x6c, 0x6b, 0x6a, 0x69, 0x6b, 0x6e, 0x73, - 0x76, 0x7d, 0x82, 0x86, 0x8b, 0x8e, 0x8c, 0x8d, 0x8d, 0x8d, 0x85, 0x79, - 0x72, 0x6d, 0x61, 0x53, 0x48, 0x43, 0x45, 0x52, 0x69, 0x6b, 0x63, 0x63, - 0x6a, 0x75, 0x7e, 0x84, 0x87, 0x89, 0x89, 0x86, 0x81, 0x7c, 0x76, 0x6c, - 0x60, 0x5a, 0x57, 0x55, 0x54, 0x52, 0x56, 0x5b, 0x65, 0x6f, 0x78, 0x7d, - 0x7f, 0x82, 0x88, 0x8f, 0x95, 0x9a, 0x9c, 0x9d, 0xa0, 0xa0, 0x9e, 0x9e, - 0x9d, 0x9c, 0x9a, 0x9a, 0x9a, 0x9a, 0x97, 0x97, 0x96, 0x94, 0x92, 0x90, - 0x8f, 0x8d, 0x8c, 0x88, 0x82, 0x7d, 0x79, 0x75, 0x70, 0x6c, 0x69, 0x66, - 0x65, 0x62, 0x5f, 0x5c, 0x58, 0x56, 0x54, 0x4f, 0x4c, 0x49, 0x47, 0x42, - 0x3c, 0x38, 0x37, 0x37, 0x36, 0x32, 0x2d, 0x29, 0x27, 0x24, 0x1e, 0x1a, - 0x17, 0x15, 0x13, 0x12, 0x9c, 0x93, 0x8e, 0x8a, 0x83, 0x79, 0x6d, 0x68, - 0x64, 0x60, 0x5c, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x59, - 0x59, 0x5a, 0x5a, 0x5a, 0x59, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x5d, 0x60, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x68, 0x69, 0x6a, 0x6c, 0x6e, 0x6e, 0x6d, - 0x6d, 0x6c, 0x6b, 0x69, 0x68, 0x67, 0x64, 0x64, 0x63, 0x62, 0x61, 0x5f, - 0x5f, 0x61, 0x66, 0x75, 0x8e, 0xa2, 0xab, 0xb0, 0xb2, 0xb4, 0xb7, 0xbb, - 0xbf, 0xc1, 0xc3, 0xc4, 0xc4, 0xc5, 0xc6, 0xc9, 0xce, 0xd0, 0xd1, 0xd1, - 0xd1, 0xd2, 0xd3, 0xd1, 0xcf, 0xca, 0xc4, 0xc0, 0xbb, 0xb9, 0xb6, 0xb4, - 0xb7, 0xbe, 0xc5, 0xce, 0xd2, 0xcf, 0xc9, 0xc5, 0xc0, 0xbc, 0xb8, 0xb6, - 0xb4, 0xb1, 0xb1, 0xb4, 0xb2, 0xb1, 0xb1, 0xb5, 0xb4, 0xb6, 0xba, 0xbb, - 0xa1, 0x7c, 0x6b, 0x65, 0x63, 0x6d, 0x73, 0x73, 0x7a, 0x91, 0xa3, 0xaa, - 0xb6, 0xba, 0xbc, 0xbe, 0xc6, 0xc5, 0xc4, 0xc4, 0xc6, 0xc5, 0xbf, 0xbd, - 0xbb, 0xba, 0xba, 0xb8, 0xb8, 0xb9, 0xba, 0xb9, 0xb7, 0xb7, 0xb8, 0xb8, - 0xb9, 0xbc, 0xc1, 0xc2, 0xc1, 0xbe, 0xbe, 0xbe, 0xbc, 0xbb, 0xbe, 0xca, - 0xd2, 0xd5, 0xd6, 0xd9, 0xd5, 0xcf, 0xcc, 0xc8, 0xc7, 0xc8, 0xc9, 0xc9, - 0xc8, 0xc4, 0xc2, 0xc1, 0xc1, 0xc0, 0xc0, 0xbc, 0xbc, 0xbb, 0xb5, 0xad, - 0xa4, 0xa1, 0x9d, 0x97, 0x93, 0x92, 0x91, 0x8e, 0x8a, 0x80, 0x73, 0x6c, - 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6f, 0x75, 0x79, 0x81, 0x87, 0x8a, - 0x8d, 0x8c, 0x88, 0x89, 0x8a, 0x89, 0x84, 0x7d, 0x79, 0x74, 0x67, 0x56, - 0x4d, 0x45, 0x44, 0x50, 0x65, 0x67, 0x5f, 0x5f, 0x67, 0x73, 0x7c, 0x80, - 0x83, 0x88, 0x89, 0x87, 0x82, 0x7e, 0x79, 0x6d, 0x60, 0x58, 0x55, 0x54, - 0x53, 0x50, 0x54, 0x5a, 0x64, 0x6e, 0x76, 0x7b, 0x7e, 0x80, 0x87, 0x8e, - 0x96, 0x9a, 0x9c, 0x9d, 0xa0, 0xa1, 0xa0, 0x9f, 0x9f, 0x9d, 0x9b, 0x9b, - 0x9b, 0x9a, 0x98, 0x97, 0x96, 0x96, 0x94, 0x92, 0x90, 0x8e, 0x8d, 0x8a, - 0x86, 0x80, 0x7b, 0x78, 0x73, 0x6f, 0x6d, 0x6b, 0x69, 0x66, 0x63, 0x5f, - 0x5d, 0x5c, 0x58, 0x54, 0x51, 0x4f, 0x4c, 0x47, 0x41, 0x3f, 0x3d, 0x3c, - 0x3c, 0x39, 0x36, 0x33, 0x32, 0x2f, 0x29, 0x22, 0x1d, 0x1a, 0x16, 0x13, - 0x9b, 0x93, 0x8c, 0x88, 0x83, 0x79, 0x6e, 0x68, 0x65, 0x61, 0x5d, 0x5a, - 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, - 0x5a, 0x5b, 0x5b, 0x5a, 0x5a, 0x5b, 0x5d, 0x60, 0x60, 0x61, 0x62, 0x64, - 0x65, 0x66, 0x68, 0x6a, 0x6d, 0x6e, 0x6e, 0x6e, 0x6e, 0x6c, 0x6b, 0x6a, - 0x69, 0x66, 0x64, 0x64, 0x63, 0x62, 0x60, 0x5f, 0x5f, 0x61, 0x67, 0x77, - 0x90, 0xa4, 0xad, 0xb1, 0xb4, 0xb5, 0xb8, 0xbc, 0xbf, 0xc1, 0xc2, 0xc4, - 0xc4, 0xc5, 0xc7, 0xc9, 0xcd, 0xd0, 0xcf, 0xce, 0xcf, 0xd2, 0xd3, 0xd2, - 0xd0, 0xcd, 0xc6, 0xc1, 0xbd, 0xba, 0xb7, 0xb3, 0xb5, 0xbb, 0xc2, 0xcd, - 0xd2, 0xd0, 0xcb, 0xc7, 0xc2, 0xbe, 0xba, 0xb7, 0xb5, 0xb1, 0xb2, 0xb3, - 0xb2, 0xb1, 0xb0, 0xb3, 0xb4, 0xb0, 0xb2, 0xba, 0xbd, 0xb0, 0x9c, 0x91, - 0x88, 0x8b, 0x98, 0xa3, 0xab, 0xb3, 0xb7, 0xb4, 0xb3, 0xb7, 0xb9, 0xbc, - 0xc1, 0xc0, 0xc2, 0xc3, 0xc3, 0xc3, 0xc0, 0xbd, 0xbc, 0xba, 0xba, 0xb8, - 0xb8, 0xb9, 0xbb, 0xba, 0xb8, 0xb7, 0xb7, 0xb6, 0xb7, 0xbb, 0xc0, 0xc2, - 0xc3, 0xc0, 0xbd, 0xbc, 0xbd, 0xbe, 0xc4, 0xc9, 0xce, 0xd0, 0xd3, 0xd9, - 0xda, 0xd5, 0xd1, 0xcc, 0xc9, 0xc8, 0xc9, 0xc9, 0xc8, 0xc4, 0xc1, 0xc1, - 0xc2, 0xc2, 0xc2, 0xbe, 0xbd, 0xba, 0xb4, 0xab, 0xa1, 0x9e, 0x9c, 0x97, - 0x93, 0x96, 0x97, 0x93, 0x8d, 0x82, 0x75, 0x6e, 0x6d, 0x6e, 0x6e, 0x6e, - 0x6e, 0x6f, 0x71, 0x74, 0x78, 0x81, 0x85, 0x86, 0x87, 0x84, 0x81, 0x85, - 0x86, 0x83, 0x81, 0x7f, 0x80, 0x7c, 0x6f, 0x56, 0x4e, 0x48, 0x46, 0x4d, - 0x62, 0x64, 0x5c, 0x5a, 0x63, 0x6e, 0x77, 0x7c, 0x7f, 0x83, 0x86, 0x86, - 0x82, 0x80, 0x7a, 0x6e, 0x60, 0x57, 0x54, 0x53, 0x52, 0x50, 0x54, 0x59, - 0x62, 0x6c, 0x73, 0x78, 0x7b, 0x7e, 0x86, 0x8f, 0x97, 0x9c, 0x9d, 0x9f, - 0xa2, 0xa3, 0xa3, 0xa2, 0xa1, 0x9f, 0x9e, 0x9d, 0x9c, 0x9c, 0x9b, 0x98, - 0x97, 0x97, 0x96, 0x94, 0x91, 0x8f, 0x8f, 0x8d, 0x89, 0x83, 0x7f, 0x7c, - 0x77, 0x73, 0x71, 0x6e, 0x6d, 0x6a, 0x68, 0x64, 0x62, 0x60, 0x5e, 0x5a, - 0x58, 0x55, 0x53, 0x4e, 0x48, 0x46, 0x45, 0x44, 0x42, 0x3f, 0x3e, 0x3b, - 0x39, 0x36, 0x32, 0x2d, 0x27, 0x24, 0x1e, 0x18, 0x99, 0x91, 0x8c, 0x87, - 0x81, 0x77, 0x6e, 0x68, 0x65, 0x61, 0x5c, 0x5a, 0x59, 0x59, 0x5a, 0x5b, - 0x5b, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5c, 0x5b, - 0x5b, 0x5d, 0x5d, 0x5e, 0x60, 0x61, 0x62, 0x64, 0x65, 0x65, 0x66, 0x69, - 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6b, 0x69, 0x68, 0x66, 0x64, 0x64, - 0x63, 0x62, 0x60, 0x5f, 0x5f, 0x61, 0x67, 0x78, 0x92, 0xa6, 0xaf, 0xb3, - 0xb5, 0xb6, 0xb9, 0xbb, 0xbe, 0xbf, 0xc1, 0xc3, 0xc5, 0xc7, 0xc8, 0xca, - 0xcd, 0xcf, 0xcf, 0xcf, 0xcf, 0xd3, 0xd3, 0xd2, 0xd2, 0xd0, 0xca, 0xc5, - 0xc1, 0xbe, 0xba, 0xb5, 0xb4, 0xba, 0xc0, 0xca, 0xd1, 0xd1, 0xcf, 0xcb, - 0xc4, 0xbf, 0xbb, 0xb8, 0xb7, 0xb3, 0xb2, 0xb3, 0xb4, 0xb2, 0xb2, 0xb4, - 0xb5, 0xb2, 0xb1, 0xb2, 0xba, 0xbe, 0xbd, 0xbc, 0xba, 0xba, 0xba, 0xb7, - 0xb5, 0xb3, 0xb6, 0xb5, 0xb2, 0xb4, 0xb6, 0xb8, 0xbc, 0xbd, 0xbe, 0xc0, - 0xc2, 0xc2, 0xc1, 0xbf, 0xbd, 0xba, 0xb8, 0xb8, 0xb8, 0xb8, 0xba, 0xbc, - 0xbb, 0xb9, 0xb8, 0xb7, 0xb7, 0xbb, 0xbf, 0xc2, 0xc3, 0xc0, 0xbe, 0xbe, - 0xc0, 0xc4, 0xcb, 0xce, 0xce, 0xcf, 0xd3, 0xd8, 0xda, 0xd8, 0xd5, 0xd1, - 0xcc, 0xc9, 0xc9, 0xc8, 0xc7, 0xc3, 0xc1, 0xc1, 0xc1, 0xc3, 0xc4, 0xc2, - 0xbe, 0xbb, 0xb3, 0xa7, 0x9e, 0x9b, 0x9a, 0x98, 0x95, 0x98, 0x99, 0x96, - 0x91, 0x84, 0x75, 0x6d, 0x6e, 0x6f, 0x6e, 0x6d, 0x6f, 0x71, 0x72, 0x73, - 0x77, 0x80, 0x84, 0x82, 0x7c, 0x79, 0x79, 0x81, 0x83, 0x7f, 0x7e, 0x81, - 0x81, 0x80, 0x77, 0x5b, 0x4f, 0x4c, 0x4b, 0x4c, 0x5d, 0x64, 0x5b, 0x5a, - 0x61, 0x6b, 0x73, 0x76, 0x79, 0x7d, 0x82, 0x84, 0x82, 0x7f, 0x79, 0x6e, - 0x61, 0x58, 0x55, 0x53, 0x50, 0x4e, 0x52, 0x58, 0x61, 0x6b, 0x71, 0x75, - 0x78, 0x7d, 0x85, 0x8f, 0x97, 0x9d, 0xa0, 0xa2, 0xa4, 0xa3, 0xa4, 0xa3, - 0xa1, 0xa1, 0x9f, 0x9f, 0x9e, 0x9e, 0x9c, 0x9b, 0x9a, 0x99, 0x97, 0x95, - 0x93, 0x91, 0x90, 0x8f, 0x8b, 0x84, 0x81, 0x7f, 0x7b, 0x76, 0x73, 0x70, - 0x6f, 0x6d, 0x6b, 0x69, 0x65, 0x64, 0x62, 0x5f, 0x5d, 0x5b, 0x59, 0x55, - 0x50, 0x4c, 0x4b, 0x4a, 0x48, 0x46, 0x45, 0x43, 0x41, 0x3d, 0x38, 0x35, - 0x32, 0x2f, 0x29, 0x21, 0x97, 0x90, 0x8a, 0x86, 0x7e, 0x76, 0x6e, 0x68, - 0x65, 0x60, 0x5b, 0x5b, 0x59, 0x59, 0x5a, 0x5b, 0x5a, 0x5a, 0x5a, 0x5b, - 0x5b, 0x5b, 0x5a, 0x59, 0x59, 0x5b, 0x5b, 0x5a, 0x5b, 0x5d, 0x5e, 0x5e, - 0x5e, 0x5f, 0x61, 0x63, 0x64, 0x64, 0x65, 0x68, 0x6b, 0x6b, 0x6b, 0x6c, - 0x6b, 0x6b, 0x69, 0x68, 0x66, 0x66, 0x64, 0x64, 0x63, 0x61, 0x5f, 0x5f, - 0x61, 0x62, 0x68, 0x7a, 0x93, 0xa7, 0xb0, 0xb4, 0xb5, 0xb6, 0xb9, 0xbb, - 0xbe, 0xbf, 0xc1, 0xc3, 0xc6, 0xc8, 0xca, 0xcb, 0xce, 0xcf, 0xd0, 0xd0, - 0xd1, 0xd2, 0xd4, 0xd4, 0xd3, 0xd1, 0xcd, 0xc8, 0xc4, 0xc1, 0xbd, 0xb7, - 0xb5, 0xba, 0xbf, 0xc9, 0xd1, 0xd2, 0xd0, 0xcc, 0xc5, 0xbf, 0xbc, 0xba, - 0xb8, 0xb4, 0xb2, 0xb4, 0xb5, 0xb4, 0xb2, 0xb4, 0xb7, 0xb6, 0xb3, 0xb0, - 0xb4, 0xba, 0xbf, 0xc1, 0xc2, 0xc0, 0xbd, 0xb7, 0xaf, 0xa6, 0xb1, 0xb4, - 0xb3, 0xb6, 0xb7, 0xb8, 0xba, 0xbc, 0xbf, 0xc1, 0xc2, 0xc1, 0xbf, 0xbd, - 0xbb, 0xb9, 0xb6, 0xb8, 0xb7, 0xb8, 0xb9, 0xbc, 0xbd, 0xbb, 0xba, 0xb8, - 0xb8, 0xbb, 0xbf, 0xc2, 0xc3, 0xc1, 0xc0, 0xc1, 0xc4, 0xca, 0xd0, 0xd1, - 0xd0, 0xd0, 0xd2, 0xd7, 0xd9, 0xd8, 0xd7, 0xd3, 0xcd, 0xc9, 0xc9, 0xc8, - 0xc6, 0xc3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc6, 0xc3, 0xbe, 0xb9, 0xb1, 0xa5, - 0x9c, 0x98, 0x97, 0x96, 0x94, 0x98, 0x9b, 0x98, 0x92, 0x85, 0x75, 0x6f, - 0x6f, 0x6f, 0x6d, 0x6b, 0x6d, 0x72, 0x73, 0x74, 0x79, 0x81, 0x85, 0x82, - 0x78, 0x73, 0x76, 0x7e, 0x81, 0x80, 0x7f, 0x81, 0x7f, 0x7e, 0x79, 0x60, - 0x4f, 0x4f, 0x4e, 0x4d, 0x5b, 0x64, 0x5d, 0x5b, 0x61, 0x69, 0x70, 0x72, - 0x74, 0x78, 0x80, 0x83, 0x84, 0x81, 0x78, 0x6d, 0x61, 0x59, 0x55, 0x52, - 0x4f, 0x4e, 0x50, 0x55, 0x5f, 0x69, 0x6e, 0x72, 0x77, 0x7c, 0x85, 0x90, - 0x9a, 0x9f, 0xa2, 0xa4, 0xa6, 0xa6, 0xa6, 0xa5, 0xa4, 0xa3, 0xa1, 0xa0, - 0xa0, 0xa0, 0x9e, 0x9d, 0x9c, 0x9b, 0x99, 0x98, 0x95, 0x92, 0x91, 0x8f, - 0x8c, 0x86, 0x83, 0x82, 0x7f, 0x79, 0x75, 0x73, 0x72, 0x70, 0x6f, 0x6c, - 0x68, 0x67, 0x65, 0x65, 0x61, 0x5f, 0x5d, 0x5a, 0x55, 0x51, 0x4f, 0x4e, - 0x4d, 0x4c, 0x4a, 0x4a, 0x48, 0x44, 0x3f, 0x3c, 0x3a, 0x37, 0x31, 0x27, - 0x96, 0x8e, 0x89, 0x84, 0x7d, 0x75, 0x6d, 0x67, 0x63, 0x5f, 0x5b, 0x5b, - 0x5a, 0x5a, 0x5b, 0x5b, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5b, 0x5a, 0x5a, - 0x59, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5e, 0x5d, 0x5e, 0x5f, 0x60, 0x63, - 0x64, 0x65, 0x65, 0x67, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x69, 0x67, - 0x66, 0x65, 0x64, 0x64, 0x63, 0x61, 0x5f, 0x5e, 0x62, 0x63, 0x69, 0x7b, - 0x94, 0xa8, 0xb1, 0xb5, 0xb6, 0xb6, 0xb9, 0xbb, 0xbe, 0xbf, 0xc1, 0xc3, - 0xc6, 0xc9, 0xca, 0xcb, 0xce, 0xcf, 0xd1, 0xd1, 0xd1, 0xd3, 0xd5, 0xd4, - 0xd3, 0xd0, 0xcd, 0xc9, 0xc6, 0xc3, 0xbe, 0xb9, 0xb6, 0xba, 0xbf, 0xc8, - 0xd1, 0xd2, 0xd0, 0xcc, 0xc5, 0xbf, 0xbc, 0xba, 0xb8, 0xb4, 0xb3, 0xb4, - 0xb4, 0xb4, 0xb2, 0xb3, 0xb8, 0xb7, 0xb5, 0xb0, 0xb1, 0xb6, 0xbc, 0xbf, - 0xc1, 0xbe, 0xbc, 0xb7, 0xb0, 0xa7, 0xb0, 0xb3, 0xb3, 0xb6, 0xb7, 0xb8, - 0xb9, 0xbb, 0xbf, 0xc0, 0xc1, 0xc0, 0xbe, 0xbc, 0xba, 0xb8, 0xb6, 0xb8, - 0xb6, 0xb6, 0xb8, 0xbb, 0xbd, 0xbc, 0xbb, 0xb9, 0xb8, 0xbb, 0xc0, 0xc2, - 0xc3, 0xc1, 0xc1, 0xc3, 0xc5, 0xcc, 0xd2, 0xd2, 0xd1, 0xd0, 0xd2, 0xd6, - 0xd8, 0xd7, 0xd6, 0xd3, 0xcc, 0xc9, 0xc9, 0xc8, 0xc6, 0xc2, 0xc2, 0xc2, - 0xc2, 0xc4, 0xc6, 0xc4, 0xbe, 0xb9, 0xb1, 0xa4, 0x9b, 0x98, 0x96, 0x95, - 0x92, 0x96, 0x9b, 0x98, 0x92, 0x86, 0x75, 0x70, 0x70, 0x70, 0x6d, 0x6a, - 0x6d, 0x72, 0x74, 0x75, 0x7b, 0x82, 0x85, 0x83, 0x79, 0x73, 0x74, 0x7d, - 0x81, 0x82, 0x7f, 0x80, 0x7f, 0x7f, 0x7a, 0x62, 0x51, 0x4f, 0x4e, 0x4d, - 0x5a, 0x65, 0x5f, 0x5e, 0x63, 0x6a, 0x6f, 0x71, 0x72, 0x76, 0x7e, 0x83, - 0x83, 0x80, 0x77, 0x6c, 0x61, 0x59, 0x56, 0x52, 0x4e, 0x4e, 0x50, 0x54, - 0x5e, 0x67, 0x6d, 0x71, 0x75, 0x7b, 0x85, 0x91, 0x9b, 0xa0, 0xa3, 0xa6, - 0xa7, 0xa7, 0xa8, 0xa7, 0xa6, 0xa4, 0xa2, 0xa1, 0xa2, 0xa1, 0x9f, 0x9e, - 0x9d, 0x9c, 0x9a, 0x99, 0x97, 0x94, 0x91, 0x8f, 0x8d, 0x88, 0x84, 0x82, - 0x80, 0x7b, 0x77, 0x75, 0x74, 0x72, 0x70, 0x6e, 0x6b, 0x6a, 0x68, 0x67, - 0x64, 0x62, 0x60, 0x5d, 0x58, 0x55, 0x52, 0x51, 0x50, 0x50, 0x4d, 0x4d, - 0x4b, 0x48, 0x44, 0x40, 0x3d, 0x3b, 0x35, 0x2b, 0x94, 0x8d, 0x86, 0x81, - 0x7b, 0x73, 0x6b, 0x65, 0x62, 0x5f, 0x5c, 0x5b, 0x5c, 0x5c, 0x5c, 0x5b, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5d, 0x5c, 0x5c, 0x5c, 0x5a, 0x5a, 0x5c, 0x5d, - 0x5d, 0x5d, 0x5e, 0x5d, 0x5e, 0x5e, 0x60, 0x63, 0x64, 0x65, 0x65, 0x66, - 0x69, 0x6a, 0x6b, 0x6b, 0x6c, 0x6b, 0x68, 0x66, 0x65, 0x65, 0x64, 0x63, - 0x62, 0x60, 0x5e, 0x5e, 0x62, 0x65, 0x6b, 0x7b, 0x94, 0xa8, 0xb1, 0xb5, - 0xb6, 0xb6, 0xb8, 0xbb, 0xbe, 0xbf, 0xc1, 0xc4, 0xc7, 0xc9, 0xca, 0xcd, - 0xcd, 0xcf, 0xd2, 0xd2, 0xd4, 0xd4, 0xd4, 0xd4, 0xd3, 0xcf, 0xcc, 0xca, - 0xc7, 0xc5, 0xc1, 0xba, 0xb6, 0xba, 0xbf, 0xc8, 0xd0, 0xd1, 0xce, 0xcb, - 0xc4, 0xbf, 0xbc, 0xb8, 0xb6, 0xb5, 0xb3, 0xb4, 0xb3, 0xb2, 0xb1, 0xb2, - 0xb8, 0xb9, 0xb7, 0xb3, 0xb0, 0xb2, 0xb4, 0xb6, 0xbb, 0xbb, 0xbb, 0xba, - 0xb8, 0xb5, 0xb3, 0xb3, 0xb2, 0xb5, 0xb7, 0xb8, 0xbb, 0xbc, 0xbe, 0xbf, - 0xbf, 0xbe, 0xbe, 0xbd, 0xbb, 0xb8, 0xb7, 0xb7, 0xb6, 0xb6, 0xb7, 0xba, - 0xbc, 0xbb, 0xba, 0xba, 0xbb, 0xbd, 0xc0, 0xc2, 0xc3, 0xc2, 0xc2, 0xc4, - 0xc7, 0xcd, 0xd2, 0xd2, 0xd2, 0xd1, 0xd2, 0xd5, 0xd6, 0xd6, 0xd5, 0xd2, - 0xcc, 0xca, 0xc9, 0xc8, 0xc5, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc6, 0xc3, - 0xbe, 0xb9, 0xb1, 0xa4, 0x9b, 0x97, 0x95, 0x93, 0x90, 0x94, 0x9a, 0x98, - 0x93, 0x88, 0x79, 0x72, 0x72, 0x71, 0x6e, 0x6b, 0x6d, 0x71, 0x73, 0x76, - 0x7c, 0x82, 0x85, 0x83, 0x7b, 0x73, 0x73, 0x7a, 0x80, 0x83, 0x7d, 0x7c, - 0x80, 0x80, 0x79, 0x63, 0x53, 0x4f, 0x4d, 0x4d, 0x5a, 0x65, 0x63, 0x63, - 0x68, 0x6e, 0x71, 0x71, 0x72, 0x75, 0x7d, 0x81, 0x81, 0x7f, 0x78, 0x6c, - 0x60, 0x5b, 0x57, 0x53, 0x4e, 0x4d, 0x4e, 0x52, 0x5c, 0x65, 0x6a, 0x6f, - 0x75, 0x7b, 0x86, 0x93, 0x9d, 0xa2, 0xa4, 0xa7, 0xa9, 0xaa, 0xa9, 0xa9, - 0xa7, 0xa5, 0xa4, 0xa3, 0xa3, 0xa2, 0xa0, 0xa0, 0x9e, 0x9d, 0x9b, 0x9a, - 0x97, 0x95, 0x93, 0x90, 0x8f, 0x8a, 0x86, 0x84, 0x81, 0x7d, 0x7a, 0x78, - 0x77, 0x74, 0x73, 0x70, 0x6e, 0x6d, 0x6b, 0x6a, 0x68, 0x66, 0x64, 0x61, - 0x5d, 0x5b, 0x59, 0x58, 0x57, 0x54, 0x52, 0x50, 0x4f, 0x4c, 0x49, 0x44, - 0x41, 0x3f, 0x3b, 0x32, 0x91, 0x89, 0x82, 0x7d, 0x76, 0x6e, 0x67, 0x63, - 0x61, 0x5f, 0x5c, 0x5a, 0x5c, 0x5c, 0x5c, 0x5b, 0x5c, 0x5d, 0x5d, 0x5c, - 0x5c, 0x5d, 0x5d, 0x5c, 0x5a, 0x5b, 0x5d, 0x5d, 0x5d, 0x5c, 0x5d, 0x5c, - 0x5e, 0x5f, 0x61, 0x63, 0x63, 0x64, 0x65, 0x66, 0x69, 0x69, 0x6a, 0x6b, - 0x6b, 0x6a, 0x67, 0x66, 0x66, 0x65, 0x64, 0x61, 0x60, 0x5f, 0x5f, 0x5f, - 0x63, 0x67, 0x6c, 0x7a, 0x92, 0xa6, 0xb1, 0xb4, 0xb6, 0xb6, 0xb9, 0xbb, - 0xbe, 0xbf, 0xc1, 0xc5, 0xc7, 0xc9, 0xcb, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, - 0xd5, 0xd5, 0xd5, 0xd4, 0xd3, 0xd0, 0xcd, 0xca, 0xc7, 0xc5, 0xc3, 0xbd, - 0xb8, 0xb9, 0xbd, 0xc5, 0xcf, 0xcf, 0xcc, 0xc9, 0xc3, 0xbf, 0xbb, 0xb8, - 0xb6, 0xb5, 0xb5, 0xb4, 0xb2, 0xb2, 0xb1, 0xb3, 0xb7, 0xb8, 0xb8, 0xb7, - 0xb5, 0xaf, 0xac, 0xae, 0xb5, 0xb8, 0xb9, 0xb9, 0xb8, 0xb7, 0xb3, 0xb2, - 0xb4, 0xb8, 0xba, 0xbb, 0xbd, 0xc0, 0xc0, 0xc1, 0xc1, 0xc1, 0xc3, 0xc3, - 0xc1, 0xbc, 0xba, 0xb9, 0xb9, 0xb8, 0xba, 0xbb, 0xbd, 0xbb, 0xba, 0xb9, - 0xbb, 0xbe, 0xc1, 0xc2, 0xc2, 0xc2, 0xc4, 0xc6, 0xc8, 0xcc, 0xd1, 0xd2, - 0xd2, 0xd2, 0xd2, 0xd5, 0xd5, 0xd5, 0xd5, 0xd2, 0xcf, 0xcc, 0xca, 0xc9, - 0xc7, 0xc5, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xbf, 0xbb, 0xb6, 0xaf, 0xa4, - 0x9b, 0x97, 0x95, 0x91, 0x8e, 0x93, 0x99, 0x98, 0x94, 0x8c, 0x7e, 0x77, - 0x75, 0x74, 0x70, 0x6b, 0x6b, 0x6f, 0x72, 0x76, 0x7c, 0x7f, 0x81, 0x80, - 0x7a, 0x74, 0x73, 0x76, 0x7b, 0x82, 0x7b, 0x75, 0x7d, 0x7f, 0x78, 0x63, - 0x54, 0x4f, 0x4e, 0x50, 0x5b, 0x66, 0x66, 0x69, 0x70, 0x75, 0x76, 0x77, - 0x77, 0x78, 0x7f, 0x83, 0x81, 0x7e, 0x78, 0x6d, 0x63, 0x5d, 0x5a, 0x55, - 0x4f, 0x4d, 0x4d, 0x50, 0x5a, 0x63, 0x68, 0x6d, 0x74, 0x7b, 0x88, 0x95, - 0x9f, 0xa4, 0xa7, 0xaa, 0xac, 0xad, 0xac, 0xab, 0xa9, 0xa8, 0xa6, 0xa5, - 0xa4, 0xa4, 0xa3, 0xa2, 0xa0, 0x9f, 0x9d, 0x9b, 0x98, 0x97, 0x96, 0x93, - 0x91, 0x8d, 0x89, 0x86, 0x84, 0x80, 0x7e, 0x7c, 0x7b, 0x78, 0x76, 0x74, - 0x73, 0x72, 0x70, 0x6f, 0x6c, 0x6a, 0x68, 0x66, 0x63, 0x61, 0x60, 0x5f, - 0x5e, 0x5b, 0x58, 0x56, 0x55, 0x53, 0x50, 0x4d, 0x4a, 0x47, 0x43, 0x3a, - 0x8c, 0x84, 0x7d, 0x78, 0x71, 0x69, 0x63, 0x61, 0x5f, 0x5e, 0x5c, 0x5b, - 0x5b, 0x5c, 0x5c, 0x5b, 0x5c, 0x5d, 0x5d, 0x5c, 0x5c, 0x5d, 0x5d, 0x5c, - 0x5a, 0x5b, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5f, 0x5f, 0x61, 0x63, - 0x63, 0x64, 0x65, 0x66, 0x68, 0x69, 0x69, 0x6a, 0x6b, 0x69, 0x67, 0x66, - 0x65, 0x65, 0x63, 0x60, 0x5f, 0x5f, 0x5e, 0x60, 0x65, 0x67, 0x6c, 0x7a, - 0x91, 0xa4, 0xaf, 0xb3, 0xb4, 0xb6, 0xb7, 0xbb, 0xbd, 0xbe, 0xc1, 0xc5, - 0xc7, 0xc9, 0xca, 0xcd, 0xce, 0xd1, 0xd3, 0xd5, 0xd5, 0xd5, 0xd5, 0xd3, - 0xd2, 0xd1, 0xce, 0xca, 0xc7, 0xc6, 0xc5, 0xc0, 0xbb, 0xbb, 0xbd, 0xc3, - 0xcc, 0xcc, 0xca, 0xc8, 0xc4, 0xc0, 0xbb, 0xb8, 0xb7, 0xb5, 0xb4, 0xb3, - 0xb3, 0xb3, 0xb2, 0xb3, 0xb6, 0xb7, 0xb7, 0xb6, 0xb7, 0xb3, 0xb2, 0xb3, - 0xb4, 0xb5, 0xb6, 0xb6, 0xb6, 0xb3, 0xb1, 0xb4, 0xb7, 0xbb, 0xbd, 0xc0, - 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc3, 0xc2, 0xc2, 0xc1, 0xbd, 0xbb, 0xbc, - 0xbc, 0xbc, 0xbb, 0xbd, 0xbe, 0xbb, 0xb9, 0xb9, 0xbc, 0xbf, 0xc1, 0xc2, - 0xc2, 0xc3, 0xc6, 0xc8, 0xc9, 0xcd, 0xd0, 0xd1, 0xd1, 0xd1, 0xd2, 0xd5, - 0xd6, 0xd5, 0xd4, 0xd1, 0xce, 0xcd, 0xcc, 0xcb, 0xc8, 0xc6, 0xc4, 0xc4, - 0xc3, 0xc1, 0xbf, 0xbc, 0xb8, 0xb4, 0xae, 0xa4, 0x9c, 0x97, 0x94, 0x90, - 0x8c, 0x91, 0x97, 0x98, 0x95, 0x8d, 0x80, 0x79, 0x76, 0x75, 0x71, 0x6c, - 0x6b, 0x6f, 0x71, 0x74, 0x7a, 0x7b, 0x7e, 0x7d, 0x77, 0x73, 0x74, 0x76, - 0x79, 0x7e, 0x7b, 0x72, 0x75, 0x76, 0x72, 0x61, 0x55, 0x51, 0x51, 0x54, - 0x60, 0x67, 0x67, 0x69, 0x73, 0x7b, 0x80, 0x81, 0x81, 0x82, 0x87, 0x89, - 0x86, 0x82, 0x7d, 0x72, 0x68, 0x60, 0x5c, 0x58, 0x50, 0x4c, 0x4c, 0x50, - 0x58, 0x60, 0x65, 0x6b, 0x74, 0x7c, 0x89, 0x97, 0xa1, 0xa7, 0xa9, 0xac, - 0xae, 0xaf, 0xae, 0xad, 0xab, 0xab, 0xaa, 0xa8, 0xa7, 0xa7, 0xa5, 0xa3, - 0xa2, 0xa1, 0x9f, 0x9c, 0x99, 0x99, 0x98, 0x96, 0x93, 0x8f, 0x8b, 0x88, - 0x87, 0x83, 0x81, 0x80, 0x7e, 0x7c, 0x7a, 0x78, 0x77, 0x77, 0x75, 0x74, - 0x72, 0x6f, 0x6d, 0x6c, 0x68, 0x66, 0x66, 0x66, 0x63, 0x61, 0x5e, 0x5d, - 0x5c, 0x5a, 0x57, 0x54, 0x50, 0x4e, 0x4a, 0x43, 0x87, 0x7f, 0x79, 0x74, - 0x6d, 0x65, 0x61, 0x5f, 0x5e, 0x5b, 0x5b, 0x5b, 0x5a, 0x5a, 0x5b, 0x5c, - 0x5d, 0x5d, 0x5d, 0x5b, 0x5b, 0x5c, 0x5d, 0x5c, 0x5b, 0x5c, 0x5d, 0x5d, - 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x63, 0x63, 0x65, 0x65, 0x66, - 0x68, 0x6a, 0x6a, 0x6b, 0x6b, 0x69, 0x68, 0x66, 0x65, 0x64, 0x63, 0x60, - 0x5f, 0x5f, 0x60, 0x60, 0x65, 0x68, 0x6c, 0x79, 0x90, 0xa3, 0xad, 0xb1, - 0xb3, 0xb5, 0xb6, 0xba, 0xbd, 0xbe, 0xc1, 0xc4, 0xc7, 0xc8, 0xca, 0xcc, - 0xce, 0xd0, 0xd3, 0xd4, 0xd5, 0xd5, 0xd4, 0xd2, 0xd2, 0xd1, 0xcf, 0xcc, - 0xc9, 0xc8, 0xc6, 0xc1, 0xbc, 0xbb, 0xbc, 0xc1, 0xc8, 0xca, 0xc8, 0xc6, - 0xc4, 0xc0, 0xbc, 0xba, 0xb8, 0xb5, 0xb4, 0xb4, 0xb5, 0xb5, 0xb4, 0xb2, - 0xb4, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb6, 0xb6, 0xb6, 0xb5, - 0xb3, 0xb2, 0xb3, 0xb7, 0xba, 0xbd, 0xbf, 0xc1, 0xc3, 0xc5, 0xc9, 0xcc, - 0xcc, 0xc5, 0xc1, 0xc2, 0xc0, 0xbe, 0xbd, 0xbd, 0xbe, 0xbd, 0xbc, 0xbd, - 0xbe, 0xbb, 0xba, 0xba, 0xbc, 0xbf, 0xc0, 0xc1, 0xc3, 0xc6, 0xc9, 0xcb, - 0xcc, 0xce, 0xd0, 0xd1, 0xd1, 0xd0, 0xd1, 0xd5, 0xd6, 0xd5, 0xd3, 0xd0, - 0xce, 0xce, 0xcd, 0xcc, 0xca, 0xc7, 0xc4, 0xc3, 0xc2, 0xc0, 0xbf, 0xb9, - 0xb5, 0xb2, 0xac, 0xa4, 0x9d, 0x97, 0x93, 0x8f, 0x8a, 0x90, 0x98, 0x99, - 0x95, 0x8c, 0x7f, 0x78, 0x76, 0x75, 0x72, 0x6d, 0x6c, 0x6e, 0x70, 0x72, - 0x77, 0x79, 0x7c, 0x7b, 0x75, 0x73, 0x76, 0x78, 0x7a, 0x7d, 0x7b, 0x6f, - 0x6e, 0x6f, 0x6f, 0x5f, 0x54, 0x52, 0x53, 0x57, 0x67, 0x68, 0x65, 0x67, - 0x71, 0x7c, 0x83, 0x85, 0x87, 0x8a, 0x8e, 0x8e, 0x8c, 0x88, 0x82, 0x78, - 0x6d, 0x64, 0x5f, 0x59, 0x53, 0x4d, 0x4d, 0x4e, 0x56, 0x5e, 0x63, 0x6b, - 0x75, 0x7d, 0x89, 0x97, 0xa2, 0xa9, 0xab, 0xae, 0xaf, 0xaf, 0xaf, 0xaf, - 0xaf, 0xae, 0xab, 0xab, 0xaa, 0xa9, 0xa7, 0xa5, 0xa4, 0xa2, 0xa0, 0x9d, - 0x9c, 0x9b, 0x99, 0x97, 0x95, 0x91, 0x8d, 0x8b, 0x88, 0x85, 0x83, 0x82, - 0x81, 0x7f, 0x7d, 0x7b, 0x7a, 0x79, 0x79, 0x77, 0x75, 0x72, 0x71, 0x70, - 0x6d, 0x6a, 0x6a, 0x6a, 0x67, 0x67, 0x64, 0x62, 0x61, 0x5f, 0x5d, 0x59, - 0x55, 0x53, 0x4f, 0x49, 0x83, 0x7b, 0x75, 0x71, 0x6a, 0x62, 0x5e, 0x5d, - 0x5d, 0x5b, 0x5a, 0x5b, 0x5a, 0x5a, 0x5a, 0x5d, 0x5d, 0x5d, 0x5d, 0x5c, - 0x5c, 0x5c, 0x5d, 0x5c, 0x5c, 0x5d, 0x5c, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, - 0x5f, 0x61, 0x62, 0x63, 0x63, 0x65, 0x65, 0x66, 0x68, 0x6a, 0x6a, 0x6a, - 0x6b, 0x69, 0x68, 0x67, 0x66, 0x64, 0x63, 0x60, 0x5f, 0x5f, 0x60, 0x61, - 0x66, 0x68, 0x6c, 0x77, 0x8e, 0xa1, 0xab, 0xaf, 0xb2, 0xb4, 0xb6, 0xb9, - 0xbd, 0xbf, 0xc1, 0xc5, 0xc7, 0xc8, 0xc9, 0xcb, 0xce, 0xd0, 0xd3, 0xd3, - 0xd5, 0xd4, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0, 0xcc, 0xca, 0xc9, 0xc6, 0xc2, - 0xbc, 0xbb, 0xbb, 0xbf, 0xc6, 0xc8, 0xc7, 0xc6, 0xc4, 0xc0, 0xbc, 0xba, - 0xb9, 0xb6, 0xb4, 0xb6, 0xb7, 0xb7, 0xb5, 0xb1, 0xb4, 0xb6, 0xb7, 0xb8, - 0xb7, 0xb9, 0xba, 0xb9, 0xb7, 0xb7, 0xb6, 0xb3, 0xb2, 0xb2, 0xb5, 0xb9, - 0xbb, 0xbe, 0xc0, 0xc3, 0xc3, 0xc5, 0xc9, 0xcc, 0xcc, 0xc6, 0xc2, 0xc1, - 0xc1, 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbd, 0xbd, 0xbe, 0xbc, 0xbb, 0xba, - 0xbd, 0xbe, 0xbf, 0xc1, 0xc4, 0xc7, 0xcb, 0xcd, 0xcd, 0xce, 0xd0, 0xd1, - 0xd0, 0xd0, 0xd1, 0xd5, 0xd6, 0xd5, 0xd3, 0xd0, 0xce, 0xcf, 0xcf, 0xce, - 0xce, 0xc9, 0xc5, 0xc3, 0xc1, 0xbf, 0xbe, 0xb8, 0xb3, 0xb1, 0xac, 0xa3, - 0x9d, 0x97, 0x94, 0x8e, 0x89, 0x91, 0x99, 0x99, 0x95, 0x8b, 0x7e, 0x78, - 0x76, 0x75, 0x73, 0x6e, 0x6c, 0x6e, 0x70, 0x73, 0x76, 0x78, 0x7b, 0x7a, - 0x74, 0x73, 0x77, 0x78, 0x79, 0x7c, 0x7a, 0x6b, 0x69, 0x6c, 0x6c, 0x5c, - 0x52, 0x51, 0x52, 0x59, 0x6c, 0x69, 0x64, 0x65, 0x70, 0x7b, 0x82, 0x86, - 0x88, 0x8c, 0x8f, 0x90, 0x8e, 0x8b, 0x85, 0x7b, 0x70, 0x67, 0x62, 0x5b, - 0x54, 0x4e, 0x4c, 0x4e, 0x54, 0x5c, 0x62, 0x6b, 0x76, 0x7e, 0x89, 0x98, - 0xa3, 0xaa, 0xac, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xaf, 0xad, 0xac, - 0xac, 0xaa, 0xa9, 0xa7, 0xa5, 0xa4, 0xa1, 0x9e, 0x9d, 0x9c, 0x9b, 0x97, - 0x96, 0x92, 0x8f, 0x8d, 0x8a, 0x87, 0x85, 0x84, 0x82, 0x80, 0x7f, 0x7e, - 0x7c, 0x7b, 0x7b, 0x7a, 0x77, 0x75, 0x74, 0x73, 0x70, 0x6d, 0x6d, 0x6c, - 0x6a, 0x6a, 0x67, 0x65, 0x64, 0x63, 0x62, 0x5d, 0x59, 0x56, 0x52, 0x4d, - 0x7b, 0x73, 0x6e, 0x6b, 0x65, 0x5e, 0x5c, 0x5c, 0x5b, 0x59, 0x5a, 0x5c, - 0x5c, 0x5b, 0x5b, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5d, 0x5d, 0x5c, 0x5d, 0x5e, 0x5d, 0x5e, 0x5f, 0x60, 0x60, 0x62, 0x63, - 0x63, 0x65, 0x66, 0x67, 0x68, 0x6a, 0x69, 0x69, 0x69, 0x69, 0x69, 0x67, - 0x65, 0x63, 0x61, 0x5f, 0x5e, 0x5e, 0x5f, 0x62, 0x66, 0x68, 0x6b, 0x75, - 0x8b, 0x9e, 0xa8, 0xae, 0xb1, 0xb3, 0xb6, 0xba, 0xbd, 0xbe, 0xc1, 0xc5, - 0xc6, 0xc7, 0xc8, 0xcc, 0xcf, 0xd1, 0xd3, 0xd4, 0xd5, 0xd5, 0xd5, 0xd4, - 0xd2, 0xd2, 0xd0, 0xcb, 0xc9, 0xc8, 0xc6, 0xc2, 0xbc, 0xba, 0xba, 0xbe, - 0xc4, 0xc6, 0xc6, 0xc5, 0xc3, 0xbe, 0xbb, 0xbb, 0xb9, 0xb7, 0xb5, 0xb8, - 0xb9, 0xb9, 0xb6, 0xb1, 0xb2, 0xb6, 0xb7, 0xb7, 0xb7, 0xba, 0xbb, 0xba, - 0xb8, 0xb7, 0xb7, 0xb3, 0xb2, 0xb4, 0xb8, 0xbb, 0xbd, 0xc1, 0xc3, 0xc5, - 0xc5, 0xc5, 0xc7, 0xc8, 0xc8, 0xc7, 0xc5, 0xc2, 0xc0, 0xbf, 0xc1, 0xc1, - 0xc1, 0xc0, 0xbf, 0xbe, 0xbf, 0xbd, 0xbc, 0xbc, 0xbe, 0xbe, 0xbe, 0xc0, - 0xc5, 0xca, 0xcd, 0xcf, 0xcf, 0xcf, 0xd1, 0xd0, 0xcf, 0xce, 0xd0, 0xd4, - 0xd6, 0xd4, 0xd2, 0xd0, 0xd1, 0xd0, 0xd1, 0xd2, 0xd3, 0xce, 0xc7, 0xc2, - 0xc0, 0xbf, 0xbc, 0xb7, 0xb2, 0xb0, 0xab, 0xa3, 0x9e, 0x99, 0x95, 0x8e, - 0x8a, 0x91, 0x9a, 0x9a, 0x94, 0x87, 0x7a, 0x74, 0x74, 0x75, 0x72, 0x6e, - 0x6a, 0x6c, 0x6f, 0x73, 0x76, 0x77, 0x78, 0x77, 0x73, 0x72, 0x76, 0x78, - 0x79, 0x7a, 0x75, 0x67, 0x66, 0x68, 0x65, 0x58, 0x50, 0x4f, 0x51, 0x5d, - 0x73, 0x6b, 0x63, 0x64, 0x6d, 0x76, 0x7d, 0x83, 0x86, 0x8b, 0x8d, 0x8f, - 0x8d, 0x8b, 0x85, 0x7f, 0x74, 0x6b, 0x65, 0x5e, 0x56, 0x4f, 0x4d, 0x4f, - 0x53, 0x5a, 0x5f, 0x69, 0x76, 0x7f, 0x8c, 0x9a, 0xa5, 0xab, 0xae, 0xb1, - 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb1, 0xae, 0xae, 0xae, 0xac, 0xab, 0xa9, - 0xa7, 0xa5, 0xa3, 0xa0, 0x9e, 0x9e, 0x9d, 0x9a, 0x96, 0x93, 0x90, 0x8f, - 0x8b, 0x89, 0x87, 0x87, 0x86, 0x83, 0x82, 0x81, 0x80, 0x7f, 0x7f, 0x7d, - 0x7b, 0x7a, 0x7a, 0x78, 0x74, 0x71, 0x70, 0x70, 0x6e, 0x6d, 0x6b, 0x6a, - 0x69, 0x68, 0x67, 0x63, 0x5e, 0x5b, 0x57, 0x50, 0x70, 0x68, 0x64, 0x61, - 0x5d, 0x59, 0x59, 0x5a, 0x5a, 0x59, 0x5b, 0x5d, 0x5c, 0x5c, 0x5d, 0x5d, - 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5c, 0x5e, - 0x5e, 0x5d, 0x5e, 0x5e, 0x5f, 0x61, 0x62, 0x63, 0x63, 0x65, 0x66, 0x67, - 0x68, 0x68, 0x69, 0x69, 0x69, 0x68, 0x68, 0x66, 0x65, 0x64, 0x60, 0x5e, - 0x5d, 0x5d, 0x5f, 0x63, 0x67, 0x69, 0x6c, 0x74, 0x88, 0x9a, 0xa5, 0xaa, - 0xaf, 0xb3, 0xb7, 0xbb, 0xbd, 0xbe, 0xc1, 0xc5, 0xc7, 0xc8, 0xc9, 0xca, - 0xce, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd5, 0xd5, 0xd3, 0xd1, 0xcd, - 0xca, 0xc9, 0xc6, 0xc2, 0xbd, 0xbc, 0xbd, 0xc0, 0xc5, 0xc7, 0xc6, 0xc4, - 0xc2, 0xbf, 0xbc, 0xbb, 0xbb, 0xb9, 0xb6, 0xb8, 0xb9, 0xb8, 0xb6, 0xb2, - 0xb3, 0xb5, 0xb6, 0xb5, 0xb6, 0xb8, 0xb9, 0xb8, 0xb8, 0xb8, 0xb9, 0xb7, - 0xb6, 0xb8, 0xb9, 0xbd, 0xc0, 0xc4, 0xc7, 0xc8, 0xc9, 0xc7, 0xc7, 0xc7, - 0xc6, 0xc6, 0xc6, 0xc3, 0xc1, 0xbf, 0xc2, 0xc3, 0xc3, 0xc2, 0xc1, 0xc1, - 0xc1, 0xbf, 0xbe, 0xbd, 0xbd, 0xbe, 0xbe, 0xc0, 0xc5, 0xcc, 0xcf, 0xd0, - 0xd0, 0xcf, 0xd1, 0xd1, 0xcf, 0xce, 0xcf, 0xd3, 0xd6, 0xd7, 0xd6, 0xd2, - 0xd1, 0xd1, 0xd4, 0xd5, 0xd7, 0xd2, 0xc7, 0xc0, 0xbe, 0xbd, 0xba, 0xb4, - 0xb1, 0xae, 0xaa, 0xa3, 0x9e, 0x99, 0x96, 0x8f, 0x8a, 0x91, 0x9a, 0x99, - 0x94, 0x85, 0x77, 0x71, 0x73, 0x74, 0x72, 0x6c, 0x66, 0x6a, 0x6d, 0x70, - 0x73, 0x73, 0x73, 0x72, 0x70, 0x6f, 0x70, 0x6f, 0x70, 0x6f, 0x6c, 0x66, - 0x64, 0x62, 0x5d, 0x5b, 0x58, 0x54, 0x58, 0x69, 0x7b, 0x6d, 0x64, 0x64, - 0x6b, 0x72, 0x79, 0x7e, 0x81, 0x85, 0x88, 0x89, 0x86, 0x84, 0x80, 0x7b, - 0x74, 0x6c, 0x67, 0x5f, 0x58, 0x51, 0x4e, 0x4e, 0x50, 0x57, 0x5d, 0x68, - 0x76, 0x80, 0x8d, 0x9c, 0xa7, 0xad, 0xb0, 0xb3, 0xb5, 0xb5, 0xb5, 0xb5, - 0xb5, 0xb2, 0xb0, 0xb0, 0xaf, 0xad, 0xab, 0xa9, 0xa9, 0xa8, 0xa6, 0xa2, - 0x9f, 0x9f, 0x9e, 0x9b, 0x98, 0x94, 0x92, 0x90, 0x8d, 0x8b, 0x8a, 0x89, - 0x89, 0x87, 0x85, 0x84, 0x82, 0x82, 0x81, 0x80, 0x7f, 0x7f, 0x7f, 0x7e, - 0x7b, 0x78, 0x77, 0x76, 0x73, 0x71, 0x71, 0x70, 0x6f, 0x6d, 0x6b, 0x67, - 0x63, 0x60, 0x5b, 0x55, 0x64, 0x5d, 0x58, 0x56, 0x54, 0x54, 0x56, 0x58, - 0x58, 0x59, 0x5c, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5c, 0x5c, 0x5e, - 0x5d, 0x5d, 0x5c, 0x5c, 0x5d, 0x5e, 0x5d, 0x5e, 0x5d, 0x5d, 0x5d, 0x5e, - 0x5f, 0x61, 0x62, 0x63, 0x63, 0x64, 0x65, 0x66, 0x68, 0x68, 0x68, 0x68, - 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x61, 0x5d, 0x5d, 0x5d, 0x5f, 0x63, - 0x67, 0x69, 0x6b, 0x72, 0x84, 0x96, 0xa1, 0xa7, 0xae, 0xb2, 0xb7, 0xbb, - 0xbe, 0xbf, 0xc1, 0xc5, 0xc7, 0xc8, 0xc9, 0xca, 0xce, 0xd0, 0xd1, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd5, 0xd4, 0xd4, 0xd2, 0xcf, 0xcd, 0xc9, 0xc5, - 0xc3, 0xc4, 0xc5, 0xc6, 0xc9, 0xca, 0xc8, 0xc6, 0xc5, 0xc0, 0xbd, 0xbd, - 0xbc, 0xbb, 0xb7, 0xb0, 0xad, 0xaf, 0xb2, 0xb2, 0xb2, 0xb4, 0xb4, 0xb3, - 0xb5, 0xb7, 0xb8, 0xb8, 0xb9, 0xb8, 0xbb, 0xbb, 0xba, 0xbb, 0xbb, 0xbe, - 0xc2, 0xc6, 0xc8, 0xc9, 0xc8, 0xc8, 0xc7, 0xc6, 0xc7, 0xc6, 0xc7, 0xc6, - 0xc4, 0xc2, 0xc3, 0xc5, 0xc6, 0xc5, 0xc5, 0xc5, 0xc5, 0xc3, 0xc1, 0xbf, - 0xbe, 0xbd, 0xbf, 0xc2, 0xc8, 0xce, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xd1, - 0xd0, 0xcf, 0xcf, 0xd3, 0xd8, 0xd7, 0xd6, 0xd2, 0xd1, 0xd1, 0xd4, 0xd7, - 0xd8, 0xd2, 0xc6, 0xbf, 0xbd, 0xbc, 0xb8, 0xb2, 0xae, 0xac, 0xa8, 0xa3, - 0x9e, 0x9b, 0x98, 0x92, 0x8b, 0x8f, 0x97, 0x96, 0x92, 0x85, 0x78, 0x74, - 0x74, 0x73, 0x6f, 0x68, 0x65, 0x68, 0x6b, 0x6e, 0x6f, 0x6c, 0x6b, 0x6b, - 0x6c, 0x69, 0x66, 0x64, 0x64, 0x63, 0x63, 0x61, 0x5a, 0x57, 0x58, 0x61, - 0x60, 0x5b, 0x61, 0x74, 0x7d, 0x6d, 0x66, 0x67, 0x6b, 0x70, 0x77, 0x7b, - 0x7e, 0x80, 0x81, 0x81, 0x7e, 0x7c, 0x7a, 0x74, 0x6e, 0x6a, 0x66, 0x60, - 0x58, 0x51, 0x4f, 0x4e, 0x50, 0x55, 0x5a, 0x67, 0x76, 0x80, 0x8f, 0x9e, - 0xa9, 0xaf, 0xb2, 0xb5, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb3, 0xb3, - 0xb2, 0xb0, 0xae, 0xac, 0xab, 0xaa, 0xa7, 0xa3, 0xa1, 0xa0, 0x9f, 0x9c, - 0x98, 0x95, 0x93, 0x92, 0x8f, 0x8e, 0x8d, 0x8c, 0x8a, 0x88, 0x88, 0x87, - 0x85, 0x84, 0x83, 0x84, 0x82, 0x83, 0x83, 0x82, 0x80, 0x7d, 0x7c, 0x7b, - 0x79, 0x76, 0x74, 0x74, 0x73, 0x72, 0x6d, 0x69, 0x67, 0x65, 0x61, 0x5a, - 0x5a, 0x55, 0x52, 0x51, 0x50, 0x52, 0x55, 0x58, 0x59, 0x59, 0x5c, 0x5d, - 0x5d, 0x5c, 0x5d, 0x5c, 0x5d, 0x5c, 0x5c, 0x5d, 0x5d, 0x5c, 0x5c, 0x5c, - 0x5d, 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5d, 0x5d, 0x5f, 0x5f, 0x61, 0x63, - 0x63, 0x65, 0x66, 0x66, 0x68, 0x68, 0x67, 0x67, 0x67, 0x67, 0x66, 0x64, - 0x63, 0x61, 0x60, 0x5e, 0x5c, 0x5c, 0x5f, 0x63, 0x67, 0x68, 0x69, 0x70, - 0x81, 0x93, 0x9f, 0xa5, 0xad, 0xb1, 0xb7, 0xbb, 0xbe, 0xbf, 0xc2, 0xc5, - 0xc7, 0xc8, 0xc9, 0xca, 0xce, 0xd0, 0xd2, 0xd3, 0xd4, 0xd4, 0xd4, 0xd5, - 0xd5, 0xd5, 0xd6, 0xd4, 0xd1, 0xcf, 0xcd, 0xca, 0xca, 0xcc, 0xcd, 0xcd, - 0xcc, 0xcb, 0xca, 0xca, 0xc7, 0xc4, 0xc0, 0xbf, 0xbe, 0xbb, 0xb4, 0xa5, - 0xa1, 0xa3, 0xad, 0xb1, 0xb3, 0xb5, 0xb6, 0xb4, 0xb5, 0xb7, 0xb9, 0xba, - 0xb8, 0xb7, 0xbb, 0xbd, 0xbd, 0xbc, 0xbb, 0xbe, 0xc3, 0xc6, 0xc7, 0xc6, - 0xc8, 0xc9, 0xc7, 0xc6, 0xc7, 0xc8, 0xc7, 0xc7, 0xc6, 0xc4, 0xc5, 0xc7, - 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc5, 0xc3, 0xbf, 0xbe, 0xbe, 0xc2, 0xc5, - 0xcb, 0xd0, 0xd2, 0xd1, 0xd1, 0xcf, 0xcf, 0xd1, 0xd0, 0xd0, 0xd1, 0xd5, - 0xd8, 0xd7, 0xd6, 0xd2, 0xd1, 0xd1, 0xd4, 0xd6, 0xd8, 0xd2, 0xc6, 0xc0, - 0xbd, 0xba, 0xb6, 0xb1, 0xad, 0xaa, 0xa6, 0xa1, 0x9f, 0x9b, 0x98, 0x93, - 0x8c, 0x8e, 0x93, 0x93, 0x90, 0x86, 0x7b, 0x77, 0x75, 0x73, 0x6e, 0x67, - 0x63, 0x65, 0x69, 0x6d, 0x6c, 0x69, 0x68, 0x68, 0x68, 0x67, 0x62, 0x60, - 0x5f, 0x5c, 0x5d, 0x5c, 0x58, 0x55, 0x56, 0x5d, 0x5f, 0x5e, 0x66, 0x79, - 0x7a, 0x6a, 0x67, 0x68, 0x6c, 0x71, 0x77, 0x7c, 0x7e, 0x7f, 0x7f, 0x7d, - 0x7c, 0x7a, 0x76, 0x6e, 0x66, 0x63, 0x61, 0x5e, 0x58, 0x52, 0x4f, 0x4e, - 0x50, 0x53, 0x58, 0x67, 0x78, 0x83, 0x91, 0xa0, 0xac, 0xb1, 0xb3, 0xb6, - 0xb8, 0xb8, 0xb8, 0xb8, 0xb9, 0xb7, 0xb5, 0xb4, 0xb4, 0xb2, 0xb0, 0xac, - 0xab, 0xaa, 0xa9, 0xa4, 0xa2, 0xa1, 0xa0, 0x9e, 0x99, 0x96, 0x96, 0x95, - 0x92, 0x90, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x8a, 0x88, 0x87, 0x86, 0x86, - 0x85, 0x85, 0x85, 0x84, 0x81, 0x80, 0x7f, 0x7e, 0x7d, 0x7b, 0x78, 0x77, - 0x77, 0x75, 0x70, 0x6c, 0x6b, 0x6a, 0x65, 0x60, 0x55, 0x51, 0x4f, 0x4e, - 0x4e, 0x51, 0x55, 0x58, 0x5a, 0x5a, 0x5c, 0x5d, 0x5c, 0x5c, 0x5c, 0x5d, - 0x5d, 0x5c, 0x5c, 0x5e, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5e, - 0x5e, 0x5e, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x63, 0x63, 0x64, 0x66, 0x66, - 0x68, 0x68, 0x67, 0x66, 0x66, 0x67, 0x66, 0x64, 0x63, 0x61, 0x5f, 0x5d, - 0x5c, 0x5c, 0x5f, 0x64, 0x67, 0x68, 0x69, 0x70, 0x7f, 0x91, 0x9d, 0xa4, - 0xac, 0xb0, 0xb7, 0xbb, 0xbe, 0xbe, 0xc1, 0xc4, 0xc6, 0xc8, 0xc9, 0xcb, - 0xce, 0xd1, 0xd2, 0xd3, 0xd4, 0xd3, 0xd3, 0xd5, 0xd5, 0xd5, 0xd6, 0xd5, - 0xd2, 0xd0, 0xce, 0xcd, 0xcd, 0xcf, 0xd0, 0xd0, 0xcf, 0xcd, 0xcd, 0xcd, - 0xca, 0xc5, 0xc1, 0xc0, 0xbf, 0xbb, 0xb1, 0x9f, 0x9a, 0x9d, 0xa8, 0xb0, - 0xb4, 0xb6, 0xb6, 0xb5, 0xb5, 0xb6, 0xba, 0xba, 0xb8, 0xb7, 0xbb, 0xbe, - 0xbe, 0xbd, 0xbb, 0xbe, 0xc4, 0xc7, 0xc7, 0xc6, 0xc7, 0xc9, 0xc7, 0xc7, - 0xc8, 0xc8, 0xc7, 0xc7, 0xc7, 0xc5, 0xc6, 0xc7, 0xca, 0xca, 0xc9, 0xc9, - 0xc9, 0xc6, 0xc3, 0xbf, 0xbe, 0xbf, 0xc4, 0xc8, 0xcd, 0xd0, 0xd2, 0xd1, - 0xd1, 0xd0, 0xcf, 0xd1, 0xd0, 0xcf, 0xd1, 0xd6, 0xd9, 0xd7, 0xd6, 0xd2, - 0xd1, 0xd1, 0xd4, 0xd6, 0xd8, 0xd2, 0xc6, 0xbf, 0xbc, 0xb8, 0xb3, 0xae, - 0xab, 0xa8, 0xa4, 0xa0, 0x9d, 0x9a, 0x97, 0x93, 0x8d, 0x8e, 0x91, 0x91, - 0x8e, 0x86, 0x7c, 0x78, 0x75, 0x72, 0x6c, 0x65, 0x62, 0x64, 0x68, 0x6c, - 0x6a, 0x68, 0x67, 0x66, 0x64, 0x63, 0x5f, 0x5d, 0x5c, 0x59, 0x5a, 0x5a, - 0x58, 0x55, 0x53, 0x58, 0x5d, 0x62, 0x6b, 0x7b, 0x78, 0x67, 0x66, 0x68, - 0x6d, 0x73, 0x7a, 0x7e, 0x7f, 0x80, 0x7e, 0x7c, 0x7c, 0x7b, 0x75, 0x6c, - 0x63, 0x5f, 0x5d, 0x5c, 0x57, 0x52, 0x4f, 0x4f, 0x4f, 0x52, 0x57, 0x67, - 0x78, 0x83, 0x92, 0xa2, 0xac, 0xb1, 0xb3, 0xb6, 0xb7, 0xb7, 0xb7, 0xb7, - 0xb8, 0xb8, 0xb6, 0xb5, 0xb4, 0xb3, 0xb1, 0xad, 0xac, 0xab, 0xa9, 0xa5, - 0xa2, 0xa2, 0xa1, 0x9e, 0x9a, 0x97, 0x97, 0x96, 0x94, 0x91, 0x90, 0x8f, - 0x8e, 0x8c, 0x8b, 0x8b, 0x8a, 0x89, 0x88, 0x88, 0x87, 0x87, 0x86, 0x86, - 0x84, 0x83, 0x81, 0x80, 0x7f, 0x7d, 0x7a, 0x79, 0x79, 0x78, 0x73, 0x6f, - 0x6d, 0x6c, 0x68, 0x63, 0x4e, 0x4d, 0x4d, 0x4d, 0x4f, 0x53, 0x55, 0x58, - 0x5a, 0x5b, 0x5d, 0x5d, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d, 0x5c, 0x5d, 0x5e, - 0x5e, 0x5d, 0x5d, 0x5d, 0x5c, 0x5d, 0x5e, 0x5e, 0x5e, 0x5f, 0x60, 0x60, - 0x5f, 0x5f, 0x61, 0x61, 0x63, 0x63, 0x64, 0x66, 0x68, 0x66, 0x67, 0x67, - 0x67, 0x66, 0x66, 0x65, 0x63, 0x60, 0x5e, 0x5d, 0x5d, 0x5d, 0x5f, 0x64, - 0x67, 0x67, 0x68, 0x6e, 0x7e, 0x8e, 0x99, 0xa1, 0xaa, 0xb0, 0xb6, 0xbb, - 0xbd, 0xbe, 0xbf, 0xc3, 0xc6, 0xc7, 0xc8, 0xca, 0xcd, 0xd1, 0xd2, 0xd2, - 0xd2, 0xd2, 0xd2, 0xd3, 0xd4, 0xd4, 0xd6, 0xd5, 0xd2, 0xd0, 0xcf, 0xcf, - 0xd1, 0xd2, 0xd2, 0xd2, 0xd3, 0xd3, 0xd2, 0xd0, 0xcd, 0xc8, 0xc3, 0xc0, - 0xbf, 0xba, 0xab, 0x98, 0x95, 0x99, 0xa2, 0xad, 0xb5, 0xb6, 0xb6, 0xb5, - 0xb6, 0xb7, 0xb9, 0xb9, 0xb8, 0xb7, 0xbb, 0xbe, 0xbe, 0xbd, 0xbd, 0xbf, - 0xc6, 0xc9, 0xc8, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xc9, 0xc7, 0xc7, 0xc7, - 0xc7, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xc9, 0xca, 0xc9, 0xc5, 0xc2, 0xbe, - 0xbe, 0xc1, 0xc7, 0xcb, 0xce, 0xd1, 0xd2, 0xd1, 0xd1, 0xd0, 0xd0, 0xd0, - 0xce, 0xce, 0xd1, 0xd6, 0xd9, 0xd8, 0xd6, 0xd2, 0xd1, 0xd1, 0xd3, 0xd5, - 0xd6, 0xd1, 0xc5, 0xbe, 0xba, 0xb3, 0xab, 0xa6, 0xa5, 0xa3, 0x9f, 0x9c, - 0x99, 0x95, 0x93, 0x8f, 0x8c, 0x8e, 0x90, 0x8e, 0x8b, 0x84, 0x7c, 0x77, - 0x73, 0x6f, 0x6a, 0x63, 0x61, 0x63, 0x66, 0x69, 0x68, 0x66, 0x63, 0x62, - 0x5e, 0x5c, 0x5b, 0x59, 0x58, 0x56, 0x58, 0x5c, 0x58, 0x53, 0x4c, 0x54, - 0x5f, 0x6a, 0x73, 0x7d, 0x71, 0x61, 0x63, 0x66, 0x6d, 0x74, 0x7d, 0x81, - 0x81, 0x81, 0x7f, 0x7f, 0x80, 0x7e, 0x77, 0x6b, 0x5f, 0x59, 0x58, 0x57, - 0x56, 0x51, 0x4f, 0x4f, 0x4f, 0x51, 0x55, 0x65, 0x78, 0x84, 0x93, 0xa2, - 0xab, 0xaf, 0xb1, 0xb4, 0xb5, 0xb4, 0xb4, 0xb5, 0xb7, 0xb8, 0xb6, 0xb5, - 0xb4, 0xb4, 0xb3, 0xb0, 0xac, 0xab, 0xab, 0xa8, 0xa4, 0xa3, 0xa2, 0x9f, - 0x9b, 0x99, 0x97, 0x96, 0x95, 0x94, 0x91, 0x90, 0x8f, 0x8e, 0x8c, 0x8c, - 0x8b, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x86, 0x85, 0x83, 0x82, - 0x82, 0x7f, 0x7e, 0x7c, 0x7b, 0x7b, 0x78, 0x74, 0x71, 0x6f, 0x6b, 0x68, - 0x49, 0x4b, 0x4c, 0x4d, 0x4f, 0x52, 0x55, 0x59, 0x5a, 0x5b, 0x5d, 0x5d, - 0x5c, 0x5c, 0x5c, 0x5e, 0x5d, 0x5e, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, - 0x5d, 0x5d, 0x5e, 0x5e, 0x5e, 0x5f, 0x61, 0x61, 0x5f, 0x5f, 0x61, 0x61, - 0x63, 0x63, 0x63, 0x65, 0x67, 0x67, 0x67, 0x67, 0x67, 0x66, 0x64, 0x64, - 0x62, 0x60, 0x5e, 0x5c, 0x5c, 0x5e, 0x61, 0x65, 0x67, 0x67, 0x68, 0x6c, - 0x7a, 0x8a, 0x96, 0x9d, 0xa7, 0xb0, 0xb6, 0xbb, 0xbc, 0xbd, 0xbe, 0xc2, - 0xc5, 0xc6, 0xc7, 0xc9, 0xcc, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0, 0xcf, - 0xcf, 0xd1, 0xd3, 0xd5, 0xd2, 0xd0, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd4, - 0xd7, 0xd7, 0xd7, 0xd5, 0xd2, 0xce, 0xc8, 0xc4, 0xc1, 0xbb, 0xa7, 0x96, - 0x98, 0x9c, 0xa0, 0xa9, 0xb4, 0xb6, 0xb6, 0xb5, 0xb6, 0xb9, 0xbb, 0xbb, - 0xbb, 0xb9, 0xba, 0xbc, 0xbd, 0xbd, 0xbf, 0xc1, 0xc5, 0xc8, 0xc9, 0xc7, - 0xc6, 0xc6, 0xca, 0xcb, 0xc9, 0xc7, 0xc6, 0xc5, 0xc5, 0xc4, 0xc6, 0xc8, - 0xca, 0xcb, 0xcc, 0xca, 0xc7, 0xc4, 0xc1, 0xc0, 0xc1, 0xc4, 0xc9, 0xcd, - 0xcf, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd2, 0xd0, 0xce, 0xce, 0xd1, 0xd6, - 0xd9, 0xd8, 0xd6, 0xd3, 0xd0, 0xd0, 0xd2, 0xd4, 0xd5, 0xce, 0xc3, 0xba, - 0xb3, 0xaa, 0x9f, 0x98, 0x97, 0x97, 0x95, 0x93, 0x91, 0x8e, 0x8c, 0x88, - 0x88, 0x8e, 0x90, 0x8c, 0x88, 0x80, 0x78, 0x73, 0x70, 0x6e, 0x6a, 0x64, - 0x61, 0x63, 0x65, 0x65, 0x65, 0x62, 0x5e, 0x5d, 0x5b, 0x59, 0x58, 0x55, - 0x54, 0x53, 0x59, 0x5d, 0x56, 0x50, 0x4d, 0x5c, 0x6a, 0x75, 0x7c, 0x7d, - 0x67, 0x5b, 0x60, 0x65, 0x6c, 0x76, 0x7f, 0x83, 0x84, 0x84, 0x85, 0x86, - 0x87, 0x86, 0x7c, 0x6b, 0x5d, 0x56, 0x55, 0x54, 0x55, 0x52, 0x50, 0x50, - 0x4f, 0x50, 0x53, 0x66, 0x7b, 0x87, 0x96, 0xa1, 0xa8, 0xac, 0xae, 0xb1, - 0xb2, 0xb0, 0xb1, 0xb2, 0xb4, 0xb7, 0xb8, 0xb7, 0xb6, 0xb4, 0xb3, 0xb0, - 0xad, 0xac, 0xab, 0xa8, 0xa4, 0xa3, 0xa2, 0x9f, 0x9c, 0x9a, 0x98, 0x97, - 0x97, 0x95, 0x92, 0x91, 0x90, 0x8f, 0x8e, 0x8e, 0x8d, 0x8c, 0x8d, 0x8d, - 0x8d, 0x8c, 0x8c, 0x8b, 0x8a, 0x8a, 0x89, 0x88, 0x87, 0x84, 0x82, 0x80, - 0x7f, 0x7e, 0x7d, 0x79, 0x76, 0x73, 0x6f, 0x6c, 0x48, 0x4a, 0x4c, 0x4d, - 0x50, 0x51, 0x55, 0x58, 0x5a, 0x5b, 0x5c, 0x5d, 0x5c, 0x5c, 0x5d, 0x5d, - 0x5d, 0x5d, 0x5c, 0x5d, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f, - 0x5f, 0x5f, 0x60, 0x61, 0x60, 0x60, 0x61, 0x61, 0x63, 0x63, 0x63, 0x65, - 0x66, 0x66, 0x67, 0x67, 0x66, 0x65, 0x63, 0x62, 0x60, 0x5e, 0x5d, 0x5c, - 0x5e, 0x5f, 0x63, 0x66, 0x67, 0x67, 0x67, 0x6a, 0x77, 0x86, 0x92, 0x9b, - 0xa5, 0xae, 0xb5, 0xba, 0xbb, 0xbc, 0xbd, 0xc0, 0xc4, 0xc6, 0xc7, 0xc7, - 0xc9, 0xcd, 0xce, 0xce, 0xcd, 0xce, 0xce, 0xcc, 0xcc, 0xcd, 0xd0, 0xcf, - 0xcd, 0xcb, 0xca, 0xcc, 0xcd, 0xce, 0xcf, 0xd2, 0xd6, 0xd8, 0xd8, 0xd8, - 0xd7, 0xd5, 0xd1, 0xcc, 0xc9, 0xc3, 0xb1, 0x9e, 0xa2, 0xa7, 0xaa, 0xac, - 0xb3, 0xb6, 0xb6, 0xb7, 0xb7, 0xba, 0xbc, 0xbb, 0xbb, 0xbb, 0xba, 0xba, - 0xbb, 0xbc, 0xbf, 0xc1, 0xc4, 0xc7, 0xc8, 0xc8, 0xc6, 0xc5, 0xca, 0xcb, - 0xc7, 0xc7, 0xc6, 0xc5, 0xc5, 0xc6, 0xc6, 0xca, 0xce, 0xcf, 0xcd, 0xc9, - 0xc7, 0xc4, 0xc3, 0xc3, 0xc3, 0xc6, 0xcc, 0xce, 0xd0, 0xd1, 0xd2, 0xd2, - 0xd2, 0xd2, 0xd2, 0xd1, 0xd0, 0xd1, 0xd5, 0xd8, 0xd9, 0xd8, 0xd6, 0xd3, - 0xcf, 0xce, 0xd0, 0xd2, 0xd2, 0xc8, 0xbd, 0xb2, 0xac, 0xa3, 0x96, 0x8d, - 0x8d, 0x8d, 0x8c, 0x89, 0x85, 0x85, 0x85, 0x84, 0x86, 0x8d, 0x8e, 0x88, - 0x84, 0x7d, 0x75, 0x6f, 0x6e, 0x6d, 0x68, 0x63, 0x62, 0x63, 0x63, 0x61, - 0x60, 0x5e, 0x5c, 0x5c, 0x5c, 0x58, 0x54, 0x52, 0x52, 0x56, 0x5b, 0x58, - 0x51, 0x50, 0x5a, 0x6c, 0x77, 0x7f, 0x80, 0x7a, 0x5f, 0x59, 0x60, 0x65, - 0x6b, 0x74, 0x7c, 0x7f, 0x81, 0x83, 0x85, 0x88, 0x8b, 0x8a, 0x82, 0x70, - 0x5e, 0x57, 0x55, 0x54, 0x54, 0x52, 0x51, 0x51, 0x50, 0x4e, 0x52, 0x67, - 0x7d, 0x89, 0x94, 0x9d, 0xa5, 0xa9, 0xac, 0xad, 0xac, 0xad, 0xaf, 0xaf, - 0xb1, 0xb4, 0xb7, 0xb8, 0xb7, 0xb4, 0xb2, 0xb0, 0xad, 0xac, 0xab, 0xa8, - 0xa5, 0xa3, 0xa1, 0x9f, 0x9e, 0x9b, 0x9a, 0x99, 0x97, 0x95, 0x94, 0x92, - 0x91, 0x91, 0x90, 0x90, 0x8f, 0x8f, 0x90, 0x90, 0x90, 0x8f, 0x8e, 0x8e, - 0x8e, 0x8c, 0x8c, 0x8c, 0x8a, 0x89, 0x87, 0x84, 0x83, 0x82, 0x81, 0x7e, - 0x7a, 0x78, 0x75, 0x71, 0x47, 0x49, 0x4b, 0x4d, 0x50, 0x51, 0x54, 0x58, - 0x5a, 0x5b, 0x5b, 0x5d, 0x5d, 0x5d, 0x5c, 0x5d, 0x5d, 0x5c, 0x5c, 0x5c, - 0x5d, 0x5e, 0x5d, 0x5d, 0x5f, 0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, - 0x60, 0x60, 0x61, 0x61, 0x63, 0x63, 0x64, 0x65, 0x66, 0x66, 0x66, 0x66, - 0x64, 0x64, 0x63, 0x61, 0x5f, 0x5e, 0x5b, 0x5b, 0x5e, 0x5f, 0x63, 0x66, - 0x68, 0x67, 0x67, 0x6a, 0x75, 0x83, 0x8f, 0x98, 0xa3, 0xab, 0xb3, 0xb9, - 0xbc, 0xbc, 0xbc, 0xbf, 0xc3, 0xc6, 0xc6, 0xc6, 0xc6, 0xca, 0xcc, 0xcc, - 0xcb, 0xcc, 0xcc, 0xcb, 0xcb, 0xcb, 0xcd, 0xcc, 0xc9, 0xc8, 0xc8, 0xca, - 0xca, 0xcc, 0xcd, 0xcf, 0xd3, 0xd6, 0xd9, 0xda, 0xda, 0xd9, 0xd6, 0xd2, - 0xcf, 0xca, 0xbe, 0xad, 0xaa, 0xac, 0xb1, 0xb3, 0xb6, 0xb7, 0xb8, 0xb7, - 0xb7, 0xba, 0xbc, 0xbc, 0xbb, 0xbd, 0xba, 0xb9, 0xba, 0xbb, 0xbd, 0xbf, - 0xc1, 0xc6, 0xc8, 0xc8, 0xc8, 0xc6, 0xc9, 0xca, 0xc7, 0xc6, 0xc7, 0xc8, - 0xc8, 0xc6, 0xc7, 0xca, 0xce, 0xcf, 0xcd, 0xca, 0xc8, 0xc6, 0xc5, 0xc4, - 0xc4, 0xc6, 0xcc, 0xce, 0xd0, 0xd0, 0xd1, 0xd2, 0xd2, 0xd2, 0xd1, 0xd1, - 0xd2, 0xd4, 0xd8, 0xda, 0xda, 0xd8, 0xd6, 0xd3, 0xcf, 0xcc, 0xce, 0xce, - 0xcd, 0xc4, 0xb7, 0xac, 0xa6, 0x9f, 0x95, 0x8a, 0x89, 0x8a, 0x89, 0x83, - 0x7c, 0x7f, 0x82, 0x85, 0x87, 0x8c, 0x8d, 0x87, 0x82, 0x7d, 0x75, 0x6f, - 0x6e, 0x6c, 0x66, 0x60, 0x60, 0x61, 0x61, 0x60, 0x5d, 0x5c, 0x5b, 0x5b, - 0x5c, 0x54, 0x4f, 0x4e, 0x52, 0x5a, 0x5b, 0x5a, 0x56, 0x5a, 0x68, 0x79, - 0x82, 0x86, 0x84, 0x77, 0x5a, 0x5a, 0x61, 0x66, 0x6c, 0x74, 0x7a, 0x7d, - 0x7e, 0x7f, 0x82, 0x86, 0x89, 0x88, 0x82, 0x72, 0x61, 0x58, 0x56, 0x57, - 0x55, 0x53, 0x51, 0x50, 0x50, 0x4e, 0x53, 0x69, 0x7e, 0x88, 0x91, 0x9a, - 0xa1, 0xa5, 0xa7, 0xa8, 0xa7, 0xa9, 0xab, 0xac, 0xae, 0xb3, 0xb6, 0xb7, - 0xb6, 0xb4, 0xb3, 0xb0, 0xad, 0xac, 0xaa, 0xa7, 0xa4, 0xa2, 0xa2, 0x9f, - 0x9e, 0x9b, 0x9a, 0x99, 0x98, 0x95, 0x94, 0x93, 0x92, 0x92, 0x92, 0x91, - 0x92, 0x92, 0x92, 0x92, 0x92, 0x90, 0x90, 0x8f, 0x8f, 0x8d, 0x8e, 0x8d, - 0x8c, 0x8b, 0x88, 0x87, 0x86, 0x84, 0x83, 0x7f, 0x7d, 0x7b, 0x78, 0x74, - 0x46, 0x48, 0x4a, 0x4d, 0x50, 0x51, 0x54, 0x58, 0x59, 0x5b, 0x5b, 0x5d, - 0x5c, 0x5c, 0x5b, 0x5c, 0x5c, 0x5b, 0x5b, 0x5b, 0x5d, 0x5e, 0x5d, 0x5d, - 0x5f, 0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x60, 0x60, 0x61, 0x61, - 0x63, 0x63, 0x63, 0x65, 0x66, 0x66, 0x66, 0x65, 0x64, 0x64, 0x62, 0x60, - 0x5f, 0x5d, 0x5b, 0x5b, 0x5e, 0x5f, 0x63, 0x66, 0x67, 0x67, 0x66, 0x69, - 0x73, 0x81, 0x8d, 0x96, 0xa1, 0xaa, 0xb3, 0xb9, 0xbc, 0xbc, 0xbc, 0xbf, - 0xc2, 0xc5, 0xc6, 0xc5, 0xc5, 0xc8, 0xca, 0xca, 0xca, 0xca, 0xca, 0xc9, - 0xca, 0xca, 0xcb, 0xc9, 0xc6, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, - 0xd0, 0xd4, 0xd8, 0xd9, 0xda, 0xda, 0xd9, 0xd6, 0xd3, 0xcf, 0xc6, 0xb8, - 0xb0, 0xaf, 0xb2, 0xb5, 0xb6, 0xb8, 0xb8, 0xb6, 0xb7, 0xba, 0xbb, 0xbb, - 0xbb, 0xbd, 0xbb, 0xba, 0xba, 0xbb, 0xbc, 0xbd, 0xc1, 0xc4, 0xc6, 0xc8, - 0xc8, 0xc6, 0xc8, 0xc8, 0xc6, 0xc4, 0xc7, 0xc9, 0xc9, 0xc7, 0xc7, 0xc9, - 0xcc, 0xce, 0xcd, 0xcb, 0xc9, 0xc7, 0xc6, 0xc4, 0xc4, 0xc5, 0xca, 0xcc, - 0xce, 0xcf, 0xcf, 0xd0, 0xd1, 0xd1, 0xd0, 0xd0, 0xd1, 0xd4, 0xd8, 0xdb, - 0xd9, 0xd8, 0xd6, 0xd3, 0xcf, 0xcc, 0xcb, 0xcb, 0xc9, 0xc0, 0xb3, 0xa7, - 0xa1, 0x9e, 0x95, 0x8a, 0x89, 0x8a, 0x8a, 0x81, 0x78, 0x7e, 0x82, 0x87, - 0x88, 0x8c, 0x8c, 0x85, 0x81, 0x7d, 0x76, 0x70, 0x6e, 0x6b, 0x63, 0x5e, - 0x5e, 0x60, 0x60, 0x5f, 0x5b, 0x5b, 0x5c, 0x5c, 0x5b, 0x53, 0x4f, 0x4f, - 0x53, 0x5c, 0x5b, 0x5c, 0x5e, 0x64, 0x73, 0x81, 0x88, 0x88, 0x83, 0x72, - 0x58, 0x5a, 0x62, 0x67, 0x6d, 0x74, 0x79, 0x7b, 0x7c, 0x7d, 0x7f, 0x83, - 0x85, 0x85, 0x80, 0x71, 0x61, 0x5a, 0x58, 0x58, 0x56, 0x54, 0x52, 0x50, - 0x4f, 0x4d, 0x54, 0x6a, 0x7c, 0x86, 0x8f, 0x97, 0x9e, 0xa2, 0xa4, 0xa5, - 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xb2, 0xb5, 0xb7, 0xb6, 0xb4, 0xb3, 0xb0, - 0xac, 0xab, 0xa9, 0xa6, 0xa3, 0xa2, 0xa1, 0x9f, 0x9d, 0x9a, 0x99, 0x99, - 0x97, 0x95, 0x94, 0x93, 0x92, 0x92, 0x93, 0x92, 0x93, 0x93, 0x93, 0x93, - 0x92, 0x92, 0x91, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8d, 0x8c, 0x89, 0x88, - 0x87, 0x85, 0x84, 0x81, 0x7e, 0x7d, 0x7a, 0x76, 0x45, 0x47, 0x49, 0x4c, - 0x4f, 0x51, 0x54, 0x58, 0x59, 0x5a, 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x5a, - 0x5b, 0x5b, 0x5b, 0x5b, 0x5c, 0x5e, 0x5d, 0x5d, 0x5e, 0x5f, 0x60, 0x60, - 0x60, 0x5f, 0x60, 0x61, 0x60, 0x60, 0x61, 0x61, 0x63, 0x63, 0x63, 0x64, - 0x66, 0x66, 0x66, 0x66, 0x64, 0x63, 0x61, 0x5f, 0x5e, 0x5d, 0x5a, 0x5c, - 0x5e, 0x60, 0x63, 0x65, 0x67, 0x66, 0x66, 0x67, 0x71, 0x80, 0x8a, 0x92, - 0x9e, 0xaa, 0xb2, 0xb8, 0xbc, 0xbc, 0xbc, 0xbf, 0xc2, 0xc4, 0xc6, 0xc4, - 0xc3, 0xc5, 0xc6, 0xc7, 0xc8, 0xc8, 0xc7, 0xc7, 0xc8, 0xc9, 0xcb, 0xc8, - 0xc3, 0xc1, 0xc2, 0xc4, 0xc6, 0xc7, 0xc7, 0xc8, 0xcc, 0xcf, 0xd3, 0xd5, - 0xd7, 0xd9, 0xdc, 0xdd, 0xdc, 0xd7, 0xcf, 0xc4, 0xba, 0xb4, 0xaf, 0xb4, - 0xb7, 0xb7, 0xb7, 0xb6, 0xb8, 0xba, 0xbb, 0xbc, 0xbb, 0xbb, 0xbc, 0xbb, - 0xbc, 0xbd, 0xbb, 0xbc, 0xc0, 0xc3, 0xc4, 0xc8, 0xc9, 0xc6, 0xc6, 0xc6, - 0xc5, 0xc3, 0xc6, 0xc9, 0xca, 0xc8, 0xc7, 0xc5, 0xc8, 0xca, 0xca, 0xc9, - 0xc9, 0xc7, 0xc6, 0xc4, 0xc3, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcc, 0xcd, - 0xcd, 0xce, 0xcd, 0xcc, 0xcd, 0xcf, 0xd3, 0xd7, 0xd6, 0xd5, 0xd4, 0xd2, - 0xce, 0xca, 0xc8, 0xc7, 0xc4, 0xba, 0xac, 0xa0, 0x9c, 0x9b, 0x95, 0x8b, - 0x8a, 0x8c, 0x8c, 0x80, 0x78, 0x7f, 0x85, 0x89, 0x89, 0x8b, 0x8b, 0x84, - 0x80, 0x7c, 0x77, 0x71, 0x6c, 0x68, 0x60, 0x5c, 0x5d, 0x5e, 0x5e, 0x5c, - 0x5a, 0x5c, 0x5d, 0x5d, 0x59, 0x52, 0x54, 0x54, 0x57, 0x5e, 0x5d, 0x60, - 0x6b, 0x76, 0x84, 0x8a, 0x8b, 0x85, 0x7b, 0x66, 0x55, 0x5c, 0x64, 0x68, - 0x6d, 0x75, 0x78, 0x7a, 0x7a, 0x79, 0x7b, 0x7e, 0x80, 0x7f, 0x79, 0x6d, - 0x61, 0x5b, 0x59, 0x5a, 0x58, 0x56, 0x52, 0x50, 0x4e, 0x4e, 0x53, 0x67, - 0x78, 0x81, 0x8c, 0x94, 0x9a, 0x9e, 0x9f, 0xa0, 0x9f, 0xa0, 0xa3, 0xa5, - 0xa9, 0xae, 0xb2, 0xb5, 0xb5, 0xb3, 0xb2, 0xaf, 0xac, 0xab, 0xa8, 0xa5, - 0xa2, 0xa1, 0xa0, 0x9e, 0x9d, 0x9a, 0x98, 0x97, 0x97, 0x95, 0x94, 0x92, - 0x92, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x94, 0x93, 0x92, 0x92, 0x90, - 0x90, 0x8f, 0x8f, 0x8f, 0x8e, 0x8d, 0x8b, 0x8a, 0x89, 0x87, 0x86, 0x83, - 0x81, 0x80, 0x7d, 0x78, 0x44, 0x47, 0x4a, 0x4c, 0x4f, 0x50, 0x53, 0x57, - 0x58, 0x59, 0x5a, 0x5a, 0x59, 0x5a, 0x5b, 0x5a, 0x5a, 0x5b, 0x5b, 0x5a, - 0x5b, 0x5d, 0x5d, 0x5c, 0x5d, 0x60, 0x60, 0x5f, 0x5e, 0x5f, 0x61, 0x61, - 0x61, 0x61, 0x62, 0x61, 0x63, 0x64, 0x64, 0x63, 0x64, 0x66, 0x66, 0x65, - 0x63, 0x61, 0x5f, 0x5e, 0x5e, 0x5c, 0x5a, 0x5b, 0x5e, 0x60, 0x63, 0x64, - 0x65, 0x67, 0x67, 0x68, 0x6f, 0x7d, 0x88, 0x90, 0x9c, 0xa7, 0xb0, 0xb7, - 0xbb, 0xbc, 0xbc, 0xbd, 0xc1, 0xc4, 0xc5, 0xc5, 0xc3, 0xc2, 0xc4, 0xc6, - 0xc7, 0xc6, 0xc6, 0xc6, 0xc7, 0xca, 0xcd, 0xc9, 0xc4, 0xc1, 0xc0, 0xc0, - 0xc1, 0xc1, 0xc3, 0xc6, 0xc9, 0xcb, 0xce, 0xd0, 0xd3, 0xd6, 0xdb, 0xe1, - 0xe3, 0xe0, 0xd9, 0xd0, 0xc8, 0xbf, 0xb2, 0xb1, 0xb5, 0xb7, 0xb8, 0xb7, - 0xb7, 0xb9, 0xba, 0xbb, 0xbc, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, - 0xbf, 0xc2, 0xc3, 0xc5, 0xc8, 0xc7, 0xc4, 0xc3, 0xc3, 0xc2, 0xc4, 0xc7, - 0xc8, 0xc7, 0xc5, 0xc4, 0xc7, 0xc8, 0xc8, 0xc7, 0xc6, 0xc5, 0xc4, 0xc5, - 0xc4, 0xc2, 0xc2, 0xc3, 0xc4, 0xc5, 0xc7, 0xc8, 0xc8, 0xc8, 0xc7, 0xc5, - 0xc3, 0xc4, 0xc8, 0xce, 0xd1, 0xd0, 0xd0, 0xce, 0xcb, 0xc7, 0xc5, 0xc3, - 0xbe, 0xb6, 0xa8, 0x9b, 0x97, 0x97, 0x8f, 0x87, 0x87, 0x89, 0x8c, 0x85, - 0x7e, 0x85, 0x89, 0x8a, 0x89, 0x8b, 0x89, 0x82, 0x7e, 0x79, 0x76, 0x70, - 0x6b, 0x66, 0x5f, 0x5c, 0x5d, 0x5d, 0x5c, 0x5a, 0x5b, 0x5d, 0x5d, 0x5a, - 0x54, 0x53, 0x5a, 0x5b, 0x5e, 0x63, 0x69, 0x74, 0x83, 0x8c, 0x92, 0x8f, - 0x87, 0x76, 0x68, 0x55, 0x53, 0x5d, 0x64, 0x68, 0x6f, 0x75, 0x77, 0x77, - 0x77, 0x76, 0x77, 0x79, 0x79, 0x77, 0x70, 0x67, 0x5f, 0x5c, 0x5b, 0x5a, - 0x5a, 0x57, 0x54, 0x52, 0x50, 0x4f, 0x54, 0x62, 0x71, 0x7a, 0x84, 0x8f, - 0x95, 0x98, 0x9a, 0x9a, 0x99, 0x99, 0x9c, 0xa0, 0xa5, 0xa9, 0xaf, 0xb3, - 0xb4, 0xb3, 0xb1, 0xaf, 0xac, 0xab, 0xa8, 0xa4, 0xa2, 0xa0, 0x9f, 0x9e, - 0x9d, 0x99, 0x97, 0x96, 0x95, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, - 0x92, 0x92, 0x92, 0x94, 0x94, 0x93, 0x93, 0x92, 0x92, 0x90, 0x90, 0x90, - 0x8f, 0x90, 0x8e, 0x8d, 0x8b, 0x8a, 0x89, 0x86, 0x84, 0x82, 0x80, 0x7c, - 0x43, 0x46, 0x4a, 0x4d, 0x4f, 0x50, 0x52, 0x55, 0x57, 0x58, 0x5a, 0x5a, - 0x59, 0x5a, 0x5c, 0x5c, 0x5b, 0x5b, 0x5b, 0x5a, 0x5b, 0x5d, 0x5d, 0x5c, - 0x5e, 0x60, 0x60, 0x5f, 0x5f, 0x5f, 0x61, 0x61, 0x60, 0x61, 0x62, 0x61, - 0x63, 0x64, 0x63, 0x63, 0x64, 0x65, 0x66, 0x65, 0x63, 0x61, 0x5e, 0x5d, - 0x5d, 0x5c, 0x5a, 0x5b, 0x5d, 0x5f, 0x63, 0x63, 0x64, 0x65, 0x66, 0x66, - 0x6d, 0x7a, 0x85, 0x8d, 0x98, 0xa5, 0xad, 0xb5, 0xba, 0xbb, 0xbb, 0xbc, - 0xbf, 0xc3, 0xc5, 0xc6, 0xc4, 0xc2, 0xc4, 0xc6, 0xc7, 0xc6, 0xc8, 0xc7, - 0xc9, 0xcc, 0xd0, 0xcf, 0xcb, 0xc8, 0xc5, 0xc1, 0xbd, 0xbd, 0xbf, 0xc4, - 0xc8, 0xca, 0xcd, 0xce, 0xd0, 0xd2, 0xd5, 0xdc, 0xe0, 0xe3, 0xe2, 0xdc, - 0xd5, 0xcc, 0xbd, 0xad, 0xaf, 0xb6, 0xb8, 0xb7, 0xb6, 0xb7, 0xba, 0xbc, - 0xbd, 0xba, 0xb8, 0xb8, 0xb9, 0xba, 0xbb, 0xba, 0xbc, 0xbf, 0xc1, 0xc2, - 0xc7, 0xc9, 0xc4, 0xc2, 0xc1, 0xc1, 0xc0, 0xc1, 0xc2, 0xc1, 0xc1, 0xc1, - 0xc3, 0xc4, 0xc4, 0xc2, 0xc2, 0xc1, 0xc1, 0xc3, 0xc3, 0xbf, 0xc0, 0xc1, - 0xc1, 0xc1, 0xc2, 0xc3, 0xc3, 0xc2, 0xc2, 0xbf, 0xbd, 0xbc, 0xbe, 0xc3, - 0xc8, 0xc9, 0xca, 0xc9, 0xc7, 0xc5, 0xc2, 0xbf, 0xba, 0xb4, 0xa8, 0x9a, - 0x94, 0x91, 0x8a, 0x84, 0x87, 0x8a, 0x8c, 0x87, 0x83, 0x89, 0x8b, 0x89, - 0x87, 0x8a, 0x88, 0x81, 0x7d, 0x78, 0x73, 0x6c, 0x66, 0x62, 0x5d, 0x5c, - 0x5e, 0x5c, 0x5b, 0x5a, 0x5f, 0x5f, 0x58, 0x54, 0x50, 0x57, 0x5f, 0x68, - 0x6e, 0x77, 0x81, 0x8a, 0x8e, 0x90, 0x8f, 0x8a, 0x72, 0x57, 0x4d, 0x4b, - 0x56, 0x60, 0x67, 0x6a, 0x70, 0x75, 0x75, 0x73, 0x71, 0x6f, 0x71, 0x73, - 0x70, 0x6e, 0x69, 0x61, 0x5b, 0x5a, 0x5a, 0x5a, 0x5b, 0x59, 0x55, 0x53, - 0x51, 0x50, 0x51, 0x5c, 0x69, 0x72, 0x7c, 0x87, 0x8e, 0x93, 0x93, 0x94, - 0x92, 0x93, 0x96, 0x9a, 0x9f, 0xa5, 0xaa, 0xae, 0xb0, 0xb1, 0xb0, 0xae, - 0xab, 0xa9, 0xa8, 0xa5, 0xa1, 0xa0, 0x9e, 0x9d, 0x9b, 0x97, 0x95, 0x93, - 0x93, 0x91, 0x91, 0x91, 0x91, 0x91, 0x92, 0x91, 0x92, 0x92, 0x91, 0x92, - 0x92, 0x92, 0x92, 0x93, 0x92, 0x90, 0x90, 0x90, 0x91, 0x92, 0x91, 0x8e, - 0x8d, 0x8b, 0x8a, 0x88, 0x86, 0x84, 0x83, 0x7f, 0x42, 0x46, 0x4a, 0x4c, - 0x4f, 0x51, 0x52, 0x55, 0x57, 0x58, 0x5a, 0x5b, 0x5b, 0x5b, 0x5b, 0x5c, - 0x5b, 0x5c, 0x5c, 0x5b, 0x5b, 0x5d, 0x5d, 0x5c, 0x5d, 0x5f, 0x60, 0x5f, - 0x5f, 0x60, 0x62, 0x62, 0x61, 0x61, 0x62, 0x61, 0x63, 0x63, 0x63, 0x62, - 0x63, 0x65, 0x66, 0x65, 0x64, 0x61, 0x5e, 0x5c, 0x5c, 0x5c, 0x5b, 0x5c, - 0x5e, 0x60, 0x62, 0x64, 0x63, 0x64, 0x65, 0x65, 0x6b, 0x79, 0x84, 0x8b, - 0x95, 0xa3, 0xab, 0xb4, 0xb9, 0xbb, 0xbc, 0xbd, 0xbf, 0xc1, 0xc3, 0xc6, - 0xc5, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc8, 0xc9, 0xca, 0xce, 0xd2, 0xd2, - 0xd1, 0xcf, 0xcb, 0xc6, 0xbf, 0xbc, 0xbd, 0xc2, 0xc7, 0xca, 0xcc, 0xcd, - 0xce, 0xcf, 0xd1, 0xd3, 0xd7, 0xde, 0xe4, 0xe3, 0xde, 0xd8, 0xc9, 0xb0, - 0xa4, 0xad, 0xb4, 0xb7, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xb9, 0xb9, 0xbb, - 0xbb, 0xba, 0xba, 0xb9, 0xba, 0xbb, 0xbb, 0xbd, 0xc4, 0xc8, 0xc5, 0xc2, - 0xc1, 0xc0, 0xbe, 0xbd, 0xbe, 0xbd, 0xbf, 0xbe, 0xbe, 0xbf, 0xbf, 0xbe, - 0xbf, 0xbe, 0xbf, 0xc1, 0xc2, 0xbe, 0xbe, 0xbf, 0xbf, 0xbe, 0xc0, 0xbf, - 0xbf, 0xbd, 0xbd, 0xbc, 0xbd, 0xbd, 0xbc, 0xbf, 0xc3, 0xc5, 0xc5, 0xc4, - 0xc5, 0xc2, 0xbf, 0xbb, 0xb7, 0xb1, 0xa7, 0x9a, 0x95, 0x8f, 0x88, 0x86, - 0x8b, 0x8e, 0x8f, 0x88, 0x84, 0x89, 0x8b, 0x89, 0x88, 0x8a, 0x88, 0x80, - 0x7c, 0x77, 0x71, 0x69, 0x62, 0x5e, 0x5c, 0x5e, 0x5f, 0x5e, 0x5c, 0x5d, - 0x61, 0x5d, 0x54, 0x50, 0x51, 0x5d, 0x6a, 0x77, 0x7f, 0x87, 0x8e, 0x8f, - 0x8f, 0x90, 0x8d, 0x7a, 0x54, 0x41, 0x3f, 0x4b, 0x5b, 0x63, 0x68, 0x6d, - 0x72, 0x74, 0x72, 0x6e, 0x6c, 0x6c, 0x6e, 0x6e, 0x6c, 0x6a, 0x65, 0x5e, - 0x59, 0x57, 0x57, 0x57, 0x59, 0x57, 0x55, 0x53, 0x51, 0x50, 0x50, 0x56, - 0x61, 0x69, 0x75, 0x81, 0x8a, 0x8e, 0x90, 0x90, 0x8e, 0x8f, 0x92, 0x95, - 0x9a, 0xa1, 0xa7, 0xaa, 0xac, 0xaf, 0xaf, 0xad, 0xaa, 0xa9, 0xa8, 0xa6, - 0xa1, 0x9f, 0x9d, 0x9c, 0x98, 0x94, 0x93, 0x92, 0x91, 0x8f, 0x90, 0x90, - 0x90, 0x90, 0x91, 0x90, 0x91, 0x91, 0x90, 0x91, 0x91, 0x91, 0x91, 0x92, - 0x92, 0x91, 0x91, 0x92, 0x92, 0x92, 0x91, 0x8f, 0x8e, 0x8d, 0x8c, 0x8a, - 0x88, 0x87, 0x85, 0x82, 0x42, 0x45, 0x4a, 0x4c, 0x4e, 0x51, 0x52, 0x55, - 0x57, 0x58, 0x5b, 0x5c, 0x5c, 0x5c, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5b, - 0x5c, 0x5d, 0x5d, 0x5d, 0x5e, 0x5f, 0x5f, 0x5e, 0x5f, 0x61, 0x62, 0x62, - 0x61, 0x61, 0x62, 0x61, 0x63, 0x63, 0x63, 0x62, 0x63, 0x65, 0x66, 0x65, - 0x64, 0x61, 0x5e, 0x5c, 0x5c, 0x5c, 0x5b, 0x5c, 0x5f, 0x60, 0x62, 0x64, - 0x63, 0x64, 0x64, 0x64, 0x69, 0x77, 0x82, 0x89, 0x94, 0xa1, 0xaa, 0xb3, - 0xb8, 0xba, 0xbc, 0xbd, 0xbe, 0xc1, 0xc2, 0xc5, 0xc5, 0xc4, 0xc5, 0xc5, - 0xc6, 0xc7, 0xc8, 0xca, 0xcb, 0xce, 0xd2, 0xd3, 0xd3, 0xd2, 0xcf, 0xca, - 0xc4, 0xbf, 0xbe, 0xc1, 0xc5, 0xc9, 0xcc, 0xcd, 0xcd, 0xcf, 0xcf, 0xcf, - 0xd2, 0xda, 0xe2, 0xe4, 0xe1, 0xdd, 0xd1, 0xb8, 0xa1, 0xa4, 0xab, 0xb4, - 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xb8, 0xb9, 0xbb, 0xbb, 0xb9, 0xb8, 0xb7, - 0xb7, 0xb7, 0xb8, 0xb9, 0xc0, 0xc7, 0xc4, 0xc2, 0xc0, 0xbf, 0xbc, 0xbc, - 0xbb, 0xbc, 0xbc, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbd, 0xbc, 0xbd, 0xc0, - 0xc0, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbe, 0xbd, 0xbd, 0xbb, 0xbb, 0xbb, - 0xbc, 0xbc, 0xbc, 0xbe, 0xc1, 0xc3, 0xc3, 0xc3, 0xc3, 0xc1, 0xbd, 0xba, - 0xb5, 0xaf, 0xa5, 0x9a, 0x95, 0x8f, 0x89, 0x8a, 0x8e, 0x91, 0x92, 0x89, - 0x84, 0x88, 0x89, 0x88, 0x87, 0x89, 0x87, 0x81, 0x7d, 0x77, 0x71, 0x67, - 0x60, 0x5d, 0x5c, 0x5f, 0x60, 0x5e, 0x5d, 0x5e, 0x5f, 0x5b, 0x52, 0x51, - 0x57, 0x65, 0x74, 0x80, 0x87, 0x8e, 0x92, 0x90, 0x90, 0x8e, 0x84, 0x67, - 0x42, 0x39, 0x3d, 0x4e, 0x5e, 0x66, 0x6a, 0x6c, 0x70, 0x71, 0x6e, 0x6c, - 0x6b, 0x6b, 0x6c, 0x6c, 0x69, 0x67, 0x63, 0x5c, 0x57, 0x55, 0x55, 0x55, - 0x58, 0x57, 0x55, 0x53, 0x51, 0x4f, 0x4d, 0x52, 0x5c, 0x63, 0x6f, 0x7d, - 0x87, 0x8c, 0x8e, 0x8e, 0x8d, 0x8e, 0x91, 0x93, 0x98, 0x9f, 0xa4, 0xa8, - 0xaa, 0xad, 0xae, 0xad, 0xaa, 0xa9, 0xa9, 0xa6, 0xa1, 0x9f, 0x9d, 0x9a, - 0x97, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, - 0x8f, 0x8f, 0x8e, 0x8f, 0x91, 0x91, 0x91, 0x92, 0x92, 0x91, 0x91, 0x92, - 0x91, 0x91, 0x91, 0x8f, 0x8f, 0x8e, 0x8d, 0x8b, 0x8a, 0x88, 0x87, 0x84, - 0x43, 0x46, 0x49, 0x4b, 0x4e, 0x52, 0x53, 0x55, 0x57, 0x58, 0x5b, 0x5c, - 0x5c, 0x5b, 0x5a, 0x5b, 0x5a, 0x5c, 0x5c, 0x5c, 0x5d, 0x5e, 0x5d, 0x5d, - 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x61, 0x63, 0x63, 0x62, 0x62, 0x62, 0x62, - 0x61, 0x62, 0x63, 0x63, 0x63, 0x65, 0x65, 0x65, 0x62, 0x60, 0x5d, 0x5c, - 0x5c, 0x5b, 0x5c, 0x5f, 0x60, 0x61, 0x61, 0x63, 0x63, 0x63, 0x63, 0x62, - 0x66, 0x75, 0x81, 0x88, 0x92, 0x9f, 0xa8, 0xb0, 0xb6, 0xb8, 0xbb, 0xbc, - 0xbd, 0xc0, 0xc2, 0xc5, 0xc6, 0xc5, 0xc6, 0xc6, 0xc6, 0xc8, 0xc9, 0xc9, - 0xcb, 0xce, 0xd0, 0xd3, 0xd4, 0xd4, 0xd2, 0xd0, 0xcb, 0xc7, 0xc4, 0xc1, - 0xc3, 0xc7, 0xca, 0xcb, 0xce, 0xcf, 0xd0, 0xcf, 0xd0, 0xd4, 0xda, 0xe0, - 0xe3, 0xe1, 0xdb, 0xc8, 0xa9, 0x9a, 0x9a, 0xa8, 0xb5, 0xb7, 0xb7, 0xb8, - 0xb8, 0xb8, 0xb7, 0xb9, 0xb8, 0xb5, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb5, - 0xbb, 0xc2, 0xc1, 0xbf, 0xbe, 0xbc, 0xbb, 0xba, 0xba, 0xba, 0xb9, 0xb7, - 0xb5, 0xb5, 0xb6, 0xb6, 0xb9, 0xba, 0xba, 0xbc, 0xbd, 0xba, 0xb9, 0xba, - 0xba, 0xba, 0xba, 0xba, 0xba, 0xb9, 0xb9, 0xba, 0xbb, 0xbb, 0xbb, 0xbc, - 0xbf, 0xc1, 0xc1, 0xc1, 0xc2, 0xc0, 0xbd, 0xb9, 0xb3, 0xab, 0xa1, 0x98, - 0x94, 0x90, 0x8b, 0x90, 0x93, 0x96, 0x96, 0x8d, 0x84, 0x85, 0x87, 0x88, - 0x86, 0x84, 0x84, 0x81, 0x7e, 0x78, 0x70, 0x66, 0x5f, 0x5d, 0x5d, 0x60, - 0x5f, 0x5e, 0x5c, 0x5b, 0x5b, 0x58, 0x54, 0x58, 0x68, 0x77, 0x82, 0x89, - 0x8e, 0x94, 0x94, 0x91, 0x8b, 0x81, 0x68, 0x44, 0x36, 0x3a, 0x43, 0x54, - 0x63, 0x69, 0x69, 0x6a, 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6b, 0x6a, - 0x66, 0x63, 0x60, 0x5a, 0x57, 0x54, 0x53, 0x54, 0x57, 0x56, 0x54, 0x52, - 0x50, 0x4b, 0x49, 0x4c, 0x53, 0x5b, 0x67, 0x76, 0x82, 0x89, 0x8d, 0x8f, - 0x90, 0x8f, 0x90, 0x91, 0x95, 0x9b, 0xa0, 0xa3, 0xa6, 0xa9, 0xab, 0xab, - 0xaa, 0xa9, 0xa8, 0xa5, 0xa1, 0x9f, 0x9c, 0x98, 0x94, 0x92, 0x90, 0x8f, - 0x8e, 0x8c, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, - 0x8f, 0x8f, 0x8f, 0x90, 0x8f, 0x90, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, - 0x90, 0x8f, 0x8d, 0x8b, 0x8a, 0x89, 0x87, 0x85, 0x43, 0x45, 0x48, 0x4a, - 0x4c, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5b, 0x5c, 0x5b, 0x5a, 0x5b, - 0x5b, 0x5a, 0x5a, 0x5b, 0x5d, 0x5e, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5e, - 0x5f, 0x61, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x61, 0x61, 0x62, 0x63, - 0x63, 0x64, 0x64, 0x63, 0x62, 0x60, 0x5d, 0x5c, 0x5b, 0x5b, 0x5c, 0x5f, - 0x61, 0x61, 0x60, 0x61, 0x61, 0x61, 0x61, 0x60, 0x64, 0x71, 0x7f, 0x86, - 0x8f, 0x9c, 0xa5, 0xad, 0xb3, 0xb6, 0xb9, 0xbb, 0xbc, 0xbf, 0xc1, 0xc3, - 0xc5, 0xc5, 0xc6, 0xc6, 0xc6, 0xc8, 0xc9, 0xcb, 0xcd, 0xce, 0xcf, 0xd2, - 0xd5, 0xd6, 0xd6, 0xd6, 0xd4, 0xd1, 0xce, 0xc8, 0xc4, 0xc3, 0xc6, 0xc9, - 0xcb, 0xcc, 0xce, 0xcf, 0xcf, 0xd0, 0xd2, 0xd7, 0xdb, 0xde, 0xe1, 0xdb, - 0xc6, 0xa9, 0x99, 0x8f, 0xa0, 0xb0, 0xb4, 0xb5, 0xb5, 0xb5, 0xb3, 0xb3, - 0xb3, 0xb3, 0xb3, 0xb3, 0xb1, 0xb0, 0xb1, 0xb1, 0xb1, 0xb7, 0xb9, 0xb9, - 0xba, 0xb9, 0xb9, 0xba, 0xb9, 0xb8, 0xb6, 0xb4, 0xb2, 0xb2, 0xb2, 0xb2, - 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb5, 0xb5, - 0xb6, 0xb6, 0xb6, 0xb8, 0xb9, 0xba, 0xba, 0xbb, 0xbe, 0xc0, 0xc0, 0xbe, - 0xbe, 0xbd, 0xba, 0xb6, 0xaf, 0xa5, 0x9c, 0x98, 0x96, 0x93, 0x90, 0x95, - 0x98, 0x98, 0x97, 0x90, 0x86, 0x84, 0x84, 0x85, 0x83, 0x80, 0x81, 0x80, - 0x7e, 0x77, 0x6e, 0x66, 0x60, 0x5e, 0x60, 0x5f, 0x5d, 0x59, 0x57, 0x56, - 0x5b, 0x64, 0x6b, 0x72, 0x7f, 0x89, 0x8e, 0x93, 0x95, 0x95, 0x8c, 0x77, - 0x5f, 0x50, 0x40, 0x35, 0x37, 0x41, 0x4a, 0x5a, 0x67, 0x6a, 0x67, 0x66, - 0x66, 0x6a, 0x6c, 0x6e, 0x6e, 0x6d, 0x6b, 0x67, 0x63, 0x61, 0x5e, 0x5a, - 0x55, 0x52, 0x51, 0x53, 0x57, 0x56, 0x52, 0x4f, 0x4b, 0x46, 0x44, 0x44, - 0x48, 0x4e, 0x5a, 0x6d, 0x7d, 0x87, 0x8c, 0x92, 0x95, 0x92, 0x90, 0x8f, - 0x91, 0x95, 0x99, 0x9d, 0xa0, 0xa3, 0xa5, 0xa6, 0xa5, 0xa5, 0xa4, 0xa2, - 0x9f, 0x9c, 0x9a, 0x96, 0x92, 0x90, 0x8f, 0x8e, 0x8c, 0x8a, 0x8b, 0x8b, - 0x8b, 0x8a, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8d, 0x8e, 0x8e, 0x8d, - 0x8d, 0x8e, 0x8e, 0x8f, 0x90, 0x91, 0x91, 0x90, 0x8f, 0x8f, 0x8e, 0x8c, - 0x8a, 0x89, 0x89, 0x86, 0x42, 0x45, 0x48, 0x4a, 0x4b, 0x4f, 0x53, 0x55, - 0x56, 0x58, 0x5a, 0x5b, 0x5b, 0x5a, 0x59, 0x5a, 0x59, 0x5a, 0x5a, 0x5b, - 0x5c, 0x5c, 0x5e, 0x5f, 0x5f, 0x5e, 0x60, 0x61, 0x61, 0x60, 0x61, 0x62, - 0x61, 0x61, 0x61, 0x62, 0x63, 0x63, 0x62, 0x62, 0x63, 0x64, 0x63, 0x62, - 0x60, 0x5f, 0x5d, 0x5b, 0x5a, 0x5b, 0x5d, 0x60, 0x61, 0x61, 0x60, 0x61, - 0x61, 0x60, 0x5f, 0x5f, 0x62, 0x6f, 0x7d, 0x85, 0x8e, 0x99, 0xa2, 0xab, - 0xb1, 0xb4, 0xb8, 0xba, 0xbb, 0xbd, 0xbe, 0xc1, 0xc3, 0xc4, 0xc7, 0xc8, - 0xc7, 0xc6, 0xc9, 0xcc, 0xce, 0xcf, 0xcf, 0xd0, 0xd3, 0xd5, 0xd7, 0xd7, - 0xd7, 0xd7, 0xd5, 0xd0, 0xca, 0xc2, 0xc2, 0xc4, 0xc7, 0xcb, 0xcd, 0xd0, - 0xd1, 0xd2, 0xd1, 0xd1, 0xd2, 0xd5, 0xdc, 0xde, 0xd8, 0xca, 0xb8, 0x97, - 0x85, 0x9b, 0xab, 0xaf, 0xac, 0xab, 0xaa, 0xac, 0xad, 0xad, 0xaf, 0xad, - 0xac, 0xad, 0xac, 0xab, 0xa7, 0xa9, 0xae, 0xb1, 0xb3, 0xb1, 0xb5, 0xb9, - 0xb9, 0xb5, 0xb2, 0xb3, 0xb3, 0xb2, 0xb1, 0xb1, 0xb2, 0xb1, 0xb0, 0xaf, - 0xaf, 0xb0, 0xaf, 0xb0, 0xb0, 0xb0, 0xb2, 0xb3, 0xb3, 0xb3, 0xb4, 0xb5, - 0xb7, 0xb8, 0xb9, 0xbb, 0xbd, 0xbe, 0xbd, 0xba, 0xb9, 0xb9, 0xb6, 0xb1, - 0xa9, 0x9f, 0x9b, 0x98, 0x95, 0x90, 0x90, 0x96, 0x99, 0x99, 0x98, 0x92, - 0x89, 0x84, 0x82, 0x81, 0x80, 0x7e, 0x7f, 0x7e, 0x7c, 0x76, 0x6d, 0x67, - 0x62, 0x60, 0x61, 0x5f, 0x5c, 0x5b, 0x5b, 0x61, 0x6f, 0x7c, 0x84, 0x88, - 0x8e, 0x93, 0x95, 0x92, 0x8c, 0x79, 0x5b, 0x44, 0x3a, 0x39, 0x39, 0x3a, - 0x3f, 0x47, 0x50, 0x5d, 0x67, 0x66, 0x63, 0x64, 0x68, 0x6d, 0x70, 0x71, - 0x71, 0x6f, 0x6b, 0x67, 0x63, 0x61, 0x5f, 0x5b, 0x55, 0x52, 0x51, 0x53, - 0x58, 0x55, 0x50, 0x4b, 0x46, 0x40, 0x3d, 0x3d, 0x3f, 0x43, 0x50, 0x67, - 0x7c, 0x89, 0x8f, 0x95, 0x98, 0x96, 0x93, 0x90, 0x8e, 0x8f, 0x93, 0x98, - 0x9b, 0x9d, 0x9f, 0x9f, 0x9f, 0x9f, 0x9d, 0x9c, 0x9a, 0x98, 0x96, 0x93, - 0x8f, 0x8e, 0x8e, 0x8e, 0x8d, 0x8a, 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x88, - 0x89, 0x89, 0x89, 0x8a, 0x8a, 0x8b, 0x8b, 0x8b, 0x8c, 0x8c, 0x8d, 0x8d, - 0x8f, 0x90, 0x90, 0x8f, 0x8f, 0x90, 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x88, - 0x41, 0x46, 0x49, 0x4a, 0x4c, 0x4e, 0x53, 0x55, 0x56, 0x57, 0x5a, 0x5b, - 0x5b, 0x5a, 0x59, 0x5a, 0x59, 0x59, 0x5a, 0x5a, 0x5c, 0x5c, 0x5e, 0x5f, - 0x5e, 0x5f, 0x61, 0x62, 0x61, 0x60, 0x61, 0x62, 0x62, 0x61, 0x61, 0x61, - 0x63, 0x64, 0x64, 0x64, 0x63, 0x63, 0x62, 0x61, 0x60, 0x5d, 0x5b, 0x5b, - 0x5a, 0x5b, 0x5e, 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x60, 0x5f, 0x5f, - 0x61, 0x6d, 0x7b, 0x84, 0x8d, 0x98, 0xa0, 0xa9, 0xaf, 0xb3, 0xb7, 0xb9, - 0xbb, 0xbc, 0xbe, 0xc0, 0xc2, 0xc5, 0xc8, 0xc9, 0xc7, 0xc6, 0xc9, 0xce, - 0xd0, 0xd1, 0xd0, 0xcf, 0xd2, 0xd4, 0xd6, 0xd7, 0xd7, 0xd8, 0xd8, 0xd5, - 0xd0, 0xc6, 0xc0, 0xc0, 0xc4, 0xc8, 0xcd, 0xd1, 0xd5, 0xd6, 0xd4, 0xd0, - 0xce, 0xd0, 0xd6, 0xdc, 0xdd, 0xdb, 0xd2, 0xb8, 0x95, 0x9d, 0xaf, 0xb3, - 0xab, 0xa5, 0xa2, 0xa4, 0xa4, 0xa2, 0xa4, 0xa6, 0xa4, 0xa6, 0xa7, 0xa6, - 0xa1, 0xa0, 0xa4, 0xa6, 0xa6, 0xa1, 0xae, 0xb7, 0xb8, 0xb3, 0xb2, 0xb2, - 0xb2, 0xb0, 0xaf, 0xaf, 0xaf, 0xae, 0xad, 0xab, 0xab, 0xac, 0xac, 0xac, - 0xab, 0xab, 0xad, 0xaf, 0xb0, 0xb1, 0xb1, 0xb3, 0xb5, 0xb7, 0xb8, 0xba, - 0xbc, 0xbc, 0xba, 0xb7, 0xb4, 0xb5, 0xb1, 0xac, 0xa3, 0x9b, 0x9b, 0x98, - 0x94, 0x8f, 0x90, 0x98, 0x9a, 0x9a, 0x98, 0x92, 0x8c, 0x87, 0x84, 0x80, - 0x7e, 0x7e, 0x7e, 0x7d, 0x7b, 0x75, 0x6d, 0x68, 0x64, 0x62, 0x60, 0x61, - 0x65, 0x69, 0x6d, 0x75, 0x82, 0x8a, 0x8e, 0x91, 0x94, 0x99, 0x8f, 0x73, - 0x5f, 0x48, 0x39, 0x35, 0x37, 0x39, 0x3c, 0x3e, 0x43, 0x4c, 0x53, 0x5e, - 0x62, 0x61, 0x61, 0x63, 0x6b, 0x70, 0x73, 0x73, 0x72, 0x70, 0x6c, 0x66, - 0x63, 0x61, 0x5e, 0x5b, 0x55, 0x52, 0x53, 0x55, 0x57, 0x53, 0x4e, 0x4a, - 0x43, 0x3c, 0x3a, 0x38, 0x37, 0x3c, 0x4b, 0x64, 0x7c, 0x8a, 0x91, 0x96, - 0x99, 0x97, 0x94, 0x91, 0x8d, 0x8c, 0x8e, 0x92, 0x95, 0x98, 0x9a, 0x9a, - 0x9a, 0x99, 0x97, 0x96, 0x94, 0x92, 0x91, 0x8f, 0x8d, 0x8d, 0x8d, 0x8d, - 0x8c, 0x8a, 0x89, 0x89, 0x88, 0x87, 0x87, 0x87, 0x88, 0x89, 0x88, 0x88, - 0x88, 0x89, 0x89, 0x89, 0x8b, 0x8c, 0x8c, 0x8b, 0x8c, 0x8e, 0x8e, 0x8f, - 0x8f, 0x8f, 0x8e, 0x8f, 0x8f, 0x8e, 0x8d, 0x8a, 0x41, 0x46, 0x4a, 0x4b, - 0x4c, 0x4e, 0x53, 0x55, 0x56, 0x57, 0x5a, 0x5b, 0x5b, 0x5b, 0x59, 0x5a, - 0x59, 0x59, 0x5a, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x5e, 0x5f, 0x61, 0x62, - 0x62, 0x60, 0x61, 0x62, 0x62, 0x61, 0x61, 0x61, 0x63, 0x64, 0x64, 0x64, - 0x62, 0x62, 0x62, 0x62, 0x60, 0x5d, 0x5b, 0x5a, 0x5a, 0x5b, 0x5f, 0x61, - 0x61, 0x61, 0x61, 0x60, 0x5f, 0x60, 0x5f, 0x5f, 0x60, 0x6b, 0x79, 0x82, - 0x8c, 0x96, 0x9f, 0xa7, 0xad, 0xb1, 0xb6, 0xb8, 0xba, 0xbc, 0xbd, 0xc0, - 0xc2, 0xc5, 0xc7, 0xc8, 0xc7, 0xc6, 0xca, 0xcf, 0xd1, 0xd1, 0xd0, 0xcf, - 0xd2, 0xd4, 0xd5, 0xd6, 0xd6, 0xd8, 0xd8, 0xd6, 0xd2, 0xc9, 0xc1, 0xbf, - 0xc1, 0xc7, 0xcc, 0xd2, 0xd5, 0xd8, 0xd7, 0xd1, 0xcf, 0xcf, 0xd3, 0xd9, - 0xde, 0xe1, 0xdd, 0xca, 0xa7, 0xa3, 0xb2, 0xb7, 0xb5, 0xaf, 0xa7, 0xa5, - 0xa2, 0x9c, 0x9a, 0x9e, 0x9c, 0x9f, 0xa0, 0xa1, 0x9d, 0x9b, 0x9c, 0x9d, - 0x9d, 0x97, 0xa5, 0xb0, 0xb3, 0xb0, 0xaf, 0xb1, 0xb0, 0xae, 0xac, 0xac, - 0xad, 0xac, 0xab, 0xa9, 0xa9, 0xaa, 0xaa, 0xaa, 0xa9, 0xa9, 0xaa, 0xac, - 0xad, 0xae, 0xae, 0xb1, 0xb4, 0xb5, 0xb7, 0xb9, 0xbb, 0xba, 0xb8, 0xb5, - 0xb2, 0xb1, 0xad, 0xa8, 0x9f, 0x98, 0x9a, 0x98, 0x94, 0x8e, 0x91, 0x99, - 0x9c, 0x9b, 0x99, 0x94, 0x8e, 0x89, 0x86, 0x80, 0x7d, 0x7e, 0x7e, 0x7c, - 0x79, 0x73, 0x6d, 0x69, 0x64, 0x62, 0x63, 0x69, 0x70, 0x75, 0x79, 0x81, - 0x8b, 0x8f, 0x92, 0x94, 0x95, 0x90, 0x79, 0x58, 0x44, 0x34, 0x30, 0x35, - 0x3a, 0x3b, 0x3e, 0x3f, 0x45, 0x4e, 0x56, 0x5f, 0x60, 0x5e, 0x61, 0x65, - 0x6d, 0x73, 0x74, 0x72, 0x70, 0x6c, 0x69, 0x64, 0x62, 0x61, 0x5e, 0x5a, - 0x55, 0x53, 0x54, 0x56, 0x57, 0x53, 0x4e, 0x4a, 0x43, 0x3c, 0x38, 0x35, - 0x34, 0x3a, 0x4a, 0x64, 0x7c, 0x8b, 0x92, 0x97, 0x99, 0x97, 0x94, 0x92, - 0x8d, 0x8a, 0x8a, 0x8e, 0x90, 0x93, 0x94, 0x95, 0x94, 0x94, 0x92, 0x90, - 0x8e, 0x8c, 0x8b, 0x8b, 0x89, 0x89, 0x8a, 0x8a, 0x8a, 0x88, 0x88, 0x88, - 0x87, 0x85, 0x85, 0x85, 0x87, 0x87, 0x87, 0x86, 0x87, 0x87, 0x87, 0x88, - 0x8a, 0x8b, 0x8b, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x8f, 0x8e, 0x8f, - 0x8f, 0x8e, 0x8d, 0x8a, 0x41, 0x47, 0x4a, 0x4b, 0x4c, 0x4f, 0x52, 0x54, - 0x55, 0x58, 0x5a, 0x5b, 0x5b, 0x5b, 0x5a, 0x59, 0x59, 0x59, 0x5a, 0x5a, - 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x5f, 0x61, 0x61, 0x61, 0x60, 0x61, 0x62, - 0x61, 0x62, 0x62, 0x62, 0x63, 0x64, 0x64, 0x64, 0x62, 0x61, 0x62, 0x61, - 0x5f, 0x5d, 0x5b, 0x5a, 0x5b, 0x5d, 0x5f, 0x61, 0x61, 0x61, 0x60, 0x5e, - 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x67, 0x76, 0x80, 0x8a, 0x95, 0x9d, 0xa4, - 0xab, 0xaf, 0xb4, 0xb6, 0xb9, 0xbc, 0xbd, 0xbe, 0xc1, 0xc3, 0xc7, 0xc8, - 0xc7, 0xc6, 0xcb, 0xd1, 0xd2, 0xd1, 0xcf, 0xd0, 0xd2, 0xd3, 0xd5, 0xd5, - 0xd5, 0xd5, 0xd6, 0xd5, 0xd3, 0xcd, 0xc5, 0xc0, 0xbe, 0xc4, 0xcc, 0xd2, - 0xd5, 0xd7, 0xda, 0xd7, 0xd4, 0xd2, 0xd1, 0xd7, 0xde, 0xe3, 0xe3, 0xd8, - 0xbf, 0xb0, 0xb3, 0xb9, 0xc5, 0xc9, 0xbd, 0xb3, 0xad, 0xa1, 0x95, 0x97, - 0x95, 0x94, 0x94, 0x98, 0x9a, 0x96, 0x94, 0x95, 0x95, 0x8f, 0x98, 0xa1, - 0xa4, 0xa3, 0xa5, 0xa8, 0xa9, 0xa8, 0xa7, 0xa6, 0xa8, 0xa7, 0xa6, 0xa5, - 0xa5, 0xa6, 0xa7, 0xa7, 0xa7, 0xa5, 0xa6, 0xa8, 0xa9, 0xa9, 0xaa, 0xae, - 0xb2, 0xb4, 0xb6, 0xb8, 0xb9, 0xb7, 0xb6, 0xb4, 0xb1, 0xae, 0xa9, 0xa4, - 0x9c, 0x95, 0x97, 0x96, 0x93, 0x90, 0x94, 0x9a, 0x9d, 0x9d, 0x9c, 0x98, - 0x93, 0x8d, 0x88, 0x7f, 0x7b, 0x7d, 0x7c, 0x7a, 0x77, 0x72, 0x6b, 0x65, - 0x63, 0x65, 0x6e, 0x7b, 0x82, 0x86, 0x88, 0x8c, 0x91, 0x94, 0x93, 0x91, - 0x87, 0x6b, 0x47, 0x36, 0x32, 0x31, 0x32, 0x37, 0x3c, 0x3e, 0x3f, 0x41, - 0x48, 0x52, 0x59, 0x5f, 0x5d, 0x5d, 0x63, 0x69, 0x70, 0x74, 0x71, 0x6b, - 0x67, 0x63, 0x62, 0x61, 0x60, 0x5e, 0x5d, 0x59, 0x56, 0x55, 0x56, 0x58, - 0x57, 0x53, 0x4f, 0x4c, 0x45, 0x3e, 0x3a, 0x37, 0x37, 0x3d, 0x4c, 0x66, - 0x7e, 0x8c, 0x92, 0x97, 0x9a, 0x98, 0x95, 0x92, 0x8c, 0x87, 0x85, 0x87, - 0x8a, 0x8c, 0x8a, 0x89, 0x89, 0x89, 0x87, 0x84, 0x82, 0x81, 0x80, 0x81, - 0x81, 0x83, 0x83, 0x84, 0x84, 0x84, 0x85, 0x85, 0x84, 0x83, 0x82, 0x84, - 0x86, 0x86, 0x85, 0x84, 0x86, 0x85, 0x85, 0x86, 0x88, 0x89, 0x89, 0x89, - 0x8a, 0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8c, 0x8d, 0x8c, 0x8c, 0x8c, 0x8a, - 0x40, 0x46, 0x49, 0x4b, 0x4c, 0x4e, 0x52, 0x54, 0x56, 0x58, 0x5b, 0x5b, - 0x5a, 0x59, 0x59, 0x58, 0x58, 0x59, 0x5a, 0x59, 0x5b, 0x5d, 0x5d, 0x5e, - 0x5f, 0x5e, 0x60, 0x5f, 0x5f, 0x5f, 0x60, 0x60, 0x62, 0x62, 0x62, 0x61, - 0x63, 0x64, 0x64, 0x64, 0x62, 0x61, 0x61, 0x60, 0x5d, 0x5c, 0x5c, 0x5c, - 0x5d, 0x5d, 0x5f, 0x5f, 0x60, 0x60, 0x5f, 0x5e, 0x5f, 0x5f, 0x5e, 0x5e, - 0x5e, 0x64, 0x72, 0x7d, 0x8a, 0x95, 0x9c, 0xa1, 0xa7, 0xab, 0xb0, 0xb4, - 0xb7, 0xbb, 0xbc, 0xbd, 0xbf, 0xc3, 0xc5, 0xc6, 0xc6, 0xc6, 0xcc, 0xd1, - 0xd2, 0xcf, 0xce, 0xd1, 0xd4, 0xd5, 0xd5, 0xd5, 0xd4, 0xd1, 0xd1, 0xd3, - 0xd3, 0xd0, 0xc9, 0xc5, 0xbf, 0xc1, 0xc8, 0xce, 0xd2, 0xd6, 0xda, 0xdb, - 0xd8, 0xd6, 0xd3, 0xd5, 0xdb, 0xde, 0xdf, 0xde, 0xd9, 0xc7, 0xb8, 0xb3, - 0xb5, 0xc6, 0xd1, 0xd0, 0xce, 0xc8, 0xbf, 0xb8, 0xad, 0xa4, 0x9f, 0x9d, - 0x9f, 0xa0, 0x9e, 0x9d, 0x9c, 0x99, 0x95, 0x96, 0x95, 0x91, 0x8f, 0x91, - 0x95, 0x98, 0x9a, 0x99, 0x99, 0x97, 0x97, 0x96, 0x97, 0x98, 0x9c, 0x9e, - 0x9e, 0x9e, 0xa1, 0xa3, 0xa3, 0xa4, 0xa6, 0xaa, 0xaf, 0xb2, 0xb6, 0xb7, - 0xb8, 0xb6, 0xb5, 0xb3, 0xaf, 0xa9, 0xa4, 0xa0, 0x9a, 0x94, 0x96, 0x98, - 0x98, 0x97, 0x99, 0x9e, 0xa1, 0xa2, 0xa0, 0x9c, 0x98, 0x91, 0x8b, 0x82, - 0x7a, 0x79, 0x78, 0x77, 0x75, 0x6e, 0x67, 0x61, 0x68, 0x71, 0x7f, 0x8e, - 0x93, 0x94, 0x95, 0x95, 0x95, 0x8d, 0x7b, 0x68, 0x4b, 0x34, 0x2f, 0x31, - 0x33, 0x34, 0x35, 0x39, 0x3c, 0x3f, 0x40, 0x42, 0x4b, 0x57, 0x5c, 0x5e, - 0x5c, 0x60, 0x6b, 0x70, 0x75, 0x73, 0x6b, 0x65, 0x61, 0x5d, 0x5d, 0x5e, - 0x5f, 0x5e, 0x5d, 0x5a, 0x58, 0x58, 0x59, 0x59, 0x58, 0x54, 0x50, 0x4d, - 0x4a, 0x47, 0x44, 0x42, 0x43, 0x47, 0x54, 0x6a, 0x80, 0x8e, 0x93, 0x98, - 0x9a, 0x9a, 0x97, 0x94, 0x8f, 0x88, 0x81, 0x80, 0x80, 0x80, 0x7b, 0x75, - 0x74, 0x74, 0x73, 0x70, 0x6f, 0x6e, 0x6f, 0x72, 0x75, 0x77, 0x79, 0x7a, - 0x7a, 0x7b, 0x7c, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x82, 0x82, 0x83, - 0x83, 0x83, 0x83, 0x84, 0x85, 0x84, 0x85, 0x86, 0x87, 0x87, 0x89, 0x89, - 0x89, 0x8a, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8a, 0x41, 0x44, 0x48, 0x4a, - 0x4c, 0x4f, 0x53, 0x54, 0x55, 0x57, 0x59, 0x59, 0x58, 0x57, 0x57, 0x58, - 0x58, 0x59, 0x59, 0x59, 0x5b, 0x5d, 0x5d, 0x5e, 0x5f, 0x5e, 0x5f, 0x60, - 0x5f, 0x5f, 0x60, 0x60, 0x61, 0x62, 0x61, 0x61, 0x63, 0x63, 0x63, 0x63, - 0x62, 0x61, 0x61, 0x60, 0x5d, 0x5b, 0x5c, 0x5c, 0x5d, 0x5d, 0x5f, 0x5f, - 0x5f, 0x5f, 0x60, 0x5e, 0x5f, 0x5e, 0x5e, 0x5e, 0x5d, 0x60, 0x6d, 0x79, - 0x89, 0x95, 0x9c, 0xa0, 0xa5, 0xa9, 0xad, 0xb2, 0xb7, 0xba, 0xbb, 0xbc, - 0xbe, 0xc2, 0xc4, 0xc4, 0xc4, 0xc4, 0xcb, 0xcf, 0xd0, 0xd0, 0xd0, 0xd2, - 0xd5, 0xd6, 0xd6, 0xd7, 0xd3, 0xcf, 0xcd, 0xce, 0xd0, 0xd2, 0xce, 0xca, - 0xc5, 0xc4, 0xc3, 0xc8, 0xcd, 0xd4, 0xda, 0xdd, 0xdc, 0xdb, 0xd7, 0xd4, - 0xd3, 0xd5, 0xd7, 0xda, 0xdd, 0xd6, 0xc8, 0xbd, 0xaf, 0xab, 0xc6, 0xd4, - 0xd6, 0xd4, 0xd2, 0xce, 0xca, 0xc6, 0xc4, 0xc1, 0xbf, 0xbf, 0xbf, 0xbe, - 0xbb, 0xb5, 0xab, 0xac, 0xaa, 0xa2, 0x95, 0x90, 0x94, 0x98, 0x9d, 0x9a, - 0x92, 0x8c, 0x88, 0x84, 0x82, 0x82, 0x85, 0x87, 0x8c, 0x92, 0x97, 0x9b, - 0x9c, 0x9e, 0xa2, 0xa6, 0xaa, 0xad, 0xb3, 0xb5, 0xb6, 0xb5, 0xb4, 0xb2, - 0xab, 0xa4, 0xa0, 0x9e, 0x9b, 0x98, 0x99, 0x9c, 0x9d, 0x9e, 0x9e, 0xa1, - 0xa4, 0xa4, 0xa2, 0x9d, 0x98, 0x91, 0x8c, 0x83, 0x7b, 0x75, 0x72, 0x71, - 0x6e, 0x69, 0x67, 0x6a, 0x79, 0x84, 0x90, 0x99, 0x9a, 0x9a, 0x98, 0x92, - 0x7f, 0x5a, 0x3a, 0x2d, 0x27, 0x28, 0x2f, 0x34, 0x35, 0x36, 0x37, 0x3a, - 0x3e, 0x40, 0x42, 0x47, 0x51, 0x5c, 0x5f, 0x5e, 0x5d, 0x69, 0x76, 0x79, - 0x76, 0x70, 0x67, 0x60, 0x5c, 0x59, 0x5a, 0x5c, 0x5d, 0x5c, 0x5a, 0x59, - 0x58, 0x59, 0x5a, 0x5b, 0x59, 0x54, 0x51, 0x50, 0x50, 0x52, 0x51, 0x51, - 0x52, 0x56, 0x5f, 0x70, 0x83, 0x8f, 0x94, 0x98, 0x9a, 0x9c, 0x9a, 0x98, - 0x93, 0x8d, 0x83, 0x7d, 0x7a, 0x75, 0x6b, 0x62, 0x5f, 0x5f, 0x60, 0x5e, - 0x5e, 0x5e, 0x5f, 0x63, 0x66, 0x68, 0x6b, 0x6b, 0x6c, 0x6e, 0x70, 0x74, - 0x76, 0x78, 0x7b, 0x7e, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x81, - 0x80, 0x81, 0x83, 0x84, 0x85, 0x84, 0x86, 0x86, 0x87, 0x88, 0x8a, 0x8a, - 0x8a, 0x8a, 0x88, 0x87, 0x40, 0x43, 0x47, 0x49, 0x4b, 0x50, 0x53, 0x54, - 0x54, 0x56, 0x58, 0x58, 0x57, 0x57, 0x56, 0x58, 0x59, 0x58, 0x59, 0x58, - 0x5a, 0x5c, 0x5d, 0x5d, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x60, 0x61, - 0x61, 0x61, 0x62, 0x62, 0x63, 0x64, 0x64, 0x62, 0x63, 0x62, 0x61, 0x60, - 0x5d, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d, 0x5f, 0x60, 0x60, 0x60, 0x60, 0x5e, - 0x5f, 0x5e, 0x5e, 0x5e, 0x5c, 0x5f, 0x6b, 0x76, 0x88, 0x95, 0x9b, 0x9f, - 0xa3, 0xa6, 0xac, 0xb2, 0xb7, 0xb9, 0xba, 0xbb, 0xbe, 0xc0, 0xc1, 0xc1, - 0xc1, 0xc3, 0xcb, 0xce, 0xcf, 0xcf, 0xd1, 0xd4, 0xd6, 0xd6, 0xd7, 0xd8, - 0xd4, 0xcf, 0xcc, 0xcb, 0xce, 0xd0, 0xd0, 0xcf, 0xcc, 0xc7, 0xc2, 0xc2, - 0xc6, 0xd0, 0xda, 0xde, 0xde, 0xdd, 0xd9, 0xd4, 0xce, 0xd1, 0xd4, 0xd7, - 0xdb, 0xdd, 0xd3, 0xc8, 0xb6, 0xa5, 0xb3, 0xcc, 0xd5, 0xd2, 0xd0, 0xd0, - 0xd0, 0xd0, 0xcf, 0xcf, 0xcd, 0xcc, 0xcc, 0xcc, 0xcb, 0xc5, 0xb9, 0xc2, - 0xc5, 0xc1, 0xb6, 0xb0, 0xb1, 0xb4, 0xb5, 0xb0, 0xa5, 0x9d, 0x97, 0x8d, - 0x85, 0x7f, 0x7f, 0x80, 0x83, 0x8b, 0x90, 0x92, 0x93, 0x94, 0x99, 0x9e, - 0xa3, 0xa7, 0xac, 0xaf, 0xb0, 0xb2, 0xb2, 0xb0, 0xa8, 0xa0, 0x9d, 0x9c, - 0x9c, 0x9b, 0x9c, 0x9f, 0x9f, 0xa0, 0xa0, 0xa1, 0xa2, 0xa2, 0xa0, 0x9c, - 0x96, 0x8f, 0x89, 0x83, 0x7b, 0x74, 0x6e, 0x6b, 0x6a, 0x69, 0x71, 0x7e, - 0x8c, 0x93, 0x99, 0x9d, 0x9a, 0x93, 0x8a, 0x76, 0x51, 0x30, 0x22, 0x20, - 0x24, 0x2a, 0x31, 0x35, 0x36, 0x37, 0x39, 0x3b, 0x3e, 0x3f, 0x42, 0x49, - 0x56, 0x5e, 0x5f, 0x5c, 0x5f, 0x74, 0x7f, 0x7e, 0x75, 0x6b, 0x64, 0x5d, - 0x59, 0x58, 0x5a, 0x5c, 0x5d, 0x5c, 0x5a, 0x58, 0x59, 0x5a, 0x5c, 0x5c, - 0x5a, 0x55, 0x53, 0x53, 0x56, 0x5b, 0x5c, 0x5c, 0x5d, 0x5f, 0x67, 0x74, - 0x86, 0x91, 0x96, 0x99, 0x9b, 0x9c, 0x9b, 0x9a, 0x96, 0x90, 0x87, 0x80, - 0x7b, 0x73, 0x66, 0x59, 0x55, 0x54, 0x55, 0x55, 0x55, 0x56, 0x57, 0x59, - 0x5b, 0x5e, 0x60, 0x60, 0x61, 0x63, 0x67, 0x6c, 0x6f, 0x73, 0x78, 0x7b, - 0x7c, 0x7d, 0x7d, 0x7e, 0x7f, 0x7f, 0x7e, 0x7e, 0x7e, 0x80, 0x82, 0x82, - 0x82, 0x82, 0x83, 0x84, 0x84, 0x86, 0x87, 0x87, 0x87, 0x87, 0x86, 0x85, - 0x40, 0x43, 0x47, 0x49, 0x4b, 0x4f, 0x53, 0x54, 0x55, 0x56, 0x58, 0x58, - 0x58, 0x57, 0x57, 0x58, 0x58, 0x58, 0x58, 0x58, 0x5a, 0x5b, 0x5c, 0x5d, - 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x5f, 0x61, 0x62, 0x61, 0x61, 0x62, 0x61, - 0x62, 0x64, 0x64, 0x62, 0x63, 0x62, 0x61, 0x60, 0x5e, 0x5c, 0x5b, 0x5c, - 0x5d, 0x5e, 0x60, 0x60, 0x60, 0x60, 0x60, 0x5e, 0x5f, 0x5e, 0x5e, 0x5e, - 0x5c, 0x5f, 0x6a, 0x75, 0x87, 0x94, 0x9b, 0x9f, 0xa2, 0xa5, 0xab, 0xb1, - 0xb6, 0xb9, 0xba, 0xbb, 0xbd, 0xbf, 0xc0, 0xbf, 0xbf, 0xc3, 0xca, 0xcd, - 0xce, 0xce, 0xd1, 0xd3, 0xd5, 0xd7, 0xd7, 0xd7, 0xd3, 0xcf, 0xcc, 0xcb, - 0xcc, 0xcf, 0xd0, 0xd0, 0xcf, 0xc9, 0xc5, 0xc1, 0xc3, 0xcb, 0xd8, 0xdf, - 0xe0, 0xde, 0xda, 0xd6, 0xce, 0xd1, 0xd4, 0xd6, 0xda, 0xdf, 0xd8, 0xce, - 0xbe, 0xaa, 0xaa, 0xc3, 0xcf, 0xd0, 0xcf, 0xcf, 0xd0, 0xd0, 0xd0, 0xd0, - 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xcc, 0xc2, 0xcc, 0xd0, 0xce, 0xc8, 0xc2, - 0xc3, 0xc4, 0xc4, 0xbf, 0xb6, 0xad, 0xa8, 0x9d, 0x93, 0x8c, 0x8a, 0x89, - 0x89, 0x8e, 0x90, 0x90, 0x8f, 0x8f, 0x94, 0x9a, 0x9f, 0xa2, 0xa6, 0xa9, - 0xab, 0xad, 0xae, 0xac, 0xa4, 0x9d, 0x9c, 0x9b, 0x9b, 0x9c, 0x9e, 0x9e, - 0x9f, 0xa0, 0xa1, 0xa0, 0xa1, 0xa0, 0x9e, 0x9a, 0x94, 0x8c, 0x87, 0x81, - 0x78, 0x71, 0x6d, 0x6c, 0x6d, 0x6f, 0x7b, 0x8a, 0x96, 0x9a, 0x9c, 0x97, - 0x8b, 0x7f, 0x74, 0x5e, 0x3b, 0x22, 0x1e, 0x21, 0x27, 0x2b, 0x31, 0x35, - 0x37, 0x39, 0x3b, 0x3d, 0x3f, 0x40, 0x43, 0x4b, 0x57, 0x5e, 0x5e, 0x5b, - 0x63, 0x7d, 0x85, 0x81, 0x74, 0x69, 0x62, 0x5b, 0x58, 0x59, 0x5c, 0x5d, - 0x5e, 0x5d, 0x5b, 0x59, 0x59, 0x5b, 0x5c, 0x5d, 0x5a, 0x58, 0x57, 0x57, - 0x5c, 0x62, 0x63, 0x62, 0x63, 0x65, 0x6b, 0x78, 0x88, 0x92, 0x96, 0x99, - 0x9a, 0x9b, 0x9b, 0x9a, 0x97, 0x91, 0x89, 0x81, 0x7c, 0x74, 0x66, 0x57, - 0x52, 0x52, 0x53, 0x53, 0x53, 0x53, 0x53, 0x55, 0x56, 0x59, 0x5b, 0x5b, - 0x5b, 0x5d, 0x61, 0x67, 0x6a, 0x70, 0x77, 0x7a, 0x7c, 0x7c, 0x7c, 0x7d, - 0x7e, 0x7e, 0x7d, 0x7d, 0x7d, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x82, 0x83, - 0x83, 0x84, 0x85, 0x85, 0x86, 0x86, 0x85, 0x84, 0x41, 0x43, 0x47, 0x48, - 0x4b, 0x50, 0x53, 0x54, 0x55, 0x56, 0x58, 0x59, 0x59, 0x59, 0x59, 0x59, - 0x59, 0x58, 0x58, 0x5a, 0x5a, 0x5a, 0x5a, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, - 0x60, 0x5f, 0x61, 0x62, 0x61, 0x61, 0x61, 0x61, 0x62, 0x63, 0x64, 0x63, - 0x63, 0x61, 0x61, 0x60, 0x5f, 0x5e, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x60, - 0x60, 0x60, 0x60, 0x5f, 0x5d, 0x5d, 0x5e, 0x5e, 0x5c, 0x5f, 0x68, 0x72, - 0x85, 0x93, 0x9c, 0x9f, 0xa1, 0xa3, 0xa8, 0xb0, 0xb6, 0xb9, 0xbb, 0xbb, - 0xbc, 0xbd, 0xbe, 0xbe, 0xbe, 0xc1, 0xc8, 0xc9, 0xcb, 0xcd, 0xd0, 0xd2, - 0xd4, 0xd5, 0xd6, 0xd5, 0xd2, 0xcf, 0xcd, 0xcc, 0xcc, 0xcc, 0xcf, 0xd0, - 0xce, 0xcd, 0xcb, 0xc5, 0xc2, 0xc4, 0xd1, 0xde, 0xdf, 0xde, 0xdc, 0xdb, - 0xd5, 0xd3, 0xd3, 0xd4, 0xd6, 0xdc, 0xd9, 0xd4, 0xc9, 0xb7, 0xa8, 0xb2, - 0xbd, 0xca, 0xd0, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcf, 0xd0, 0xd1, 0xd1, - 0xd1, 0xd0, 0xcf, 0xd1, 0xd2, 0xd2, 0xd1, 0xcf, 0xce, 0xce, 0xce, 0xcb, - 0xc7, 0xc3, 0xbf, 0xb8, 0xb2, 0xac, 0xaa, 0xa7, 0xa3, 0x9f, 0x9a, 0x96, - 0x93, 0x90, 0x94, 0x99, 0x9b, 0x9c, 0x9f, 0xa1, 0xa2, 0xa5, 0xa6, 0xa5, - 0x9f, 0x9a, 0x99, 0x99, 0x99, 0x9b, 0x9b, 0x9c, 0x9c, 0x9e, 0x9e, 0x9c, - 0x9b, 0x99, 0x98, 0x95, 0x8e, 0x88, 0x83, 0x7d, 0x73, 0x6f, 0x71, 0x76, - 0x7a, 0x80, 0x8c, 0x96, 0x9b, 0x9a, 0x92, 0x7d, 0x64, 0x55, 0x4d, 0x43, - 0x30, 0x23, 0x22, 0x25, 0x29, 0x2e, 0x33, 0x37, 0x39, 0x3b, 0x3d, 0x40, - 0x41, 0x42, 0x45, 0x4f, 0x5a, 0x5d, 0x5c, 0x5b, 0x6d, 0x88, 0x8b, 0x83, - 0x72, 0x66, 0x60, 0x5b, 0x5a, 0x5d, 0x60, 0x61, 0x5f, 0x5e, 0x5c, 0x5a, - 0x5a, 0x5c, 0x5d, 0x5e, 0x5d, 0x5c, 0x5d, 0x5f, 0x65, 0x6b, 0x6d, 0x6c, - 0x6c, 0x6d, 0x73, 0x7e, 0x8a, 0x92, 0x95, 0x98, 0x99, 0x9a, 0x9a, 0x99, - 0x96, 0x91, 0x89, 0x83, 0x7e, 0x76, 0x6a, 0x5a, 0x55, 0x53, 0x54, 0x54, - 0x54, 0x55, 0x55, 0x54, 0x55, 0x57, 0x57, 0x57, 0x57, 0x57, 0x59, 0x5e, - 0x64, 0x6d, 0x76, 0x7a, 0x7b, 0x7c, 0x7b, 0x7c, 0x7d, 0x7c, 0x7c, 0x7c, - 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x80, 0x81, 0x82, 0x81, 0x82, 0x83, - 0x84, 0x84, 0x83, 0x83, 0x42, 0x44, 0x47, 0x49, 0x4b, 0x50, 0x53, 0x54, - 0x54, 0x55, 0x58, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x58, 0x58, 0x5a, - 0x59, 0x59, 0x5a, 0x5b, 0x5d, 0x5d, 0x5e, 0x5f, 0x60, 0x5f, 0x61, 0x62, - 0x61, 0x61, 0x62, 0x61, 0x62, 0x64, 0x64, 0x62, 0x63, 0x61, 0x60, 0x60, - 0x5f, 0x5e, 0x5d, 0x5e, 0x5e, 0x5e, 0x60, 0x5f, 0x5f, 0x5f, 0x5f, 0x60, - 0x5d, 0x5e, 0x5f, 0x5f, 0x5f, 0x61, 0x65, 0x6e, 0x82, 0x93, 0x9c, 0x9f, - 0x9f, 0xa1, 0xa7, 0xaf, 0xb6, 0xba, 0xbb, 0xbb, 0xba, 0xbb, 0xbb, 0xbb, - 0xbc, 0xbf, 0xc4, 0xc6, 0xc7, 0xca, 0xce, 0xcf, 0xd1, 0xd3, 0xd4, 0xd4, - 0xd0, 0xcf, 0xce, 0xcc, 0xcb, 0xca, 0xcd, 0xcd, 0xca, 0xcb, 0xcc, 0xca, - 0xc8, 0xc4, 0xc8, 0xd5, 0xde, 0xe1, 0xe0, 0xdf, 0xdb, 0xd6, 0xd2, 0xcd, - 0xcd, 0xd6, 0xd9, 0xd5, 0xc9, 0xb4, 0x9c, 0x8f, 0x91, 0xa3, 0xb5, 0xbe, - 0xc2, 0xc6, 0xc8, 0xc9, 0xcb, 0xcc, 0xcd, 0xcf, 0xd0, 0xd2, 0xd2, 0xd2, - 0xd2, 0xd1, 0xd1, 0xd0, 0xcf, 0xcf, 0xd2, 0xd2, 0xd0, 0xce, 0xce, 0xcc, - 0xca, 0xc8, 0xc6, 0xc3, 0xbd, 0xb6, 0xb0, 0xac, 0xa8, 0xa4, 0xa4, 0xa6, - 0xa5, 0xa3, 0xa0, 0x9f, 0x9d, 0x9c, 0x9c, 0x9b, 0x97, 0x95, 0x95, 0x95, - 0x95, 0x96, 0x96, 0x95, 0x95, 0x96, 0x95, 0x91, 0x8e, 0x8e, 0x8f, 0x8d, - 0x89, 0x84, 0x80, 0x7b, 0x77, 0x7a, 0x83, 0x8a, 0x8f, 0x95, 0x9b, 0x97, - 0x8a, 0x7e, 0x69, 0x53, 0x49, 0x46, 0x44, 0x3d, 0x2c, 0x24, 0x26, 0x29, - 0x2e, 0x31, 0x35, 0x3a, 0x3c, 0x3f, 0x41, 0x43, 0x44, 0x45, 0x48, 0x54, - 0x5e, 0x5e, 0x5c, 0x5f, 0x7d, 0x90, 0x8b, 0x80, 0x6e, 0x65, 0x60, 0x5d, - 0x5e, 0x62, 0x66, 0x65, 0x63, 0x60, 0x5e, 0x5c, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x62, 0x64, 0x67, 0x6e, 0x75, 0x77, 0x75, 0x75, 0x75, 0x79, 0x81, - 0x8d, 0x93, 0x95, 0x97, 0x97, 0x98, 0x98, 0x98, 0x95, 0x90, 0x88, 0x81, - 0x7d, 0x77, 0x70, 0x64, 0x5e, 0x5b, 0x59, 0x58, 0x57, 0x57, 0x57, 0x57, - 0x58, 0x58, 0x57, 0x57, 0x57, 0x55, 0x55, 0x5c, 0x63, 0x6e, 0x79, 0x7e, - 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x7f, 0x7f, 0x81, 0x81, 0x81, 0x80, 0x81, 0x81, 0x82, 0x83, 0x84, 0x85, - 0x44, 0x45, 0x47, 0x49, 0x4c, 0x51, 0x51, 0x53, 0x53, 0x55, 0x58, 0x58, - 0x58, 0x58, 0x59, 0x59, 0x59, 0x58, 0x58, 0x59, 0x59, 0x59, 0x5b, 0x5c, - 0x5d, 0x5c, 0x5f, 0x61, 0x60, 0x5f, 0x5f, 0x61, 0x61, 0x62, 0x62, 0x62, - 0x62, 0x63, 0x64, 0x62, 0x63, 0x61, 0x60, 0x60, 0x5e, 0x5d, 0x5e, 0x5e, - 0x5e, 0x5e, 0x5f, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x60, 0x61, 0x61, 0x5f, - 0x60, 0x62, 0x65, 0x6d, 0x80, 0x91, 0x9a, 0x9f, 0x9f, 0xa0, 0xa5, 0xad, - 0xb4, 0xb9, 0xbb, 0xba, 0xb8, 0xb8, 0xba, 0xb9, 0xb8, 0xbc, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc9, 0xcb, 0xcd, 0xcf, 0xd0, 0xd1, 0xce, 0xcd, 0xcd, 0xcc, - 0xca, 0xc8, 0xcb, 0xcb, 0xc8, 0xc7, 0xc9, 0xcb, 0xcb, 0xc9, 0xcb, 0xcf, - 0xd5, 0xda, 0xde, 0xda, 0xd2, 0xcb, 0xc9, 0xcb, 0xce, 0xca, 0xce, 0xc9, - 0xb2, 0x8e, 0x74, 0x67, 0x60, 0x5b, 0x65, 0x73, 0x7d, 0x89, 0x90, 0x96, - 0x99, 0x9e, 0xa5, 0xab, 0xb1, 0xb8, 0xba, 0xbb, 0xbc, 0xbe, 0xc1, 0xc4, - 0xc5, 0xc7, 0xcb, 0xcf, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2, 0xd0, 0xd0, 0xcf, - 0xcb, 0xc8, 0xc7, 0xc5, 0xc3, 0xc0, 0xbf, 0xbd, 0xbc, 0xb9, 0xb3, 0xae, - 0xa7, 0xa0, 0x9c, 0x98, 0x94, 0x93, 0x92, 0x91, 0x91, 0x90, 0x8d, 0x8c, - 0x8c, 0x8d, 0x8d, 0x8b, 0x8b, 0x8c, 0x8f, 0x8f, 0x8d, 0x8b, 0x8a, 0x8a, - 0x89, 0x90, 0x98, 0x9c, 0x9d, 0x9d, 0x90, 0x70, 0x52, 0x46, 0x44, 0x4d, - 0x50, 0x4c, 0x47, 0x3c, 0x2a, 0x25, 0x2b, 0x2e, 0x31, 0x34, 0x38, 0x3c, - 0x3e, 0x41, 0x45, 0x45, 0x45, 0x47, 0x4c, 0x58, 0x5d, 0x5b, 0x5c, 0x66, - 0x86, 0x90, 0x82, 0x77, 0x6b, 0x66, 0x62, 0x61, 0x63, 0x67, 0x6a, 0x68, - 0x65, 0x63, 0x60, 0x5d, 0x5c, 0x5f, 0x60, 0x62, 0x64, 0x67, 0x6b, 0x70, - 0x77, 0x7c, 0x7e, 0x7d, 0x7a, 0x79, 0x7a, 0x81, 0x8b, 0x92, 0x94, 0x94, - 0x94, 0x94, 0x95, 0x95, 0x93, 0x8d, 0x86, 0x80, 0x7c, 0x78, 0x76, 0x6f, - 0x69, 0x67, 0x64, 0x5f, 0x5c, 0x5a, 0x5a, 0x5b, 0x5a, 0x5a, 0x59, 0x58, - 0x57, 0x56, 0x59, 0x61, 0x68, 0x73, 0x7f, 0x86, 0x87, 0x87, 0x87, 0x88, - 0x87, 0x87, 0x88, 0x89, 0x89, 0x88, 0x87, 0x87, 0x87, 0x88, 0x87, 0x86, - 0x86, 0x86, 0x86, 0x86, 0x87, 0x88, 0x8b, 0x8d, 0x46, 0x46, 0x47, 0x49, - 0x4c, 0x50, 0x51, 0x52, 0x53, 0x56, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, - 0x59, 0x58, 0x58, 0x59, 0x59, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x61, - 0x61, 0x5f, 0x60, 0x62, 0x63, 0x63, 0x62, 0x62, 0x62, 0x64, 0x64, 0x63, - 0x63, 0x61, 0x61, 0x61, 0x5f, 0x5d, 0x5d, 0x5e, 0x5f, 0x60, 0x60, 0x5f, - 0x5f, 0x5f, 0x5f, 0x60, 0x61, 0x63, 0x62, 0x61, 0x62, 0x64, 0x67, 0x6e, - 0x7e, 0x90, 0x98, 0x9e, 0x9e, 0x9f, 0xa3, 0xab, 0xb4, 0xb9, 0xba, 0xb9, - 0xb8, 0xb8, 0xb9, 0xb9, 0xb7, 0xb9, 0xbe, 0xc0, 0xc0, 0xbe, 0xc2, 0xc7, - 0xc9, 0xcb, 0xcd, 0xce, 0xcc, 0xcc, 0xcb, 0xc9, 0xc8, 0xc6, 0xc8, 0xca, - 0xcd, 0xd2, 0xd2, 0xcb, 0xc6, 0xc4, 0xcc, 0xd0, 0xd1, 0xd0, 0xce, 0xc8, - 0xc5, 0xc6, 0xcb, 0xd5, 0xd3, 0xb8, 0xb3, 0xb0, 0x9c, 0x74, 0x5b, 0x4f, - 0x4a, 0x4d, 0x5e, 0x59, 0x46, 0x42, 0x42, 0x42, 0x41, 0x47, 0x51, 0x58, - 0x63, 0x71, 0x79, 0x7e, 0x82, 0x88, 0x95, 0xa1, 0xaa, 0xaf, 0xb7, 0xc2, - 0xcb, 0xd0, 0xd1, 0xd3, 0xd2, 0xd0, 0xd1, 0xd2, 0xd1, 0xd0, 0xd1, 0xd0, - 0xcf, 0xcd, 0xcd, 0xcc, 0xca, 0xc8, 0xc4, 0xbf, 0xb7, 0xae, 0xa9, 0xa1, - 0x9c, 0x98, 0x93, 0x90, 0x8f, 0x8c, 0x8b, 0x8b, 0x8c, 0x90, 0x93, 0x95, - 0x96, 0x97, 0x99, 0x99, 0x97, 0x96, 0x96, 0x97, 0x98, 0x9c, 0x9f, 0x9d, - 0x98, 0x8c, 0x6e, 0x46, 0x2f, 0x2b, 0x38, 0x50, 0x58, 0x50, 0x48, 0x39, - 0x28, 0x28, 0x2e, 0x32, 0x34, 0x36, 0x3a, 0x3e, 0x40, 0x44, 0x47, 0x46, - 0x46, 0x48, 0x4f, 0x59, 0x5b, 0x58, 0x5b, 0x6a, 0x87, 0x8c, 0x7a, 0x70, - 0x6a, 0x68, 0x65, 0x66, 0x68, 0x6b, 0x6c, 0x68, 0x65, 0x63, 0x60, 0x5e, - 0x5d, 0x60, 0x61, 0x63, 0x67, 0x6b, 0x71, 0x75, 0x7a, 0x7f, 0x82, 0x81, - 0x7d, 0x7b, 0x7a, 0x7d, 0x86, 0x8e, 0x92, 0x92, 0x92, 0x91, 0x92, 0x92, - 0x90, 0x8a, 0x85, 0x80, 0x7d, 0x7b, 0x7a, 0x77, 0x74, 0x72, 0x70, 0x6a, - 0x63, 0x5f, 0x5d, 0x5c, 0x5c, 0x5c, 0x5a, 0x59, 0x57, 0x58, 0x5e, 0x68, - 0x6e, 0x7a, 0x86, 0x8d, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8f, 0x90, 0x8f, - 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x90, 0x8f, 0x8e, 0x8e, 0x8e, 0x8d, 0x8d, - 0x8e, 0x8f, 0x90, 0x92, 0x48, 0x46, 0x48, 0x49, 0x4c, 0x4f, 0x51, 0x52, - 0x54, 0x57, 0x59, 0x58, 0x58, 0x58, 0x59, 0x58, 0x59, 0x59, 0x59, 0x59, - 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5f, 0x60, 0x60, 0x60, 0x61, 0x63, - 0x63, 0x63, 0x62, 0x61, 0x62, 0x64, 0x64, 0x63, 0x63, 0x62, 0x61, 0x61, - 0x60, 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x60, 0x5f, 0x60, 0x61, - 0x62, 0x63, 0x63, 0x63, 0x64, 0x67, 0x6a, 0x6f, 0x7d, 0x8f, 0x98, 0x9d, - 0x9e, 0x9f, 0xa2, 0xaa, 0xb2, 0xb8, 0xb9, 0xb8, 0xb7, 0xb8, 0xba, 0xba, - 0xb6, 0xb7, 0xbb, 0xbe, 0xbd, 0xba, 0xbe, 0xc5, 0xc7, 0xc9, 0xcc, 0xce, - 0xcc, 0xcc, 0xcc, 0xca, 0xc7, 0xc5, 0xc8, 0xcb, 0xd1, 0xd8, 0xcf, 0xbf, - 0xb9, 0xbd, 0xca, 0xd0, 0xcf, 0xcd, 0xc8, 0xc1, 0xc1, 0xc6, 0xcd, 0xd9, - 0xd3, 0xab, 0xa7, 0xa6, 0x9a, 0x81, 0x70, 0x64, 0x61, 0x67, 0x73, 0x65, - 0x4a, 0x3c, 0x35, 0x2a, 0x20, 0x24, 0x2d, 0x33, 0x3b, 0x48, 0x50, 0x55, - 0x59, 0x5f, 0x6c, 0x78, 0x82, 0x88, 0x91, 0xa2, 0xb4, 0xbf, 0xc4, 0xc9, - 0xcd, 0xcc, 0xcf, 0xd1, 0xd2, 0xd2, 0xd3, 0xd2, 0xd2, 0xd1, 0xd1, 0xd0, - 0xd0, 0xcf, 0xcc, 0xc8, 0xc0, 0xb8, 0xb3, 0xab, 0xa6, 0xa1, 0x9a, 0x96, - 0x93, 0x8f, 0x8f, 0x91, 0x93, 0x97, 0x9b, 0x9d, 0x9e, 0x9f, 0xa0, 0x9e, - 0x9c, 0x9b, 0x9b, 0x9c, 0x9c, 0x9c, 0x97, 0x8f, 0x87, 0x77, 0x59, 0x37, - 0x27, 0x27, 0x36, 0x51, 0x59, 0x50, 0x46, 0x36, 0x27, 0x2b, 0x30, 0x33, - 0x36, 0x38, 0x3c, 0x40, 0x42, 0x45, 0x48, 0x47, 0x48, 0x4a, 0x52, 0x5a, - 0x59, 0x56, 0x5a, 0x6c, 0x86, 0x86, 0x74, 0x6c, 0x6a, 0x69, 0x67, 0x69, - 0x6b, 0x6d, 0x6c, 0x67, 0x64, 0x61, 0x60, 0x5d, 0x5d, 0x60, 0x61, 0x64, - 0x69, 0x6e, 0x74, 0x78, 0x7c, 0x81, 0x82, 0x82, 0x7d, 0x7b, 0x79, 0x7b, - 0x81, 0x8a, 0x8e, 0x91, 0x91, 0x8f, 0x90, 0x8f, 0x8e, 0x89, 0x84, 0x80, - 0x7e, 0x7c, 0x7c, 0x7b, 0x7a, 0x7a, 0x79, 0x73, 0x6a, 0x65, 0x62, 0x5f, - 0x5f, 0x5e, 0x5d, 0x5b, 0x5a, 0x5b, 0x62, 0x6c, 0x73, 0x7d, 0x8a, 0x92, - 0x93, 0x94, 0x93, 0x93, 0x94, 0x95, 0x95, 0x95, 0x94, 0x95, 0x95, 0x95, - 0x95, 0x96, 0x95, 0x94, 0x94, 0x93, 0x93, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x49, 0x47, 0x47, 0x48, 0x4a, 0x4f, 0x51, 0x54, 0x56, 0x58, 0x5a, 0x5a, - 0x59, 0x58, 0x59, 0x58, 0x59, 0x59, 0x59, 0x59, 0x57, 0x58, 0x59, 0x5a, - 0x5b, 0x5d, 0x5f, 0x60, 0x60, 0x61, 0x62, 0x63, 0x63, 0x62, 0x61, 0x61, - 0x62, 0x64, 0x64, 0x64, 0x64, 0x62, 0x62, 0x61, 0x60, 0x5e, 0x5e, 0x60, - 0x60, 0x5f, 0x60, 0x61, 0x62, 0x62, 0x61, 0x62, 0x64, 0x65, 0x65, 0x66, - 0x69, 0x6c, 0x6f, 0x72, 0x7c, 0x8d, 0x97, 0x9d, 0x9e, 0x9f, 0xa1, 0xa8, - 0xb1, 0xb7, 0xb8, 0xb6, 0xb5, 0xb6, 0xb9, 0xb8, 0xb4, 0xb4, 0xb8, 0xba, - 0xb8, 0xb4, 0xbb, 0xc4, 0xc7, 0xc9, 0xcd, 0xd0, 0xd1, 0xd1, 0xd0, 0xcd, - 0xc9, 0xc6, 0xc9, 0xce, 0xd6, 0xd7, 0xbe, 0xa7, 0xa5, 0xb5, 0xc7, 0xca, - 0xcd, 0xcd, 0xc8, 0xc2, 0xc6, 0xca, 0xcf, 0xd5, 0xc7, 0x9b, 0xa0, 0xa5, - 0xa4, 0xaf, 0xb1, 0xa9, 0xa5, 0xa5, 0x9b, 0x8b, 0x7c, 0x6f, 0x62, 0x4a, - 0x33, 0x29, 0x28, 0x28, 0x29, 0x2d, 0x2f, 0x31, 0x32, 0x31, 0x34, 0x38, - 0x3e, 0x42, 0x48, 0x5c, 0x77, 0x8c, 0x98, 0xa5, 0xb2, 0xb9, 0xc1, 0xc6, - 0xcb, 0xce, 0xcf, 0xcf, 0xcf, 0xd0, 0xd1, 0xd1, 0xd0, 0xcf, 0xce, 0xcd, - 0xc7, 0xc3, 0xbf, 0xba, 0xb6, 0xb1, 0xaa, 0xa5, 0xa0, 0x9d, 0x9e, 0xa0, - 0xa3, 0xa5, 0xa7, 0xa6, 0xa6, 0xa6, 0xa5, 0xa1, 0x9e, 0x9c, 0x9b, 0x9a, - 0x95, 0x8a, 0x77, 0x69, 0x61, 0x57, 0x48, 0x3b, 0x32, 0x30, 0x36, 0x4d, - 0x57, 0x4e, 0x43, 0x32, 0x28, 0x2e, 0x34, 0x35, 0x37, 0x3b, 0x3e, 0x42, - 0x44, 0x47, 0x49, 0x49, 0x4b, 0x4f, 0x56, 0x5b, 0x57, 0x53, 0x58, 0x6c, - 0x7f, 0x7b, 0x6d, 0x69, 0x6c, 0x6b, 0x6a, 0x6c, 0x6e, 0x6e, 0x6a, 0x64, - 0x61, 0x60, 0x5e, 0x5c, 0x5d, 0x5f, 0x61, 0x65, 0x6b, 0x72, 0x79, 0x7c, - 0x7f, 0x82, 0x82, 0x81, 0x7d, 0x7a, 0x76, 0x75, 0x7a, 0x83, 0x88, 0x8d, - 0x8e, 0x8d, 0x8c, 0x8d, 0x8c, 0x88, 0x82, 0x80, 0x7f, 0x7f, 0x81, 0x82, - 0x83, 0x84, 0x84, 0x7f, 0x77, 0x71, 0x6d, 0x68, 0x65, 0x63, 0x62, 0x62, - 0x60, 0x62, 0x69, 0x72, 0x78, 0x82, 0x8d, 0x96, 0x99, 0x9a, 0x9a, 0x9a, - 0x9c, 0x9d, 0x9c, 0x9c, 0x9b, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, - 0x9c, 0x9c, 0x9c, 0x9b, 0x9a, 0x9b, 0x9c, 0x9d, 0x4d, 0x48, 0x48, 0x48, - 0x4b, 0x4f, 0x52, 0x55, 0x57, 0x58, 0x5a, 0x5a, 0x59, 0x58, 0x58, 0x58, - 0x59, 0x59, 0x58, 0x57, 0x57, 0x58, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5f, - 0x5f, 0x61, 0x62, 0x63, 0x62, 0x62, 0x61, 0x63, 0x63, 0x63, 0x63, 0x62, - 0x63, 0x63, 0x62, 0x61, 0x5f, 0x5f, 0x61, 0x62, 0x62, 0x61, 0x62, 0x64, - 0x64, 0x64, 0x64, 0x65, 0x68, 0x69, 0x6a, 0x6b, 0x6e, 0x71, 0x73, 0x76, - 0x7d, 0x8b, 0x97, 0x9d, 0x9e, 0x9f, 0xa1, 0xa6, 0xae, 0xb4, 0xb6, 0xb5, - 0xb5, 0xb6, 0xb8, 0xb7, 0xb3, 0xb3, 0xb6, 0xb5, 0xb4, 0xb3, 0xbf, 0xc7, - 0xcb, 0xcd, 0xd1, 0xd4, 0xd5, 0xd6, 0xd7, 0xd5, 0xd0, 0xca, 0xce, 0xd3, - 0xd6, 0xc9, 0xb0, 0xb2, 0xbb, 0xc8, 0xcb, 0xc8, 0xc9, 0xc8, 0xc5, 0xc4, - 0xc7, 0xc5, 0xc5, 0xc5, 0xaf, 0x8b, 0x9b, 0xa3, 0xa1, 0xa7, 0xb6, 0xb8, - 0xb7, 0xb6, 0xae, 0x9e, 0x98, 0x91, 0x8a, 0x81, 0x72, 0x50, 0x35, 0x2d, - 0x2e, 0x31, 0x30, 0x2f, 0x2c, 0x26, 0x26, 0x2c, 0x2d, 0x2d, 0x2c, 0x31, - 0x3c, 0x44, 0x4b, 0x57, 0x6b, 0x7e, 0x8d, 0x97, 0xa2, 0xaf, 0xb5, 0xb7, - 0xb9, 0xbc, 0xc2, 0xc4, 0xc5, 0xc6, 0xc6, 0xc8, 0xc6, 0xc5, 0xc5, 0xc3, - 0xc0, 0xbc, 0xb7, 0xb3, 0xae, 0xab, 0xa7, 0xa8, 0xa8, 0xa7, 0xa7, 0xa5, - 0xa3, 0xa2, 0xa1, 0x9c, 0x99, 0x96, 0x93, 0x88, 0x72, 0x5d, 0x4d, 0x48, - 0x4a, 0x4f, 0x4d, 0x45, 0x40, 0x3c, 0x38, 0x44, 0x4f, 0x46, 0x3b, 0x2c, - 0x2a, 0x32, 0x36, 0x37, 0x38, 0x3d, 0x42, 0x45, 0x47, 0x49, 0x49, 0x4c, - 0x51, 0x54, 0x59, 0x5b, 0x54, 0x52, 0x58, 0x69, 0x76, 0x6e, 0x69, 0x69, - 0x6d, 0x6e, 0x6e, 0x6f, 0x6f, 0x6d, 0x67, 0x61, 0x5e, 0x5e, 0x5d, 0x5d, - 0x5e, 0x5f, 0x61, 0x66, 0x6d, 0x75, 0x7d, 0x80, 0x82, 0x84, 0x83, 0x80, - 0x7c, 0x79, 0x73, 0x6e, 0x70, 0x77, 0x7c, 0x81, 0x86, 0x89, 0x8c, 0x8d, - 0x8b, 0x87, 0x82, 0x81, 0x82, 0x82, 0x86, 0x8b, 0x8e, 0x8f, 0x8f, 0x8c, - 0x85, 0x80, 0x7d, 0x78, 0x73, 0x70, 0x6f, 0x6e, 0x6d, 0x6e, 0x74, 0x7b, - 0x81, 0x89, 0x92, 0x9a, 0x9e, 0x9f, 0xa0, 0xa3, 0xa4, 0xa3, 0xa4, 0xa5, - 0xa5, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa3, - 0xa3, 0xa3, 0xa3, 0xa3, 0x4f, 0x49, 0x48, 0x49, 0x4b, 0x4f, 0x52, 0x55, - 0x57, 0x58, 0x5a, 0x5a, 0x59, 0x58, 0x58, 0x58, 0x59, 0x59, 0x57, 0x57, - 0x57, 0x58, 0x58, 0x59, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5f, 0x61, 0x62, - 0x62, 0x62, 0x62, 0x62, 0x63, 0x63, 0x62, 0x62, 0x63, 0x63, 0x62, 0x61, - 0x5f, 0x5f, 0x61, 0x63, 0x62, 0x63, 0x65, 0x66, 0x66, 0x67, 0x68, 0x69, - 0x6c, 0x6e, 0x6f, 0x70, 0x73, 0x76, 0x79, 0x7b, 0x7f, 0x8a, 0x95, 0x9c, - 0x9e, 0x9f, 0xa0, 0xa4, 0xaa, 0xb0, 0xb3, 0xb5, 0xb6, 0xb7, 0xb7, 0xb6, - 0xb5, 0xb2, 0xb4, 0xb4, 0xb5, 0xbb, 0xc8, 0xcc, 0xce, 0xd0, 0xd5, 0xd7, - 0xd6, 0xd8, 0xd8, 0xd8, 0xd6, 0xce, 0xd1, 0xd3, 0xd2, 0xca, 0xc4, 0xc8, - 0xcb, 0xcd, 0xcb, 0xc6, 0xc4, 0xc2, 0xc2, 0xc0, 0xb6, 0xa4, 0x9e, 0x9a, - 0x83, 0x83, 0xa3, 0xac, 0xa2, 0x9f, 0xa8, 0xaf, 0xae, 0xaa, 0xac, 0xab, - 0xaa, 0x9d, 0x98, 0x99, 0x94, 0x7d, 0x64, 0x5b, 0x5b, 0x60, 0x59, 0x4c, - 0x40, 0x2f, 0x2a, 0x34, 0x35, 0x34, 0x30, 0x32, 0x37, 0x3b, 0x3d, 0x42, - 0x47, 0x4c, 0x50, 0x53, 0x5a, 0x68, 0x73, 0x79, 0x7d, 0x83, 0x8d, 0x94, - 0x9a, 0x9e, 0xa3, 0xa9, 0xaf, 0xb5, 0xb8, 0xba, 0xba, 0xb7, 0xb3, 0xaf, - 0xaa, 0xa6, 0xa1, 0xa2, 0xa1, 0xa0, 0x9e, 0x9d, 0x9c, 0x9a, 0x97, 0x91, - 0x86, 0x7a, 0x6e, 0x58, 0x3f, 0x3e, 0x42, 0x45, 0x49, 0x50, 0x52, 0x4d, - 0x4a, 0x46, 0x3e, 0x3c, 0x43, 0x3c, 0x32, 0x28, 0x2c, 0x34, 0x37, 0x38, - 0x39, 0x3f, 0x44, 0x48, 0x4a, 0x4b, 0x4b, 0x50, 0x57, 0x5a, 0x5d, 0x59, - 0x51, 0x52, 0x58, 0x66, 0x6e, 0x68, 0x68, 0x6a, 0x6d, 0x6f, 0x70, 0x70, - 0x6e, 0x6a, 0x64, 0x5f, 0x5c, 0x5b, 0x5d, 0x5f, 0x5f, 0x5e, 0x61, 0x67, - 0x6e, 0x79, 0x7f, 0x81, 0x82, 0x84, 0x83, 0x80, 0x7c, 0x77, 0x70, 0x68, - 0x66, 0x69, 0x6e, 0x74, 0x79, 0x80, 0x86, 0x89, 0x8b, 0x8a, 0x86, 0x84, - 0x84, 0x85, 0x8b, 0x91, 0x96, 0x97, 0x98, 0x95, 0x90, 0x8c, 0x89, 0x86, - 0x82, 0x80, 0x7f, 0x7e, 0x7d, 0x7c, 0x80, 0x86, 0x8a, 0x91, 0x99, 0xa0, - 0xa3, 0xa4, 0xa6, 0xa8, 0xa9, 0xaa, 0xaa, 0xa9, 0xaa, 0xa9, 0xaa, 0xab, - 0xab, 0xaa, 0xaa, 0xab, 0xac, 0xab, 0xa9, 0xaa, 0xa9, 0xa9, 0xa8, 0xa9, - 0x52, 0x4a, 0x48, 0x4a, 0x4d, 0x50, 0x52, 0x56, 0x58, 0x58, 0x59, 0x5a, - 0x5a, 0x59, 0x59, 0x58, 0x58, 0x58, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, - 0x5b, 0x5c, 0x5c, 0x5c, 0x5d, 0x5e, 0x60, 0x61, 0x61, 0x61, 0x61, 0x63, - 0x62, 0x62, 0x61, 0x60, 0x62, 0x62, 0x61, 0x61, 0x61, 0x61, 0x62, 0x63, - 0x64, 0x65, 0x66, 0x67, 0x69, 0x6a, 0x6b, 0x6c, 0x6f, 0x70, 0x71, 0x74, - 0x77, 0x7a, 0x7d, 0x7e, 0x80, 0x89, 0x93, 0x9c, 0x9f, 0xa1, 0xa2, 0xa3, - 0xa8, 0xae, 0xb2, 0xb5, 0xb6, 0xb6, 0xb6, 0xb6, 0xb5, 0xb3, 0xb3, 0xb5, - 0xb8, 0xc1, 0xcd, 0xcd, 0xce, 0xd0, 0xd5, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, - 0xd7, 0xd0, 0xce, 0xcc, 0xc7, 0xc5, 0xc7, 0xca, 0xcb, 0xcc, 0xcd, 0xc4, - 0xbb, 0xb8, 0xb3, 0x9f, 0x88, 0x79, 0x74, 0x72, 0x67, 0x7b, 0x9a, 0xa1, - 0x97, 0x99, 0x9c, 0xa8, 0xad, 0xae, 0xb3, 0xb5, 0xb7, 0xb5, 0xb4, 0xb5, - 0xaf, 0x9e, 0x8a, 0x7e, 0x73, 0x77, 0x83, 0x7d, 0x6f, 0x4f, 0x35, 0x39, - 0x3b, 0x39, 0x36, 0x37, 0x3c, 0x40, 0x42, 0x45, 0x48, 0x48, 0x48, 0x46, - 0x46, 0x49, 0x4f, 0x51, 0x53, 0x56, 0x5b, 0x60, 0x63, 0x66, 0x6c, 0x77, - 0x88, 0x95, 0x9d, 0xa4, 0xa9, 0xa9, 0xa6, 0xa4, 0xa1, 0x9d, 0x9b, 0x9c, - 0x9d, 0x9e, 0x9c, 0x9a, 0x98, 0x95, 0x8b, 0x79, 0x60, 0x4c, 0x40, 0x31, - 0x29, 0x36, 0x42, 0x46, 0x48, 0x4c, 0x4e, 0x4e, 0x4f, 0x4d, 0x45, 0x3d, - 0x3b, 0x33, 0x2c, 0x26, 0x2d, 0x34, 0x36, 0x37, 0x3a, 0x41, 0x47, 0x4a, - 0x4c, 0x4c, 0x4d, 0x53, 0x5b, 0x5d, 0x5d, 0x57, 0x50, 0x52, 0x59, 0x66, - 0x6a, 0x68, 0x69, 0x6a, 0x6c, 0x6f, 0x70, 0x6f, 0x6d, 0x68, 0x61, 0x5d, - 0x5c, 0x5c, 0x5d, 0x60, 0x5f, 0x5f, 0x61, 0x67, 0x6f, 0x7b, 0x80, 0x82, - 0x83, 0x83, 0x82, 0x80, 0x7c, 0x78, 0x6f, 0x64, 0x5e, 0x60, 0x64, 0x6a, - 0x71, 0x79, 0x80, 0x84, 0x8a, 0x8c, 0x8a, 0x88, 0x87, 0x88, 0x8e, 0x95, - 0x99, 0x9b, 0x9d, 0x9b, 0x96, 0x93, 0x92, 0x8f, 0x8c, 0x8b, 0x8a, 0x89, - 0x88, 0x86, 0x89, 0x8d, 0x90, 0x95, 0x9d, 0xa3, 0xa5, 0xa7, 0xa8, 0xa9, - 0xab, 0xac, 0xac, 0xad, 0xae, 0xac, 0xac, 0xad, 0xae, 0xae, 0xae, 0xae, - 0xae, 0xae, 0xae, 0xad, 0xab, 0xaa, 0xaa, 0xac, 0x54, 0x4b, 0x49, 0x4a, - 0x4d, 0x4f, 0x52, 0x56, 0x57, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5a, 0x58, - 0x58, 0x57, 0x58, 0x58, 0x57, 0x57, 0x57, 0x58, 0x5a, 0x5c, 0x5b, 0x5c, - 0x5d, 0x5e, 0x5f, 0x61, 0x61, 0x61, 0x61, 0x63, 0x62, 0x61, 0x61, 0x60, - 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x63, 0x63, 0x64, 0x66, 0x66, 0x68, - 0x6b, 0x6d, 0x6d, 0x6e, 0x70, 0x72, 0x74, 0x77, 0x7a, 0x7d, 0x7f, 0x80, - 0x81, 0x88, 0x92, 0x9c, 0xa0, 0xa1, 0xa2, 0xa3, 0xa7, 0xac, 0xb0, 0xb4, - 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4, 0xb4, 0xb7, 0xbb, 0xc5, 0xd0, 0xce, - 0xce, 0xd0, 0xd6, 0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xcf, 0xca, 0xc7, - 0xc3, 0xc5, 0xc9, 0xca, 0xc9, 0xc5, 0xc1, 0xb4, 0xa8, 0xa4, 0xa0, 0x89, - 0x72, 0x68, 0x65, 0x65, 0x63, 0x7b, 0x92, 0x96, 0x8f, 0x94, 0x95, 0xa0, - 0xa7, 0xb0, 0xb9, 0xbc, 0xbf, 0xc1, 0xc2, 0xc0, 0xb8, 0xa8, 0x97, 0x8a, - 0x7a, 0x7a, 0x8d, 0x8e, 0x7f, 0x5c, 0x3b, 0x3b, 0x3e, 0x3c, 0x39, 0x3a, - 0x3e, 0x42, 0x45, 0x48, 0x4b, 0x4c, 0x4a, 0x48, 0x45, 0x44, 0x46, 0x48, - 0x48, 0x4a, 0x4b, 0x4d, 0x4e, 0x50, 0x54, 0x5f, 0x6f, 0x7b, 0x81, 0x8a, - 0x92, 0x98, 0x98, 0x98, 0x98, 0x96, 0x96, 0x97, 0x98, 0x99, 0x95, 0x8f, - 0x8b, 0x85, 0x77, 0x5e, 0x45, 0x35, 0x2d, 0x25, 0x26, 0x35, 0x42, 0x45, - 0x46, 0x48, 0x4b, 0x4d, 0x51, 0x50, 0x4a, 0x40, 0x39, 0x2e, 0x28, 0x26, - 0x30, 0x35, 0x37, 0x38, 0x3b, 0x42, 0x48, 0x4b, 0x4c, 0x4b, 0x4e, 0x55, - 0x5c, 0x5e, 0x5c, 0x56, 0x50, 0x52, 0x59, 0x65, 0x69, 0x69, 0x6a, 0x6b, - 0x6c, 0x6e, 0x6f, 0x6e, 0x6c, 0x67, 0x60, 0x5c, 0x5c, 0x5d, 0x5e, 0x60, - 0x5f, 0x5f, 0x61, 0x67, 0x70, 0x7c, 0x81, 0x83, 0x83, 0x83, 0x83, 0x80, - 0x7d, 0x78, 0x70, 0x63, 0x5a, 0x5b, 0x5d, 0x63, 0x6b, 0x73, 0x7a, 0x7f, - 0x85, 0x8a, 0x8a, 0x89, 0x89, 0x8a, 0x8e, 0x96, 0x9a, 0x9d, 0x9f, 0x9e, - 0x9a, 0x98, 0x96, 0x93, 0x91, 0x90, 0x90, 0x8f, 0x8e, 0x8c, 0x8d, 0x90, - 0x93, 0x97, 0x9e, 0xa4, 0xa7, 0xa9, 0xa9, 0xaa, 0xac, 0xad, 0xad, 0xaf, - 0xb0, 0xaf, 0xae, 0xae, 0xaf, 0xaf, 0xb0, 0xaf, 0xaf, 0xaf, 0xb0, 0xae, - 0xad, 0xac, 0xac, 0xad, 0x54, 0x4c, 0x48, 0x49, 0x4c, 0x4f, 0x53, 0x56, - 0x57, 0x58, 0x5a, 0x59, 0x5a, 0x5a, 0x59, 0x58, 0x58, 0x57, 0x57, 0x58, - 0x57, 0x57, 0x57, 0x57, 0x59, 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5f, 0x60, - 0x61, 0x61, 0x61, 0x62, 0x61, 0x62, 0x61, 0x61, 0x62, 0x61, 0x60, 0x60, - 0x60, 0x62, 0x64, 0x65, 0x66, 0x68, 0x68, 0x6a, 0x6d, 0x6f, 0x70, 0x71, - 0x75, 0x77, 0x79, 0x7c, 0x7f, 0x81, 0x83, 0x83, 0x84, 0x87, 0x90, 0x9a, - 0x9f, 0xa0, 0xa2, 0xa2, 0xa5, 0xab, 0xaf, 0xb3, 0xb4, 0xb3, 0xb2, 0xb3, - 0xb5, 0xb4, 0xb5, 0xba, 0xc0, 0xcb, 0xd4, 0xd1, 0xd0, 0xd2, 0xd7, 0xd9, - 0xd9, 0xd7, 0xd5, 0xd5, 0xd4, 0xcb, 0xc6, 0xc4, 0xc3, 0xc5, 0xc7, 0xc4, - 0xbd, 0xad, 0x9c, 0x8d, 0x83, 0x80, 0x81, 0x79, 0x6d, 0x68, 0x67, 0x69, - 0x72, 0x82, 0x89, 0x8a, 0x88, 0x8e, 0x8c, 0x8f, 0x96, 0xa7, 0xbb, 0xc3, - 0xc5, 0xc4, 0xc2, 0xbe, 0xb2, 0x9e, 0x90, 0x87, 0x79, 0x72, 0x7d, 0x80, - 0x75, 0x56, 0x3e, 0x3e, 0x40, 0x3f, 0x3c, 0x3c, 0x41, 0x46, 0x48, 0x4b, - 0x4e, 0x50, 0x4f, 0x4d, 0x49, 0x47, 0x49, 0x4b, 0x4c, 0x4e, 0x4e, 0x4f, - 0x4f, 0x4f, 0x50, 0x53, 0x56, 0x58, 0x5a, 0x5f, 0x69, 0x74, 0x7b, 0x7f, - 0x82, 0x83, 0x83, 0x85, 0x86, 0x85, 0x7d, 0x73, 0x6b, 0x63, 0x50, 0x36, - 0x2b, 0x29, 0x29, 0x27, 0x29, 0x33, 0x41, 0x45, 0x46, 0x46, 0x46, 0x4a, - 0x50, 0x52, 0x51, 0x47, 0x38, 0x2a, 0x25, 0x27, 0x33, 0x37, 0x38, 0x39, - 0x3d, 0x44, 0x4a, 0x4d, 0x4d, 0x4d, 0x50, 0x56, 0x5b, 0x5c, 0x59, 0x53, - 0x50, 0x54, 0x5a, 0x63, 0x69, 0x6b, 0x6d, 0x6d, 0x6d, 0x6d, 0x6e, 0x6c, - 0x6a, 0x65, 0x5e, 0x5c, 0x5e, 0x5f, 0x61, 0x61, 0x5f, 0x5f, 0x61, 0x67, - 0x73, 0x7e, 0x82, 0x83, 0x84, 0x84, 0x84, 0x81, 0x7d, 0x79, 0x71, 0x64, - 0x59, 0x56, 0x55, 0x58, 0x60, 0x6a, 0x71, 0x75, 0x7d, 0x83, 0x86, 0x88, - 0x88, 0x8b, 0x8f, 0x96, 0x9a, 0x9d, 0xa0, 0xa1, 0x9e, 0x9d, 0x9c, 0x98, - 0x97, 0x96, 0x96, 0x96, 0x96, 0x93, 0x92, 0x94, 0x96, 0x9a, 0xa0, 0xa5, - 0xa8, 0xaa, 0xab, 0xac, 0xae, 0xaf, 0xaf, 0xb0, 0xb1, 0xb0, 0xb0, 0xb0, - 0xb0, 0xb2, 0xb2, 0xb2, 0xb1, 0xb1, 0xb2, 0xb1, 0xae, 0xad, 0xae, 0xaf, - 0x57, 0x4e, 0x4a, 0x4b, 0x4e, 0x52, 0x54, 0x56, 0x57, 0x58, 0x5a, 0x59, - 0x5a, 0x5a, 0x59, 0x59, 0x57, 0x58, 0x58, 0x56, 0x56, 0x57, 0x57, 0x56, - 0x57, 0x5a, 0x59, 0x5a, 0x5b, 0x5d, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, - 0x61, 0x61, 0x61, 0x61, 0x63, 0x62, 0x63, 0x62, 0x61, 0x62, 0x65, 0x68, - 0x69, 0x6b, 0x6c, 0x6e, 0x70, 0x71, 0x72, 0x75, 0x78, 0x7c, 0x7f, 0x82, - 0x84, 0x86, 0x86, 0x86, 0x86, 0x87, 0x8e, 0x98, 0x9e, 0xa0, 0xa1, 0xa2, - 0xa5, 0xaa, 0xae, 0xb2, 0xb3, 0xb0, 0xaf, 0xb0, 0xb5, 0xb7, 0xb7, 0xbd, - 0xc5, 0xd0, 0xd8, 0xd6, 0xd5, 0xd4, 0xd3, 0xcf, 0xcb, 0xca, 0xcb, 0xcb, - 0xca, 0xc5, 0xc1, 0xc0, 0xbd, 0xb1, 0xa7, 0x9a, 0x91, 0x86, 0x7c, 0x7b, - 0x78, 0x78, 0x7b, 0x80, 0x77, 0x72, 0x73, 0x78, 0x83, 0x8a, 0x88, 0x86, - 0x84, 0x80, 0x7e, 0x7a, 0x7d, 0x8d, 0xa7, 0xb5, 0xb6, 0xb0, 0xad, 0xa6, - 0x93, 0x77, 0x6c, 0x68, 0x62, 0x5b, 0x55, 0x55, 0x52, 0x48, 0x41, 0x41, - 0x42, 0x41, 0x3e, 0x3e, 0x42, 0x48, 0x4a, 0x4e, 0x51, 0x53, 0x53, 0x51, - 0x4d, 0x48, 0x48, 0x4a, 0x4b, 0x4f, 0x51, 0x52, 0x52, 0x52, 0x53, 0x55, - 0x54, 0x52, 0x51, 0x4e, 0x4a, 0x48, 0x49, 0x4a, 0x4a, 0x4a, 0x4d, 0x53, - 0x58, 0x5e, 0x5c, 0x57, 0x55, 0x52, 0x47, 0x2e, 0x27, 0x28, 0x29, 0x2a, - 0x2a, 0x2f, 0x3f, 0x48, 0x4a, 0x47, 0x44, 0x47, 0x4d, 0x50, 0x54, 0x4f, - 0x3b, 0x29, 0x25, 0x2a, 0x35, 0x38, 0x39, 0x3b, 0x40, 0x47, 0x4b, 0x4d, - 0x4e, 0x4f, 0x55, 0x59, 0x5b, 0x5a, 0x57, 0x4f, 0x4f, 0x55, 0x5a, 0x61, - 0x68, 0x6c, 0x6e, 0x6f, 0x6e, 0x6c, 0x6c, 0x6a, 0x67, 0x61, 0x5c, 0x5c, - 0x60, 0x62, 0x64, 0x62, 0x5e, 0x5d, 0x60, 0x67, 0x75, 0x7f, 0x82, 0x83, - 0x84, 0x85, 0x87, 0x83, 0x80, 0x7c, 0x73, 0x66, 0x5c, 0x55, 0x52, 0x51, - 0x54, 0x5c, 0x62, 0x67, 0x6f, 0x78, 0x7e, 0x82, 0x84, 0x87, 0x8c, 0x95, - 0x99, 0x9c, 0xa0, 0xa2, 0xa3, 0xa2, 0xa1, 0xa0, 0x9e, 0x9f, 0x9f, 0x9f, - 0x9e, 0x9b, 0x99, 0x99, 0x9a, 0x9d, 0xa3, 0xa6, 0xa9, 0xaa, 0xab, 0xad, - 0xb0, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xb2, 0xb3, 0xb2, 0xb2, 0xb3, 0xb4, - 0xb4, 0xb5, 0xb5, 0xb4, 0xb1, 0xb0, 0xb0, 0xb0, 0x5a, 0x51, 0x4d, 0x4d, - 0x4f, 0x52, 0x55, 0x57, 0x58, 0x59, 0x5b, 0x5b, 0x5b, 0x5a, 0x59, 0x59, - 0x58, 0x59, 0x59, 0x57, 0x57, 0x57, 0x56, 0x56, 0x57, 0x59, 0x59, 0x5a, - 0x5a, 0x5e, 0x60, 0x61, 0x60, 0x5f, 0x60, 0x5f, 0x60, 0x60, 0x60, 0x61, - 0x63, 0x63, 0x64, 0x65, 0x63, 0x64, 0x66, 0x69, 0x6b, 0x6d, 0x6e, 0x71, - 0x72, 0x72, 0x75, 0x79, 0x7d, 0x81, 0x83, 0x85, 0x87, 0x89, 0x89, 0x89, - 0x89, 0x89, 0x8d, 0x94, 0x9c, 0x9f, 0xa1, 0xa2, 0xa5, 0xa9, 0xac, 0xb0, - 0xb2, 0xad, 0xac, 0xae, 0xb4, 0xb9, 0xba, 0xbf, 0xc5, 0xce, 0xd6, 0xd4, - 0xcb, 0xc2, 0xb4, 0xa6, 0xa2, 0xa9, 0xaf, 0xb5, 0xb4, 0xad, 0xa8, 0xa5, - 0xa3, 0x96, 0x8d, 0x86, 0x84, 0x85, 0x82, 0x82, 0x85, 0x86, 0x87, 0x87, - 0x80, 0x7c, 0x7b, 0x7f, 0x86, 0x8c, 0x89, 0x88, 0x87, 0x81, 0x78, 0x6f, - 0x6f, 0x79, 0x86, 0x8d, 0x8a, 0x80, 0x7c, 0x7a, 0x71, 0x69, 0x69, 0x67, - 0x61, 0x58, 0x4c, 0x4c, 0x4a, 0x45, 0x43, 0x40, 0x42, 0x42, 0x40, 0x3e, - 0x42, 0x46, 0x49, 0x4d, 0x52, 0x53, 0x53, 0x53, 0x50, 0x4a, 0x48, 0x48, - 0x49, 0x4c, 0x51, 0x54, 0x55, 0x56, 0x56, 0x59, 0x5a, 0x59, 0x58, 0x54, - 0x4a, 0x3f, 0x39, 0x35, 0x32, 0x31, 0x36, 0x42, 0x4c, 0x56, 0x55, 0x4f, - 0x51, 0x53, 0x4e, 0x36, 0x2a, 0x29, 0x2a, 0x2a, 0x2a, 0x2d, 0x3b, 0x4b, - 0x4f, 0x4b, 0x45, 0x43, 0x47, 0x4b, 0x51, 0x51, 0x3e, 0x2c, 0x28, 0x2f, - 0x38, 0x3a, 0x3a, 0x3c, 0x42, 0x49, 0x4c, 0x50, 0x51, 0x51, 0x57, 0x5a, - 0x59, 0x57, 0x53, 0x4b, 0x4e, 0x56, 0x5b, 0x60, 0x68, 0x6b, 0x6d, 0x6c, - 0x6c, 0x6c, 0x69, 0x66, 0x63, 0x5f, 0x5c, 0x5f, 0x64, 0x67, 0x69, 0x65, - 0x5d, 0x5a, 0x5d, 0x69, 0x79, 0x7f, 0x81, 0x82, 0x83, 0x87, 0x89, 0x86, - 0x83, 0x7f, 0x75, 0x67, 0x5d, 0x58, 0x56, 0x52, 0x51, 0x51, 0x54, 0x59, - 0x60, 0x69, 0x72, 0x78, 0x7a, 0x7d, 0x84, 0x8d, 0x92, 0x95, 0x99, 0x9d, - 0xa3, 0xa4, 0xa5, 0xa4, 0xa4, 0xa5, 0xa5, 0xa4, 0xa3, 0x9f, 0x9d, 0x9d, - 0x9e, 0x9f, 0xa3, 0xa6, 0xa8, 0xa9, 0xaa, 0xae, 0xb0, 0xb1, 0xb1, 0xb1, - 0xb1, 0xb1, 0xb2, 0xb1, 0xb1, 0xb1, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb5, - 0xb2, 0xb2, 0xb1, 0xb2, 0x5d, 0x54, 0x4f, 0x4e, 0x4f, 0x52, 0x54, 0x57, - 0x58, 0x59, 0x5a, 0x5a, 0x5b, 0x5a, 0x59, 0x59, 0x58, 0x59, 0x59, 0x57, - 0x57, 0x57, 0x56, 0x56, 0x56, 0x59, 0x59, 0x5a, 0x5b, 0x5e, 0x60, 0x61, - 0x5f, 0x5f, 0x60, 0x5f, 0x61, 0x60, 0x60, 0x60, 0x62, 0x63, 0x64, 0x64, - 0x64, 0x66, 0x67, 0x6b, 0x6c, 0x6e, 0x6f, 0x72, 0x73, 0x75, 0x78, 0x7e, - 0x81, 0x85, 0x86, 0x88, 0x88, 0x8a, 0x8b, 0x8b, 0x8b, 0x8b, 0x8d, 0x93, - 0x9a, 0x9e, 0xa0, 0xa2, 0xa4, 0xa9, 0xab, 0xb0, 0xb1, 0xac, 0xab, 0xae, - 0xb4, 0xb9, 0xbb, 0xc0, 0xc4, 0xc9, 0xca, 0xc3, 0xb1, 0xa4, 0x95, 0x8b, - 0x8b, 0x92, 0x97, 0x9d, 0x9f, 0x9b, 0x9b, 0x9a, 0x97, 0x90, 0x8d, 0x8b, - 0x8b, 0x8a, 0x88, 0x87, 0x87, 0x88, 0x8a, 0x85, 0x80, 0x80, 0x81, 0x84, - 0x85, 0x8c, 0x8c, 0x8b, 0x89, 0x8a, 0x80, 0x73, 0x70, 0x72, 0x75, 0x73, - 0x71, 0x69, 0x69, 0x6e, 0x6a, 0x6b, 0x6c, 0x6a, 0x63, 0x5b, 0x51, 0x4f, - 0x4d, 0x4a, 0x47, 0x40, 0x42, 0x43, 0x41, 0x3f, 0x40, 0x43, 0x46, 0x4b, - 0x50, 0x52, 0x54, 0x55, 0x54, 0x4e, 0x49, 0x47, 0x47, 0x4a, 0x50, 0x54, - 0x56, 0x57, 0x58, 0x5b, 0x5f, 0x5f, 0x5e, 0x5a, 0x51, 0x43, 0x3b, 0x36, - 0x32, 0x30, 0x38, 0x47, 0x51, 0x5b, 0x57, 0x4e, 0x50, 0x54, 0x52, 0x3d, - 0x2d, 0x2c, 0x2c, 0x2a, 0x28, 0x2b, 0x37, 0x49, 0x51, 0x50, 0x46, 0x42, - 0x43, 0x46, 0x4d, 0x4f, 0x3e, 0x2d, 0x2b, 0x32, 0x3a, 0x3b, 0x3b, 0x3d, - 0x42, 0x47, 0x4c, 0x51, 0x53, 0x55, 0x5b, 0x5b, 0x58, 0x55, 0x4f, 0x48, - 0x4e, 0x58, 0x5d, 0x62, 0x68, 0x6c, 0x6b, 0x6b, 0x6b, 0x6b, 0x67, 0x63, - 0x60, 0x5d, 0x5c, 0x61, 0x69, 0x6c, 0x6d, 0x67, 0x5d, 0x59, 0x5e, 0x6c, - 0x7b, 0x7f, 0x7f, 0x80, 0x82, 0x87, 0x89, 0x89, 0x85, 0x81, 0x77, 0x68, - 0x5e, 0x5c, 0x59, 0x55, 0x52, 0x4f, 0x4f, 0x50, 0x53, 0x5b, 0x65, 0x6c, - 0x70, 0x75, 0x7c, 0x84, 0x88, 0x8b, 0x90, 0x96, 0x9e, 0xa3, 0xa4, 0xa6, - 0xa7, 0xa8, 0xa8, 0xa8, 0xa6, 0xa3, 0x9f, 0xa0, 0xa0, 0xa2, 0xa5, 0xa6, - 0xa8, 0xa9, 0xab, 0xac, 0xaf, 0xb0, 0xb0, 0xb1, 0xb0, 0xb1, 0xb0, 0xb0, - 0xaf, 0xaf, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb6, 0xb4, 0xb3, 0xb2, 0xb2, - 0x5f, 0x55, 0x50, 0x4e, 0x4f, 0x53, 0x55, 0x57, 0x58, 0x59, 0x5b, 0x5b, - 0x5b, 0x5a, 0x59, 0x59, 0x58, 0x59, 0x58, 0x57, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x59, 0x59, 0x5a, 0x5a, 0x5d, 0x60, 0x60, 0x5f, 0x5f, 0x5f, 0x5f, - 0x60, 0x60, 0x60, 0x5f, 0x62, 0x63, 0x64, 0x64, 0x64, 0x67, 0x68, 0x6b, - 0x6c, 0x6e, 0x70, 0x73, 0x75, 0x77, 0x7a, 0x80, 0x84, 0x86, 0x88, 0x8a, - 0x8a, 0x8c, 0x8b, 0x8c, 0x8c, 0x8c, 0x8d, 0x91, 0x98, 0x9c, 0xa0, 0xa1, - 0xa3, 0xa8, 0xab, 0xaf, 0xb0, 0xab, 0xaa, 0xad, 0xb4, 0xba, 0xbc, 0xc1, - 0xc4, 0xc4, 0xb9, 0xa9, 0x9c, 0x95, 0x8f, 0x89, 0x89, 0x8c, 0x8e, 0x92, - 0x95, 0x95, 0x98, 0x99, 0x94, 0x90, 0x8f, 0x8f, 0x8f, 0x8d, 0x8a, 0x88, - 0x88, 0x89, 0x8a, 0x85, 0x81, 0x83, 0x84, 0x85, 0x84, 0x8b, 0x8e, 0x8d, - 0x89, 0x8c, 0x86, 0x7a, 0x75, 0x73, 0x71, 0x69, 0x68, 0x65, 0x67, 0x6e, - 0x6b, 0x6e, 0x6e, 0x6b, 0x64, 0x5c, 0x53, 0x51, 0x50, 0x4e, 0x4a, 0x40, - 0x41, 0x43, 0x43, 0x40, 0x3f, 0x41, 0x44, 0x48, 0x4e, 0x51, 0x54, 0x55, - 0x55, 0x50, 0x4a, 0x48, 0x48, 0x49, 0x4e, 0x53, 0x56, 0x58, 0x59, 0x5c, - 0x61, 0x62, 0x61, 0x5d, 0x55, 0x48, 0x3e, 0x39, 0x33, 0x32, 0x3b, 0x4b, - 0x55, 0x5f, 0x58, 0x4d, 0x50, 0x54, 0x55, 0x40, 0x2f, 0x2c, 0x2c, 0x2b, - 0x29, 0x2a, 0x34, 0x47, 0x4f, 0x52, 0x49, 0x42, 0x42, 0x45, 0x4b, 0x4c, - 0x3c, 0x2e, 0x2c, 0x35, 0x3c, 0x3d, 0x3d, 0x3f, 0x43, 0x46, 0x4c, 0x52, - 0x54, 0x57, 0x5b, 0x5b, 0x57, 0x53, 0x4c, 0x47, 0x4e, 0x59, 0x5e, 0x63, - 0x68, 0x6b, 0x6b, 0x6a, 0x6a, 0x6a, 0x67, 0x62, 0x5f, 0x5c, 0x5e, 0x64, - 0x6b, 0x6f, 0x71, 0x68, 0x5c, 0x5a, 0x60, 0x6f, 0x7c, 0x80, 0x80, 0x80, - 0x81, 0x86, 0x8a, 0x8a, 0x86, 0x82, 0x78, 0x69, 0x5f, 0x5c, 0x5a, 0x57, - 0x53, 0x4f, 0x4e, 0x4e, 0x4e, 0x54, 0x5c, 0x63, 0x68, 0x6e, 0x76, 0x7c, - 0x80, 0x82, 0x86, 0x90, 0x9b, 0xa1, 0xa3, 0xa5, 0xa8, 0xa9, 0xa9, 0xa9, - 0xa7, 0xa3, 0xa0, 0xa1, 0xa2, 0xa3, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xac, - 0xaf, 0xb0, 0xb0, 0xb1, 0xb0, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb1, 0xb2, - 0xb3, 0xb5, 0xb6, 0xb6, 0xb4, 0xb3, 0xb3, 0xb2, 0x62, 0x58, 0x52, 0x50, - 0x4f, 0x53, 0x56, 0x57, 0x58, 0x5a, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x58, - 0x58, 0x57, 0x56, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x58, 0x5a, 0x59, - 0x5a, 0x5c, 0x5f, 0x5f, 0x5e, 0x5e, 0x5e, 0x60, 0x60, 0x5f, 0x5f, 0x5f, - 0x62, 0x64, 0x65, 0x65, 0x65, 0x67, 0x69, 0x6b, 0x6c, 0x6e, 0x72, 0x75, - 0x78, 0x7a, 0x7e, 0x83, 0x87, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8d, 0x8d, - 0x8e, 0x8e, 0x8d, 0x8f, 0x95, 0x99, 0x9d, 0xa1, 0xa4, 0xa7, 0xaa, 0xae, - 0xaf, 0xa9, 0xa9, 0xac, 0xb4, 0xba, 0xbd, 0xc3, 0xc4, 0xbe, 0x9c, 0x7f, - 0x88, 0x93, 0x9b, 0x97, 0x95, 0x93, 0x90, 0x8e, 0x93, 0x92, 0x98, 0x99, - 0x94, 0x90, 0x90, 0x90, 0x91, 0x90, 0x8d, 0x8c, 0x8d, 0x8d, 0x8c, 0x88, - 0x87, 0x88, 0x88, 0x86, 0x85, 0x8a, 0x90, 0x90, 0x89, 0x89, 0x89, 0x83, - 0x7e, 0x78, 0x74, 0x6b, 0x69, 0x6b, 0x6e, 0x71, 0x71, 0x71, 0x6f, 0x6d, - 0x65, 0x5b, 0x53, 0x52, 0x53, 0x54, 0x4c, 0x3e, 0x3e, 0x42, 0x45, 0x41, - 0x3d, 0x3e, 0x3f, 0x43, 0x4a, 0x4f, 0x53, 0x54, 0x55, 0x52, 0x4e, 0x4b, - 0x4a, 0x49, 0x4a, 0x50, 0x57, 0x5a, 0x5b, 0x5e, 0x63, 0x66, 0x67, 0x64, - 0x5b, 0x4e, 0x41, 0x3b, 0x34, 0x33, 0x3e, 0x50, 0x5b, 0x62, 0x59, 0x4c, - 0x4e, 0x54, 0x57, 0x46, 0x30, 0x2c, 0x2c, 0x2d, 0x2b, 0x2a, 0x32, 0x41, - 0x4b, 0x54, 0x4e, 0x45, 0x45, 0x47, 0x4a, 0x49, 0x39, 0x30, 0x30, 0x39, - 0x3f, 0x40, 0x40, 0x40, 0x43, 0x45, 0x4d, 0x53, 0x55, 0x58, 0x5c, 0x5b, - 0x55, 0x50, 0x49, 0x46, 0x51, 0x5c, 0x61, 0x65, 0x67, 0x6a, 0x6a, 0x69, - 0x69, 0x6a, 0x66, 0x61, 0x5f, 0x5e, 0x62, 0x69, 0x71, 0x75, 0x74, 0x69, - 0x5d, 0x5d, 0x64, 0x72, 0x7e, 0x81, 0x80, 0x80, 0x80, 0x86, 0x8c, 0x8c, - 0x88, 0x83, 0x79, 0x6b, 0x61, 0x5c, 0x5a, 0x59, 0x55, 0x51, 0x50, 0x4f, - 0x4d, 0x4d, 0x51, 0x57, 0x5b, 0x61, 0x6a, 0x6f, 0x72, 0x74, 0x78, 0x87, - 0x97, 0x9f, 0xa2, 0xa4, 0xa8, 0xaa, 0xaa, 0xa9, 0xa7, 0xa2, 0xa0, 0xa0, - 0xa1, 0xa3, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xad, 0xae, 0xae, 0xaf, - 0xaf, 0xb0, 0xb0, 0xb0, 0xaf, 0xaf, 0xb0, 0xb1, 0xb1, 0xb3, 0xb5, 0xb6, - 0xb5, 0xb4, 0xb4, 0xb1, 0x65, 0x5c, 0x56, 0x54, 0x52, 0x54, 0x56, 0x57, - 0x58, 0x5a, 0x5c, 0x5c, 0x5a, 0x5a, 0x5a, 0x59, 0x58, 0x56, 0x55, 0x56, - 0x56, 0x55, 0x55, 0x56, 0x57, 0x58, 0x58, 0x59, 0x5a, 0x5c, 0x5f, 0x5f, - 0x5e, 0x5e, 0x5e, 0x60, 0x60, 0x5f, 0x5f, 0x5f, 0x61, 0x64, 0x64, 0x65, - 0x66, 0x69, 0x6c, 0x6e, 0x6f, 0x71, 0x74, 0x7a, 0x7d, 0x7f, 0x82, 0x86, - 0x8a, 0x8c, 0x8c, 0x8d, 0x8e, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8f, - 0x93, 0x96, 0x9c, 0xa0, 0xa3, 0xa6, 0xa9, 0xac, 0xad, 0xaa, 0xab, 0xae, - 0xb5, 0xba, 0xbd, 0xc2, 0xc5, 0xbd, 0x98, 0x89, 0x9e, 0xa9, 0xaa, 0xa7, - 0xa5, 0xa2, 0x9f, 0x9a, 0x96, 0x95, 0x99, 0x9a, 0x97, 0x92, 0x93, 0x93, - 0x93, 0x95, 0x94, 0x95, 0x96, 0x96, 0x94, 0x93, 0x8e, 0x8a, 0x89, 0x8a, - 0x8b, 0x89, 0x8e, 0x90, 0x8f, 0x88, 0x8a, 0x89, 0x85, 0x7f, 0x7c, 0x79, - 0x78, 0x79, 0x79, 0x77, 0x73, 0x70, 0x6f, 0x6e, 0x69, 0x5b, 0x56, 0x59, - 0x5d, 0x5e, 0x4f, 0x3d, 0x3d, 0x41, 0x47, 0x44, 0x3c, 0x3a, 0x3b, 0x3f, - 0x46, 0x4d, 0x53, 0x55, 0x57, 0x57, 0x54, 0x52, 0x50, 0x4b, 0x49, 0x4e, - 0x55, 0x59, 0x5d, 0x60, 0x65, 0x6b, 0x6d, 0x6d, 0x65, 0x58, 0x48, 0x3f, - 0x38, 0x35, 0x43, 0x56, 0x61, 0x68, 0x5d, 0x4d, 0x4e, 0x54, 0x59, 0x4d, - 0x33, 0x2c, 0x2c, 0x2e, 0x2c, 0x2b, 0x30, 0x3a, 0x44, 0x52, 0x53, 0x4d, - 0x4c, 0x4c, 0x4c, 0x48, 0x37, 0x31, 0x35, 0x3f, 0x43, 0x43, 0x42, 0x42, - 0x44, 0x47, 0x4f, 0x56, 0x58, 0x5b, 0x5d, 0x58, 0x4f, 0x49, 0x44, 0x47, - 0x53, 0x5e, 0x63, 0x66, 0x68, 0x6a, 0x6a, 0x6a, 0x6a, 0x68, 0x62, 0x5f, - 0x5f, 0x62, 0x6a, 0x73, 0x7a, 0x7c, 0x78, 0x6b, 0x60, 0x63, 0x6a, 0x77, - 0x81, 0x81, 0x7f, 0x7e, 0x80, 0x86, 0x8c, 0x8f, 0x8c, 0x87, 0x7d, 0x70, - 0x64, 0x5d, 0x5b, 0x5a, 0x56, 0x54, 0x52, 0x51, 0x4e, 0x4c, 0x4b, 0x4c, - 0x4e, 0x52, 0x5a, 0x60, 0x60, 0x61, 0x67, 0x7a, 0x90, 0x9b, 0xa0, 0xa4, - 0xa7, 0xa8, 0xa9, 0xa8, 0xa5, 0xa2, 0x9f, 0x9f, 0x9f, 0xa2, 0xa6, 0xa8, - 0xa8, 0xa9, 0xab, 0xac, 0xac, 0xac, 0xac, 0xad, 0xad, 0xaf, 0xaf, 0xaf, - 0xae, 0xae, 0xae, 0xae, 0xaf, 0xb1, 0xb3, 0xb5, 0xb5, 0xb5, 0xb4, 0xb1, - 0x69, 0x60, 0x5b, 0x58, 0x57, 0x55, 0x56, 0x58, 0x5a, 0x5b, 0x5d, 0x5d, - 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, - 0x58, 0x57, 0x58, 0x5a, 0x5a, 0x5c, 0x5e, 0x5e, 0x5d, 0x5e, 0x5f, 0x60, - 0x5f, 0x5f, 0x5f, 0x5f, 0x62, 0x63, 0x65, 0x66, 0x69, 0x6c, 0x6e, 0x70, - 0x71, 0x74, 0x78, 0x7e, 0x81, 0x83, 0x86, 0x8a, 0x8d, 0x8e, 0x8f, 0x90, - 0x91, 0x91, 0x91, 0x91, 0x90, 0x8f, 0x90, 0x8f, 0x90, 0x93, 0x98, 0xa0, - 0xa3, 0xa6, 0xa8, 0xa9, 0xab, 0xaa, 0xad, 0xb0, 0xb5, 0xb9, 0xbb, 0xc2, - 0xc6, 0xc7, 0xc2, 0xc6, 0xc5, 0xbd, 0xad, 0xa9, 0xa9, 0xa5, 0xa2, 0x9f, - 0x9a, 0x9a, 0x9c, 0x9c, 0x9b, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9b, 0x99, - 0x9a, 0x98, 0x94, 0x91, 0x8f, 0x90, 0x91, 0x91, 0x88, 0x7b, 0x84, 0x8d, - 0x93, 0x8d, 0x88, 0x8a, 0x89, 0x85, 0x83, 0x82, 0x80, 0x7e, 0x7c, 0x7b, - 0x77, 0x73, 0x70, 0x70, 0x6d, 0x64, 0x63, 0x69, 0x6b, 0x66, 0x4a, 0x39, - 0x3b, 0x40, 0x46, 0x48, 0x41, 0x3c, 0x3b, 0x3e, 0x44, 0x4c, 0x53, 0x57, - 0x5a, 0x5c, 0x5b, 0x5a, 0x58, 0x53, 0x4c, 0x4d, 0x51, 0x55, 0x5c, 0x63, - 0x67, 0x6b, 0x6e, 0x72, 0x70, 0x63, 0x52, 0x47, 0x3c, 0x39, 0x48, 0x5c, - 0x67, 0x6d, 0x60, 0x4d, 0x4e, 0x53, 0x5a, 0x52, 0x36, 0x2c, 0x2b, 0x2e, - 0x2d, 0x2b, 0x2d, 0x33, 0x3c, 0x4b, 0x53, 0x4f, 0x4e, 0x4e, 0x4e, 0x47, - 0x36, 0x34, 0x39, 0x44, 0x46, 0x45, 0x44, 0x46, 0x47, 0x4a, 0x52, 0x57, - 0x59, 0x5d, 0x5f, 0x58, 0x4d, 0x47, 0x44, 0x4b, 0x57, 0x61, 0x65, 0x67, - 0x6a, 0x6b, 0x6b, 0x6a, 0x6a, 0x66, 0x61, 0x61, 0x63, 0x68, 0x72, 0x79, - 0x7d, 0x7d, 0x76, 0x6a, 0x65, 0x6c, 0x72, 0x7b, 0x82, 0x82, 0x7f, 0x7e, - 0x80, 0x86, 0x8d, 0x91, 0x90, 0x8c, 0x82, 0x74, 0x67, 0x5f, 0x5c, 0x5b, - 0x59, 0x57, 0x55, 0x53, 0x50, 0x4d, 0x4b, 0x4a, 0x4b, 0x4c, 0x4e, 0x52, - 0x52, 0x53, 0x5c, 0x74, 0x8d, 0x98, 0x9e, 0xa3, 0xa6, 0xa7, 0xa7, 0xa6, - 0xa4, 0xa0, 0x9e, 0x9e, 0x9e, 0xa1, 0xa5, 0xa8, 0xa8, 0xa9, 0xab, 0xac, - 0xac, 0xab, 0xab, 0xab, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xae, - 0xae, 0xb0, 0xb3, 0xb5, 0xb5, 0xb5, 0xb4, 0xb1, 0x6d, 0x64, 0x60, 0x5e, - 0x5b, 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5d, 0x5d, 0x5d, 0x5d, 0x5c, 0x5b, - 0x5a, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x58, 0x59, 0x59, - 0x5a, 0x5b, 0x5c, 0x5d, 0x5d, 0x5e, 0x60, 0x60, 0x5f, 0x5e, 0x5f, 0x60, - 0x62, 0x65, 0x67, 0x68, 0x6b, 0x6d, 0x6f, 0x71, 0x72, 0x75, 0x7b, 0x80, - 0x83, 0x86, 0x88, 0x8c, 0x8f, 0x90, 0x90, 0x91, 0x91, 0x90, 0x91, 0x90, - 0x90, 0x8f, 0x90, 0x90, 0x90, 0x92, 0x96, 0x9e, 0xa2, 0xa5, 0xa6, 0xa7, - 0xaa, 0xab, 0xaf, 0xb2, 0xb5, 0xb7, 0xbd, 0xc7, 0xce, 0xd4, 0xd9, 0xdc, - 0xd4, 0xc5, 0xab, 0xa6, 0xa9, 0xa9, 0xa7, 0xa4, 0xa1, 0xa2, 0xa2, 0xa2, - 0xa2, 0xa0, 0x9e, 0x9f, 0x9f, 0x9e, 0x9b, 0x97, 0x96, 0x94, 0x91, 0x92, - 0x95, 0x97, 0x98, 0x92, 0x76, 0x69, 0x7c, 0x8a, 0x93, 0x90, 0x8a, 0x8b, - 0x8c, 0x8b, 0x88, 0x84, 0x81, 0x7e, 0x7d, 0x7b, 0x78, 0x77, 0x74, 0x72, - 0x71, 0x6e, 0x6f, 0x70, 0x70, 0x66, 0x41, 0x36, 0x3a, 0x3e, 0x44, 0x4b, - 0x47, 0x3e, 0x3c, 0x3e, 0x44, 0x4d, 0x55, 0x59, 0x5c, 0x5f, 0x60, 0x5f, - 0x5d, 0x58, 0x50, 0x4d, 0x4f, 0x52, 0x5a, 0x64, 0x68, 0x6b, 0x6e, 0x75, - 0x79, 0x6d, 0x5d, 0x51, 0x42, 0x3c, 0x4b, 0x60, 0x6b, 0x70, 0x63, 0x4e, - 0x4e, 0x53, 0x5b, 0x55, 0x39, 0x2b, 0x2a, 0x2e, 0x2e, 0x2d, 0x2a, 0x2e, - 0x35, 0x45, 0x51, 0x52, 0x4f, 0x4f, 0x4f, 0x47, 0x37, 0x37, 0x3c, 0x47, - 0x49, 0x48, 0x47, 0x47, 0x4a, 0x4d, 0x54, 0x58, 0x5b, 0x60, 0x61, 0x57, - 0x4b, 0x45, 0x43, 0x4c, 0x5a, 0x63, 0x67, 0x6a, 0x6c, 0x6d, 0x6d, 0x6c, - 0x6a, 0x64, 0x61, 0x64, 0x67, 0x6e, 0x78, 0x7d, 0x7e, 0x7a, 0x72, 0x69, - 0x68, 0x70, 0x77, 0x7e, 0x82, 0x82, 0x80, 0x7f, 0x7f, 0x85, 0x8c, 0x92, - 0x91, 0x8e, 0x85, 0x78, 0x6a, 0x60, 0x5c, 0x5b, 0x59, 0x58, 0x57, 0x56, - 0x53, 0x51, 0x4e, 0x4c, 0x4c, 0x4c, 0x4d, 0x4e, 0x4e, 0x51, 0x5c, 0x75, - 0x8c, 0x98, 0x9e, 0xa2, 0xa5, 0xa6, 0xa6, 0xa5, 0xa1, 0x9f, 0x9e, 0x9d, - 0x9f, 0xa2, 0xa6, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xac, 0xab, 0xac, - 0xac, 0xab, 0xab, 0xab, 0xab, 0xac, 0xab, 0xac, 0xad, 0xaf, 0xb2, 0xb4, - 0xb4, 0xb4, 0xb3, 0xb1, 0x6f, 0x67, 0x62, 0x60, 0x5d, 0x59, 0x59, 0x5a, - 0x5a, 0x5b, 0x5d, 0x5e, 0x5e, 0x5d, 0x5c, 0x5a, 0x5a, 0x59, 0x58, 0x57, - 0x57, 0x57, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, 0x5a, 0x5b, 0x5c, - 0x5d, 0x5e, 0x5f, 0x5f, 0x5e, 0x5e, 0x5f, 0x60, 0x62, 0x65, 0x67, 0x69, - 0x6b, 0x6d, 0x71, 0x72, 0x74, 0x78, 0x7d, 0x82, 0x85, 0x87, 0x8a, 0x8d, - 0x8f, 0x90, 0x91, 0x92, 0x92, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, - 0x90, 0x91, 0x95, 0x9c, 0xa1, 0xa4, 0xa5, 0xa7, 0xa9, 0xab, 0xaf, 0xb3, - 0xb6, 0xba, 0xc3, 0xce, 0xd4, 0xda, 0xdf, 0xe0, 0xd9, 0xc9, 0xac, 0xa4, - 0xa8, 0xa8, 0xa8, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa2, 0x9e, 0x9d, - 0x9d, 0x9d, 0x9a, 0x97, 0x96, 0x95, 0x93, 0x95, 0x98, 0x99, 0x97, 0x8b, - 0x65, 0x5b, 0x75, 0x86, 0x91, 0x90, 0x8b, 0x8c, 0x8d, 0x8d, 0x8a, 0x86, - 0x82, 0x80, 0x7e, 0x7e, 0x7b, 0x7a, 0x77, 0x75, 0x72, 0x71, 0x72, 0x72, - 0x6f, 0x61, 0x3a, 0x33, 0x39, 0x3d, 0x43, 0x4c, 0x4b, 0x43, 0x3f, 0x40, - 0x45, 0x4e, 0x56, 0x5b, 0x5e, 0x62, 0x63, 0x62, 0x60, 0x5b, 0x53, 0x4e, - 0x4d, 0x50, 0x58, 0x63, 0x68, 0x6b, 0x6e, 0x76, 0x7e, 0x73, 0x65, 0x58, - 0x45, 0x3e, 0x4d, 0x62, 0x6d, 0x71, 0x65, 0x4f, 0x4e, 0x53, 0x5b, 0x57, - 0x3b, 0x2a, 0x28, 0x2d, 0x30, 0x2e, 0x2a, 0x2c, 0x32, 0x41, 0x51, 0x52, - 0x50, 0x4f, 0x50, 0x47, 0x38, 0x39, 0x3f, 0x49, 0x4a, 0x49, 0x48, 0x49, - 0x4b, 0x4f, 0x55, 0x5a, 0x5d, 0x62, 0x62, 0x55, 0x49, 0x44, 0x43, 0x4e, - 0x5d, 0x65, 0x68, 0x6b, 0x6c, 0x6e, 0x6d, 0x6c, 0x69, 0x63, 0x61, 0x66, - 0x6a, 0x71, 0x7b, 0x7e, 0x7b, 0x77, 0x6f, 0x68, 0x6a, 0x73, 0x79, 0x7f, - 0x83, 0x82, 0x80, 0x7f, 0x7f, 0x85, 0x8c, 0x92, 0x92, 0x90, 0x87, 0x7a, - 0x6d, 0x62, 0x5d, 0x5b, 0x58, 0x57, 0x57, 0x57, 0x55, 0x53, 0x50, 0x4f, - 0x4f, 0x4e, 0x4e, 0x4e, 0x4f, 0x53, 0x60, 0x78, 0x8d, 0x99, 0x9d, 0xa1, - 0xa3, 0xa5, 0xa5, 0xa4, 0xa1, 0x9f, 0x9d, 0x9d, 0x9e, 0xa1, 0xa5, 0xa7, - 0xa8, 0xa9, 0xaa, 0xaa, 0xaa, 0xab, 0xab, 0xab, 0xab, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xab, 0xae, 0xb1, 0xb4, 0xb5, 0xb4, 0xb3, 0xb1, - 0x71, 0x6a, 0x65, 0x63, 0x60, 0x5c, 0x5a, 0x5b, 0x5b, 0x5c, 0x5e, 0x5f, - 0x5e, 0x5d, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58, 0x56, 0x56, 0x58, 0x58, - 0x58, 0x59, 0x58, 0x59, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5e, - 0x5d, 0x5e, 0x5e, 0x60, 0x62, 0x64, 0x66, 0x68, 0x6b, 0x6e, 0x71, 0x75, - 0x78, 0x7b, 0x80, 0x85, 0x88, 0x89, 0x8b, 0x8e, 0x90, 0x91, 0x91, 0x93, - 0x93, 0x91, 0x90, 0x91, 0x92, 0x92, 0x91, 0x91, 0x8f, 0x8f, 0x93, 0x99, - 0x9f, 0xa2, 0xa3, 0xa5, 0xa7, 0xab, 0xb1, 0xb6, 0xbe, 0xc8, 0xd2, 0xd9, - 0xdc, 0xdc, 0xdf, 0xe1, 0xde, 0xd1, 0xb5, 0xa7, 0xa5, 0xa5, 0xa6, 0xa9, - 0xab, 0xaa, 0xa8, 0xa8, 0xa6, 0xa3, 0x9b, 0x99, 0x99, 0x9a, 0x9c, 0x9c, - 0x9c, 0x9c, 0x9b, 0x9a, 0x99, 0x93, 0x8c, 0x79, 0x56, 0x53, 0x6e, 0x7e, - 0x8b, 0x8f, 0x8b, 0x8b, 0x8b, 0x8b, 0x89, 0x88, 0x85, 0x82, 0x82, 0x81, - 0x80, 0x7e, 0x7a, 0x77, 0x74, 0x71, 0x71, 0x71, 0x6b, 0x55, 0x36, 0x32, - 0x37, 0x3a, 0x40, 0x4b, 0x51, 0x4b, 0x46, 0x42, 0x46, 0x50, 0x58, 0x5d, - 0x62, 0x66, 0x67, 0x66, 0x65, 0x60, 0x58, 0x51, 0x4e, 0x4e, 0x55, 0x62, - 0x69, 0x6c, 0x6e, 0x76, 0x82, 0x7b, 0x70, 0x63, 0x4c, 0x3f, 0x50, 0x65, - 0x70, 0x74, 0x69, 0x51, 0x4d, 0x52, 0x5c, 0x5b, 0x40, 0x2b, 0x26, 0x2d, - 0x32, 0x30, 0x2c, 0x2b, 0x2e, 0x3c, 0x50, 0x55, 0x52, 0x51, 0x51, 0x48, - 0x3a, 0x3d, 0x44, 0x4b, 0x4b, 0x4b, 0x4a, 0x4b, 0x4d, 0x51, 0x58, 0x5d, - 0x61, 0x66, 0x63, 0x54, 0x46, 0x42, 0x43, 0x51, 0x61, 0x69, 0x6b, 0x6c, - 0x6c, 0x6d, 0x6d, 0x6c, 0x68, 0x62, 0x63, 0x6a, 0x6f, 0x75, 0x7e, 0x7c, - 0x75, 0x70, 0x6a, 0x68, 0x6d, 0x77, 0x7d, 0x82, 0x84, 0x82, 0x80, 0x7e, - 0x7e, 0x84, 0x8c, 0x92, 0x94, 0x92, 0x8c, 0x7f, 0x70, 0x65, 0x60, 0x5c, - 0x56, 0x56, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x52, 0x52, 0x52, 0x51, - 0x53, 0x59, 0x67, 0x7c, 0x8e, 0x97, 0x9c, 0x9f, 0xa1, 0xa3, 0xa2, 0xa1, - 0xa0, 0x9f, 0x9c, 0x9c, 0x9d, 0xa0, 0xa4, 0xa6, 0xa9, 0xa9, 0xa9, 0xaa, - 0xaa, 0xa8, 0xa8, 0xa8, 0xa9, 0xa9, 0xa8, 0xa8, 0xa9, 0xa8, 0xa7, 0xa6, - 0xa7, 0xab, 0xaf, 0xb2, 0xb3, 0xb3, 0xb2, 0xb0, 0x75, 0x6e, 0x6b, 0x68, - 0x65, 0x5f, 0x5c, 0x5c, 0x5d, 0x5e, 0x5f, 0x5e, 0x5e, 0x5d, 0x5b, 0x5a, - 0x5a, 0x5a, 0x59, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x59, 0x59, - 0x59, 0x5a, 0x5c, 0x5c, 0x5d, 0x5e, 0x5f, 0x5e, 0x5f, 0x5f, 0x5f, 0x60, - 0x64, 0x65, 0x67, 0x69, 0x6a, 0x6d, 0x73, 0x79, 0x7c, 0x7f, 0x83, 0x86, - 0x89, 0x8b, 0x8e, 0x90, 0x91, 0x92, 0x92, 0x93, 0x93, 0x91, 0x91, 0x91, - 0x92, 0x93, 0x91, 0x92, 0x90, 0x90, 0x91, 0x95, 0x9b, 0x9f, 0xa2, 0xa4, - 0xa9, 0xb6, 0xc2, 0xca, 0xd2, 0xd9, 0xdc, 0xde, 0xde, 0xdd, 0xdd, 0xe0, - 0xe1, 0xd9, 0xc5, 0xb3, 0xac, 0xa7, 0xa6, 0xa9, 0xa9, 0xa9, 0xa8, 0xa6, - 0xa5, 0xa5, 0xa0, 0x9d, 0x9d, 0x9e, 0xa2, 0xa4, 0xa3, 0xa3, 0xa0, 0x9a, - 0x90, 0x7e, 0x75, 0x71, 0x75, 0x7e, 0x84, 0x86, 0x88, 0x8a, 0x87, 0x87, - 0x88, 0x87, 0x85, 0x82, 0x80, 0x80, 0x81, 0x80, 0x7e, 0x7d, 0x7b, 0x7a, - 0x78, 0x77, 0x71, 0x66, 0x5b, 0x4c, 0x40, 0x37, 0x36, 0x37, 0x3d, 0x47, - 0x55, 0x58, 0x54, 0x49, 0x49, 0x54, 0x5d, 0x62, 0x66, 0x6b, 0x6b, 0x6c, - 0x6b, 0x68, 0x61, 0x57, 0x51, 0x50, 0x53, 0x5d, 0x68, 0x6c, 0x6e, 0x74, - 0x83, 0x88, 0x7d, 0x70, 0x59, 0x46, 0x52, 0x67, 0x72, 0x78, 0x6c, 0x52, - 0x4e, 0x52, 0x5c, 0x5f, 0x48, 0x2e, 0x27, 0x2c, 0x33, 0x34, 0x30, 0x2e, - 0x2f, 0x39, 0x4f, 0x5a, 0x58, 0x56, 0x55, 0x4a, 0x3b, 0x41, 0x48, 0x4e, - 0x4d, 0x4c, 0x4c, 0x4d, 0x51, 0x56, 0x5d, 0x61, 0x64, 0x68, 0x64, 0x52, - 0x45, 0x42, 0x47, 0x58, 0x68, 0x6d, 0x6f, 0x6e, 0x6d, 0x6d, 0x6c, 0x6b, - 0x67, 0x62, 0x66, 0x6e, 0x73, 0x78, 0x7b, 0x75, 0x6d, 0x68, 0x64, 0x69, - 0x73, 0x7b, 0x7f, 0x83, 0x84, 0x82, 0x7f, 0x7e, 0x7d, 0x83, 0x8b, 0x92, - 0x94, 0x94, 0x90, 0x84, 0x74, 0x6a, 0x65, 0x5e, 0x57, 0x55, 0x55, 0x56, - 0x55, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x56, 0x5a, 0x60, 0x6d, 0x7f, - 0x8e, 0x97, 0x9a, 0x9d, 0x9f, 0xa0, 0x9f, 0x9f, 0x9e, 0x9d, 0x9c, 0x9c, - 0x9d, 0x9f, 0xa2, 0xa5, 0xa7, 0xa8, 0xa8, 0xa8, 0xa8, 0xa7, 0xa6, 0xa7, - 0xa5, 0xa6, 0xa5, 0xa6, 0xa7, 0xa5, 0xa3, 0xa3, 0xa4, 0xa7, 0xab, 0xaf, - 0xb1, 0xb1, 0xb0, 0xae, 0x77, 0x72, 0x6f, 0x6d, 0x69, 0x63, 0x5f, 0x5e, - 0x5e, 0x60, 0x60, 0x60, 0x5f, 0x5e, 0x5c, 0x5c, 0x5c, 0x5b, 0x5a, 0x58, - 0x57, 0x57, 0x57, 0x58, 0x59, 0x59, 0x5a, 0x59, 0x5a, 0x5b, 0x5c, 0x5c, - 0x5d, 0x5e, 0x5e, 0x5e, 0x61, 0x61, 0x61, 0x61, 0x64, 0x66, 0x68, 0x6a, - 0x6c, 0x70, 0x78, 0x7c, 0x7f, 0x82, 0x85, 0x87, 0x8a, 0x8c, 0x8e, 0x91, - 0x91, 0x92, 0x92, 0x92, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x90, 0x91, - 0x90, 0x8f, 0x8e, 0x91, 0x99, 0xa1, 0xa7, 0xb1, 0xc1, 0xd0, 0xd7, 0xda, - 0xdb, 0xdd, 0xdc, 0xdd, 0xde, 0xdd, 0xde, 0xe1, 0xe2, 0xe0, 0xd4, 0xbd, - 0xb3, 0xaf, 0xae, 0xad, 0xac, 0xac, 0xab, 0xab, 0xa9, 0xaa, 0xa8, 0xa5, - 0xa5, 0xa5, 0xa6, 0xa7, 0xa5, 0xa2, 0x9e, 0x97, 0x92, 0x8d, 0x8e, 0x96, - 0xa8, 0xb2, 0xb3, 0xb1, 0xa7, 0x97, 0x87, 0x81, 0x7f, 0x7f, 0x81, 0x81, - 0x80, 0x81, 0x81, 0x7f, 0x7c, 0x7e, 0x80, 0x80, 0x7d, 0x72, 0x61, 0x55, - 0x52, 0x52, 0x51, 0x48, 0x3d, 0x39, 0x3a, 0x43, 0x56, 0x65, 0x66, 0x5a, - 0x4e, 0x57, 0x62, 0x67, 0x6c, 0x6f, 0x6f, 0x70, 0x70, 0x6e, 0x67, 0x5f, - 0x58, 0x54, 0x52, 0x59, 0x66, 0x6c, 0x6f, 0x72, 0x7f, 0x91, 0x8a, 0x80, - 0x6a, 0x4f, 0x53, 0x67, 0x74, 0x7e, 0x6f, 0x53, 0x4d, 0x51, 0x5c, 0x62, - 0x50, 0x36, 0x2b, 0x2a, 0x32, 0x36, 0x35, 0x32, 0x32, 0x37, 0x48, 0x5b, - 0x5e, 0x5d, 0x59, 0x4d, 0x3e, 0x45, 0x4d, 0x52, 0x51, 0x50, 0x51, 0x53, - 0x58, 0x5d, 0x61, 0x65, 0x67, 0x67, 0x61, 0x4f, 0x45, 0x44, 0x4d, 0x61, - 0x6f, 0x72, 0x72, 0x6f, 0x6d, 0x6d, 0x6b, 0x69, 0x65, 0x63, 0x6a, 0x73, - 0x76, 0x77, 0x73, 0x69, 0x60, 0x5d, 0x61, 0x6d, 0x77, 0x7e, 0x80, 0x83, - 0x83, 0x81, 0x7f, 0x7d, 0x7c, 0x82, 0x89, 0x90, 0x94, 0x94, 0x93, 0x8c, - 0x7c, 0x71, 0x6b, 0x62, 0x5a, 0x56, 0x55, 0x55, 0x54, 0x54, 0x55, 0x55, - 0x55, 0x56, 0x56, 0x59, 0x5d, 0x63, 0x6f, 0x80, 0x8e, 0x95, 0x98, 0x9a, - 0x9c, 0x9d, 0x9c, 0x9b, 0x9c, 0x9b, 0x9a, 0x9b, 0x9b, 0x9d, 0xa1, 0xa4, - 0xa6, 0xa7, 0xa6, 0xa6, 0xa6, 0xa5, 0xa4, 0xa4, 0xa3, 0xa3, 0xa3, 0xa3, - 0xa4, 0xa2, 0x9f, 0x9f, 0x9f, 0xa1, 0xa6, 0xab, 0xad, 0xad, 0xac, 0xaa, - 0x7a, 0x77, 0x74, 0x71, 0x6e, 0x68, 0x62, 0x60, 0x60, 0x61, 0x62, 0x61, - 0x60, 0x5f, 0x5e, 0x5d, 0x5d, 0x5d, 0x5b, 0x59, 0x58, 0x59, 0x59, 0x59, - 0x58, 0x5a, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5e, 0x5e, 0x5e, 0x5f, 0x5e, - 0x60, 0x60, 0x60, 0x61, 0x63, 0x67, 0x69, 0x6b, 0x6e, 0x74, 0x7b, 0x7f, - 0x82, 0x84, 0x87, 0x89, 0x8c, 0x8d, 0x8f, 0x91, 0x91, 0x92, 0x92, 0x92, - 0x93, 0x92, 0x92, 0x93, 0x92, 0x91, 0x8f, 0x8f, 0x8f, 0x90, 0x91, 0x9c, - 0xae, 0xbe, 0xc6, 0xcf, 0xd8, 0xdc, 0xdd, 0xdc, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xdd, 0xc9, 0xb8, 0xb3, 0xb1, 0xae, - 0xac, 0xac, 0xac, 0xac, 0xab, 0xab, 0xa9, 0xa7, 0xa6, 0xa7, 0xa6, 0xa5, - 0xa1, 0xa1, 0xa4, 0xad, 0xb6, 0xbb, 0xbd, 0xbe, 0xbf, 0xc0, 0xc2, 0xc2, - 0xc0, 0xb9, 0xa5, 0x8a, 0x7b, 0x72, 0x77, 0x7e, 0x7f, 0x80, 0x80, 0x7f, - 0x7e, 0x79, 0x78, 0x74, 0x69, 0x5b, 0x55, 0x56, 0x59, 0x5e, 0x64, 0x5f, - 0x54, 0x4a, 0x3e, 0x3f, 0x54, 0x6e, 0x7a, 0x78, 0x5c, 0x59, 0x64, 0x6b, - 0x73, 0x77, 0x78, 0x78, 0x76, 0x73, 0x6e, 0x66, 0x60, 0x5b, 0x57, 0x56, - 0x60, 0x6a, 0x6f, 0x72, 0x7c, 0x8e, 0x98, 0x93, 0x7b, 0x5e, 0x55, 0x63, - 0x72, 0x80, 0x73, 0x55, 0x4e, 0x52, 0x5c, 0x63, 0x56, 0x40, 0x34, 0x2c, - 0x30, 0x37, 0x39, 0x38, 0x37, 0x36, 0x3e, 0x53, 0x5f, 0x61, 0x5d, 0x4f, - 0x42, 0x49, 0x4f, 0x54, 0x54, 0x54, 0x56, 0x5a, 0x60, 0x65, 0x66, 0x68, - 0x68, 0x66, 0x5c, 0x4d, 0x45, 0x47, 0x54, 0x67, 0x71, 0x73, 0x73, 0x71, - 0x6f, 0x6c, 0x69, 0x66, 0x62, 0x65, 0x6e, 0x74, 0x75, 0x70, 0x64, 0x59, - 0x53, 0x55, 0x5f, 0x70, 0x7c, 0x82, 0x83, 0x83, 0x83, 0x81, 0x7e, 0x7c, - 0x7c, 0x80, 0x89, 0x8f, 0x93, 0x94, 0x95, 0x91, 0x86, 0x7a, 0x72, 0x66, - 0x5d, 0x57, 0x55, 0x55, 0x54, 0x54, 0x55, 0x54, 0x55, 0x55, 0x56, 0x5a, - 0x5f, 0x64, 0x6e, 0x7f, 0x8c, 0x91, 0x94, 0x96, 0x98, 0x98, 0x98, 0x98, - 0x99, 0x98, 0x99, 0x99, 0x99, 0x9c, 0x9f, 0xa3, 0xa4, 0xa5, 0xa5, 0xa5, - 0xa4, 0xa3, 0xa3, 0xa2, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x9e, 0x9b, 0x9a, - 0x9a, 0x9c, 0xa1, 0xa6, 0xa9, 0xa9, 0xa7, 0xa4, 0x7d, 0x7a, 0x77, 0x75, - 0x71, 0x6c, 0x65, 0x62, 0x61, 0x61, 0x62, 0x62, 0x61, 0x60, 0x5e, 0x5d, - 0x5c, 0x5c, 0x5b, 0x5a, 0x59, 0x5a, 0x59, 0x59, 0x58, 0x59, 0x5a, 0x5a, - 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x5f, 0x5f, 0x5d, 0x5e, 0x5f, 0x5f, 0x60, - 0x63, 0x66, 0x69, 0x6c, 0x71, 0x77, 0x7e, 0x82, 0x83, 0x86, 0x89, 0x8b, - 0x8d, 0x8e, 0x8f, 0x91, 0x92, 0x93, 0x93, 0x93, 0x92, 0x90, 0x90, 0x91, - 0x91, 0x8f, 0x8d, 0x91, 0x99, 0xa0, 0xac, 0xbd, 0xcd, 0xd5, 0xd8, 0xda, - 0xdc, 0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe2, 0xe3, 0xe1, - 0xe2, 0xe2, 0xe0, 0xd2, 0xbb, 0xb2, 0xaf, 0xab, 0xa9, 0xa9, 0xaa, 0xaa, - 0xa9, 0xa9, 0xa8, 0xa6, 0xa4, 0xa1, 0x9e, 0xa2, 0xa9, 0xaf, 0xb8, 0xc3, - 0xc8, 0xca, 0xc9, 0xc7, 0xc7, 0xc7, 0xc9, 0xca, 0xc9, 0xc9, 0xc1, 0xb2, - 0xa2, 0x87, 0x75, 0x73, 0x6d, 0x73, 0x79, 0x7a, 0x6c, 0x5e, 0x5a, 0x59, - 0x56, 0x54, 0x59, 0x5e, 0x64, 0x6f, 0x7a, 0x78, 0x6c, 0x60, 0x4b, 0x3e, - 0x52, 0x6c, 0x80, 0x8f, 0x70, 0x5b, 0x64, 0x6e, 0x79, 0x7e, 0x80, 0x80, - 0x7d, 0x79, 0x73, 0x6d, 0x66, 0x61, 0x5a, 0x56, 0x5c, 0x68, 0x6e, 0x73, - 0x78, 0x89, 0x9c, 0x9d, 0x88, 0x6c, 0x59, 0x60, 0x6c, 0x7d, 0x76, 0x58, - 0x4f, 0x51, 0x5b, 0x64, 0x5a, 0x48, 0x3c, 0x31, 0x2f, 0x37, 0x3b, 0x3c, - 0x3b, 0x38, 0x38, 0x4a, 0x5a, 0x5f, 0x5c, 0x51, 0x45, 0x4d, 0x53, 0x57, - 0x57, 0x58, 0x5b, 0x5f, 0x65, 0x68, 0x68, 0x69, 0x68, 0x64, 0x58, 0x4a, - 0x46, 0x4a, 0x58, 0x6a, 0x73, 0x74, 0x73, 0x71, 0x6f, 0x6b, 0x66, 0x63, - 0x60, 0x66, 0x6f, 0x71, 0x6f, 0x66, 0x56, 0x4f, 0x4f, 0x54, 0x60, 0x72, - 0x7d, 0x82, 0x83, 0x82, 0x82, 0x7f, 0x7d, 0x7c, 0x7c, 0x7f, 0x88, 0x8e, - 0x92, 0x94, 0x95, 0x93, 0x8b, 0x82, 0x79, 0x6a, 0x5e, 0x58, 0x55, 0x54, - 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x59, 0x5e, 0x62, 0x6b, 0x7c, - 0x8a, 0x8e, 0x91, 0x93, 0x95, 0x96, 0x96, 0x97, 0x98, 0x98, 0x97, 0x97, - 0x98, 0x9b, 0x9e, 0xa2, 0xa4, 0xa4, 0xa5, 0xa4, 0xa3, 0xa3, 0xa2, 0xa0, - 0x9e, 0x9d, 0x9d, 0x9e, 0x9e, 0x9b, 0x99, 0x97, 0x96, 0x98, 0x9b, 0xa1, - 0xa5, 0xa5, 0xa2, 0x9f, 0x80, 0x7c, 0x7a, 0x77, 0x74, 0x6e, 0x68, 0x63, - 0x62, 0x61, 0x62, 0x62, 0x61, 0x60, 0x5e, 0x5d, 0x5c, 0x5c, 0x5b, 0x5a, - 0x5a, 0x5a, 0x5a, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5b, 0x5d, 0x5d, 0x5e, - 0x5f, 0x5f, 0x5f, 0x5d, 0x5d, 0x5e, 0x5f, 0x60, 0x63, 0x66, 0x69, 0x6b, - 0x72, 0x79, 0x7f, 0x83, 0x85, 0x87, 0x8a, 0x8c, 0x8e, 0x8f, 0x8f, 0x91, - 0x91, 0x93, 0x93, 0x93, 0x92, 0x8f, 0x8f, 0x8e, 0x8f, 0x91, 0x94, 0x9e, - 0xaa, 0xb3, 0xc0, 0xcf, 0xd9, 0xdc, 0xdd, 0xdc, 0xdd, 0xdc, 0xdd, 0xde, - 0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe1, 0xe0, 0xd5, - 0xbd, 0xb1, 0xad, 0xa9, 0xa6, 0xa6, 0xa7, 0xa7, 0xa6, 0xa5, 0xa3, 0xa2, - 0xa1, 0xa0, 0xa1, 0xa9, 0xb2, 0xba, 0xc4, 0xcb, 0xcd, 0xcc, 0xcb, 0xca, - 0xca, 0xcc, 0xcd, 0xce, 0xce, 0xce, 0xcb, 0xc6, 0xbb, 0x9f, 0x85, 0x79, - 0x69, 0x6e, 0x76, 0x7d, 0x67, 0x51, 0x4e, 0x4f, 0x53, 0x59, 0x62, 0x6b, - 0x72, 0x7e, 0x89, 0x86, 0x7d, 0x71, 0x5a, 0x45, 0x50, 0x68, 0x7e, 0x98, - 0x82, 0x61, 0x64, 0x6d, 0x7c, 0x84, 0x85, 0x85, 0x83, 0x7e, 0x78, 0x71, - 0x6a, 0x64, 0x5d, 0x57, 0x5a, 0x65, 0x6d, 0x75, 0x77, 0x84, 0x9a, 0x9f, - 0x90, 0x75, 0x5e, 0x60, 0x69, 0x79, 0x76, 0x5a, 0x4f, 0x51, 0x5c, 0x65, - 0x5d, 0x4d, 0x41, 0x34, 0x30, 0x37, 0x3d, 0x3e, 0x3d, 0x3a, 0x38, 0x44, - 0x53, 0x59, 0x58, 0x4f, 0x47, 0x50, 0x55, 0x59, 0x5a, 0x5d, 0x60, 0x63, - 0x68, 0x6a, 0x69, 0x69, 0x67, 0x62, 0x55, 0x49, 0x48, 0x4c, 0x5b, 0x6c, - 0x74, 0x75, 0x73, 0x70, 0x6f, 0x6a, 0x64, 0x61, 0x60, 0x67, 0x6d, 0x6d, - 0x69, 0x5e, 0x4f, 0x4b, 0x4f, 0x55, 0x61, 0x72, 0x7e, 0x82, 0x83, 0x83, - 0x81, 0x7e, 0x7c, 0x7c, 0x7a, 0x7e, 0x86, 0x8d, 0x91, 0x93, 0x95, 0x94, - 0x8f, 0x86, 0x7e, 0x6f, 0x61, 0x59, 0x55, 0x53, 0x53, 0x53, 0x53, 0x55, - 0x55, 0x54, 0x54, 0x57, 0x5c, 0x60, 0x68, 0x79, 0x87, 0x8d, 0x8f, 0x91, - 0x93, 0x95, 0x95, 0x96, 0x97, 0x97, 0x96, 0x96, 0x97, 0x9a, 0x9d, 0xa1, - 0xa3, 0xa4, 0xa5, 0xa4, 0xa2, 0xa2, 0xa1, 0x9f, 0x9c, 0x9b, 0x9c, 0x9c, - 0x9c, 0x99, 0x96, 0x94, 0x93, 0x95, 0x98, 0x9e, 0xa2, 0xa2, 0x9e, 0x9a, - 0x84, 0x80, 0x7d, 0x7b, 0x76, 0x70, 0x6b, 0x66, 0x64, 0x62, 0x63, 0x62, - 0x62, 0x61, 0x60, 0x5e, 0x5c, 0x5c, 0x5b, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, - 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5d, 0x5e, 0x5d, 0x5d, 0x5d, 0x5d, 0x5e, - 0x5e, 0x5e, 0x5f, 0x61, 0x63, 0x65, 0x69, 0x6d, 0x74, 0x7b, 0x81, 0x85, - 0x86, 0x88, 0x8a, 0x8d, 0x8f, 0x8f, 0x8f, 0x90, 0x90, 0x92, 0x92, 0x91, - 0x8f, 0x8e, 0x8e, 0x90, 0x95, 0xa0, 0xb0, 0xc0, 0xca, 0xcf, 0xd5, 0xda, - 0xdc, 0xdc, 0xdc, 0xdd, 0xdf, 0xdf, 0xdf, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, - 0xe1, 0xe2, 0xe1, 0xdf, 0xe0, 0xdf, 0xdd, 0xd3, 0xc0, 0xb2, 0xac, 0xa8, - 0xa5, 0xa4, 0xa2, 0xa1, 0xa0, 0x9d, 0x9c, 0x9f, 0xa1, 0xa7, 0xb0, 0xbc, - 0xc3, 0xc7, 0xcc, 0xce, 0xcd, 0xcc, 0xcc, 0xce, 0xd1, 0xd3, 0xd2, 0xd2, - 0xd2, 0xd1, 0xcf, 0xce, 0xcb, 0xc0, 0xaa, 0x95, 0x7a, 0x72, 0x7c, 0x8e, - 0x77, 0x55, 0x4f, 0x53, 0x5f, 0x6b, 0x7a, 0x87, 0x8e, 0x94, 0x99, 0x97, - 0x91, 0x89, 0x75, 0x57, 0x51, 0x62, 0x76, 0x97, 0x9b, 0x73, 0x67, 0x6c, - 0x7d, 0x89, 0x8c, 0x8b, 0x8a, 0x85, 0x80, 0x76, 0x6f, 0x69, 0x62, 0x59, - 0x58, 0x5f, 0x68, 0x75, 0x77, 0x7e, 0x92, 0x9c, 0x9c, 0x81, 0x68, 0x61, - 0x64, 0x72, 0x75, 0x5d, 0x51, 0x51, 0x5b, 0x66, 0x60, 0x51, 0x46, 0x3a, - 0x34, 0x39, 0x3f, 0x40, 0x40, 0x3e, 0x3a, 0x3d, 0x47, 0x4c, 0x4f, 0x4b, - 0x4a, 0x54, 0x5a, 0x5c, 0x5f, 0x65, 0x68, 0x6a, 0x6c, 0x6c, 0x69, 0x67, - 0x65, 0x5e, 0x51, 0x48, 0x4b, 0x52, 0x61, 0x6f, 0x75, 0x73, 0x71, 0x6f, - 0x6d, 0x67, 0x61, 0x5f, 0x60, 0x67, 0x69, 0x64, 0x5e, 0x54, 0x49, 0x4a, - 0x50, 0x57, 0x64, 0x74, 0x7f, 0x82, 0x83, 0x82, 0x80, 0x7e, 0x7c, 0x7b, - 0x79, 0x7b, 0x83, 0x8c, 0x90, 0x92, 0x94, 0x95, 0x92, 0x8d, 0x87, 0x79, - 0x69, 0x5d, 0x57, 0x54, 0x52, 0x51, 0x52, 0x53, 0x54, 0x53, 0x53, 0x55, - 0x59, 0x5c, 0x64, 0x73, 0x83, 0x89, 0x8c, 0x8f, 0x90, 0x93, 0x93, 0x94, - 0x94, 0x94, 0x95, 0x94, 0x95, 0x98, 0x9b, 0x9f, 0xa0, 0xa1, 0xa3, 0xa3, - 0xa1, 0xa0, 0x9f, 0x9d, 0x9a, 0x99, 0x9a, 0x9b, 0x9a, 0x96, 0x93, 0x91, - 0x90, 0x91, 0x94, 0x99, 0x9b, 0x9b, 0x98, 0x94, 0x87, 0x84, 0x80, 0x7e, - 0x7b, 0x75, 0x6f, 0x68, 0x65, 0x63, 0x64, 0x62, 0x62, 0x62, 0x61, 0x5f, - 0x5d, 0x5c, 0x5c, 0x5b, 0x5c, 0x5a, 0x59, 0x59, 0x5a, 0x5c, 0x5c, 0x5b, - 0x5b, 0x5c, 0x5d, 0x5d, 0x5d, 0x5c, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, - 0x64, 0x67, 0x6b, 0x6f, 0x77, 0x7d, 0x82, 0x85, 0x87, 0x8a, 0x8c, 0x8e, - 0x8e, 0x8e, 0x8f, 0x90, 0x8f, 0x8f, 0x8e, 0x8e, 0x8f, 0x96, 0xa0, 0xa9, - 0xb8, 0xc7, 0xd2, 0xd8, 0xda, 0xdb, 0xdc, 0xdd, 0xdd, 0xdd, 0xde, 0xdf, - 0xdf, 0xe0, 0xdf, 0xdf, 0xe0, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, - 0xe0, 0xde, 0xdb, 0xd2, 0xc8, 0xc1, 0xbc, 0xb6, 0xb3, 0xaf, 0xac, 0xaa, - 0xa7, 0xaa, 0xaf, 0xb4, 0xb8, 0xbc, 0xc1, 0xc8, 0xcc, 0xcd, 0xce, 0xcf, - 0xcf, 0xcf, 0xd0, 0xd2, 0xd6, 0xd8, 0xd7, 0xd6, 0xd6, 0xd6, 0xd4, 0xd3, - 0xd2, 0xd0, 0xc8, 0xb8, 0x9c, 0x86, 0x8a, 0xa5, 0xa5, 0x76, 0x5c, 0x5c, - 0x73, 0x8a, 0x99, 0xa2, 0xa6, 0xa8, 0xa9, 0xa6, 0xa1, 0x9b, 0x8f, 0x75, - 0x5d, 0x60, 0x6c, 0x88, 0xa9, 0x97, 0x76, 0x6d, 0x79, 0x8c, 0x93, 0x93, - 0x91, 0x8d, 0x88, 0x7f, 0x77, 0x71, 0x69, 0x5f, 0x58, 0x59, 0x61, 0x73, - 0x7b, 0x7a, 0x85, 0x92, 0xa1, 0x93, 0x78, 0x69, 0x66, 0x6d, 0x73, 0x60, - 0x52, 0x51, 0x5a, 0x66, 0x65, 0x57, 0x4d, 0x42, 0x3d, 0x40, 0x44, 0x45, - 0x44, 0x41, 0x3e, 0x3b, 0x3d, 0x40, 0x44, 0x46, 0x4e, 0x5b, 0x61, 0x62, - 0x65, 0x6d, 0x6f, 0x6f, 0x6f, 0x6d, 0x6a, 0x66, 0x62, 0x5a, 0x4e, 0x48, - 0x4f, 0x59, 0x68, 0x73, 0x75, 0x70, 0x6d, 0x6c, 0x6c, 0x65, 0x5f, 0x5e, - 0x61, 0x66, 0x61, 0x56, 0x4f, 0x4a, 0x49, 0x4e, 0x53, 0x5a, 0x68, 0x77, - 0x80, 0x82, 0x82, 0x82, 0x80, 0x7d, 0x7b, 0x7a, 0x78, 0x7a, 0x81, 0x8a, - 0x8e, 0x91, 0x93, 0x96, 0x94, 0x91, 0x8e, 0x85, 0x74, 0x67, 0x5f, 0x5b, - 0x57, 0x54, 0x53, 0x53, 0x53, 0x54, 0x54, 0x57, 0x5a, 0x5d, 0x63, 0x70, - 0x7e, 0x86, 0x88, 0x8b, 0x8f, 0x90, 0x90, 0x90, 0x91, 0x92, 0x94, 0x94, - 0x94, 0x95, 0x98, 0x9d, 0x9f, 0xa0, 0xa0, 0xa1, 0xa0, 0x9f, 0x9d, 0x9b, - 0x98, 0x97, 0x99, 0x99, 0x97, 0x94, 0x91, 0x8e, 0x8d, 0x8d, 0x90, 0x93, - 0x94, 0x94, 0x91, 0x8d, 0x8a, 0x86, 0x83, 0x81, 0x7e, 0x78, 0x71, 0x6b, - 0x68, 0x65, 0x65, 0x63, 0x61, 0x61, 0x60, 0x60, 0x5d, 0x5d, 0x5d, 0x5d, - 0x5c, 0x5a, 0x5a, 0x5a, 0x5c, 0x5d, 0x5c, 0x5c, 0x5c, 0x5c, 0x5d, 0x5e, - 0x5d, 0x5c, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x62, 0x65, 0x68, 0x6d, 0x71, - 0x78, 0x7e, 0x83, 0x86, 0x88, 0x8b, 0x8c, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, - 0x8d, 0x8e, 0x91, 0x99, 0xaa, 0xbe, 0xcb, 0xd1, 0xd6, 0xda, 0xdb, 0xdc, - 0xdc, 0xdc, 0xdd, 0xdd, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xde, - 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe1, 0xe2, 0xe2, 0xe3, 0xe1, 0xdd, - 0xd8, 0xd6, 0xd4, 0xd1, 0xcf, 0xcd, 0xcb, 0xca, 0xc8, 0xc4, 0xc4, 0xc2, - 0xc2, 0xc2, 0xc5, 0xc8, 0xca, 0xcb, 0xcc, 0xce, 0xcf, 0xd2, 0xd4, 0xd5, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, 0xd9, 0xd8, 0xd7, 0xd6, 0xd4, 0xd1, 0xcc, - 0xbd, 0xa7, 0x9c, 0x9d, 0xb6, 0xa3, 0x76, 0x6b, 0x80, 0xa0, 0xaf, 0xb3, - 0xb4, 0xb3, 0xb2, 0xae, 0xa9, 0xa5, 0x9d, 0x8d, 0x75, 0x67, 0x68, 0x7b, - 0xa2, 0xb3, 0x99, 0x84, 0x74, 0x86, 0x95, 0x99, 0x98, 0x95, 0x90, 0x8b, - 0x82, 0x7c, 0x72, 0x66, 0x5c, 0x57, 0x5b, 0x6a, 0x7d, 0x7c, 0x7e, 0x87, - 0x9b, 0xa1, 0x8a, 0x7a, 0x74, 0x72, 0x71, 0x60, 0x52, 0x51, 0x5a, 0x66, - 0x68, 0x5d, 0x55, 0x49, 0x46, 0x4b, 0x4e, 0x4d, 0x4a, 0x45, 0x3f, 0x3b, - 0x3a, 0x3b, 0x3f, 0x4a, 0x59, 0x64, 0x68, 0x68, 0x6a, 0x6f, 0x70, 0x70, - 0x70, 0x6c, 0x68, 0x61, 0x5d, 0x55, 0x49, 0x49, 0x56, 0x60, 0x6d, 0x74, - 0x72, 0x6c, 0x6a, 0x6b, 0x69, 0x62, 0x5e, 0x5e, 0x62, 0x63, 0x57, 0x4c, - 0x49, 0x4a, 0x4d, 0x52, 0x58, 0x5f, 0x6b, 0x77, 0x7e, 0x80, 0x81, 0x80, - 0x7f, 0x7e, 0x7c, 0x7a, 0x78, 0x79, 0x7f, 0x87, 0x8c, 0x8f, 0x92, 0x95, - 0x96, 0x94, 0x92, 0x8c, 0x7f, 0x70, 0x68, 0x64, 0x5e, 0x5b, 0x59, 0x58, - 0x59, 0x59, 0x5b, 0x5c, 0x5d, 0x5f, 0x65, 0x70, 0x7d, 0x85, 0x88, 0x8b, - 0x8d, 0x8f, 0x90, 0x8f, 0x90, 0x91, 0x93, 0x94, 0x94, 0x94, 0x96, 0x9a, - 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0x9e, 0x9d, 0x9b, 0x98, 0x97, 0x97, 0x97, - 0x96, 0x94, 0x90, 0x8d, 0x8c, 0x8b, 0x8e, 0x8f, 0x8e, 0x8d, 0x8c, 0x88, - 0x8c, 0x89, 0x86, 0x84, 0x82, 0x7b, 0x75, 0x6e, 0x6b, 0x67, 0x65, 0x65, - 0x62, 0x61, 0x60, 0x60, 0x5f, 0x5e, 0x5e, 0x5d, 0x5d, 0x5c, 0x5c, 0x5c, - 0x5d, 0x5d, 0x5c, 0x5d, 0x5d, 0x5c, 0x5e, 0x5e, 0x5e, 0x5d, 0x5c, 0x5d, - 0x5d, 0x5e, 0x5f, 0x62, 0x65, 0x69, 0x6f, 0x74, 0x7a, 0x7f, 0x84, 0x87, - 0x89, 0x8b, 0x8c, 0x8e, 0x8e, 0x8d, 0x8c, 0x8b, 0x8f, 0x9c, 0xa8, 0xb9, - 0xcb, 0xd5, 0xda, 0xdb, 0xdc, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdd, - 0xdf, 0xde, 0xdf, 0xdf, 0xdf, 0xde, 0xdf, 0xdf, 0xdf, 0xe1, 0xe1, 0xe2, - 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe0, 0xdd, 0xdc, 0xdc, 0xda, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd6, 0xd3, 0xd2, 0xd2, 0xd0, 0xcd, 0xcc, 0xc9, - 0xc7, 0xc8, 0xc9, 0xcd, 0xd0, 0xd5, 0xd7, 0xd8, 0xd9, 0xd9, 0xda, 0xda, - 0xd9, 0xda, 0xd9, 0xd9, 0xd9, 0xd6, 0xd4, 0xd3, 0xcd, 0xc1, 0xb3, 0xa0, - 0xab, 0xb6, 0x93, 0x80, 0x82, 0xa5, 0xb8, 0xba, 0xba, 0xb8, 0xb5, 0xb1, - 0xad, 0xa9, 0xa4, 0x99, 0x85, 0x70, 0x6b, 0x77, 0x98, 0xb7, 0xb4, 0xa0, - 0x7c, 0x7f, 0x93, 0x9b, 0x9c, 0x9b, 0x97, 0x91, 0x89, 0x83, 0x79, 0x6d, - 0x61, 0x59, 0x58, 0x63, 0x7c, 0x7f, 0x7e, 0x82, 0x92, 0xa4, 0x98, 0x88, - 0x80, 0x7b, 0x74, 0x60, 0x53, 0x51, 0x5a, 0x65, 0x6a, 0x62, 0x5a, 0x4e, - 0x4a, 0x51, 0x56, 0x52, 0x4d, 0x46, 0x3d, 0x3a, 0x3a, 0x3c, 0x45, 0x57, - 0x66, 0x6d, 0x6e, 0x6b, 0x6d, 0x6f, 0x70, 0x70, 0x71, 0x6d, 0x65, 0x5e, - 0x59, 0x51, 0x47, 0x4c, 0x5a, 0x64, 0x6e, 0x74, 0x6f, 0x69, 0x67, 0x69, - 0x66, 0x5f, 0x5d, 0x5f, 0x63, 0x5f, 0x51, 0x4a, 0x49, 0x4c, 0x4f, 0x55, - 0x5b, 0x61, 0x6c, 0x77, 0x7d, 0x7f, 0x80, 0x80, 0x7f, 0x7e, 0x7c, 0x7a, - 0x77, 0x78, 0x7e, 0x86, 0x8a, 0x8d, 0x91, 0x94, 0x97, 0x97, 0x95, 0x90, - 0x86, 0x77, 0x6e, 0x69, 0x63, 0x5f, 0x5e, 0x5e, 0x5e, 0x5e, 0x5f, 0x5e, - 0x5f, 0x62, 0x67, 0x71, 0x7d, 0x84, 0x88, 0x8a, 0x8c, 0x8e, 0x8f, 0x8f, - 0x90, 0x91, 0x92, 0x92, 0x92, 0x93, 0x95, 0x97, 0x9a, 0x9b, 0x9d, 0x9d, - 0x9e, 0x9d, 0x9d, 0x9a, 0x97, 0x96, 0x97, 0x97, 0x95, 0x94, 0x91, 0x8e, - 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x88, 0x84, 0x8d, 0x8a, 0x89, 0x87, - 0x83, 0x7d, 0x77, 0x70, 0x6c, 0x68, 0x65, 0x65, 0x63, 0x62, 0x61, 0x61, - 0x60, 0x5f, 0x5f, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5c, 0x5d, - 0x5d, 0x5d, 0x5d, 0x5e, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x61, - 0x65, 0x6a, 0x70, 0x75, 0x7a, 0x7f, 0x84, 0x88, 0x88, 0x8a, 0x8b, 0x8d, - 0x8d, 0x8c, 0x8b, 0x8d, 0x9a, 0xae, 0xbb, 0xcc, 0xd7, 0xdb, 0xdb, 0xdc, - 0xdc, 0xdb, 0xdc, 0xdc, 0xdc, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xdf, 0xdf, - 0xe0, 0xdf, 0xe0, 0xe0, 0xe0, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe3, 0xe2, 0xe1, 0xe0, 0xde, 0xdd, 0xdc, 0xdc, 0xda, 0xda, 0xdb, 0xdb, - 0xda, 0xd8, 0xd9, 0xd8, 0xd7, 0xd4, 0xd2, 0xce, 0xcb, 0xcb, 0xcb, 0xce, - 0xd1, 0xd5, 0xd7, 0xd8, 0xda, 0xd9, 0xdb, 0xdb, 0xda, 0xdb, 0xda, 0xda, - 0xda, 0xd8, 0xd5, 0xd4, 0xd2, 0xcb, 0xbf, 0xa8, 0xa5, 0xb8, 0xa3, 0x8f, - 0x83, 0xa3, 0xba, 0xbd, 0xbd, 0xbb, 0xb7, 0xb3, 0xaf, 0xab, 0xa7, 0x9e, - 0x8d, 0x79, 0x70, 0x74, 0x91, 0xb4, 0xbf, 0xb1, 0x8a, 0x7c, 0x8e, 0x99, - 0x9c, 0x9d, 0x9a, 0x94, 0x8d, 0x87, 0x7c, 0x71, 0x65, 0x5c, 0x59, 0x5f, - 0x78, 0x80, 0x7e, 0x80, 0x8d, 0xa3, 0x9f, 0x91, 0x89, 0x82, 0x77, 0x60, - 0x53, 0x52, 0x59, 0x64, 0x6a, 0x65, 0x5d, 0x51, 0x4c, 0x53, 0x59, 0x57, - 0x52, 0x47, 0x39, 0x36, 0x3c, 0x43, 0x4f, 0x63, 0x6e, 0x70, 0x6f, 0x6d, - 0x6f, 0x6f, 0x6f, 0x70, 0x71, 0x6c, 0x63, 0x5b, 0x56, 0x4e, 0x47, 0x4f, - 0x5e, 0x67, 0x6f, 0x73, 0x6e, 0x68, 0x66, 0x67, 0x64, 0x5e, 0x5e, 0x60, - 0x64, 0x5d, 0x4e, 0x4a, 0x4a, 0x4e, 0x51, 0x57, 0x5e, 0x64, 0x6e, 0x77, - 0x7d, 0x7f, 0x80, 0x7f, 0x7e, 0x7d, 0x7b, 0x79, 0x77, 0x77, 0x7d, 0x84, - 0x89, 0x8b, 0x90, 0x94, 0x97, 0x97, 0x96, 0x93, 0x8a, 0x7c, 0x73, 0x6d, - 0x66, 0x62, 0x61, 0x61, 0x61, 0x60, 0x61, 0x61, 0x62, 0x64, 0x68, 0x72, - 0x7d, 0x84, 0x88, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x91, 0x91, 0x91, 0x91, - 0x91, 0x92, 0x95, 0x96, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9b, 0x9b, 0x99, - 0x97, 0x96, 0x97, 0x97, 0x95, 0x94, 0x91, 0x8e, 0x8d, 0x8c, 0x8c, 0x8b, - 0x8a, 0x89, 0x87, 0x82, 0x90, 0x8d, 0x8a, 0x88, 0x85, 0x80, 0x77, 0x72, - 0x6f, 0x69, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x5f, 0x5e, 0x5d, 0x5d, - 0x5d, 0x5c, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5c, - 0x5e, 0x5e, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e, 0x61, 0x66, 0x6c, 0x72, 0x76, - 0x7b, 0x80, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x89, 0x89, 0x8d, 0x9d, - 0xba, 0xcd, 0xd4, 0xd9, 0xdb, 0xdc, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdd, - 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xe0, 0xe1, 0xe1, 0xe1, - 0xe1, 0xe2, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xdf, - 0xdd, 0xdd, 0xdc, 0xdc, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, - 0xda, 0xda, 0xd8, 0xd7, 0xd7, 0xd6, 0xd4, 0xd2, 0xd2, 0xd4, 0xd5, 0xd7, - 0xd9, 0xd9, 0xdb, 0xdb, 0xdb, 0xda, 0xdb, 0xdb, 0xdb, 0xda, 0xd7, 0xd5, - 0xd3, 0xd1, 0xcb, 0xba, 0xa6, 0xae, 0xb1, 0xa3, 0x88, 0x9c, 0xb8, 0xc0, - 0xc0, 0xbe, 0xb9, 0xb5, 0xb1, 0xaf, 0xac, 0xa3, 0x95, 0x86, 0x7b, 0x73, - 0x87, 0xa9, 0xc0, 0xbf, 0xa3, 0x7e, 0x84, 0x8e, 0x95, 0x9b, 0x9c, 0x98, - 0x92, 0x8c, 0x83, 0x77, 0x6c, 0x62, 0x5c, 0x5c, 0x6d, 0x7e, 0x80, 0x80, - 0x88, 0x9e, 0xa5, 0x9f, 0x99, 0x8f, 0x7d, 0x60, 0x53, 0x52, 0x57, 0x61, - 0x68, 0x66, 0x61, 0x56, 0x50, 0x55, 0x5b, 0x5c, 0x59, 0x4b, 0x34, 0x32, - 0x47, 0x55, 0x65, 0x74, 0x76, 0x72, 0x6f, 0x6f, 0x73, 0x71, 0x70, 0x70, - 0x71, 0x6a, 0x60, 0x58, 0x53, 0x4c, 0x49, 0x55, 0x64, 0x6b, 0x71, 0x72, - 0x6c, 0x65, 0x63, 0x64, 0x61, 0x5d, 0x60, 0x63, 0x63, 0x5a, 0x4d, 0x4b, - 0x4d, 0x4f, 0x53, 0x5b, 0x64, 0x6a, 0x71, 0x78, 0x7d, 0x7f, 0x7f, 0x7f, - 0x7d, 0x7c, 0x7a, 0x78, 0x76, 0x75, 0x7b, 0x83, 0x87, 0x8a, 0x8e, 0x93, - 0x97, 0x98, 0x98, 0x96, 0x8e, 0x84, 0x7a, 0x74, 0x6c, 0x66, 0x65, 0x64, - 0x63, 0x63, 0x64, 0x64, 0x66, 0x68, 0x6d, 0x75, 0x7f, 0x85, 0x88, 0x8b, - 0x8e, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x90, 0x93, 0x95, - 0x97, 0x98, 0x99, 0x9b, 0x9b, 0x99, 0x98, 0x98, 0x97, 0x95, 0x96, 0x95, - 0x95, 0x94, 0x92, 0x8f, 0x8e, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x87, 0x82, - 0x91, 0x8e, 0x8d, 0x8b, 0x88, 0x83, 0x7c, 0x76, 0x72, 0x6b, 0x67, 0x66, - 0x65, 0x64, 0x63, 0x62, 0x5f, 0x5e, 0x5d, 0x5e, 0x5d, 0x5d, 0x5c, 0x5c, - 0x5c, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5c, 0x5d, 0x5d, 0x5c, 0x5e, - 0x5f, 0x5e, 0x5f, 0x63, 0x68, 0x6e, 0x72, 0x76, 0x7b, 0x80, 0x84, 0x85, - 0x86, 0x87, 0x87, 0x86, 0x89, 0x91, 0xa6, 0xc5, 0xd7, 0xdb, 0xdc, 0xdb, - 0xdb, 0xdd, 0xdc, 0xdd, 0xdc, 0xdd, 0xdd, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe1, 0xe1, 0xe1, 0xe0, 0xe1, 0xe0, 0xdf, 0xdf, 0xde, 0xdd, 0xdc, 0xdb, - 0xda, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, 0xd9, - 0xdb, 0xdc, 0xdc, 0xda, 0xd7, 0xd6, 0xd6, 0xd6, 0xd8, 0xd9, 0xda, 0xda, - 0xdb, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xd9, 0xd6, 0xd5, 0xd3, 0xd1, 0xcc, - 0xb9, 0xa9, 0xb1, 0xac, 0x94, 0x8e, 0xad, 0xbc, 0xc0, 0xc0, 0xbc, 0xb8, - 0xb5, 0xb3, 0xaf, 0xa9, 0x9f, 0x94, 0x8a, 0x7b, 0x7b, 0x98, 0xb4, 0xbe, - 0xba, 0x92, 0x79, 0x78, 0x81, 0x94, 0x9e, 0x9d, 0x99, 0x94, 0x8d, 0x80, - 0x73, 0x6a, 0x64, 0x5c, 0x62, 0x77, 0x82, 0x84, 0x85, 0x97, 0xa6, 0xa7, - 0xa5, 0x9e, 0x88, 0x61, 0x54, 0x54, 0x58, 0x5d, 0x64, 0x66, 0x64, 0x5d, - 0x56, 0x58, 0x5d, 0x60, 0x5e, 0x50, 0x37, 0x3d, 0x5f, 0x71, 0x7c, 0x81, - 0x7a, 0x72, 0x71, 0x73, 0x76, 0x72, 0x70, 0x6f, 0x6e, 0x65, 0x5c, 0x55, - 0x50, 0x4a, 0x4c, 0x5d, 0x6a, 0x70, 0x73, 0x71, 0x69, 0x64, 0x63, 0x62, - 0x5c, 0x5e, 0x63, 0x65, 0x62, 0x55, 0x4e, 0x4f, 0x50, 0x52, 0x57, 0x60, - 0x6b, 0x70, 0x75, 0x79, 0x7d, 0x7e, 0x7e, 0x7e, 0x7e, 0x7b, 0x79, 0x77, - 0x74, 0x74, 0x78, 0x81, 0x86, 0x89, 0x8c, 0x93, 0x96, 0x99, 0x9a, 0x98, - 0x92, 0x8a, 0x82, 0x7d, 0x74, 0x6d, 0x69, 0x68, 0x68, 0x69, 0x6a, 0x6c, - 0x70, 0x72, 0x76, 0x7b, 0x82, 0x86, 0x88, 0x89, 0x8d, 0x90, 0x90, 0x90, - 0x91, 0x90, 0x90, 0x90, 0x90, 0x8f, 0x91, 0x92, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x97, 0x96, 0x96, 0x95, 0x93, 0x92, 0x93, 0x93, 0x93, 0x92, 0x8f, - 0x8f, 0x90, 0x8f, 0x8d, 0x8d, 0x8b, 0x88, 0x84, 0x93, 0x90, 0x8e, 0x8c, - 0x89, 0x84, 0x7e, 0x79, 0x74, 0x6e, 0x69, 0x67, 0x66, 0x64, 0x63, 0x62, - 0x60, 0x5e, 0x5d, 0x5e, 0x5d, 0x5c, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, - 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5c, 0x5d, 0x5f, 0x60, 0x60, 0x60, 0x63, - 0x69, 0x6f, 0x74, 0x77, 0x7b, 0x80, 0x84, 0x86, 0x86, 0x85, 0x85, 0x93, - 0xab, 0xbb, 0xce, 0xda, 0xdc, 0xdb, 0xdc, 0xdc, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdc, 0xdc, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe1, 0xe1, 0xe0, 0xe0, 0xe1, - 0xe0, 0xe0, 0xdf, 0xdf, 0xde, 0xdd, 0xdd, 0xdd, 0xdb, 0xda, 0xd9, 0xd9, - 0xd9, 0xd8, 0xd9, 0xd8, 0xd7, 0xd7, 0xd6, 0xd7, 0xd9, 0xd9, 0xd9, 0xda, - 0xdb, 0xda, 0xda, 0xda, 0xd8, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdb, 0xda, - 0xda, 0xd9, 0xd9, 0xd7, 0xd7, 0xd5, 0xd4, 0xd2, 0xca, 0xb9, 0xad, 0xa9, - 0x9f, 0x86, 0x9c, 0xb3, 0xbc, 0xbf, 0xbe, 0xba, 0xb8, 0xb6, 0xb3, 0xad, - 0xa5, 0x9d, 0x96, 0x88, 0x77, 0x82, 0x9e, 0xb1, 0xc0, 0xae, 0x84, 0x75, - 0x78, 0x88, 0x9b, 0xa1, 0x9e, 0x9b, 0x95, 0x88, 0x7b, 0x72, 0x6c, 0x62, - 0x5e, 0x6d, 0x7c, 0x81, 0x84, 0x91, 0xa2, 0xa8, 0xa9, 0xa5, 0x90, 0x64, - 0x56, 0x55, 0x57, 0x5b, 0x61, 0x65, 0x66, 0x62, 0x5c, 0x5c, 0x60, 0x62, - 0x5f, 0x52, 0x41, 0x59, 0x77, 0x84, 0x86, 0x82, 0x7a, 0x74, 0x74, 0x78, - 0x79, 0x73, 0x70, 0x6f, 0x6a, 0x61, 0x59, 0x52, 0x4d, 0x48, 0x52, 0x64, - 0x6f, 0x73, 0x74, 0x70, 0x68, 0x64, 0x62, 0x5f, 0x5b, 0x60, 0x65, 0x65, - 0x5e, 0x52, 0x51, 0x52, 0x53, 0x56, 0x5c, 0x67, 0x71, 0x75, 0x78, 0x7a, - 0x7b, 0x7c, 0x7d, 0x7e, 0x7e, 0x7b, 0x78, 0x75, 0x73, 0x72, 0x76, 0x7e, - 0x84, 0x88, 0x8d, 0x93, 0x97, 0x9b, 0x9c, 0x9c, 0x97, 0x90, 0x8a, 0x86, - 0x7e, 0x76, 0x70, 0x6e, 0x6e, 0x70, 0x73, 0x77, 0x7c, 0x7f, 0x80, 0x83, - 0x85, 0x87, 0x89, 0x89, 0x8d, 0x8f, 0x90, 0x90, 0x91, 0x90, 0x90, 0x90, - 0x8f, 0x8e, 0x8f, 0x91, 0x92, 0x93, 0x95, 0x96, 0x96, 0x94, 0x93, 0x92, - 0x92, 0x90, 0x8f, 0x90, 0x91, 0x93, 0x93, 0x91, 0x90, 0x91, 0x90, 0x8f, - 0x8d, 0x8c, 0x8a, 0x87, 0x95, 0x91, 0x90, 0x8e, 0x8b, 0x87, 0x80, 0x7a, - 0x76, 0x6f, 0x69, 0x68, 0x66, 0x64, 0x63, 0x63, 0x62, 0x5f, 0x5f, 0x5f, - 0x5e, 0x5d, 0x5d, 0x5d, 0x5d, 0x5e, 0x5d, 0x5d, 0x5d, 0x5c, 0x5d, 0x5d, - 0x5c, 0x5c, 0x5d, 0x5e, 0x60, 0x5f, 0x60, 0x62, 0x68, 0x70, 0x74, 0x77, - 0x7b, 0x80, 0x83, 0x84, 0x83, 0x80, 0x8d, 0xb4, 0xcd, 0xd8, 0xdd, 0xdd, - 0xdc, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xde, 0xde, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xdf, 0xde, 0xde, 0xde, - 0xde, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe1, 0xe1, 0xe1, 0xe0, 0xdf, 0xde, 0xdd, 0xdd, 0xdc, 0xda, 0xda, 0xd8, - 0xd8, 0xd7, 0xd6, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xda, 0xdb, 0xdc, - 0xdb, 0xd9, 0xd8, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xd8, 0xd6, - 0xd7, 0xd6, 0xd4, 0xd3, 0xcf, 0xc4, 0xb7, 0xaf, 0xa3, 0x8a, 0x8e, 0xaa, - 0xb8, 0xbf, 0xbe, 0xbb, 0xb8, 0xb7, 0xb4, 0xaf, 0xa8, 0xa2, 0x9c, 0x92, - 0x7f, 0x76, 0x8b, 0x9f, 0xba, 0xbe, 0x9f, 0x8b, 0x81, 0x7e, 0x94, 0xa2, - 0xa1, 0x9e, 0x98, 0x8e, 0x82, 0x77, 0x72, 0x69, 0x5f, 0x66, 0x74, 0x7c, - 0x83, 0x8e, 0xa0, 0xa9, 0xab, 0xa8, 0x93, 0x68, 0x58, 0x55, 0x58, 0x5a, - 0x60, 0x64, 0x65, 0x64, 0x60, 0x5f, 0x62, 0x63, 0x5f, 0x53, 0x4a, 0x6c, - 0x84, 0x8a, 0x86, 0x81, 0x7a, 0x78, 0x78, 0x7b, 0x7a, 0x74, 0x71, 0x6d, - 0x67, 0x5e, 0x58, 0x4f, 0x4a, 0x4a, 0x5a, 0x6a, 0x72, 0x74, 0x74, 0x6e, - 0x67, 0x63, 0x60, 0x5c, 0x5b, 0x62, 0x66, 0x65, 0x5c, 0x53, 0x52, 0x55, - 0x56, 0x5a, 0x61, 0x6c, 0x74, 0x77, 0x78, 0x7a, 0x7a, 0x7b, 0x7d, 0x7e, - 0x7d, 0x7a, 0x76, 0x74, 0x72, 0x71, 0x75, 0x7d, 0x84, 0x88, 0x8d, 0x94, - 0x99, 0x9c, 0x9d, 0x9d, 0x9a, 0x94, 0x8e, 0x8a, 0x83, 0x7c, 0x77, 0x75, - 0x75, 0x76, 0x7a, 0x7e, 0x82, 0x85, 0x86, 0x88, 0x87, 0x88, 0x88, 0x8a, - 0x8b, 0x8e, 0x8e, 0x8f, 0x90, 0x8f, 0x90, 0x8f, 0x8e, 0x8e, 0x8e, 0x90, - 0x91, 0x92, 0x93, 0x95, 0x94, 0x92, 0x91, 0x90, 0x90, 0x8f, 0x8f, 0x8f, - 0x91, 0x92, 0x92, 0x92, 0x92, 0x92, 0x90, 0x8f, 0x8d, 0x8c, 0x8a, 0x88, - 0x95, 0x92, 0x91, 0x8f, 0x8c, 0x88, 0x81, 0x7b, 0x76, 0x6f, 0x6a, 0x68, - 0x65, 0x64, 0x63, 0x63, 0x62, 0x60, 0x5f, 0x5f, 0x5e, 0x5e, 0x5d, 0x5d, - 0x5d, 0x5e, 0x5d, 0x5d, 0x5c, 0x5d, 0x5c, 0x5d, 0x5c, 0x5c, 0x5d, 0x5d, - 0x5f, 0x60, 0x61, 0x62, 0x68, 0x70, 0x75, 0x78, 0x7b, 0x7f, 0x81, 0x81, - 0x81, 0x84, 0x9e, 0xc8, 0xda, 0xdf, 0xdf, 0xdd, 0xdc, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe1, 0xe1, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe3, 0xe2, 0xe2, - 0xe1, 0xe1, 0xe0, 0xe0, 0xdf, 0xdd, 0xdc, 0xda, 0xd9, 0xd8, 0xd7, 0xd8, - 0xd7, 0xd7, 0xd7, 0xd6, 0xd6, 0xd8, 0xda, 0xdc, 0xdc, 0xd9, 0xd9, 0xd9, - 0xda, 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xd8, 0xd6, 0xd7, 0xd6, 0xd5, 0xd3, - 0xd1, 0xca, 0xbe, 0xb6, 0xa8, 0x8e, 0x87, 0xa2, 0xb3, 0xbd, 0xbe, 0xbc, - 0xb9, 0xb8, 0xb5, 0xb1, 0xab, 0xa5, 0xa0, 0x97, 0x85, 0x75, 0x7f, 0x91, - 0xb0, 0xc1, 0xb0, 0x9d, 0x8d, 0x7c, 0x8f, 0xa0, 0xa2, 0xa0, 0x9b, 0x91, - 0x86, 0x7c, 0x76, 0x6e, 0x62, 0x63, 0x6f, 0x78, 0x82, 0x8c, 0x9f, 0xa9, - 0xac, 0xa8, 0x94, 0x6b, 0x5a, 0x56, 0x58, 0x5a, 0x5f, 0x63, 0x65, 0x65, - 0x62, 0x60, 0x63, 0x63, 0x5e, 0x53, 0x51, 0x76, 0x88, 0x8b, 0x86, 0x81, - 0x7b, 0x7b, 0x7c, 0x7d, 0x7a, 0x74, 0x70, 0x6c, 0x64, 0x5b, 0x57, 0x4e, - 0x4a, 0x4c, 0x5e, 0x6e, 0x74, 0x75, 0x73, 0x6d, 0x66, 0x62, 0x5f, 0x5b, - 0x5b, 0x63, 0x66, 0x63, 0x5a, 0x54, 0x54, 0x56, 0x58, 0x5c, 0x64, 0x6f, - 0x76, 0x78, 0x78, 0x7a, 0x7a, 0x7b, 0x7c, 0x7e, 0x7d, 0x7a, 0x76, 0x74, - 0x72, 0x71, 0x75, 0x7d, 0x85, 0x89, 0x8e, 0x94, 0x9a, 0x9d, 0x9e, 0x9d, - 0x9a, 0x95, 0x90, 0x8c, 0x86, 0x80, 0x7b, 0x7a, 0x7a, 0x7b, 0x7f, 0x82, - 0x85, 0x87, 0x89, 0x8a, 0x89, 0x88, 0x88, 0x8a, 0x8a, 0x8d, 0x8e, 0x8f, - 0x90, 0x90, 0x90, 0x8e, 0x8d, 0x8d, 0x8d, 0x8f, 0x91, 0x91, 0x92, 0x93, - 0x92, 0x90, 0x8f, 0x8f, 0x90, 0x8f, 0x8f, 0x8e, 0x90, 0x92, 0x91, 0x92, - 0x92, 0x92, 0x90, 0x8f, 0x8d, 0x8c, 0x8a, 0x89, 0x98, 0x95, 0x93, 0x91, - 0x8e, 0x89, 0x83, 0x7d, 0x79, 0x71, 0x6b, 0x68, 0x66, 0x65, 0x65, 0x64, - 0x63, 0x61, 0x60, 0x60, 0x5f, 0x5e, 0x5e, 0x5e, 0x5c, 0x5d, 0x5d, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5d, 0x5c, 0x5e, 0x60, 0x61, 0x62, - 0x69, 0x70, 0x75, 0x77, 0x7a, 0x7e, 0x7e, 0x7d, 0x82, 0x98, 0xc1, 0xd9, - 0xde, 0xdf, 0xdd, 0xdc, 0xdc, 0xdd, 0xdd, 0xdd, 0xdc, 0xdd, 0xdc, 0xdd, - 0xdc, 0xdc, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, - 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe2, 0xe3, - 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe3, 0xe3, 0xe2, 0xe3, 0xe3, 0xe2, 0xe2, - 0xe2, 0xe1, 0xdf, 0xde, 0xdd, 0xdb, 0xda, 0xd8, 0xd9, 0xd9, 0xd8, 0xd5, - 0xd5, 0xd6, 0xd6, 0xd9, 0xda, 0xda, 0xdb, 0xdb, 0xda, 0xd9, 0xd9, 0xd9, - 0xd9, 0xda, 0xd8, 0xd6, 0xd7, 0xd6, 0xd6, 0xd4, 0xd2, 0xce, 0xc8, 0xc1, - 0xb3, 0x97, 0x82, 0x97, 0xa8, 0xb9, 0xbe, 0xbc, 0xbb, 0xb9, 0xb6, 0xb2, - 0xae, 0xaa, 0xa5, 0x9c, 0x8f, 0x7d, 0x74, 0x7c, 0x9a, 0xbb, 0xc0, 0xb3, - 0xa1, 0x83, 0x85, 0x9b, 0xa2, 0xa2, 0x9d, 0x95, 0x8d, 0x84, 0x7d, 0x74, - 0x68, 0x64, 0x6a, 0x72, 0x7f, 0x8a, 0x9e, 0xa8, 0xac, 0xa9, 0x96, 0x6f, - 0x5c, 0x57, 0x59, 0x5b, 0x5e, 0x63, 0x65, 0x67, 0x65, 0x63, 0x65, 0x64, - 0x5e, 0x55, 0x60, 0x80, 0x8a, 0x8a, 0x86, 0x82, 0x7e, 0x7f, 0x80, 0x7f, - 0x7b, 0x74, 0x6e, 0x69, 0x5f, 0x5a, 0x56, 0x4d, 0x4a, 0x51, 0x64, 0x70, - 0x76, 0x77, 0x73, 0x6a, 0x64, 0x61, 0x5f, 0x5c, 0x5e, 0x64, 0x64, 0x60, - 0x57, 0x55, 0x55, 0x59, 0x5b, 0x61, 0x68, 0x73, 0x78, 0x7a, 0x7a, 0x7a, - 0x79, 0x7b, 0x7b, 0x7c, 0x7b, 0x79, 0x75, 0x72, 0x70, 0x70, 0x74, 0x7d, - 0x85, 0x89, 0x8f, 0x95, 0x9a, 0x9e, 0x9f, 0x9f, 0x9c, 0x96, 0x91, 0x8e, - 0x8a, 0x85, 0x82, 0x81, 0x81, 0x82, 0x86, 0x89, 0x8b, 0x8c, 0x8d, 0x8d, - 0x8a, 0x88, 0x88, 0x89, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x8f, 0x8d, - 0x8d, 0x8d, 0x8c, 0x8d, 0x8f, 0x8f, 0x8f, 0x90, 0x8f, 0x8d, 0x8c, 0x8d, - 0x8e, 0x8d, 0x8e, 0x8e, 0x8f, 0x90, 0x90, 0x91, 0x91, 0x91, 0x8f, 0x8e, - 0x8d, 0x8c, 0x8b, 0x8a, 0x9a, 0x96, 0x93, 0x91, 0x8f, 0x8a, 0x84, 0x7d, - 0x79, 0x72, 0x6c, 0x69, 0x68, 0x67, 0x65, 0x65, 0x62, 0x62, 0x62, 0x61, - 0x60, 0x60, 0x60, 0x5f, 0x5d, 0x5c, 0x5d, 0x5d, 0x5d, 0x5d, 0x5b, 0x5a, - 0x5b, 0x5c, 0x5c, 0x5c, 0x5d, 0x5e, 0x60, 0x63, 0x6a, 0x70, 0x75, 0x77, - 0x78, 0x7a, 0x7c, 0x89, 0x9d, 0xc3, 0xdb, 0xe0, 0xdf, 0xde, 0xde, 0xdd, - 0xdc, 0xdd, 0xdd, 0xdd, 0xdc, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, - 0xdf, 0xde, 0xde, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe0, 0xe0, 0xe1, - 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe1, - 0xe1, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe1, 0xe2, 0xe2, 0xe1, 0xe0, 0xe1, - 0xe1, 0xe0, 0xdf, 0xdc, 0xdb, 0xdb, 0xd9, 0xd8, 0xd8, 0xd6, 0xd5, 0xd5, - 0xd5, 0xd8, 0xd9, 0xd9, 0xda, 0xda, 0xd9, 0xd8, 0xd9, 0xd9, 0xd8, 0xd8, - 0xd8, 0xd7, 0xd6, 0xd5, 0xd2, 0xd0, 0xcd, 0xca, 0xc1, 0xaa, 0x8a, 0x86, - 0x92, 0xae, 0xbc, 0xbb, 0xbb, 0xba, 0xb7, 0xb3, 0xb1, 0xae, 0xab, 0xa4, - 0x99, 0x8b, 0x7b, 0x75, 0x7e, 0xa5, 0xbe, 0xc1, 0xb8, 0x9c, 0x7d, 0x8f, - 0x9f, 0xa2, 0xa0, 0x9b, 0x94, 0x8b, 0x84, 0x79, 0x70, 0x68, 0x67, 0x6c, - 0x79, 0x87, 0x9c, 0xa7, 0xab, 0xa8, 0x97, 0x75, 0x5e, 0x57, 0x59, 0x5c, - 0x5f, 0x62, 0x64, 0x67, 0x67, 0x67, 0x67, 0x63, 0x5e, 0x5a, 0x73, 0x89, - 0x8a, 0x88, 0x85, 0x83, 0x81, 0x82, 0x83, 0x81, 0x7b, 0x72, 0x69, 0x63, - 0x5c, 0x58, 0x54, 0x4d, 0x4e, 0x5a, 0x6c, 0x75, 0x79, 0x78, 0x73, 0x68, - 0x63, 0x60, 0x5e, 0x5c, 0x62, 0x65, 0x60, 0x5b, 0x55, 0x57, 0x5a, 0x5d, - 0x60, 0x67, 0x6f, 0x76, 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7a, - 0x78, 0x76, 0x73, 0x72, 0x70, 0x6f, 0x74, 0x7e, 0x85, 0x8a, 0x90, 0x97, - 0x9c, 0x9f, 0xa1, 0xa0, 0x9d, 0x98, 0x94, 0x91, 0x8d, 0x8a, 0x88, 0x87, - 0x88, 0x89, 0x8b, 0x8e, 0x90, 0x91, 0x90, 0x8f, 0x8c, 0x89, 0x88, 0x87, - 0x87, 0x8a, 0x8b, 0x8c, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d, 0x8c, 0x8c, 0x8c, - 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8b, 0x8b, 0x8a, 0x8b, 0x8b, 0x8c, 0x8c, - 0x8d, 0x8f, 0x90, 0x90, 0x8f, 0x90, 0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8c, - 0x9b, 0x98, 0x94, 0x92, 0x90, 0x8c, 0x84, 0x7e, 0x79, 0x73, 0x6e, 0x6b, - 0x69, 0x68, 0x67, 0x65, 0x63, 0x64, 0x63, 0x62, 0x60, 0x60, 0x60, 0x5f, - 0x5d, 0x5e, 0x5e, 0x5e, 0x5e, 0x5d, 0x5a, 0x59, 0x59, 0x5a, 0x5b, 0x5d, - 0x5d, 0x5f, 0x61, 0x65, 0x6a, 0x6e, 0x73, 0x75, 0x76, 0x77, 0x8c, 0xb3, - 0xca, 0xda, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdd, 0xdc, 0xdd, 0xde, 0xdf, - 0xdf, 0xde, 0xde, 0xdf, 0xe0, 0xe0, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xdf, - 0xe0, 0xdf, 0xdf, 0xdf, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xdf, - 0xde, 0xdd, 0xdd, 0xdb, 0xda, 0xd9, 0xd7, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, - 0xd6, 0xd8, 0xda, 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd7, 0xd7, 0xd6, 0xd5, - 0xd3, 0xd1, 0xce, 0xcd, 0xc9, 0xbe, 0xa0, 0x83, 0x84, 0xa0, 0xb6, 0xbc, - 0xbb, 0xba, 0xb9, 0xb6, 0xb4, 0xb2, 0xaf, 0xa9, 0xa1, 0x95, 0x8b, 0x82, - 0x76, 0x86, 0xa7, 0xb7, 0xb9, 0xac, 0x84, 0x83, 0x94, 0x9d, 0xa2, 0xa0, - 0x9a, 0x93, 0x8c, 0x81, 0x76, 0x6e, 0x67, 0x66, 0x70, 0x83, 0x98, 0xa7, - 0xac, 0xa9, 0x98, 0x7a, 0x61, 0x59, 0x5a, 0x5d, 0x5f, 0x61, 0x63, 0x67, - 0x69, 0x6a, 0x69, 0x61, 0x5e, 0x66, 0x83, 0x8d, 0x8a, 0x88, 0x85, 0x85, - 0x84, 0x86, 0x85, 0x81, 0x78, 0x6c, 0x62, 0x5d, 0x59, 0x58, 0x52, 0x4e, - 0x54, 0x64, 0x75, 0x78, 0x79, 0x78, 0x71, 0x65, 0x60, 0x5d, 0x5c, 0x5e, - 0x65, 0x64, 0x5b, 0x56, 0x56, 0x5b, 0x5f, 0x62, 0x65, 0x6b, 0x72, 0x76, - 0x78, 0x79, 0x79, 0x7a, 0x7b, 0x7b, 0x7b, 0x79, 0x76, 0x74, 0x72, 0x71, - 0x70, 0x6f, 0x75, 0x7f, 0x86, 0x8b, 0x92, 0x9a, 0xa0, 0xa2, 0xa2, 0xa2, - 0x9f, 0x9a, 0x96, 0x94, 0x90, 0x8e, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x92, - 0x92, 0x92, 0x91, 0x8f, 0x8c, 0x88, 0x86, 0x84, 0x84, 0x87, 0x89, 0x8a, - 0x8b, 0x8b, 0x8c, 0x8d, 0x8d, 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x89, - 0x89, 0x88, 0x87, 0x87, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8e, 0x8e, - 0x8e, 0x8c, 0x8d, 0x8d, 0x8b, 0x8b, 0x8a, 0x8c, 0x9c, 0x98, 0x96, 0x94, - 0x92, 0x8d, 0x86, 0x80, 0x7b, 0x75, 0x6f, 0x6b, 0x69, 0x68, 0x67, 0x66, - 0x64, 0x64, 0x64, 0x63, 0x61, 0x61, 0x61, 0x5f, 0x5e, 0x5e, 0x5d, 0x5d, - 0x5d, 0x5d, 0x5a, 0x5a, 0x59, 0x5a, 0x5b, 0x5c, 0x5e, 0x60, 0x62, 0x66, - 0x6a, 0x6d, 0x71, 0x73, 0x73, 0x79, 0xaa, 0xcf, 0xdc, 0xdf, 0xdf, 0xde, - 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xde, 0xde, 0xde, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xdf, 0xe1, 0xe1, 0xe1, 0xdf, - 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, - 0xdf, 0xdf, 0xdf, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xe2, 0xe2, 0xe1, 0xe1, - 0xe2, 0xe2, 0xe0, 0xe0, 0xe0, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xde, 0xde, - 0xdd, 0xdb, 0xda, 0xd7, 0xd6, 0xd4, 0xd2, 0xd2, 0xd3, 0xd4, 0xd8, 0xd9, - 0xda, 0xd9, 0xd8, 0xd7, 0xd7, 0xd6, 0xd6, 0xd5, 0xd5, 0xd3, 0xd0, 0xce, - 0xcb, 0xc5, 0xb1, 0x94, 0x8a, 0x94, 0xb0, 0xbc, 0xbb, 0xba, 0xb8, 0xb6, - 0xb5, 0xb3, 0xb1, 0xac, 0xa5, 0x9b, 0x94, 0x8c, 0x7c, 0x76, 0x8c, 0x9e, - 0xa8, 0xae, 0x93, 0x7a, 0x89, 0x96, 0xa0, 0xa2, 0x9d, 0x98, 0x93, 0x88, - 0x7a, 0x71, 0x68, 0x65, 0x6a, 0x7e, 0x93, 0xa5, 0xac, 0xab, 0x9a, 0x7e, - 0x64, 0x5b, 0x5a, 0x5c, 0x5f, 0x61, 0x63, 0x66, 0x6a, 0x6c, 0x68, 0x5f, - 0x5f, 0x71, 0x8c, 0x90, 0x8c, 0x89, 0x87, 0x87, 0x87, 0x89, 0x88, 0x82, - 0x76, 0x68, 0x5e, 0x5a, 0x5a, 0x58, 0x52, 0x52, 0x5a, 0x6d, 0x7e, 0x7d, - 0x7a, 0x77, 0x6f, 0x64, 0x5d, 0x5b, 0x5c, 0x60, 0x67, 0x64, 0x5a, 0x56, - 0x58, 0x5d, 0x62, 0x66, 0x69, 0x6d, 0x73, 0x76, 0x76, 0x77, 0x78, 0x7a, - 0x7a, 0x7a, 0x7a, 0x78, 0x75, 0x72, 0x70, 0x70, 0x6f, 0x70, 0x76, 0x7f, - 0x87, 0x8c, 0x94, 0x9c, 0xa2, 0xa3, 0xa4, 0xa3, 0xa0, 0x9b, 0x97, 0x95, - 0x92, 0x90, 0x90, 0x90, 0x91, 0x92, 0x93, 0x94, 0x93, 0x93, 0x90, 0x8e, - 0x8b, 0x87, 0x85, 0x83, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8c, - 0x8c, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85, 0x83, - 0x84, 0x84, 0x86, 0x87, 0x89, 0x89, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8b, - 0x8a, 0x8a, 0x8a, 0x8c, 0x9d, 0x99, 0x97, 0x95, 0x92, 0x8c, 0x86, 0x7f, - 0x7c, 0x76, 0x70, 0x6c, 0x6a, 0x69, 0x67, 0x66, 0x65, 0x64, 0x64, 0x63, - 0x61, 0x61, 0x61, 0x5f, 0x5e, 0x5e, 0x5d, 0x5d, 0x5d, 0x5d, 0x5b, 0x5a, - 0x5a, 0x5a, 0x5b, 0x5c, 0x5e, 0x61, 0x63, 0x66, 0x6a, 0x6d, 0x71, 0x72, - 0x72, 0x84, 0xbc, 0xd9, 0xe0, 0xdf, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdd, - 0xdd, 0xdf, 0xdf, 0xe0, 0xe0, 0xde, 0xde, 0xde, 0xdf, 0xde, 0xe0, 0xe0, - 0xe0, 0xe0, 0xde, 0xdf, 0xe1, 0xe1, 0xe1, 0xdf, 0xe0, 0xdf, 0xe1, 0xe2, - 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, - 0xdf, 0xdf, 0xdf, 0xdf, 0xe2, 0xe2, 0xe1, 0xe1, 0xe2, 0xe1, 0xdf, 0xdf, - 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xde, 0xdc, 0xdb, 0xd9, - 0xd8, 0xd4, 0xd3, 0xd2, 0xd2, 0xd3, 0xd5, 0xd8, 0xd9, 0xd9, 0xd8, 0xd6, - 0xd7, 0xd6, 0xd6, 0xd5, 0xd4, 0xd3, 0xd0, 0xce, 0xcc, 0xc8, 0xb9, 0xa2, - 0x95, 0x91, 0xaa, 0xba, 0xbc, 0xbb, 0xb7, 0xb5, 0xb5, 0xb3, 0xb1, 0xad, - 0xa7, 0x9d, 0x97, 0x90, 0x82, 0x73, 0x7c, 0x8a, 0x97, 0xa9, 0x9b, 0x78, - 0x82, 0x8f, 0x9d, 0xa3, 0x9f, 0x9b, 0x96, 0x8c, 0x7d, 0x74, 0x6a, 0x65, - 0x66, 0x7b, 0x90, 0xa4, 0xac, 0xab, 0x9c, 0x81, 0x67, 0x5c, 0x5a, 0x5c, - 0x5f, 0x61, 0x63, 0x66, 0x6a, 0x6c, 0x68, 0x5f, 0x63, 0x79, 0x90, 0x90, - 0x8d, 0x8a, 0x88, 0x88, 0x89, 0x8a, 0x89, 0x82, 0x75, 0x65, 0x5c, 0x5a, - 0x5a, 0x56, 0x52, 0x56, 0x5e, 0x72, 0x83, 0x80, 0x7c, 0x77, 0x6d, 0x62, - 0x5d, 0x5b, 0x5d, 0x62, 0x68, 0x64, 0x5a, 0x57, 0x5b, 0x60, 0x64, 0x68, - 0x6a, 0x6e, 0x72, 0x75, 0x75, 0x76, 0x78, 0x79, 0x79, 0x79, 0x79, 0x78, - 0x74, 0x71, 0x70, 0x6f, 0x6f, 0x6f, 0x76, 0x7f, 0x87, 0x8d, 0x94, 0x9d, - 0xa2, 0xa4, 0xa5, 0xa3, 0xa0, 0x9b, 0x98, 0x96, 0x93, 0x92, 0x91, 0x92, - 0x92, 0x93, 0x94, 0x94, 0x93, 0x92, 0x8f, 0x8d, 0x8a, 0x87, 0x85, 0x83, - 0x82, 0x84, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8c, 0x8b, 0x89, 0x89, 0x8a, - 0x89, 0x89, 0x88, 0x86, 0x86, 0x84, 0x83, 0x82, 0x83, 0x84, 0x84, 0x86, - 0x88, 0x88, 0x8b, 0x8c, 0x8c, 0x8a, 0x89, 0x8a, 0x89, 0x89, 0x8a, 0x8c, - 0x9e, 0x9b, 0x98, 0x96, 0x92, 0x8b, 0x85, 0x7f, 0x7c, 0x76, 0x70, 0x6c, - 0x6a, 0x68, 0x67, 0x66, 0x65, 0x64, 0x64, 0x63, 0x61, 0x61, 0x61, 0x60, - 0x5e, 0x5f, 0x5e, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5a, 0x5a, 0x5b, 0x5c, - 0x60, 0x61, 0x63, 0x66, 0x6a, 0x6e, 0x6f, 0x70, 0x76, 0x9f, 0xcf, 0xdd, - 0xdf, 0xdf, 0xde, 0xde, 0xdf, 0xdf, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, - 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, - 0xe1, 0xe2, 0xe2, 0xe0, 0xe0, 0xe0, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe0, 0xe0, 0xe0, 0xe0, - 0xe2, 0xe1, 0xe0, 0xe0, 0xe1, 0xdf, 0xde, 0xde, 0xdf, 0xdf, 0xe0, 0xdf, - 0xdf, 0xde, 0xde, 0xde, 0xdf, 0xdd, 0xdc, 0xdb, 0xd8, 0xd6, 0xd5, 0xd4, - 0xd3, 0xd1, 0xd2, 0xd5, 0xd6, 0xd8, 0xd8, 0xd6, 0xd6, 0xd5, 0xd4, 0xd4, - 0xd3, 0xd2, 0xcf, 0xce, 0xcb, 0xc9, 0xc1, 0xb5, 0xa8, 0x97, 0xa2, 0xb3, - 0xbb, 0xbb, 0xb6, 0xb4, 0xb4, 0xb4, 0xb2, 0xae, 0xa8, 0xa1, 0x9b, 0x95, - 0x8a, 0x79, 0x6e, 0x72, 0x7f, 0x99, 0xa0, 0x7d, 0x79, 0x83, 0x97, 0xa3, - 0xa2, 0x9e, 0x99, 0x90, 0x85, 0x78, 0x6f, 0x68, 0x62, 0x74, 0x8b, 0xa1, - 0xaa, 0xab, 0x9d, 0x83, 0x6b, 0x60, 0x5a, 0x5c, 0x5e, 0x61, 0x63, 0x65, - 0x6a, 0x6b, 0x68, 0x66, 0x6d, 0x84, 0x93, 0x91, 0x8e, 0x8c, 0x8b, 0x8c, - 0x8c, 0x8c, 0x8a, 0x81, 0x72, 0x61, 0x5b, 0x59, 0x5b, 0x55, 0x53, 0x5c, - 0x66, 0x76, 0x86, 0x84, 0x7e, 0x77, 0x6a, 0x60, 0x5d, 0x5d, 0x5f, 0x64, - 0x68, 0x62, 0x5b, 0x5a, 0x5e, 0x61, 0x66, 0x6a, 0x6d, 0x6e, 0x70, 0x75, - 0x75, 0x75, 0x77, 0x78, 0x77, 0x77, 0x77, 0x77, 0x73, 0x70, 0x70, 0x6f, - 0x6f, 0x70, 0x74, 0x7f, 0x89, 0x8f, 0x96, 0x9e, 0xa3, 0xa5, 0xa5, 0xa3, - 0xa0, 0x9b, 0x98, 0x96, 0x95, 0x93, 0x93, 0x94, 0x94, 0x95, 0x94, 0x94, - 0x92, 0x91, 0x8e, 0x8c, 0x89, 0x86, 0x85, 0x82, 0x81, 0x82, 0x84, 0x86, - 0x88, 0x89, 0x8a, 0x8a, 0x8a, 0x89, 0x87, 0x87, 0x87, 0x86, 0x85, 0x85, - 0x83, 0x81, 0x80, 0x80, 0x82, 0x83, 0x83, 0x84, 0x86, 0x86, 0x89, 0x8a, - 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x89, 0x8b, 0xa0, 0x9c, 0x98, 0x95, - 0x91, 0x8a, 0x85, 0x7f, 0x7c, 0x77, 0x71, 0x6d, 0x6a, 0x68, 0x67, 0x66, - 0x65, 0x64, 0x63, 0x62, 0x61, 0x61, 0x61, 0x60, 0x5e, 0x5f, 0x5e, 0x5b, - 0x5b, 0x5c, 0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x5c, 0x60, 0x61, 0x62, 0x65, - 0x6a, 0x6c, 0x6b, 0x72, 0x8d, 0xc4, 0xdd, 0xdf, 0xdf, 0xe0, 0xdf, 0xde, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe0, 0xe1, 0xe1, 0xe1, 0xe2, - 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe1, - 0xe2, 0xe2, 0xe3, 0xe3, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, - 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xdd, 0xdd, 0xdd, 0xdc, - 0xdd, 0xdd, 0xdd, 0xdc, 0xda, 0xd8, 0xd8, 0xd7, 0xd5, 0xd2, 0xd0, 0xd1, - 0xd2, 0xd3, 0xd6, 0xd6, 0xd6, 0xd5, 0xd4, 0xd5, 0xd3, 0xd2, 0xd0, 0xce, - 0xcd, 0xca, 0xc4, 0xbf, 0xb7, 0xa7, 0x9e, 0xab, 0xb6, 0xb9, 0xb6, 0xb2, - 0xb3, 0xb4, 0xb2, 0xaf, 0xaa, 0xa5, 0x9f, 0x9a, 0x92, 0x84, 0x72, 0x6b, - 0x70, 0x82, 0x9e, 0x8b, 0x73, 0x74, 0x8c, 0x9f, 0xa4, 0xa2, 0x9f, 0x98, - 0x8d, 0x7f, 0x76, 0x6d, 0x62, 0x69, 0x83, 0x9b, 0xa6, 0xab, 0xa2, 0x87, - 0x70, 0x63, 0x5a, 0x5c, 0x5e, 0x61, 0x63, 0x66, 0x6b, 0x6c, 0x6c, 0x76, - 0x81, 0x90, 0x95, 0x92, 0x8d, 0x8c, 0x8d, 0x90, 0x90, 0x8e, 0x89, 0x7e, - 0x6c, 0x5c, 0x59, 0x59, 0x5a, 0x52, 0x55, 0x63, 0x6d, 0x79, 0x87, 0x85, - 0x7e, 0x76, 0x66, 0x5e, 0x5d, 0x60, 0x62, 0x66, 0x67, 0x5f, 0x5d, 0x5e, - 0x61, 0x64, 0x68, 0x6c, 0x6d, 0x6f, 0x70, 0x73, 0x74, 0x75, 0x76, 0x76, - 0x74, 0x74, 0x75, 0x77, 0x73, 0x6f, 0x6f, 0x6f, 0x6f, 0x70, 0x74, 0x81, - 0x8c, 0x92, 0x99, 0xa0, 0xa6, 0xa7, 0xa7, 0xa5, 0xa1, 0x9b, 0x98, 0x96, - 0x96, 0x95, 0x95, 0x96, 0x96, 0x96, 0x95, 0x93, 0x90, 0x8e, 0x8d, 0x8b, - 0x88, 0x86, 0x84, 0x81, 0x7f, 0x7e, 0x80, 0x81, 0x84, 0x87, 0x88, 0x88, - 0x88, 0x87, 0x85, 0x85, 0x84, 0x82, 0x81, 0x81, 0x80, 0x7f, 0x7e, 0x7e, - 0x80, 0x81, 0x81, 0x81, 0x83, 0x85, 0x87, 0x87, 0x87, 0x86, 0x87, 0x87, - 0x86, 0x86, 0x87, 0x89, 0x9e, 0x9b, 0x98, 0x96, 0x90, 0x8a, 0x84, 0x7f, - 0x7b, 0x76, 0x72, 0x6d, 0x6b, 0x6a, 0x68, 0x65, 0x64, 0x65, 0x64, 0x63, - 0x62, 0x60, 0x60, 0x60, 0x5e, 0x5d, 0x5c, 0x5b, 0x5b, 0x5c, 0x5d, 0x5c, - 0x5b, 0x5b, 0x5b, 0x5c, 0x60, 0x61, 0x62, 0x65, 0x68, 0x69, 0x70, 0x85, - 0xb8, 0xda, 0xde, 0xde, 0xdf, 0xe0, 0xde, 0xde, 0xdf, 0xe0, 0xe0, 0xe0, - 0xe0, 0xdf, 0xdf, 0xde, 0xe1, 0xe1, 0xe1, 0xe1, 0xdf, 0xdf, 0xe1, 0xe0, - 0xe2, 0xe2, 0xe1, 0xe2, 0xe1, 0xe1, 0xe2, 0xe3, 0xe3, 0xe2, 0xe3, 0xe3, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe0, 0xe1, 0xe1, 0xe0, 0xe1, - 0xe1, 0xe1, 0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe1, 0xdf, 0xdf, 0xe0, 0xe0, - 0xdf, 0xdf, 0xdf, 0xde, 0xdc, 0xdb, 0xdb, 0xdc, 0xdb, 0xdc, 0xdc, 0xdc, - 0xdb, 0xda, 0xda, 0xd9, 0xd8, 0xd5, 0xd3, 0xd3, 0xd1, 0xd1, 0xd1, 0xd3, - 0xd5, 0xd5, 0xd5, 0xd5, 0xd4, 0xd1, 0xd0, 0xcf, 0xcf, 0xcc, 0xc8, 0xc4, - 0xc0, 0xb5, 0xa4, 0xa3, 0xad, 0xb2, 0xb5, 0xb2, 0xb1, 0xb2, 0xb2, 0xb0, - 0xac, 0xa8, 0xa3, 0x9e, 0x96, 0x8c, 0x81, 0x79, 0x74, 0x73, 0x8e, 0x94, - 0x77, 0x6f, 0x7f, 0x98, 0xa3, 0xa5, 0xa5, 0xa0, 0x95, 0x89, 0x7e, 0x74, - 0x65, 0x62, 0x79, 0x90, 0x9d, 0xa9, 0xa5, 0x8b, 0x75, 0x68, 0x5b, 0x5b, - 0x5d, 0x5f, 0x60, 0x64, 0x69, 0x6b, 0x73, 0x86, 0x90, 0x97, 0x97, 0x92, - 0x8c, 0x8c, 0x90, 0x94, 0x94, 0x91, 0x8b, 0x7d, 0x67, 0x5a, 0x59, 0x5a, - 0x59, 0x53, 0x59, 0x67, 0x71, 0x7c, 0x87, 0x85, 0x7c, 0x72, 0x63, 0x5b, - 0x5c, 0x60, 0x63, 0x67, 0x65, 0x5d, 0x5e, 0x61, 0x64, 0x67, 0x6a, 0x6c, - 0x6d, 0x6f, 0x71, 0x71, 0x73, 0x74, 0x74, 0x75, 0x72, 0x72, 0x73, 0x75, - 0x73, 0x6f, 0x6e, 0x6e, 0x6e, 0x70, 0x74, 0x82, 0x8e, 0x94, 0x9b, 0xa5, - 0xa8, 0xa9, 0xa8, 0xa5, 0xa0, 0x9a, 0x99, 0x97, 0x97, 0x96, 0x97, 0x96, - 0x96, 0x95, 0x94, 0x91, 0x8e, 0x8c, 0x8b, 0x8a, 0x88, 0x86, 0x84, 0x81, - 0x7e, 0x7b, 0x7d, 0x7e, 0x80, 0x83, 0x85, 0x86, 0x86, 0x85, 0x83, 0x82, - 0x81, 0x7f, 0x7f, 0x7f, 0x7e, 0x7c, 0x7b, 0x7b, 0x7d, 0x7f, 0x80, 0x81, - 0x82, 0x85, 0x86, 0x85, 0x85, 0x84, 0x84, 0x83, 0x84, 0x85, 0x87, 0x88, - 0x9e, 0x9a, 0x96, 0x93, 0x8f, 0x89, 0x83, 0x7d, 0x7a, 0x76, 0x72, 0x6e, - 0x6b, 0x6a, 0x68, 0x66, 0x64, 0x65, 0x65, 0x64, 0x62, 0x61, 0x61, 0x61, - 0x60, 0x5e, 0x5d, 0x5b, 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5c, 0x5b, 0x5b, - 0x60, 0x62, 0x63, 0x64, 0x66, 0x6b, 0x85, 0xa2, 0xce, 0xde, 0xde, 0xde, - 0xde, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xde, 0xde, - 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe1, 0xe1, 0xe1, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe1, - 0xe1, 0xe0, 0xe1, 0xe0, 0xe0, 0xe0, 0xdf, 0xe0, 0xe0, 0xe0, 0xdf, 0xe0, - 0xe0, 0xe0, 0xe1, 0xe0, 0xdf, 0xdf, 0xdf, 0xe0, 0xdf, 0xde, 0xde, 0xde, - 0xdc, 0xdb, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xd9, - 0xd9, 0xd7, 0xd4, 0xd4, 0xd3, 0xd1, 0xd1, 0xd1, 0xd4, 0xd4, 0xd4, 0xd3, - 0xd3, 0xd1, 0xcf, 0xcf, 0xce, 0xcc, 0xc8, 0xc6, 0xc3, 0xbc, 0xac, 0xa0, - 0xa5, 0xab, 0xb3, 0xb2, 0xaf, 0xb0, 0xb0, 0xb1, 0xae, 0xa9, 0xa6, 0xa2, - 0x99, 0x91, 0x8c, 0x85, 0x7d, 0x71, 0x7e, 0x94, 0x7f, 0x73, 0x76, 0x91, - 0xa2, 0xa7, 0xa7, 0xa3, 0x9c, 0x91, 0x84, 0x79, 0x68, 0x5e, 0x72, 0x87, - 0x95, 0xa8, 0xa7, 0x91, 0x7a, 0x6a, 0x5b, 0x59, 0x5b, 0x5d, 0x5f, 0x63, - 0x67, 0x69, 0x7b, 0x8d, 0x95, 0x9a, 0x99, 0x94, 0x8e, 0x8e, 0x93, 0x96, - 0x95, 0x91, 0x8b, 0x7a, 0x63, 0x59, 0x59, 0x59, 0x56, 0x53, 0x5f, 0x6b, - 0x73, 0x7d, 0x89, 0x86, 0x7a, 0x6f, 0x5f, 0x5a, 0x5e, 0x62, 0x65, 0x67, - 0x63, 0x5d, 0x5f, 0x62, 0x65, 0x68, 0x6c, 0x6e, 0x6e, 0x6f, 0x70, 0x72, - 0x74, 0x74, 0x74, 0x74, 0x73, 0x73, 0x73, 0x75, 0x73, 0x6f, 0x6e, 0x6e, - 0x6d, 0x6f, 0x74, 0x84, 0x90, 0x96, 0x9e, 0xa6, 0xa9, 0xa9, 0xa8, 0xa5, - 0xa0, 0x9a, 0x98, 0x97, 0x97, 0x96, 0x97, 0x96, 0x96, 0x95, 0x94, 0x90, - 0x8c, 0x8b, 0x8a, 0x8a, 0x89, 0x87, 0x85, 0x81, 0x7c, 0x7a, 0x7b, 0x7c, - 0x7e, 0x82, 0x84, 0x85, 0x85, 0x83, 0x82, 0x80, 0x7e, 0x7d, 0x7d, 0x7c, - 0x7c, 0x7a, 0x7a, 0x7a, 0x7c, 0x7d, 0x7f, 0x80, 0x81, 0x84, 0x85, 0x84, - 0x83, 0x82, 0x80, 0x80, 0x81, 0x82, 0x86, 0x87, 0x9d, 0x99, 0x95, 0x92, - 0x8e, 0x89, 0x82, 0x7c, 0x79, 0x76, 0x73, 0x6f, 0x6b, 0x6a, 0x68, 0x66, - 0x64, 0x65, 0x65, 0x64, 0x62, 0x62, 0x61, 0x61, 0x61, 0x5f, 0x5d, 0x5c, - 0x5b, 0x5b, 0x5b, 0x5c, 0x5d, 0x5d, 0x5b, 0x5b, 0x60, 0x62, 0x63, 0x64, - 0x66, 0x70, 0x98, 0xb7, 0xd6, 0xde, 0xde, 0xdd, 0xde, 0xdf, 0xdf, 0xe0, - 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xe1, 0xe1, 0xe1, 0xe1, - 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe0, 0xe1, 0xe3, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe0, 0xe1, 0xe0, - 0xe0, 0xdf, 0xde, 0xdf, 0xdf, 0xde, 0xde, 0xdf, 0xde, 0xdf, 0xdf, 0xdf, - 0xde, 0xde, 0xde, 0xdf, 0xde, 0xdd, 0xdd, 0xde, 0xdc, 0xdc, 0xdc, 0xdc, - 0xda, 0xda, 0xda, 0xda, 0xda, 0xd9, 0xda, 0xd9, 0xd9, 0xd7, 0xd5, 0xd5, - 0xd4, 0xd2, 0xd1, 0xd0, 0xd2, 0xd3, 0xd3, 0xd3, 0xd3, 0xd1, 0xcf, 0xce, - 0xce, 0xcd, 0xc9, 0xc7, 0xc4, 0xbf, 0xb1, 0xa1, 0xa0, 0xa5, 0xb0, 0xb1, - 0xaf, 0xaf, 0xaf, 0xb1, 0xae, 0xaa, 0xa7, 0xa3, 0x9c, 0x93, 0x90, 0x8b, - 0x83, 0x75, 0x77, 0x8f, 0x85, 0x78, 0x73, 0x8d, 0xa0, 0xa7, 0xa7, 0xa5, - 0x9f, 0x95, 0x88, 0x7d, 0x6c, 0x5e, 0x6d, 0x80, 0x90, 0xa5, 0xa9, 0x95, - 0x7d, 0x6d, 0x5c, 0x59, 0x5a, 0x5c, 0x5e, 0x63, 0x66, 0x6a, 0x81, 0x92, - 0x98, 0x9b, 0x9a, 0x94, 0x90, 0x90, 0x96, 0x97, 0x95, 0x90, 0x88, 0x77, - 0x61, 0x59, 0x5a, 0x58, 0x53, 0x54, 0x63, 0x6e, 0x75, 0x7e, 0x8a, 0x86, - 0x77, 0x6b, 0x5d, 0x59, 0x5e, 0x63, 0x66, 0x67, 0x62, 0x5e, 0x61, 0x64, - 0x66, 0x69, 0x6c, 0x6f, 0x6f, 0x6f, 0x70, 0x73, 0x74, 0x74, 0x74, 0x74, - 0x74, 0x73, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x6e, 0x6d, 0x6e, 0x74, 0x85, - 0x92, 0x98, 0xa0, 0xa7, 0xaa, 0xa9, 0xa8, 0xa5, 0x9f, 0x9b, 0x98, 0x97, - 0x96, 0x95, 0x96, 0x96, 0x95, 0x94, 0x93, 0x8e, 0x8b, 0x8a, 0x8a, 0x8a, - 0x89, 0x87, 0x85, 0x81, 0x7b, 0x79, 0x7a, 0x7b, 0x7d, 0x81, 0x84, 0x85, - 0x84, 0x83, 0x80, 0x7f, 0x7d, 0x7c, 0x7c, 0x7b, 0x7a, 0x78, 0x78, 0x7a, - 0x7b, 0x7c, 0x7f, 0x80, 0x81, 0x83, 0x84, 0x83, 0x83, 0x81, 0x7f, 0x7f, - 0x81, 0x82, 0x85, 0x87, 0x9c, 0x98, 0x94, 0x91, 0x8c, 0x87, 0x81, 0x7c, - 0x79, 0x76, 0x73, 0x6f, 0x6c, 0x6a, 0x68, 0x67, 0x65, 0x65, 0x65, 0x64, - 0x62, 0x61, 0x61, 0x61, 0x61, 0x60, 0x5f, 0x5d, 0x5c, 0x5a, 0x5b, 0x5d, - 0x5e, 0x5e, 0x5d, 0x5d, 0x60, 0x62, 0x63, 0x64, 0x67, 0x81, 0xb6, 0xd0, - 0xdc, 0xde, 0xdd, 0xdd, 0xde, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, - 0xdf, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe1, 0xe0, 0xdf, 0xdf, 0xde, 0xdd, 0xdd, - 0xdc, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, - 0xde, 0xdd, 0xdd, 0xdd, 0xdc, 0xdb, 0xda, 0xdb, 0xd9, 0xd9, 0xd9, 0xd8, - 0xd8, 0xd8, 0xd9, 0xd9, 0xd8, 0xd7, 0xd6, 0xd6, 0xd5, 0xd4, 0xd2, 0xcf, - 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd2, 0xd0, 0xd0, 0xcf, 0xcd, 0xca, 0xc8, - 0xc6, 0xc1, 0xb6, 0xa6, 0x9c, 0x9c, 0xa7, 0xaf, 0xaf, 0xad, 0xad, 0xae, - 0xad, 0xaa, 0xa7, 0xa4, 0x9e, 0x97, 0x92, 0x8f, 0x8a, 0x7e, 0x74, 0x86, - 0x8b, 0x81, 0x6f, 0x83, 0x9c, 0xa6, 0xa7, 0xa7, 0xa3, 0x9b, 0x90, 0x85, - 0x73, 0x60, 0x66, 0x76, 0x86, 0xa0, 0xab, 0x9c, 0x84, 0x72, 0x5e, 0x57, - 0x59, 0x5b, 0x5d, 0x60, 0x62, 0x6e, 0x8c, 0x98, 0x9b, 0x9c, 0x9b, 0x96, - 0x93, 0x95, 0x98, 0x98, 0x92, 0x8b, 0x83, 0x73, 0x5e, 0x59, 0x59, 0x56, - 0x50, 0x57, 0x69, 0x72, 0x78, 0x82, 0x8b, 0x84, 0x73, 0x67, 0x5a, 0x59, - 0x5f, 0x64, 0x66, 0x66, 0x60, 0x60, 0x63, 0x66, 0x68, 0x6b, 0x6e, 0x6f, - 0x6f, 0x6f, 0x70, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, 0x72, 0x72, 0x73, - 0x71, 0x6e, 0x6e, 0x6e, 0x6d, 0x6f, 0x75, 0x87, 0x95, 0x9c, 0xa3, 0xa9, - 0xaa, 0xa9, 0xa7, 0xa3, 0x9d, 0x99, 0x96, 0x95, 0x95, 0x94, 0x94, 0x93, - 0x91, 0x90, 0x8f, 0x8c, 0x8a, 0x89, 0x89, 0x8a, 0x89, 0x88, 0x86, 0x82, - 0x7c, 0x78, 0x78, 0x79, 0x7b, 0x80, 0x82, 0x84, 0x84, 0x82, 0x80, 0x7e, - 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x78, 0x78, 0x79, 0x7a, 0x7b, 0x7f, 0x80, - 0x80, 0x82, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x81, 0x82, 0x84, 0x85, - 0x99, 0x95, 0x92, 0x90, 0x8b, 0x86, 0x7f, 0x7c, 0x7a, 0x76, 0x73, 0x6f, - 0x6c, 0x6b, 0x69, 0x67, 0x66, 0x66, 0x66, 0x65, 0x63, 0x61, 0x61, 0x61, - 0x60, 0x60, 0x60, 0x5f, 0x5e, 0x5d, 0x5d, 0x5e, 0x60, 0x60, 0x5f, 0x5f, - 0x61, 0x63, 0x63, 0x63, 0x6d, 0xa7, 0xd0, 0xdc, 0xdd, 0xdd, 0xdd, 0xde, - 0xde, 0xdd, 0xde, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xe0, 0xe1, 0xe1, - 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe0, 0xe0, 0xdf, 0xde, 0xde, 0xdd, 0xdd, 0xde, 0xdd, - 0xda, 0xd9, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xdc, 0xdc, - 0xdc, 0xdb, 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xd9, 0xd8, 0xd7, 0xd7, 0xd7, - 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd4, 0xd2, 0xd2, 0xd1, 0xd0, 0xd1, - 0xd1, 0xd2, 0xd1, 0xd1, 0xcf, 0xcc, 0xcb, 0xc9, 0xc7, 0xc2, 0xbb, 0xaf, - 0xa1, 0x9c, 0x9e, 0xaa, 0xae, 0xad, 0xad, 0xac, 0xab, 0xa9, 0xa8, 0xa5, - 0xa0, 0x9b, 0x97, 0x95, 0x91, 0x87, 0x78, 0x7d, 0x8a, 0x85, 0x6f, 0x76, - 0x94, 0xa3, 0xa7, 0xa8, 0xa7, 0xa2, 0x99, 0x8e, 0x7a, 0x65, 0x62, 0x6e, - 0x7d, 0x96, 0xaa, 0xa3, 0x8c, 0x79, 0x60, 0x53, 0x54, 0x56, 0x57, 0x57, - 0x5f, 0x7b, 0x9a, 0x9f, 0x9e, 0x9d, 0x9a, 0x98, 0x98, 0x98, 0x97, 0x95, - 0x8b, 0x82, 0x7b, 0x6d, 0x5d, 0x59, 0x55, 0x51, 0x50, 0x5d, 0x6f, 0x78, - 0x7e, 0x87, 0x8d, 0x82, 0x6e, 0x62, 0x58, 0x59, 0x61, 0x66, 0x67, 0x64, - 0x5f, 0x62, 0x65, 0x67, 0x6a, 0x6c, 0x6e, 0x70, 0x70, 0x70, 0x73, 0x74, - 0x73, 0x73, 0x73, 0x74, 0x73, 0x72, 0x72, 0x72, 0x70, 0x6f, 0x6e, 0x6d, - 0x6d, 0x70, 0x7a, 0x8d, 0x99, 0xa0, 0xa7, 0xac, 0xab, 0xa9, 0xa6, 0xa0, - 0x98, 0x94, 0x91, 0x90, 0x8e, 0x8d, 0x8e, 0x8d, 0x8c, 0x89, 0x88, 0x86, - 0x85, 0x84, 0x86, 0x87, 0x87, 0x86, 0x85, 0x82, 0x7c, 0x79, 0x77, 0x78, - 0x7a, 0x7e, 0x82, 0x83, 0x83, 0x82, 0x7f, 0x7e, 0x7c, 0x7b, 0x7a, 0x78, - 0x78, 0x78, 0x79, 0x7a, 0x79, 0x7b, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x82, - 0x82, 0x80, 0x81, 0x80, 0x82, 0x82, 0x84, 0x86, 0x97, 0x93, 0x90, 0x8d, - 0x89, 0x83, 0x7f, 0x7c, 0x79, 0x76, 0x73, 0x6f, 0x6d, 0x6c, 0x6b, 0x68, - 0x66, 0x66, 0x66, 0x65, 0x63, 0x62, 0x62, 0x62, 0x61, 0x60, 0x60, 0x60, - 0x60, 0x5e, 0x5e, 0x5e, 0x5f, 0x60, 0x60, 0x60, 0x62, 0x64, 0x63, 0x64, - 0x82, 0xc5, 0xdb, 0xde, 0xdd, 0xdf, 0xde, 0xdd, 0xdd, 0xde, 0xde, 0xdf, - 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe1, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe1, - 0xe1, 0xe1, 0xe0, 0xe1, 0xe0, 0xdf, 0xdf, 0xde, 0xdb, 0xda, 0xd9, 0xd9, - 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd9, 0xdb, 0xdb, 0xdb, 0xda, 0xd8, 0xd8, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd6, 0xd6, 0xd5, 0xd5, 0xd4, 0xd5, 0xd5, - 0xd5, 0xd5, 0xd4, 0xd2, 0xd3, 0xd2, 0xd1, 0xd0, 0xcf, 0xd0, 0xd1, 0xd0, - 0xcf, 0xcc, 0xcb, 0xc8, 0xc7, 0xc3, 0xbf, 0xb6, 0xad, 0xa5, 0x9b, 0xa0, - 0xa9, 0xab, 0xab, 0xaa, 0xaa, 0xa9, 0xa8, 0xa6, 0xa3, 0x9f, 0x9d, 0x9b, - 0x97, 0x8e, 0x82, 0x7b, 0x84, 0x82, 0x71, 0x6d, 0x8b, 0x9e, 0xa5, 0xa8, - 0xaa, 0xa6, 0xa1, 0x96, 0x80, 0x6b, 0x61, 0x69, 0x74, 0x88, 0xa6, 0xa9, - 0x97, 0x84, 0x65, 0x4f, 0x4d, 0x4c, 0x4d, 0x52, 0x6b, 0x8c, 0xa3, 0xa5, - 0xa2, 0x9d, 0x98, 0x98, 0x9c, 0x9b, 0x95, 0x8f, 0x84, 0x7c, 0x74, 0x67, - 0x5b, 0x57, 0x4f, 0x4d, 0x54, 0x66, 0x73, 0x7e, 0x85, 0x8d, 0x8f, 0x7e, - 0x68, 0x5d, 0x57, 0x5c, 0x63, 0x66, 0x65, 0x60, 0x60, 0x65, 0x67, 0x68, - 0x6a, 0x6b, 0x6e, 0x71, 0x71, 0x71, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, - 0x72, 0x71, 0x71, 0x72, 0x72, 0x70, 0x6f, 0x6e, 0x6d, 0x71, 0x7f, 0x93, - 0x9f, 0xa5, 0xaa, 0xad, 0xab, 0xa7, 0xa4, 0x9c, 0x94, 0x8f, 0x8a, 0x87, - 0x84, 0x83, 0x83, 0x82, 0x81, 0x7f, 0x7e, 0x7c, 0x7b, 0x7c, 0x7e, 0x80, - 0x81, 0x82, 0x83, 0x82, 0x7f, 0x7b, 0x79, 0x79, 0x7a, 0x7d, 0x80, 0x81, - 0x81, 0x80, 0x7d, 0x7d, 0x7c, 0x7b, 0x79, 0x78, 0x77, 0x77, 0x78, 0x79, - 0x79, 0x7b, 0x7e, 0x80, 0x81, 0x83, 0x84, 0x83, 0x83, 0x82, 0x82, 0x81, - 0x82, 0x83, 0x85, 0x87, 0x94, 0x91, 0x8e, 0x8c, 0x88, 0x82, 0x7f, 0x7c, - 0x7a, 0x77, 0x73, 0x70, 0x6e, 0x6d, 0x6c, 0x69, 0x67, 0x65, 0x65, 0x65, - 0x62, 0x63, 0x62, 0x62, 0x61, 0x60, 0x60, 0x5f, 0x60, 0x5f, 0x5e, 0x5e, - 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x61, 0x67, 0x9d, 0xd3, 0xdd, 0xde, - 0xde, 0xdf, 0xdf, 0xde, 0xde, 0xdf, 0xdf, 0xde, 0xdf, 0xdf, 0xdf, 0xe0, - 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe2, 0xe1, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe1, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, - 0xe1, 0xe1, 0xe1, 0xe0, 0xde, 0xdd, 0xdb, 0xda, 0xd8, 0xd7, 0xd6, 0xd6, - 0xd7, 0xd8, 0xd9, 0xda, 0xda, 0xd9, 0xd8, 0xd7, 0xd5, 0xd6, 0xd6, 0xd6, - 0xd6, 0xd6, 0xd6, 0xd5, 0xd3, 0xd3, 0xd3, 0xd4, 0xd4, 0xd4, 0xd3, 0xd3, - 0xd3, 0xd2, 0xd1, 0xd1, 0xd0, 0xd0, 0xd0, 0xd0, 0xcf, 0xcd, 0xcb, 0xc8, - 0xc6, 0xc4, 0xc0, 0xb9, 0xb4, 0xac, 0x9f, 0x9a, 0xa5, 0xa9, 0xa9, 0xa9, - 0xa9, 0xa8, 0xa7, 0xa6, 0xa4, 0xa0, 0x9f, 0x9e, 0x9b, 0x93, 0x88, 0x7d, - 0x7f, 0x7e, 0x73, 0x68, 0x83, 0x9a, 0xa3, 0xa8, 0xab, 0xaa, 0xa7, 0x9d, - 0x87, 0x6f, 0x62, 0x66, 0x6d, 0x7e, 0xa0, 0xab, 0x9f, 0x8d, 0x6a, 0x4c, - 0x45, 0x46, 0x4a, 0x59, 0x79, 0x94, 0xa4, 0xa7, 0xa4, 0x9c, 0x96, 0x9a, - 0x9f, 0x9e, 0x96, 0x8a, 0x80, 0x79, 0x72, 0x65, 0x5b, 0x56, 0x4d, 0x4d, - 0x58, 0x6b, 0x77, 0x81, 0x89, 0x91, 0x8f, 0x7b, 0x64, 0x5a, 0x57, 0x5c, - 0x63, 0x66, 0x64, 0x5f, 0x60, 0x65, 0x68, 0x69, 0x6a, 0x6b, 0x6f, 0x71, - 0x72, 0x72, 0x73, 0x74, 0x73, 0x73, 0x73, 0x73, 0x70, 0x71, 0x72, 0x72, - 0x72, 0x71, 0x70, 0x6e, 0x6d, 0x73, 0x84, 0x98, 0xa3, 0xa8, 0xab, 0xac, - 0xaa, 0xa5, 0xa0, 0x98, 0x8f, 0x88, 0x81, 0x7d, 0x7a, 0x79, 0x79, 0x78, - 0x77, 0x75, 0x75, 0x73, 0x73, 0x74, 0x75, 0x79, 0x7c, 0x7f, 0x80, 0x80, - 0x7f, 0x7d, 0x7b, 0x7a, 0x7a, 0x7c, 0x7f, 0x80, 0x81, 0x80, 0x7d, 0x7b, - 0x7b, 0x7a, 0x78, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x7d, 0x7e, 0x7f, - 0x82, 0x84, 0x84, 0x84, 0x84, 0x82, 0x83, 0x83, 0x83, 0x84, 0x86, 0x88, - 0x93, 0x8f, 0x8d, 0x8a, 0x87, 0x82, 0x7f, 0x7c, 0x7a, 0x77, 0x72, 0x70, - 0x6e, 0x6d, 0x6c, 0x6a, 0x67, 0x65, 0x64, 0x64, 0x62, 0x62, 0x62, 0x62, - 0x61, 0x60, 0x60, 0x60, 0x60, 0x5f, 0x5e, 0x5d, 0x5e, 0x5f, 0x60, 0x61, - 0x62, 0x62, 0x61, 0x6b, 0xaf, 0xd8, 0xdd, 0xdd, 0xdd, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xde, 0xdf, 0xdf, 0xde, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, - 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe2, 0xe2, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, - 0xe2, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe0, 0xe1, 0xe0, 0xe1, 0xe0, 0xe1, - 0xdf, 0xdf, 0xdd, 0xdc, 0xda, 0xd8, 0xd6, 0xd6, 0xd6, 0xd7, 0xd8, 0xd9, - 0xda, 0xd9, 0xd7, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd6, 0xd5, - 0xd3, 0xd3, 0xd2, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd2, 0xd1, 0xd1, - 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcd, 0xcb, 0xc8, 0xc6, 0xc4, 0xc1, 0xba, - 0xb6, 0xb0, 0xa3, 0x98, 0xa2, 0xa6, 0xa8, 0xa8, 0xa8, 0xa7, 0xa7, 0xa6, - 0xa4, 0xa0, 0x9f, 0x9e, 0x9c, 0x96, 0x8b, 0x7f, 0x7e, 0x7c, 0x74, 0x67, - 0x7d, 0x95, 0xa0, 0xa7, 0xac, 0xac, 0xaa, 0xa0, 0x8a, 0x71, 0x63, 0x63, - 0x69, 0x7a, 0x9a, 0xab, 0xa4, 0x93, 0x6f, 0x4a, 0x44, 0x4c, 0x54, 0x63, - 0x7e, 0x95, 0xa3, 0xa6, 0xa3, 0x99, 0x97, 0x9f, 0xa3, 0xa1, 0x97, 0x87, - 0x7c, 0x77, 0x70, 0x65, 0x5a, 0x53, 0x4c, 0x4e, 0x5b, 0x6d, 0x78, 0x84, - 0x8c, 0x93, 0x8f, 0x79, 0x61, 0x58, 0x57, 0x5c, 0x63, 0x64, 0x62, 0x5e, - 0x60, 0x66, 0x68, 0x6a, 0x6b, 0x6c, 0x6e, 0x71, 0x71, 0x71, 0x74, 0x74, - 0x73, 0x73, 0x74, 0x72, 0x70, 0x71, 0x72, 0x73, 0x73, 0x72, 0x70, 0x6f, - 0x6e, 0x75, 0x88, 0x9a, 0xa4, 0xa9, 0xac, 0xac, 0xa8, 0xa2, 0x9c, 0x93, - 0x89, 0x81, 0x7b, 0x77, 0x75, 0x73, 0x74, 0x73, 0x73, 0x71, 0x70, 0x6f, - 0x6f, 0x70, 0x71, 0x75, 0x78, 0x7c, 0x7e, 0x7e, 0x7e, 0x7d, 0x7c, 0x7c, - 0x7b, 0x7c, 0x7e, 0x7f, 0x7f, 0x7f, 0x7d, 0x7b, 0x7b, 0x79, 0x77, 0x77, - 0x76, 0x77, 0x78, 0x77, 0x79, 0x7d, 0x7e, 0x80, 0x82, 0x85, 0x85, 0x85, - 0x84, 0x83, 0x84, 0x84, 0x83, 0x84, 0x87, 0x88, 0x90, 0x8d, 0x8a, 0x88, - 0x85, 0x80, 0x7e, 0x7b, 0x79, 0x77, 0x72, 0x6f, 0x6e, 0x6d, 0x6c, 0x69, - 0x67, 0x65, 0x64, 0x64, 0x62, 0x62, 0x62, 0x62, 0x61, 0x60, 0x60, 0x60, - 0x60, 0x60, 0x5e, 0x5e, 0x5e, 0x5e, 0x60, 0x61, 0x63, 0x60, 0x62, 0x78, - 0xc1, 0xdb, 0xdc, 0xdc, 0xde, 0xdf, 0xdf, 0xdf, 0xe0, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe1, 0xe1, - 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe1, 0xe0, 0xe1, - 0xe1, 0xe0, 0xdf, 0xdf, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xdf, 0xde, - 0xdd, 0xdb, 0xd8, 0xd7, 0xd5, 0xd4, 0xd3, 0xd6, 0xd8, 0xd8, 0xd8, 0xd7, - 0xd4, 0xd3, 0xd3, 0xd3, 0xd3, 0xd5, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd2, - 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd2, 0xd2, 0xd1, 0xd0, 0xd0, 0xcf, 0xce, - 0xce, 0xcd, 0xcb, 0xc8, 0xc7, 0xc5, 0xc1, 0xbc, 0xb8, 0xb3, 0xa8, 0x99, - 0x9b, 0xa0, 0xa4, 0xa6, 0xa8, 0xa8, 0xa8, 0xa6, 0xa3, 0xa1, 0x9f, 0x9e, - 0x9c, 0x99, 0x90, 0x83, 0x7d, 0x7b, 0x76, 0x66, 0x73, 0x8c, 0x9a, 0xa4, - 0xac, 0xae, 0xab, 0xa4, 0x90, 0x74, 0x64, 0x61, 0x65, 0x73, 0x8e, 0xa8, - 0xaa, 0x9c, 0x78, 0x4a, 0x4b, 0x64, 0x70, 0x76, 0x7e, 0x91, 0xa0, 0xa3, - 0x9f, 0x94, 0x9c, 0xac, 0xae, 0xa9, 0x98, 0x82, 0x78, 0x71, 0x6b, 0x62, - 0x59, 0x4f, 0x4b, 0x4f, 0x61, 0x6f, 0x79, 0x87, 0x8f, 0x95, 0x8e, 0x75, - 0x5f, 0x57, 0x58, 0x5e, 0x62, 0x60, 0x5f, 0x5e, 0x61, 0x67, 0x69, 0x6a, - 0x6b, 0x6c, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x74, 0x73, 0x73, 0x73, 0x71, - 0x6f, 0x72, 0x73, 0x75, 0x76, 0x74, 0x71, 0x6f, 0x71, 0x7a, 0x8c, 0x9c, - 0xa6, 0xaa, 0xac, 0xab, 0xa3, 0x9a, 0x94, 0x88, 0x7d, 0x76, 0x72, 0x70, - 0x70, 0x6f, 0x70, 0x6f, 0x6e, 0x6c, 0x6b, 0x6b, 0x6c, 0x6c, 0x6f, 0x72, - 0x74, 0x77, 0x79, 0x7b, 0x7b, 0x7d, 0x7e, 0x7d, 0x7d, 0x7b, 0x7c, 0x7e, - 0x7e, 0x7d, 0x7b, 0x79, 0x79, 0x78, 0x76, 0x76, 0x75, 0x76, 0x77, 0x76, - 0x79, 0x7e, 0x7f, 0x80, 0x82, 0x85, 0x86, 0x87, 0x86, 0x85, 0x86, 0x86, - 0x84, 0x85, 0x87, 0x88, 0x8c, 0x8a, 0x88, 0x87, 0x84, 0x80, 0x7d, 0x79, - 0x78, 0x76, 0x72, 0x6f, 0x6e, 0x6e, 0x6c, 0x69, 0x67, 0x66, 0x65, 0x64, - 0x62, 0x62, 0x62, 0x61, 0x61, 0x60, 0x5f, 0x60, 0x60, 0x5f, 0x60, 0x5f, - 0x5e, 0x5e, 0x5f, 0x62, 0x61, 0x5c, 0x6a, 0x9b, 0xd2, 0xdc, 0xdb, 0xdc, - 0xdd, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xe0, - 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, - 0xe1, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, - 0xdf, 0xde, 0xdd, 0xdd, 0xdc, 0xdd, 0xde, 0xde, 0xde, 0xdc, 0xdb, 0xda, - 0xd8, 0xd6, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd7, 0xd6, 0xd5, 0xd4, 0xd2, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd3, 0xd3, 0xd2, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, - 0xd2, 0xd1, 0xd1, 0xd1, 0xcf, 0xcf, 0xce, 0xce, 0xcd, 0xcb, 0xcb, 0xc9, - 0xc7, 0xc5, 0xc1, 0xbe, 0xbb, 0xb7, 0xaf, 0xa2, 0x96, 0x98, 0x9c, 0xa1, - 0xa5, 0xa7, 0xa7, 0xa6, 0xa4, 0xa1, 0x9e, 0x9e, 0x9d, 0x9c, 0x94, 0x89, - 0x7f, 0x7c, 0x78, 0x69, 0x6a, 0x81, 0x90, 0xa0, 0xab, 0xaf, 0xae, 0xa9, - 0x97, 0x77, 0x66, 0x61, 0x63, 0x6e, 0x83, 0xa2, 0xae, 0xa7, 0x87, 0x54, - 0x5c, 0x7f, 0x8c, 0x88, 0x79, 0x87, 0x9c, 0xa3, 0x9e, 0x91, 0xa2, 0xbc, - 0xbf, 0xb6, 0x9f, 0x87, 0x77, 0x6c, 0x65, 0x5c, 0x54, 0x4b, 0x4d, 0x56, - 0x67, 0x70, 0x7d, 0x8d, 0x95, 0x99, 0x8e, 0x71, 0x5c, 0x56, 0x59, 0x5f, - 0x60, 0x5c, 0x5b, 0x5f, 0x64, 0x68, 0x6a, 0x6b, 0x6c, 0x6d, 0x70, 0x71, - 0x71, 0x72, 0x74, 0x75, 0x74, 0x73, 0x73, 0x71, 0x71, 0x73, 0x75, 0x78, - 0x7a, 0x78, 0x74, 0x72, 0x74, 0x80, 0x92, 0xa0, 0xa7, 0xaa, 0xaa, 0xa4, - 0x99, 0x8c, 0x84, 0x7a, 0x72, 0x6d, 0x6b, 0x69, 0x69, 0x6a, 0x6a, 0x69, - 0x68, 0x67, 0x66, 0x66, 0x66, 0x67, 0x6b, 0x6e, 0x72, 0x75, 0x77, 0x7a, - 0x7b, 0x7d, 0x7e, 0x7d, 0x7d, 0x7b, 0x7b, 0x7c, 0x7c, 0x7b, 0x7a, 0x77, - 0x76, 0x76, 0x75, 0x75, 0x77, 0x78, 0x78, 0x78, 0x7b, 0x7f, 0x80, 0x82, - 0x84, 0x86, 0x87, 0x88, 0x87, 0x86, 0x87, 0x87, 0x86, 0x86, 0x87, 0x87, - 0x89, 0x86, 0x85, 0x84, 0x81, 0x7d, 0x7a, 0x78, 0x76, 0x74, 0x72, 0x70, - 0x6f, 0x6e, 0x6c, 0x6a, 0x67, 0x66, 0x66, 0x65, 0x62, 0x62, 0x62, 0x62, - 0x60, 0x60, 0x60, 0x60, 0x60, 0x5f, 0x5f, 0x5f, 0x5f, 0x60, 0x5f, 0x61, - 0x5e, 0x5f, 0x79, 0xb9, 0xd9, 0xdb, 0xdb, 0xdb, 0xdd, 0xde, 0xde, 0xde, - 0xde, 0xdd, 0xdd, 0xdd, 0xdc, 0xdd, 0xde, 0xde, 0xde, 0xe0, 0xe1, 0xe1, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe0, 0xe2, 0xe1, 0xe1, 0xe0, 0xe0, 0xe1, - 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe0, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xdf, 0xde, 0xde, - 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xda, 0xdb, 0xdb, 0xda, 0xd6, 0xd3, - 0xd2, 0xd2, 0xd2, 0xd4, 0xd5, 0xd5, 0xd4, 0xd3, 0xcf, 0xcd, 0xcd, 0xce, - 0xd0, 0xd2, 0xd2, 0xd1, 0xd0, 0xce, 0xce, 0xcf, 0xd0, 0xcf, 0xcf, 0xcf, - 0xce, 0xce, 0xcd, 0xcd, 0xcc, 0xca, 0xca, 0xc9, 0xc8, 0xc6, 0xc2, 0xbf, - 0xbc, 0xb9, 0xb3, 0xa8, 0x99, 0x92, 0x92, 0x99, 0xa0, 0xa3, 0xa5, 0xa5, - 0xa3, 0xa2, 0xa0, 0x9f, 0x9f, 0x9d, 0x98, 0x8e, 0x84, 0x7f, 0x7a, 0x6d, - 0x65, 0x74, 0x83, 0x98, 0xa8, 0xae, 0xb0, 0xac, 0x9c, 0x78, 0x67, 0x63, - 0x64, 0x6b, 0x7a, 0x98, 0xac, 0xae, 0x95, 0x63, 0x68, 0x87, 0x93, 0x8d, - 0x77, 0x79, 0x94, 0xa2, 0xa0, 0x95, 0x9a, 0xb1, 0xbb, 0xb7, 0xa4, 0x8e, - 0x78, 0x68, 0x60, 0x59, 0x4e, 0x49, 0x53, 0x5d, 0x6a, 0x6f, 0x82, 0x94, - 0x9b, 0x9b, 0x8c, 0x6d, 0x5b, 0x56, 0x5a, 0x5f, 0x5e, 0x5c, 0x5d, 0x61, - 0x66, 0x69, 0x6a, 0x6b, 0x6c, 0x6f, 0x72, 0x73, 0x73, 0x75, 0x75, 0x74, - 0x74, 0x74, 0x72, 0x71, 0x73, 0x74, 0x76, 0x7b, 0x7e, 0x7c, 0x79, 0x77, - 0x79, 0x86, 0x96, 0xa2, 0xa8, 0xa8, 0xa4, 0x98, 0x87, 0x7b, 0x75, 0x70, - 0x6c, 0x68, 0x65, 0x65, 0x64, 0x66, 0x67, 0x66, 0x65, 0x63, 0x63, 0x64, - 0x64, 0x65, 0x69, 0x6d, 0x71, 0x73, 0x74, 0x78, 0x7b, 0x7e, 0x7e, 0x7e, - 0x7d, 0x7a, 0x7a, 0x7a, 0x7a, 0x79, 0x78, 0x77, 0x75, 0x75, 0x75, 0x77, - 0x79, 0x7b, 0x7c, 0x7c, 0x80, 0x82, 0x84, 0x85, 0x87, 0x88, 0x87, 0x89, - 0x89, 0x88, 0x88, 0x87, 0x86, 0x86, 0x87, 0x85, 0x86, 0x84, 0x82, 0x81, - 0x7e, 0x7a, 0x78, 0x75, 0x74, 0x73, 0x71, 0x70, 0x6e, 0x6d, 0x6b, 0x6a, - 0x67, 0x66, 0x66, 0x65, 0x62, 0x61, 0x62, 0x62, 0x60, 0x60, 0x60, 0x5f, - 0x5f, 0x5f, 0x60, 0x5f, 0x60, 0x60, 0x60, 0x60, 0x5f, 0x6e, 0x8d, 0xc7, - 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xde, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xdd, - 0xdd, 0xdd, 0xdf, 0xdf, 0xdf, 0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe2, 0xe1, 0xe2, 0xe1, 0xe1, 0xe0, 0xe0, 0xe1, 0xe3, 0xe3, 0xe3, 0xe2, - 0xe3, 0xe3, 0xe2, 0xe2, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe1, - 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe0, 0xdf, 0xdf, 0xde, 0xde, 0xdc, 0xdc, - 0xda, 0xda, 0xd9, 0xda, 0xda, 0xdb, 0xd9, 0xd7, 0xd6, 0xd4, 0xd2, 0xd2, - 0xd2, 0xd3, 0xd3, 0xd3, 0xd1, 0xcd, 0xcb, 0xcb, 0xcc, 0xce, 0xd1, 0xd1, - 0xd0, 0xce, 0xcc, 0xcd, 0xce, 0xcf, 0xcf, 0xce, 0xcd, 0xcd, 0xcd, 0xcd, - 0xcb, 0xc9, 0xca, 0xc9, 0xc8, 0xc7, 0xc4, 0xbf, 0xbb, 0xb9, 0xb5, 0xac, - 0x9e, 0x92, 0x8e, 0x93, 0x9b, 0xa1, 0xa4, 0xa4, 0xa2, 0xa3, 0xa2, 0xa1, - 0xa0, 0x9e, 0x9b, 0x92, 0x88, 0x82, 0x7d, 0x71, 0x66, 0x6d, 0x79, 0x91, - 0xa4, 0xae, 0xb1, 0xaf, 0xa0, 0x7a, 0x69, 0x65, 0x65, 0x6a, 0x76, 0x8e, - 0xa8, 0xaf, 0x9f, 0x71, 0x70, 0x89, 0x93, 0x8d, 0x78, 0x6d, 0x8a, 0x9f, - 0xa3, 0x9b, 0x8d, 0x96, 0xa8, 0xac, 0xa4, 0x91, 0x77, 0x66, 0x5e, 0x55, - 0x4a, 0x48, 0x57, 0x62, 0x6a, 0x70, 0x88, 0x99, 0x9f, 0x9a, 0x88, 0x69, - 0x59, 0x57, 0x5c, 0x5f, 0x5d, 0x5d, 0x5f, 0x62, 0x67, 0x6a, 0x6c, 0x6c, - 0x6d, 0x70, 0x72, 0x73, 0x74, 0x76, 0x76, 0x74, 0x74, 0x74, 0x73, 0x72, - 0x73, 0x74, 0x77, 0x7d, 0x81, 0x7f, 0x7d, 0x7c, 0x7e, 0x89, 0x98, 0xa2, - 0xa6, 0xa5, 0x9c, 0x8b, 0x79, 0x70, 0x6d, 0x69, 0x67, 0x64, 0x64, 0x64, - 0x63, 0x64, 0x65, 0x65, 0x63, 0x62, 0x62, 0x63, 0x65, 0x66, 0x6a, 0x6e, - 0x71, 0x72, 0x74, 0x77, 0x7b, 0x7e, 0x7e, 0x7e, 0x7d, 0x7a, 0x78, 0x77, - 0x76, 0x77, 0x76, 0x76, 0x76, 0x77, 0x78, 0x7a, 0x7c, 0x7f, 0x7f, 0x80, - 0x84, 0x86, 0x86, 0x87, 0x89, 0x8a, 0x89, 0x8a, 0x8a, 0x89, 0x88, 0x87, - 0x86, 0x86, 0x86, 0x85, 0x84, 0x82, 0x80, 0x7f, 0x7c, 0x78, 0x77, 0x74, - 0x73, 0x73, 0x70, 0x6f, 0x6e, 0x6c, 0x6a, 0x69, 0x67, 0x66, 0x65, 0x65, - 0x63, 0x62, 0x62, 0x61, 0x60, 0x60, 0x60, 0x5f, 0x5f, 0x60, 0x60, 0x5f, - 0x60, 0x60, 0x5f, 0x5f, 0x61, 0x7e, 0x9e, 0xce, 0xdb, 0xdb, 0xdc, 0xdd, - 0xdd, 0xde, 0xdf, 0xde, 0xde, 0xdf, 0xde, 0xde, 0xdd, 0xde, 0xdf, 0xdf, - 0xdf, 0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe2, 0xe1, - 0xe1, 0xe1, 0xe0, 0xe1, 0xe3, 0xe3, 0xe3, 0xe2, 0xe3, 0xe3, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, - 0xe1, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xde, 0xdd, 0xdb, 0xdb, 0xd9, 0xda, - 0xda, 0xdb, 0xda, 0xd9, 0xd8, 0xd6, 0xd4, 0xd2, 0xd1, 0xd1, 0xd2, 0xd3, - 0xd2, 0xce, 0xcb, 0xca, 0xc9, 0xcb, 0xcf, 0xd0, 0xd0, 0xce, 0xcd, 0xcc, - 0xcd, 0xce, 0xce, 0xce, 0xcd, 0xcd, 0xcc, 0xcc, 0xcb, 0xca, 0xc9, 0xc9, - 0xc8, 0xc7, 0xc4, 0xc0, 0xbc, 0xb9, 0xb6, 0xae, 0xa1, 0x95, 0x8f, 0x8f, - 0x98, 0xa0, 0xa3, 0xa3, 0xa2, 0xa3, 0xa3, 0xa2, 0xa1, 0x9f, 0x9c, 0x93, - 0x8a, 0x85, 0x7f, 0x73, 0x66, 0x68, 0x74, 0x8d, 0xa2, 0xae, 0xb2, 0xb0, - 0xa3, 0x7c, 0x69, 0x66, 0x66, 0x6a, 0x74, 0x89, 0xa4, 0xae, 0xa3, 0x7a, - 0x75, 0x8b, 0x94, 0x8d, 0x78, 0x67, 0x82, 0x9b, 0xa2, 0x9d, 0x8a, 0x84, - 0x96, 0x9f, 0x9e, 0x90, 0x76, 0x64, 0x5b, 0x52, 0x47, 0x4a, 0x5b, 0x64, - 0x6c, 0x72, 0x8c, 0x9c, 0x9f, 0x9a, 0x86, 0x65, 0x58, 0x57, 0x5c, 0x5e, - 0x5c, 0x5e, 0x60, 0x63, 0x68, 0x6b, 0x6c, 0x6c, 0x6d, 0x71, 0x73, 0x74, - 0x74, 0x76, 0x76, 0x74, 0x75, 0x75, 0x74, 0x73, 0x74, 0x76, 0x79, 0x7f, - 0x83, 0x82, 0x7f, 0x7e, 0x80, 0x8b, 0x99, 0xa2, 0xa3, 0xa0, 0x95, 0x82, - 0x72, 0x6c, 0x68, 0x65, 0x63, 0x62, 0x63, 0x64, 0x63, 0x65, 0x65, 0x64, - 0x63, 0x62, 0x61, 0x63, 0x65, 0x67, 0x6a, 0x6f, 0x72, 0x73, 0x73, 0x76, - 0x7a, 0x7d, 0x7e, 0x7e, 0x7d, 0x7a, 0x78, 0x76, 0x75, 0x75, 0x76, 0x77, - 0x77, 0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x81, 0x82, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x8b, 0x8a, 0x8a, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x86, 0x85, 0x84, - 0x81, 0x81, 0x7f, 0x7d, 0x7b, 0x77, 0x75, 0x74, 0x74, 0x72, 0x70, 0x70, - 0x6d, 0x6c, 0x6a, 0x69, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x61, - 0x61, 0x60, 0x5f, 0x5f, 0x5f, 0x60, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5e, - 0x65, 0x97, 0xb9, 0xd4, 0xda, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xde, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xe0, 0xe1, 0xe1, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe0, 0xe0, 0xe1, 0xe1, 0xe2, - 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe2, 0xe1, 0xe1, 0xe1, - 0xe2, 0xe2, 0xe2, 0xe1, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe0, 0xe1, 0xe1, - 0xe1, 0xe1, 0xdf, 0xdf, 0xdd, 0xdd, 0xdb, 0xdb, 0xdb, 0xda, 0xd9, 0xd8, - 0xd9, 0xda, 0xd8, 0xd5, 0xd2, 0xd1, 0xd1, 0xd2, 0xd3, 0xd1, 0xce, 0xcc, - 0xc9, 0xc7, 0xcb, 0xcd, 0xcf, 0xcf, 0xcd, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, - 0xcc, 0xcb, 0xcc, 0xcc, 0xcc, 0xcb, 0xc8, 0xc8, 0xc8, 0xc7, 0xc5, 0xc0, - 0xbd, 0xbb, 0xb7, 0xb1, 0xa7, 0x9c, 0x94, 0x8d, 0x94, 0x9d, 0xa0, 0xa1, - 0xa1, 0xa2, 0xa3, 0xa3, 0xa1, 0x9f, 0x9c, 0x96, 0x8f, 0x8a, 0x81, 0x74, - 0x68, 0x64, 0x6c, 0x86, 0x9f, 0xac, 0xb2, 0xb1, 0xa5, 0x7f, 0x6a, 0x67, - 0x67, 0x68, 0x71, 0x84, 0x9e, 0xa9, 0xa7, 0x89, 0x81, 0x94, 0x99, 0x8f, - 0x78, 0x63, 0x78, 0x93, 0x9e, 0x9d, 0x8c, 0x74, 0x7a, 0x83, 0x8c, 0x8a, - 0x73, 0x5e, 0x54, 0x4a, 0x46, 0x50, 0x60, 0x6a, 0x70, 0x79, 0x93, 0x9e, - 0x9f, 0x97, 0x81, 0x61, 0x57, 0x58, 0x5c, 0x5e, 0x5c, 0x5e, 0x60, 0x65, - 0x68, 0x6b, 0x6b, 0x6b, 0x6e, 0x72, 0x74, 0x75, 0x75, 0x75, 0x75, 0x75, - 0x76, 0x76, 0x76, 0x74, 0x76, 0x79, 0x7d, 0x83, 0x86, 0x84, 0x81, 0x81, - 0x83, 0x8c, 0x97, 0x9e, 0x9d, 0x96, 0x88, 0x77, 0x6c, 0x67, 0x64, 0x62, - 0x61, 0x61, 0x63, 0x64, 0x65, 0x66, 0x65, 0x63, 0x63, 0x62, 0x61, 0x63, - 0x65, 0x67, 0x6b, 0x70, 0x72, 0x74, 0x74, 0x74, 0x77, 0x7c, 0x7e, 0x7f, - 0x7d, 0x7a, 0x76, 0x74, 0x74, 0x75, 0x76, 0x79, 0x7a, 0x7a, 0x7c, 0x7f, - 0x81, 0x82, 0x83, 0x86, 0x88, 0x89, 0x89, 0x8a, 0x8b, 0x8c, 0x8c, 0x8b, - 0x8a, 0x89, 0x87, 0x86, 0x86, 0x85, 0x85, 0x84, 0x7f, 0x7e, 0x7c, 0x7a, - 0x77, 0x75, 0x75, 0x74, 0x73, 0x72, 0x70, 0x6f, 0x6e, 0x6c, 0x69, 0x68, - 0x66, 0x65, 0x64, 0x62, 0x63, 0x62, 0x61, 0x61, 0x61, 0x60, 0x5f, 0x5f, - 0x5f, 0x5f, 0x5f, 0x5e, 0x5f, 0x5f, 0x5f, 0x5e, 0x71, 0xb0, 0xcf, 0xd8, - 0xda, 0xdb, 0xdc, 0xdc, 0xdc, 0xdb, 0xdc, 0xdd, 0xdd, 0xde, 0xde, 0xdf, - 0xdf, 0xdf, 0xde, 0xde, 0xdf, 0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe1, 0xe0, 0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe1, 0xe0, - 0xe1, 0xe1, 0xe0, 0xe0, 0xe1, 0xe0, 0xe0, 0xe1, 0xe1, 0xe0, 0xdf, 0xe0, - 0xe0, 0xe0, 0xe1, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, - 0xde, 0xde, 0xde, 0xde, 0xde, 0xdc, 0xda, 0xd8, 0xd9, 0xd9, 0xd8, 0xd7, - 0xd6, 0xd4, 0xd4, 0xd2, 0xd3, 0xd3, 0xd2, 0xd0, 0xcb, 0xc6, 0xc6, 0xc8, - 0xca, 0xcd, 0xce, 0xcc, 0xc9, 0xc8, 0xc9, 0xc9, 0xcb, 0xc9, 0xca, 0xca, - 0xcb, 0xcb, 0xc9, 0xc7, 0xc7, 0xc6, 0xc5, 0xc2, 0xbf, 0xbc, 0xb8, 0xb2, - 0xac, 0xa4, 0x9c, 0x90, 0x8d, 0x96, 0x9a, 0x9c, 0x9f, 0xa0, 0xa1, 0xa1, - 0xa0, 0x9e, 0x9e, 0x99, 0x93, 0x8e, 0x86, 0x78, 0x6a, 0x62, 0x66, 0x7b, - 0x97, 0xa9, 0xb1, 0xb2, 0xa8, 0x85, 0x6b, 0x68, 0x68, 0x6a, 0x70, 0x7e, - 0x94, 0xa1, 0xab, 0x9a, 0x91, 0xa8, 0xab, 0x93, 0x7a, 0x63, 0x6f, 0x89, - 0x95, 0x9b, 0x91, 0x6d, 0x5d, 0x5d, 0x69, 0x77, 0x6b, 0x59, 0x4f, 0x48, - 0x4d, 0x59, 0x65, 0x6c, 0x74, 0x82, 0x9a, 0xa0, 0x9d, 0x93, 0x79, 0x5d, - 0x57, 0x59, 0x5e, 0x5d, 0x5d, 0x5f, 0x61, 0x65, 0x69, 0x6b, 0x6b, 0x6c, - 0x6f, 0x72, 0x76, 0x78, 0x78, 0x77, 0x76, 0x75, 0x76, 0x77, 0x77, 0x77, - 0x7a, 0x7f, 0x83, 0x88, 0x88, 0x86, 0x83, 0x83, 0x85, 0x8d, 0x95, 0x96, - 0x8f, 0x86, 0x77, 0x6b, 0x65, 0x62, 0x61, 0x60, 0x61, 0x62, 0x64, 0x65, - 0x66, 0x66, 0x66, 0x64, 0x63, 0x62, 0x62, 0x64, 0x67, 0x69, 0x6d, 0x70, - 0x73, 0x74, 0x74, 0x74, 0x75, 0x79, 0x7d, 0x7e, 0x7d, 0x7a, 0x76, 0x73, - 0x73, 0x76, 0x79, 0x7e, 0x80, 0x80, 0x81, 0x83, 0x86, 0x86, 0x87, 0x89, - 0x8c, 0x8c, 0x8d, 0x8e, 0x8e, 0x8e, 0x8d, 0x8b, 0x8a, 0x89, 0x87, 0x86, - 0x85, 0x85, 0x85, 0x84, 0x7d, 0x7b, 0x79, 0x78, 0x76, 0x75, 0x73, 0x72, - 0x71, 0x71, 0x70, 0x6e, 0x6d, 0x6b, 0x68, 0x67, 0x64, 0x64, 0x63, 0x62, - 0x63, 0x61, 0x60, 0x61, 0x61, 0x60, 0x5f, 0x5f, 0x5f, 0x5f, 0x5e, 0x5e, - 0x5e, 0x5f, 0x5f, 0x62, 0x88, 0xc1, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdc, - 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdd, 0xde, 0xde, 0xdf, 0xdf, 0xde, 0xde, - 0xde, 0xe0, 0xe1, 0xe0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe1, 0xe1, 0xe2, 0xe2, 0xe0, 0xe1, 0xe0, 0xdf, 0xe0, 0xe0, 0xdf, 0xdf, - 0xe0, 0xe0, 0xdf, 0xe0, 0xe0, 0xe0, 0xde, 0xdf, 0xdf, 0xdf, 0xde, 0xdf, - 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xdf, 0xe0, 0xe0, 0xe0, - 0xe0, 0xdf, 0xdd, 0xdc, 0xda, 0xda, 0xd9, 0xd7, 0xd6, 0xd6, 0xd5, 0xd5, - 0xd4, 0xd2, 0xd2, 0xd1, 0xcf, 0xcb, 0xc5, 0xc4, 0xc4, 0xc7, 0xcb, 0xcd, - 0xcb, 0xc8, 0xc6, 0xc5, 0xc8, 0xc9, 0xc9, 0xc9, 0xc8, 0xca, 0xc9, 0xc7, - 0xc6, 0xc5, 0xc5, 0xc2, 0xc0, 0xbe, 0xba, 0xb3, 0xad, 0xa7, 0xa1, 0x96, - 0x8a, 0x8d, 0x93, 0x97, 0x9b, 0x9d, 0xa1, 0xa2, 0xa1, 0x9f, 0x9e, 0x9b, - 0x95, 0x92, 0x8b, 0x7f, 0x70, 0x64, 0x64, 0x71, 0x8e, 0xa5, 0xaf, 0xb1, - 0xa9, 0x8a, 0x6d, 0x68, 0x69, 0x6c, 0x6f, 0x7a, 0x8a, 0x97, 0xa9, 0xa2, - 0x93, 0xb0, 0xb5, 0x9b, 0x7e, 0x65, 0x6b, 0x83, 0x8f, 0x95, 0x95, 0x75, - 0x59, 0x4e, 0x4d, 0x58, 0x5a, 0x56, 0x55, 0x57, 0x5c, 0x60, 0x65, 0x69, - 0x72, 0x86, 0x9d, 0x9e, 0x99, 0x8b, 0x70, 0x5a, 0x59, 0x5b, 0x5d, 0x5b, - 0x5f, 0x61, 0x63, 0x65, 0x69, 0x6b, 0x6b, 0x6c, 0x6f, 0x72, 0x76, 0x78, - 0x78, 0x78, 0x77, 0x75, 0x76, 0x78, 0x79, 0x7b, 0x7f, 0x83, 0x86, 0x89, - 0x88, 0x85, 0x82, 0x82, 0x84, 0x8a, 0x8f, 0x89, 0x7d, 0x75, 0x6c, 0x64, - 0x61, 0x60, 0x5f, 0x5f, 0x60, 0x63, 0x65, 0x66, 0x68, 0x68, 0x67, 0x66, - 0x65, 0x64, 0x63, 0x66, 0x69, 0x6b, 0x6e, 0x72, 0x74, 0x74, 0x74, 0x73, - 0x74, 0x77, 0x7c, 0x7d, 0x7c, 0x7a, 0x75, 0x73, 0x74, 0x78, 0x7e, 0x82, - 0x85, 0x86, 0x87, 0x89, 0x8b, 0x8c, 0x8c, 0x8c, 0x8e, 0x90, 0x91, 0x91, - 0x90, 0x90, 0x8e, 0x8c, 0x8b, 0x8a, 0x87, 0x86, 0x85, 0x84, 0x84, 0x82, - 0x7e, 0x7a, 0x79, 0x78, 0x76, 0x75, 0x73, 0x71, 0x71, 0x70, 0x6e, 0x6c, - 0x6b, 0x6a, 0x68, 0x66, 0x65, 0x63, 0x63, 0x62, 0x62, 0x60, 0x60, 0x61, - 0x61, 0x5f, 0x5e, 0x5e, 0x5f, 0x60, 0x60, 0x5f, 0x60, 0x60, 0x5f, 0x65, - 0x9c, 0xca, 0xd9, 0xd8, 0xd8, 0xda, 0xdb, 0xdc, 0xdc, 0xdb, 0xdb, 0xdc, - 0xdc, 0xdc, 0xdc, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xe0, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, - 0xdf, 0xdf, 0xdf, 0xde, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xdf, 0xde, 0xde, - 0xde, 0xdf, 0xdf, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, - 0xde, 0xde, 0xdf, 0xdf, 0xde, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xde, 0xde, - 0xdc, 0xdb, 0xd9, 0xd8, 0xd6, 0xd5, 0xd5, 0xd6, 0xd4, 0xd3, 0xd3, 0xd3, - 0xd1, 0xce, 0xc8, 0xc3, 0xc2, 0xc3, 0xc8, 0xcd, 0xcd, 0xc9, 0xc6, 0xc5, - 0xc5, 0xc8, 0xc9, 0xc9, 0xc8, 0xc9, 0xc7, 0xc7, 0xc6, 0xc5, 0xc4, 0xc1, - 0xc0, 0xbf, 0xbb, 0xb4, 0xaf, 0xaa, 0xa5, 0x9b, 0x8b, 0x88, 0x8e, 0x93, - 0x98, 0x9c, 0xa0, 0xa1, 0xa1, 0xa0, 0x9f, 0x9c, 0x96, 0x92, 0x8e, 0x85, - 0x75, 0x68, 0x64, 0x6b, 0x89, 0xa2, 0xad, 0xb0, 0xaa, 0x8f, 0x6d, 0x67, - 0x69, 0x6d, 0x70, 0x7a, 0x85, 0x91, 0xa6, 0xa6, 0x93, 0xa9, 0xb1, 0xa0, - 0x83, 0x66, 0x68, 0x7e, 0x89, 0x8e, 0x93, 0x7d, 0x62, 0x52, 0x44, 0x42, - 0x4d, 0x5d, 0x65, 0x6b, 0x6a, 0x64, 0x64, 0x66, 0x6e, 0x86, 0x9c, 0x9b, - 0x94, 0x83, 0x6a, 0x59, 0x59, 0x5b, 0x5c, 0x5b, 0x60, 0x62, 0x64, 0x66, - 0x69, 0x6b, 0x6c, 0x6d, 0x6f, 0x71, 0x75, 0x77, 0x77, 0x76, 0x77, 0x77, - 0x77, 0x78, 0x7b, 0x7d, 0x82, 0x85, 0x87, 0x87, 0x86, 0x84, 0x82, 0x82, - 0x83, 0x85, 0x85, 0x7c, 0x72, 0x6c, 0x67, 0x61, 0x5e, 0x5e, 0x5e, 0x5f, - 0x61, 0x65, 0x66, 0x68, 0x69, 0x69, 0x68, 0x66, 0x65, 0x65, 0x65, 0x67, - 0x6a, 0x6b, 0x6e, 0x72, 0x75, 0x75, 0x74, 0x72, 0x73, 0x76, 0x7a, 0x7c, - 0x7c, 0x7a, 0x75, 0x74, 0x76, 0x7b, 0x81, 0x85, 0x88, 0x88, 0x8a, 0x8c, - 0x8d, 0x8f, 0x8f, 0x8f, 0x90, 0x92, 0x93, 0x93, 0x92, 0x91, 0x8e, 0x8c, - 0x8b, 0x89, 0x87, 0x85, 0x84, 0x83, 0x81, 0x80, 0x7d, 0x7a, 0x79, 0x78, - 0x76, 0x74, 0x72, 0x71, 0x70, 0x6f, 0x6d, 0x6b, 0x6a, 0x69, 0x68, 0x66, - 0x65, 0x63, 0x63, 0x62, 0x61, 0x5f, 0x60, 0x61, 0x61, 0x5f, 0x5d, 0x5d, - 0x5e, 0x60, 0x61, 0x60, 0x60, 0x60, 0x5f, 0x66, 0xa7, 0xd0, 0xda, 0xd8, - 0xd8, 0xd9, 0xdb, 0xdc, 0xdc, 0xdb, 0xdb, 0xdc, 0xdc, 0xdb, 0xdb, 0xdc, - 0xdd, 0xdd, 0xde, 0xdf, 0xde, 0xdf, 0xdf, 0xde, 0xde, 0xdf, 0xde, 0xdf, - 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xdf, 0xdf, 0xdf, 0xde, - 0xdf, 0xdf, 0xde, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdc, - 0xdc, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xdd, 0xde, 0xde, - 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe0, 0xde, 0xdd, 0xdd, 0xdc, 0xda, 0xd9, - 0xd7, 0xd5, 0xd5, 0xd5, 0xd3, 0xd3, 0xd3, 0xd3, 0xd2, 0xd0, 0xcb, 0xc5, - 0xc2, 0xc1, 0xc5, 0xcb, 0xcd, 0xca, 0xc8, 0xc5, 0xc4, 0xc7, 0xc8, 0xc8, - 0xc7, 0xc8, 0xc7, 0xc7, 0xc6, 0xc5, 0xc2, 0xc0, 0xc0, 0xbf, 0xbb, 0xb4, - 0xaf, 0xab, 0xa7, 0x9e, 0x8d, 0x85, 0x8a, 0x8f, 0x96, 0x9b, 0x9f, 0xa0, - 0xa0, 0xa0, 0xa0, 0x9d, 0x97, 0x93, 0x90, 0x87, 0x79, 0x6b, 0x66, 0x68, - 0x83, 0x9f, 0xab, 0xae, 0xaa, 0x91, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x7a, - 0x84, 0x90, 0xa3, 0xa8, 0x93, 0xa1, 0xa9, 0xa1, 0x87, 0x69, 0x67, 0x7a, - 0x84, 0x8a, 0x91, 0x7f, 0x66, 0x56, 0x44, 0x3b, 0x4b, 0x64, 0x70, 0x76, - 0x70, 0x66, 0x63, 0x64, 0x6b, 0x88, 0x9a, 0x97, 0x8f, 0x7e, 0x66, 0x59, - 0x5a, 0x5b, 0x5b, 0x5c, 0x60, 0x63, 0x65, 0x67, 0x68, 0x6b, 0x6d, 0x6d, - 0x6e, 0x70, 0x74, 0x75, 0x75, 0x75, 0x76, 0x76, 0x76, 0x78, 0x7a, 0x7d, - 0x81, 0x84, 0x84, 0x84, 0x82, 0x81, 0x80, 0x7f, 0x7f, 0x7f, 0x7d, 0x74, - 0x6d, 0x69, 0x64, 0x5e, 0x5e, 0x5e, 0x5e, 0x60, 0x62, 0x66, 0x68, 0x69, - 0x6a, 0x69, 0x68, 0x66, 0x66, 0x65, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x72, - 0x75, 0x75, 0x74, 0x72, 0x73, 0x75, 0x78, 0x79, 0x7a, 0x79, 0x76, 0x77, - 0x78, 0x7d, 0x83, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8f, 0x90, 0x91, 0x91, - 0x91, 0x93, 0x93, 0x93, 0x92, 0x90, 0x8e, 0x8c, 0x8b, 0x89, 0x86, 0x84, - 0x83, 0x82, 0x80, 0x7e, 0x7d, 0x7a, 0x79, 0x78, 0x76, 0x75, 0x72, 0x71, - 0x70, 0x6f, 0x6b, 0x68, 0x68, 0x68, 0x67, 0x64, 0x63, 0x62, 0x61, 0x61, - 0x60, 0x60, 0x61, 0x61, 0x61, 0x5f, 0x5d, 0x5e, 0x5e, 0x60, 0x61, 0x61, - 0x61, 0x61, 0x5e, 0x6b, 0xb6, 0xd4, 0xd9, 0xd8, 0xd8, 0xd9, 0xda, 0xda, - 0xda, 0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xdb, 0xdd, 0xdd, 0xdd, 0xde, 0xdf, - 0xde, 0xdf, 0xe0, 0xdf, 0xdf, 0xdf, 0xde, 0xdf, 0xe1, 0xe2, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe1, 0xdf, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xde, 0xdd, - 0xdd, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdd, 0xdd, 0xdd, 0xde, 0xde, - 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xde, 0xde, - 0xde, 0xde, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xd9, 0xd8, 0xd7, 0xd5, - 0xd3, 0xd2, 0xd3, 0xd3, 0xd2, 0xd1, 0xce, 0xca, 0xc6, 0xc0, 0xc0, 0xc5, - 0xca, 0xcc, 0xcb, 0xc6, 0xc2, 0xc4, 0xc5, 0xc6, 0xc5, 0xc5, 0xc5, 0xc6, - 0xc6, 0xc5, 0xc1, 0xc0, 0xbf, 0xbe, 0xbc, 0xb6, 0xb0, 0xad, 0xaa, 0xa2, - 0x92, 0x84, 0x83, 0x87, 0x91, 0x99, 0x9d, 0x9e, 0x9e, 0x9f, 0x9f, 0x9e, - 0x99, 0x96, 0x92, 0x8b, 0x7f, 0x72, 0x6b, 0x67, 0x7b, 0x99, 0xa7, 0xac, - 0xa9, 0x92, 0x6e, 0x64, 0x66, 0x6d, 0x6f, 0x79, 0x86, 0x90, 0xa0, 0xaa, - 0x98, 0x95, 0x9c, 0xa3, 0x8d, 0x6d, 0x66, 0x73, 0x7a, 0x82, 0x8c, 0x7f, - 0x69, 0x5b, 0x4b, 0x41, 0x53, 0x6e, 0x7b, 0x7f, 0x74, 0x66, 0x62, 0x63, - 0x6c, 0x8b, 0x99, 0x91, 0x88, 0x77, 0x61, 0x58, 0x5b, 0x5c, 0x5b, 0x5d, - 0x60, 0x63, 0x64, 0x67, 0x68, 0x6a, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x73, - 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, 0x78, 0x7a, 0x7d, 0x7e, 0x7d, 0x7a, - 0x79, 0x7a, 0x79, 0x78, 0x78, 0x76, 0x72, 0x6b, 0x66, 0x63, 0x5f, 0x5d, - 0x5d, 0x5e, 0x5e, 0x60, 0x62, 0x66, 0x68, 0x6a, 0x6a, 0x6a, 0x69, 0x67, - 0x67, 0x66, 0x67, 0x69, 0x6c, 0x6d, 0x6f, 0x72, 0x75, 0x74, 0x73, 0x71, - 0x71, 0x72, 0x74, 0x75, 0x76, 0x76, 0x76, 0x79, 0x7c, 0x81, 0x86, 0x8b, - 0x8d, 0x8d, 0x8e, 0x90, 0x92, 0x92, 0x92, 0x92, 0x91, 0x93, 0x93, 0x93, - 0x92, 0x90, 0x8d, 0x8b, 0x8a, 0x87, 0x84, 0x80, 0x80, 0x7f, 0x7d, 0x7e, - 0x7b, 0x79, 0x78, 0x78, 0x76, 0x74, 0x71, 0x6f, 0x6e, 0x6d, 0x69, 0x67, - 0x66, 0x66, 0x65, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x61, 0x62, - 0x61, 0x5f, 0x5e, 0x60, 0x60, 0x60, 0x61, 0x62, 0x63, 0x62, 0x60, 0x75, - 0xc1, 0xd6, 0xd8, 0xd7, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xdb, 0xdb, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xde, 0xdf, 0xde, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xde, 0xdf, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, - 0xdf, 0xe0, 0xe0, 0xe0, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, - 0xe0, 0xe0, 0xdf, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xdd, 0xde, - 0xde, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, - 0xdc, 0xdc, 0xdd, 0xdd, 0xda, 0xda, 0xd9, 0xd7, 0xd6, 0xd3, 0xd3, 0xd2, - 0xd2, 0xd2, 0xd1, 0xce, 0xcb, 0xc5, 0xc0, 0xbf, 0xc5, 0xc9, 0xcb, 0xc9, - 0xc4, 0xc0, 0xc1, 0xc3, 0xc4, 0xc4, 0xc4, 0xc5, 0xc4, 0xc4, 0xc2, 0xbe, - 0xbe, 0xbe, 0xbc, 0xb8, 0xb2, 0xaf, 0xad, 0xa6, 0x9a, 0x89, 0x7f, 0x80, - 0x8a, 0x96, 0x99, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9b, 0x98, 0x95, 0x90, - 0x86, 0x7a, 0x71, 0x67, 0x70, 0x90, 0xa4, 0xab, 0xa9, 0x94, 0x6e, 0x62, - 0x63, 0x6d, 0x70, 0x77, 0x87, 0x91, 0x9d, 0xaa, 0x9d, 0x8f, 0x92, 0xa3, - 0x92, 0x72, 0x69, 0x6b, 0x6f, 0x77, 0x81, 0x78, 0x6a, 0x63, 0x5b, 0x56, - 0x62, 0x75, 0x7e, 0x80, 0x70, 0x62, 0x62, 0x65, 0x6f, 0x89, 0x94, 0x8b, - 0x81, 0x70, 0x5a, 0x57, 0x5c, 0x5d, 0x5b, 0x5e, 0x61, 0x64, 0x65, 0x67, - 0x69, 0x6a, 0x6d, 0x6e, 0x6f, 0x6f, 0x70, 0x71, 0x71, 0x71, 0x72, 0x71, - 0x72, 0x72, 0x73, 0x73, 0x73, 0x73, 0x72, 0x71, 0x72, 0x73, 0x73, 0x73, - 0x71, 0x6d, 0x69, 0x63, 0x60, 0x5e, 0x5c, 0x5d, 0x5d, 0x5e, 0x5f, 0x5f, - 0x62, 0x66, 0x69, 0x6a, 0x6c, 0x6c, 0x6a, 0x69, 0x68, 0x67, 0x68, 0x6a, - 0x6d, 0x6e, 0x71, 0x74, 0x76, 0x74, 0x73, 0x71, 0x70, 0x70, 0x70, 0x70, - 0x71, 0x73, 0x76, 0x7a, 0x7d, 0x83, 0x8a, 0x8f, 0x90, 0x91, 0x91, 0x93, - 0x95, 0x94, 0x94, 0x93, 0x91, 0x93, 0x92, 0x92, 0x91, 0x8f, 0x8b, 0x89, - 0x88, 0x85, 0x81, 0x7e, 0x7c, 0x7c, 0x7b, 0x7a, 0x79, 0x78, 0x78, 0x77, - 0x75, 0x73, 0x72, 0x6f, 0x6d, 0x6c, 0x68, 0x66, 0x65, 0x64, 0x63, 0x60, - 0x5f, 0x5f, 0x60, 0x61, 0x61, 0x60, 0x61, 0x62, 0x63, 0x61, 0x5f, 0x60, - 0x60, 0x60, 0x62, 0x64, 0x63, 0x62, 0x65, 0x88, 0xc8, 0xd7, 0xd6, 0xd6, - 0xd7, 0xd8, 0xd8, 0xd8, 0xd9, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, - 0xdb, 0xdb, 0xdc, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xdf, - 0xde, 0xde, 0xe0, 0xe0, 0xdf, 0xdf, 0xde, 0xdf, 0xe0, 0xdf, 0xde, 0xdf, - 0xde, 0xde, 0xdf, 0xdf, 0xde, 0xdd, 0xdc, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, - 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdb, 0xdc, 0xdc, 0xdc, 0xdb, - 0xdb, 0xdb, 0xdb, 0xd9, 0xd8, 0xd6, 0xd3, 0xd2, 0xd1, 0xd1, 0xd1, 0xd1, - 0xcf, 0xcc, 0xc5, 0xbd, 0xbe, 0xc3, 0xc6, 0xc8, 0xc7, 0xc2, 0xbe, 0xbf, - 0xc2, 0xc4, 0xc3, 0xc3, 0xc3, 0xc3, 0xc2, 0xbe, 0xbd, 0xbc, 0xba, 0xb7, - 0xb3, 0xb0, 0xae, 0xa9, 0x9f, 0x8f, 0x82, 0x7f, 0x82, 0x8e, 0x95, 0x97, - 0x99, 0x9b, 0x9d, 0x9d, 0x9b, 0x98, 0x96, 0x93, 0x8a, 0x7c, 0x72, 0x67, - 0x6a, 0x88, 0x9f, 0xa8, 0xa8, 0x96, 0x70, 0x61, 0x61, 0x6b, 0x72, 0x76, - 0x85, 0x8f, 0x9a, 0xa8, 0xa3, 0x8e, 0x8f, 0xa2, 0x97, 0x77, 0x6b, 0x67, - 0x68, 0x6e, 0x77, 0x6f, 0x67, 0x64, 0x62, 0x62, 0x6d, 0x79, 0x7f, 0x81, - 0x6e, 0x5f, 0x62, 0x68, 0x71, 0x7e, 0x86, 0x83, 0x7c, 0x69, 0x58, 0x58, - 0x5d, 0x5e, 0x5c, 0x5f, 0x63, 0x64, 0x66, 0x68, 0x6a, 0x6b, 0x6c, 0x6c, - 0x6e, 0x6e, 0x6e, 0x6f, 0x70, 0x6f, 0x70, 0x70, 0x6f, 0x70, 0x70, 0x6f, - 0x6d, 0x6c, 0x6d, 0x6e, 0x70, 0x6f, 0x70, 0x6f, 0x6d, 0x67, 0x62, 0x5e, - 0x5d, 0x5c, 0x5c, 0x5c, 0x5d, 0x5f, 0x60, 0x60, 0x63, 0x67, 0x6a, 0x6b, - 0x6c, 0x6d, 0x6b, 0x6a, 0x69, 0x68, 0x69, 0x6b, 0x6d, 0x6e, 0x72, 0x76, - 0x75, 0x72, 0x71, 0x70, 0x6f, 0x6f, 0x6e, 0x6e, 0x6f, 0x71, 0x75, 0x79, - 0x7d, 0x83, 0x8a, 0x8f, 0x91, 0x92, 0x92, 0x95, 0x96, 0x96, 0x95, 0x95, - 0x93, 0x91, 0x91, 0x8f, 0x8e, 0x8c, 0x88, 0x85, 0x83, 0x81, 0x7f, 0x7e, - 0x7b, 0x79, 0x78, 0x77, 0x79, 0x79, 0x78, 0x77, 0x75, 0x73, 0x71, 0x6e, - 0x6c, 0x69, 0x66, 0x65, 0x63, 0x62, 0x60, 0x5e, 0x5f, 0x5f, 0x60, 0x61, - 0x61, 0x60, 0x61, 0x62, 0x63, 0x61, 0x60, 0x60, 0x60, 0x61, 0x63, 0x65, - 0x64, 0x62, 0x67, 0x9a, 0xce, 0xd6, 0xd5, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, - 0xd9, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdc, 0xdb, 0xdb, 0xdd, 0xde, - 0xde, 0xdf, 0xdf, 0xdf, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, - 0xde, 0xdd, 0xde, 0xdf, 0xdf, 0xde, 0xdd, 0xde, 0xdd, 0xdd, 0xde, 0xdd, - 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdb, 0xdc, - 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xd9, 0xdb, 0xdc, 0xdc, 0xdb, - 0xd9, 0xd7, 0xd6, 0xd5, 0xd3, 0xd1, 0xd0, 0xd0, 0xd0, 0xcf, 0xcb, 0xc1, - 0xbb, 0xbd, 0xc0, 0xc4, 0xc8, 0xc5, 0xc0, 0xbe, 0xc0, 0xc2, 0xc2, 0xc2, - 0xc2, 0xc2, 0xc2, 0xc0, 0xbd, 0xbb, 0xb8, 0xb7, 0xb5, 0xb1, 0xaf, 0xab, - 0xa3, 0x95, 0x8a, 0x82, 0x7d, 0x87, 0x8f, 0x93, 0x95, 0x99, 0x9c, 0x9e, - 0x9c, 0x9a, 0x96, 0x94, 0x8d, 0x7e, 0x74, 0x67, 0x68, 0x82, 0x9b, 0xa5, - 0xa7, 0x97, 0x71, 0x60, 0x5f, 0x68, 0x72, 0x75, 0x81, 0x8b, 0x9a, 0xa6, - 0xa6, 0x90, 0x8e, 0x9e, 0x99, 0x79, 0x6a, 0x66, 0x66, 0x6a, 0x76, 0x6f, - 0x63, 0x5f, 0x60, 0x66, 0x72, 0x78, 0x7c, 0x81, 0x70, 0x5e, 0x62, 0x69, - 0x71, 0x72, 0x77, 0x7b, 0x77, 0x66, 0x57, 0x59, 0x5c, 0x5c, 0x5c, 0x60, - 0x64, 0x66, 0x67, 0x68, 0x6a, 0x6b, 0x6b, 0x6c, 0x6d, 0x6e, 0x6d, 0x6e, - 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6d, 0x6d, 0x6b, 0x6a, 0x6b, 0x6c, - 0x6e, 0x6f, 0x6e, 0x6c, 0x69, 0x63, 0x5f, 0x5d, 0x5c, 0x5b, 0x5c, 0x5b, - 0x5c, 0x5e, 0x5f, 0x61, 0x65, 0x69, 0x6b, 0x6c, 0x6e, 0x6e, 0x6b, 0x6b, - 0x6a, 0x69, 0x69, 0x6c, 0x6d, 0x6f, 0x72, 0x76, 0x74, 0x71, 0x6f, 0x6f, - 0x6e, 0x6d, 0x6c, 0x6d, 0x6e, 0x6f, 0x72, 0x76, 0x7a, 0x80, 0x87, 0x8b, - 0x8f, 0x91, 0x92, 0x94, 0x96, 0x95, 0x95, 0x94, 0x92, 0x91, 0x8f, 0x8e, - 0x8c, 0x8a, 0x85, 0x82, 0x80, 0x7d, 0x7d, 0x7c, 0x79, 0x77, 0x76, 0x75, - 0x7a, 0x79, 0x77, 0x76, 0x74, 0x73, 0x71, 0x6d, 0x6c, 0x68, 0x65, 0x63, - 0x62, 0x60, 0x5f, 0x5e, 0x5f, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x63, - 0x63, 0x62, 0x61, 0x61, 0x61, 0x61, 0x64, 0x65, 0x64, 0x61, 0x69, 0xa5, - 0xd0, 0xd5, 0xd4, 0xd4, 0xd5, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xd9, 0xda, - 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdd, 0xde, 0xde, 0xdf, 0xdf, 0xdf, - 0xde, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xdc, 0xdd, 0xdf, - 0xde, 0xdd, 0xdd, 0xdd, 0xdc, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdd, - 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, - 0xdb, 0xdb, 0xda, 0xd9, 0xdb, 0xdc, 0xdc, 0xda, 0xd9, 0xd8, 0xd8, 0xd7, - 0xd5, 0xd1, 0xcf, 0xcf, 0xcf, 0xd0, 0xce, 0xc5, 0xbc, 0xba, 0xbb, 0xc1, - 0xc7, 0xc6, 0xc1, 0xbf, 0xbe, 0xc1, 0xc2, 0xc1, 0xc1, 0xc1, 0xc1, 0xc0, - 0xbe, 0xbb, 0xb8, 0xb6, 0xb5, 0xb2, 0xb0, 0xad, 0xa4, 0x98, 0x8f, 0x86, - 0x7c, 0x83, 0x8c, 0x90, 0x93, 0x97, 0x9b, 0x9d, 0x9c, 0x9a, 0x97, 0x95, - 0x8d, 0x7f, 0x74, 0x68, 0x67, 0x7c, 0x96, 0xa2, 0xa6, 0x98, 0x72, 0x60, - 0x5f, 0x66, 0x71, 0x76, 0x7e, 0x88, 0x99, 0xa7, 0xa7, 0x92, 0x8f, 0x9c, - 0x9a, 0x7b, 0x68, 0x64, 0x63, 0x67, 0x78, 0x72, 0x62, 0x5c, 0x5e, 0x68, - 0x74, 0x76, 0x7a, 0x80, 0x71, 0x5e, 0x61, 0x68, 0x71, 0x6b, 0x6b, 0x71, - 0x6f, 0x62, 0x57, 0x5a, 0x5b, 0x5c, 0x5d, 0x61, 0x65, 0x66, 0x67, 0x68, - 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6c, - 0x6d, 0x6d, 0x6c, 0x6c, 0x6a, 0x6a, 0x6a, 0x6c, 0x6e, 0x6d, 0x6b, 0x6a, - 0x67, 0x61, 0x5e, 0x5d, 0x5b, 0x5b, 0x5b, 0x5b, 0x5c, 0x5e, 0x5f, 0x62, - 0x66, 0x6a, 0x6c, 0x6d, 0x6e, 0x6e, 0x6c, 0x6c, 0x6b, 0x69, 0x6a, 0x6c, - 0x6d, 0x6f, 0x72, 0x76, 0x74, 0x70, 0x6f, 0x6e, 0x6c, 0x6c, 0x6c, 0x6c, - 0x6d, 0x6e, 0x70, 0x73, 0x76, 0x7c, 0x84, 0x89, 0x8d, 0x8f, 0x91, 0x93, - 0x94, 0x93, 0x93, 0x93, 0x90, 0x8f, 0x8d, 0x8b, 0x89, 0x88, 0x82, 0x7f, - 0x7d, 0x7a, 0x7b, 0x7a, 0x77, 0x76, 0x75, 0x73, 0x7a, 0x79, 0x76, 0x74, - 0x73, 0x72, 0x6f, 0x6b, 0x69, 0x68, 0x63, 0x61, 0x5e, 0x5d, 0x5d, 0x5e, - 0x5f, 0x60, 0x60, 0x5f, 0x5f, 0x61, 0x63, 0x63, 0x64, 0x63, 0x62, 0x62, - 0x62, 0x62, 0x64, 0x64, 0x63, 0x62, 0x6d, 0xb3, 0xd3, 0xd4, 0xd3, 0xd4, - 0xd6, 0xd8, 0xd8, 0xd8, 0xd9, 0xdb, 0xda, 0xd9, 0xd8, 0xd8, 0xd8, 0xda, - 0xda, 0xda, 0xdc, 0xdd, 0xdd, 0xde, 0xdf, 0xdf, 0xdd, 0xde, 0xde, 0xde, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, - 0xdd, 0xde, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdd, 0xdd, 0xdc, 0xdc, 0xdb, - 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, - 0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, - 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, 0xd7, 0xd4, 0xd1, 0xce, - 0xcd, 0xce, 0xce, 0xca, 0xc0, 0xba, 0xb8, 0xbb, 0xc3, 0xc7, 0xc6, 0xc3, - 0xbe, 0xbd, 0xc0, 0xc0, 0xc0, 0xbf, 0xc0, 0xc0, 0xbf, 0xbd, 0xb9, 0xb6, - 0xb6, 0xb3, 0xb1, 0xae, 0xa6, 0x9c, 0x94, 0x8b, 0x7f, 0x7d, 0x87, 0x8d, - 0x90, 0x95, 0x9a, 0x9c, 0x9b, 0x99, 0x98, 0x97, 0x8f, 0x80, 0x76, 0x6a, - 0x66, 0x74, 0x8f, 0x9e, 0xa5, 0x99, 0x73, 0x60, 0x5d, 0x64, 0x71, 0x77, - 0x7a, 0x82, 0x96, 0xa7, 0xaa, 0x98, 0x91, 0x98, 0x9c, 0x7c, 0x61, 0x5c, - 0x5c, 0x60, 0x79, 0x77, 0x61, 0x59, 0x5e, 0x6f, 0x77, 0x73, 0x73, 0x7b, - 0x75, 0x61, 0x5d, 0x63, 0x6c, 0x65, 0x5a, 0x5d, 0x5e, 0x59, 0x55, 0x59, - 0x5a, 0x5b, 0x5e, 0x62, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6b, - 0x6b, 0x6c, 0x6c, 0x6c, 0x6c, 0x6b, 0x6c, 0x6b, 0x6c, 0x6c, 0x6b, 0x69, - 0x69, 0x69, 0x6a, 0x6c, 0x6d, 0x6c, 0x68, 0x65, 0x62, 0x5f, 0x5d, 0x5c, - 0x5b, 0x5a, 0x5a, 0x5b, 0x5d, 0x5e, 0x60, 0x62, 0x67, 0x6b, 0x6e, 0x6f, - 0x6f, 0x6f, 0x6e, 0x6b, 0x6a, 0x69, 0x69, 0x6b, 0x6d, 0x70, 0x73, 0x76, - 0x74, 0x71, 0x6f, 0x6c, 0x6c, 0x6c, 0x6b, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, - 0x70, 0x74, 0x7c, 0x82, 0x86, 0x89, 0x8c, 0x8f, 0x90, 0x8f, 0x8f, 0x8e, - 0x8c, 0x8a, 0x87, 0x85, 0x83, 0x81, 0x7c, 0x7a, 0x78, 0x77, 0x76, 0x75, - 0x74, 0x73, 0x73, 0x71, 0x7a, 0x77, 0x75, 0x74, 0x71, 0x70, 0x6c, 0x68, - 0x66, 0x64, 0x60, 0x5e, 0x5c, 0x5c, 0x5b, 0x5c, 0x5e, 0x5f, 0x5e, 0x5e, - 0x5f, 0x61, 0x62, 0x63, 0x63, 0x63, 0x63, 0x64, 0x65, 0x65, 0x64, 0x64, - 0x62, 0x62, 0x74, 0xbe, 0xd3, 0xd1, 0xd1, 0xd4, 0xd6, 0xd7, 0xd7, 0xd7, - 0xd8, 0xd9, 0xda, 0xd9, 0xd8, 0xd8, 0xd8, 0xda, 0xda, 0xda, 0xdc, 0xdd, - 0xdc, 0xde, 0xde, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdc, 0xdb, - 0xdb, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xda, 0xda, 0xdb, 0xda, 0xd9, 0xd9, - 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, - 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xd8, 0xd7, 0xd7, 0xd8, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, 0xd6, 0xd4, 0xd1, 0xcf, 0xcd, 0xcd, 0xcd, - 0xc8, 0xc2, 0xbd, 0xb8, 0xba, 0xc3, 0xc7, 0xc7, 0xc1, 0xba, 0xba, 0xbd, - 0xbe, 0xbd, 0xbd, 0xbd, 0xbe, 0xbe, 0xbb, 0xb6, 0xb5, 0xb3, 0xb1, 0xaf, - 0xa9, 0xa0, 0x99, 0x92, 0x85, 0x79, 0x7f, 0x85, 0x8a, 0x90, 0x96, 0x99, - 0x9a, 0x99, 0x98, 0x97, 0x8f, 0x85, 0x7b, 0x6e, 0x68, 0x6d, 0x86, 0x97, - 0xa3, 0x9a, 0x76, 0x62, 0x5c, 0x60, 0x6f, 0x7c, 0x7a, 0x7e, 0x92, 0xa7, - 0xad, 0xa0, 0x97, 0x95, 0x9f, 0x83, 0x5d, 0x53, 0x52, 0x56, 0x70, 0x74, - 0x5e, 0x57, 0x60, 0x77, 0x82, 0x78, 0x75, 0x79, 0x79, 0x66, 0x58, 0x5a, - 0x65, 0x5f, 0x4c, 0x45, 0x47, 0x4d, 0x54, 0x59, 0x59, 0x5b, 0x5f, 0x63, - 0x65, 0x67, 0x67, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x6a, 0x69, 0x69, 0x6a, - 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x68, 0x69, 0x6a, 0x6b, 0x6c, - 0x6c, 0x68, 0x64, 0x61, 0x5e, 0x5c, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a, 0x5b, - 0x5e, 0x60, 0x62, 0x64, 0x68, 0x6c, 0x6f, 0x70, 0x70, 0x6f, 0x6e, 0x6b, - 0x6a, 0x69, 0x69, 0x6c, 0x6e, 0x70, 0x73, 0x75, 0x73, 0x70, 0x6e, 0x6c, - 0x6b, 0x6b, 0x6a, 0x6a, 0x6a, 0x69, 0x6a, 0x6a, 0x6a, 0x6b, 0x72, 0x77, - 0x7c, 0x7f, 0x83, 0x85, 0x86, 0x86, 0x86, 0x85, 0x83, 0x7f, 0x7e, 0x7d, - 0x7a, 0x79, 0x76, 0x74, 0x74, 0x73, 0x73, 0x71, 0x71, 0x71, 0x70, 0x6e, - 0x78, 0x76, 0x74, 0x72, 0x6f, 0x6d, 0x69, 0x65, 0x63, 0x61, 0x5d, 0x5b, - 0x59, 0x59, 0x59, 0x5a, 0x5c, 0x5c, 0x5d, 0x5d, 0x60, 0x60, 0x60, 0x61, - 0x61, 0x62, 0x63, 0x65, 0x66, 0x66, 0x65, 0x64, 0x62, 0x67, 0x82, 0xc5, - 0xd3, 0xd0, 0xd1, 0xd4, 0xd5, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd9, 0xd9, - 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0xdc, 0xdc, 0xde, 0xde, 0xdd, - 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, - 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdb, - 0xdb, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd7, 0xd6, 0xd6, 0xd6, 0xd6, - 0xd5, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, 0xd6, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd8, - 0xd7, 0xd6, 0xd6, 0xd5, 0xd4, 0xd1, 0xce, 0xcb, 0xcb, 0xca, 0xc7, 0xc0, - 0xb7, 0xb9, 0xc0, 0xc4, 0xc4, 0xbd, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbb, - 0xbd, 0xbe, 0xbc, 0xb7, 0xb4, 0xb2, 0xb1, 0xaf, 0xaa, 0xa3, 0x9e, 0x98, - 0x8e, 0x7d, 0x77, 0x79, 0x7e, 0x88, 0x92, 0x97, 0x99, 0x99, 0x99, 0x97, - 0x90, 0x89, 0x80, 0x72, 0x6a, 0x69, 0x7e, 0x8f, 0xa0, 0x9b, 0x78, 0x63, - 0x5c, 0x5d, 0x6a, 0x7d, 0x7d, 0x7e, 0x8a, 0xa4, 0xb1, 0xa9, 0x9e, 0x92, - 0x9e, 0x87, 0x62, 0x53, 0x4d, 0x4c, 0x5f, 0x6d, 0x5f, 0x5a, 0x63, 0x7e, - 0x9b, 0x92, 0x8c, 0x8c, 0x82, 0x6e, 0x59, 0x54, 0x5d, 0x5c, 0x4a, 0x3f, - 0x3f, 0x49, 0x54, 0x58, 0x5a, 0x5c, 0x60, 0x64, 0x65, 0x66, 0x66, 0x66, - 0x67, 0x68, 0x68, 0x68, 0x69, 0x67, 0x68, 0x69, 0x69, 0x69, 0x6a, 0x69, - 0x6a, 0x6a, 0x69, 0x67, 0x68, 0x6b, 0x6c, 0x6d, 0x6a, 0x64, 0x61, 0x5f, - 0x5b, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5c, 0x5f, 0x61, 0x63, 0x66, - 0x69, 0x6d, 0x6f, 0x70, 0x72, 0x72, 0x6f, 0x6c, 0x6a, 0x69, 0x69, 0x6c, - 0x70, 0x72, 0x74, 0x75, 0x74, 0x71, 0x6f, 0x6c, 0x6a, 0x6b, 0x6b, 0x6b, - 0x6b, 0x69, 0x66, 0x65, 0x64, 0x65, 0x69, 0x6c, 0x6f, 0x71, 0x74, 0x76, - 0x78, 0x79, 0x79, 0x79, 0x77, 0x76, 0x76, 0x75, 0x74, 0x72, 0x71, 0x70, - 0x6f, 0x6f, 0x6e, 0x6d, 0x6d, 0x6d, 0x6c, 0x6a, 0x77, 0x75, 0x71, 0x70, - 0x6e, 0x6b, 0x68, 0x64, 0x62, 0x60, 0x5b, 0x58, 0x57, 0x57, 0x58, 0x59, - 0x5a, 0x5c, 0x5d, 0x5e, 0x61, 0x62, 0x61, 0x61, 0x61, 0x62, 0x66, 0x68, - 0x68, 0x66, 0x65, 0x64, 0x62, 0x6b, 0x8c, 0xc8, 0xd3, 0xd1, 0xd1, 0xd3, - 0xd4, 0xd7, 0xd8, 0xd8, 0xd7, 0xd8, 0xd8, 0xd9, 0xd9, 0xda, 0xd9, 0xd9, - 0xda, 0xda, 0xdb, 0xdc, 0xdc, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdd, - 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xdd, 0xdd, 0xdd, 0xde, - 0xdf, 0xde, 0xdf, 0xdf, 0xdf, 0xdd, 0xde, 0xde, 0xdd, 0xdb, 0xdb, 0xda, - 0xda, 0xda, 0xd9, 0xd8, 0xd8, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd6, 0xd6, - 0xd5, 0xd5, 0xd5, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd6, - 0xd5, 0xd5, 0xd5, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd4, - 0xd4, 0xd4, 0xd1, 0xcd, 0xcb, 0xcb, 0xca, 0xc6, 0xbb, 0xb5, 0xb8, 0xbd, - 0xc3, 0xc3, 0xba, 0xb6, 0xb6, 0xb9, 0xb9, 0xb9, 0xbc, 0xbd, 0xbc, 0xb8, - 0xb4, 0xb2, 0xb0, 0xaf, 0xab, 0xa5, 0xa0, 0x9c, 0x93, 0x82, 0x74, 0x71, - 0x75, 0x81, 0x8d, 0x94, 0x98, 0x99, 0x98, 0x96, 0x91, 0x8b, 0x83, 0x75, - 0x6b, 0x68, 0x78, 0x88, 0x9c, 0x9a, 0x79, 0x65, 0x5d, 0x5b, 0x66, 0x7a, - 0x81, 0x82, 0x87, 0xa1, 0xb4, 0xaf, 0xa2, 0x91, 0x9c, 0x89, 0x68, 0x58, - 0x51, 0x4c, 0x5a, 0x6c, 0x65, 0x61, 0x67, 0x81, 0xa5, 0x9b, 0x95, 0x97, - 0x8c, 0x75, 0x5d, 0x55, 0x58, 0x59, 0x4f, 0x46, 0x46, 0x4e, 0x56, 0x58, - 0x5b, 0x5d, 0x61, 0x63, 0x64, 0x65, 0x65, 0x66, 0x67, 0x67, 0x67, 0x66, - 0x66, 0x68, 0x68, 0x69, 0x69, 0x69, 0x6a, 0x69, 0x6a, 0x6a, 0x69, 0x68, - 0x68, 0x6a, 0x6b, 0x6c, 0x68, 0x62, 0x5f, 0x5d, 0x5b, 0x5a, 0x5a, 0x5a, - 0x5a, 0x5b, 0x5c, 0x5e, 0x60, 0x62, 0x64, 0x67, 0x6b, 0x6f, 0x72, 0x73, - 0x74, 0x74, 0x6f, 0x6c, 0x6a, 0x69, 0x6a, 0x6e, 0x71, 0x73, 0x74, 0x74, - 0x74, 0x72, 0x6f, 0x6d, 0x6b, 0x6a, 0x6a, 0x6a, 0x6a, 0x68, 0x64, 0x61, - 0x60, 0x60, 0x62, 0x65, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x71, 0x71, 0x71, - 0x70, 0x70, 0x70, 0x70, 0x6f, 0x6f, 0x6d, 0x6d, 0x6c, 0x6b, 0x6b, 0x6b, - 0x6a, 0x6a, 0x69, 0x67, 0x76, 0x74, 0x71, 0x6f, 0x6d, 0x6a, 0x66, 0x62, - 0x60, 0x5e, 0x5a, 0x56, 0x56, 0x56, 0x57, 0x58, 0x59, 0x5b, 0x5c, 0x5d, - 0x61, 0x62, 0x61, 0x61, 0x62, 0x63, 0x67, 0x69, 0x69, 0x67, 0x67, 0x64, - 0x62, 0x6d, 0x94, 0xca, 0xd4, 0xd2, 0xd1, 0xd2, 0xd4, 0xd6, 0xd8, 0xd8, - 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xdb, 0xdc, - 0xdc, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xde, 0xde, 0xdf, 0xdf, - 0xde, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xde, 0xdf, 0xdf, 0xe1, 0xe1, - 0xe1, 0xdf, 0xdf, 0xe0, 0xdf, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xda, 0xd9, - 0xd9, 0xd8, 0xd7, 0xd7, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, - 0xd5, 0xd6, 0xd5, 0xd4, 0xd4, 0xd4, 0xd4, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, - 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd4, 0xd5, 0xd4, 0xd5, 0xd5, 0xd3, 0xd0, - 0xcc, 0xcb, 0xca, 0xc8, 0xc0, 0xb7, 0xb5, 0xb9, 0xc0, 0xc4, 0xbd, 0xb6, - 0xb5, 0xb8, 0xb9, 0xb8, 0xbb, 0xbc, 0xbb, 0xb8, 0xb4, 0xb2, 0xb0, 0xaf, - 0xac, 0xa7, 0xa2, 0x9e, 0x96, 0x87, 0x76, 0x71, 0x73, 0x7d, 0x8a, 0x92, - 0x96, 0x98, 0x97, 0x96, 0x91, 0x8b, 0x85, 0x79, 0x6c, 0x68, 0x74, 0x83, - 0x9a, 0x9a, 0x7b, 0x65, 0x5d, 0x5b, 0x63, 0x76, 0x82, 0x85, 0x88, 0x9f, - 0xb3, 0xb1, 0xa3, 0x8f, 0x99, 0x8a, 0x6d, 0x5d, 0x55, 0x4f, 0x5b, 0x6e, - 0x6b, 0x67, 0x6a, 0x80, 0xa3, 0x97, 0x8f, 0x92, 0x8f, 0x79, 0x60, 0x57, - 0x55, 0x57, 0x51, 0x4b, 0x4c, 0x51, 0x58, 0x58, 0x5c, 0x5e, 0x60, 0x62, - 0x63, 0x63, 0x64, 0x65, 0x66, 0x67, 0x66, 0x65, 0x65, 0x68, 0x68, 0x69, - 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6a, 0x69, 0x68, 0x68, 0x69, 0x6a, 0x6b, - 0x66, 0x60, 0x5d, 0x5b, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5d, 0x60, - 0x61, 0x63, 0x64, 0x68, 0x6d, 0x72, 0x74, 0x75, 0x76, 0x73, 0x6e, 0x6b, - 0x6a, 0x69, 0x6a, 0x6e, 0x72, 0x73, 0x74, 0x74, 0x74, 0x72, 0x6f, 0x6d, - 0x6b, 0x6a, 0x6a, 0x6a, 0x69, 0x67, 0x62, 0x5f, 0x5f, 0x5d, 0x5e, 0x61, - 0x64, 0x66, 0x68, 0x69, 0x6b, 0x6c, 0x6d, 0x6d, 0x6d, 0x6c, 0x6d, 0x6d, - 0x6d, 0x6c, 0x6a, 0x6a, 0x69, 0x69, 0x69, 0x69, 0x68, 0x68, 0x67, 0x65, - 0x75, 0x73, 0x71, 0x6f, 0x6c, 0x68, 0x64, 0x60, 0x5e, 0x5b, 0x57, 0x53, - 0x53, 0x53, 0x54, 0x58, 0x58, 0x5a, 0x5b, 0x5d, 0x60, 0x62, 0x62, 0x62, - 0x63, 0x65, 0x68, 0x6a, 0x6b, 0x69, 0x68, 0x63, 0x60, 0x6f, 0x9f, 0xcc, - 0xd2, 0xd1, 0xd1, 0xd1, 0xd3, 0xd4, 0xd7, 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, - 0xd8, 0xd8, 0xd9, 0xd9, 0xda, 0xdb, 0xdb, 0xdc, 0xdc, 0xdd, 0xde, 0xdd, - 0xdc, 0xdc, 0xdc, 0xdc, 0xde, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, - 0xdd, 0xdd, 0xdd, 0xdd, 0xe0, 0xe1, 0xe2, 0xe2, 0xe2, 0xe0, 0xe0, 0xe1, - 0xe1, 0xe1, 0xe0, 0xdf, 0xdf, 0xdf, 0xde, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, - 0xd9, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd8, 0xd6, 0xd5, - 0xd5, 0xd5, 0xd5, 0xd6, 0xd4, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, - 0xd5, 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, 0xd3, 0xce, 0xcc, 0xcb, 0xc9, - 0xc6, 0xbd, 0xb7, 0xb6, 0xba, 0xc2, 0xc1, 0xba, 0xb7, 0xb6, 0xb8, 0xba, - 0xbb, 0xbc, 0xbc, 0xb9, 0xb6, 0xb3, 0xb1, 0xb0, 0xac, 0xa8, 0xa4, 0xa1, - 0x9a, 0x8d, 0x7d, 0x76, 0x74, 0x78, 0x86, 0x8f, 0x95, 0x96, 0x97, 0x95, - 0x91, 0x8c, 0x87, 0x7e, 0x71, 0x69, 0x6e, 0x7b, 0x95, 0x9a, 0x7b, 0x66, - 0x5d, 0x5a, 0x5f, 0x70, 0x82, 0x89, 0x8d, 0x9d, 0xaf, 0xad, 0xa0, 0x8a, - 0x96, 0x8b, 0x75, 0x66, 0x5d, 0x56, 0x5d, 0x71, 0x73, 0x70, 0x6e, 0x7d, - 0x96, 0x86, 0x7c, 0x7f, 0x8b, 0x79, 0x65, 0x5b, 0x53, 0x53, 0x51, 0x4f, - 0x51, 0x56, 0x59, 0x58, 0x5c, 0x5e, 0x5f, 0x61, 0x62, 0x61, 0x62, 0x64, - 0x64, 0x65, 0x65, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6a, 0x6a, - 0x6a, 0x6a, 0x69, 0x67, 0x67, 0x68, 0x68, 0x68, 0x63, 0x5e, 0x5b, 0x5a, - 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5e, 0x60, 0x61, 0x63, 0x65, 0x69, - 0x70, 0x76, 0x79, 0x79, 0x78, 0x73, 0x6d, 0x6a, 0x68, 0x68, 0x6a, 0x6e, - 0x71, 0x73, 0x73, 0x74, 0x74, 0x71, 0x6f, 0x6d, 0x6b, 0x69, 0x68, 0x68, - 0x67, 0x64, 0x5f, 0x5c, 0x5b, 0x5a, 0x59, 0x5b, 0x5e, 0x60, 0x61, 0x62, - 0x63, 0x65, 0x66, 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x67, 0x66, 0x66, - 0x65, 0x64, 0x64, 0x64, 0x64, 0x64, 0x63, 0x61, 0x75, 0x73, 0x70, 0x6e, - 0x6a, 0x66, 0x62, 0x5d, 0x5a, 0x57, 0x54, 0x50, 0x50, 0x50, 0x52, 0x56, - 0x58, 0x5a, 0x5c, 0x5e, 0x61, 0x63, 0x63, 0x63, 0x64, 0x66, 0x6a, 0x6c, - 0x6d, 0x6d, 0x6b, 0x65, 0x60, 0x73, 0xab, 0xce, 0xd1, 0xcf, 0xd0, 0xd1, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd8, - 0xd9, 0xda, 0xdb, 0xdc, 0xdc, 0xdd, 0xde, 0xdd, 0xdc, 0xdd, 0xdc, 0xdc, - 0xdd, 0xdd, 0xde, 0xde, 0xdd, 0xdc, 0xdc, 0xdc, 0xde, 0xde, 0xde, 0xde, - 0xe0, 0xe0, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, - 0xe1, 0xe1, 0xe0, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xde, 0xdd, 0xdd, 0xdc, - 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xdb, 0xda, 0xd9, 0xd8, 0xd9, 0xd9, - 0xd7, 0xd8, 0xd7, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd7, 0xd6, 0xd6, 0xd5, - 0xd5, 0xd6, 0xd4, 0xd4, 0xd2, 0xd0, 0xce, 0xcb, 0xc9, 0xc5, 0xbf, 0xbc, - 0xb8, 0xbb, 0xc1, 0xc1, 0xbd, 0xb7, 0xb5, 0xb9, 0xba, 0xba, 0xba, 0xba, - 0xb7, 0xb5, 0xb3, 0xb0, 0xac, 0xa9, 0xa6, 0xa4, 0x9e, 0x94, 0x87, 0x7e, - 0x78, 0x73, 0x7e, 0x8b, 0x91, 0x94, 0x95, 0x94, 0x91, 0x8c, 0x89, 0x83, - 0x76, 0x6a, 0x69, 0x73, 0x8e, 0x99, 0x7c, 0x67, 0x5e, 0x5a, 0x5b, 0x6a, - 0x7d, 0x87, 0x92, 0x9d, 0xa9, 0xa7, 0x9a, 0x82, 0x8f, 0x8d, 0x7c, 0x6e, - 0x66, 0x5c, 0x5d, 0x70, 0x79, 0x79, 0x73, 0x7c, 0x87, 0x75, 0x6d, 0x73, - 0x7e, 0x73, 0x67, 0x5d, 0x4f, 0x4f, 0x4e, 0x51, 0x55, 0x59, 0x59, 0x58, - 0x5c, 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x61, 0x62, 0x63, 0x64, 0x64, 0x64, - 0x64, 0x66, 0x67, 0x68, 0x68, 0x69, 0x69, 0x69, 0x69, 0x69, 0x68, 0x67, - 0x66, 0x66, 0x66, 0x64, 0x5f, 0x5b, 0x5a, 0x59, 0x59, 0x5a, 0x59, 0x5a, - 0x5b, 0x5c, 0x5d, 0x60, 0x64, 0x65, 0x67, 0x6d, 0x73, 0x78, 0x7b, 0x7b, - 0x78, 0x70, 0x6b, 0x68, 0x68, 0x67, 0x69, 0x6e, 0x72, 0x73, 0x73, 0x72, - 0x72, 0x70, 0x6e, 0x6c, 0x6a, 0x68, 0x67, 0x67, 0x65, 0x61, 0x5c, 0x58, - 0x56, 0x55, 0x55, 0x57, 0x58, 0x59, 0x59, 0x5a, 0x5b, 0x5d, 0x5e, 0x5e, - 0x60, 0x61, 0x60, 0x61, 0x61, 0x60, 0x5f, 0x60, 0x60, 0x60, 0x5e, 0x5e, - 0x5f, 0x5f, 0x5e, 0x5c, 0x72, 0x71, 0x6e, 0x6c, 0x67, 0x63, 0x5f, 0x5b, - 0x58, 0x54, 0x4f, 0x4c, 0x4d, 0x4e, 0x52, 0x56, 0x58, 0x5b, 0x5c, 0x5f, - 0x61, 0x62, 0x63, 0x63, 0x65, 0x67, 0x6b, 0x6e, 0x6f, 0x6f, 0x6c, 0x66, - 0x62, 0x79, 0xb6, 0xd0, 0xd0, 0xcf, 0xd0, 0xd1, 0xd2, 0xd4, 0xd4, 0xd5, - 0xd7, 0xd8, 0xd8, 0xd7, 0xd6, 0xd6, 0xd7, 0xd8, 0xd8, 0xd8, 0xd9, 0xdb, - 0xdb, 0xdc, 0xdd, 0xdc, 0xdb, 0xdc, 0xdb, 0xdc, 0xdd, 0xdc, 0xdd, 0xdd, - 0xdc, 0xdb, 0xdb, 0xdb, 0xde, 0xde, 0xde, 0xdd, 0xdd, 0xde, 0xdf, 0xe0, - 0xe1, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1, 0xe1, 0xe2, 0xe1, 0xe1, 0xe0, 0xe1, - 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xdd, 0xdd, - 0xdd, 0xdc, 0xdd, 0xdc, 0xdc, 0xdb, 0xdb, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, - 0xda, 0xd8, 0xd7, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd6, 0xd5, - 0xd4, 0xd2, 0xd1, 0xd0, 0xcc, 0xc8, 0xc6, 0xc4, 0xbd, 0xb6, 0xb9, 0xc0, - 0xc1, 0xbc, 0xb4, 0xb4, 0xb7, 0xb8, 0xb9, 0xb9, 0xb8, 0xb5, 0xb3, 0xb1, - 0xad, 0xa9, 0xa7, 0xa5, 0xa1, 0x98, 0x8f, 0x87, 0x80, 0x75, 0x74, 0x84, - 0x8d, 0x90, 0x93, 0x93, 0x91, 0x8f, 0x8c, 0x85, 0x79, 0x6c, 0x67, 0x70, - 0x88, 0x96, 0x7c, 0x67, 0x5e, 0x5a, 0x59, 0x64, 0x73, 0x7f, 0x8f, 0x9d, - 0xa2, 0x9e, 0x8f, 0x77, 0x88, 0x8e, 0x82, 0x75, 0x6d, 0x63, 0x5c, 0x68, - 0x72, 0x74, 0x73, 0x7b, 0x7f, 0x6e, 0x67, 0x6a, 0x72, 0x6f, 0x69, 0x5f, - 0x4d, 0x49, 0x4b, 0x4f, 0x53, 0x59, 0x5a, 0x58, 0x5a, 0x5c, 0x5e, 0x5f, - 0x5f, 0x60, 0x61, 0x62, 0x62, 0x63, 0x63, 0x64, 0x65, 0x67, 0x68, 0x67, - 0x66, 0x66, 0x67, 0x66, 0x67, 0x67, 0x65, 0x66, 0x65, 0x65, 0x64, 0x61, - 0x5d, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5c, 0x5e, 0x5f, 0x62, - 0x66, 0x69, 0x6b, 0x70, 0x77, 0x7a, 0x7b, 0x7a, 0x75, 0x6d, 0x68, 0x67, - 0x66, 0x67, 0x69, 0x6d, 0x72, 0x73, 0x71, 0x6f, 0x6f, 0x6c, 0x6b, 0x6a, - 0x67, 0x65, 0x65, 0x64, 0x62, 0x5e, 0x58, 0x54, 0x53, 0x52, 0x53, 0x54, - 0x55, 0x55, 0x54, 0x54, 0x56, 0x57, 0x57, 0x57, 0x58, 0x5a, 0x5a, 0x5a, - 0x5a, 0x5a, 0x5b, 0x5b, 0x5a, 0x5a, 0x59, 0x59, 0x5a, 0x5a, 0x58, 0x56, - 0x70, 0x6f, 0x6c, 0x6a, 0x66, 0x61, 0x5d, 0x59, 0x57, 0x53, 0x4d, 0x4b, - 0x4c, 0x4e, 0x51, 0x56, 0x59, 0x5b, 0x5d, 0x5f, 0x61, 0x62, 0x63, 0x64, - 0x66, 0x69, 0x6c, 0x70, 0x71, 0x70, 0x6c, 0x67, 0x65, 0x7e, 0xbc, 0xd1, - 0xcf, 0xcf, 0xcf, 0xd0, 0xd3, 0xd3, 0xd4, 0xd5, 0xd7, 0xd7, 0xd7, 0xd6, - 0xd6, 0xd5, 0xd5, 0xd8, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xdb, 0xdc, 0xdb, - 0xda, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, - 0xde, 0xde, 0xde, 0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xdf, 0xe0, 0xe0, 0xe1, - 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe0, 0xdf, 0xdf, 0xe0, 0xdf, 0xdf, 0xe0, - 0xe0, 0xde, 0xdf, 0xde, 0xdd, 0xdc, 0xdc, 0xdd, 0xdd, 0xdb, 0xdb, 0xdb, - 0xdb, 0xda, 0xda, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xda, 0xd9, 0xd8, 0xd8, - 0xd9, 0xd8, 0xd8, 0xd8, 0xd9, 0xd8, 0xd7, 0xd7, 0xd6, 0xd4, 0xd3, 0xd3, - 0xd2, 0xcd, 0xca, 0xc9, 0xc4, 0xba, 0xb4, 0xb8, 0xbc, 0xbf, 0xb7, 0xb1, - 0xb4, 0xb6, 0xb8, 0xb9, 0xb8, 0xb6, 0xb4, 0xb1, 0xae, 0xaa, 0xa8, 0xa6, - 0xa3, 0x9c, 0x94, 0x8e, 0x87, 0x79, 0x70, 0x7e, 0x89, 0x8d, 0x90, 0x92, - 0x91, 0x8f, 0x8c, 0x86, 0x7a, 0x6e, 0x69, 0x6f, 0x85, 0x93, 0x7b, 0x66, - 0x5e, 0x59, 0x59, 0x61, 0x6d, 0x78, 0x89, 0x9a, 0x9d, 0x95, 0x86, 0x6f, - 0x83, 0x8f, 0x85, 0x78, 0x70, 0x65, 0x5b, 0x5e, 0x66, 0x6a, 0x6f, 0x78, - 0x7a, 0x6d, 0x67, 0x66, 0x6c, 0x70, 0x6b, 0x61, 0x4d, 0x4a, 0x4b, 0x4e, - 0x52, 0x59, 0x5b, 0x59, 0x5a, 0x5b, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, - 0x62, 0x63, 0x64, 0x64, 0x65, 0x67, 0x67, 0x66, 0x65, 0x65, 0x66, 0x65, - 0x66, 0x66, 0x64, 0x65, 0x63, 0x62, 0x61, 0x5e, 0x5b, 0x59, 0x5a, 0x5a, - 0x5a, 0x5a, 0x59, 0x5b, 0x5e, 0x5f, 0x60, 0x64, 0x68, 0x6b, 0x6f, 0x74, - 0x7a, 0x7b, 0x7c, 0x79, 0x73, 0x6c, 0x68, 0x67, 0x66, 0x67, 0x69, 0x6c, - 0x71, 0x72, 0x70, 0x6d, 0x6d, 0x6b, 0x6a, 0x68, 0x65, 0x63, 0x63, 0x61, - 0x5f, 0x5b, 0x55, 0x52, 0x51, 0x51, 0x51, 0x52, 0x51, 0x51, 0x51, 0x52, - 0x53, 0x54, 0x55, 0x54, 0x55, 0x56, 0x56, 0x56, 0x57, 0x56, 0x57, 0x57, - 0x56, 0x57, 0x55, 0x56, 0x56, 0x56, 0x54, 0x53, 0x6f, 0x6d, 0x6a, 0x68, - 0x64, 0x5f, 0x5b, 0x58, 0x56, 0x51, 0x4c, 0x49, 0x4a, 0x4d, 0x51, 0x55, - 0x59, 0x5b, 0x5c, 0x5f, 0x61, 0x62, 0x63, 0x64, 0x66, 0x69, 0x6d, 0x71, - 0x72, 0x71, 0x6d, 0x68, 0x69, 0x82, 0xbe, 0xd1, 0xcf, 0xce, 0xcf, 0xd0, - 0xd2, 0xd2, 0xd4, 0xd5, 0xd6, 0xd7, 0xd7, 0xd6, 0xd6, 0xd5, 0xd6, 0xd7, - 0xd7, 0xd8, 0xd8, 0xd8, 0xd9, 0xda, 0xda, 0xdb, 0xda, 0xdb, 0xdb, 0xdb, - 0xdc, 0xdc, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdd, 0xdd, 0xdd, 0xdc, - 0xdc, 0xdd, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xe0, 0xe0, 0xdf, 0xdf, 0xe0, - 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdc, 0xdd, 0xdd, - 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xd9, 0xda, 0xd9, 0xd9, 0xd8, 0xd8, - 0xd9, 0xd9, 0xd9, 0xda, 0xda, 0xd8, 0xd8, 0xd9, 0xd9, 0xd8, 0xd8, 0xd9, - 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd5, 0xd4, 0xd5, 0xd4, 0xd0, 0xcd, 0xcb, - 0xc8, 0xbf, 0xb6, 0xb4, 0xb8, 0xbe, 0xbb, 0xb1, 0xb1, 0xb3, 0xb7, 0xb9, - 0xb8, 0xb6, 0xb4, 0xb2, 0xae, 0xab, 0xa9, 0xa8, 0xa4, 0x9e, 0x96, 0x90, - 0x8a, 0x7d, 0x6f, 0x7b, 0x86, 0x8b, 0x8f, 0x92, 0x91, 0x8f, 0x8c, 0x86, - 0x7b, 0x6e, 0x69, 0x6f, 0x82, 0x91, 0x7a, 0x67, 0x5e, 0x5a, 0x59, 0x5f, - 0x6a, 0x73, 0x84, 0x94, 0x98, 0x90, 0x81, 0x6d, 0x81, 0x8f, 0x85, 0x78, - 0x70, 0x66, 0x5a, 0x58, 0x5d, 0x62, 0x6a, 0x75, 0x76, 0x6c, 0x66, 0x64, - 0x6a, 0x70, 0x6c, 0x61, 0x4d, 0x4a, 0x4d, 0x4d, 0x51, 0x57, 0x5b, 0x5a, - 0x5a, 0x5a, 0x5c, 0x5e, 0x5e, 0x5f, 0x5f, 0x61, 0x62, 0x63, 0x64, 0x64, - 0x65, 0x67, 0x67, 0x65, 0x65, 0x65, 0x66, 0x65, 0x65, 0x65, 0x64, 0x63, - 0x62, 0x61, 0x5f, 0x5d, 0x5a, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5c, - 0x5f, 0x60, 0x62, 0x66, 0x6a, 0x6e, 0x71, 0x76, 0x7b, 0x7b, 0x7b, 0x78, - 0x71, 0x6a, 0x67, 0x66, 0x66, 0x67, 0x69, 0x6c, 0x70, 0x71, 0x6e, 0x6c, - 0x6c, 0x6a, 0x69, 0x67, 0x64, 0x61, 0x61, 0x5f, 0x5d, 0x59, 0x54, 0x51, - 0x50, 0x50, 0x50, 0x51, 0x50, 0x50, 0x50, 0x50, 0x51, 0x53, 0x53, 0x53, - 0x53, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x54, 0x55, 0x53, 0x54, - 0x54, 0x54, 0x52, 0x51, 0x6f, 0x6b, 0x68, 0x65, 0x61, 0x5d, 0x59, 0x56, - 0x54, 0x4f, 0x4a, 0x47, 0x49, 0x4b, 0x50, 0x54, 0x58, 0x5a, 0x5b, 0x5d, - 0x62, 0x64, 0x65, 0x65, 0x66, 0x68, 0x6d, 0x71, 0x73, 0x73, 0x6f, 0x6b, - 0x6f, 0x88, 0xc1, 0xd0, 0xce, 0xce, 0xce, 0xd0, 0xd2, 0xd2, 0xd4, 0xd5, - 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd6, 0xd6, 0xd6, 0xd7, 0xd7, 0xd8, 0xd9, - 0xd8, 0xd9, 0xd9, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xdb, - 0xdc, 0xdc, 0xdc, 0xdc, 0xdd, 0xdd, 0xdd, 0xdb, 0xdc, 0xdd, 0xdd, 0xdd, - 0xdc, 0xdd, 0xdd, 0xdf, 0xdf, 0xde, 0xde, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, - 0xdd, 0xdc, 0xdb, 0xdc, 0xda, 0xda, 0xda, 0xda, 0xd8, 0xd9, 0xd9, 0xda, - 0xda, 0xda, 0xd8, 0xd8, 0xd7, 0xd7, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, 0xd9, - 0xd9, 0xd7, 0xd7, 0xd7, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd5, 0xd6, - 0xd6, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, 0xd1, 0xd0, 0xcd, 0xc7, 0xbe, 0xb7, - 0xb5, 0xb9, 0xbc, 0xb4, 0xae, 0xae, 0xb2, 0xb7, 0xb8, 0xb6, 0xb4, 0xb3, - 0xaf, 0xac, 0xab, 0xaa, 0xa6, 0xa0, 0x98, 0x93, 0x8e, 0x82, 0x71, 0x75, - 0x80, 0x86, 0x8c, 0x90, 0x90, 0x8e, 0x8b, 0x86, 0x7d, 0x70, 0x6a, 0x6e, - 0x7e, 0x8d, 0x78, 0x66, 0x5f, 0x5a, 0x59, 0x5c, 0x65, 0x6e, 0x7a, 0x8a, - 0x8f, 0x89, 0x7c, 0x6b, 0x7c, 0x8b, 0x84, 0x78, 0x70, 0x66, 0x59, 0x52, - 0x52, 0x56, 0x62, 0x72, 0x71, 0x67, 0x62, 0x60, 0x67, 0x6d, 0x6a, 0x5f, - 0x4d, 0x4c, 0x4f, 0x4e, 0x4f, 0x56, 0x5a, 0x5b, 0x5a, 0x5a, 0x5c, 0x5e, - 0x5f, 0x5e, 0x5f, 0x60, 0x61, 0x63, 0x63, 0x64, 0x65, 0x66, 0x66, 0x65, - 0x64, 0x65, 0x65, 0x64, 0x64, 0x64, 0x63, 0x62, 0x61, 0x5f, 0x5e, 0x5c, - 0x5a, 0x59, 0x58, 0x59, 0x59, 0x59, 0x5a, 0x5d, 0x60, 0x61, 0x64, 0x68, - 0x6d, 0x71, 0x75, 0x78, 0x7b, 0x79, 0x76, 0x74, 0x6f, 0x69, 0x66, 0x66, - 0x66, 0x67, 0x68, 0x6b, 0x6e, 0x6e, 0x6c, 0x6a, 0x69, 0x68, 0x67, 0x63, - 0x60, 0x5e, 0x5d, 0x5c, 0x5a, 0x56, 0x51, 0x4e, 0x4e, 0x4e, 0x4f, 0x4e, - 0x4e, 0x4e, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x50, 0x51, 0x52, 0x52, 0x53, - 0x53, 0x53, 0x53, 0x53, 0x52, 0x52, 0x51, 0x52, 0x51, 0x51, 0x50, 0x4f, - 0x6b, 0x66, 0x63, 0x61, 0x5e, 0x5a, 0x56, 0x52, 0x4f, 0x4c, 0x47, 0x45, - 0x47, 0x4a, 0x4e, 0x52, 0x57, 0x5a, 0x5c, 0x5e, 0x62, 0x64, 0x66, 0x66, - 0x67, 0x69, 0x6e, 0x73, 0x76, 0x76, 0x72, 0x6e, 0x76, 0x90, 0xc3, 0xd0, - 0xcf, 0xce, 0xce, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd3, 0xd4, 0xd4, - 0xd4, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd7, 0xd8, 0xd7, 0xd8, 0xd9, - 0xd9, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xda, 0xdc, 0xdc, 0xdb, 0xdb, - 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xda, 0xdb, 0xdc, - 0xdc, 0xdb, 0xdc, 0xda, 0xda, 0xda, 0xdb, 0xda, 0xda, 0xdc, 0xdc, 0xdb, - 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, - 0xd8, 0xd8, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, - 0xd7, 0xd6, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, - 0xd5, 0xd5, 0xd5, 0xd4, 0xd3, 0xd1, 0xcc, 0xc4, 0xbe, 0xb7, 0xb9, 0xb9, - 0xb3, 0xaf, 0xad, 0xb3, 0xb6, 0xb6, 0xb5, 0xb3, 0xb0, 0xad, 0xac, 0xab, - 0xa7, 0xa1, 0x9b, 0x96, 0x93, 0x89, 0x76, 0x6d, 0x78, 0x81, 0x87, 0x8d, - 0x8f, 0x8e, 0x8c, 0x87, 0x7e, 0x73, 0x6c, 0x6e, 0x7b, 0x88, 0x75, 0x66, - 0x5f, 0x5b, 0x59, 0x5a, 0x61, 0x68, 0x71, 0x7d, 0x86, 0x84, 0x7a, 0x67, - 0x6f, 0x87, 0x84, 0x79, 0x72, 0x69, 0x58, 0x4f, 0x4b, 0x4e, 0x5b, 0x6c, - 0x6a, 0x62, 0x5d, 0x59, 0x5e, 0x68, 0x69, 0x61, 0x4f, 0x4c, 0x4e, 0x4d, - 0x4f, 0x55, 0x5b, 0x5c, 0x59, 0x59, 0x5b, 0x5d, 0x5f, 0x5f, 0x5f, 0x5f, - 0x61, 0x62, 0x62, 0x63, 0x63, 0x65, 0x65, 0x64, 0x63, 0x64, 0x64, 0x62, - 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5d, 0x5c, 0x5b, 0x58, 0x57, 0x58, 0x58, - 0x59, 0x5a, 0x5b, 0x5f, 0x62, 0x64, 0x65, 0x6a, 0x70, 0x76, 0x79, 0x7a, - 0x7a, 0x76, 0x71, 0x6e, 0x6a, 0x67, 0x64, 0x65, 0x65, 0x66, 0x68, 0x6a, - 0x6a, 0x6a, 0x68, 0x66, 0x64, 0x63, 0x61, 0x5e, 0x5b, 0x5a, 0x58, 0x57, - 0x56, 0x53, 0x4f, 0x4d, 0x4d, 0x4e, 0x4e, 0x4d, 0x4e, 0x4e, 0x4e, 0x4f, - 0x4f, 0x50, 0x50, 0x4f, 0x50, 0x50, 0x50, 0x50, 0x51, 0x50, 0x50, 0x4f, - 0x4f, 0x4f, 0x4d, 0x4d, 0x4d, 0x4c, 0x4d, 0x4c, 0x67, 0x63, 0x61, 0x5f, - 0x5b, 0x57, 0x53, 0x4f, 0x4d, 0x49, 0x47, 0x46, 0x47, 0x49, 0x4c, 0x52, - 0x58, 0x5a, 0x5c, 0x5e, 0x62, 0x64, 0x66, 0x67, 0x68, 0x6b, 0x70, 0x76, - 0x78, 0x78, 0x74, 0x71, 0x80, 0x98, 0xc4, 0xcf, 0xce, 0xce, 0xce, 0xcf, - 0xd0, 0xd1, 0xd3, 0xd3, 0xd3, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd4, - 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xda, 0xda, 0xd9, - 0xd9, 0xd9, 0xdb, 0xdc, 0xdb, 0xda, 0xdb, 0xda, 0xdb, 0xda, 0xda, 0xdb, - 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xda, 0xdb, 0xda, 0xda, 0xd9, 0xdb, 0xdb, - 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xda, 0xdb, 0xdc, 0xda, 0xda, 0xdb, 0xdb, - 0xda, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, - 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xda, 0xd9, 0xd8, - 0xd7, 0xd8, 0xd6, 0xd5, 0xd4, 0xd5, 0xd4, 0xd4, 0xd5, 0xd4, 0xd4, 0xd4, - 0xd4, 0xd4, 0xd3, 0xd0, 0xcb, 0xc3, 0xbd, 0xbc, 0xba, 0xb5, 0xad, 0xac, - 0xb3, 0xb6, 0xb6, 0xb4, 0xb1, 0xaf, 0xae, 0xac, 0xa7, 0xa2, 0x9c, 0x99, - 0x96, 0x8e, 0x7f, 0x6c, 0x71, 0x78, 0x84, 0x8a, 0x8c, 0x8d, 0x8b, 0x86, - 0x80, 0x75, 0x6d, 0x6e, 0x77, 0x83, 0x73, 0x65, 0x5f, 0x5c, 0x59, 0x59, - 0x5d, 0x63, 0x6c, 0x76, 0x7f, 0x83, 0x7b, 0x64, 0x5a, 0x7d, 0x83, 0x7a, - 0x74, 0x6b, 0x5b, 0x50, 0x4c, 0x4e, 0x59, 0x68, 0x66, 0x61, 0x5d, 0x57, - 0x59, 0x64, 0x6a, 0x66, 0x56, 0x4d, 0x4f, 0x4e, 0x4e, 0x53, 0x59, 0x5c, - 0x59, 0x58, 0x5a, 0x5c, 0x5e, 0x5e, 0x5e, 0x5e, 0x60, 0x60, 0x62, 0x62, - 0x63, 0x64, 0x64, 0x64, 0x64, 0x63, 0x62, 0x62, 0x61, 0x61, 0x60, 0x5e, - 0x5d, 0x5b, 0x5a, 0x58, 0x57, 0x57, 0x58, 0x58, 0x59, 0x5a, 0x5c, 0x60, - 0x63, 0x65, 0x67, 0x6d, 0x74, 0x78, 0x7a, 0x7b, 0x78, 0x73, 0x6d, 0x6a, - 0x68, 0x65, 0x63, 0x64, 0x64, 0x65, 0x66, 0x67, 0x67, 0x65, 0x64, 0x62, - 0x5f, 0x5d, 0x5c, 0x5a, 0x56, 0x55, 0x54, 0x54, 0x53, 0x51, 0x4e, 0x4d, - 0x4c, 0x4d, 0x4d, 0x4c, 0x4c, 0x4d, 0x4f, 0x50, 0x50, 0x50, 0x50, 0x50, - 0x50, 0x4f, 0x4f, 0x4f, 0x4f, 0x4e, 0x4e, 0x4c, 0x4c, 0x4c, 0x4b, 0x4b, - 0x4a, 0x49, 0x48, 0x4a, 0x64, 0x61, 0x5f, 0x5c, 0x58, 0x55, 0x52, 0x4e, - 0x4c, 0x49, 0x47, 0x45, 0x45, 0x47, 0x4c, 0x51, 0x59, 0x5b, 0x5d, 0x5f, - 0x62, 0x65, 0x68, 0x69, 0x6a, 0x6e, 0x73, 0x79, 0x7b, 0x7a, 0x74, 0x73, - 0x88, 0xa1, 0xc6, 0xcf, 0xcd, 0xcd, 0xcd, 0xce, 0xcf, 0xd2, 0xd3, 0xd3, - 0xd3, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd3, 0xd5, 0xd5, 0xd5, 0xd5, 0xd6, - 0xd6, 0xd7, 0xd7, 0xd7, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xdb, 0xdc, - 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xda, 0xdb, 0xdb, - 0xdb, 0xdb, 0xda, 0xdb, 0xdb, 0xda, 0xda, 0xdb, 0xdb, 0xda, 0xda, 0xda, - 0xda, 0xdc, 0xdd, 0xdd, 0xdc, 0xdc, 0xdd, 0xdd, 0xdc, 0xdc, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, - 0xdc, 0xdd, 0xdc, 0xdb, 0xdb, 0xdc, 0xdb, 0xda, 0xd9, 0xd9, 0xd9, 0xd6, - 0xd6, 0xd5, 0xd5, 0xd4, 0xd5, 0xd5, 0xd4, 0xd4, 0xd4, 0xd5, 0xd4, 0xd3, - 0xd2, 0xce, 0xc7, 0xc2, 0xc0, 0xbc, 0xb2, 0xab, 0xb0, 0xb5, 0xb6, 0xb4, - 0xb2, 0xb0, 0xae, 0xac, 0xa8, 0xa3, 0x9e, 0x9b, 0x98, 0x91, 0x83, 0x70, - 0x6a, 0x70, 0x7f, 0x88, 0x8b, 0x8b, 0x8a, 0x87, 0x81, 0x76, 0x6e, 0x6e, - 0x75, 0x7f, 0x71, 0x65, 0x5f, 0x5c, 0x59, 0x58, 0x5b, 0x60, 0x69, 0x73, - 0x7d, 0x83, 0x7d, 0x64, 0x4b, 0x72, 0x80, 0x79, 0x74, 0x6e, 0x5f, 0x54, - 0x4f, 0x50, 0x59, 0x66, 0x65, 0x62, 0x5e, 0x55, 0x54, 0x5f, 0x6b, 0x6a, - 0x5c, 0x51, 0x51, 0x50, 0x4e, 0x4f, 0x57, 0x5b, 0x58, 0x57, 0x5a, 0x5b, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5e, 0x5f, 0x61, 0x62, 0x62, 0x62, 0x62, 0x63, - 0x64, 0x63, 0x61, 0x60, 0x60, 0x60, 0x5f, 0x5d, 0x5c, 0x5b, 0x5a, 0x58, - 0x57, 0x57, 0x58, 0x58, 0x59, 0x5b, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6f, - 0x76, 0x78, 0x78, 0x77, 0x75, 0x70, 0x6b, 0x69, 0x65, 0x63, 0x62, 0x63, - 0x63, 0x63, 0x63, 0x63, 0x63, 0x61, 0x60, 0x5e, 0x5b, 0x59, 0x58, 0x55, - 0x53, 0x51, 0x51, 0x51, 0x51, 0x4f, 0x4d, 0x4c, 0x4c, 0x4c, 0x4b, 0x4b, - 0x4c, 0x4d, 0x4f, 0x4f, 0x50, 0x51, 0x51, 0x50, 0x51, 0x4f, 0x4f, 0x4e, - 0x4d, 0x4c, 0x4c, 0x4b, 0x4a, 0x4a, 0x4a, 0x49, 0x47, 0x47, 0x47, 0x48, - 0x62, 0x5f, 0x5d, 0x5b, 0x57, 0x54, 0x50, 0x4d, 0x4b, 0x48, 0x46, 0x44, - 0x44, 0x46, 0x4b, 0x52, 0x59, 0x5c, 0x5d, 0x5f, 0x63, 0x65, 0x68, 0x6a, - 0x6b, 0x6e, 0x74, 0x7a, 0x7c, 0x7b, 0x74, 0x73, 0x8d, 0xa6, 0xc7, 0xcf, - 0xcd, 0xcc, 0xcd, 0xcd, 0xcf, 0xd1, 0xd2, 0xd2, 0xd2, 0xd4, 0xd4, 0xd3, - 0xd3, 0xd4, 0xd3, 0xd4, 0xd4, 0xd3, 0xd4, 0xd5, 0xd5, 0xd6, 0xd6, 0xd6, - 0xd8, 0xd8, 0xd8, 0xd9, 0xd8, 0xd8, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdc, - 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdd, 0xde, 0xde, - 0xde, 0xde, 0xdd, 0xdd, 0xdc, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdd, 0xdd, 0xdd, 0xdc, - 0xdb, 0xdc, 0xdb, 0xdb, 0xda, 0xda, 0xda, 0xd7, 0xd7, 0xd6, 0xd5, 0xd4, - 0xd5, 0xd5, 0xd5, 0xd5, 0xd4, 0xd5, 0xd4, 0xd3, 0xd3, 0xd2, 0xcd, 0xc7, - 0xc4, 0xc1, 0xb8, 0xac, 0xae, 0xb2, 0xb4, 0xb4, 0xb2, 0xb0, 0xae, 0xac, - 0xa9, 0xa5, 0x9f, 0x9c, 0x99, 0x93, 0x85, 0x74, 0x68, 0x6a, 0x7b, 0x86, - 0x8a, 0x8a, 0x89, 0x86, 0x81, 0x77, 0x6f, 0x6e, 0x74, 0x7c, 0x70, 0x64, - 0x5f, 0x5d, 0x59, 0x58, 0x5b, 0x5e, 0x67, 0x72, 0x7b, 0x84, 0x7f, 0x65, - 0x45, 0x65, 0x7b, 0x78, 0x74, 0x6f, 0x61, 0x56, 0x51, 0x51, 0x58, 0x65, - 0x64, 0x61, 0x5d, 0x55, 0x51, 0x5b, 0x69, 0x6a, 0x5f, 0x54, 0x52, 0x50, - 0x4e, 0x4e, 0x56, 0x5b, 0x57, 0x56, 0x59, 0x5a, 0x5c, 0x5b, 0x5b, 0x5c, - 0x5d, 0x5f, 0x60, 0x61, 0x61, 0x61, 0x61, 0x62, 0x63, 0x62, 0x61, 0x60, - 0x60, 0x5f, 0x5e, 0x5c, 0x5b, 0x5b, 0x5a, 0x58, 0x57, 0x57, 0x57, 0x58, - 0x59, 0x5c, 0x60, 0x63, 0x66, 0x68, 0x6a, 0x70, 0x76, 0x77, 0x77, 0x75, - 0x71, 0x6d, 0x6a, 0x67, 0x64, 0x61, 0x61, 0x62, 0x62, 0x61, 0x61, 0x61, - 0x60, 0x5f, 0x5c, 0x5b, 0x58, 0x57, 0x56, 0x53, 0x51, 0x50, 0x50, 0x50, - 0x50, 0x4e, 0x4c, 0x4b, 0x4b, 0x4c, 0x4b, 0x4b, 0x4d, 0x4d, 0x4f, 0x4f, - 0x50, 0x51, 0x51, 0x50, 0x51, 0x4f, 0x4e, 0x4d, 0x4b, 0x4a, 0x4b, 0x49, - 0x49, 0x48, 0x49, 0x48, 0x46, 0x45, 0x45, 0x46, 0x60, 0x5d, 0x5b, 0x59, - 0x56, 0x52, 0x4e, 0x4c, 0x49, 0x47, 0x45, 0x42, 0x42, 0x45, 0x4a, 0x51, - 0x59, 0x5d, 0x5e, 0x60, 0x63, 0x66, 0x69, 0x6b, 0x6c, 0x6f, 0x75, 0x7b, - 0x7d, 0x7c, 0x75, 0x73, 0x93, 0xac, 0xc8, 0xcf, 0xcd, 0xcd, 0xcd, 0xce, - 0xcf, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd2, 0xd3, - 0xd3, 0xd2, 0xd3, 0xd4, 0xd5, 0xd5, 0xd6, 0xd6, 0xd7, 0xd7, 0xd7, 0xd7, - 0xd8, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, - 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, - 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdf, 0xdf, 0xde, 0xe0, 0xdf, 0xde, 0xde, - 0xdd, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, - 0xdd, 0xdd, 0xdd, 0xde, 0xdd, 0xde, 0xdd, 0xdc, 0xdb, 0xdc, 0xdd, 0xdc, - 0xdc, 0xdc, 0xdb, 0xd9, 0xd8, 0xd7, 0xd7, 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, - 0xd5, 0xd5, 0xd4, 0xd4, 0xd3, 0xd3, 0xd1, 0xcd, 0xca, 0xc8, 0xc2, 0xb5, - 0xab, 0xad, 0xb0, 0xb2, 0xb1, 0xb0, 0xae, 0xad, 0xa9, 0xa5, 0xa1, 0x9e, - 0x9b, 0x95, 0x8a, 0x79, 0x6a, 0x68, 0x75, 0x81, 0x86, 0x87, 0x87, 0x85, - 0x80, 0x77, 0x70, 0x6f, 0x72, 0x79, 0x6f, 0x64, 0x60, 0x5c, 0x59, 0x58, - 0x59, 0x5d, 0x64, 0x6e, 0x79, 0x83, 0x81, 0x6a, 0x42, 0x50, 0x6f, 0x75, - 0x74, 0x6f, 0x63, 0x59, 0x54, 0x53, 0x57, 0x63, 0x62, 0x5f, 0x5b, 0x54, - 0x4f, 0x55, 0x61, 0x65, 0x62, 0x58, 0x52, 0x4f, 0x4d, 0x4c, 0x55, 0x5b, - 0x57, 0x56, 0x58, 0x59, 0x5a, 0x5b, 0x5b, 0x5c, 0x5d, 0x5f, 0x60, 0x60, - 0x5e, 0x5e, 0x5f, 0x61, 0x62, 0x61, 0x5f, 0x5f, 0x5f, 0x5e, 0x5d, 0x5c, - 0x5a, 0x5a, 0x59, 0x58, 0x57, 0x57, 0x58, 0x59, 0x59, 0x5d, 0x61, 0x64, - 0x67, 0x69, 0x6c, 0x72, 0x74, 0x74, 0x73, 0x71, 0x6e, 0x69, 0x66, 0x65, - 0x62, 0x60, 0x5f, 0x60, 0x60, 0x60, 0x5e, 0x5d, 0x5c, 0x5a, 0x59, 0x57, - 0x55, 0x52, 0x51, 0x50, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4d, 0x4b, 0x4a, - 0x4a, 0x4b, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x4f, 0x51, 0x51, 0x50, 0x50, - 0x50, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x48, 0x47, 0x46, 0x46, 0x46, - 0x45, 0x44, 0x44, 0x45, 0x5f, 0x5c, 0x58, 0x56, 0x52, 0x50, 0x4d, 0x4a, - 0x47, 0x45, 0x42, 0x42, 0x41, 0x43, 0x49, 0x51, 0x58, 0x5d, 0x5f, 0x61, - 0x64, 0x69, 0x6b, 0x6c, 0x6e, 0x71, 0x77, 0x7c, 0x7e, 0x7d, 0x75, 0x75, - 0x9d, 0xb7, 0xca, 0xce, 0xce, 0xce, 0xce, 0xcd, 0xce, 0xd1, 0xd1, 0xd1, - 0xd1, 0xd3, 0xd3, 0xd3, 0xd3, 0xd1, 0xd1, 0xd3, 0xd3, 0xd2, 0xd3, 0xd2, - 0xd3, 0xd5, 0xd5, 0xd4, 0xd6, 0xd7, 0xd7, 0xd7, 0xd8, 0xd8, 0xd9, 0xd8, - 0xd8, 0xd9, 0xda, 0xdb, 0xda, 0xda, 0xda, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, - 0xdb, 0xdb, 0xdb, 0xdc, 0xdd, 0xdd, 0xdc, 0xde, 0xde, 0xde, 0xde, 0xde, - 0xde, 0xdf, 0xdf, 0xdf, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, - 0xe0, 0xe0, 0xe0, 0xe0, 0xde, 0xde, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xdf, - 0xdf, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdd, 0xdb, - 0xd9, 0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd6, 0xd5, 0xd6, 0xd6, 0xd5, 0xd5, - 0xd5, 0xd3, 0xd2, 0xd1, 0xce, 0xcd, 0xca, 0xc1, 0xb2, 0xaa, 0xaa, 0xae, - 0xb0, 0xaf, 0xae, 0xac, 0xa9, 0xa5, 0xa1, 0x9f, 0x9c, 0x97, 0x8f, 0x81, - 0x71, 0x6a, 0x6d, 0x7a, 0x82, 0x85, 0x84, 0x83, 0x7c, 0x75, 0x71, 0x6f, - 0x71, 0x75, 0x6d, 0x63, 0x5e, 0x5d, 0x5a, 0x59, 0x59, 0x5b, 0x62, 0x6c, - 0x77, 0x81, 0x80, 0x6c, 0x42, 0x3b, 0x59, 0x6d, 0x72, 0x6f, 0x66, 0x5e, - 0x58, 0x56, 0x57, 0x62, 0x61, 0x5c, 0x58, 0x52, 0x4c, 0x4e, 0x56, 0x5c, - 0x62, 0x5b, 0x53, 0x4e, 0x4c, 0x4c, 0x54, 0x5a, 0x57, 0x56, 0x58, 0x57, - 0x57, 0x59, 0x59, 0x5c, 0x5e, 0x5f, 0x5f, 0x5f, 0x5e, 0x5e, 0x5f, 0x60, - 0x60, 0x5f, 0x5e, 0x5e, 0x5d, 0x5d, 0x5c, 0x5a, 0x59, 0x58, 0x58, 0x58, - 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5f, 0x62, 0x66, 0x68, 0x69, 0x6d, 0x72, - 0x71, 0x70, 0x6e, 0x6c, 0x68, 0x64, 0x61, 0x60, 0x5f, 0x5f, 0x5d, 0x5c, - 0x5c, 0x5c, 0x5a, 0x57, 0x56, 0x55, 0x54, 0x52, 0x4f, 0x4e, 0x4e, 0x4d, - 0x4d, 0x4f, 0x50, 0x50, 0x4e, 0x4c, 0x4a, 0x49, 0x49, 0x4a, 0x4b, 0x4c, - 0x4e, 0x4f, 0x50, 0x50, 0x50, 0x51, 0x51, 0x50, 0x4e, 0x4c, 0x4a, 0x4a, - 0x49, 0x47, 0x46, 0x46, 0x46, 0x46, 0x44, 0x43, 0x43, 0x42, 0x42, 0x42, - 0x5d, 0x59, 0x56, 0x54, 0x50, 0x4e, 0x4b, 0x47, 0x45, 0x43, 0x41, 0x41, - 0x41, 0x42, 0x49, 0x51, 0x59, 0x5e, 0x60, 0x63, 0x66, 0x6a, 0x6d, 0x6e, - 0x71, 0x75, 0x7b, 0x7e, 0x7f, 0x7e, 0x76, 0x78, 0xa7, 0xc0, 0xcc, 0xce, - 0xcf, 0xce, 0xce, 0xcd, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xd1, 0xd1, 0xd2, - 0xd2, 0xd1, 0xd0, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd4, 0xd5, 0xd4, - 0xd5, 0xd7, 0xd8, 0xd8, 0xd8, 0xd8, 0xda, 0xd9, 0xd8, 0xd9, 0xdb, 0xdb, - 0xdb, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdc, - 0xdc, 0xdc, 0xdc, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xde, 0xdf, 0xe0, 0xe0, - 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, - 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdd, 0xde, 0xdc, 0xdd, 0xdd, - 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdd, 0xdd, 0xdc, 0xd9, 0xd8, 0xd8, 0xd8, - 0xd9, 0xd9, 0xd7, 0xd7, 0xd7, 0xd7, 0xd6, 0xd6, 0xd6, 0xd5, 0xd4, 0xd3, - 0xd1, 0xd0, 0xce, 0xca, 0xc0, 0xb6, 0xb1, 0xaf, 0xae, 0xad, 0xad, 0xac, - 0xa9, 0xa6, 0xa1, 0x9f, 0x9d, 0x9a, 0x92, 0x86, 0x7a, 0x70, 0x67, 0x72, - 0x7d, 0x81, 0x82, 0x80, 0x7a, 0x74, 0x70, 0x6e, 0x70, 0x73, 0x6b, 0x61, - 0x5d, 0x5c, 0x5a, 0x59, 0x59, 0x5b, 0x62, 0x6c, 0x78, 0x80, 0x7e, 0x6e, - 0x44, 0x2f, 0x42, 0x5b, 0x65, 0x68, 0x64, 0x60, 0x5a, 0x55, 0x52, 0x5e, - 0x5f, 0x5a, 0x56, 0x4f, 0x46, 0x44, 0x4a, 0x53, 0x60, 0x5d, 0x54, 0x4e, - 0x4b, 0x4a, 0x51, 0x58, 0x56, 0x55, 0x57, 0x56, 0x56, 0x57, 0x58, 0x5a, - 0x5d, 0x5e, 0x5e, 0x5e, 0x5d, 0x5d, 0x5e, 0x5f, 0x5f, 0x5d, 0x5e, 0x5d, - 0x5c, 0x5b, 0x5b, 0x59, 0x58, 0x58, 0x58, 0x58, 0x57, 0x58, 0x5a, 0x5b, - 0x5d, 0x60, 0x63, 0x67, 0x69, 0x6a, 0x6c, 0x6f, 0x6d, 0x6a, 0x68, 0x67, - 0x64, 0x60, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58, 0x56, 0x55, 0x53, - 0x52, 0x50, 0x4f, 0x4d, 0x4c, 0x4b, 0x4b, 0x4b, 0x4d, 0x4f, 0x50, 0x50, - 0x4f, 0x4d, 0x4b, 0x4a, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51, - 0x51, 0x50, 0x50, 0x50, 0x4e, 0x4b, 0x49, 0x48, 0x48, 0x46, 0x44, 0x43, - 0x44, 0x44, 0x43, 0x42, 0x41, 0x42, 0x43, 0x43, 0x5c, 0x58, 0x55, 0x52, - 0x4f, 0x4c, 0x48, 0x45, 0x43, 0x42, 0x40, 0x40, 0x3f, 0x41, 0x48, 0x52, - 0x59, 0x5e, 0x60, 0x63, 0x67, 0x6b, 0x6d, 0x6e, 0x71, 0x77, 0x7c, 0x80, - 0x81, 0x7f, 0x77, 0x7c, 0xaf, 0xc7, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcc, - 0xcd, 0xce, 0xce, 0xce, 0xcf, 0xd0, 0xd1, 0xd1, 0xd1, 0xd0, 0xcf, 0xcf, - 0xd0, 0xd1, 0xd3, 0xd3, 0xd2, 0xd4, 0xd4, 0xd4, 0xd4, 0xd7, 0xd8, 0xd8, - 0xd8, 0xd8, 0xd9, 0xd8, 0xda, 0xda, 0xda, 0xda, 0xdb, 0xdc, 0xdc, 0xdb, - 0xdb, 0xdc, 0xdc, 0xdc, 0xdc, 0xdb, 0xda, 0xdc, 0xdc, 0xdc, 0xdd, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdd, 0xdc, 0xdd, 0xde, - 0xdd, 0xde, 0xde, 0xdc, 0xdc, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, - 0xdc, 0xdc, 0xdc, 0xda, 0xda, 0xd9, 0xd8, 0xd8, 0xd9, 0xd9, 0xd8, 0xd8, - 0xd8, 0xd7, 0xd7, 0xd7, 0xd6, 0xd6, 0xd6, 0xd4, 0xd3, 0xd3, 0xd1, 0xce, - 0xca, 0xc3, 0xbd, 0xb7, 0xb0, 0xac, 0xac, 0xac, 0xaa, 0xa6, 0xa1, 0x9f, - 0x9e, 0x9b, 0x94, 0x8a, 0x80, 0x76, 0x67, 0x6c, 0x78, 0x7f, 0x80, 0x7e, - 0x78, 0x73, 0x70, 0x6f, 0x6f, 0x72, 0x6a, 0x60, 0x5d, 0x5c, 0x5a, 0x59, - 0x5a, 0x5d, 0x63, 0x6d, 0x79, 0x80, 0x7e, 0x6e, 0x47, 0x2b, 0x32, 0x46, - 0x51, 0x5b, 0x5f, 0x5f, 0x5a, 0x54, 0x4f, 0x59, 0x5d, 0x59, 0x55, 0x4e, - 0x44, 0x41, 0x44, 0x4d, 0x5c, 0x5d, 0x56, 0x4f, 0x4b, 0x4a, 0x50, 0x57, - 0x56, 0x55, 0x56, 0x56, 0x56, 0x57, 0x57, 0x59, 0x5d, 0x5e, 0x5e, 0x5d, - 0x5d, 0x5d, 0x5e, 0x5d, 0x5d, 0x5d, 0x5d, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, - 0x58, 0x57, 0x57, 0x58, 0x58, 0x58, 0x5a, 0x5b, 0x5d, 0x61, 0x64, 0x68, - 0x6a, 0x6b, 0x6b, 0x6c, 0x6a, 0x67, 0x65, 0x64, 0x61, 0x5e, 0x5d, 0x5b, - 0x59, 0x58, 0x57, 0x56, 0x55, 0x54, 0x52, 0x50, 0x4e, 0x4d, 0x4b, 0x4a, - 0x4a, 0x4a, 0x4a, 0x4b, 0x4e, 0x50, 0x50, 0x50, 0x4f, 0x4d, 0x4a, 0x49, - 0x49, 0x4a, 0x4c, 0x4e, 0x4f, 0x50, 0x50, 0x50, 0x51, 0x50, 0x50, 0x4f, - 0x4d, 0x4a, 0x49, 0x48, 0x47, 0x45, 0x43, 0x43, 0x43, 0x43, 0x42, 0x41, - 0x41, 0x41, 0x42, 0x42, 0x5b, 0x57, 0x53, 0x51, 0x4e, 0x4b, 0x47, 0x44, - 0x43, 0x42, 0x40, 0x3f, 0x40, 0x41, 0x48, 0x52, 0x5a, 0x5e, 0x60, 0x63, - 0x68, 0x6c, 0x6e, 0x6f, 0x72, 0x78, 0x7d, 0x80, 0x81, 0x7f, 0x77, 0x80, - 0xb3, 0xca, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0xcf, 0xce, - 0xce, 0xd0, 0xd1, 0xd1, 0xd1, 0xd0, 0xcf, 0xcf, 0xcf, 0xd0, 0xd2, 0xd3, - 0xd2, 0xd3, 0xd4, 0xd3, 0xd4, 0xd6, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd8, - 0xd9, 0xda, 0xda, 0xda, 0xdb, 0xdc, 0xdc, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, - 0xdc, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, - 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdd, 0xdc, 0xdc, 0xdd, 0xdc, 0xde, 0xdd, 0xdb, - 0xdb, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc, 0xd9, - 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, 0xd7, 0xd7, 0xd7, 0xd8, 0xd7, - 0xd6, 0xd6, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd0, 0xcd, 0xc9, 0xc5, 0xbe, - 0xb5, 0xae, 0xac, 0xab, 0xaa, 0xa6, 0xa1, 0x9f, 0x9e, 0x9b, 0x95, 0x8c, - 0x84, 0x7a, 0x69, 0x68, 0x74, 0x7c, 0x7e, 0x7c, 0x77, 0x72, 0x70, 0x6f, - 0x6f, 0x72, 0x69, 0x60, 0x5c, 0x5b, 0x59, 0x59, 0x5a, 0x5d, 0x64, 0x6d, - 0x78, 0x7f, 0x7e, 0x6f, 0x49, 0x2a, 0x2c, 0x39, 0x42, 0x4e, 0x58, 0x5c, - 0x57, 0x52, 0x4c, 0x54, 0x5a, 0x58, 0x54, 0x4d, 0x43, 0x41, 0x43, 0x4a, - 0x58, 0x5c, 0x56, 0x50, 0x4c, 0x4a, 0x50, 0x56, 0x55, 0x54, 0x56, 0x56, - 0x57, 0x57, 0x57, 0x59, 0x5c, 0x5e, 0x5d, 0x5d, 0x5d, 0x5e, 0x5d, 0x5d, - 0x5d, 0x5d, 0x5d, 0x5b, 0x59, 0x59, 0x59, 0x57, 0x57, 0x57, 0x57, 0x58, - 0x57, 0x58, 0x59, 0x5b, 0x5e, 0x62, 0x64, 0x68, 0x6a, 0x6a, 0x6a, 0x69, - 0x67, 0x65, 0x63, 0x62, 0x5f, 0x5d, 0x5b, 0x5a, 0x58, 0x56, 0x55, 0x54, - 0x53, 0x52, 0x51, 0x4f, 0x4c, 0x4b, 0x49, 0x48, 0x48, 0x49, 0x4a, 0x4b, - 0x4e, 0x50, 0x50, 0x50, 0x4f, 0x4d, 0x4a, 0x49, 0x49, 0x4a, 0x4c, 0x4e, - 0x4f, 0x50, 0x50, 0x4f, 0x50, 0x4f, 0x4f, 0x4e, 0x4c, 0x49, 0x48, 0x47, - 0x46, 0x44, 0x43, 0x42, 0x43, 0x42, 0x41, 0x42, 0x41, 0x41, 0x42, 0x42, - 0x59, 0x55, 0x51, 0x4f, 0x4c, 0x49, 0x45, 0x43, 0x42, 0x41, 0x3f, 0x40, - 0x40, 0x42, 0x48, 0x54, 0x5c, 0x5f, 0x61, 0x63, 0x69, 0x6d, 0x6f, 0x70, - 0x73, 0x7a, 0x7f, 0x81, 0x81, 0x7f, 0x78, 0x86, 0xb8, 0xcd, 0xcc, 0xcc, - 0xcd, 0xcc, 0xcc, 0xcb, 0xcc, 0xce, 0xcf, 0xcf, 0xce, 0xcf, 0xd0, 0xd0, - 0xd0, 0xcf, 0xd0, 0xcf, 0xcf, 0xcf, 0xd2, 0xd3, 0xd2, 0xd3, 0xd3, 0xd3, - 0xd5, 0xd5, 0xd6, 0xd7, 0xd9, 0xd9, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0xd9, - 0xdb, 0xdc, 0xdc, 0xdb, 0xdb, 0xdc, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, - 0xdc, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, - 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, - 0xdc, 0xdb, 0xdc, 0xdc, 0xdc, 0xdd, 0xdc, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, - 0xdb, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xd9, 0xd8, 0xd9, 0xda, 0xd9, - 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7, 0xd6, 0xd5, 0xd6, 0xd5, - 0xd5, 0xd4, 0xd3, 0xd2, 0xd0, 0xcd, 0xcc, 0xc8, 0xc0, 0xb6, 0xaf, 0xac, - 0xa9, 0xa5, 0xa2, 0xa1, 0xa0, 0x9d, 0x96, 0x8d, 0x86, 0x7e, 0x6f, 0x66, - 0x6d, 0x77, 0x79, 0x78, 0x75, 0x71, 0x6f, 0x6e, 0x6f, 0x71, 0x68, 0x5f, - 0x5b, 0x5a, 0x5a, 0x59, 0x5a, 0x5c, 0x63, 0x6b, 0x75, 0x7b, 0x7b, 0x6e, - 0x4c, 0x2b, 0x28, 0x2c, 0x30, 0x39, 0x48, 0x52, 0x51, 0x4c, 0x46, 0x4a, - 0x54, 0x53, 0x4f, 0x49, 0x41, 0x40, 0x40, 0x45, 0x51, 0x5a, 0x58, 0x52, - 0x4f, 0x4d, 0x50, 0x54, 0x53, 0x53, 0x56, 0x57, 0x58, 0x57, 0x58, 0x59, - 0x5c, 0x5c, 0x5b, 0x5b, 0x5b, 0x5d, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5a, - 0x58, 0x58, 0x58, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x58, 0x5a, 0x5c, - 0x60, 0x63, 0x65, 0x67, 0x68, 0x68, 0x68, 0x66, 0x64, 0x62, 0x60, 0x5d, - 0x5b, 0x5a, 0x58, 0x57, 0x55, 0x53, 0x52, 0x50, 0x50, 0x4f, 0x4e, 0x4c, - 0x49, 0x48, 0x48, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4f, 0x50, 0x50, 0x4f, - 0x4e, 0x4b, 0x49, 0x49, 0x49, 0x49, 0x4c, 0x4d, 0x4e, 0x4f, 0x4f, 0x4e, - 0x4e, 0x4e, 0x4d, 0x4c, 0x4a, 0x48, 0x46, 0x46, 0x45, 0x44, 0x43, 0x42, - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x41, 0x41, 0x57, 0x52, 0x4e, 0x4c, - 0x4a, 0x47, 0x44, 0x42, 0x42, 0x40, 0x3f, 0x41, 0x41, 0x42, 0x48, 0x53, - 0x5d, 0x61, 0x63, 0x65, 0x6a, 0x6e, 0x6f, 0x72, 0x76, 0x7d, 0x81, 0x82, - 0x81, 0x7f, 0x7b, 0x90, 0xbe, 0xcf, 0xcd, 0xcc, 0xcd, 0xcd, 0xcc, 0xcb, - 0xcc, 0xce, 0xcf, 0xcf, 0xcf, 0xcf, 0xce, 0xce, 0xcf, 0xd0, 0xd0, 0xd0, - 0xcf, 0xcf, 0xd1, 0xd2, 0xd2, 0xd3, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd7, - 0xd9, 0xd9, 0xd9, 0xd8, 0xd9, 0xda, 0xda, 0xd9, 0xdb, 0xdc, 0xdc, 0xdb, - 0xdb, 0xdc, 0xdd, 0xdd, 0xdc, 0xde, 0xde, 0xdc, 0xdc, 0xde, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, - 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xde, 0xdc, 0xdc, 0xdd, 0xdd, - 0xde, 0xde, 0xdd, 0xdc, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, - 0xdb, 0xdc, 0xdc, 0xda, 0xd9, 0xd9, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, 0xd8, - 0xd7, 0xd8, 0xd7, 0xd7, 0xd6, 0xd5, 0xd6, 0xd5, 0xd5, 0xd5, 0xd4, 0xd4, - 0xd2, 0xd0, 0xd0, 0xcf, 0xcb, 0xc2, 0xb9, 0xb3, 0xac, 0xa4, 0xa3, 0xa2, - 0xa1, 0x9d, 0x97, 0x8e, 0x89, 0x84, 0x77, 0x66, 0x67, 0x6f, 0x72, 0x72, - 0x72, 0x70, 0x6e, 0x6d, 0x6e, 0x70, 0x66, 0x5d, 0x5a, 0x59, 0x59, 0x59, - 0x59, 0x5b, 0x62, 0x6b, 0x72, 0x76, 0x74, 0x6c, 0x50, 0x2f, 0x28, 0x26, - 0x25, 0x28, 0x38, 0x44, 0x44, 0x40, 0x3a, 0x3b, 0x4a, 0x4c, 0x49, 0x44, - 0x3d, 0x3d, 0x3c, 0x3f, 0x49, 0x54, 0x57, 0x55, 0x53, 0x51, 0x51, 0x53, - 0x52, 0x52, 0x57, 0x58, 0x58, 0x58, 0x59, 0x58, 0x59, 0x5b, 0x5a, 0x5a, - 0x5a, 0x5b, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x59, 0x57, 0x57, 0x57, 0x55, - 0x56, 0x56, 0x57, 0x57, 0x57, 0x58, 0x5b, 0x5d, 0x61, 0x64, 0x66, 0x67, - 0x66, 0x65, 0x64, 0x63, 0x60, 0x5e, 0x5b, 0x58, 0x56, 0x55, 0x54, 0x53, - 0x51, 0x50, 0x4e, 0x4d, 0x4c, 0x4c, 0x4a, 0x47, 0x47, 0x47, 0x46, 0x47, - 0x4a, 0x4b, 0x4c, 0x4d, 0x4f, 0x50, 0x50, 0x4f, 0x4d, 0x4a, 0x49, 0x49, - 0x49, 0x49, 0x4c, 0x4d, 0x4e, 0x4e, 0x4e, 0x4d, 0x4d, 0x4c, 0x4b, 0x4a, - 0x48, 0x47, 0x45, 0x44, 0x44, 0x42, 0x42, 0x41, 0x40, 0x41, 0x42, 0x41, - 0x42, 0x42, 0x41, 0x42, 0x80, 0x72, 0x80, 0x72, 0x7f, 0x72, 0x7f, 0x72, - 0x7f, 0x71, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, - 0x7e, 0x71, 0x7d, 0x70, 0x7d, 0x70, 0x7e, 0x70, 0x7f, 0x71, 0x79, 0x6d, - 0x6e, 0x68, 0x5b, 0x64, 0x3f, 0x63, 0x39, 0x62, 0x39, 0x60, 0x3c, 0x5d, - 0x3c, 0x5d, 0x3d, 0x5d, 0x3c, 0x5c, 0x3b, 0x5e, 0x3b, 0x60, 0x3c, 0x5e, - 0x3e, 0x5d, 0x40, 0x5d, 0x41, 0x5a, 0x43, 0x5a, 0x45, 0x5b, 0x46, 0x5c, - 0x47, 0x5c, 0x47, 0x56, 0x46, 0x57, 0x45, 0x57, 0x43, 0x58, 0x41, 0x5a, - 0x40, 0x5b, 0x3e, 0x5a, 0x3e, 0x5b, 0x3f, 0x5c, 0x40, 0x5d, 0x3f, 0x5f, - 0x40, 0x5f, 0x41, 0x5f, 0x42, 0x60, 0x43, 0x5f, 0x43, 0x5f, 0x41, 0x5d, - 0x41, 0x5d, 0x3f, 0x60, 0x3e, 0x61, 0x3e, 0x61, 0x3e, 0x62, 0x3e, 0x61, - 0x3d, 0x60, 0x3e, 0x61, 0x3e, 0x63, 0x3f, 0x64, 0x3e, 0x64, 0x3e, 0x64, - 0x3e, 0x65, 0x40, 0x65, 0x42, 0x66, 0x47, 0x68, 0x4f, 0x6b, 0x55, 0x6b, - 0x57, 0x6c, 0x5a, 0x6d, 0x5a, 0x6e, 0x5a, 0x6e, 0x59, 0x6e, 0x5a, 0x70, - 0x5d, 0x71, 0x60, 0x74, 0x60, 0x75, 0x61, 0x74, 0x60, 0x74, 0x5f, 0x75, - 0x60, 0x76, 0x60, 0x76, 0x5f, 0x75, 0x60, 0x76, 0x62, 0x77, 0x62, 0x77, - 0x63, 0x77, 0x63, 0x78, 0x64, 0x78, 0x64, 0x79, 0x66, 0x7a, 0x67, 0x7a, - 0x68, 0x7a, 0x69, 0x7a, 0x68, 0x7b, 0x68, 0x7b, 0x68, 0x7b, 0x68, 0x7b, - 0x68, 0x7a, 0x64, 0x79, 0x62, 0x79, 0x61, 0x78, 0x5e, 0x77, 0x5f, 0x77, - 0x5f, 0x77, 0x60, 0x77, 0x60, 0x77, 0x5f, 0x77, 0x60, 0x78, 0x5f, 0x78, - 0x5e, 0x77, 0x5e, 0x77, 0x5e, 0x77, 0x5d, 0x77, 0x5d, 0x77, 0x5d, 0x77, - 0x5c, 0x77, 0x5a, 0x77, 0x5a, 0x76, 0x5a, 0x76, 0x57, 0x74, 0x55, 0x72, - 0x50, 0x73, 0x50, 0x73, 0x51, 0x74, 0x55, 0x75, 0x58, 0x75, 0x62, 0x75, - 0x6e, 0x72, 0x76, 0x72, 0x7a, 0x71, 0x7a, 0x71, 0x7a, 0x70, 0x7a, 0x71, - 0x7a, 0x73, 0x7b, 0x72, 0x7b, 0x72, 0x7d, 0x72, 0x7c, 0x71, 0x7c, 0x71, - 0x7d, 0x74, 0x7d, 0x74, 0x7c, 0x75, 0x7d, 0x75, 0x7d, 0x75, 0x7c, 0x79, - 0x7d, 0x7d, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, - 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x80, 0x72, 0x80, 0x72, 0x7f, 0x72, 0x7f, 0x72, 0x7f, 0x71, 0x7f, 0x70, - 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7e, 0x70, 0x7d, 0x70, - 0x7e, 0x70, 0x7e, 0x70, 0x7c, 0x70, 0x73, 0x6a, 0x62, 0x66, 0x4b, 0x64, - 0x39, 0x63, 0x37, 0x62, 0x38, 0x60, 0x3a, 0x5e, 0x3b, 0x5e, 0x3b, 0x5e, - 0x3b, 0x5d, 0x3b, 0x5f, 0x3b, 0x5f, 0x3c, 0x5e, 0x3e, 0x5c, 0x40, 0x5c, - 0x42, 0x5a, 0x44, 0x5a, 0x45, 0x5a, 0x46, 0x5a, 0x46, 0x5a, 0x46, 0x57, - 0x45, 0x58, 0x43, 0x58, 0x42, 0x59, 0x40, 0x5c, 0x3f, 0x5d, 0x3e, 0x5c, - 0x3e, 0x5d, 0x3f, 0x5d, 0x40, 0x5e, 0x40, 0x5f, 0x41, 0x5f, 0x42, 0x5f, - 0x42, 0x5f, 0x43, 0x5f, 0x42, 0x5f, 0x41, 0x5e, 0x41, 0x5d, 0x3f, 0x60, - 0x3e, 0x60, 0x3e, 0x61, 0x3e, 0x62, 0x3e, 0x61, 0x3d, 0x60, 0x3e, 0x61, - 0x3e, 0x63, 0x3e, 0x63, 0x3e, 0x63, 0x3e, 0x64, 0x3e, 0x65, 0x40, 0x65, - 0x42, 0x66, 0x47, 0x68, 0x4e, 0x6b, 0x54, 0x6b, 0x55, 0x6c, 0x57, 0x6d, - 0x58, 0x6e, 0x59, 0x6e, 0x5a, 0x6e, 0x5b, 0x70, 0x5e, 0x72, 0x5f, 0x73, - 0x60, 0x75, 0x61, 0x75, 0x60, 0x74, 0x60, 0x75, 0x61, 0x76, 0x60, 0x76, - 0x5f, 0x75, 0x5f, 0x76, 0x60, 0x77, 0x60, 0x77, 0x62, 0x77, 0x62, 0x78, - 0x63, 0x78, 0x63, 0x78, 0x64, 0x7a, 0x64, 0x7a, 0x66, 0x7a, 0x68, 0x7a, - 0x68, 0x7b, 0x68, 0x7b, 0x68, 0x7b, 0x68, 0x7b, 0x67, 0x7a, 0x65, 0x7a, - 0x62, 0x7a, 0x61, 0x78, 0x5e, 0x78, 0x5f, 0x77, 0x5f, 0x77, 0x60, 0x77, - 0x60, 0x77, 0x5f, 0x77, 0x60, 0x78, 0x5f, 0x78, 0x5e, 0x77, 0x5d, 0x77, - 0x5c, 0x78, 0x5c, 0x77, 0x5d, 0x77, 0x5d, 0x77, 0x5c, 0x77, 0x59, 0x77, - 0x59, 0x75, 0x58, 0x76, 0x56, 0x74, 0x55, 0x73, 0x52, 0x73, 0x52, 0x72, - 0x53, 0x74, 0x56, 0x75, 0x5a, 0x75, 0x64, 0x75, 0x70, 0x72, 0x78, 0x72, - 0x7b, 0x71, 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x72, 0x7a, 0x73, 0x7b, 0x72, - 0x7b, 0x72, 0x7c, 0x72, 0x7c, 0x72, 0x7d, 0x70, 0x7d, 0x73, 0x7d, 0x75, - 0x7c, 0x74, 0x7d, 0x75, 0x7d, 0x75, 0x7c, 0x79, 0x7d, 0x7d, 0x80, 0x7f, - 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x7f, - 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x72, 0x80, 0x72, - 0x7f, 0x72, 0x7f, 0x72, 0x7f, 0x71, 0x7f, 0x71, 0x7f, 0x70, 0x7f, 0x70, - 0x7f, 0x70, 0x7f, 0x70, 0x7e, 0x71, 0x7d, 0x70, 0x7e, 0x71, 0x7d, 0x70, - 0x79, 0x70, 0x6b, 0x68, 0x54, 0x62, 0x40, 0x63, 0x37, 0x63, 0x37, 0x62, - 0x37, 0x60, 0x39, 0x5f, 0x39, 0x5f, 0x39, 0x5e, 0x39, 0x5f, 0x3a, 0x5f, - 0x3b, 0x5f, 0x3c, 0x5e, 0x3e, 0x5c, 0x40, 0x5c, 0x43, 0x5a, 0x45, 0x5a, - 0x45, 0x59, 0x45, 0x58, 0x45, 0x58, 0x45, 0x58, 0x43, 0x5a, 0x42, 0x5a, - 0x41, 0x5a, 0x3f, 0x5d, 0x3e, 0x5e, 0x3e, 0x5d, 0x3e, 0x5e, 0x3f, 0x5e, - 0x41, 0x5f, 0x42, 0x5f, 0x43, 0x5f, 0x44, 0x60, 0x44, 0x5f, 0x43, 0x5f, - 0x43, 0x5f, 0x41, 0x5d, 0x40, 0x5d, 0x3f, 0x5f, 0x3e, 0x60, 0x3e, 0x61, - 0x3e, 0x62, 0x3e, 0x61, 0x3e, 0x60, 0x3e, 0x62, 0x3e, 0x63, 0x3e, 0x63, - 0x3e, 0x63, 0x3e, 0x63, 0x3e, 0x65, 0x40, 0x65, 0x43, 0x66, 0x47, 0x68, - 0x4c, 0x6b, 0x52, 0x6b, 0x54, 0x6c, 0x57, 0x6d, 0x57, 0x6e, 0x57, 0x6e, - 0x5a, 0x6e, 0x5c, 0x71, 0x5f, 0x72, 0x5f, 0x72, 0x60, 0x74, 0x60, 0x75, - 0x60, 0x74, 0x61, 0x74, 0x61, 0x76, 0x60, 0x76, 0x5f, 0x75, 0x5f, 0x75, - 0x5f, 0x77, 0x5f, 0x77, 0x60, 0x77, 0x60, 0x77, 0x61, 0x78, 0x63, 0x78, - 0x63, 0x7a, 0x63, 0x7a, 0x64, 0x7a, 0x66, 0x7a, 0x68, 0x7a, 0x68, 0x7b, - 0x68, 0x7b, 0x68, 0x7b, 0x68, 0x7a, 0x65, 0x7a, 0x63, 0x79, 0x61, 0x78, - 0x5f, 0x77, 0x5f, 0x77, 0x60, 0x77, 0x60, 0x77, 0x60, 0x77, 0x5f, 0x77, - 0x60, 0x78, 0x5f, 0x78, 0x5e, 0x77, 0x5c, 0x77, 0x5b, 0x78, 0x5c, 0x78, - 0x5d, 0x77, 0x5d, 0x77, 0x5c, 0x77, 0x59, 0x77, 0x57, 0x76, 0x57, 0x76, - 0x56, 0x74, 0x55, 0x73, 0x54, 0x73, 0x53, 0x73, 0x54, 0x74, 0x57, 0x75, - 0x5b, 0x75, 0x64, 0x74, 0x72, 0x72, 0x7a, 0x71, 0x7b, 0x71, 0x7b, 0x70, - 0x7a, 0x70, 0x7b, 0x72, 0x7b, 0x73, 0x7b, 0x72, 0x7b, 0x72, 0x7c, 0x72, - 0x7c, 0x72, 0x7c, 0x70, 0x7d, 0x73, 0x7c, 0x75, 0x7c, 0x74, 0x7e, 0x75, - 0x7e, 0x75, 0x7c, 0x79, 0x7e, 0x7c, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x70, 0x80, 0x71, 0x80, 0x71, 0x80, 0x71, - 0x7f, 0x72, 0x7f, 0x72, 0x7f, 0x71, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, - 0x7e, 0x71, 0x7e, 0x70, 0x7d, 0x70, 0x7b, 0x6f, 0x74, 0x6e, 0x5d, 0x65, - 0x44, 0x60, 0x39, 0x62, 0x36, 0x62, 0x36, 0x61, 0x37, 0x60, 0x38, 0x5e, - 0x38, 0x5d, 0x38, 0x5e, 0x38, 0x5f, 0x3a, 0x5f, 0x3b, 0x5d, 0x3d, 0x5d, - 0x3f, 0x5b, 0x41, 0x5a, 0x44, 0x5a, 0x45, 0x5a, 0x45, 0x5a, 0x45, 0x5a, - 0x45, 0x59, 0x44, 0x59, 0x43, 0x5a, 0x42, 0x5a, 0x40, 0x5b, 0x3f, 0x5e, - 0x3f, 0x5e, 0x3f, 0x5d, 0x3f, 0x5e, 0x41, 0x60, 0x42, 0x60, 0x43, 0x61, - 0x45, 0x61, 0x46, 0x62, 0x44, 0x61, 0x42, 0x60, 0x43, 0x60, 0x41, 0x5e, - 0x40, 0x5f, 0x3e, 0x61, 0x3e, 0x61, 0x3e, 0x62, 0x3e, 0x63, 0x3f, 0x63, - 0x3e, 0x63, 0x3e, 0x63, 0x3e, 0x63, 0x3e, 0x63, 0x3f, 0x63, 0x3e, 0x64, - 0x3f, 0x65, 0x40, 0x65, 0x44, 0x66, 0x49, 0x68, 0x4d, 0x6a, 0x53, 0x6b, - 0x55, 0x6c, 0x56, 0x6c, 0x55, 0x6d, 0x57, 0x6e, 0x5a, 0x6e, 0x5b, 0x70, - 0x5f, 0x72, 0x5f, 0x73, 0x5f, 0x75, 0x5f, 0x75, 0x5f, 0x75, 0x60, 0x75, - 0x5f, 0x75, 0x5e, 0x75, 0x5d, 0x75, 0x5e, 0x75, 0x60, 0x75, 0x5f, 0x75, - 0x5f, 0x77, 0x5f, 0x77, 0x60, 0x77, 0x62, 0x77, 0x62, 0x79, 0x64, 0x78, - 0x65, 0x79, 0x65, 0x7a, 0x66, 0x7a, 0x68, 0x7a, 0x68, 0x7a, 0x67, 0x7b, - 0x67, 0x7b, 0x66, 0x7a, 0x65, 0x78, 0x64, 0x78, 0x61, 0x78, 0x60, 0x78, - 0x60, 0x79, 0x60, 0x77, 0x60, 0x77, 0x60, 0x77, 0x60, 0x77, 0x5f, 0x78, - 0x5c, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5a, 0x77, 0x5a, 0x77, 0x58, 0x77, 0x57, 0x77, 0x56, 0x75, 0x56, 0x75, - 0x56, 0x75, 0x55, 0x74, 0x56, 0x73, 0x59, 0x73, 0x5c, 0x75, 0x67, 0x74, - 0x74, 0x71, 0x79, 0x70, 0x7b, 0x70, 0x7a, 0x70, 0x7b, 0x70, 0x7b, 0x70, - 0x7a, 0x71, 0x7b, 0x73, 0x7a, 0x73, 0x7b, 0x72, 0x7c, 0x72, 0x7d, 0x71, - 0x7c, 0x72, 0x7c, 0x73, 0x7d, 0x73, 0x7d, 0x74, 0x7e, 0x73, 0x7e, 0x75, - 0x7f, 0x7b, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, - 0x80, 0x70, 0x80, 0x70, 0x80, 0x70, 0x80, 0x70, 0x7f, 0x72, 0x7f, 0x72, - 0x7f, 0x71, 0x7f, 0x71, 0x7f, 0x70, 0x7f, 0x70, 0x7e, 0x70, 0x7d, 0x70, - 0x7d, 0x70, 0x79, 0x6e, 0x6f, 0x6b, 0x55, 0x63, 0x3e, 0x60, 0x37, 0x62, - 0x36, 0x62, 0x36, 0x61, 0x36, 0x60, 0x37, 0x5e, 0x37, 0x5e, 0x37, 0x5f, - 0x38, 0x5f, 0x3b, 0x5e, 0x3c, 0x5d, 0x3e, 0x5d, 0x40, 0x5b, 0x42, 0x5a, - 0x44, 0x5a, 0x45, 0x5a, 0x44, 0x5a, 0x44, 0x5a, 0x44, 0x5b, 0x43, 0x5b, - 0x42, 0x5a, 0x41, 0x5a, 0x40, 0x5b, 0x3f, 0x5e, 0x3f, 0x5f, 0x40, 0x5d, - 0x40, 0x5f, 0x43, 0x61, 0x44, 0x62, 0x45, 0x62, 0x46, 0x62, 0x46, 0x62, - 0x43, 0x62, 0x42, 0x60, 0x43, 0x60, 0x41, 0x5e, 0x40, 0x60, 0x3e, 0x62, - 0x3f, 0x61, 0x3e, 0x62, 0x3f, 0x64, 0x3f, 0x63, 0x3e, 0x63, 0x3d, 0x63, - 0x3d, 0x63, 0x3e, 0x63, 0x3f, 0x63, 0x3f, 0x64, 0x3f, 0x65, 0x41, 0x65, - 0x44, 0x66, 0x49, 0x68, 0x4d, 0x6a, 0x54, 0x6c, 0x56, 0x6d, 0x56, 0x6c, - 0x55, 0x6d, 0x57, 0x6e, 0x5a, 0x6f, 0x5b, 0x70, 0x5e, 0x72, 0x5f, 0x73, - 0x5f, 0x75, 0x5f, 0x75, 0x5f, 0x75, 0x5f, 0x75, 0x5f, 0x75, 0x5e, 0x75, - 0x5d, 0x75, 0x5e, 0x75, 0x5e, 0x74, 0x5e, 0x74, 0x5e, 0x76, 0x5e, 0x77, - 0x5f, 0x77, 0x60, 0x77, 0x61, 0x78, 0x63, 0x78, 0x64, 0x79, 0x64, 0x7a, - 0x64, 0x7a, 0x67, 0x79, 0x67, 0x7a, 0x67, 0x7b, 0x66, 0x7a, 0x66, 0x79, - 0x66, 0x78, 0x65, 0x78, 0x61, 0x78, 0x60, 0x78, 0x60, 0x78, 0x60, 0x77, - 0x60, 0x77, 0x60, 0x77, 0x60, 0x77, 0x5f, 0x77, 0x5d, 0x77, 0x5c, 0x77, - 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, - 0x59, 0x77, 0x57, 0x77, 0x56, 0x75, 0x56, 0x75, 0x56, 0x75, 0x56, 0x75, - 0x58, 0x73, 0x5a, 0x74, 0x5d, 0x76, 0x68, 0x73, 0x74, 0x70, 0x79, 0x70, - 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x72, 0x7b, 0x73, - 0x7b, 0x73, 0x7a, 0x72, 0x7b, 0x72, 0x7d, 0x72, 0x7c, 0x72, 0x7d, 0x73, - 0x7d, 0x73, 0x7e, 0x74, 0x7e, 0x72, 0x7d, 0x75, 0x7e, 0x7b, 0x80, 0x7f, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x70, 0x80, 0x70, - 0x80, 0x70, 0x80, 0x70, 0x7f, 0x71, 0x7f, 0x72, 0x7f, 0x71, 0x7f, 0x70, - 0x7f, 0x70, 0x7f, 0x70, 0x7e, 0x70, 0x7d, 0x71, 0x7c, 0x70, 0x73, 0x6c, - 0x65, 0x67, 0x48, 0x60, 0x3a, 0x60, 0x38, 0x62, 0x36, 0x62, 0x36, 0x61, - 0x36, 0x60, 0x35, 0x60, 0x36, 0x60, 0x37, 0x5f, 0x39, 0x5f, 0x3b, 0x5e, - 0x3d, 0x5e, 0x3f, 0x5d, 0x42, 0x5b, 0x44, 0x5a, 0x44, 0x5a, 0x44, 0x5a, - 0x44, 0x5a, 0x43, 0x5b, 0x42, 0x5c, 0x42, 0x5d, 0x42, 0x5b, 0x41, 0x5a, - 0x40, 0x5c, 0x3f, 0x5e, 0x40, 0x60, 0x42, 0x61, 0x42, 0x62, 0x45, 0x63, - 0x46, 0x63, 0x47, 0x64, 0x47, 0x63, 0x46, 0x62, 0x44, 0x62, 0x43, 0x60, - 0x43, 0x60, 0x41, 0x60, 0x3f, 0x62, 0x3f, 0x62, 0x3f, 0x62, 0x3e, 0x62, - 0x3e, 0x63, 0x3e, 0x63, 0x3e, 0x63, 0x3e, 0x62, 0x3e, 0x63, 0x3e, 0x63, - 0x3f, 0x64, 0x3e, 0x64, 0x3f, 0x65, 0x41, 0x65, 0x44, 0x66, 0x49, 0x68, - 0x4e, 0x6a, 0x54, 0x6c, 0x56, 0x6d, 0x56, 0x6c, 0x55, 0x6e, 0x57, 0x6e, - 0x5a, 0x6e, 0x5b, 0x70, 0x5e, 0x72, 0x5f, 0x72, 0x5f, 0x74, 0x5f, 0x75, - 0x5f, 0x75, 0x5f, 0x75, 0x5f, 0x75, 0x5e, 0x75, 0x5d, 0x75, 0x5d, 0x74, - 0x5d, 0x75, 0x5c, 0x75, 0x5d, 0x74, 0x5c, 0x75, 0x5c, 0x77, 0x5e, 0x77, - 0x5f, 0x78, 0x61, 0x78, 0x62, 0x7a, 0x62, 0x7a, 0x63, 0x79, 0x65, 0x79, - 0x66, 0x7a, 0x67, 0x7b, 0x67, 0x7a, 0x66, 0x7a, 0x65, 0x79, 0x63, 0x78, - 0x61, 0x78, 0x60, 0x78, 0x60, 0x78, 0x60, 0x77, 0x60, 0x77, 0x60, 0x77, - 0x60, 0x77, 0x5f, 0x77, 0x5d, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x59, 0x77, 0x57, 0x77, - 0x56, 0x76, 0x56, 0x75, 0x58, 0x76, 0x58, 0x76, 0x5a, 0x76, 0x5c, 0x76, - 0x5f, 0x76, 0x6b, 0x73, 0x75, 0x70, 0x79, 0x70, 0x7b, 0x70, 0x7a, 0x70, - 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x71, 0x7b, 0x73, 0x7b, 0x72, 0x7a, 0x72, - 0x7b, 0x72, 0x7c, 0x72, 0x7c, 0x72, 0x7c, 0x73, 0x7c, 0x73, 0x7e, 0x74, - 0x7d, 0x72, 0x7b, 0x75, 0x7c, 0x7a, 0x7f, 0x7e, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x70, 0x80, 0x70, 0x80, 0x70, 0x7f, 0x70, - 0x7f, 0x71, 0x7f, 0x71, 0x7f, 0x71, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, - 0x7f, 0x70, 0x7e, 0x70, 0x7c, 0x70, 0x6e, 0x6a, 0x5d, 0x64, 0x3e, 0x61, - 0x37, 0x61, 0x37, 0x62, 0x36, 0x62, 0x35, 0x61, 0x35, 0x61, 0x35, 0x61, - 0x36, 0x61, 0x38, 0x60, 0x3a, 0x5f, 0x3c, 0x5e, 0x3e, 0x5e, 0x40, 0x5c, - 0x43, 0x5b, 0x44, 0x5a, 0x43, 0x5b, 0x43, 0x5b, 0x43, 0x5c, 0x43, 0x5d, - 0x41, 0x5d, 0x41, 0x5e, 0x41, 0x5c, 0x41, 0x5d, 0x40, 0x5f, 0x40, 0x5f, - 0x41, 0x5f, 0x43, 0x61, 0x43, 0x63, 0x45, 0x64, 0x47, 0x64, 0x48, 0x66, - 0x48, 0x65, 0x46, 0x63, 0x44, 0x61, 0x43, 0x61, 0x43, 0x62, 0x40, 0x62, - 0x40, 0x62, 0x3f, 0x63, 0x40, 0x63, 0x3f, 0x63, 0x3e, 0x63, 0x3e, 0x64, - 0x3e, 0x65, 0x3e, 0x64, 0x3e, 0x64, 0x3e, 0x65, 0x3e, 0x65, 0x3e, 0x65, - 0x40, 0x65, 0x41, 0x65, 0x45, 0x68, 0x4a, 0x6a, 0x4e, 0x6b, 0x53, 0x6d, - 0x55, 0x6e, 0x56, 0x6d, 0x56, 0x6f, 0x57, 0x6f, 0x5a, 0x6f, 0x5b, 0x71, - 0x5e, 0x73, 0x5e, 0x72, 0x5f, 0x74, 0x5f, 0x75, 0x5f, 0x75, 0x5e, 0x75, - 0x5d, 0x75, 0x5d, 0x75, 0x5d, 0x75, 0x5c, 0x74, 0x5c, 0x73, 0x5c, 0x73, - 0x5b, 0x75, 0x5b, 0x75, 0x5c, 0x77, 0x5e, 0x77, 0x5e, 0x79, 0x60, 0x79, - 0x61, 0x78, 0x61, 0x78, 0x62, 0x78, 0x63, 0x78, 0x64, 0x79, 0x66, 0x7a, - 0x67, 0x7b, 0x65, 0x7b, 0x65, 0x7a, 0x63, 0x79, 0x62, 0x79, 0x60, 0x77, - 0x60, 0x78, 0x61, 0x77, 0x61, 0x77, 0x5f, 0x77, 0x60, 0x77, 0x5f, 0x77, - 0x5c, 0x77, 0x5b, 0x77, 0x5d, 0x78, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x5b, 0x77, 0x59, 0x77, 0x57, 0x77, 0x56, 0x76, 0x56, 0x75, - 0x57, 0x75, 0x58, 0x75, 0x5b, 0x76, 0x5d, 0x76, 0x63, 0x75, 0x6d, 0x72, - 0x77, 0x6f, 0x7a, 0x70, 0x7b, 0x6f, 0x7a, 0x6f, 0x7b, 0x70, 0x7b, 0x70, - 0x7a, 0x71, 0x7a, 0x73, 0x7b, 0x72, 0x7b, 0x72, 0x7b, 0x72, 0x7b, 0x72, - 0x7b, 0x72, 0x7b, 0x73, 0x7b, 0x72, 0x7d, 0x72, 0x7d, 0x72, 0x7b, 0x76, - 0x7c, 0x7b, 0x7f, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, - 0x80, 0x70, 0x80, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, - 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7e, 0x6f, - 0x7a, 0x6e, 0x6a, 0x68, 0x57, 0x63, 0x3b, 0x62, 0x36, 0x62, 0x37, 0x62, - 0x37, 0x62, 0x36, 0x63, 0x35, 0x62, 0x35, 0x61, 0x37, 0x60, 0x39, 0x61, - 0x3b, 0x5f, 0x3e, 0x5d, 0x40, 0x5c, 0x41, 0x5a, 0x43, 0x5a, 0x43, 0x5a, - 0x42, 0x5b, 0x42, 0x5b, 0x42, 0x5d, 0x41, 0x5d, 0x41, 0x5d, 0x41, 0x5d, - 0x41, 0x5c, 0x40, 0x5e, 0x40, 0x61, 0x40, 0x61, 0x41, 0x60, 0x43, 0x63, - 0x44, 0x65, 0x47, 0x66, 0x49, 0x66, 0x49, 0x66, 0x48, 0x66, 0x46, 0x64, - 0x44, 0x61, 0x44, 0x62, 0x43, 0x62, 0x40, 0x63, 0x40, 0x63, 0x40, 0x63, - 0x40, 0x63, 0x40, 0x63, 0x3f, 0x63, 0x3f, 0x64, 0x3e, 0x65, 0x3e, 0x65, - 0x3e, 0x65, 0x3d, 0x65, 0x3d, 0x66, 0x3d, 0x66, 0x40, 0x65, 0x42, 0x66, - 0x48, 0x69, 0x4d, 0x6b, 0x50, 0x6b, 0x53, 0x6e, 0x55, 0x6e, 0x56, 0x6e, - 0x55, 0x6f, 0x58, 0x6f, 0x5a, 0x6f, 0x5b, 0x71, 0x5e, 0x73, 0x5e, 0x73, - 0x5f, 0x74, 0x5f, 0x75, 0x5f, 0x75, 0x5e, 0x75, 0x5d, 0x75, 0x5d, 0x75, - 0x5c, 0x75, 0x5b, 0x74, 0x5b, 0x73, 0x5b, 0x72, 0x59, 0x74, 0x5a, 0x74, - 0x5c, 0x75, 0x5c, 0x75, 0x5d, 0x78, 0x5f, 0x78, 0x60, 0x77, 0x60, 0x77, - 0x61, 0x77, 0x61, 0x77, 0x62, 0x78, 0x64, 0x79, 0x66, 0x7a, 0x66, 0x7b, - 0x65, 0x7a, 0x65, 0x7a, 0x63, 0x79, 0x61, 0x78, 0x61, 0x78, 0x61, 0x78, - 0x60, 0x78, 0x5f, 0x76, 0x5f, 0x77, 0x5f, 0x77, 0x5b, 0x77, 0x5c, 0x77, - 0x5d, 0x77, 0x5c, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x59, 0x77, 0x57, 0x77, 0x55, 0x75, 0x55, 0x76, 0x55, 0x75, 0x57, 0x76, - 0x5b, 0x76, 0x5e, 0x75, 0x65, 0x74, 0x6f, 0x72, 0x78, 0x6f, 0x7a, 0x6f, - 0x7b, 0x6e, 0x7a, 0x6e, 0x7a, 0x70, 0x7b, 0x70, 0x7b, 0x71, 0x7a, 0x72, - 0x7b, 0x72, 0x7b, 0x72, 0x7b, 0x72, 0x7b, 0x72, 0x7b, 0x72, 0x7a, 0x72, - 0x7a, 0x72, 0x7c, 0x72, 0x7d, 0x72, 0x7b, 0x75, 0x7d, 0x7a, 0x7f, 0x7e, - 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x71, 0x80, 0x71, - 0x7f, 0x71, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, - 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x6f, 0x7e, 0x6f, 0x7a, 0x6e, 0x65, 0x66, - 0x50, 0x61, 0x39, 0x61, 0x36, 0x61, 0x37, 0x62, 0x37, 0x63, 0x36, 0x62, - 0x35, 0x62, 0x35, 0x60, 0x37, 0x60, 0x3a, 0x61, 0x3d, 0x5f, 0x40, 0x5c, - 0x42, 0x5a, 0x42, 0x58, 0x41, 0x5a, 0x41, 0x5a, 0x41, 0x5b, 0x41, 0x5b, - 0x41, 0x5d, 0x41, 0x5d, 0x41, 0x5d, 0x41, 0x5d, 0x41, 0x5c, 0x41, 0x5d, - 0x40, 0x62, 0x40, 0x63, 0x42, 0x63, 0x43, 0x67, 0x46, 0x68, 0x48, 0x68, - 0x4a, 0x68, 0x49, 0x66, 0x48, 0x66, 0x46, 0x64, 0x44, 0x62, 0x44, 0x63, - 0x43, 0x62, 0x41, 0x63, 0x40, 0x63, 0x40, 0x62, 0x40, 0x63, 0x40, 0x63, - 0x3f, 0x63, 0x3f, 0x64, 0x3f, 0x65, 0x3e, 0x65, 0x3d, 0x65, 0x3d, 0x65, - 0x3d, 0x65, 0x3d, 0x65, 0x40, 0x65, 0x42, 0x66, 0x4a, 0x69, 0x4e, 0x6a, - 0x52, 0x6b, 0x55, 0x6e, 0x56, 0x6e, 0x56, 0x6e, 0x55, 0x6f, 0x58, 0x6f, - 0x5a, 0x6f, 0x5b, 0x71, 0x5d, 0x74, 0x5e, 0x73, 0x5f, 0x74, 0x60, 0x75, - 0x5f, 0x75, 0x5f, 0x75, 0x5e, 0x74, 0x5e, 0x75, 0x5d, 0x75, 0x5b, 0x75, - 0x59, 0x73, 0x59, 0x73, 0x57, 0x72, 0x58, 0x71, 0x5a, 0x72, 0x5b, 0x73, - 0x5b, 0x76, 0x5d, 0x76, 0x5e, 0x77, 0x5d, 0x77, 0x5f, 0x77, 0x5f, 0x77, - 0x5f, 0x78, 0x62, 0x77, 0x65, 0x78, 0x66, 0x78, 0x65, 0x79, 0x65, 0x7a, - 0x64, 0x79, 0x63, 0x78, 0x63, 0x78, 0x60, 0x78, 0x60, 0x78, 0x60, 0x77, - 0x60, 0x77, 0x5f, 0x77, 0x5c, 0x77, 0x5c, 0x77, 0x5d, 0x77, 0x5b, 0x78, - 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x58, 0x77, 0x56, 0x77, - 0x55, 0x75, 0x55, 0x76, 0x56, 0x75, 0x59, 0x75, 0x5b, 0x75, 0x5e, 0x75, - 0x67, 0x74, 0x70, 0x72, 0x78, 0x6f, 0x7a, 0x6f, 0x7b, 0x6f, 0x7b, 0x6f, - 0x7b, 0x70, 0x7b, 0x70, 0x7a, 0x72, 0x7a, 0x73, 0x7a, 0x72, 0x7a, 0x72, - 0x7b, 0x72, 0x7b, 0x73, 0x7b, 0x72, 0x7b, 0x72, 0x7b, 0x72, 0x7d, 0x72, - 0x7d, 0x72, 0x7b, 0x74, 0x7c, 0x76, 0x7f, 0x7e, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, - 0x80, 0x70, 0x80, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, - 0x7f, 0x70, 0x7e, 0x6f, 0x78, 0x6d, 0x62, 0x64, 0x4b, 0x61, 0x38, 0x62, - 0x36, 0x62, 0x37, 0x61, 0x37, 0x62, 0x36, 0x62, 0x36, 0x62, 0x36, 0x61, - 0x38, 0x60, 0x3b, 0x60, 0x3e, 0x5e, 0x40, 0x5c, 0x42, 0x59, 0x42, 0x59, - 0x41, 0x5b, 0x41, 0x5a, 0x41, 0x5a, 0x41, 0x5a, 0x41, 0x5c, 0x41, 0x5c, - 0x41, 0x5c, 0x40, 0x5d, 0x40, 0x5d, 0x40, 0x5e, 0x40, 0x63, 0x41, 0x65, - 0x42, 0x66, 0x44, 0x68, 0x47, 0x69, 0x49, 0x6a, 0x4a, 0x69, 0x48, 0x66, - 0x47, 0x65, 0x45, 0x64, 0x44, 0x62, 0x44, 0x62, 0x43, 0x62, 0x41, 0x63, - 0x41, 0x62, 0x40, 0x63, 0x41, 0x64, 0x40, 0x63, 0x40, 0x63, 0x3f, 0x63, - 0x3e, 0x64, 0x3d, 0x65, 0x3d, 0x65, 0x3d, 0x65, 0x3d, 0x65, 0x3f, 0x66, - 0x40, 0x66, 0x43, 0x66, 0x4b, 0x69, 0x4f, 0x6b, 0x52, 0x6b, 0x56, 0x6e, - 0x57, 0x6f, 0x57, 0x6e, 0x56, 0x6f, 0x57, 0x6f, 0x5a, 0x70, 0x5b, 0x71, - 0x5d, 0x73, 0x5d, 0x73, 0x5e, 0x73, 0x5e, 0x74, 0x5f, 0x74, 0x5e, 0x74, - 0x5d, 0x74, 0x5e, 0x74, 0x5c, 0x74, 0x5a, 0x73, 0x58, 0x73, 0x57, 0x72, - 0x57, 0x71, 0x57, 0x72, 0x58, 0x72, 0x59, 0x72, 0x59, 0x74, 0x5c, 0x74, - 0x5d, 0x76, 0x5d, 0x76, 0x5e, 0x77, 0x60, 0x77, 0x5f, 0x76, 0x61, 0x76, - 0x64, 0x77, 0x65, 0x78, 0x66, 0x78, 0x65, 0x7a, 0x65, 0x79, 0x64, 0x79, - 0x63, 0x78, 0x60, 0x78, 0x61, 0x78, 0x5f, 0x77, 0x60, 0x77, 0x5f, 0x77, - 0x5c, 0x77, 0x5c, 0x77, 0x5c, 0x77, 0x5c, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x5b, 0x77, 0x59, 0x77, 0x58, 0x77, 0x56, 0x75, 0x56, 0x75, - 0x56, 0x75, 0x58, 0x75, 0x59, 0x76, 0x5f, 0x75, 0x68, 0x73, 0x71, 0x71, - 0x79, 0x6f, 0x7a, 0x6f, 0x7b, 0x6f, 0x7b, 0x6f, 0x7a, 0x70, 0x7b, 0x70, - 0x7b, 0x71, 0x7b, 0x72, 0x7b, 0x71, 0x7b, 0x72, 0x7b, 0x72, 0x7b, 0x72, - 0x7a, 0x71, 0x7b, 0x72, 0x7b, 0x72, 0x7d, 0x72, 0x7c, 0x71, 0x7b, 0x72, - 0x7d, 0x76, 0x7f, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7f, - 0x7d, 0x6f, 0x7d, 0x6f, 0x7f, 0x70, 0x7f, 0x70, 0x80, 0x70, 0x80, 0x70, - 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7e, 0x70, 0x7e, 0x6e, - 0x76, 0x6b, 0x5f, 0x63, 0x48, 0x63, 0x36, 0x64, 0x36, 0x62, 0x36, 0x60, - 0x36, 0x60, 0x37, 0x61, 0x37, 0x62, 0x37, 0x60, 0x39, 0x61, 0x3c, 0x5e, - 0x3e, 0x5d, 0x40, 0x5c, 0x41, 0x5b, 0x41, 0x5c, 0x40, 0x5d, 0x40, 0x5c, - 0x41, 0x5b, 0x41, 0x5b, 0x41, 0x5c, 0x41, 0x5c, 0x40, 0x5c, 0x40, 0x5f, - 0x40, 0x60, 0x40, 0x61, 0x40, 0x64, 0x42, 0x67, 0x44, 0x69, 0x46, 0x68, - 0x47, 0x69, 0x48, 0x6a, 0x48, 0x6a, 0x47, 0x68, 0x47, 0x65, 0x45, 0x65, - 0x44, 0x64, 0x44, 0x62, 0x43, 0x62, 0x42, 0x63, 0x42, 0x63, 0x41, 0x65, - 0x41, 0x66, 0x41, 0x64, 0x41, 0x63, 0x40, 0x63, 0x3e, 0x63, 0x3c, 0x65, - 0x3d, 0x66, 0x3d, 0x66, 0x3e, 0x66, 0x41, 0x66, 0x42, 0x67, 0x44, 0x68, - 0x4b, 0x69, 0x50, 0x6b, 0x53, 0x6c, 0x57, 0x6f, 0x58, 0x6f, 0x59, 0x6f, - 0x57, 0x6f, 0x58, 0x6f, 0x5a, 0x71, 0x5b, 0x72, 0x5c, 0x71, 0x5c, 0x71, - 0x5d, 0x72, 0x5d, 0x73, 0x5e, 0x73, 0x5d, 0x72, 0x5d, 0x73, 0x5d, 0x72, - 0x5b, 0x72, 0x5a, 0x72, 0x57, 0x72, 0x56, 0x72, 0x57, 0x72, 0x57, 0x73, - 0x57, 0x73, 0x56, 0x73, 0x57, 0x73, 0x5a, 0x73, 0x5c, 0x74, 0x5c, 0x74, - 0x5c, 0x75, 0x60, 0x76, 0x5f, 0x75, 0x61, 0x77, 0x62, 0x79, 0x64, 0x78, - 0x66, 0x79, 0x66, 0x7a, 0x66, 0x7a, 0x65, 0x7a, 0x63, 0x79, 0x60, 0x78, - 0x60, 0x78, 0x5f, 0x77, 0x60, 0x77, 0x5e, 0x77, 0x5d, 0x77, 0x5d, 0x77, - 0x5d, 0x77, 0x5d, 0x77, 0x5d, 0x77, 0x5c, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5a, 0x77, 0x5a, 0x77, 0x58, 0x75, 0x58, 0x75, 0x57, 0x74, 0x57, 0x74, - 0x59, 0x76, 0x61, 0x73, 0x69, 0x73, 0x73, 0x70, 0x7a, 0x6f, 0x7a, 0x6f, - 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x70, 0x7b, 0x70, - 0x7b, 0x70, 0x7b, 0x72, 0x7a, 0x71, 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x73, - 0x7a, 0x72, 0x7d, 0x71, 0x7d, 0x70, 0x7c, 0x70, 0x7e, 0x76, 0x7f, 0x7e, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7e, 0x6f, 0x7e, 0x6f, - 0x7f, 0x70, 0x7f, 0x70, 0x80, 0x70, 0x80, 0x70, 0x7f, 0x70, 0x7f, 0x70, - 0x7f, 0x70, 0x7f, 0x71, 0x7f, 0x70, 0x7d, 0x6e, 0x76, 0x6b, 0x5e, 0x63, - 0x46, 0x63, 0x36, 0x64, 0x36, 0x61, 0x36, 0x60, 0x36, 0x61, 0x37, 0x63, - 0x37, 0x62, 0x37, 0x61, 0x3a, 0x60, 0x3d, 0x5e, 0x3e, 0x5d, 0x3f, 0x5d, - 0x3f, 0x5d, 0x40, 0x5d, 0x40, 0x5e, 0x41, 0x5e, 0x41, 0x5e, 0x41, 0x5d, - 0x41, 0x5e, 0x41, 0x5d, 0x41, 0x5e, 0x40, 0x61, 0x40, 0x64, 0x40, 0x65, - 0x41, 0x66, 0x43, 0x68, 0x47, 0x6b, 0x48, 0x6b, 0x48, 0x6a, 0x48, 0x6a, - 0x48, 0x6a, 0x46, 0x67, 0x46, 0x65, 0x44, 0x65, 0x44, 0x64, 0x43, 0x64, - 0x43, 0x63, 0x42, 0x66, 0x41, 0x65, 0x41, 0x64, 0x40, 0x65, 0x40, 0x63, - 0x41, 0x63, 0x40, 0x62, 0x3e, 0x63, 0x3d, 0x65, 0x3d, 0x66, 0x3d, 0x66, - 0x3e, 0x65, 0x41, 0x65, 0x44, 0x67, 0x46, 0x68, 0x4d, 0x69, 0x52, 0x6b, - 0x55, 0x6c, 0x58, 0x6f, 0x5a, 0x6f, 0x5b, 0x6f, 0x59, 0x6e, 0x59, 0x6f, - 0x5b, 0x72, 0x5c, 0x73, 0x5d, 0x72, 0x5d, 0x72, 0x5d, 0x72, 0x5e, 0x73, - 0x5e, 0x73, 0x5e, 0x73, 0x5d, 0x73, 0x5d, 0x72, 0x5b, 0x72, 0x5a, 0x72, - 0x57, 0x72, 0x55, 0x72, 0x56, 0x72, 0x55, 0x72, 0x55, 0x73, 0x55, 0x73, - 0x56, 0x73, 0x59, 0x73, 0x5b, 0x75, 0x5a, 0x75, 0x5b, 0x75, 0x5e, 0x76, - 0x5f, 0x75, 0x60, 0x77, 0x62, 0x79, 0x64, 0x78, 0x66, 0x79, 0x66, 0x7a, - 0x66, 0x7a, 0x65, 0x7a, 0x62, 0x79, 0x60, 0x78, 0x61, 0x78, 0x5f, 0x77, - 0x5f, 0x78, 0x5e, 0x77, 0x5d, 0x77, 0x5d, 0x77, 0x5d, 0x77, 0x5d, 0x77, - 0x5d, 0x77, 0x5c, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x77, 0x59, 0x77, - 0x57, 0x75, 0x57, 0x75, 0x57, 0x75, 0x58, 0x74, 0x5a, 0x76, 0x62, 0x73, - 0x6a, 0x73, 0x74, 0x71, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x70, - 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x70, 0x7a, 0x71, 0x7b, 0x71, 0x7b, 0x73, - 0x7a, 0x71, 0x7a, 0x70, 0x7a, 0x71, 0x7a, 0x73, 0x7a, 0x72, 0x7c, 0x6f, - 0x7c, 0x70, 0x7c, 0x71, 0x7d, 0x75, 0x7f, 0x7e, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x7f, 0x80, 0x7f, 0x7d, 0x6f, 0x7d, 0x6f, 0x7f, 0x70, 0x7f, 0x70, - 0x80, 0x70, 0x80, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x6f, - 0x7e, 0x70, 0x7e, 0x6f, 0x73, 0x6b, 0x5b, 0x64, 0x45, 0x63, 0x35, 0x63, - 0x36, 0x61, 0x36, 0x60, 0x37, 0x60, 0x37, 0x61, 0x37, 0x61, 0x38, 0x60, - 0x3a, 0x60, 0x3c, 0x5e, 0x3e, 0x5d, 0x3e, 0x5e, 0x3e, 0x5e, 0x3f, 0x5e, - 0x40, 0x5f, 0x40, 0x5e, 0x41, 0x5f, 0x41, 0x5e, 0x41, 0x60, 0x41, 0x5f, - 0x40, 0x60, 0x40, 0x62, 0x40, 0x65, 0x40, 0x67, 0x43, 0x67, 0x46, 0x69, - 0x4a, 0x6b, 0x4c, 0x6c, 0x4a, 0x6a, 0x47, 0x6a, 0x46, 0x69, 0x45, 0x67, - 0x45, 0x65, 0x44, 0x64, 0x43, 0x65, 0x43, 0x65, 0x43, 0x65, 0x42, 0x67, - 0x42, 0x66, 0x41, 0x64, 0x41, 0x65, 0x40, 0x63, 0x40, 0x63, 0x3f, 0x62, - 0x3d, 0x64, 0x3c, 0x65, 0x3c, 0x66, 0x3d, 0x66, 0x3e, 0x66, 0x42, 0x66, - 0x45, 0x67, 0x47, 0x67, 0x4e, 0x6a, 0x53, 0x6b, 0x56, 0x6e, 0x5a, 0x6f, - 0x5c, 0x70, 0x5b, 0x6f, 0x5b, 0x6f, 0x5b, 0x6f, 0x5b, 0x71, 0x5b, 0x72, - 0x5c, 0x72, 0x5d, 0x73, 0x5d, 0x73, 0x5e, 0x73, 0x5e, 0x73, 0x5d, 0x73, - 0x5c, 0x73, 0x5c, 0x73, 0x5a, 0x72, 0x59, 0x72, 0x57, 0x72, 0x55, 0x72, - 0x54, 0x72, 0x54, 0x72, 0x53, 0x72, 0x54, 0x73, 0x56, 0x73, 0x58, 0x73, - 0x59, 0x74, 0x59, 0x74, 0x5a, 0x74, 0x5c, 0x74, 0x5e, 0x75, 0x60, 0x77, - 0x61, 0x78, 0x63, 0x78, 0x66, 0x79, 0x65, 0x7b, 0x65, 0x7a, 0x65, 0x7a, - 0x63, 0x7a, 0x61, 0x78, 0x61, 0x78, 0x5f, 0x78, 0x60, 0x78, 0x5f, 0x77, - 0x5d, 0x77, 0x5c, 0x77, 0x5d, 0x77, 0x5c, 0x77, 0x5c, 0x77, 0x5c, 0x77, - 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x77, 0x59, 0x76, 0x58, 0x75, 0x58, 0x75, - 0x57, 0x75, 0x57, 0x75, 0x5b, 0x75, 0x64, 0x74, 0x6c, 0x72, 0x75, 0x70, - 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, - 0x7a, 0x6f, 0x7a, 0x71, 0x7a, 0x71, 0x7b, 0x71, 0x7a, 0x71, 0x7a, 0x70, - 0x7a, 0x70, 0x7a, 0x72, 0x7a, 0x72, 0x7d, 0x6f, 0x7d, 0x71, 0x7c, 0x72, - 0x7d, 0x75, 0x7f, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, - 0x7b, 0x70, 0x7c, 0x70, 0x7d, 0x70, 0x7e, 0x6f, 0x7e, 0x70, 0x7e, 0x70, - 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x6f, 0x7e, 0x6f, 0x7c, 0x6e, - 0x6f, 0x6b, 0x58, 0x65, 0x43, 0x63, 0x35, 0x62, 0x35, 0x60, 0x36, 0x60, - 0x37, 0x60, 0x38, 0x60, 0x39, 0x60, 0x39, 0x60, 0x3a, 0x5f, 0x3b, 0x5f, - 0x3c, 0x5f, 0x3d, 0x5f, 0x3d, 0x5f, 0x3e, 0x5f, 0x3f, 0x5f, 0x40, 0x5f, - 0x41, 0x5f, 0x41, 0x5f, 0x40, 0x61, 0x40, 0x62, 0x3f, 0x63, 0x3e, 0x65, - 0x41, 0x65, 0x43, 0x67, 0x47, 0x69, 0x4b, 0x6a, 0x4e, 0x6c, 0x4e, 0x6b, - 0x4c, 0x6a, 0x46, 0x6a, 0x43, 0x6a, 0x44, 0x67, 0x44, 0x65, 0x44, 0x65, - 0x42, 0x65, 0x42, 0x65, 0x42, 0x66, 0x41, 0x66, 0x41, 0x66, 0x41, 0x65, - 0x41, 0x65, 0x42, 0x64, 0x3f, 0x63, 0x3f, 0x62, 0x3d, 0x65, 0x3b, 0x66, - 0x3b, 0x65, 0x3d, 0x66, 0x3f, 0x68, 0x41, 0x67, 0x46, 0x66, 0x48, 0x67, - 0x4f, 0x6b, 0x53, 0x6e, 0x58, 0x70, 0x5c, 0x70, 0x5e, 0x70, 0x5b, 0x70, - 0x5b, 0x71, 0x5b, 0x71, 0x5b, 0x71, 0x5b, 0x70, 0x5c, 0x72, 0x5d, 0x73, - 0x5d, 0x73, 0x5d, 0x73, 0x5d, 0x73, 0x5c, 0x73, 0x5b, 0x72, 0x5b, 0x72, - 0x59, 0x72, 0x58, 0x72, 0x56, 0x72, 0x53, 0x72, 0x53, 0x72, 0x53, 0x72, - 0x53, 0x72, 0x53, 0x72, 0x55, 0x73, 0x56, 0x73, 0x55, 0x73, 0x57, 0x73, - 0x59, 0x72, 0x5b, 0x72, 0x5c, 0x72, 0x5e, 0x76, 0x5f, 0x77, 0x62, 0x78, - 0x64, 0x7b, 0x65, 0x7b, 0x64, 0x7b, 0x64, 0x7a, 0x65, 0x7a, 0x63, 0x77, - 0x60, 0x78, 0x5f, 0x79, 0x60, 0x79, 0x5f, 0x78, 0x5c, 0x77, 0x5d, 0x77, - 0x5d, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5c, 0x78, 0x5c, 0x77, - 0x5a, 0x77, 0x5a, 0x76, 0x58, 0x76, 0x58, 0x76, 0x57, 0x75, 0x57, 0x75, - 0x5c, 0x75, 0x66, 0x74, 0x6e, 0x70, 0x75, 0x70, 0x7a, 0x6f, 0x7a, 0x70, - 0x7a, 0x6e, 0x7a, 0x6e, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x71, - 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x71, - 0x7a, 0x70, 0x7d, 0x6f, 0x7d, 0x71, 0x7d, 0x71, 0x7c, 0x74, 0x7e, 0x7d, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x7f, 0x7f, 0x7a, 0x6f, 0x7a, 0x6f, - 0x7b, 0x6f, 0x7c, 0x6f, 0x7e, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, - 0x7e, 0x70, 0x7d, 0x6f, 0x7d, 0x6f, 0x7b, 0x6c, 0x6e, 0x69, 0x57, 0x65, - 0x41, 0x63, 0x35, 0x62, 0x35, 0x60, 0x36, 0x60, 0x37, 0x61, 0x38, 0x60, - 0x39, 0x60, 0x39, 0x61, 0x3a, 0x60, 0x3a, 0x61, 0x3b, 0x61, 0x3c, 0x60, - 0x3d, 0x60, 0x3e, 0x60, 0x3f, 0x60, 0x3f, 0x60, 0x41, 0x60, 0x40, 0x60, - 0x40, 0x62, 0x3f, 0x63, 0x3e, 0x64, 0x3f, 0x66, 0x45, 0x67, 0x47, 0x69, - 0x4b, 0x69, 0x4d, 0x6c, 0x50, 0x6d, 0x4f, 0x6d, 0x4d, 0x6b, 0x47, 0x6a, - 0x44, 0x6a, 0x44, 0x67, 0x44, 0x65, 0x44, 0x65, 0x43, 0x65, 0x43, 0x65, - 0x42, 0x65, 0x41, 0x66, 0x41, 0x66, 0x41, 0x65, 0x41, 0x65, 0x42, 0x64, - 0x3f, 0x63, 0x3f, 0x62, 0x3d, 0x64, 0x3b, 0x66, 0x3d, 0x65, 0x3f, 0x67, - 0x40, 0x68, 0x43, 0x68, 0x47, 0x68, 0x49, 0x68, 0x50, 0x6b, 0x55, 0x6e, - 0x58, 0x70, 0x5c, 0x70, 0x5e, 0x70, 0x5b, 0x70, 0x5b, 0x70, 0x5c, 0x70, - 0x5b, 0x70, 0x5b, 0x70, 0x5c, 0x72, 0x5d, 0x73, 0x5d, 0x73, 0x5d, 0x73, - 0x5d, 0x73, 0x5c, 0x73, 0x5b, 0x72, 0x5b, 0x72, 0x59, 0x72, 0x58, 0x72, - 0x56, 0x72, 0x53, 0x72, 0x53, 0x72, 0x53, 0x72, 0x53, 0x72, 0x53, 0x72, - 0x54, 0x73, 0x55, 0x73, 0x54, 0x73, 0x56, 0x73, 0x58, 0x73, 0x5b, 0x72, - 0x5c, 0x72, 0x5e, 0x76, 0x5f, 0x76, 0x62, 0x78, 0x64, 0x7b, 0x65, 0x7b, - 0x64, 0x7b, 0x65, 0x7a, 0x65, 0x7a, 0x63, 0x77, 0x60, 0x77, 0x5f, 0x78, - 0x60, 0x78, 0x60, 0x77, 0x5c, 0x77, 0x5c, 0x77, 0x5d, 0x77, 0x5c, 0x77, - 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x77, 0x5a, 0x77, - 0x59, 0x75, 0x58, 0x75, 0x59, 0x75, 0x58, 0x75, 0x5e, 0x74, 0x67, 0x74, - 0x6f, 0x71, 0x77, 0x70, 0x7a, 0x70, 0x7a, 0x6f, 0x7a, 0x6e, 0x7a, 0x6e, - 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, - 0x7b, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x70, 0x7b, 0x70, 0x7c, 0x6f, - 0x7d, 0x71, 0x7d, 0x71, 0x7c, 0x74, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, - 0x80, 0x80, 0x7f, 0x80, 0x79, 0x6f, 0x79, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, - 0x7d, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7d, 0x70, 0x7c, 0x6f, - 0x7b, 0x6e, 0x79, 0x6b, 0x6c, 0x68, 0x54, 0x65, 0x40, 0x63, 0x35, 0x62, - 0x35, 0x60, 0x36, 0x60, 0x38, 0x60, 0x39, 0x5f, 0x38, 0x60, 0x39, 0x62, - 0x39, 0x62, 0x3a, 0x61, 0x3a, 0x62, 0x3c, 0x62, 0x3d, 0x62, 0x3e, 0x63, - 0x3f, 0x62, 0x3f, 0x62, 0x40, 0x62, 0x40, 0x62, 0x3f, 0x64, 0x3e, 0x65, - 0x40, 0x66, 0x46, 0x68, 0x4b, 0x69, 0x4d, 0x6b, 0x4f, 0x6c, 0x51, 0x6d, - 0x52, 0x6e, 0x51, 0x6e, 0x4e, 0x6c, 0x49, 0x6a, 0x44, 0x6a, 0x43, 0x67, - 0x43, 0x65, 0x43, 0x65, 0x43, 0x65, 0x43, 0x66, 0x42, 0x65, 0x42, 0x65, - 0x41, 0x65, 0x42, 0x64, 0x41, 0x64, 0x41, 0x63, 0x3f, 0x63, 0x3f, 0x62, - 0x3d, 0x64, 0x3b, 0x66, 0x3e, 0x65, 0x41, 0x66, 0x43, 0x67, 0x46, 0x69, - 0x49, 0x6a, 0x4b, 0x6a, 0x52, 0x6b, 0x57, 0x6e, 0x59, 0x71, 0x5c, 0x71, - 0x5d, 0x70, 0x5b, 0x70, 0x5b, 0x71, 0x5b, 0x71, 0x5b, 0x71, 0x5c, 0x71, - 0x5c, 0x72, 0x5c, 0x73, 0x5d, 0x73, 0x5d, 0x73, 0x5d, 0x73, 0x5c, 0x73, - 0x5b, 0x73, 0x5b, 0x73, 0x59, 0x72, 0x58, 0x72, 0x57, 0x72, 0x54, 0x72, - 0x53, 0x72, 0x53, 0x72, 0x53, 0x72, 0x52, 0x72, 0x53, 0x72, 0x53, 0x72, - 0x53, 0x73, 0x54, 0x73, 0x57, 0x73, 0x5b, 0x72, 0x5b, 0x73, 0x5e, 0x75, - 0x5f, 0x76, 0x61, 0x77, 0x64, 0x7a, 0x64, 0x7b, 0x65, 0x7b, 0x64, 0x7a, - 0x64, 0x7a, 0x63, 0x78, 0x61, 0x78, 0x5f, 0x77, 0x60, 0x78, 0x60, 0x78, - 0x5d, 0x77, 0x5c, 0x77, 0x5d, 0x77, 0x5c, 0x78, 0x5b, 0x77, 0x5a, 0x77, - 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x58, 0x76, 0x58, 0x76, - 0x59, 0x75, 0x5b, 0x75, 0x60, 0x74, 0x6a, 0x73, 0x72, 0x70, 0x78, 0x70, - 0x79, 0x6f, 0x79, 0x6f, 0x7a, 0x6e, 0x7a, 0x6e, 0x7a, 0x6f, 0x7a, 0x6f, - 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x70, 0x7b, 0x71, - 0x7b, 0x71, 0x7b, 0x71, 0x7b, 0x71, 0x7c, 0x6f, 0x7c, 0x71, 0x7c, 0x70, - 0x7c, 0x74, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, - 0x78, 0x6f, 0x79, 0x6f, 0x79, 0x6f, 0x7c, 0x6f, 0x7e, 0x6f, 0x7e, 0x6f, - 0x7f, 0x6f, 0x7e, 0x6f, 0x7c, 0x70, 0x7b, 0x6f, 0x78, 0x6d, 0x76, 0x6b, - 0x69, 0x66, 0x52, 0x63, 0x3f, 0x63, 0x35, 0x62, 0x35, 0x60, 0x36, 0x60, - 0x38, 0x60, 0x38, 0x5f, 0x39, 0x60, 0x39, 0x63, 0x39, 0x62, 0x39, 0x63, - 0x3a, 0x64, 0x3a, 0x65, 0x3b, 0x65, 0x3d, 0x65, 0x3e, 0x64, 0x3e, 0x64, - 0x3f, 0x64, 0x3f, 0x64, 0x3d, 0x65, 0x3f, 0x68, 0x44, 0x68, 0x4c, 0x6a, - 0x50, 0x6c, 0x50, 0x6c, 0x51, 0x6d, 0x52, 0x6d, 0x53, 0x6e, 0x51, 0x6e, - 0x4f, 0x6d, 0x4a, 0x6b, 0x45, 0x69, 0x42, 0x68, 0x42, 0x67, 0x42, 0x66, - 0x42, 0x67, 0x41, 0x67, 0x41, 0x68, 0x42, 0x66, 0x42, 0x64, 0x42, 0x64, - 0x41, 0x62, 0x40, 0x62, 0x3f, 0x62, 0x3e, 0x62, 0x3c, 0x65, 0x3b, 0x66, - 0x3e, 0x66, 0x43, 0x65, 0x46, 0x67, 0x47, 0x69, 0x49, 0x6b, 0x4d, 0x6b, - 0x51, 0x6b, 0x56, 0x6e, 0x5a, 0x72, 0x5c, 0x72, 0x5c, 0x72, 0x5b, 0x72, - 0x5a, 0x70, 0x59, 0x70, 0x5b, 0x71, 0x5c, 0x72, 0x5b, 0x72, 0x5b, 0x72, - 0x5b, 0x72, 0x5b, 0x72, 0x5b, 0x71, 0x5b, 0x73, 0x5b, 0x73, 0x5c, 0x72, - 0x59, 0x71, 0x58, 0x72, 0x57, 0x72, 0x54, 0x72, 0x53, 0x72, 0x53, 0x72, - 0x53, 0x72, 0x51, 0x72, 0x52, 0x72, 0x53, 0x72, 0x52, 0x72, 0x54, 0x72, - 0x57, 0x73, 0x59, 0x72, 0x5c, 0x74, 0x5e, 0x75, 0x5f, 0x77, 0x60, 0x78, - 0x63, 0x78, 0x64, 0x7a, 0x64, 0x7a, 0x63, 0x7a, 0x63, 0x7a, 0x62, 0x7a, - 0x62, 0x7a, 0x60, 0x77, 0x60, 0x78, 0x60, 0x78, 0x60, 0x78, 0x5e, 0x78, - 0x5d, 0x77, 0x5b, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, - 0x5a, 0x77, 0x59, 0x77, 0x58, 0x77, 0x58, 0x77, 0x5a, 0x76, 0x5e, 0x75, - 0x64, 0x75, 0x6d, 0x71, 0x75, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, - 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, - 0x7a, 0x70, 0x7a, 0x72, 0x7a, 0x72, 0x7b, 0x72, 0x7b, 0x73, 0x7b, 0x73, - 0x7b, 0x72, 0x7b, 0x71, 0x7b, 0x70, 0x7c, 0x70, 0x7c, 0x74, 0x7e, 0x7c, - 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, - 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x77, 0x6f, 0x77, 0x6f, - 0x78, 0x6f, 0x7b, 0x6f, 0x7c, 0x6f, 0x7c, 0x6f, 0x7d, 0x6e, 0x7b, 0x6e, - 0x79, 0x6e, 0x78, 0x6d, 0x76, 0x6b, 0x74, 0x6a, 0x67, 0x65, 0x50, 0x63, - 0x3e, 0x63, 0x36, 0x63, 0x36, 0x60, 0x37, 0x60, 0x38, 0x60, 0x38, 0x60, - 0x39, 0x62, 0x39, 0x64, 0x38, 0x64, 0x38, 0x65, 0x38, 0x66, 0x39, 0x66, - 0x39, 0x67, 0x3b, 0x67, 0x3d, 0x65, 0x3d, 0x65, 0x3d, 0x65, 0x3d, 0x65, - 0x3e, 0x67, 0x44, 0x69, 0x4b, 0x6a, 0x50, 0x6c, 0x53, 0x6d, 0x53, 0x6d, - 0x53, 0x6e, 0x53, 0x6f, 0x53, 0x6e, 0x51, 0x6e, 0x4f, 0x6d, 0x4a, 0x6b, - 0x46, 0x69, 0x42, 0x68, 0x41, 0x68, 0x42, 0x68, 0x41, 0x68, 0x41, 0x67, - 0x41, 0x68, 0x42, 0x67, 0x42, 0x65, 0x42, 0x64, 0x41, 0x62, 0x40, 0x61, - 0x3f, 0x62, 0x3e, 0x62, 0x3c, 0x64, 0x3c, 0x66, 0x3f, 0x66, 0x44, 0x66, - 0x45, 0x67, 0x47, 0x69, 0x4a, 0x6a, 0x4e, 0x6c, 0x52, 0x6c, 0x57, 0x6f, - 0x5a, 0x72, 0x5c, 0x72, 0x5b, 0x72, 0x5b, 0x72, 0x5a, 0x70, 0x5a, 0x70, - 0x5b, 0x72, 0x5c, 0x73, 0x5b, 0x72, 0x5b, 0x72, 0x5b, 0x72, 0x5b, 0x72, - 0x5b, 0x72, 0x5b, 0x72, 0x5b, 0x73, 0x5c, 0x72, 0x5a, 0x72, 0x57, 0x72, - 0x56, 0x72, 0x54, 0x72, 0x53, 0x72, 0x53, 0x72, 0x53, 0x72, 0x51, 0x72, - 0x51, 0x72, 0x50, 0x72, 0x50, 0x72, 0x52, 0x72, 0x55, 0x72, 0x58, 0x72, - 0x5a, 0x74, 0x5d, 0x75, 0x5f, 0x77, 0x60, 0x78, 0x63, 0x79, 0x64, 0x7a, - 0x63, 0x7a, 0x63, 0x7a, 0x63, 0x7a, 0x62, 0x79, 0x62, 0x7a, 0x60, 0x77, - 0x60, 0x78, 0x60, 0x78, 0x60, 0x78, 0x5e, 0x77, 0x5c, 0x77, 0x5b, 0x77, - 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5b, 0x77, 0x5a, 0x77, - 0x59, 0x77, 0x59, 0x77, 0x5d, 0x75, 0x62, 0x75, 0x67, 0x75, 0x70, 0x72, - 0x75, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x79, 0x6f, 0x7a, 0x6f, - 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x70, 0x7a, 0x72, - 0x7a, 0x72, 0x7a, 0x72, 0x7b, 0x73, 0x7b, 0x73, 0x7b, 0x72, 0x7a, 0x71, - 0x7b, 0x70, 0x7c, 0x70, 0x7c, 0x74, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x80, 0x80, 0x80, 0x80, 0x75, 0x6f, 0x75, 0x6f, 0x76, 0x6f, 0x79, 0x6f, - 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6d, 0x78, 0x6c, 0x75, 0x6c, 0x74, 0x6b, - 0x71, 0x69, 0x6f, 0x67, 0x63, 0x64, 0x4e, 0x63, 0x3d, 0x63, 0x36, 0x62, - 0x36, 0x60, 0x37, 0x60, 0x38, 0x60, 0x38, 0x61, 0x39, 0x64, 0x38, 0x66, - 0x39, 0x66, 0x37, 0x66, 0x37, 0x67, 0x38, 0x68, 0x38, 0x69, 0x3a, 0x69, - 0x3b, 0x66, 0x3c, 0x67, 0x3c, 0x67, 0x3c, 0x67, 0x40, 0x69, 0x4a, 0x6b, - 0x52, 0x6c, 0x54, 0x6e, 0x57, 0x6f, 0x57, 0x6f, 0x55, 0x70, 0x55, 0x70, - 0x54, 0x6f, 0x52, 0x6e, 0x4f, 0x6d, 0x4a, 0x6b, 0x46, 0x69, 0x43, 0x68, - 0x41, 0x69, 0x40, 0x6a, 0x41, 0x6a, 0x41, 0x67, 0x40, 0x68, 0x42, 0x68, - 0x42, 0x65, 0x41, 0x64, 0x41, 0x63, 0x3f, 0x62, 0x3e, 0x62, 0x3d, 0x62, - 0x3c, 0x64, 0x3c, 0x66, 0x42, 0x66, 0x45, 0x66, 0x45, 0x68, 0x47, 0x69, - 0x4c, 0x6a, 0x50, 0x6c, 0x55, 0x6e, 0x59, 0x71, 0x5a, 0x72, 0x5c, 0x72, - 0x5b, 0x72, 0x5b, 0x72, 0x5a, 0x70, 0x5a, 0x70, 0x5b, 0x72, 0x5b, 0x72, - 0x5b, 0x72, 0x5b, 0x72, 0x5b, 0x72, 0x5b, 0x72, 0x5b, 0x72, 0x5c, 0x72, - 0x5c, 0x73, 0x5c, 0x72, 0x5a, 0x72, 0x57, 0x72, 0x56, 0x72, 0x54, 0x71, - 0x53, 0x72, 0x53, 0x72, 0x54, 0x72, 0x51, 0x72, 0x4f, 0x72, 0x4f, 0x72, - 0x4f, 0x72, 0x51, 0x72, 0x53, 0x72, 0x56, 0x72, 0x58, 0x74, 0x5b, 0x75, - 0x5f, 0x76, 0x61, 0x78, 0x63, 0x79, 0x64, 0x7a, 0x63, 0x7a, 0x63, 0x7a, - 0x63, 0x7a, 0x62, 0x79, 0x62, 0x7a, 0x60, 0x78, 0x60, 0x78, 0x60, 0x78, - 0x5f, 0x78, 0x5e, 0x78, 0x5c, 0x77, 0x5b, 0x77, 0x5a, 0x77, 0x5a, 0x77, - 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5b, 0x77, 0x5c, 0x77, - 0x61, 0x76, 0x66, 0x76, 0x6b, 0x75, 0x73, 0x72, 0x76, 0x6f, 0x78, 0x6f, - 0x79, 0x6e, 0x78, 0x6f, 0x79, 0x6f, 0x7a, 0x6f, 0x7a, 0x70, 0x7a, 0x6f, - 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x70, 0x7a, 0x72, 0x7a, 0x72, 0x7a, 0x72, - 0x7b, 0x72, 0x7a, 0x72, 0x7a, 0x73, 0x7b, 0x71, 0x7b, 0x70, 0x7c, 0x70, - 0x7c, 0x73, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x74, 0x6e, 0x73, 0x6e, 0x75, 0x6f, 0x77, 0x6f, 0x79, 0x6f, 0x78, 0x6f, - 0x77, 0x6d, 0x75, 0x6b, 0x73, 0x6a, 0x71, 0x6a, 0x6e, 0x67, 0x6c, 0x66, - 0x61, 0x63, 0x4a, 0x62, 0x3c, 0x61, 0x36, 0x62, 0x35, 0x63, 0x36, 0x61, - 0x37, 0x61, 0x38, 0x63, 0x39, 0x65, 0x38, 0x64, 0x37, 0x66, 0x37, 0x68, - 0x36, 0x69, 0x37, 0x69, 0x38, 0x69, 0x39, 0x69, 0x3a, 0x68, 0x3a, 0x69, - 0x3c, 0x69, 0x3f, 0x68, 0x45, 0x6a, 0x4d, 0x6d, 0x53, 0x6e, 0x55, 0x6f, - 0x57, 0x70, 0x58, 0x70, 0x56, 0x70, 0x56, 0x70, 0x54, 0x70, 0x51, 0x6d, - 0x50, 0x6d, 0x4b, 0x6a, 0x46, 0x68, 0x44, 0x69, 0x41, 0x69, 0x40, 0x69, - 0x41, 0x69, 0x41, 0x68, 0x41, 0x68, 0x42, 0x67, 0x41, 0x65, 0x41, 0x63, - 0x40, 0x63, 0x3f, 0x62, 0x3d, 0x63, 0x3d, 0x63, 0x3b, 0x65, 0x3d, 0x67, - 0x42, 0x67, 0x46, 0x67, 0x46, 0x68, 0x49, 0x69, 0x4c, 0x6c, 0x51, 0x6d, - 0x56, 0x6f, 0x59, 0x72, 0x5b, 0x72, 0x5c, 0x72, 0x5b, 0x72, 0x5a, 0x72, - 0x59, 0x70, 0x59, 0x70, 0x5a, 0x71, 0x5b, 0x70, 0x5b, 0x71, 0x5c, 0x70, - 0x5b, 0x71, 0x5a, 0x72, 0x5a, 0x72, 0x5b, 0x72, 0x5c, 0x72, 0x5b, 0x72, - 0x5a, 0x72, 0x59, 0x72, 0x57, 0x72, 0x56, 0x72, 0x54, 0x72, 0x54, 0x72, - 0x54, 0x72, 0x50, 0x72, 0x4f, 0x70, 0x50, 0x71, 0x4f, 0x72, 0x52, 0x72, - 0x54, 0x73, 0x57, 0x72, 0x59, 0x73, 0x5b, 0x75, 0x5e, 0x76, 0x60, 0x77, - 0x62, 0x78, 0x61, 0x79, 0x62, 0x79, 0x63, 0x7a, 0x62, 0x7a, 0x62, 0x79, - 0x62, 0x7a, 0x60, 0x78, 0x5f, 0x78, 0x5f, 0x78, 0x60, 0x78, 0x5e, 0x78, - 0x5c, 0x78, 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x77, 0x59, 0x77, 0x59, 0x77, - 0x59, 0x78, 0x5b, 0x77, 0x5d, 0x76, 0x5e, 0x76, 0x63, 0x76, 0x68, 0x74, - 0x6d, 0x73, 0x75, 0x71, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6e, 0x78, 0x6e, - 0x79, 0x6f, 0x79, 0x70, 0x78, 0x70, 0x79, 0x6f, 0x79, 0x6f, 0x7a, 0x6f, - 0x7a, 0x6f, 0x7a, 0x71, 0x7a, 0x71, 0x7b, 0x71, 0x7b, 0x71, 0x7b, 0x72, - 0x7b, 0x72, 0x7b, 0x70, 0x7b, 0x70, 0x7c, 0x70, 0x7c, 0x74, 0x7e, 0x7c, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x72, 0x6d, 0x72, 0x6e, - 0x74, 0x6e, 0x75, 0x6e, 0x76, 0x6d, 0x73, 0x6d, 0x72, 0x6b, 0x70, 0x68, - 0x6d, 0x67, 0x6b, 0x65, 0x68, 0x63, 0x68, 0x63, 0x5d, 0x61, 0x46, 0x5f, - 0x3c, 0x5f, 0x37, 0x62, 0x35, 0x64, 0x36, 0x63, 0x37, 0x63, 0x38, 0x65, - 0x39, 0x66, 0x38, 0x64, 0x37, 0x67, 0x36, 0x6a, 0x37, 0x6b, 0x39, 0x6a, - 0x3b, 0x6b, 0x3a, 0x6b, 0x38, 0x6a, 0x39, 0x6a, 0x3c, 0x6a, 0x43, 0x6a, - 0x4a, 0x6c, 0x50, 0x6f, 0x54, 0x70, 0x56, 0x70, 0x57, 0x70, 0x57, 0x70, - 0x56, 0x70, 0x56, 0x70, 0x54, 0x70, 0x51, 0x6d, 0x50, 0x6c, 0x4a, 0x69, - 0x45, 0x68, 0x44, 0x6a, 0x42, 0x69, 0x42, 0x68, 0x41, 0x68, 0x41, 0x68, - 0x41, 0x68, 0x41, 0x65, 0x41, 0x63, 0x41, 0x62, 0x40, 0x62, 0x3e, 0x63, - 0x3c, 0x63, 0x3c, 0x63, 0x3b, 0x66, 0x3e, 0x68, 0x42, 0x68, 0x47, 0x68, - 0x49, 0x68, 0x4b, 0x68, 0x4e, 0x6c, 0x52, 0x6d, 0x57, 0x6f, 0x59, 0x72, - 0x5b, 0x73, 0x5c, 0x72, 0x5a, 0x72, 0x5a, 0x72, 0x59, 0x70, 0x58, 0x70, - 0x59, 0x71, 0x59, 0x71, 0x59, 0x70, 0x5a, 0x70, 0x5a, 0x71, 0x5b, 0x73, - 0x5a, 0x72, 0x5b, 0x72, 0x5b, 0x72, 0x5a, 0x72, 0x5b, 0x72, 0x5a, 0x72, - 0x58, 0x72, 0x57, 0x73, 0x55, 0x72, 0x55, 0x72, 0x53, 0x72, 0x50, 0x72, - 0x50, 0x70, 0x50, 0x70, 0x4e, 0x72, 0x50, 0x73, 0x54, 0x72, 0x57, 0x72, - 0x59, 0x73, 0x5c, 0x75, 0x5c, 0x77, 0x5f, 0x77, 0x60, 0x77, 0x60, 0x77, - 0x61, 0x78, 0x62, 0x7a, 0x62, 0x7a, 0x62, 0x7a, 0x62, 0x79, 0x60, 0x78, - 0x5e, 0x78, 0x5e, 0x78, 0x5e, 0x78, 0x5e, 0x78, 0x5d, 0x78, 0x5b, 0x78, - 0x5b, 0x77, 0x59, 0x77, 0x58, 0x77, 0x58, 0x77, 0x5a, 0x77, 0x5d, 0x77, - 0x5f, 0x75, 0x61, 0x75, 0x67, 0x74, 0x6c, 0x72, 0x71, 0x71, 0x76, 0x6f, - 0x78, 0x6f, 0x77, 0x6f, 0x77, 0x6e, 0x77, 0x6e, 0x78, 0x6f, 0x78, 0x6f, - 0x78, 0x6f, 0x78, 0x6f, 0x79, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7b, 0x70, - 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x71, 0x7b, 0x72, 0x7b, 0x73, 0x7b, 0x70, - 0x7b, 0x70, 0x7c, 0x71, 0x7d, 0x75, 0x7e, 0x7c, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x7f, 0x80, 0x7f, 0x70, 0x6e, 0x70, 0x6d, 0x73, 0x6c, 0x73, 0x6c, - 0x73, 0x6b, 0x71, 0x6b, 0x6e, 0x69, 0x6b, 0x67, 0x68, 0x64, 0x66, 0x62, - 0x63, 0x60, 0x61, 0x5f, 0x55, 0x5d, 0x43, 0x5d, 0x3d, 0x5d, 0x39, 0x62, - 0x37, 0x64, 0x36, 0x64, 0x37, 0x64, 0x38, 0x65, 0x39, 0x65, 0x38, 0x65, - 0x37, 0x68, 0x36, 0x6b, 0x38, 0x6c, 0x3e, 0x6c, 0x3e, 0x6c, 0x3d, 0x6c, - 0x3b, 0x6c, 0x3b, 0x6c, 0x42, 0x6c, 0x49, 0x6c, 0x4d, 0x6d, 0x53, 0x71, - 0x56, 0x72, 0x58, 0x71, 0x58, 0x70, 0x57, 0x70, 0x56, 0x70, 0x56, 0x70, - 0x54, 0x70, 0x52, 0x6d, 0x50, 0x6c, 0x49, 0x69, 0x43, 0x69, 0x43, 0x6a, - 0x42, 0x6a, 0x44, 0x68, 0x43, 0x68, 0x41, 0x68, 0x41, 0x68, 0x41, 0x64, - 0x41, 0x61, 0x40, 0x60, 0x40, 0x60, 0x3f, 0x62, 0x3c, 0x63, 0x3b, 0x62, - 0x3c, 0x66, 0x40, 0x68, 0x42, 0x68, 0x48, 0x67, 0x4b, 0x68, 0x4d, 0x68, - 0x50, 0x6b, 0x54, 0x6d, 0x57, 0x6e, 0x59, 0x72, 0x5b, 0x73, 0x5b, 0x72, - 0x5b, 0x72, 0x5a, 0x72, 0x59, 0x71, 0x58, 0x71, 0x57, 0x71, 0x57, 0x71, - 0x58, 0x70, 0x58, 0x71, 0x59, 0x71, 0x5b, 0x73, 0x5b, 0x73, 0x5b, 0x73, - 0x5c, 0x73, 0x5a, 0x72, 0x5a, 0x72, 0x59, 0x72, 0x57, 0x72, 0x57, 0x73, - 0x55, 0x72, 0x55, 0x72, 0x53, 0x72, 0x50, 0x72, 0x50, 0x70, 0x50, 0x70, - 0x4d, 0x72, 0x4f, 0x72, 0x53, 0x72, 0x57, 0x72, 0x59, 0x73, 0x5c, 0x75, - 0x5c, 0x77, 0x5f, 0x77, 0x61, 0x77, 0x60, 0x78, 0x61, 0x78, 0x62, 0x7a, - 0x62, 0x7a, 0x62, 0x7a, 0x62, 0x79, 0x60, 0x78, 0x5e, 0x78, 0x5d, 0x78, - 0x5c, 0x78, 0x5d, 0x78, 0x5d, 0x78, 0x5b, 0x77, 0x5b, 0x77, 0x59, 0x76, - 0x58, 0x77, 0x59, 0x77, 0x5c, 0x78, 0x5e, 0x77, 0x61, 0x75, 0x63, 0x76, - 0x6a, 0x73, 0x6f, 0x70, 0x75, 0x70, 0x76, 0x6d, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6e, 0x77, 0x6e, 0x78, 0x6e, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, - 0x79, 0x6f, 0x7a, 0x6e, 0x7a, 0x6f, 0x7a, 0x71, 0x7a, 0x70, 0x7a, 0x70, - 0x7b, 0x70, 0x7b, 0x72, 0x7b, 0x72, 0x7b, 0x71, 0x7a, 0x70, 0x7c, 0x71, - 0x7c, 0x75, 0x7e, 0x7c, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, - 0x6f, 0x6d, 0x6f, 0x6d, 0x71, 0x6d, 0x70, 0x6b, 0x70, 0x6a, 0x6e, 0x68, - 0x6a, 0x67, 0x67, 0x65, 0x63, 0x62, 0x61, 0x5f, 0x5a, 0x5e, 0x56, 0x5d, - 0x4d, 0x5c, 0x43, 0x5c, 0x3f, 0x5c, 0x3a, 0x62, 0x37, 0x65, 0x36, 0x65, - 0x37, 0x65, 0x37, 0x65, 0x38, 0x66, 0x37, 0x68, 0x37, 0x6a, 0x37, 0x6c, - 0x3a, 0x6d, 0x40, 0x6d, 0x41, 0x6d, 0x42, 0x6c, 0x41, 0x6c, 0x42, 0x6d, - 0x48, 0x6e, 0x4e, 0x6e, 0x51, 0x70, 0x55, 0x71, 0x58, 0x72, 0x58, 0x71, - 0x58, 0x71, 0x57, 0x71, 0x56, 0x70, 0x56, 0x70, 0x54, 0x6f, 0x51, 0x6d, - 0x4d, 0x6b, 0x46, 0x6a, 0x45, 0x6a, 0x44, 0x6a, 0x44, 0x6a, 0x45, 0x69, - 0x42, 0x6a, 0x40, 0x69, 0x41, 0x68, 0x41, 0x64, 0x41, 0x62, 0x40, 0x61, - 0x3f, 0x61, 0x3d, 0x62, 0x3c, 0x64, 0x3b, 0x65, 0x3d, 0x67, 0x41, 0x68, - 0x44, 0x68, 0x49, 0x69, 0x4b, 0x69, 0x4d, 0x6a, 0x50, 0x6c, 0x54, 0x6e, - 0x57, 0x6f, 0x59, 0x71, 0x5b, 0x72, 0x5b, 0x72, 0x5a, 0x72, 0x59, 0x72, - 0x57, 0x71, 0x57, 0x71, 0x57, 0x70, 0x56, 0x70, 0x56, 0x70, 0x56, 0x70, - 0x57, 0x70, 0x58, 0x71, 0x59, 0x72, 0x5a, 0x71, 0x5b, 0x71, 0x5a, 0x71, - 0x5b, 0x72, 0x59, 0x72, 0x57, 0x72, 0x58, 0x72, 0x57, 0x72, 0x56, 0x72, - 0x54, 0x72, 0x51, 0x72, 0x50, 0x70, 0x50, 0x70, 0x4d, 0x72, 0x4e, 0x72, - 0x51, 0x72, 0x55, 0x72, 0x57, 0x73, 0x5a, 0x75, 0x5c, 0x77, 0x5e, 0x77, - 0x60, 0x78, 0x60, 0x78, 0x62, 0x79, 0x62, 0x79, 0x63, 0x79, 0x62, 0x7a, - 0x62, 0x7a, 0x60, 0x78, 0x5d, 0x78, 0x5b, 0x77, 0x5b, 0x77, 0x5c, 0x78, - 0x5d, 0x78, 0x5c, 0x77, 0x5c, 0x77, 0x5a, 0x77, 0x59, 0x77, 0x5a, 0x77, - 0x5c, 0x76, 0x5e, 0x76, 0x63, 0x76, 0x66, 0x75, 0x6e, 0x71, 0x71, 0x70, - 0x76, 0x6f, 0x76, 0x6e, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x70, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x7a, 0x70, - 0x7a, 0x70, 0x7a, 0x71, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x71, - 0x7a, 0x71, 0x7b, 0x70, 0x7a, 0x72, 0x7b, 0x73, 0x7b, 0x75, 0x7d, 0x7c, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x80, - 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x6d, 0x6d, 0x6d, 0x6d, - 0x6e, 0x6d, 0x6c, 0x6a, 0x6b, 0x68, 0x69, 0x65, 0x65, 0x63, 0x60, 0x61, - 0x5c, 0x5f, 0x57, 0x5d, 0x4e, 0x5a, 0x4c, 0x58, 0x4b, 0x59, 0x45, 0x5a, - 0x41, 0x5b, 0x3c, 0x61, 0x38, 0x67, 0x36, 0x67, 0x36, 0x67, 0x36, 0x67, - 0x37, 0x68, 0x37, 0x6b, 0x38, 0x6b, 0x3a, 0x6d, 0x3e, 0x6e, 0x41, 0x6d, - 0x44, 0x6e, 0x45, 0x6d, 0x47, 0x6e, 0x49, 0x70, 0x4d, 0x70, 0x51, 0x70, - 0x54, 0x72, 0x57, 0x72, 0x59, 0x72, 0x58, 0x72, 0x58, 0x72, 0x59, 0x72, - 0x57, 0x70, 0x56, 0x71, 0x53, 0x6f, 0x4f, 0x6d, 0x4b, 0x6b, 0x44, 0x6a, - 0x47, 0x6b, 0x45, 0x6a, 0x46, 0x6a, 0x45, 0x6a, 0x42, 0x6a, 0x40, 0x69, - 0x41, 0x66, 0x40, 0x63, 0x40, 0x61, 0x3e, 0x62, 0x3e, 0x62, 0x3c, 0x62, - 0x3b, 0x65, 0x3a, 0x66, 0x3d, 0x67, 0x41, 0x68, 0x45, 0x68, 0x49, 0x69, - 0x4a, 0x6a, 0x4d, 0x6b, 0x50, 0x6e, 0x54, 0x6f, 0x56, 0x71, 0x59, 0x70, - 0x5a, 0x72, 0x5b, 0x72, 0x5a, 0x72, 0x57, 0x72, 0x56, 0x71, 0x56, 0x70, - 0x56, 0x70, 0x56, 0x70, 0x56, 0x70, 0x55, 0x70, 0x55, 0x70, 0x56, 0x70, - 0x57, 0x70, 0x59, 0x70, 0x5a, 0x70, 0x5a, 0x71, 0x5b, 0x72, 0x5a, 0x72, - 0x58, 0x72, 0x58, 0x72, 0x59, 0x73, 0x56, 0x72, 0x55, 0x72, 0x52, 0x72, - 0x50, 0x70, 0x50, 0x70, 0x4e, 0x72, 0x4d, 0x72, 0x50, 0x72, 0x54, 0x73, - 0x56, 0x74, 0x59, 0x76, 0x5b, 0x77, 0x5d, 0x77, 0x5e, 0x77, 0x5f, 0x78, - 0x62, 0x79, 0x62, 0x78, 0x62, 0x78, 0x63, 0x7a, 0x63, 0x7a, 0x60, 0x78, - 0x5e, 0x78, 0x5b, 0x77, 0x5b, 0x76, 0x5c, 0x77, 0x5c, 0x78, 0x5b, 0x78, - 0x5b, 0x77, 0x5b, 0x78, 0x5a, 0x77, 0x5b, 0x76, 0x5e, 0x75, 0x62, 0x76, - 0x67, 0x75, 0x6b, 0x73, 0x72, 0x71, 0x74, 0x70, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x71, 0x77, 0x71, 0x77, 0x70, 0x77, 0x6f, - 0x77, 0x6f, 0x78, 0x6e, 0x79, 0x6f, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, - 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x70, - 0x7a, 0x72, 0x7a, 0x74, 0x7a, 0x74, 0x7d, 0x7b, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x7f, - 0x80, 0x7f, 0x80, 0x7f, 0x6b, 0x6d, 0x6c, 0x6d, 0x6c, 0x6c, 0x69, 0x69, - 0x67, 0x67, 0x64, 0x65, 0x60, 0x61, 0x5b, 0x5e, 0x53, 0x5c, 0x4d, 0x5c, - 0x4b, 0x57, 0x4c, 0x54, 0x4c, 0x54, 0x47, 0x55, 0x43, 0x59, 0x3d, 0x61, - 0x39, 0x66, 0x37, 0x69, 0x36, 0x69, 0x36, 0x69, 0x36, 0x69, 0x36, 0x6a, - 0x39, 0x6a, 0x3d, 0x6d, 0x41, 0x6e, 0x44, 0x6d, 0x45, 0x6d, 0x47, 0x6e, - 0x4b, 0x6f, 0x4d, 0x71, 0x50, 0x71, 0x54, 0x71, 0x55, 0x73, 0x58, 0x73, - 0x59, 0x74, 0x59, 0x74, 0x58, 0x72, 0x59, 0x72, 0x57, 0x70, 0x56, 0x70, - 0x53, 0x70, 0x4e, 0x6d, 0x49, 0x6b, 0x44, 0x6b, 0x47, 0x6b, 0x47, 0x6a, - 0x46, 0x6a, 0x44, 0x69, 0x42, 0x6a, 0x40, 0x68, 0x41, 0x65, 0x40, 0x62, - 0x40, 0x60, 0x3e, 0x61, 0x3e, 0x62, 0x3c, 0x61, 0x3a, 0x64, 0x3a, 0x66, - 0x3d, 0x67, 0x41, 0x67, 0x45, 0x68, 0x4a, 0x69, 0x4a, 0x6a, 0x4c, 0x6a, - 0x4f, 0x6e, 0x54, 0x6f, 0x56, 0x71, 0x59, 0x70, 0x5b, 0x72, 0x5a, 0x72, - 0x5a, 0x72, 0x57, 0x72, 0x56, 0x71, 0x56, 0x70, 0x56, 0x70, 0x56, 0x71, - 0x56, 0x71, 0x56, 0x71, 0x56, 0x70, 0x57, 0x70, 0x57, 0x70, 0x5a, 0x70, - 0x5b, 0x70, 0x5b, 0x71, 0x5b, 0x72, 0x5a, 0x72, 0x58, 0x72, 0x58, 0x72, - 0x58, 0x72, 0x55, 0x72, 0x54, 0x72, 0x52, 0x72, 0x50, 0x70, 0x50, 0x70, - 0x4e, 0x73, 0x4d, 0x72, 0x50, 0x73, 0x54, 0x73, 0x56, 0x74, 0x5a, 0x75, - 0x5c, 0x77, 0x5e, 0x77, 0x5f, 0x78, 0x60, 0x78, 0x62, 0x78, 0x62, 0x78, - 0x62, 0x78, 0x62, 0x7a, 0x62, 0x7a, 0x61, 0x78, 0x5e, 0x78, 0x5b, 0x77, - 0x5b, 0x77, 0x5c, 0x78, 0x5d, 0x78, 0x5c, 0x78, 0x5b, 0x78, 0x5c, 0x78, - 0x5b, 0x77, 0x5c, 0x76, 0x60, 0x75, 0x66, 0x76, 0x6a, 0x74, 0x6e, 0x72, - 0x75, 0x70, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, - 0x79, 0x6f, 0x7a, 0x70, 0x7b, 0x70, 0x7a, 0x71, 0x7a, 0x70, 0x7a, 0x70, - 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x70, 0x7b, 0x72, 0x7a, 0x74, - 0x7a, 0x75, 0x7d, 0x7b, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, - 0x6a, 0x6c, 0x68, 0x6b, 0x69, 0x69, 0x65, 0x66, 0x62, 0x64, 0x5e, 0x62, - 0x58, 0x5f, 0x51, 0x5c, 0x49, 0x5a, 0x47, 0x59, 0x4a, 0x54, 0x4c, 0x51, - 0x4d, 0x50, 0x4a, 0x53, 0x46, 0x56, 0x40, 0x5f, 0x3c, 0x65, 0x39, 0x68, - 0x37, 0x6b, 0x38, 0x6b, 0x3a, 0x6a, 0x3b, 0x6b, 0x3b, 0x6b, 0x40, 0x6c, - 0x43, 0x6d, 0x47, 0x6e, 0x48, 0x6f, 0x4b, 0x6f, 0x4f, 0x71, 0x51, 0x73, - 0x53, 0x72, 0x56, 0x72, 0x57, 0x74, 0x59, 0x75, 0x58, 0x75, 0x58, 0x75, - 0x58, 0x73, 0x57, 0x72, 0x56, 0x71, 0x55, 0x70, 0x51, 0x6f, 0x4d, 0x6d, - 0x4a, 0x6b, 0x47, 0x6b, 0x48, 0x6b, 0x48, 0x6a, 0x46, 0x6b, 0x43, 0x6a, - 0x40, 0x68, 0x40, 0x65, 0x41, 0x62, 0x40, 0x60, 0x40, 0x5f, 0x3e, 0x62, - 0x3e, 0x62, 0x3c, 0x61, 0x3b, 0x65, 0x3b, 0x67, 0x3e, 0x67, 0x42, 0x68, - 0x46, 0x68, 0x49, 0x6a, 0x4b, 0x6b, 0x4d, 0x6a, 0x4f, 0x6c, 0x53, 0x6f, - 0x56, 0x71, 0x58, 0x70, 0x5a, 0x72, 0x59, 0x72, 0x59, 0x72, 0x57, 0x71, - 0x56, 0x71, 0x56, 0x70, 0x56, 0x70, 0x56, 0x71, 0x56, 0x71, 0x55, 0x71, - 0x55, 0x70, 0x55, 0x70, 0x57, 0x70, 0x59, 0x71, 0x59, 0x71, 0x59, 0x72, - 0x59, 0x72, 0x59, 0x71, 0x59, 0x72, 0x58, 0x72, 0x58, 0x72, 0x56, 0x72, - 0x55, 0x72, 0x53, 0x72, 0x50, 0x71, 0x50, 0x72, 0x4e, 0x73, 0x4d, 0x72, - 0x50, 0x73, 0x54, 0x73, 0x56, 0x74, 0x58, 0x75, 0x5b, 0x77, 0x5d, 0x77, - 0x5f, 0x77, 0x5f, 0x78, 0x61, 0x78, 0x62, 0x78, 0x62, 0x78, 0x62, 0x79, - 0x62, 0x79, 0x60, 0x78, 0x5e, 0x77, 0x5c, 0x77, 0x5b, 0x77, 0x5c, 0x78, - 0x5c, 0x78, 0x5b, 0x77, 0x5b, 0x77, 0x5d, 0x77, 0x5e, 0x76, 0x5f, 0x76, - 0x65, 0x75, 0x6a, 0x75, 0x6f, 0x72, 0x73, 0x71, 0x77, 0x70, 0x78, 0x70, - 0x78, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, 0x79, 0x70, - 0x79, 0x70, 0x79, 0x71, 0x79, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, - 0x7a, 0x70, 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x74, 0x7c, 0x75, 0x7d, 0x7b, - 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, - 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x68, 0x6b, 0x65, 0x68, - 0x65, 0x66, 0x60, 0x64, 0x5d, 0x62, 0x57, 0x5f, 0x50, 0x5d, 0x49, 0x5b, - 0x46, 0x58, 0x47, 0x56, 0x49, 0x53, 0x4a, 0x50, 0x4d, 0x4f, 0x4d, 0x52, - 0x4a, 0x54, 0x43, 0x5d, 0x3f, 0x65, 0x3b, 0x65, 0x3a, 0x6c, 0x3e, 0x6c, - 0x3f, 0x6b, 0x40, 0x6c, 0x3e, 0x6c, 0x41, 0x6d, 0x45, 0x6e, 0x48, 0x6f, - 0x4a, 0x71, 0x4d, 0x71, 0x50, 0x73, 0x52, 0x73, 0x55, 0x72, 0x57, 0x73, - 0x58, 0x74, 0x58, 0x75, 0x58, 0x75, 0x59, 0x75, 0x58, 0x74, 0x56, 0x72, - 0x55, 0x71, 0x53, 0x70, 0x50, 0x6d, 0x4c, 0x6c, 0x4a, 0x6c, 0x48, 0x6b, - 0x49, 0x6b, 0x48, 0x6b, 0x45, 0x6b, 0x41, 0x6b, 0x3f, 0x67, 0x40, 0x63, - 0x41, 0x60, 0x41, 0x60, 0x41, 0x61, 0x3e, 0x62, 0x3e, 0x62, 0x3d, 0x62, - 0x3c, 0x65, 0x3b, 0x67, 0x3f, 0x68, 0x44, 0x69, 0x46, 0x68, 0x48, 0x6a, - 0x4b, 0x6b, 0x4c, 0x6b, 0x4f, 0x6b, 0x52, 0x6e, 0x55, 0x70, 0x58, 0x70, - 0x58, 0x72, 0x58, 0x72, 0x57, 0x71, 0x57, 0x70, 0x56, 0x70, 0x56, 0x70, - 0x56, 0x70, 0x56, 0x71, 0x55, 0x71, 0x55, 0x70, 0x54, 0x70, 0x55, 0x70, - 0x56, 0x70, 0x57, 0x71, 0x57, 0x72, 0x57, 0x72, 0x58, 0x72, 0x58, 0x72, - 0x58, 0x73, 0x58, 0x73, 0x58, 0x73, 0x56, 0x72, 0x56, 0x72, 0x53, 0x72, - 0x50, 0x73, 0x50, 0x72, 0x4d, 0x72, 0x4d, 0x72, 0x51, 0x74, 0x54, 0x73, - 0x55, 0x73, 0x57, 0x76, 0x5a, 0x77, 0x5c, 0x77, 0x5f, 0x77, 0x5f, 0x77, - 0x5f, 0x77, 0x60, 0x78, 0x61, 0x78, 0x61, 0x78, 0x60, 0x78, 0x5e, 0x77, - 0x5d, 0x77, 0x5c, 0x78, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x77, - 0x5b, 0x78, 0x5e, 0x76, 0x5f, 0x75, 0x63, 0x75, 0x6a, 0x74, 0x6d, 0x73, - 0x72, 0x70, 0x76, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x71, 0x77, 0x70, - 0x77, 0x70, 0x77, 0x71, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x70, 0x78, 0x70, 0x78, 0x70, 0x77, 0x70, - 0x78, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x71, 0x7a, 0x70, 0x7b, 0x70, - 0x7a, 0x6f, 0x7c, 0x74, 0x7d, 0x76, 0x7e, 0x7b, 0x7f, 0x7f, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x80, 0x7f, 0x80, 0x7f, 0x64, 0x6a, 0x62, 0x67, 0x61, 0x65, 0x5b, 0x63, - 0x57, 0x61, 0x4e, 0x5e, 0x47, 0x5a, 0x46, 0x57, 0x47, 0x54, 0x47, 0x52, - 0x49, 0x51, 0x4a, 0x51, 0x4c, 0x4f, 0x4e, 0x50, 0x4c, 0x52, 0x47, 0x5c, - 0x42, 0x63, 0x3d, 0x65, 0x40, 0x6b, 0x45, 0x6d, 0x46, 0x6d, 0x45, 0x6e, - 0x43, 0x6e, 0x46, 0x6f, 0x46, 0x6f, 0x48, 0x6f, 0x4a, 0x71, 0x4d, 0x71, - 0x52, 0x73, 0x54, 0x72, 0x57, 0x74, 0x59, 0x75, 0x58, 0x74, 0x58, 0x75, - 0x58, 0x75, 0x58, 0x75, 0x58, 0x74, 0x56, 0x72, 0x53, 0x72, 0x51, 0x70, - 0x4e, 0x6d, 0x4a, 0x6c, 0x48, 0x6c, 0x47, 0x6b, 0x49, 0x6b, 0x48, 0x6b, - 0x45, 0x6b, 0x40, 0x6a, 0x3f, 0x67, 0x40, 0x64, 0x40, 0x61, 0x40, 0x60, - 0x40, 0x61, 0x3e, 0x62, 0x3d, 0x62, 0x3d, 0x62, 0x3c, 0x65, 0x3b, 0x67, - 0x3f, 0x68, 0x44, 0x69, 0x45, 0x68, 0x47, 0x69, 0x49, 0x6b, 0x4b, 0x6b, - 0x4f, 0x6c, 0x53, 0x6e, 0x55, 0x70, 0x58, 0x70, 0x59, 0x72, 0x58, 0x72, - 0x57, 0x70, 0x57, 0x70, 0x57, 0x70, 0x56, 0x70, 0x56, 0x70, 0x56, 0x70, - 0x55, 0x71, 0x55, 0x70, 0x55, 0x70, 0x55, 0x70, 0x56, 0x70, 0x58, 0x71, - 0x57, 0x72, 0x57, 0x72, 0x58, 0x72, 0x58, 0x72, 0x58, 0x73, 0x58, 0x74, - 0x58, 0x73, 0x56, 0x73, 0x55, 0x72, 0x52, 0x72, 0x50, 0x72, 0x50, 0x72, - 0x4d, 0x72, 0x4d, 0x72, 0x4f, 0x73, 0x52, 0x73, 0x54, 0x73, 0x57, 0x76, - 0x5a, 0x78, 0x5c, 0x77, 0x5d, 0x77, 0x5d, 0x77, 0x5e, 0x78, 0x5e, 0x78, - 0x5f, 0x78, 0x5f, 0x78, 0x5e, 0x78, 0x5c, 0x77, 0x5c, 0x77, 0x5c, 0x77, - 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5d, 0x77, 0x60, 0x76, - 0x62, 0x76, 0x67, 0x74, 0x6c, 0x72, 0x71, 0x72, 0x75, 0x70, 0x76, 0x70, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x71, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x70, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x7a, 0x70, - 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x6f, 0x7c, 0x74, - 0x7c, 0x76, 0x7d, 0x7b, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x61, 0x67, 0x5e, 0x64, 0x5b, 0x63, 0x54, 0x60, 0x4e, 0x5f, 0x47, 0x5b, - 0x45, 0x56, 0x46, 0x53, 0x48, 0x50, 0x48, 0x4f, 0x49, 0x50, 0x4a, 0x51, - 0x4d, 0x4f, 0x4f, 0x4f, 0x50, 0x51, 0x4b, 0x5a, 0x45, 0x61, 0x41, 0x64, - 0x47, 0x6a, 0x4c, 0x6d, 0x4c, 0x6f, 0x4b, 0x70, 0x48, 0x70, 0x4a, 0x70, - 0x49, 0x71, 0x48, 0x70, 0x4a, 0x70, 0x4e, 0x71, 0x54, 0x73, 0x56, 0x73, - 0x58, 0x75, 0x5a, 0x76, 0x5a, 0x75, 0x59, 0x75, 0x58, 0x75, 0x58, 0x75, - 0x58, 0x74, 0x56, 0x72, 0x52, 0x71, 0x4f, 0x6f, 0x4c, 0x6d, 0x49, 0x6d, - 0x49, 0x6d, 0x49, 0x6b, 0x4a, 0x6b, 0x49, 0x6c, 0x42, 0x6b, 0x3f, 0x6a, - 0x3f, 0x66, 0x40, 0x63, 0x41, 0x61, 0x40, 0x5e, 0x40, 0x60, 0x3f, 0x61, - 0x3e, 0x62, 0x3e, 0x63, 0x3c, 0x65, 0x3c, 0x66, 0x3e, 0x67, 0x42, 0x68, - 0x44, 0x68, 0x47, 0x69, 0x47, 0x6b, 0x4b, 0x6a, 0x4e, 0x6c, 0x52, 0x6e, - 0x54, 0x70, 0x56, 0x70, 0x58, 0x72, 0x58, 0x72, 0x58, 0x71, 0x57, 0x70, - 0x57, 0x71, 0x56, 0x71, 0x56, 0x71, 0x57, 0x71, 0x56, 0x71, 0x55, 0x70, - 0x55, 0x70, 0x56, 0x70, 0x56, 0x70, 0x58, 0x71, 0x57, 0x72, 0x58, 0x72, - 0x59, 0x72, 0x59, 0x72, 0x58, 0x73, 0x58, 0x73, 0x57, 0x73, 0x57, 0x73, - 0x56, 0x73, 0x53, 0x72, 0x51, 0x72, 0x50, 0x72, 0x4e, 0x72, 0x4d, 0x72, - 0x4e, 0x72, 0x51, 0x73, 0x54, 0x74, 0x58, 0x76, 0x59, 0x76, 0x5b, 0x76, - 0x5d, 0x77, 0x5d, 0x77, 0x5c, 0x78, 0x5d, 0x78, 0x5c, 0x78, 0x5c, 0x78, - 0x5c, 0x78, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x5c, 0x77, 0x5e, 0x77, 0x62, 0x76, 0x66, 0x75, 0x6c, 0x73, - 0x70, 0x71, 0x75, 0x70, 0x77, 0x70, 0x76, 0x70, 0x77, 0x70, 0x77, 0x71, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x70, 0x78, 0x70, - 0x78, 0x71, 0x78, 0x70, 0x79, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, - 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x6e, 0x7c, 0x72, 0x7c, 0x76, 0x7e, 0x7b, - 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x65, 0x5b, 0x63, - 0x58, 0x62, 0x4e, 0x5f, 0x48, 0x5e, 0x45, 0x59, 0x46, 0x53, 0x47, 0x51, - 0x49, 0x4e, 0x49, 0x4f, 0x49, 0x50, 0x4c, 0x50, 0x4d, 0x50, 0x50, 0x4e, - 0x52, 0x50, 0x4f, 0x58, 0x47, 0x5f, 0x45, 0x64, 0x49, 0x69, 0x4d, 0x6b, - 0x4e, 0x6e, 0x4e, 0x70, 0x4c, 0x71, 0x4b, 0x70, 0x4a, 0x70, 0x49, 0x70, - 0x4b, 0x70, 0x4e, 0x71, 0x55, 0x73, 0x57, 0x74, 0x58, 0x74, 0x5a, 0x76, - 0x5b, 0x76, 0x5b, 0x75, 0x58, 0x75, 0x59, 0x75, 0x57, 0x73, 0x55, 0x70, - 0x51, 0x6e, 0x4d, 0x6d, 0x4b, 0x6c, 0x4a, 0x6d, 0x4a, 0x6d, 0x4a, 0x6c, - 0x4b, 0x6d, 0x48, 0x6d, 0x40, 0x6c, 0x3e, 0x69, 0x40, 0x65, 0x40, 0x60, - 0x40, 0x60, 0x40, 0x5d, 0x40, 0x5f, 0x3f, 0x60, 0x3e, 0x62, 0x3e, 0x65, - 0x3d, 0x66, 0x3d, 0x65, 0x3d, 0x66, 0x40, 0x68, 0x44, 0x69, 0x47, 0x69, - 0x48, 0x6a, 0x4b, 0x69, 0x4e, 0x6c, 0x51, 0x6e, 0x53, 0x6f, 0x56, 0x71, - 0x57, 0x72, 0x59, 0x72, 0x58, 0x72, 0x57, 0x72, 0x57, 0x72, 0x57, 0x72, - 0x57, 0x72, 0x57, 0x72, 0x56, 0x71, 0x56, 0x70, 0x56, 0x70, 0x57, 0x70, - 0x56, 0x70, 0x57, 0x72, 0x58, 0x73, 0x57, 0x73, 0x58, 0x72, 0x59, 0x72, - 0x58, 0x73, 0x58, 0x73, 0x58, 0x73, 0x58, 0x73, 0x57, 0x73, 0x54, 0x73, - 0x52, 0x72, 0x4f, 0x72, 0x4e, 0x72, 0x4c, 0x72, 0x4e, 0x72, 0x51, 0x73, - 0x54, 0x74, 0x58, 0x75, 0x58, 0x75, 0x59, 0x75, 0x5c, 0x76, 0x5d, 0x77, - 0x5d, 0x77, 0x5d, 0x77, 0x5d, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x77, - 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5c, 0x77, 0x5b, 0x77, - 0x5e, 0x76, 0x64, 0x75, 0x68, 0x75, 0x70, 0x73, 0x73, 0x71, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x71, 0x78, 0x71, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x70, 0x79, 0x70, 0x78, 0x6f, - 0x79, 0x70, 0x7b, 0x71, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, - 0x7a, 0x6f, 0x7b, 0x70, 0x7d, 0x75, 0x7e, 0x7b, 0x80, 0x80, 0x81, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x7f, 0x80, 0x5e, 0x65, 0x59, 0x63, 0x53, 0x60, 0x48, 0x5d, - 0x44, 0x5c, 0x46, 0x57, 0x48, 0x54, 0x49, 0x52, 0x4a, 0x4e, 0x4b, 0x4e, - 0x4c, 0x50, 0x4e, 0x4f, 0x4f, 0x51, 0x50, 0x50, 0x51, 0x52, 0x50, 0x58, - 0x4b, 0x5f, 0x4a, 0x64, 0x4f, 0x6a, 0x51, 0x6c, 0x52, 0x6f, 0x52, 0x70, - 0x50, 0x71, 0x4d, 0x70, 0x4c, 0x70, 0x4a, 0x70, 0x4c, 0x70, 0x4e, 0x71, - 0x52, 0x73, 0x55, 0x74, 0x58, 0x73, 0x5a, 0x76, 0x5b, 0x75, 0x5b, 0x75, - 0x58, 0x74, 0x58, 0x75, 0x55, 0x73, 0x53, 0x71, 0x4f, 0x6f, 0x4c, 0x6d, - 0x49, 0x6d, 0x48, 0x6d, 0x49, 0x6d, 0x4a, 0x6c, 0x4a, 0x6d, 0x46, 0x6d, - 0x3f, 0x6b, 0x3e, 0x67, 0x3f, 0x63, 0x40, 0x60, 0x40, 0x60, 0x40, 0x5f, - 0x40, 0x61, 0x3f, 0x62, 0x3f, 0x65, 0x3e, 0x66, 0x3d, 0x65, 0x3c, 0x65, - 0x3d, 0x67, 0x40, 0x69, 0x44, 0x68, 0x47, 0x69, 0x48, 0x6a, 0x4b, 0x6a, - 0x4f, 0x6c, 0x52, 0x6e, 0x54, 0x6f, 0x56, 0x72, 0x57, 0x72, 0x59, 0x72, - 0x59, 0x72, 0x59, 0x72, 0x59, 0x73, 0x59, 0x73, 0x58, 0x72, 0x57, 0x72, - 0x57, 0x71, 0x56, 0x70, 0x56, 0x70, 0x56, 0x70, 0x56, 0x70, 0x57, 0x71, - 0x58, 0x72, 0x57, 0x72, 0x58, 0x72, 0x5a, 0x72, 0x5a, 0x73, 0x5a, 0x73, - 0x5a, 0x74, 0x5b, 0x74, 0x59, 0x73, 0x56, 0x73, 0x54, 0x72, 0x51, 0x72, - 0x50, 0x72, 0x4e, 0x72, 0x4e, 0x72, 0x51, 0x73, 0x53, 0x74, 0x56, 0x75, - 0x57, 0x76, 0x59, 0x75, 0x5d, 0x76, 0x5d, 0x77, 0x5d, 0x77, 0x5d, 0x77, - 0x5d, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, - 0x5b, 0x77, 0x5a, 0x77, 0x5c, 0x77, 0x5d, 0x77, 0x60, 0x75, 0x67, 0x74, - 0x6d, 0x73, 0x74, 0x72, 0x76, 0x70, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, - 0x77, 0x71, 0x77, 0x71, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x78, 0x70, 0x78, 0x70, 0x78, 0x6f, 0x79, 0x70, 0x7a, 0x70, - 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x6f, 0x7a, 0x6f, 0x79, 0x71, - 0x7a, 0x75, 0x7d, 0x7b, 0x80, 0x80, 0x81, 0x80, 0x80, 0x7f, 0x80, 0x80, - 0x80, 0x7f, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x5d, 0x65, 0x58, 0x63, 0x4f, 0x60, 0x44, 0x5c, 0x44, 0x5a, 0x47, 0x55, - 0x4a, 0x53, 0x4a, 0x52, 0x4b, 0x4f, 0x4d, 0x4f, 0x4e, 0x50, 0x4f, 0x50, - 0x50, 0x51, 0x51, 0x53, 0x51, 0x54, 0x51, 0x58, 0x4f, 0x5f, 0x4e, 0x64, - 0x54, 0x6a, 0x54, 0x6c, 0x54, 0x6f, 0x55, 0x70, 0x52, 0x71, 0x50, 0x70, - 0x4d, 0x70, 0x4b, 0x70, 0x4b, 0x70, 0x4d, 0x70, 0x51, 0x73, 0x53, 0x73, - 0x57, 0x74, 0x5a, 0x76, 0x5b, 0x76, 0x5b, 0x75, 0x59, 0x74, 0x58, 0x75, - 0x54, 0x72, 0x52, 0x71, 0x4d, 0x6f, 0x4a, 0x6d, 0x48, 0x6d, 0x47, 0x6c, - 0x49, 0x6c, 0x4a, 0x6c, 0x4a, 0x6d, 0x44, 0x6d, 0x3e, 0x6a, 0x3e, 0x65, - 0x40, 0x61, 0x40, 0x60, 0x41, 0x60, 0x40, 0x61, 0x40, 0x63, 0x3f, 0x64, - 0x3f, 0x66, 0x3f, 0x66, 0x3e, 0x66, 0x3d, 0x65, 0x3d, 0x67, 0x40, 0x69, - 0x44, 0x68, 0x47, 0x68, 0x48, 0x6a, 0x4a, 0x6a, 0x4e, 0x6c, 0x52, 0x6e, - 0x54, 0x6f, 0x55, 0x71, 0x57, 0x72, 0x5a, 0x72, 0x5b, 0x72, 0x5b, 0x72, - 0x5a, 0x73, 0x5a, 0x73, 0x58, 0x72, 0x58, 0x72, 0x57, 0x71, 0x56, 0x70, - 0x56, 0x70, 0x56, 0x70, 0x56, 0x70, 0x57, 0x71, 0x57, 0x72, 0x57, 0x72, - 0x58, 0x72, 0x5b, 0x73, 0x5c, 0x73, 0x5c, 0x73, 0x5c, 0x76, 0x5c, 0x75, - 0x5b, 0x73, 0x57, 0x73, 0x55, 0x72, 0x53, 0x72, 0x51, 0x72, 0x50, 0x72, - 0x4e, 0x73, 0x51, 0x72, 0x52, 0x73, 0x55, 0x75, 0x57, 0x75, 0x5a, 0x75, - 0x5d, 0x77, 0x5d, 0x78, 0x5d, 0x78, 0x5d, 0x78, 0x5c, 0x78, 0x5b, 0x77, - 0x5b, 0x77, 0x5a, 0x77, 0x5b, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x5a, 0x77, - 0x5c, 0x77, 0x5e, 0x77, 0x62, 0x76, 0x6a, 0x73, 0x70, 0x71, 0x77, 0x70, - 0x77, 0x71, 0x77, 0x6f, 0x78, 0x6f, 0x77, 0x6f, 0x77, 0x71, 0x77, 0x71, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x70, 0x78, 0x70, 0x78, 0x71, - 0x77, 0x70, 0x78, 0x6f, 0x78, 0x6f, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, - 0x7a, 0x71, 0x7a, 0x6d, 0x7a, 0x6f, 0x78, 0x71, 0x7a, 0x75, 0x7d, 0x7a, - 0x80, 0x80, 0x80, 0x81, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x5c, 0x65, 0x58, 0x62, - 0x4b, 0x5f, 0x45, 0x59, 0x46, 0x58, 0x49, 0x52, 0x4c, 0x4f, 0x4b, 0x51, - 0x4c, 0x50, 0x4e, 0x4e, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x52, 0x53, - 0x52, 0x56, 0x51, 0x5a, 0x51, 0x60, 0x52, 0x63, 0x58, 0x67, 0x56, 0x6a, - 0x55, 0x6e, 0x57, 0x6f, 0x55, 0x71, 0x53, 0x72, 0x50, 0x72, 0x4b, 0x71, - 0x4a, 0x70, 0x4a, 0x70, 0x4f, 0x72, 0x52, 0x72, 0x58, 0x73, 0x5a, 0x76, - 0x5b, 0x75, 0x5b, 0x75, 0x5a, 0x75, 0x58, 0x73, 0x55, 0x71, 0x51, 0x70, - 0x4d, 0x6e, 0x49, 0x6e, 0x47, 0x6d, 0x49, 0x6c, 0x4b, 0x6d, 0x4a, 0x6e, - 0x48, 0x6d, 0x42, 0x6c, 0x3d, 0x67, 0x3e, 0x64, 0x40, 0x61, 0x41, 0x62, - 0x41, 0x62, 0x40, 0x61, 0x41, 0x64, 0x40, 0x65, 0x40, 0x65, 0x3f, 0x66, - 0x3e, 0x68, 0x3e, 0x68, 0x3d, 0x67, 0x3e, 0x67, 0x43, 0x68, 0x48, 0x69, - 0x4a, 0x6a, 0x4b, 0x6a, 0x4f, 0x6e, 0x53, 0x6f, 0x55, 0x6f, 0x58, 0x72, - 0x5a, 0x74, 0x5b, 0x74, 0x5c, 0x74, 0x5c, 0x74, 0x5a, 0x72, 0x5a, 0x73, - 0x59, 0x74, 0x58, 0x75, 0x56, 0x73, 0x57, 0x72, 0x57, 0x72, 0x57, 0x72, - 0x57, 0x72, 0x57, 0x73, 0x57, 0x73, 0x58, 0x74, 0x5b, 0x74, 0x5c, 0x74, - 0x5c, 0x75, 0x5d, 0x75, 0x5b, 0x76, 0x5c, 0x76, 0x5c, 0x75, 0x59, 0x75, - 0x58, 0x72, 0x56, 0x72, 0x53, 0x72, 0x51, 0x73, 0x50, 0x73, 0x50, 0x72, - 0x52, 0x72, 0x55, 0x73, 0x57, 0x73, 0x58, 0x75, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x5b, 0x78, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x77, - 0x5a, 0x77, 0x59, 0x78, 0x58, 0x77, 0x59, 0x76, 0x5d, 0x75, 0x5f, 0x76, - 0x66, 0x74, 0x6f, 0x73, 0x73, 0x72, 0x76, 0x70, 0x77, 0x71, 0x77, 0x70, - 0x77, 0x6f, 0x77, 0x6f, 0x76, 0x70, 0x76, 0x71, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x71, 0x78, 0x72, 0x78, 0x71, 0x78, 0x70, - 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x6f, - 0x7a, 0x70, 0x7a, 0x71, 0x7a, 0x74, 0x7d, 0x7b, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, - 0x80, 0x7f, 0x80, 0x7f, 0x59, 0x63, 0x52, 0x60, 0x48, 0x5d, 0x47, 0x57, - 0x49, 0x55, 0x4c, 0x50, 0x4d, 0x4e, 0x4d, 0x50, 0x4f, 0x51, 0x50, 0x51, - 0x52, 0x50, 0x53, 0x51, 0x52, 0x53, 0x53, 0x55, 0x53, 0x58, 0x52, 0x5a, - 0x52, 0x5f, 0x58, 0x63, 0x5e, 0x66, 0x5c, 0x68, 0x5a, 0x6b, 0x5a, 0x6e, - 0x57, 0x71, 0x55, 0x72, 0x53, 0x72, 0x4d, 0x71, 0x4b, 0x70, 0x4a, 0x71, - 0x4d, 0x72, 0x50, 0x72, 0x56, 0x73, 0x58, 0x75, 0x5a, 0x75, 0x5a, 0x75, - 0x5a, 0x76, 0x58, 0x73, 0x53, 0x71, 0x4f, 0x6f, 0x4c, 0x6e, 0x49, 0x6e, - 0x45, 0x6d, 0x48, 0x6c, 0x49, 0x6d, 0x48, 0x6e, 0x44, 0x6e, 0x3f, 0x6b, - 0x3d, 0x67, 0x3e, 0x64, 0x40, 0x62, 0x41, 0x62, 0x41, 0x62, 0x41, 0x63, - 0x41, 0x65, 0x41, 0x68, 0x41, 0x67, 0x40, 0x67, 0x3e, 0x67, 0x3e, 0x68, - 0x3d, 0x68, 0x3e, 0x67, 0x42, 0x68, 0x49, 0x69, 0x4b, 0x6a, 0x4b, 0x6a, - 0x51, 0x6e, 0x55, 0x6f, 0x58, 0x71, 0x5a, 0x73, 0x5d, 0x75, 0x5d, 0x75, - 0x5d, 0x74, 0x5c, 0x75, 0x5b, 0x74, 0x5b, 0x74, 0x5c, 0x75, 0x5a, 0x75, - 0x58, 0x74, 0x58, 0x73, 0x58, 0x73, 0x57, 0x73, 0x57, 0x72, 0x57, 0x73, - 0x57, 0x73, 0x59, 0x74, 0x5c, 0x75, 0x5c, 0x75, 0x5c, 0x75, 0x5e, 0x76, - 0x5d, 0x75, 0x5e, 0x75, 0x5e, 0x75, 0x5c, 0x75, 0x5b, 0x74, 0x58, 0x75, - 0x55, 0x73, 0x53, 0x72, 0x51, 0x73, 0x50, 0x73, 0x52, 0x72, 0x54, 0x73, - 0x57, 0x73, 0x58, 0x75, 0x5b, 0x77, 0x5c, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x59, 0x78, - 0x58, 0x77, 0x5a, 0x76, 0x5f, 0x75, 0x63, 0x75, 0x6a, 0x74, 0x72, 0x73, - 0x76, 0x72, 0x77, 0x70, 0x77, 0x71, 0x77, 0x71, 0x77, 0x6f, 0x77, 0x6f, - 0x76, 0x71, 0x75, 0x70, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x71, 0x77, 0x71, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x71, 0x78, 0x72, 0x78, 0x71, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, - 0x78, 0x70, 0x7a, 0x70, 0x7a, 0x71, 0x7b, 0x72, 0x7b, 0x72, 0x7a, 0x72, - 0x7a, 0x73, 0x7d, 0x7b, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, - 0x57, 0x61, 0x4d, 0x5e, 0x46, 0x5c, 0x49, 0x55, 0x4c, 0x52, 0x4e, 0x4f, - 0x4f, 0x4e, 0x50, 0x51, 0x51, 0x52, 0x52, 0x52, 0x54, 0x50, 0x54, 0x50, - 0x53, 0x55, 0x53, 0x57, 0x53, 0x59, 0x52, 0x5a, 0x53, 0x5e, 0x59, 0x62, - 0x5f, 0x66, 0x5f, 0x67, 0x5e, 0x6a, 0x5c, 0x6e, 0x58, 0x71, 0x57, 0x73, - 0x54, 0x73, 0x50, 0x71, 0x4d, 0x70, 0x4b, 0x71, 0x4c, 0x72, 0x4e, 0x72, - 0x55, 0x73, 0x57, 0x75, 0x58, 0x76, 0x59, 0x75, 0x5a, 0x75, 0x57, 0x74, - 0x51, 0x72, 0x4e, 0x6f, 0x4c, 0x6e, 0x48, 0x6d, 0x45, 0x6d, 0x46, 0x6c, - 0x48, 0x6d, 0x47, 0x6e, 0x42, 0x6e, 0x3d, 0x6c, 0x3d, 0x68, 0x3d, 0x63, - 0x40, 0x62, 0x41, 0x62, 0x41, 0x62, 0x40, 0x65, 0x40, 0x67, 0x41, 0x69, - 0x41, 0x69, 0x40, 0x68, 0x3f, 0x67, 0x3f, 0x67, 0x3e, 0x68, 0x3e, 0x67, - 0x43, 0x68, 0x49, 0x69, 0x4b, 0x6a, 0x4c, 0x6a, 0x53, 0x6d, 0x57, 0x6f, - 0x5a, 0x72, 0x5c, 0x75, 0x5e, 0x75, 0x5e, 0x75, 0x5d, 0x75, 0x5c, 0x75, - 0x5d, 0x76, 0x5d, 0x76, 0x5e, 0x75, 0x5c, 0x74, 0x5a, 0x73, 0x5a, 0x73, - 0x59, 0x72, 0x57, 0x72, 0x57, 0x72, 0x57, 0x72, 0x56, 0x73, 0x58, 0x74, - 0x5c, 0x75, 0x5c, 0x75, 0x5c, 0x75, 0x5e, 0x75, 0x5f, 0x75, 0x60, 0x75, - 0x60, 0x75, 0x5d, 0x75, 0x5c, 0x76, 0x59, 0x76, 0x57, 0x73, 0x55, 0x72, - 0x52, 0x73, 0x50, 0x73, 0x52, 0x72, 0x54, 0x73, 0x57, 0x73, 0x58, 0x75, - 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x5a, 0x77, 0x5a, 0x77, 0x59, 0x77, 0x58, 0x77, 0x5b, 0x76, - 0x61, 0x75, 0x66, 0x76, 0x6d, 0x74, 0x74, 0x73, 0x77, 0x72, 0x78, 0x70, - 0x76, 0x70, 0x76, 0x70, 0x77, 0x6f, 0x77, 0x6f, 0x76, 0x70, 0x75, 0x70, - 0x78, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x70, 0x77, 0x71, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x78, 0x72, - 0x78, 0x71, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x7a, 0x71, - 0x7a, 0x71, 0x7b, 0x73, 0x7b, 0x73, 0x7a, 0x72, 0x7a, 0x73, 0x7c, 0x7b, - 0x7f, 0x7f, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, - 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x54, 0x5f, 0x49, 0x5b, - 0x48, 0x59, 0x4c, 0x52, 0x4e, 0x51, 0x50, 0x50, 0x51, 0x51, 0x52, 0x52, - 0x53, 0x51, 0x54, 0x50, 0x55, 0x50, 0x55, 0x53, 0x55, 0x58, 0x54, 0x59, - 0x54, 0x59, 0x53, 0x5b, 0x52, 0x60, 0x57, 0x64, 0x62, 0x65, 0x64, 0x67, - 0x61, 0x6a, 0x5f, 0x6d, 0x5c, 0x70, 0x58, 0x72, 0x55, 0x72, 0x52, 0x71, - 0x4f, 0x70, 0x4b, 0x70, 0x4c, 0x70, 0x4f, 0x70, 0x54, 0x73, 0x58, 0x75, - 0x58, 0x76, 0x58, 0x75, 0x58, 0x73, 0x55, 0x72, 0x50, 0x70, 0x4d, 0x6f, - 0x4b, 0x6f, 0x48, 0x6e, 0x46, 0x6e, 0x46, 0x6d, 0x47, 0x6d, 0x44, 0x6d, - 0x3f, 0x6d, 0x3c, 0x6b, 0x3c, 0x66, 0x3e, 0x63, 0x40, 0x60, 0x41, 0x5f, - 0x41, 0x62, 0x40, 0x66, 0x40, 0x69, 0x40, 0x6a, 0x40, 0x6a, 0x40, 0x69, - 0x40, 0x66, 0x40, 0x66, 0x3d, 0x66, 0x3d, 0x66, 0x43, 0x68, 0x49, 0x69, - 0x4b, 0x6a, 0x4f, 0x6c, 0x53, 0x6e, 0x57, 0x70, 0x5b, 0x72, 0x5d, 0x74, - 0x5f, 0x75, 0x5f, 0x75, 0x5e, 0x75, 0x5d, 0x75, 0x5e, 0x75, 0x5e, 0x75, - 0x5d, 0x74, 0x5c, 0x74, 0x5b, 0x74, 0x5a, 0x74, 0x59, 0x73, 0x58, 0x71, - 0x58, 0x72, 0x57, 0x73, 0x58, 0x75, 0x59, 0x75, 0x5c, 0x75, 0x5e, 0x76, - 0x5f, 0x77, 0x5f, 0x77, 0x62, 0x77, 0x62, 0x77, 0x60, 0x77, 0x5d, 0x77, - 0x5e, 0x76, 0x5b, 0x75, 0x58, 0x75, 0x56, 0x74, 0x54, 0x73, 0x51, 0x73, - 0x52, 0x73, 0x55, 0x73, 0x58, 0x74, 0x59, 0x75, 0x5b, 0x76, 0x5b, 0x77, - 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x58, 0x76, 0x5a, 0x76, 0x5d, 0x76, 0x63, 0x74, 0x69, 0x73, - 0x6f, 0x72, 0x75, 0x72, 0x77, 0x72, 0x77, 0x71, 0x77, 0x71, 0x77, 0x70, - 0x77, 0x6e, 0x77, 0x6e, 0x77, 0x6f, 0x77, 0x70, 0x78, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x78, 0x70, 0x77, 0x71, 0x77, 0x70, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, - 0x78, 0x70, 0x78, 0x70, 0x79, 0x70, 0x7a, 0x71, 0x7a, 0x71, 0x7b, 0x72, - 0x7b, 0x72, 0x7b, 0x72, 0x7a, 0x73, 0x7c, 0x79, 0x7f, 0x7f, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x80, 0x7f, - 0x80, 0x7f, 0x80, 0x7f, 0x4f, 0x5d, 0x48, 0x59, 0x4c, 0x55, 0x50, 0x51, - 0x51, 0x51, 0x54, 0x50, 0x54, 0x54, 0x54, 0x55, 0x55, 0x53, 0x55, 0x52, - 0x55, 0x53, 0x56, 0x56, 0x55, 0x5a, 0x53, 0x5c, 0x54, 0x5c, 0x53, 0x5d, - 0x52, 0x62, 0x54, 0x65, 0x5f, 0x65, 0x64, 0x67, 0x65, 0x6b, 0x63, 0x6b, - 0x60, 0x6d, 0x5b, 0x70, 0x58, 0x70, 0x55, 0x70, 0x51, 0x70, 0x4d, 0x70, - 0x4c, 0x70, 0x4d, 0x70, 0x51, 0x72, 0x55, 0x74, 0x56, 0x74, 0x56, 0x74, - 0x56, 0x72, 0x53, 0x72, 0x4f, 0x6f, 0x4d, 0x6f, 0x4a, 0x6f, 0x49, 0x6f, - 0x46, 0x6e, 0x45, 0x6e, 0x45, 0x6d, 0x41, 0x6d, 0x3d, 0x6c, 0x3b, 0x69, - 0x3d, 0x65, 0x3e, 0x62, 0x40, 0x60, 0x41, 0x61, 0x41, 0x64, 0x40, 0x67, - 0x40, 0x69, 0x40, 0x6a, 0x40, 0x6a, 0x40, 0x69, 0x41, 0x65, 0x40, 0x65, - 0x3e, 0x65, 0x3d, 0x65, 0x42, 0x67, 0x49, 0x69, 0x4b, 0x6a, 0x50, 0x6c, - 0x55, 0x6f, 0x59, 0x71, 0x5c, 0x72, 0x5e, 0x74, 0x60, 0x76, 0x5f, 0x75, - 0x5e, 0x75, 0x5e, 0x75, 0x5d, 0x75, 0x5d, 0x75, 0x5b, 0x74, 0x5a, 0x74, - 0x59, 0x75, 0x58, 0x75, 0x58, 0x74, 0x57, 0x72, 0x58, 0x72, 0x5a, 0x74, - 0x59, 0x75, 0x5a, 0x75, 0x5c, 0x76, 0x5f, 0x76, 0x60, 0x78, 0x5f, 0x77, - 0x62, 0x77, 0x62, 0x77, 0x62, 0x77, 0x5f, 0x77, 0x5f, 0x75, 0x5d, 0x75, - 0x5a, 0x75, 0x58, 0x75, 0x55, 0x73, 0x53, 0x73, 0x52, 0x73, 0x54, 0x72, - 0x57, 0x74, 0x58, 0x75, 0x5b, 0x76, 0x5c, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5a, 0x76, - 0x5c, 0x75, 0x5f, 0x75, 0x65, 0x73, 0x6c, 0x72, 0x71, 0x72, 0x76, 0x72, - 0x77, 0x72, 0x77, 0x71, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, - 0x78, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x70, 0x77, 0x70, - 0x77, 0x71, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, - 0x78, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x79, 0x72, 0x79, 0x72, 0x7a, 0x72, - 0x7a, 0x73, 0x7c, 0x79, 0x80, 0x7f, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, - 0x4d, 0x5c, 0x4a, 0x57, 0x50, 0x53, 0x53, 0x51, 0x54, 0x52, 0x56, 0x50, - 0x56, 0x52, 0x56, 0x53, 0x57, 0x55, 0x56, 0x56, 0x56, 0x55, 0x56, 0x57, - 0x54, 0x5c, 0x53, 0x5f, 0x54, 0x5f, 0x53, 0x5e, 0x52, 0x63, 0x52, 0x66, - 0x5d, 0x67, 0x63, 0x68, 0x67, 0x6a, 0x66, 0x6a, 0x63, 0x6c, 0x5e, 0x6f, - 0x5b, 0x6f, 0x57, 0x70, 0x52, 0x70, 0x4f, 0x70, 0x4d, 0x70, 0x4b, 0x71, - 0x4e, 0x72, 0x53, 0x74, 0x54, 0x73, 0x55, 0x73, 0x54, 0x73, 0x52, 0x72, - 0x50, 0x6f, 0x4e, 0x6f, 0x4b, 0x6f, 0x49, 0x6f, 0x45, 0x6e, 0x43, 0x6e, - 0x43, 0x6d, 0x3e, 0x6c, 0x3b, 0x6b, 0x3b, 0x67, 0x3d, 0x64, 0x3e, 0x62, - 0x40, 0x60, 0x41, 0x63, 0x40, 0x65, 0x41, 0x67, 0x41, 0x69, 0x40, 0x6a, - 0x40, 0x6a, 0x40, 0x69, 0x41, 0x66, 0x41, 0x65, 0x3f, 0x65, 0x3d, 0x65, - 0x41, 0x68, 0x48, 0x6a, 0x4b, 0x6a, 0x51, 0x6c, 0x56, 0x6f, 0x5a, 0x71, - 0x5c, 0x72, 0x5e, 0x74, 0x5f, 0x76, 0x5f, 0x76, 0x5e, 0x75, 0x5e, 0x75, - 0x5c, 0x75, 0x5b, 0x75, 0x59, 0x74, 0x58, 0x75, 0x57, 0x75, 0x57, 0x75, - 0x56, 0x75, 0x56, 0x74, 0x59, 0x74, 0x5c, 0x74, 0x5b, 0x75, 0x5b, 0x75, - 0x5c, 0x75, 0x5e, 0x76, 0x5f, 0x77, 0x60, 0x77, 0x62, 0x77, 0x63, 0x76, - 0x63, 0x77, 0x60, 0x77, 0x61, 0x75, 0x5f, 0x75, 0x5b, 0x75, 0x5a, 0x75, - 0x57, 0x74, 0x55, 0x73, 0x53, 0x73, 0x54, 0x72, 0x57, 0x74, 0x59, 0x75, - 0x5b, 0x76, 0x5c, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x76, 0x5e, 0x75, 0x61, 0x75, - 0x67, 0x74, 0x6d, 0x72, 0x73, 0x72, 0x77, 0x72, 0x77, 0x72, 0x77, 0x71, - 0x77, 0x70, 0x77, 0x71, 0x77, 0x71, 0x77, 0x71, 0x77, 0x6e, 0x77, 0x6e, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x70, 0x77, 0x70, 0x77, 0x71, 0x78, 0x70, - 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x7a, 0x71, - 0x7a, 0x70, 0x78, 0x72, 0x78, 0x72, 0x7a, 0x72, 0x7a, 0x73, 0x7c, 0x78, - 0x80, 0x7f, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x4d, 0x5a, 0x51, 0x53, - 0x55, 0x52, 0x56, 0x53, 0x57, 0x53, 0x58, 0x52, 0x58, 0x52, 0x58, 0x53, - 0x57, 0x56, 0x57, 0x57, 0x56, 0x59, 0x55, 0x5c, 0x54, 0x5f, 0x53, 0x62, - 0x53, 0x61, 0x52, 0x62, 0x51, 0x63, 0x51, 0x67, 0x5b, 0x68, 0x62, 0x6a, - 0x67, 0x6b, 0x69, 0x6a, 0x66, 0x6b, 0x62, 0x6f, 0x5f, 0x6f, 0x5b, 0x6f, - 0x57, 0x6f, 0x53, 0x70, 0x4f, 0x71, 0x4b, 0x71, 0x4c, 0x72, 0x50, 0x72, - 0x53, 0x73, 0x53, 0x73, 0x52, 0x72, 0x50, 0x72, 0x4f, 0x70, 0x4d, 0x70, - 0x4a, 0x6f, 0x49, 0x6f, 0x46, 0x6e, 0x42, 0x6d, 0x41, 0x6e, 0x3c, 0x6c, - 0x3b, 0x6a, 0x3b, 0x66, 0x3e, 0x63, 0x40, 0x62, 0x41, 0x62, 0x40, 0x63, - 0x3f, 0x67, 0x3f, 0x6a, 0x40, 0x6a, 0x41, 0x6b, 0x3f, 0x6a, 0x40, 0x69, - 0x42, 0x66, 0x41, 0x65, 0x3f, 0x65, 0x3d, 0x66, 0x41, 0x69, 0x49, 0x69, - 0x4b, 0x6a, 0x50, 0x6d, 0x57, 0x70, 0x5a, 0x72, 0x5c, 0x75, 0x5d, 0x74, - 0x5e, 0x76, 0x5e, 0x76, 0x5e, 0x74, 0x5c, 0x73, 0x58, 0x73, 0x55, 0x71, - 0x55, 0x71, 0x57, 0x73, 0x57, 0x75, 0x57, 0x75, 0x57, 0x77, 0x59, 0x77, - 0x5a, 0x76, 0x5b, 0x75, 0x5c, 0x74, 0x5c, 0x75, 0x5c, 0x76, 0x5c, 0x76, - 0x5e, 0x77, 0x5f, 0x77, 0x60, 0x78, 0x61, 0x78, 0x62, 0x78, 0x62, 0x77, - 0x60, 0x76, 0x5d, 0x77, 0x5b, 0x75, 0x59, 0x75, 0x58, 0x75, 0x56, 0x74, - 0x54, 0x74, 0x54, 0x74, 0x57, 0x75, 0x58, 0x75, 0x5a, 0x77, 0x5b, 0x78, - 0x5b, 0x77, 0x5c, 0x78, 0x5c, 0x78, 0x5b, 0x78, 0x5b, 0x78, 0x5c, 0x77, - 0x5c, 0x78, 0x5c, 0x77, 0x60, 0x75, 0x63, 0x74, 0x6a, 0x74, 0x70, 0x73, - 0x74, 0x73, 0x77, 0x73, 0x77, 0x72, 0x77, 0x71, 0x77, 0x71, 0x77, 0x71, - 0x78, 0x71, 0x77, 0x71, 0x77, 0x70, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x70, - 0x78, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x72, - 0x78, 0x72, 0x78, 0x70, 0x78, 0x70, 0x78, 0x72, 0x79, 0x71, 0x78, 0x72, - 0x78, 0x72, 0x79, 0x72, 0x79, 0x74, 0x7a, 0x78, 0x7f, 0x7f, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x50, 0x58, 0x56, 0x51, 0x58, 0x52, 0x58, 0x53, - 0x58, 0x53, 0x59, 0x52, 0x59, 0x52, 0x58, 0x55, 0x57, 0x58, 0x57, 0x5a, - 0x55, 0x5c, 0x54, 0x5e, 0x54, 0x60, 0x53, 0x62, 0x53, 0x63, 0x51, 0x63, - 0x51, 0x63, 0x50, 0x66, 0x58, 0x67, 0x5f, 0x69, 0x64, 0x6a, 0x68, 0x69, - 0x67, 0x6b, 0x65, 0x6e, 0x62, 0x6e, 0x5e, 0x6f, 0x5b, 0x6f, 0x56, 0x70, - 0x51, 0x71, 0x4d, 0x70, 0x4c, 0x72, 0x4e, 0x72, 0x50, 0x73, 0x50, 0x72, - 0x4f, 0x72, 0x4d, 0x72, 0x4d, 0x71, 0x4b, 0x70, 0x4a, 0x70, 0x48, 0x6f, - 0x46, 0x6e, 0x42, 0x6e, 0x3f, 0x6d, 0x3c, 0x6b, 0x3a, 0x68, 0x3c, 0x66, - 0x3f, 0x63, 0x41, 0x62, 0x41, 0x62, 0x40, 0x64, 0x3f, 0x69, 0x3f, 0x6c, - 0x41, 0x6b, 0x41, 0x6c, 0x3f, 0x6a, 0x40, 0x6a, 0x42, 0x66, 0x42, 0x65, - 0x40, 0x65, 0x3e, 0x66, 0x40, 0x69, 0x48, 0x69, 0x4b, 0x6b, 0x51, 0x6d, - 0x57, 0x70, 0x5a, 0x72, 0x5c, 0x75, 0x5d, 0x75, 0x5e, 0x76, 0x5e, 0x75, - 0x5c, 0x73, 0x58, 0x72, 0x55, 0x70, 0x56, 0x6e, 0x59, 0x70, 0x5a, 0x72, - 0x59, 0x72, 0x56, 0x73, 0x58, 0x76, 0x5b, 0x76, 0x59, 0x76, 0x58, 0x76, - 0x5a, 0x76, 0x5e, 0x77, 0x61, 0x78, 0x61, 0x77, 0x61, 0x78, 0x60, 0x78, - 0x61, 0x78, 0x61, 0x78, 0x62, 0x78, 0x62, 0x78, 0x5e, 0x77, 0x5d, 0x77, - 0x5b, 0x75, 0x5a, 0x75, 0x58, 0x75, 0x56, 0x75, 0x55, 0x75, 0x55, 0x74, - 0x57, 0x75, 0x58, 0x75, 0x59, 0x77, 0x5a, 0x78, 0x5a, 0x78, 0x5b, 0x78, - 0x5b, 0x78, 0x5b, 0x78, 0x5b, 0x78, 0x5d, 0x78, 0x5d, 0x78, 0x5d, 0x77, - 0x62, 0x74, 0x65, 0x74, 0x6d, 0x75, 0x72, 0x74, 0x75, 0x73, 0x77, 0x73, - 0x77, 0x72, 0x77, 0x71, 0x77, 0x71, 0x77, 0x71, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x70, 0x77, 0x71, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x70, 0x77, 0x71, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x73, 0x77, 0x72, 0x78, 0x70, - 0x78, 0x70, 0x78, 0x72, 0x78, 0x72, 0x78, 0x72, 0x78, 0x72, 0x78, 0x72, - 0x77, 0x74, 0x79, 0x78, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, - 0x56, 0x55, 0x58, 0x52, 0x59, 0x51, 0x5a, 0x51, 0x5a, 0x52, 0x5a, 0x53, - 0x5a, 0x54, 0x59, 0x57, 0x57, 0x5b, 0x57, 0x5d, 0x56, 0x5e, 0x55, 0x5d, - 0x54, 0x60, 0x53, 0x64, 0x52, 0x63, 0x51, 0x63, 0x51, 0x63, 0x4f, 0x66, - 0x53, 0x67, 0x5b, 0x69, 0x61, 0x6a, 0x65, 0x69, 0x67, 0x6b, 0x68, 0x6d, - 0x66, 0x6d, 0x61, 0x6e, 0x5e, 0x6f, 0x5a, 0x70, 0x55, 0x71, 0x51, 0x70, - 0x4d, 0x72, 0x4b, 0x72, 0x4c, 0x71, 0x4e, 0x71, 0x4e, 0x72, 0x4c, 0x72, - 0x4b, 0x70, 0x49, 0x70, 0x48, 0x6f, 0x46, 0x70, 0x45, 0x6f, 0x40, 0x6e, - 0x3c, 0x6d, 0x3a, 0x69, 0x3b, 0x66, 0x3c, 0x63, 0x3f, 0x62, 0x40, 0x62, - 0x40, 0x62, 0x3f, 0x65, 0x3f, 0x6a, 0x41, 0x6d, 0x43, 0x6d, 0x41, 0x6c, - 0x3e, 0x6a, 0x40, 0x69, 0x42, 0x66, 0x42, 0x65, 0x40, 0x65, 0x3e, 0x66, - 0x3f, 0x68, 0x46, 0x69, 0x4b, 0x6b, 0x51, 0x6d, 0x57, 0x70, 0x5a, 0x72, - 0x5b, 0x74, 0x5d, 0x75, 0x5e, 0x76, 0x5e, 0x75, 0x5a, 0x73, 0x56, 0x72, - 0x57, 0x70, 0x59, 0x72, 0x5b, 0x72, 0x5a, 0x70, 0x57, 0x6f, 0x55, 0x70, - 0x56, 0x73, 0x59, 0x75, 0x5a, 0x74, 0x60, 0x77, 0x64, 0x78, 0x67, 0x78, - 0x6a, 0x79, 0x6a, 0x79, 0x67, 0x79, 0x63, 0x79, 0x63, 0x78, 0x63, 0x78, - 0x62, 0x78, 0x63, 0x78, 0x68, 0x77, 0x62, 0x77, 0x59, 0x75, 0x59, 0x75, - 0x5a, 0x75, 0x56, 0x75, 0x57, 0x74, 0x57, 0x75, 0x58, 0x75, 0x58, 0x76, - 0x59, 0x77, 0x5a, 0x77, 0x5b, 0x77, 0x5b, 0x78, 0x5b, 0x78, 0x5b, 0x78, - 0x5b, 0x78, 0x5d, 0x78, 0x5c, 0x78, 0x5d, 0x77, 0x63, 0x74, 0x68, 0x74, - 0x70, 0x74, 0x75, 0x73, 0x77, 0x73, 0x78, 0x73, 0x77, 0x72, 0x77, 0x71, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x70, 0x78, 0x71, 0x77, 0x70, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x70, 0x77, 0x72, 0x77, 0x71, 0x78, 0x70, 0x78, 0x71, 0x78, 0x72, - 0x78, 0x72, 0x78, 0x72, 0x78, 0x72, 0x76, 0x72, 0x76, 0x75, 0x79, 0x78, - 0x7f, 0x7f, 0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, - 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x58, 0x53, 0x59, 0x53, - 0x5a, 0x52, 0x5a, 0x54, 0x5a, 0x54, 0x5a, 0x54, 0x5a, 0x54, 0x59, 0x59, - 0x58, 0x5a, 0x57, 0x5d, 0x55, 0x5f, 0x54, 0x5f, 0x53, 0x62, 0x51, 0x65, - 0x51, 0x65, 0x50, 0x65, 0x50, 0x65, 0x4e, 0x66, 0x4f, 0x68, 0x55, 0x69, - 0x5f, 0x69, 0x64, 0x6a, 0x68, 0x6a, 0x6c, 0x6c, 0x69, 0x6d, 0x66, 0x6e, - 0x63, 0x6e, 0x5d, 0x6e, 0x58, 0x6e, 0x54, 0x6f, 0x50, 0x71, 0x4a, 0x71, - 0x4a, 0x70, 0x4c, 0x70, 0x4c, 0x70, 0x4a, 0x70, 0x48, 0x6f, 0x47, 0x70, - 0x45, 0x6f, 0x43, 0x6e, 0x3f, 0x6e, 0x3c, 0x6e, 0x3a, 0x6c, 0x3a, 0x69, - 0x3b, 0x66, 0x3d, 0x62, 0x3f, 0x60, 0x40, 0x61, 0x40, 0x63, 0x3e, 0x66, - 0x3d, 0x6a, 0x41, 0x6e, 0x44, 0x6e, 0x42, 0x6e, 0x3e, 0x6b, 0x41, 0x69, - 0x42, 0x66, 0x42, 0x65, 0x41, 0x65, 0x3f, 0x65, 0x3e, 0x68, 0x43, 0x6a, - 0x4a, 0x6a, 0x51, 0x6d, 0x55, 0x6f, 0x59, 0x72, 0x5d, 0x74, 0x5d, 0x74, - 0x60, 0x76, 0x5b, 0x74, 0x55, 0x74, 0x55, 0x73, 0x58, 0x72, 0x59, 0x74, - 0x57, 0x72, 0x55, 0x6f, 0x55, 0x6d, 0x54, 0x6f, 0x55, 0x71, 0x5b, 0x71, - 0x64, 0x72, 0x74, 0x75, 0x75, 0x76, 0x74, 0x77, 0x72, 0x78, 0x6e, 0x78, - 0x6a, 0x79, 0x65, 0x79, 0x63, 0x77, 0x62, 0x76, 0x62, 0x76, 0x70, 0x75, - 0x7f, 0x74, 0x6e, 0x74, 0x5c, 0x79, 0x5b, 0x79, 0x5a, 0x75, 0x59, 0x75, - 0x58, 0x75, 0x57, 0x75, 0x57, 0x76, 0x58, 0x76, 0x59, 0x77, 0x5b, 0x78, - 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5c, 0x79, 0x5d, 0x78, 0x5c, 0x78, - 0x5e, 0x78, 0x60, 0x77, 0x66, 0x76, 0x6b, 0x75, 0x73, 0x75, 0x77, 0x74, - 0x78, 0x73, 0x77, 0x73, 0x77, 0x73, 0x77, 0x72, 0x77, 0x72, 0x77, 0x72, - 0x77, 0x72, 0x77, 0x72, 0x77, 0x71, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x70, - 0x76, 0x70, 0x76, 0x71, 0x76, 0x70, 0x76, 0x70, 0x76, 0x70, 0x76, 0x70, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x71, - 0x78, 0x71, 0x77, 0x71, 0x78, 0x72, 0x78, 0x72, 0x78, 0x72, 0x78, 0x73, - 0x78, 0x73, 0x76, 0x72, 0x76, 0x75, 0x79, 0x78, 0x7f, 0x7e, 0x7f, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, - 0x80, 0x80, 0x7f, 0x80, 0x58, 0x54, 0x58, 0x54, 0x59, 0x53, 0x59, 0x56, - 0x59, 0x55, 0x59, 0x54, 0x59, 0x53, 0x59, 0x59, 0x58, 0x59, 0x56, 0x5c, - 0x54, 0x5f, 0x54, 0x60, 0x52, 0x62, 0x50, 0x65, 0x50, 0x65, 0x4f, 0x66, - 0x4f, 0x66, 0x4e, 0x65, 0x4e, 0x68, 0x51, 0x68, 0x5d, 0x68, 0x62, 0x6a, - 0x66, 0x6a, 0x6b, 0x6b, 0x6a, 0x6d, 0x68, 0x6e, 0x66, 0x6e, 0x61, 0x6d, - 0x5b, 0x6d, 0x57, 0x6e, 0x53, 0x70, 0x4c, 0x70, 0x49, 0x70, 0x4a, 0x6f, - 0x4a, 0x6f, 0x47, 0x6f, 0x46, 0x6f, 0x44, 0x6f, 0x42, 0x6e, 0x40, 0x6d, - 0x3b, 0x6c, 0x3a, 0x6c, 0x39, 0x6b, 0x3a, 0x69, 0x3b, 0x66, 0x3d, 0x62, - 0x40, 0x5f, 0x41, 0x60, 0x40, 0x64, 0x3e, 0x67, 0x3e, 0x69, 0x42, 0x6e, - 0x44, 0x6e, 0x42, 0x6f, 0x3f, 0x6b, 0x41, 0x68, 0x43, 0x64, 0x43, 0x64, - 0x41, 0x64, 0x40, 0x65, 0x3e, 0x68, 0x42, 0x6a, 0x49, 0x6a, 0x50, 0x6d, - 0x55, 0x70, 0x59, 0x72, 0x5c, 0x75, 0x5c, 0x75, 0x5f, 0x75, 0x58, 0x73, - 0x51, 0x74, 0x54, 0x74, 0x58, 0x72, 0x56, 0x72, 0x54, 0x71, 0x54, 0x6f, - 0x54, 0x6e, 0x53, 0x6f, 0x5b, 0x71, 0x6a, 0x72, 0x75, 0x73, 0x7f, 0x75, - 0x7b, 0x74, 0x77, 0x75, 0x74, 0x76, 0x6f, 0x76, 0x6b, 0x78, 0x66, 0x78, - 0x63, 0x76, 0x67, 0x74, 0x6b, 0x73, 0x7e, 0x76, 0x85, 0x76, 0x70, 0x79, - 0x61, 0x7d, 0x5e, 0x7c, 0x5a, 0x75, 0x5b, 0x76, 0x59, 0x75, 0x57, 0x75, - 0x58, 0x76, 0x58, 0x77, 0x5a, 0x78, 0x5c, 0x78, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x5d, 0x79, 0x5d, 0x79, 0x5d, 0x78, 0x5f, 0x78, 0x62, 0x77, - 0x69, 0x78, 0x6d, 0x76, 0x74, 0x75, 0x77, 0x74, 0x77, 0x73, 0x77, 0x73, - 0x77, 0x73, 0x77, 0x73, 0x77, 0x73, 0x77, 0x74, 0x77, 0x72, 0x77, 0x72, - 0x77, 0x71, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x75, 0x71, 0x75, 0x70, - 0x75, 0x70, 0x75, 0x70, 0x75, 0x70, 0x75, 0x70, 0x76, 0x70, 0x77, 0x70, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x71, 0x77, 0x72, - 0x77, 0x72, 0x78, 0x72, 0x78, 0x72, 0x78, 0x73, 0x78, 0x74, 0x78, 0x72, - 0x77, 0x75, 0x7a, 0x78, 0x7e, 0x7e, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x80, - 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x7f, 0x80, - 0x58, 0x53, 0x58, 0x53, 0x58, 0x53, 0x57, 0x56, 0x57, 0x55, 0x57, 0x54, - 0x57, 0x54, 0x57, 0x58, 0x56, 0x5a, 0x54, 0x5d, 0x53, 0x5f, 0x52, 0x60, - 0x51, 0x62, 0x50, 0x65, 0x50, 0x65, 0x4f, 0x66, 0x4e, 0x66, 0x4e, 0x65, - 0x4e, 0x69, 0x4e, 0x68, 0x57, 0x68, 0x5e, 0x6a, 0x61, 0x6a, 0x67, 0x6a, - 0x6a, 0x6b, 0x6a, 0x6d, 0x69, 0x6e, 0x67, 0x6e, 0x61, 0x6e, 0x5d, 0x6e, - 0x57, 0x6e, 0x50, 0x6e, 0x4a, 0x6e, 0x45, 0x6e, 0x43, 0x6f, 0x41, 0x6f, - 0x41, 0x6d, 0x3f, 0x6d, 0x3e, 0x6c, 0x3c, 0x6b, 0x39, 0x6a, 0x39, 0x6a, - 0x38, 0x6a, 0x39, 0x68, 0x3b, 0x65, 0x3d, 0x62, 0x40, 0x5f, 0x41, 0x5f, - 0x40, 0x65, 0x3e, 0x69, 0x42, 0x6c, 0x47, 0x6e, 0x45, 0x6e, 0x41, 0x6e, - 0x3e, 0x6c, 0x40, 0x68, 0x42, 0x64, 0x43, 0x64, 0x42, 0x65, 0x41, 0x65, - 0x3e, 0x68, 0x41, 0x6a, 0x46, 0x6a, 0x4f, 0x6d, 0x55, 0x6f, 0x59, 0x71, - 0x5a, 0x75, 0x5a, 0x75, 0x5b, 0x73, 0x54, 0x71, 0x4e, 0x73, 0x54, 0x74, - 0x56, 0x72, 0x53, 0x73, 0x52, 0x73, 0x53, 0x71, 0x53, 0x6f, 0x55, 0x6f, - 0x5f, 0x72, 0x6a, 0x74, 0x6d, 0x75, 0x73, 0x76, 0x76, 0x75, 0x7a, 0x75, - 0x79, 0x74, 0x73, 0x75, 0x6c, 0x76, 0x68, 0x76, 0x67, 0x76, 0x72, 0x73, - 0x7e, 0x74, 0x83, 0x78, 0x79, 0x7d, 0x67, 0x81, 0x5e, 0x81, 0x61, 0x7f, - 0x5e, 0x77, 0x5a, 0x76, 0x5a, 0x76, 0x59, 0x75, 0x5a, 0x77, 0x5b, 0x78, - 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5d, 0x78, - 0x5d, 0x78, 0x5f, 0x78, 0x61, 0x78, 0x64, 0x78, 0x6a, 0x78, 0x6f, 0x77, - 0x75, 0x75, 0x78, 0x74, 0x77, 0x73, 0x77, 0x73, 0x77, 0x73, 0x77, 0x73, - 0x77, 0x73, 0x77, 0x73, 0x77, 0x72, 0x77, 0x72, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x70, 0x77, 0x70, 0x75, 0x70, 0x75, 0x70, 0x76, 0x71, 0x75, 0x71, - 0x75, 0x71, 0x75, 0x70, 0x76, 0x71, 0x77, 0x71, 0x77, 0x71, 0x77, 0x70, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x71, 0x77, 0x72, 0x77, 0x72, 0x78, 0x72, - 0x78, 0x72, 0x78, 0x72, 0x78, 0x73, 0x79, 0x73, 0x79, 0x74, 0x7a, 0x77, - 0x7e, 0x7e, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x57, 0x53, 0x57, 0x53, - 0x58, 0x52, 0x57, 0x55, 0x56, 0x54, 0x57, 0x55, 0x56, 0x54, 0x55, 0x58, - 0x54, 0x5a, 0x54, 0x5b, 0x52, 0x5d, 0x51, 0x5e, 0x50, 0x61, 0x50, 0x63, - 0x50, 0x64, 0x4e, 0x66, 0x4e, 0x66, 0x4d, 0x65, 0x4d, 0x68, 0x4d, 0x68, - 0x52, 0x69, 0x59, 0x69, 0x5e, 0x69, 0x65, 0x68, 0x69, 0x69, 0x6b, 0x6c, - 0x6b, 0x6e, 0x6b, 0x6e, 0x66, 0x6e, 0x62, 0x6d, 0x5b, 0x6c, 0x54, 0x6c, - 0x4b, 0x6c, 0x42, 0x6d, 0x40, 0x6f, 0x3e, 0x6f, 0x3e, 0x6c, 0x3d, 0x6c, - 0x3b, 0x6a, 0x3a, 0x6a, 0x39, 0x69, 0x39, 0x69, 0x38, 0x67, 0x3a, 0x65, - 0x3b, 0x64, 0x3e, 0x62, 0x40, 0x60, 0x40, 0x60, 0x3f, 0x66, 0x3e, 0x6b, - 0x43, 0x6d, 0x48, 0x6e, 0x47, 0x6d, 0x42, 0x6e, 0x3e, 0x6b, 0x40, 0x68, - 0x43, 0x64, 0x43, 0x64, 0x42, 0x65, 0x40, 0x65, 0x3e, 0x67, 0x40, 0x69, - 0x45, 0x6a, 0x4f, 0x6c, 0x55, 0x6f, 0x58, 0x71, 0x59, 0x74, 0x59, 0x74, - 0x58, 0x71, 0x51, 0x70, 0x4d, 0x72, 0x54, 0x74, 0x55, 0x73, 0x54, 0x73, - 0x53, 0x74, 0x53, 0x71, 0x54, 0x6e, 0x59, 0x6f, 0x63, 0x72, 0x67, 0x74, - 0x65, 0x76, 0x65, 0x77, 0x70, 0x75, 0x79, 0x74, 0x7a, 0x73, 0x77, 0x74, - 0x70, 0x74, 0x6b, 0x75, 0x6c, 0x77, 0x75, 0x75, 0x84, 0x77, 0x7c, 0x78, - 0x6e, 0x7e, 0x5f, 0x81, 0x5b, 0x83, 0x6b, 0x82, 0x68, 0x7a, 0x5a, 0x75, - 0x5b, 0x76, 0x5b, 0x76, 0x5c, 0x76, 0x5c, 0x77, 0x5b, 0x77, 0x5b, 0x77, - 0x5b, 0x77, 0x5c, 0x77, 0x5c, 0x77, 0x5d, 0x78, 0x5e, 0x78, 0x60, 0x78, - 0x63, 0x78, 0x66, 0x77, 0x6c, 0x76, 0x71, 0x75, 0x76, 0x75, 0x78, 0x74, - 0x78, 0x73, 0x77, 0x73, 0x77, 0x72, 0x77, 0x73, 0x77, 0x73, 0x77, 0x73, - 0x77, 0x72, 0x77, 0x71, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, - 0x76, 0x70, 0x76, 0x70, 0x76, 0x6f, 0x76, 0x6f, 0x76, 0x70, 0x76, 0x70, - 0x77, 0x70, 0x78, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x6f, - 0x77, 0x70, 0x77, 0x71, 0x78, 0x71, 0x78, 0x71, 0x78, 0x71, 0x79, 0x71, - 0x79, 0x73, 0x7a, 0x74, 0x7a, 0x74, 0x7b, 0x75, 0x7e, 0x7e, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x80, 0x7f, 0x80, 0x7f, 0x56, 0x50, 0x57, 0x50, 0x58, 0x4f, 0x57, 0x51, - 0x57, 0x51, 0x57, 0x52, 0x56, 0x55, 0x55, 0x57, 0x53, 0x59, 0x53, 0x5a, - 0x52, 0x5b, 0x51, 0x5d, 0x50, 0x5f, 0x4f, 0x61, 0x4f, 0x63, 0x4e, 0x66, - 0x4e, 0x66, 0x4d, 0x66, 0x4d, 0x66, 0x4d, 0x67, 0x4f, 0x68, 0x54, 0x68, - 0x5b, 0x68, 0x62, 0x68, 0x65, 0x69, 0x6a, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, - 0x6a, 0x6e, 0x68, 0x6d, 0x61, 0x6d, 0x5a, 0x6c, 0x51, 0x6c, 0x45, 0x6c, - 0x3e, 0x6d, 0x3b, 0x6e, 0x3c, 0x6c, 0x3c, 0x6a, 0x3b, 0x69, 0x3b, 0x69, - 0x3b, 0x68, 0x3a, 0x67, 0x3a, 0x65, 0x3b, 0x63, 0x3c, 0x63, 0x3e, 0x62, - 0x40, 0x61, 0x3f, 0x62, 0x3f, 0x68, 0x3f, 0x6b, 0x43, 0x6d, 0x48, 0x6e, - 0x49, 0x6e, 0x42, 0x6c, 0x3e, 0x6a, 0x40, 0x67, 0x43, 0x64, 0x44, 0x65, - 0x43, 0x65, 0x41, 0x64, 0x3f, 0x65, 0x3e, 0x67, 0x44, 0x68, 0x4e, 0x6b, - 0x54, 0x6e, 0x57, 0x70, 0x58, 0x72, 0x58, 0x72, 0x57, 0x70, 0x4f, 0x70, - 0x4d, 0x71, 0x54, 0x75, 0x55, 0x75, 0x5a, 0x72, 0x58, 0x72, 0x51, 0x70, - 0x58, 0x72, 0x70, 0x74, 0x6e, 0x74, 0x69, 0x77, 0x66, 0x79, 0x63, 0x78, - 0x67, 0x75, 0x6e, 0x73, 0x76, 0x73, 0x7e, 0x73, 0x78, 0x74, 0x6c, 0x76, - 0x6a, 0x76, 0x73, 0x75, 0x7e, 0x75, 0x74, 0x7d, 0x67, 0x80, 0x5d, 0x7e, - 0x63, 0x83, 0x78, 0x81, 0x6f, 0x7b, 0x5a, 0x75, 0x5b, 0x77, 0x5d, 0x78, - 0x5c, 0x76, 0x5b, 0x75, 0x5b, 0x76, 0x5b, 0x77, 0x5c, 0x77, 0x5d, 0x77, - 0x5d, 0x77, 0x5d, 0x78, 0x5f, 0x78, 0x61, 0x78, 0x66, 0x77, 0x69, 0x77, - 0x6e, 0x74, 0x74, 0x74, 0x77, 0x74, 0x78, 0x73, 0x78, 0x73, 0x78, 0x72, - 0x78, 0x72, 0x77, 0x72, 0x77, 0x72, 0x77, 0x72, 0x78, 0x70, 0x78, 0x70, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x71, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6d, 0x77, 0x6e, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, - 0x78, 0x6f, 0x78, 0x70, 0x78, 0x70, 0x7a, 0x70, 0x7a, 0x72, 0x7a, 0x73, - 0x7a, 0x73, 0x7b, 0x74, 0x7e, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x80, - 0x57, 0x4f, 0x57, 0x4f, 0x57, 0x4e, 0x57, 0x4f, 0x56, 0x50, 0x56, 0x53, - 0x55, 0x55, 0x54, 0x57, 0x53, 0x5a, 0x53, 0x5a, 0x52, 0x5b, 0x51, 0x5d, - 0x50, 0x5f, 0x4f, 0x62, 0x4f, 0x63, 0x4e, 0x63, 0x4d, 0x63, 0x4d, 0x65, - 0x4d, 0x66, 0x4d, 0x65, 0x4d, 0x66, 0x4f, 0x68, 0x54, 0x68, 0x5d, 0x69, - 0x62, 0x6a, 0x68, 0x6d, 0x6c, 0x6c, 0x6f, 0x6d, 0x6e, 0x6e, 0x6c, 0x6d, - 0x67, 0x6d, 0x61, 0x6d, 0x59, 0x6a, 0x4c, 0x6a, 0x3f, 0x6b, 0x3a, 0x6b, - 0x3c, 0x6a, 0x3c, 0x68, 0x3d, 0x68, 0x3d, 0x68, 0x3c, 0x66, 0x3b, 0x65, - 0x3b, 0x64, 0x3b, 0x63, 0x3c, 0x63, 0x3f, 0x61, 0x40, 0x62, 0x3f, 0x64, - 0x3e, 0x69, 0x40, 0x6b, 0x45, 0x6e, 0x48, 0x6e, 0x48, 0x6e, 0x41, 0x6c, - 0x3f, 0x69, 0x41, 0x68, 0x43, 0x64, 0x43, 0x64, 0x43, 0x65, 0x42, 0x64, - 0x40, 0x65, 0x3e, 0x68, 0x41, 0x68, 0x49, 0x6b, 0x52, 0x6e, 0x56, 0x70, - 0x56, 0x72, 0x57, 0x72, 0x55, 0x70, 0x4d, 0x70, 0x4e, 0x71, 0x53, 0x74, - 0x56, 0x75, 0x5d, 0x73, 0x51, 0x6f, 0x47, 0x74, 0x63, 0x7d, 0x74, 0x7f, - 0x69, 0x7c, 0x5f, 0x7d, 0x5f, 0x7c, 0x65, 0x79, 0x61, 0x77, 0x63, 0x74, - 0x72, 0x73, 0x7d, 0x73, 0x7b, 0x74, 0x71, 0x76, 0x6d, 0x76, 0x6d, 0x73, - 0x6f, 0x75, 0x69, 0x80, 0x61, 0x7e, 0x61, 0x7b, 0x77, 0x7f, 0x84, 0x80, - 0x6f, 0x7b, 0x5c, 0x75, 0x5c, 0x77, 0x5d, 0x78, 0x5c, 0x77, 0x5b, 0x75, - 0x5b, 0x76, 0x5c, 0x77, 0x5c, 0x77, 0x5d, 0x77, 0x5d, 0x77, 0x5f, 0x78, - 0x61, 0x78, 0x63, 0x77, 0x67, 0x78, 0x6c, 0x77, 0x72, 0x74, 0x76, 0x74, - 0x77, 0x75, 0x78, 0x73, 0x78, 0x73, 0x78, 0x72, 0x78, 0x72, 0x77, 0x72, - 0x77, 0x72, 0x77, 0x72, 0x78, 0x70, 0x78, 0x70, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x71, 0x78, 0x71, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6e, 0x77, 0x6e, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x70, - 0x78, 0x70, 0x7a, 0x70, 0x7a, 0x71, 0x7a, 0x71, 0x7a, 0x71, 0x7b, 0x73, - 0x7f, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, - 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x56, 0x52, 0x56, 0x52, - 0x57, 0x51, 0x56, 0x53, 0x55, 0x54, 0x55, 0x56, 0x54, 0x57, 0x53, 0x57, - 0x53, 0x5a, 0x53, 0x5b, 0x52, 0x5b, 0x50, 0x5e, 0x50, 0x60, 0x4f, 0x61, - 0x4e, 0x63, 0x4d, 0x63, 0x4d, 0x63, 0x4d, 0x66, 0x4d, 0x66, 0x4c, 0x65, - 0x4d, 0x65, 0x4e, 0x67, 0x51, 0x68, 0x5a, 0x68, 0x5f, 0x6a, 0x66, 0x6b, - 0x6b, 0x6c, 0x6f, 0x6d, 0x71, 0x6e, 0x6f, 0x6d, 0x6b, 0x6d, 0x64, 0x6d, - 0x5d, 0x6a, 0x50, 0x69, 0x42, 0x6a, 0x3b, 0x6a, 0x3c, 0x69, 0x3c, 0x67, - 0x3e, 0x67, 0x3e, 0x67, 0x3d, 0x65, 0x3d, 0x64, 0x3c, 0x63, 0x3b, 0x63, - 0x3c, 0x63, 0x3e, 0x62, 0x3f, 0x63, 0x3e, 0x65, 0x3f, 0x6a, 0x42, 0x6b, - 0x46, 0x6d, 0x49, 0x6e, 0x48, 0x6e, 0x41, 0x6c, 0x3f, 0x69, 0x41, 0x68, - 0x44, 0x65, 0x44, 0x64, 0x43, 0x65, 0x42, 0x64, 0x40, 0x65, 0x3e, 0x67, - 0x3f, 0x69, 0x46, 0x6c, 0x50, 0x6f, 0x54, 0x71, 0x55, 0x72, 0x56, 0x72, - 0x53, 0x71, 0x4c, 0x70, 0x4f, 0x72, 0x53, 0x75, 0x54, 0x75, 0x59, 0x72, - 0x45, 0x71, 0x47, 0x7b, 0x66, 0x83, 0x62, 0x87, 0x62, 0x87, 0x5d, 0x7f, - 0x59, 0x7d, 0x63, 0x7b, 0x61, 0x79, 0x62, 0x77, 0x70, 0x73, 0x76, 0x73, - 0x78, 0x74, 0x75, 0x76, 0x74, 0x76, 0x6b, 0x75, 0x66, 0x76, 0x62, 0x7b, - 0x61, 0x7c, 0x68, 0x7a, 0x77, 0x7d, 0x74, 0x80, 0x66, 0x7c, 0x5d, 0x75, - 0x5d, 0x77, 0x5d, 0x78, 0x5c, 0x77, 0x5c, 0x75, 0x5b, 0x76, 0x5b, 0x77, - 0x5c, 0x78, 0x5d, 0x77, 0x5d, 0x77, 0x60, 0x78, 0x62, 0x78, 0x64, 0x77, - 0x68, 0x77, 0x6f, 0x77, 0x75, 0x75, 0x77, 0x74, 0x77, 0x75, 0x78, 0x74, - 0x78, 0x73, 0x78, 0x72, 0x78, 0x72, 0x77, 0x72, 0x77, 0x72, 0x77, 0x72, - 0x78, 0x70, 0x78, 0x70, 0x77, 0x70, 0x77, 0x71, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6e, 0x77, 0x6e, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, - 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x71, 0x78, 0x71, 0x7a, 0x70, - 0x7b, 0x71, 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x72, 0x7f, 0x7d, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x80, - 0x80, 0x7f, 0x80, 0x80, 0x53, 0x55, 0x53, 0x54, 0x55, 0x51, 0x54, 0x56, - 0x54, 0x56, 0x54, 0x56, 0x53, 0x59, 0x53, 0x59, 0x52, 0x5a, 0x52, 0x5c, - 0x51, 0x5d, 0x4f, 0x5f, 0x4f, 0x60, 0x4f, 0x61, 0x4e, 0x63, 0x4d, 0x65, - 0x4c, 0x65, 0x4c, 0x66, 0x4c, 0x65, 0x4c, 0x66, 0x4d, 0x67, 0x4e, 0x67, - 0x4f, 0x67, 0x54, 0x68, 0x5b, 0x68, 0x63, 0x69, 0x68, 0x6b, 0x6e, 0x6d, - 0x72, 0x6f, 0x72, 0x6f, 0x70, 0x6f, 0x68, 0x6c, 0x62, 0x6b, 0x54, 0x68, - 0x48, 0x68, 0x3e, 0x68, 0x3c, 0x68, 0x3c, 0x68, 0x3e, 0x67, 0x3f, 0x65, - 0x3e, 0x64, 0x3d, 0x64, 0x3d, 0x63, 0x3d, 0x63, 0x3d, 0x63, 0x3f, 0x63, - 0x3f, 0x65, 0x3e, 0x68, 0x3e, 0x6b, 0x44, 0x6e, 0x46, 0x6e, 0x4b, 0x6d, - 0x48, 0x6e, 0x40, 0x6b, 0x3f, 0x69, 0x41, 0x68, 0x43, 0x65, 0x44, 0x65, - 0x44, 0x66, 0x43, 0x65, 0x41, 0x65, 0x3f, 0x66, 0x3f, 0x69, 0x46, 0x6e, - 0x4e, 0x71, 0x50, 0x73, 0x54, 0x72, 0x53, 0x72, 0x4d, 0x72, 0x4c, 0x72, - 0x4f, 0x74, 0x50, 0x77, 0x51, 0x75, 0x4d, 0x72, 0x45, 0x73, 0x52, 0x7d, - 0x67, 0x83, 0x61, 0x87, 0x50, 0x8c, 0x57, 0x85, 0x53, 0x7f, 0x5d, 0x7c, - 0x61, 0x80, 0x65, 0x7f, 0x73, 0x75, 0x76, 0x74, 0x76, 0x74, 0x74, 0x74, - 0x72, 0x75, 0x6c, 0x77, 0x6a, 0x77, 0x62, 0x76, 0x63, 0x78, 0x72, 0x7c, - 0x73, 0x7e, 0x66, 0x7e, 0x5f, 0x79, 0x5d, 0x77, 0x5d, 0x77, 0x5e, 0x77, - 0x5d, 0x77, 0x5d, 0x77, 0x5c, 0x77, 0x5b, 0x77, 0x5b, 0x77, 0x5d, 0x77, - 0x5f, 0x77, 0x62, 0x78, 0x64, 0x78, 0x69, 0x78, 0x6d, 0x78, 0x73, 0x78, - 0x77, 0x77, 0x78, 0x75, 0x78, 0x74, 0x78, 0x76, 0x78, 0x75, 0x78, 0x74, - 0x78, 0x73, 0x78, 0x73, 0x78, 0x73, 0x78, 0x72, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x70, 0x78, 0x70, 0x76, 0x70, 0x75, 0x70, 0x78, 0x6f, 0x77, 0x6f, - 0x76, 0x6f, 0x76, 0x6f, 0x77, 0x6f, 0x78, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, 0x78, 0x6f, - 0x78, 0x6f, 0x78, 0x70, 0x78, 0x70, 0x7a, 0x6f, 0x7b, 0x70, 0x7a, 0x70, - 0x7a, 0x70, 0x7a, 0x72, 0x7e, 0x7c, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x53, 0x55, 0x53, 0x54, 0x54, 0x52, 0x53, 0x57, 0x54, 0x57, 0x54, 0x56, - 0x53, 0x58, 0x53, 0x59, 0x52, 0x5a, 0x51, 0x5c, 0x50, 0x5d, 0x4e, 0x5e, - 0x4e, 0x60, 0x4e, 0x60, 0x4e, 0x63, 0x4c, 0x66, 0x4c, 0x66, 0x4b, 0x65, - 0x4c, 0x65, 0x4c, 0x67, 0x4c, 0x67, 0x4d, 0x67, 0x4f, 0x67, 0x51, 0x68, - 0x56, 0x68, 0x5f, 0x69, 0x65, 0x6b, 0x6a, 0x6e, 0x70, 0x70, 0x72, 0x70, - 0x72, 0x70, 0x6e, 0x6e, 0x68, 0x6d, 0x5b, 0x69, 0x50, 0x67, 0x44, 0x68, - 0x3c, 0x68, 0x3c, 0x68, 0x3e, 0x66, 0x3f, 0x63, 0x3f, 0x62, 0x3f, 0x63, - 0x3e, 0x63, 0x3e, 0x63, 0x3e, 0x64, 0x3e, 0x64, 0x3e, 0x66, 0x3d, 0x6a, - 0x3e, 0x6c, 0x44, 0x6e, 0x46, 0x6e, 0x4a, 0x6e, 0x47, 0x6d, 0x3e, 0x6b, - 0x3e, 0x68, 0x41, 0x67, 0x43, 0x64, 0x44, 0x65, 0x44, 0x66, 0x43, 0x66, - 0x41, 0x65, 0x3f, 0x66, 0x41, 0x68, 0x48, 0x6e, 0x4e, 0x71, 0x50, 0x73, - 0x52, 0x73, 0x51, 0x73, 0x4e, 0x72, 0x50, 0x71, 0x51, 0x73, 0x4f, 0x75, - 0x4d, 0x74, 0x49, 0x74, 0x4e, 0x77, 0x60, 0x7b, 0x8a, 0x83, 0x88, 0x86, - 0x5b, 0x8a, 0x51, 0x8b, 0x55, 0x85, 0x58, 0x7b, 0x61, 0x82, 0x67, 0x81, - 0x7b, 0x75, 0x7d, 0x75, 0x78, 0x75, 0x74, 0x75, 0x71, 0x75, 0x70, 0x74, - 0x71, 0x74, 0x68, 0x74, 0x67, 0x79, 0x75, 0x7d, 0x75, 0x7d, 0x67, 0x78, - 0x5d, 0x76, 0x5d, 0x77, 0x5d, 0x77, 0x5d, 0x77, 0x5e, 0x77, 0x5d, 0x77, - 0x5d, 0x77, 0x5c, 0x77, 0x5d, 0x77, 0x5f, 0x76, 0x61, 0x77, 0x65, 0x78, - 0x67, 0x78, 0x6b, 0x78, 0x70, 0x78, 0x75, 0x78, 0x78, 0x77, 0x78, 0x76, - 0x78, 0x75, 0x78, 0x75, 0x78, 0x75, 0x78, 0x74, 0x78, 0x73, 0x78, 0x73, - 0x78, 0x73, 0x78, 0x72, 0x77, 0x71, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, - 0x76, 0x70, 0x75, 0x70, 0x77, 0x6f, 0x77, 0x6f, 0x76, 0x6f, 0x75, 0x6f, - 0x76, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x70, - 0x78, 0x70, 0x7a, 0x6f, 0x7b, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x72, - 0x7e, 0x7b, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x52, 0x55, 0x53, 0x54, - 0x52, 0x54, 0x52, 0x58, 0x53, 0x57, 0x54, 0x56, 0x54, 0x57, 0x53, 0x57, - 0x51, 0x59, 0x51, 0x5c, 0x50, 0x5d, 0x4f, 0x5e, 0x4e, 0x60, 0x4e, 0x61, - 0x4e, 0x62, 0x4c, 0x65, 0x4c, 0x65, 0x4c, 0x66, 0x4c, 0x66, 0x4c, 0x67, - 0x4c, 0x67, 0x4d, 0x67, 0x4f, 0x67, 0x50, 0x67, 0x53, 0x67, 0x5b, 0x69, - 0x62, 0x6a, 0x68, 0x6d, 0x6e, 0x6f, 0x72, 0x70, 0x74, 0x71, 0x73, 0x6f, - 0x6e, 0x6e, 0x62, 0x6b, 0x58, 0x68, 0x4c, 0x68, 0x3e, 0x69, 0x3b, 0x68, - 0x3e, 0x65, 0x3f, 0x62, 0x40, 0x61, 0x40, 0x61, 0x40, 0x63, 0x3f, 0x64, - 0x3f, 0x65, 0x3e, 0x66, 0x3e, 0x68, 0x3d, 0x6b, 0x3f, 0x6e, 0x44, 0x6e, - 0x46, 0x6e, 0x48, 0x6e, 0x46, 0x6e, 0x3e, 0x6c, 0x3e, 0x68, 0x40, 0x68, - 0x43, 0x65, 0x44, 0x65, 0x44, 0x66, 0x44, 0x66, 0x42, 0x65, 0x41, 0x65, - 0x43, 0x68, 0x49, 0x6e, 0x4f, 0x71, 0x51, 0x73, 0x51, 0x74, 0x52, 0x74, - 0x54, 0x72, 0x64, 0x72, 0x6e, 0x73, 0x60, 0x75, 0x4f, 0x74, 0x55, 0x77, - 0x5e, 0x79, 0x66, 0x7a, 0x8c, 0x80, 0x8e, 0x81, 0x72, 0x85, 0x61, 0x8a, - 0x69, 0x85, 0x61, 0x7d, 0x6c, 0x81, 0x69, 0x7e, 0x7c, 0x76, 0x82, 0x77, - 0x7a, 0x76, 0x71, 0x77, 0x6a, 0x78, 0x6c, 0x77, 0x70, 0x77, 0x6a, 0x78, - 0x6c, 0x7b, 0x77, 0x7e, 0x75, 0x7c, 0x69, 0x79, 0x5c, 0x77, 0x5d, 0x77, - 0x5e, 0x77, 0x5e, 0x77, 0x5e, 0x77, 0x5e, 0x77, 0x5d, 0x77, 0x5e, 0x77, - 0x5f, 0x77, 0x60, 0x77, 0x63, 0x77, 0x68, 0x78, 0x6a, 0x78, 0x6e, 0x78, - 0x73, 0x78, 0x77, 0x78, 0x79, 0x77, 0x79, 0x77, 0x78, 0x77, 0x78, 0x76, - 0x78, 0x75, 0x79, 0x74, 0x78, 0x73, 0x78, 0x73, 0x78, 0x72, 0x78, 0x72, - 0x77, 0x71, 0x77, 0x70, 0x78, 0x70, 0x78, 0x71, 0x76, 0x70, 0x76, 0x71, - 0x77, 0x70, 0x78, 0x6f, 0x76, 0x6f, 0x75, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x70, 0x78, 0x70, 0x7a, 0x6f, - 0x7a, 0x71, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x73, 0x7e, 0x7b, 0x80, 0x7f, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x80, 0x7f, 0x80, 0x7f, 0x51, 0x54, 0x51, 0x54, 0x51, 0x57, 0x51, 0x58, - 0x52, 0x57, 0x53, 0x57, 0x53, 0x58, 0x54, 0x57, 0x52, 0x59, 0x51, 0x5c, - 0x51, 0x5f, 0x4f, 0x60, 0x4e, 0x61, 0x4e, 0x62, 0x4e, 0x62, 0x4c, 0x64, - 0x4c, 0x66, 0x4c, 0x67, 0x4c, 0x67, 0x4c, 0x67, 0x4c, 0x67, 0x4d, 0x65, - 0x4e, 0x66, 0x4f, 0x67, 0x50, 0x67, 0x57, 0x69, 0x60, 0x6a, 0x66, 0x6c, - 0x6e, 0x6f, 0x71, 0x71, 0x75, 0x70, 0x77, 0x70, 0x74, 0x6f, 0x6a, 0x6c, - 0x60, 0x69, 0x56, 0x67, 0x47, 0x68, 0x3f, 0x68, 0x3c, 0x65, 0x3e, 0x63, - 0x40, 0x63, 0x41, 0x63, 0x41, 0x63, 0x40, 0x64, 0x40, 0x66, 0x3f, 0x67, - 0x3d, 0x6a, 0x3c, 0x6b, 0x40, 0x6f, 0x44, 0x6e, 0x46, 0x6e, 0x46, 0x6e, - 0x43, 0x6e, 0x3d, 0x6c, 0x3e, 0x69, 0x40, 0x69, 0x42, 0x67, 0x43, 0x66, - 0x44, 0x66, 0x44, 0x66, 0x43, 0x65, 0x42, 0x66, 0x45, 0x69, 0x4b, 0x70, - 0x52, 0x73, 0x54, 0x73, 0x54, 0x73, 0x57, 0x75, 0x5f, 0x76, 0x73, 0x76, - 0x80, 0x79, 0x73, 0x77, 0x56, 0x77, 0x63, 0x7d, 0x62, 0x7b, 0x5c, 0x7e, - 0x76, 0x80, 0x80, 0x80, 0x73, 0x84, 0x6e, 0x86, 0x73, 0x85, 0x6f, 0x82, - 0x7b, 0x83, 0x71, 0x7f, 0x72, 0x79, 0x7c, 0x78, 0x78, 0x79, 0x67, 0x7b, - 0x64, 0x7c, 0x65, 0x7f, 0x68, 0x84, 0x68, 0x86, 0x6e, 0x7f, 0x7a, 0x7e, - 0x6f, 0x7d, 0x65, 0x7d, 0x5c, 0x78, 0x5e, 0x78, 0x5f, 0x78, 0x5f, 0x78, - 0x5f, 0x77, 0x5f, 0x77, 0x5e, 0x77, 0x5f, 0x77, 0x61, 0x77, 0x63, 0x77, - 0x65, 0x77, 0x6a, 0x77, 0x6e, 0x77, 0x72, 0x78, 0x77, 0x77, 0x7a, 0x77, - 0x7b, 0x78, 0x7a, 0x77, 0x7a, 0x77, 0x7a, 0x76, 0x7a, 0x75, 0x7a, 0x74, - 0x7a, 0x74, 0x79, 0x73, 0x77, 0x73, 0x78, 0x72, 0x78, 0x72, 0x78, 0x72, - 0x77, 0x72, 0x77, 0x72, 0x77, 0x70, 0x77, 0x71, 0x78, 0x71, 0x77, 0x71, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x7a, 0x6f, - 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x71, 0x7b, 0x72, - 0x79, 0x73, 0x7a, 0x74, 0x7e, 0x7d, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x51, 0x55, 0x51, 0x55, 0x51, 0x57, 0x52, 0x58, 0x53, 0x58, 0x53, 0x58, - 0x53, 0x59, 0x53, 0x58, 0x52, 0x5a, 0x51, 0x5d, 0x50, 0x5f, 0x4f, 0x60, - 0x4e, 0x62, 0x4e, 0x62, 0x4e, 0x62, 0x4c, 0x65, 0x4c, 0x67, 0x4c, 0x67, - 0x4b, 0x67, 0x4c, 0x67, 0x4d, 0x67, 0x4d, 0x66, 0x4e, 0x66, 0x4f, 0x67, - 0x51, 0x67, 0x56, 0x69, 0x5c, 0x6a, 0x64, 0x6b, 0x6b, 0x6d, 0x6f, 0x70, - 0x75, 0x70, 0x78, 0x70, 0x76, 0x70, 0x6e, 0x6d, 0x66, 0x6b, 0x5c, 0x68, - 0x4e, 0x68, 0x45, 0x68, 0x3d, 0x67, 0x3d, 0x64, 0x40, 0x63, 0x42, 0x63, - 0x41, 0x62, 0x41, 0x65, 0x41, 0x66, 0x3f, 0x68, 0x3d, 0x6a, 0x3c, 0x6b, - 0x40, 0x6e, 0x42, 0x6e, 0x45, 0x6e, 0x44, 0x6e, 0x40, 0x6e, 0x3c, 0x6c, - 0x3e, 0x6a, 0x40, 0x69, 0x42, 0x68, 0x43, 0x66, 0x44, 0x65, 0x45, 0x65, - 0x44, 0x65, 0x42, 0x66, 0x45, 0x69, 0x4c, 0x70, 0x54, 0x73, 0x55, 0x72, - 0x55, 0x74, 0x5c, 0x77, 0x66, 0x78, 0x6e, 0x7a, 0x76, 0x7b, 0x73, 0x78, - 0x5b, 0x7b, 0x61, 0x7e, 0x5e, 0x7b, 0x57, 0x81, 0x5e, 0x83, 0x64, 0x83, - 0x5c, 0x85, 0x68, 0x85, 0x70, 0x83, 0x6e, 0x81, 0x70, 0x82, 0x6a, 0x80, - 0x70, 0x7d, 0x79, 0x7b, 0x76, 0x80, 0x68, 0x86, 0x68, 0x88, 0x66, 0x89, - 0x66, 0x8a, 0x6a, 0x86, 0x73, 0x80, 0x78, 0x7e, 0x6c, 0x7d, 0x63, 0x7d, - 0x5e, 0x78, 0x60, 0x78, 0x60, 0x78, 0x60, 0x78, 0x60, 0x77, 0x60, 0x77, - 0x60, 0x77, 0x62, 0x77, 0x64, 0x77, 0x65, 0x77, 0x68, 0x77, 0x6d, 0x77, - 0x71, 0x77, 0x76, 0x77, 0x79, 0x77, 0x7b, 0x77, 0x7b, 0x77, 0x7b, 0x77, - 0x7b, 0x77, 0x7a, 0x76, 0x7b, 0x75, 0x7a, 0x75, 0x7a, 0x75, 0x79, 0x74, - 0x78, 0x73, 0x78, 0x73, 0x78, 0x72, 0x78, 0x72, 0x77, 0x72, 0x77, 0x72, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x71, 0x77, 0x71, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, - 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x71, 0x7b, 0x72, 0x79, 0x73, 0x7a, 0x74, - 0x7e, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, - 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x51, 0x57, 0x51, 0x58, - 0x51, 0x58, 0x51, 0x58, 0x52, 0x59, 0x53, 0x5a, 0x53, 0x59, 0x53, 0x5a, - 0x52, 0x5c, 0x51, 0x5f, 0x50, 0x60, 0x4f, 0x60, 0x4f, 0x62, 0x4e, 0x62, - 0x4e, 0x62, 0x4c, 0x64, 0x4c, 0x67, 0x4c, 0x67, 0x4b, 0x67, 0x4c, 0x67, - 0x4c, 0x67, 0x4d, 0x66, 0x4e, 0x66, 0x4f, 0x67, 0x51, 0x67, 0x54, 0x69, - 0x58, 0x6b, 0x60, 0x6a, 0x67, 0x6b, 0x6c, 0x6d, 0x75, 0x70, 0x77, 0x70, - 0x77, 0x72, 0x74, 0x6f, 0x6d, 0x6d, 0x64, 0x6a, 0x58, 0x68, 0x4f, 0x68, - 0x41, 0x68, 0x3d, 0x66, 0x40, 0x64, 0x42, 0x63, 0x42, 0x62, 0x42, 0x65, - 0x42, 0x67, 0x3f, 0x68, 0x3e, 0x6a, 0x3d, 0x6b, 0x3f, 0x6d, 0x41, 0x6e, - 0x42, 0x6e, 0x40, 0x6e, 0x3c, 0x6d, 0x3b, 0x6c, 0x3e, 0x6a, 0x3f, 0x69, - 0x42, 0x67, 0x43, 0x65, 0x44, 0x66, 0x44, 0x66, 0x44, 0x65, 0x42, 0x66, - 0x45, 0x69, 0x4d, 0x70, 0x56, 0x72, 0x57, 0x72, 0x5a, 0x76, 0x5d, 0x78, - 0x66, 0x79, 0x72, 0x7f, 0x77, 0x83, 0x76, 0x80, 0x5c, 0x80, 0x53, 0x7f, - 0x50, 0x7b, 0x53, 0x7d, 0x54, 0x85, 0x4d, 0x87, 0x55, 0x86, 0x6e, 0x83, - 0x68, 0x81, 0x62, 0x7f, 0x64, 0x80, 0x65, 0x7f, 0x70, 0x80, 0x7a, 0x82, - 0x76, 0x85, 0x6a, 0x89, 0x69, 0x88, 0x67, 0x85, 0x65, 0x82, 0x6f, 0x81, - 0x7b, 0x81, 0x73, 0x7e, 0x67, 0x7c, 0x62, 0x7c, 0x5f, 0x78, 0x62, 0x78, - 0x62, 0x78, 0x61, 0x78, 0x62, 0x78, 0x62, 0x77, 0x63, 0x77, 0x66, 0x77, - 0x68, 0x77, 0x69, 0x77, 0x6d, 0x77, 0x73, 0x77, 0x77, 0x78, 0x7b, 0x77, - 0x7b, 0x77, 0x7b, 0x77, 0x7b, 0x77, 0x7b, 0x77, 0x7b, 0x77, 0x7a, 0x76, - 0x7a, 0x76, 0x7a, 0x75, 0x7a, 0x75, 0x79, 0x74, 0x78, 0x72, 0x78, 0x73, - 0x78, 0x72, 0x78, 0x72, 0x77, 0x72, 0x77, 0x72, 0x77, 0x71, 0x77, 0x70, - 0x77, 0x71, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, - 0x79, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, - 0x7a, 0x71, 0x7a, 0x72, 0x79, 0x73, 0x7a, 0x74, 0x7e, 0x7d, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, - 0x80, 0x7f, 0x80, 0x7f, 0x52, 0x56, 0x51, 0x59, 0x51, 0x59, 0x51, 0x59, - 0x52, 0x5a, 0x53, 0x5a, 0x53, 0x58, 0x53, 0x5b, 0x52, 0x5f, 0x51, 0x5f, - 0x50, 0x60, 0x50, 0x61, 0x50, 0x62, 0x4e, 0x60, 0x4e, 0x61, 0x4d, 0x66, - 0x4e, 0x66, 0x4c, 0x67, 0x4b, 0x67, 0x4c, 0x67, 0x4c, 0x67, 0x4d, 0x66, - 0x4d, 0x66, 0x4f, 0x66, 0x50, 0x65, 0x53, 0x66, 0x56, 0x69, 0x5c, 0x6a, - 0x67, 0x6a, 0x6c, 0x6c, 0x73, 0x6e, 0x77, 0x70, 0x78, 0x71, 0x78, 0x70, - 0x74, 0x6e, 0x68, 0x6c, 0x5f, 0x69, 0x57, 0x69, 0x48, 0x68, 0x3e, 0x67, - 0x3f, 0x64, 0x41, 0x62, 0x42, 0x62, 0x43, 0x64, 0x42, 0x66, 0x40, 0x68, - 0x3e, 0x69, 0x3c, 0x6a, 0x3d, 0x6c, 0x40, 0x6d, 0x41, 0x6e, 0x3e, 0x6c, - 0x3b, 0x6c, 0x3b, 0x6a, 0x3d, 0x6a, 0x3f, 0x69, 0x41, 0x66, 0x42, 0x66, - 0x44, 0x68, 0x45, 0x66, 0x44, 0x65, 0x44, 0x66, 0x45, 0x6a, 0x4d, 0x70, - 0x5a, 0x71, 0x65, 0x72, 0x64, 0x77, 0x5d, 0x79, 0x63, 0x78, 0x7a, 0x80, - 0x82, 0x86, 0x75, 0x84, 0x59, 0x80, 0x4b, 0x7e, 0x47, 0x79, 0x4f, 0x79, - 0x62, 0x81, 0x64, 0x82, 0x6b, 0x82, 0x75, 0x82, 0x62, 0x80, 0x5a, 0x7c, - 0x61, 0x7e, 0x67, 0x7f, 0x6c, 0x81, 0x73, 0x85, 0x75, 0x86, 0x6e, 0x85, - 0x6a, 0x84, 0x66, 0x84, 0x66, 0x83, 0x72, 0x82, 0x7d, 0x82, 0x6c, 0x7d, - 0x5e, 0x79, 0x5f, 0x7e, 0x63, 0x7a, 0x64, 0x79, 0x63, 0x79, 0x61, 0x7a, - 0x61, 0x79, 0x63, 0x78, 0x66, 0x78, 0x67, 0x77, 0x69, 0x77, 0x6d, 0x77, - 0x72, 0x78, 0x76, 0x78, 0x79, 0x78, 0x7d, 0x78, 0x7d, 0x77, 0x7c, 0x77, - 0x7c, 0x77, 0x7c, 0x76, 0x7c, 0x76, 0x7b, 0x75, 0x7a, 0x75, 0x7b, 0x75, - 0x7a, 0x75, 0x7a, 0x74, 0x7b, 0x73, 0x7a, 0x73, 0x78, 0x72, 0x78, 0x72, - 0x77, 0x72, 0x77, 0x73, 0x77, 0x71, 0x77, 0x70, 0x77, 0x70, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, - 0x7a, 0x6f, 0x7a, 0x70, 0x7b, 0x70, 0x7a, 0x6f, 0x7a, 0x70, 0x7a, 0x71, - 0x7a, 0x74, 0x7a, 0x74, 0x7e, 0x7c, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, - 0x52, 0x56, 0x52, 0x58, 0x51, 0x59, 0x51, 0x5a, 0x52, 0x5a, 0x53, 0x5a, - 0x54, 0x57, 0x53, 0x5b, 0x52, 0x60, 0x51, 0x5f, 0x51, 0x60, 0x51, 0x62, - 0x50, 0x62, 0x4e, 0x62, 0x4e, 0x63, 0x4d, 0x66, 0x4d, 0x65, 0x4c, 0x67, - 0x4b, 0x67, 0x4c, 0x67, 0x4c, 0x67, 0x4d, 0x66, 0x4d, 0x66, 0x4e, 0x65, - 0x50, 0x64, 0x52, 0x65, 0x55, 0x67, 0x5b, 0x69, 0x66, 0x6a, 0x6b, 0x6c, - 0x73, 0x6d, 0x77, 0x6f, 0x78, 0x71, 0x78, 0x70, 0x75, 0x6f, 0x6c, 0x6d, - 0x64, 0x6a, 0x5d, 0x6a, 0x52, 0x68, 0x44, 0x67, 0x40, 0x65, 0x40, 0x63, - 0x42, 0x63, 0x43, 0x64, 0x42, 0x66, 0x41, 0x68, 0x3e, 0x6a, 0x3d, 0x6a, - 0x3c, 0x6c, 0x3e, 0x6e, 0x3e, 0x6e, 0x3c, 0x6c, 0x3a, 0x6c, 0x3b, 0x6a, - 0x3d, 0x6a, 0x3f, 0x69, 0x41, 0x67, 0x42, 0x66, 0x44, 0x67, 0x45, 0x66, - 0x44, 0x64, 0x43, 0x65, 0x44, 0x6a, 0x4f, 0x70, 0x6a, 0x73, 0x79, 0x76, - 0x6a, 0x77, 0x5d, 0x77, 0x69, 0x78, 0x81, 0x82, 0x83, 0x85, 0x61, 0x86, - 0x4d, 0x80, 0x48, 0x7c, 0x45, 0x77, 0x47, 0x78, 0x44, 0x82, 0x54, 0x82, - 0x5d, 0x80, 0x60, 0x80, 0x56, 0x7f, 0x5b, 0x7c, 0x6c, 0x7e, 0x67, 0x7e, - 0x6a, 0x7f, 0x6e, 0x82, 0x73, 0x85, 0x72, 0x85, 0x6d, 0x85, 0x67, 0x85, - 0x69, 0x84, 0x74, 0x81, 0x7b, 0x7e, 0x68, 0x7b, 0x56, 0x7c, 0x5b, 0x82, - 0x63, 0x7b, 0x64, 0x7a, 0x63, 0x7a, 0x62, 0x7a, 0x62, 0x79, 0x65, 0x78, - 0x67, 0x78, 0x68, 0x77, 0x6c, 0x77, 0x70, 0x77, 0x75, 0x78, 0x79, 0x78, - 0x7b, 0x78, 0x7d, 0x77, 0x7e, 0x77, 0x7d, 0x77, 0x7c, 0x77, 0x7c, 0x76, - 0x7c, 0x75, 0x7b, 0x75, 0x7b, 0x75, 0x7b, 0x75, 0x7b, 0x75, 0x7a, 0x74, - 0x7a, 0x73, 0x7a, 0x72, 0x77, 0x72, 0x78, 0x72, 0x77, 0x72, 0x77, 0x73, - 0x77, 0x71, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, 0x78, 0x6f, - 0x78, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x70, - 0x7b, 0x70, 0x7a, 0x6f, 0x7a, 0x70, 0x7a, 0x72, 0x7b, 0x73, 0x7a, 0x73, - 0x7e, 0x7c, 0x81, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x80, 0x7f, - 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x53, 0x58, 0x53, 0x55, - 0x52, 0x59, 0x51, 0x5a, 0x52, 0x5a, 0x53, 0x5a, 0x53, 0x57, 0x53, 0x5b, - 0x52, 0x60, 0x51, 0x5f, 0x51, 0x60, 0x51, 0x62, 0x50, 0x63, 0x4f, 0x65, - 0x4f, 0x65, 0x4d, 0x65, 0x4d, 0x65, 0x4c, 0x67, 0x4b, 0x67, 0x4b, 0x67, - 0x4b, 0x67, 0x4d, 0x66, 0x4d, 0x66, 0x4d, 0x65, 0x4f, 0x65, 0x52, 0x64, - 0x56, 0x65, 0x5b, 0x68, 0x64, 0x6b, 0x6a, 0x6c, 0x73, 0x6d, 0x77, 0x6f, - 0x78, 0x70, 0x78, 0x71, 0x77, 0x71, 0x72, 0x6f, 0x6d, 0x6c, 0x65, 0x6c, - 0x5a, 0x69, 0x51, 0x68, 0x44, 0x66, 0x40, 0x65, 0x41, 0x64, 0x42, 0x64, - 0x42, 0x66, 0x41, 0x68, 0x3f, 0x69, 0x3d, 0x69, 0x3b, 0x6c, 0x3a, 0x6e, - 0x3a, 0x6e, 0x3a, 0x6d, 0x39, 0x6c, 0x3a, 0x6a, 0x3c, 0x6a, 0x3e, 0x69, - 0x41, 0x66, 0x41, 0x66, 0x43, 0x67, 0x45, 0x66, 0x44, 0x65, 0x42, 0x65, - 0x44, 0x69, 0x53, 0x71, 0x78, 0x77, 0x80, 0x7c, 0x66, 0x7d, 0x5d, 0x7a, - 0x73, 0x7b, 0x8b, 0x88, 0x7f, 0x86, 0x51, 0x89, 0x47, 0x86, 0x43, 0x7e, - 0x3c, 0x77, 0x3e, 0x78, 0x2e, 0x86, 0x2e, 0x87, 0x38, 0x82, 0x49, 0x7e, - 0x54, 0x7c, 0x69, 0x7e, 0x70, 0x7f, 0x6a, 0x7f, 0x62, 0x7d, 0x61, 0x7c, - 0x6b, 0x82, 0x72, 0x86, 0x71, 0x86, 0x67, 0x85, 0x68, 0x84, 0x74, 0x81, - 0x73, 0x7d, 0x5e, 0x7d, 0x56, 0x7e, 0x5e, 0x80, 0x64, 0x7a, 0x63, 0x7a, - 0x63, 0x7a, 0x64, 0x7a, 0x64, 0x79, 0x67, 0x78, 0x6a, 0x78, 0x6d, 0x77, - 0x70, 0x77, 0x74, 0x77, 0x78, 0x77, 0x7d, 0x78, 0x7f, 0x78, 0x7d, 0x77, - 0x7e, 0x78, 0x7c, 0x77, 0x7c, 0x77, 0x7c, 0x76, 0x7c, 0x75, 0x7b, 0x75, - 0x7b, 0x75, 0x7a, 0x75, 0x7a, 0x75, 0x7a, 0x74, 0x7a, 0x73, 0x79, 0x72, - 0x77, 0x72, 0x78, 0x72, 0x77, 0x72, 0x77, 0x72, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, 0x77, 0x6f, - 0x77, 0x6f, 0x77, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x78, 0x6f, 0x79, 0x6f, - 0x79, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x70, 0x7b, 0x70, 0x7b, 0x6f, - 0x7b, 0x71, 0x7b, 0x72, 0x7a, 0x70, 0x7a, 0x71, 0x7e, 0x7c, 0x81, 0x7f, - 0x80, 0x81, 0x80, 0x80, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, - 0x7f, 0x80, 0x7f, 0x80, 0x54, 0x59, 0x54, 0x56, 0x53, 0x58, 0x52, 0x5b, - 0x52, 0x5b, 0x53, 0x5b, 0x53, 0x59, 0x52, 0x5c, 0x52, 0x5f, 0x52, 0x5f, - 0x51, 0x60, 0x50, 0x62, 0x50, 0x63, 0x50, 0x64, 0x4f, 0x65, 0x4e, 0x66, - 0x4e, 0x66, 0x4d, 0x66, 0x4c, 0x66, 0x4c, 0x67, 0x4b, 0x67, 0x4c, 0x68, - 0x4d, 0x66, 0x4d, 0x65, 0x4f, 0x65, 0x52, 0x65, 0x56, 0x65, 0x5b, 0x67, - 0x64, 0x6a, 0x6a, 0x6c, 0x72, 0x6e, 0x77, 0x70, 0x78, 0x70, 0x78, 0x71, - 0x77, 0x71, 0x76, 0x70, 0x70, 0x6d, 0x68, 0x6c, 0x5e, 0x6a, 0x56, 0x68, - 0x48, 0x66, 0x40, 0x66, 0x40, 0x65, 0x40, 0x65, 0x41, 0x67, 0x40, 0x67, - 0x3f, 0x69, 0x3d, 0x6a, 0x3b, 0x6b, 0x39, 0x6c, 0x39, 0x6c, 0x39, 0x6b, - 0x39, 0x6b, 0x3a, 0x6b, 0x3c, 0x69, 0x3d, 0x69, 0x3f, 0x66, 0x40, 0x66, - 0x42, 0x67, 0x44, 0x65, 0x44, 0x63, 0x43, 0x65, 0x44, 0x6a, 0x52, 0x72, - 0x7a, 0x7c, 0x81, 0x82, 0x62, 0x82, 0x5f, 0x7b, 0x79, 0x7c, 0x8a, 0x88, - 0x76, 0x86, 0x4b, 0x8c, 0x44, 0x8b, 0x3f, 0x82, 0x32, 0x7c, 0x36, 0x7a, - 0x31, 0x88, 0x2f, 0x89, 0x31, 0x83, 0x4d, 0x7e, 0x61, 0x7c, 0x6c, 0x7d, - 0x73, 0x80, 0x6d, 0x7f, 0x61, 0x7e, 0x61, 0x7e, 0x6b, 0x7f, 0x70, 0x83, - 0x71, 0x84, 0x68, 0x84, 0x65, 0x84, 0x6e, 0x82, 0x66, 0x7f, 0x56, 0x80, - 0x5a, 0x7c, 0x61, 0x7b, 0x65, 0x7a, 0x65, 0x7a, 0x65, 0x79, 0x66, 0x79, - 0x67, 0x78, 0x6a, 0x78, 0x6d, 0x78, 0x70, 0x77, 0x73, 0x77, 0x77, 0x77, - 0x7d, 0x77, 0x7f, 0x78, 0x80, 0x77, 0x7e, 0x77, 0x7e, 0x77, 0x7d, 0x77, - 0x7d, 0x78, 0x7d, 0x76, 0x7d, 0x75, 0x7c, 0x74, 0x7b, 0x75, 0x7b, 0x75, - 0x7b, 0x74, 0x7b, 0x74, 0x7a, 0x73, 0x7a, 0x72, 0x79, 0x72, 0x79, 0x72, - 0x77, 0x72, 0x77, 0x72, 0x77, 0x71, 0x77, 0x71, 0x78, 0x6f, 0x77, 0x6f, - 0x77, 0x70, 0x78, 0x70, 0x78, 0x70, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x6f, - 0x78, 0x6f, 0x79, 0x6f, 0x79, 0x6f, 0x79, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, - 0x7b, 0x6f, 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x71, 0x7b, 0x71, - 0x7b, 0x6f, 0x7a, 0x70, 0x7e, 0x7c, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x7f, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, - 0x54, 0x5b, 0x54, 0x59, 0x53, 0x5a, 0x53, 0x5d, 0x52, 0x5d, 0x52, 0x5d, - 0x52, 0x5d, 0x52, 0x5e, 0x51, 0x60, 0x52, 0x5f, 0x52, 0x60, 0x51, 0x62, - 0x51, 0x62, 0x51, 0x64, 0x50, 0x65, 0x4f, 0x65, 0x4e, 0x66, 0x4d, 0x66, - 0x4d, 0x65, 0x4c, 0x67, 0x4b, 0x67, 0x4c, 0x68, 0x4c, 0x66, 0x4d, 0x65, - 0x4e, 0x65, 0x51, 0x65, 0x55, 0x65, 0x5b, 0x66, 0x65, 0x68, 0x6b, 0x6c, - 0x71, 0x6f, 0x76, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, - 0x71, 0x6e, 0x6c, 0x6c, 0x64, 0x6a, 0x5b, 0x69, 0x51, 0x66, 0x44, 0x65, - 0x40, 0x66, 0x3f, 0x67, 0x3f, 0x67, 0x3f, 0x67, 0x3f, 0x68, 0x3e, 0x6a, - 0x3c, 0x6a, 0x3b, 0x6b, 0x3b, 0x6a, 0x39, 0x6a, 0x39, 0x6a, 0x39, 0x6b, - 0x3b, 0x69, 0x3d, 0x68, 0x3f, 0x66, 0x40, 0x65, 0x41, 0x65, 0x43, 0x64, - 0x44, 0x62, 0x44, 0x63, 0x44, 0x69, 0x52, 0x72, 0x80, 0x81, 0x8a, 0x85, - 0x63, 0x82, 0x65, 0x7a, 0x79, 0x7d, 0x77, 0x85, 0x65, 0x84, 0x46, 0x8b, - 0x34, 0x8c, 0x34, 0x85, 0x2d, 0x84, 0x31, 0x80, 0x2c, 0x88, 0x29, 0x89, - 0x2b, 0x85, 0x3a, 0x82, 0x42, 0x81, 0x42, 0x7f, 0x49, 0x7e, 0x4f, 0x7c, - 0x6f, 0x7f, 0x7b, 0x82, 0x6e, 0x81, 0x57, 0x80, 0x5c, 0x81, 0x5f, 0x80, - 0x55, 0x81, 0x5d, 0x81, 0x53, 0x7f, 0x50, 0x7f, 0x60, 0x7c, 0x68, 0x7a, - 0x65, 0x7a, 0x67, 0x7a, 0x67, 0x79, 0x6a, 0x78, 0x6c, 0x77, 0x6e, 0x77, - 0x71, 0x77, 0x74, 0x77, 0x79, 0x77, 0x7b, 0x77, 0x7f, 0x77, 0x7f, 0x77, - 0x7f, 0x77, 0x7f, 0x78, 0x7f, 0x77, 0x7d, 0x77, 0x7e, 0x77, 0x7e, 0x76, - 0x7e, 0x75, 0x7d, 0x74, 0x7d, 0x75, 0x7d, 0x75, 0x7d, 0x74, 0x7c, 0x74, - 0x7b, 0x73, 0x7a, 0x73, 0x7a, 0x72, 0x79, 0x72, 0x78, 0x72, 0x78, 0x72, - 0x77, 0x72, 0x77, 0x72, 0x77, 0x70, 0x77, 0x70, 0x78, 0x70, 0x78, 0x71, - 0x78, 0x70, 0x78, 0x70, 0x78, 0x6f, 0x78, 0x6f, 0x79, 0x6f, 0x7b, 0x6f, - 0x7a, 0x6f, 0x7a, 0x6f, 0x7b, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x70, - 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x70, 0x7a, 0x70, - 0x7d, 0x7b, 0x7f, 0x7f, 0x80, 0x80, 0x7f, 0x7f, 0x80, 0x80, 0x7f, 0x80, - 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x54, 0x5f, 0x54, 0x5d, - 0x54, 0x5c, 0x53, 0x5e, 0x52, 0x5e, 0x51, 0x5e, 0x51, 0x5e, 0x51, 0x60, - 0x51, 0x61, 0x52, 0x61, 0x52, 0x61, 0x52, 0x62, 0x52, 0x61, 0x51, 0x65, - 0x50, 0x66, 0x4f, 0x65, 0x4f, 0x66, 0x4e, 0x66, 0x4d, 0x66, 0x4c, 0x67, - 0x4b, 0x67, 0x4c, 0x68, 0x4c, 0x66, 0x4d, 0x64, 0x4e, 0x65, 0x52, 0x65, - 0x54, 0x65, 0x5a, 0x66, 0x65, 0x69, 0x6b, 0x6b, 0x71, 0x6f, 0x76, 0x6f, - 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x71, 0x75, 0x70, 0x72, 0x6e, - 0x6b, 0x6b, 0x61, 0x69, 0x58, 0x66, 0x49, 0x66, 0x42, 0x66, 0x3e, 0x67, - 0x3f, 0x67, 0x3f, 0x67, 0x40, 0x68, 0x3f, 0x6b, 0x3c, 0x6b, 0x3b, 0x6b, - 0x3b, 0x6b, 0x39, 0x6b, 0x39, 0x6b, 0x39, 0x6b, 0x3b, 0x68, 0x3c, 0x68, - 0x3e, 0x66, 0x3f, 0x64, 0x42, 0x63, 0x44, 0x62, 0x44, 0x62, 0x43, 0x64, - 0x44, 0x6a, 0x53, 0x73, 0x80, 0x80, 0x85, 0x85, 0x5c, 0x82, 0x68, 0x7a, - 0x7a, 0x7f, 0x6b, 0x83, 0x5d, 0x83, 0x54, 0x88, 0x35, 0x8a, 0x29, 0x88, - 0x31, 0x88, 0x38, 0x86, 0x30, 0x88, 0x2b, 0x89, 0x30, 0x88, 0x2f, 0x88, - 0x2a, 0x89, 0x29, 0x8d, 0x28, 0x89, 0x38, 0x84, 0x5b, 0x84, 0x5f, 0x85, - 0x49, 0x86, 0x33, 0x85, 0x38, 0x84, 0x49, 0x7e, 0x49, 0x7d, 0x52, 0x7e, - 0x4e, 0x7f, 0x56, 0x7f, 0x67, 0x7c, 0x6c, 0x7a, 0x66, 0x79, 0x66, 0x7a, - 0x68, 0x79, 0x6b, 0x78, 0x6f, 0x77, 0x72, 0x77, 0x74, 0x77, 0x77, 0x77, - 0x7d, 0x77, 0x7e, 0x77, 0x7e, 0x77, 0x7f, 0x78, 0x7f, 0x78, 0x7f, 0x78, - 0x7f, 0x78, 0x7e, 0x77, 0x7e, 0x77, 0x7e, 0x76, 0x7d, 0x75, 0x7e, 0x75, - 0x7e, 0x74, 0x7d, 0x75, 0x7d, 0x74, 0x7b, 0x73, 0x7a, 0x73, 0x7a, 0x72, - 0x7a, 0x72, 0x7a, 0x71, 0x78, 0x71, 0x78, 0x72, 0x78, 0x72, 0x77, 0x72, - 0x77, 0x70, 0x77, 0x70, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, - 0x78, 0x70, 0x78, 0x6e, 0x79, 0x6f, 0x7a, 0x6e, 0x7a, 0x6f, 0x7b, 0x6f, - 0x7b, 0x6f, 0x7a, 0x6f, 0x7a, 0x6f, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, - 0x7b, 0x70, 0x7b, 0x70, 0x7a, 0x70, 0x7b, 0x70, 0x7d, 0x7b, 0x7f, 0x7f, - 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x80, 0x7f, 0x7f, 0x55, 0x61, 0x54, 0x60, 0x54, 0x5f, 0x53, 0x60, - 0x52, 0x60, 0x51, 0x60, 0x51, 0x5f, 0x51, 0x61, 0x51, 0x63, 0x51, 0x62, - 0x52, 0x61, 0x51, 0x62, 0x51, 0x62, 0x51, 0x64, 0x50, 0x64, 0x50, 0x64, - 0x4f, 0x65, 0x4e, 0x65, 0x4d, 0x66, 0x4c, 0x67, 0x4b, 0x67, 0x4c, 0x68, - 0x4c, 0x66, 0x4d, 0x65, 0x4e, 0x65, 0x51, 0x66, 0x55, 0x67, 0x5b, 0x67, - 0x65, 0x69, 0x6c, 0x6c, 0x72, 0x6f, 0x76, 0x6f, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x70, 0x78, 0x71, 0x76, 0x70, 0x75, 0x6f, 0x71, 0x6d, 0x67, 0x6a, - 0x5d, 0x67, 0x51, 0x66, 0x48, 0x66, 0x3f, 0x68, 0x3d, 0x67, 0x3e, 0x67, - 0x40, 0x68, 0x3f, 0x6a, 0x3c, 0x6a, 0x3b, 0x6b, 0x3b, 0x6a, 0x3a, 0x6a, - 0x3a, 0x6a, 0x3a, 0x6a, 0x3b, 0x69, 0x3b, 0x68, 0x3e, 0x65, 0x3f, 0x63, - 0x42, 0x62, 0x43, 0x62, 0x44, 0x61, 0x43, 0x66, 0x44, 0x6e, 0x51, 0x76, - 0x6d, 0x7f, 0x67, 0x83, 0x4e, 0x81, 0x66, 0x7b, 0x7e, 0x80, 0x6c, 0x83, - 0x60, 0x84, 0x6c, 0x85, 0x51, 0x87, 0x2a, 0x8a, 0x2a, 0x8b, 0x31, 0x89, - 0x3b, 0x89, 0x3a, 0x8a, 0x3b, 0x8a, 0x37, 0x8b, 0x33, 0x8c, 0x33, 0x8d, - 0x34, 0x8a, 0x36, 0x87, 0x39, 0x87, 0x3a, 0x87, 0x33, 0x88, 0x30, 0x88, - 0x35, 0x85, 0x4a, 0x80, 0x52, 0x7f, 0x54, 0x7f, 0x5c, 0x7f, 0x6b, 0x80, - 0x6a, 0x7c, 0x6a, 0x7a, 0x65, 0x7a, 0x66, 0x7c, 0x66, 0x7a, 0x6b, 0x78, - 0x70, 0x77, 0x75, 0x77, 0x77, 0x77, 0x79, 0x77, 0x80, 0x77, 0x80, 0x77, - 0x7f, 0x76, 0x7f, 0x76, 0x7f, 0x77, 0x80, 0x77, 0x7f, 0x77, 0x7d, 0x76, - 0x7d, 0x76, 0x7e, 0x76, 0x7e, 0x76, 0x7e, 0x75, 0x7e, 0x74, 0x7e, 0x74, - 0x7d, 0x74, 0x7c, 0x73, 0x7b, 0x73, 0x7b, 0x73, 0x7a, 0x72, 0x7a, 0x72, - 0x79, 0x72, 0x79, 0x72, 0x77, 0x72, 0x76, 0x72, 0x77, 0x71, 0x77, 0x71, - 0x78, 0x71, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x78, 0x70, 0x79, 0x70, - 0x79, 0x70, 0x79, 0x6f, 0x79, 0x70, 0x7b, 0x6f, 0x7b, 0x6f, 0x7b, 0x6f, - 0x7b, 0x6f, 0x7b, 0x70, 0x7b, 0x71, 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, - 0x7a, 0x70, 0x7b, 0x71, 0x7d, 0x7c, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x7f, - 0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, - 0x55, 0x60, 0x55, 0x61, 0x53, 0x62, 0x53, 0x62, 0x52, 0x62, 0x51, 0x62, - 0x51, 0x61, 0x51, 0x63, 0x51, 0x65, 0x51, 0x64, 0x51, 0x61, 0x51, 0x62, - 0x51, 0x62, 0x51, 0x63, 0x51, 0x63, 0x50, 0x63, 0x51, 0x63, 0x4e, 0x65, - 0x4d, 0x66, 0x4c, 0x67, 0x4c, 0x67, 0x4c, 0x68, 0x4c, 0x67, 0x4c, 0x65, - 0x4e, 0x65, 0x51, 0x66, 0x56, 0x68, 0x5d, 0x67, 0x66, 0x69, 0x6e, 0x6c, - 0x73, 0x6f, 0x76, 0x6f, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, - 0x76, 0x70, 0x76, 0x71, 0x74, 0x6f, 0x6c, 0x6c, 0x64, 0x69, 0x59, 0x67, - 0x51, 0x68, 0x46, 0x68, 0x3f, 0x67, 0x3d, 0x67, 0x3e, 0x68, 0x3e, 0x68, - 0x3e, 0x68, 0x3c, 0x69, 0x3b, 0x69, 0x3b, 0x68, 0x3b, 0x68, 0x3b, 0x68, - 0x3b, 0x68, 0x3b, 0x67, 0x3d, 0x64, 0x3e, 0x63, 0x41, 0x61, 0x42, 0x60, - 0x43, 0x60, 0x42, 0x68, 0x46, 0x72, 0x49, 0x79, 0x45, 0x7e, 0x44, 0x81, - 0x4d, 0x7f, 0x68, 0x7b, 0x80, 0x82, 0x6a, 0x85, 0x68, 0x86, 0x78, 0x84, - 0x76, 0x85, 0x4e, 0x8a, 0x26, 0x8e, 0x2a, 0x8c, 0x3a, 0x8b, 0x42, 0x89, - 0x47, 0x87, 0x44, 0x88, 0x42, 0x88, 0x41, 0x89, 0x45, 0x88, 0x47, 0x87, - 0x47, 0x86, 0x46, 0x86, 0x47, 0x85, 0x4d, 0x85, 0x51, 0x82, 0x53, 0x81, - 0x51, 0x82, 0x60, 0x82, 0x75, 0x81, 0x73, 0x81, 0x6a, 0x7b, 0x6a, 0x79, - 0x66, 0x79, 0x68, 0x7d, 0x62, 0x7d, 0x63, 0x7b, 0x6d, 0x77, 0x77, 0x75, - 0x7e, 0x75, 0x80, 0x75, 0x82, 0x76, 0x81, 0x77, 0x7f, 0x75, 0x7f, 0x76, - 0x7f, 0x78, 0x81, 0x74, 0x81, 0x74, 0x7e, 0x76, 0x7d, 0x75, 0x7f, 0x76, - 0x80, 0x77, 0x7e, 0x75, 0x7e, 0x75, 0x7e, 0x73, 0x7d, 0x73, 0x7d, 0x73, - 0x7d, 0x73, 0x7d, 0x73, 0x7b, 0x73, 0x7b, 0x73, 0x7a, 0x72, 0x7a, 0x72, - 0x78, 0x72, 0x77, 0x72, 0x78, 0x72, 0x78, 0x72, 0x78, 0x71, 0x78, 0x70, - 0x78, 0x70, 0x78, 0x70, 0x79, 0x70, 0x7a, 0x71, 0x7a, 0x71, 0x79, 0x71, - 0x7a, 0x71, 0x7b, 0x6f, 0x7b, 0x6f, 0x7c, 0x70, 0x7d, 0x71, 0x7d, 0x70, - 0x7d, 0x71, 0x7b, 0x70, 0x7b, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x72, - 0x7e, 0x7b, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, - 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x55, 0x60, 0x55, 0x60, - 0x54, 0x63, 0x52, 0x63, 0x52, 0x63, 0x51, 0x63, 0x51, 0x61, 0x51, 0x63, - 0x50, 0x65, 0x51, 0x64, 0x51, 0x61, 0x51, 0x62, 0x51, 0x62, 0x51, 0x63, - 0x51, 0x63, 0x51, 0x63, 0x51, 0x63, 0x4f, 0x65, 0x4e, 0x66, 0x4c, 0x67, - 0x4b, 0x67, 0x4c, 0x68, 0x4c, 0x66, 0x4c, 0x65, 0x4e, 0x65, 0x51, 0x67, - 0x56, 0x67, 0x5d, 0x68, 0x67, 0x69, 0x6f, 0x6b, 0x73, 0x6f, 0x76, 0x6f, - 0x77, 0x71, 0x77, 0x70, 0x77, 0x70, 0x77, 0x70, 0x76, 0x70, 0x76, 0x70, - 0x75, 0x70, 0x70, 0x6d, 0x69, 0x6a, 0x61, 0x69, 0x5b, 0x69, 0x4e, 0x67, - 0x46, 0x68, 0x3f, 0x67, 0x3d, 0x68, 0x3e, 0x68, 0x3e, 0x68, 0x3d, 0x68, - 0x3c, 0x68, 0x3b, 0x68, 0x3b, 0x68, 0x3b, 0x67, 0x3b, 0x67, 0x3b, 0x66, - 0x3d, 0x63, 0x3e, 0x63, 0x40, 0x61, 0x42, 0x60, 0x43, 0x60, 0x43, 0x69, - 0x4b, 0x75, 0x4b, 0x7b, 0x3c, 0x7f, 0x44, 0x83, 0x53, 0x7f, 0x6d, 0x7c, - 0x81, 0x84, 0x6c, 0x83, 0x69, 0x86, 0x70, 0x84, 0x7d, 0x82, 0x75, 0x87, - 0x3a, 0x8d, 0x29, 0x90, 0x30, 0x8d, 0x47, 0x87, 0x56, 0x83, 0x57, 0x83, - 0x55, 0x83, 0x4f, 0x82, 0x4f, 0x82, 0x4e, 0x83, 0x4f, 0x85, 0x51, 0x84, - 0x4f, 0x82, 0x52, 0x81, 0x53, 0x81, 0x54, 0x81, 0x5b, 0x82, 0x71, 0x83, - 0x79, 0x83, 0x6f, 0x80, 0x69, 0x7b, 0x6e, 0x79, 0x67, 0x76, 0x68, 0x7c, - 0x5f, 0x81, 0x58, 0x80, 0x67, 0x75, 0x73, 0x72, 0x7e, 0x72, 0x7e, 0x74, - 0x77, 0x78, 0x73, 0x7a, 0x71, 0x7a, 0x70, 0x7c, 0x6f, 0x7e, 0x75, 0x7a, - 0x7f, 0x77, 0x80, 0x75, 0x7f, 0x76, 0x7f, 0x75, 0x7f, 0x75, 0x7e, 0x75, - 0x7d, 0x75, 0x7d, 0x73, 0x7d, 0x72, 0x7d, 0x73, 0x7d, 0x73, 0x7c, 0x73, - 0x7b, 0x73, 0x7b, 0x73, 0x7a, 0x72, 0x7a, 0x72, 0x79, 0x72, 0x78, 0x72, - 0x78, 0x72, 0x78, 0x72, 0x78, 0x71, 0x77, 0x70, 0x79, 0x70, 0x7a, 0x70, - 0x7a, 0x70, 0x7a, 0x70, 0x7a, 0x70, 0x7b, 0x71, 0x7b, 0x70, 0x7d, 0x6f, - 0x7c, 0x6f, 0x7c, 0x70, 0x7c, 0x70, 0x7c, 0x70, 0x7d, 0x70, 0x7d, 0x70, - 0x7d, 0x70, 0x7c, 0x71, 0x7c, 0x70, 0x7c, 0x72, 0x7e, 0x79, 0x7f, 0x7e, - 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, - 0x7f, 0x80, 0x7f, 0x7f, 0x56, 0x61, 0x55, 0x60, 0x53, 0x63, 0x52, 0x65, - 0x52, 0x65, 0x51, 0x64, 0x51, 0x62, 0x51, 0x63, 0x51, 0x65, 0x51, 0x63, - 0x51, 0x62, 0x50, 0x62, 0x51, 0x63, 0x51, 0x64, 0x51, 0x64, 0x50, 0x64, - 0x50, 0x64, 0x4e, 0x65, 0x4e, 0x66, 0x4d, 0x67, 0x4b, 0x67, 0x4c, 0x68, - 0x4c, 0x67, 0x4c, 0x65, 0x4e, 0x65, 0x51, 0x67, 0x57, 0x68, 0x5e, 0x67, - 0x69, 0x69, 0x70, 0x6c, 0x73, 0x6f, 0x75, 0x6f, 0x77, 0x70, 0x77, 0x70, - 0x77, 0x70, 0x77, 0x70, 0x75, 0x70, 0x75, 0x70, 0x76, 0x70, 0x74, 0x6f, - 0x6f, 0x6c, 0x6a, 0x6b, 0x64, 0x69, 0x59, 0x67, 0x51, 0x67, 0x48, 0x67, - 0x3f, 0x67, 0x3e, 0x68, 0x3d, 0x67, 0x3d, 0x66, 0x3d, 0x66, 0x3c, 0x67, - 0x3c, 0x68, 0x3c, 0x65, 0x3b, 0x65, 0x3b, 0x65, 0x3c, 0x63, 0x3d, 0x63, - 0x3f, 0x62, 0x42, 0x61, 0x42, 0x60, 0x45, 0x68, 0x54, 0x72, 0x59, 0x7b, - 0x55, 0x82, 0x5c, 0x85, 0x5b, 0x7d, 0x73, 0x7c, 0x7f, 0x84, 0x6c, 0x82, - 0x5b, 0x86, 0x5f, 0x85, 0x78, 0x7c, 0x80, 0x7e, 0x6d, 0x87, 0x4f, 0x8c, - 0x39, 0x8c, 0x50, 0x88, 0x5e, 0x82, 0x57, 0x80, 0x59, 0x80, 0x5c, 0x7e, - 0x5b, 0x80, 0x59, 0x80, 0x5c, 0x7f, 0x62, 0x7e, 0x6b, 0x7e, 0x6d, 0x7e, - 0x6f, 0x7d, 0x77, 0x7e, 0x78, 0x82, 0x6d, 0x8a, 0x6f, 0x86, 0x6e, 0x7f, - 0x66, 0x7b, 0x6d, 0x79, 0x61, 0x75, 0x62, 0x7a, 0x5c, 0x82, 0x50, 0x83, - 0x60, 0x72, 0x69, 0x6f, 0x70, 0x75, 0x6c, 0x7b, 0x68, 0x7f, 0x67, 0x81, - 0x63, 0x84, 0x60, 0x88, 0x5f, 0x8b, 0x61, 0x8e, 0x6e, 0x83, 0x7d, 0x76, - 0x81, 0x75, 0x7f, 0x74, 0x80, 0x74, 0x7f, 0x74, 0x7e, 0x74, 0x7e, 0x73, - 0x7e, 0x73, 0x7d, 0x73, 0x7c, 0x73, 0x7c, 0x73, 0x7a, 0x73, 0x7a, 0x73, - 0x7a, 0x72, 0x7a, 0x72, 0x7a, 0x72, 0x7a, 0x73, 0x79, 0x72, 0x78, 0x71, - 0x78, 0x71, 0x78, 0x70, 0x7a, 0x70, 0x7b, 0x70, 0x7b, 0x70, 0x7b, 0x70, - 0x7b, 0x70, 0x7c, 0x70, 0x7d, 0x70, 0x7e, 0x6f, 0x7e, 0x70, 0x7d, 0x70, - 0x7e, 0x6f, 0x7d, 0x70, 0x7e, 0x70, 0x7e, 0x70, 0x7e, 0x70, 0x7e, 0x70, - 0x7e, 0x70, 0x7d, 0x71, 0x7e, 0x79, 0x7f, 0x7e, 0x80, 0x7f, 0x7f, 0x7f, - 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x56, 0x63, 0x54, 0x63, 0x54, 0x63, 0x52, 0x65, 0x51, 0x66, 0x51, 0x66, - 0x51, 0x65, 0x51, 0x64, 0x50, 0x64, 0x50, 0x65, 0x50, 0x65, 0x50, 0x65, - 0x50, 0x65, 0x50, 0x65, 0x50, 0x65, 0x50, 0x65, 0x50, 0x65, 0x4f, 0x65, - 0x4e, 0x65, 0x4d, 0x66, 0x4b, 0x67, 0x4c, 0x67, 0x4c, 0x67, 0x4c, 0x67, - 0x4d, 0x67, 0x52, 0x67, 0x59, 0x67, 0x60, 0x67, 0x6a, 0x69, 0x70, 0x6d, - 0x72, 0x6f, 0x74, 0x70, 0x75, 0x6f, 0x76, 0x6f, 0x76, 0x70, 0x76, 0x70, - 0x76, 0x6f, 0x75, 0x6f, 0x76, 0x6f, 0x76, 0x6f, 0x73, 0x6f, 0x6d, 0x6d, - 0x68, 0x6b, 0x60, 0x68, 0x59, 0x67, 0x51, 0x67, 0x45, 0x68, 0x3e, 0x68, - 0x3c, 0x66, 0x3d, 0x65, 0x3d, 0x65, 0x3d, 0x66, 0x3c, 0x65, 0x3c, 0x65, - 0x3c, 0x65, 0x3c, 0x64, 0x3c, 0x63, 0x3d, 0x63, 0x3f, 0x62, 0x40, 0x60, - 0x42, 0x5e, 0x49, 0x67, 0x5c, 0x72, 0x60, 0x7c, 0x68, 0x83, 0x6f, 0x84, - 0x5d, 0x7b, 0x79, 0x79, 0x78, 0x7f, 0x62, 0x80, 0x55, 0x86, 0x62, 0x86, - 0x77, 0x77, 0x79, 0x77, 0x7d, 0x80, 0x7a, 0x83, 0x65, 0x8c, 0x62, 0x8c, - 0x65, 0x86, 0x63, 0x82, 0x64, 0x81, 0x62, 0x80, 0x64, 0x81, 0x6a, 0x81, - 0x70, 0x7e, 0x76, 0x7d, 0x7d, 0x7e, 0x7f, 0x7d, 0x7e, 0x7d, 0x7f, 0x7d, - 0x7a, 0x7e, 0x70, 0x85, 0x6d, 0x86, 0x6a, 0x81, 0x5f, 0x7c, 0x63, 0x7a, - 0x5d, 0x78, 0x66, 0x77, 0x67, 0x77, 0x56, 0x7c, 0x5f, 0x6e, 0x61, 0x72, - 0x68, 0x7d, 0x6a, 0x80, 0x6d, 0x80, 0x6c, 0x84, 0x66, 0x89, 0x5f, 0x8f, - 0x5f, 0x91, 0x69, 0x8e, 0x69, 0x8a, 0x78, 0x7c, 0x80, 0x74, 0x7f, 0x74, - 0x80, 0x74, 0x80, 0x74, 0x80, 0x73, 0x80, 0x73, 0x7f, 0x73, 0x7f, 0x73, - 0x7d, 0x73, 0x7d, 0x72, 0x7b, 0x73, 0x7a, 0x73, 0x7b, 0x73, 0x7a, 0x73, - 0x7a, 0x73, 0x7a, 0x73, 0x7a, 0x72, 0x7a, 0x71, 0x7a, 0x72, 0x7a, 0x70, - 0x7a, 0x70, 0x7b, 0x70, 0x7c, 0x70, 0x7d, 0x70, 0x7c, 0x70, 0x7d, 0x70, - 0x7d, 0x71, 0x7e, 0x70, 0x7e, 0x70, 0x7f, 0x6f, 0x7f, 0x6e, 0x7f, 0x70, - 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7e, 0x70, 0x7d, 0x70, 0x7f, 0x70, - 0x7f, 0x79, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x56, 0x65, 0x54, 0x65, - 0x54, 0x64, 0x52, 0x67, 0x51, 0x67, 0x51, 0x67, 0x50, 0x66, 0x4f, 0x66, - 0x4f, 0x66, 0x4e, 0x66, 0x4e, 0x66, 0x4e, 0x66, 0x4f, 0x66, 0x51, 0x65, - 0x50, 0x65, 0x50, 0x65, 0x50, 0x65, 0x4f, 0x65, 0x4e, 0x65, 0x4d, 0x67, - 0x4c, 0x67, 0x4c, 0x67, 0x4c, 0x67, 0x4b, 0x68, 0x4c, 0x69, 0x53, 0x68, - 0x5b, 0x68, 0x61, 0x67, 0x6a, 0x6b, 0x70, 0x6e, 0x72, 0x6f, 0x74, 0x6f, - 0x75, 0x6f, 0x76, 0x70, 0x76, 0x70, 0x76, 0x70, 0x76, 0x6f, 0x76, 0x6f, - 0x76, 0x6f, 0x76, 0x6f, 0x75, 0x70, 0x70, 0x6f, 0x6b, 0x6d, 0x64, 0x6a, - 0x5e, 0x67, 0x57, 0x67, 0x4d, 0x68, 0x44, 0x68, 0x3d, 0x66, 0x3d, 0x65, - 0x3d, 0x66, 0x3c, 0x66, 0x3c, 0x66, 0x3c, 0x65, 0x3c, 0x65, 0x3c, 0x64, - 0x3c, 0x63, 0x3c, 0x62, 0x3e, 0x62, 0x40, 0x5f, 0x42, 0x5b, 0x4b, 0x67, - 0x61, 0x74, 0x63, 0x7a, 0x66, 0x83, 0x6b, 0x85, 0x58, 0x7a, 0x7a, 0x76, - 0x76, 0x7b, 0x5e, 0x7c, 0x5a, 0x81, 0x6b, 0x85, 0x75, 0x74, 0x72, 0x74, - 0x6a, 0x7f, 0x6b, 0x85, 0x63, 0x8f, 0x61, 0x92, 0x6a, 0x8c, 0x76, 0x82, - 0x78, 0x7f, 0x74, 0x7f, 0x74, 0x7f, 0x77, 0x80, 0x7b, 0x7f, 0x7d, 0x7e, - 0x7f, 0x7e, 0x7e, 0x7d, 0x7e, 0x7d, 0x7c, 0x7c, 0x78, 0x7c, 0x70, 0x80, - 0x6d, 0x81, 0x69, 0x80, 0x5c, 0x7e, 0x61, 0x7c, 0x60, 0x7c, 0x6a, 0x78, - 0x6e, 0x78, 0x5b, 0x7b, 0x5f, 0x73, 0x61, 0x78, 0x6d, 0x80, 0x72, 0x7f, - 0x71, 0x80, 0x6f, 0x84, 0x65, 0x8c, 0x60, 0x90, 0x6e, 0x8d, 0x78, 0x82, - 0x71, 0x83, 0x76, 0x7e, 0x7f, 0x76, 0x80, 0x74, 0x81, 0x74, 0x80, 0x74, - 0x80, 0x73, 0x80, 0x73, 0x7f, 0x73, 0x7f, 0x73, 0x7d, 0x73, 0x7d, 0x73, - 0x7d, 0x73, 0x7d, 0x73, 0x7b, 0x73, 0x7b, 0x73, 0x7a, 0x73, 0x7a, 0x73, - 0x7a, 0x73, 0x7a, 0x73, 0x7a, 0x73, 0x7a, 0x72, 0x7a, 0x71, 0x7b, 0x72, - 0x7c, 0x71, 0x7c, 0x70, 0x7c, 0x70, 0x7c, 0x70, 0x7d, 0x70, 0x7d, 0x70, - 0x7d, 0x6f, 0x7f, 0x6f, 0x7f, 0x6f, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, - 0x7f, 0x71, 0x7e, 0x71, 0x7d, 0x70, 0x7e, 0x6f, 0x7f, 0x79, 0x7f, 0x7f, - 0x80, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x56, 0x66, 0x54, 0x66, 0x53, 0x66, 0x52, 0x68, - 0x51, 0x68, 0x51, 0x68, 0x4f, 0x67, 0x4e, 0x67, 0x4e, 0x68, 0x4d, 0x67, - 0x4d, 0x67, 0x4d, 0x67, 0x4e, 0x66, 0x50, 0x64, 0x50, 0x65, 0x50, 0x64, - 0x51, 0x64, 0x4f, 0x65, 0x4f, 0x65, 0x4e, 0x66, 0x4c, 0x67, 0x4c, 0x67, - 0x4b, 0x68, 0x4b, 0x69, 0x4c, 0x6a, 0x54, 0x69, 0x5c, 0x68, 0x62, 0x68, - 0x6a, 0x6c, 0x6f, 0x6f, 0x72, 0x6f, 0x74, 0x6f, 0x75, 0x6f, 0x75, 0x6f, - 0x75, 0x70, 0x75, 0x70, 0x75, 0x6f, 0x75, 0x6f, 0x75, 0x6f, 0x75, 0x6f, - 0x76, 0x71, 0x73, 0x70, 0x71, 0x6e, 0x69, 0x6b, 0x63, 0x69, 0x5f, 0x68, - 0x58, 0x68, 0x50, 0x68, 0x44, 0x66, 0x3d, 0x65, 0x3d, 0x66, 0x3c, 0x66, - 0x3c, 0x65, 0x3c, 0x64, 0x3c, 0x64, 0x3c, 0x63, 0x3c, 0x64, 0x3c, 0x62, - 0x3d, 0x60, 0x3f, 0x61, 0x44, 0x60, 0x53, 0x6b, 0x66, 0x75, 0x69, 0x7a, - 0x5e, 0x83, 0x5e, 0x85, 0x50, 0x7a, 0x6e, 0x72, 0x78, 0x76, 0x61, 0x78, - 0x5e, 0x7b, 0x65, 0x81, 0x6e, 0x7d, 0x6a, 0x7e, 0x4e, 0x86, 0x4c, 0x89, - 0x53, 0x8e, 0x59, 0x92, 0x66, 0x92, 0x7d, 0x83, 0x7e, 0x7f, 0x7b, 0x80, - 0x7b, 0x80, 0x7b, 0x80, 0x7a, 0x7f, 0x7a, 0x7e, 0x79, 0x7e, 0x78, 0x7e, - 0x79, 0x7d, 0x76, 0x7e, 0x72, 0x7f, 0x6d, 0x80, 0x69, 0x7c, 0x5f, 0x85, - 0x56, 0x86, 0x5d, 0x84, 0x5f, 0x84, 0x5f, 0x87, 0x5b, 0x89, 0x5a, 0x82, - 0x62, 0x7e, 0x67, 0x7f, 0x73, 0x7f, 0x78, 0x7f, 0x79, 0x80, 0x71, 0x87, - 0x64, 0x90, 0x73, 0x8d, 0x7e, 0x85, 0x79, 0x7f, 0x70, 0x7c, 0x73, 0x79, - 0x7b, 0x77, 0x7d, 0x75, 0x7f, 0x75, 0x80, 0x73, 0x80, 0x73, 0x80, 0x73, - 0x7f, 0x73, 0x7e, 0x73, 0x7e, 0x73, 0x7e, 0x73, 0x7e, 0x73, 0x7e, 0x73, - 0x7b, 0x73, 0x7b, 0x73, 0x7a, 0x73, 0x7a, 0x73, 0x7a, 0x75, 0x7b, 0x75, - 0x7a, 0x75, 0x7a, 0x73, 0x7b, 0x72, 0x7b, 0x73, 0x7c, 0x72, 0x7c, 0x71, - 0x7d, 0x70, 0x7d, 0x70, 0x7e, 0x70, 0x7d, 0x71, 0x7e, 0x70, 0x7f, 0x6f, - 0x7f, 0x6f, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x70, 0x7f, 0x71, 0x7f, 0x73, - 0x7d, 0x6f, 0x7e, 0x6e, 0x7f, 0x79, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x56, 0x65, 0x54, 0x67, 0x53, 0x68, 0x52, 0x67, 0x51, 0x66, 0x51, 0x65, - 0x50, 0x66, 0x4e, 0x69, 0x4e, 0x68, 0x4d, 0x66, 0x4e, 0x67, 0x4e, 0x67, - 0x4e, 0x66, 0x4f, 0x64, 0x50, 0x64, 0x50, 0x62, 0x50, 0x62, 0x4f, 0x65, - 0x4f, 0x66, 0x4e, 0x66, 0x4d, 0x65, 0x4b, 0x66, 0x4b, 0x68, 0x4b, 0x69, - 0x4e, 0x68, 0x56, 0x68, 0x5b, 0x68, 0x63, 0x69, 0x6c, 0x6c, 0x6f, 0x6e, - 0x71, 0x6f, 0x73, 0x6f, 0x74, 0x6f, 0x74, 0x6f, 0x75, 0x6f, 0x75, 0x6e, - 0x72, 0x6f, 0x72, 0x6f, 0x73, 0x6f, 0x72, 0x6f, 0x74, 0x70, 0x75, 0x70, - 0x75, 0x70, 0x6e, 0x6c, 0x67, 0x6b, 0x63, 0x6a, 0x5a, 0x68, 0x55, 0x68, - 0x4c, 0x66, 0x41, 0x66, 0x3e, 0x66, 0x3c, 0x66, 0x3b, 0x65, 0x3c, 0x62, - 0x3c, 0x63, 0x3c, 0x63, 0x3b, 0x63, 0x3c, 0x60, 0x40, 0x62, 0x47, 0x6d, - 0x51, 0x70, 0x5d, 0x76, 0x66, 0x79, 0x6a, 0x7b, 0x5f, 0x7f, 0x5f, 0x82, - 0x44, 0x7d, 0x5e, 0x70, 0x71, 0x74, 0x64, 0x77, 0x69, 0x76, 0x64, 0x7c, - 0x70, 0x85, 0x77, 0x88, 0x56, 0x8c, 0x57, 0x8c, 0x60, 0x8c, 0x56, 0x92, - 0x5c, 0x94, 0x75, 0x85, 0x75, 0x82, 0x70, 0x84, 0x6f, 0x83, 0x6f, 0x83, - 0x6e, 0x7f, 0x6f, 0x7f, 0x70, 0x80, 0x70, 0x80, 0x72, 0x80, 0x72, 0x7f, - 0x70, 0x80, 0x6d, 0x7f, 0x67, 0x7d, 0x57, 0x8e, 0x51, 0x95, 0x54, 0x94, - 0x55, 0x94, 0x4e, 0x94, 0x4a, 0x90, 0x5c, 0x80, 0x62, 0x82, 0x6b, 0x80, - 0x77, 0x7f, 0x7c, 0x7e, 0x7a, 0x81, 0x6a, 0x8c, 0x67, 0x91, 0x7b, 0x8a, - 0x7a, 0x83, 0x73, 0x83, 0x70, 0x7c, 0x74, 0x78, 0x75, 0x76, 0x76, 0x74, - 0x77, 0x72, 0x7b, 0x70, 0x7f, 0x72, 0x81, 0x74, 0x7f, 0x73, 0x7d, 0x73, - 0x7f, 0x73, 0x7f, 0x73, 0x7d, 0x73, 0x7d, 0x73, 0x7d, 0x75, 0x7d, 0x75, - 0x7b, 0x74, 0x7b, 0x73, 0x7b, 0x75, 0x7a, 0x75, 0x7b, 0x73, 0x7b, 0x73, - 0x7c, 0x73, 0x7d, 0x73, 0x7d, 0x73, 0x7d, 0x73, 0x7e, 0x72, 0x7f, 0x70, - 0x7f, 0x70, 0x80, 0x71, 0x80, 0x6f, 0x80, 0x6f, 0x80, 0x6f, 0x80, 0x6f, - 0x80, 0x6f, 0x80, 0x6f, 0x80, 0x71, 0x80, 0x73, 0x80, 0x6f, 0x80, 0x70, - 0x7f, 0x79, 0x7f, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x57, 0x65, 0x54, 0x67, - 0x53, 0x67, 0x53, 0x67, 0x52, 0x67, 0x51, 0x67, 0x50, 0x66, 0x4f, 0x69, - 0x4e, 0x69, 0x4d, 0x68, 0x4d, 0x68, 0x4d, 0x67, 0x4e, 0x67, 0x4f, 0x66, - 0x4f, 0x65, 0x50, 0x64, 0x50, 0x64, 0x4f, 0x65, 0x4e, 0x66, 0x4e, 0x66, - 0x4d, 0x66, 0x4c, 0x66, 0x4b, 0x68, 0x4b, 0x68, 0x50, 0x68, 0x57, 0x68, - 0x5d, 0x68, 0x64, 0x69, 0x6c, 0x6c, 0x6f, 0x6e, 0x71, 0x6f, 0x73, 0x6f, - 0x74, 0x6f, 0x75, 0x6f, 0x75, 0x6f, 0x75, 0x6f, 0x73, 0x6f, 0x73, 0x6f, - 0x73, 0x6f, 0x72, 0x6f, 0x74, 0x70, 0x76, 0x71, 0x76, 0x70, 0x71, 0x6d, - 0x6d, 0x6c, 0x68, 0x6c, 0x5f, 0x69, 0x5b, 0x68, 0x53, 0x65, 0x4c, 0x66, - 0x41, 0x65, 0x3e, 0x65, 0x3c, 0x65, 0x3c, 0x63, 0x3b, 0x63, 0x3d, 0x64, - 0x3d, 0x62, 0x45, 0x68, 0x58, 0x79, 0x64, 0x82, 0x68, 0x82, 0x6a, 0x83, - 0x69, 0x81, 0x68, 0x7e, 0x69, 0x7c, 0x6a, 0x7d, 0x4d, 0x7c, 0x49, 0x75, - 0x62, 0x74, 0x66, 0x75, 0x6c, 0x76, 0x76, 0x7b, 0x68, 0x81, 0x6d, 0x86, - 0x57, 0x8d, 0x5e, 0x8d, 0x65, 0x8c, 0x56, 0x90, 0x56, 0x8f, 0x65, 0x84, - 0x69, 0x82, 0x68, 0x84, 0x68, 0x84, 0x67, 0x83, 0x67, 0x80, 0x67, 0x7f, - 0x69, 0x80, 0x6b, 0x80, 0x6d, 0x80, 0x6e, 0x80, 0x6d, 0x7f, 0x6a, 0x7f, - 0x67, 0x7e, 0x5e, 0x89, 0x55, 0x94, 0x52, 0x98, 0x4c, 0x9a, 0x4b, 0x8f, - 0x53, 0x86, 0x60, 0x7e, 0x64, 0x82, 0x6d, 0x81, 0x76, 0x7f, 0x7a, 0x7e, - 0x73, 0x84, 0x60, 0x8d, 0x70, 0x8f, 0x7d, 0x87, 0x76, 0x84, 0x70, 0x83, - 0x73, 0x7e, 0x72, 0x7a, 0x71, 0x77, 0x70, 0x74, 0x70, 0x6f, 0x73, 0x6e, - 0x79, 0x70, 0x7e, 0x73, 0x7f, 0x73, 0x7f, 0x73, 0x7f, 0x73, 0x7f, 0x73, - 0x7d, 0x73, 0x7d, 0x73, 0x7c, 0x75, 0x7c, 0x74, 0x7b, 0x73, 0x7b, 0x73, - 0x7a, 0x75, 0x7b, 0x75, 0x7a, 0x73, 0x7a, 0x73, 0x7c, 0x73, 0x7d, 0x73, - 0x7d, 0x73, 0x7e, 0x73, 0x7e, 0x73, 0x7f, 0x72, 0x7f, 0x72, 0x80, 0x71, - 0x80, 0x6f, 0x80, 0x6f, 0x80, 0x6f, 0x80, 0x6f, 0x80, 0x6f, 0x80, 0x6f, - 0x80, 0x71, 0x80, 0x72, 0x80, 0x6f, 0x80, 0x71, 0x7f, 0x7a, 0x7f, 0x7f, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, - 0x80, 0x7f, 0x80, 0x80, 0x56, 0x65, 0x55, 0x67, 0x54, 0x67, 0x53, 0x68, - 0x52, 0x68, 0x51, 0x69, 0x4f, 0x67, 0x4e, 0x69, 0x4d, 0x6a, 0x4d, 0x6a, - 0x4d, 0x69, 0x4d, 0x68, 0x4d, 0x68, 0x4e, 0x67, 0x4e, 0x67, 0x4f, 0x66, - 0x50, 0x66, 0x4f, 0x65, 0x4e, 0x66, 0x4e, 0x66, 0x4d, 0x66, 0x4c, 0x66, - 0x4a, 0x68, 0x4c, 0x68, 0x52, 0x68, 0x59, 0x68, 0x5e, 0x68, 0x65, 0x69, - 0x6c, 0x6c, 0x6f, 0x6e, 0x71, 0x70, 0x73, 0x6f, 0x74, 0x6f, 0x74, 0x6f, - 0x74, 0x6f, 0x74, 0x6f, 0x73, 0x70, 0x73, 0x6f, 0x72, 0x6f, 0x72, 0x6e, - 0x74, 0x70, 0x76, 0x70, 0x76, 0x71, 0x75, 0x6f, 0x73, 0x6e, 0x6d, 0x6e, - 0x66, 0x6b, 0x62, 0x69, 0x5b, 0x66, 0x57, 0x66, 0x4c, 0x65, 0x40, 0x65, - 0x3d, 0x65, 0x3c, 0x63, 0x3b, 0x63, 0x3c, 0x62, 0x47, 0x6d, 0x5c, 0x81, - 0x6c, 0x8b, 0x6c, 0x89, 0x6f, 0x88, 0x75, 0x83, 0x79, 0x82, 0x6d, 0x83, - 0x6b, 0x80, 0x67, 0x7e, 0x63, 0x7c, 0x53, 0x7c, 0x54, 0x79, 0x59, 0x7d, - 0x55, 0x7c, 0x7c, 0x78, 0x71, 0x76, 0x56, 0x7d, 0x5b, 0x81, 0x66, 0x7e, - 0x6b, 0x7e, 0x61, 0x81, 0x5e, 0x80, 0x66, 0x7c, 0x67, 0x7c, 0x66, 0x7f, - 0x66, 0x80, 0x65, 0x80, 0x64, 0x80, 0x64, 0x7f, 0x66, 0x80, 0x6a, 0x80, - 0x68, 0x80, 0x69, 0x80, 0x69, 0x80, 0x66, 0x80, 0x65, 0x7f, 0x63, 0x83, - 0x5d, 0x88, 0x5b, 0x89, 0x51, 0x8b, 0x52, 0x81, 0x5b, 0x7d, 0x61, 0x81, - 0x68, 0x84, 0x6f, 0x83, 0x75, 0x80, 0x77, 0x80, 0x6a, 0x88, 0x60, 0x8e, - 0x76, 0x8f, 0x7a, 0x88, 0x75, 0x84, 0x72, 0x82, 0x72, 0x7f, 0x6e, 0x7c, - 0x6e, 0x79, 0x6d, 0x79, 0x6d, 0x70, 0x6b, 0x6b, 0x70, 0x6e, 0x7a, 0x71, - 0x7e, 0x72, 0x81, 0x73, 0x7f, 0x73, 0x7f, 0x73, 0x7d, 0x73, 0x7d, 0x73, - 0x7c, 0x75, 0x7d, 0x75, 0x7b, 0x72, 0x7b, 0x73, 0x7b, 0x75, 0x7b, 0x75, - 0x7a, 0x73, 0x7b, 0x73, 0x7c, 0x73, 0x7d, 0x73, 0x7d, 0x72, 0x7e, 0x72, - 0x7e, 0x73, 0x7f, 0x74, 0x80, 0x73, 0x80, 0x71, 0x80, 0x6f, 0x80, 0x6f, - 0x80, 0x6f, 0x81, 0x6f, 0x81, 0x6f, 0x80, 0x70, 0x80, 0x71, 0x80, 0x70, - 0x80, 0x71, 0x7f, 0x72, 0x7f, 0x7a, 0x7f, 0x7e, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x80, - 0x56, 0x66, 0x55, 0x66, 0x54, 0x66, 0x53, 0x68, 0x52, 0x69, 0x51, 0x6a, - 0x50, 0x69, 0x4e, 0x6a, 0x4d, 0x6b, 0x4c, 0x6b, 0x4c, 0x6a, 0x4c, 0x68, - 0x4c, 0x69, 0x4d, 0x68, 0x4d, 0x68, 0x4e, 0x66, 0x4e, 0x66, 0x4f, 0x65, - 0x4e, 0x66, 0x4d, 0x66, 0x4d, 0x65, 0x4c, 0x67, 0x4b, 0x68, 0x4c, 0x68, - 0x52, 0x68, 0x59, 0x69, 0x5f, 0x6a, 0x66, 0x6a, 0x6d, 0x6c, 0x6f, 0x6e, - 0x72, 0x6f, 0x73, 0x6f, 0x73, 0x6f, 0x73, 0x6f, 0x73, 0x6f, 0x73, 0x6f, - 0x72, 0x6f, 0x72, 0x6f, 0x72, 0x6e, 0x72, 0x6d, 0x73, 0x6f, 0x75, 0x70, - 0x75, 0x70, 0x75, 0x6f, 0x74, 0x6f, 0x70, 0x6e, 0x68, 0x6c, 0x64, 0x6a, - 0x5e, 0x67, 0x5a, 0x66, 0x54, 0x64, 0x47, 0x65, 0x41, 0x65, 0x3c, 0x65, - 0x3b, 0x63, 0x3e, 0x63, 0x56, 0x7c, 0x69, 0x8c, 0x73, 0x88, 0x72, 0x88, - 0x74, 0x89, 0x72, 0x85, 0x78, 0x84, 0x76, 0x83, 0x6c, 0x85, 0x66, 0x84, - 0x65, 0x7e, 0x64, 0x7b, 0x56, 0x7b, 0x3e, 0x8b, 0x39, 0x8f, 0x67, 0x7f, - 0x7d, 0x77, 0x63, 0x7a, 0x62, 0x7b, 0x67, 0x78, 0x6e, 0x77, 0x69, 0x78, - 0x69, 0x77, 0x69, 0x78, 0x69, 0x7a, 0x67, 0x7c, 0x66, 0x7d, 0x65, 0x7f, - 0x66, 0x7e, 0x65, 0x7d, 0x65, 0x80, 0x66, 0x7f, 0x66, 0x7e, 0x67, 0x80, - 0x69, 0x81, 0x67, 0x80, 0x65, 0x80, 0x62, 0x84, 0x5d, 0x83, 0x5a, 0x82, - 0x55, 0x81, 0x58, 0x7e, 0x5c, 0x7e, 0x62, 0x81, 0x6d, 0x82, 0x70, 0x83, - 0x74, 0x82, 0x76, 0x84, 0x67, 0x8a, 0x66, 0x8e, 0x77, 0x8c, 0x74, 0x8a, - 0x73, 0x86, 0x73, 0x82, 0x72, 0x7e, 0x6e, 0x7b, 0x6d, 0x79, 0x6e, 0x7c, - 0x71, 0x75, 0x6a, 0x6b, 0x6b, 0x6b, 0x76, 0x6e, 0x7b, 0x71, 0x82, 0x74, - 0x81, 0x72, 0x7f, 0x73, 0x7e, 0x74, 0x7e, 0x74, 0x7d, 0x75, 0x7e, 0x75, - 0x7d, 0x74, 0x7c, 0x74, 0x7b, 0x75, 0x7b, 0x75, 0x7c, 0x75, 0x7c, 0x74, - 0x7d, 0x72, 0x7d, 0x72, 0x7e, 0x72, 0x7f, 0x73, 0x7f, 0x73, 0x80, 0x73, - 0x80, 0x72, 0x81, 0x70, 0x82, 0x70, 0x81, 0x6f, 0x82, 0x70, 0x82, 0x70, - 0x82, 0x70, 0x81, 0x70, 0x80, 0x70, 0x81, 0x6f, 0x81, 0x72, 0x80, 0x74, - 0x80, 0x78, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x80, 0x56, 0x65, 0x55, 0x64, - 0x54, 0x65, 0x54, 0x68, 0x52, 0x6a, 0x51, 0x6a, 0x51, 0x69, 0x4e, 0x6a, - 0x4d, 0x6a, 0x4c, 0x6b, 0x4c, 0x6a, 0x4c, 0x6a, 0x4b, 0x6a, 0x4c, 0x68, - 0x4d, 0x68, 0x4e, 0x66, 0x4e, 0x66, 0x4e, 0x66, 0x4d, 0x66, 0x4e, 0x66, - 0x4d, 0x65, 0x4c, 0x67, 0x4c, 0x68, 0x4c, 0x68, 0x51, 0x68, 0x5a, 0x69, - 0x61, 0x6a, 0x68, 0x6a, 0x6d, 0x6c, 0x6f, 0x6e, 0x72, 0x6f, 0x72, 0x6f, - 0x73, 0x6f, 0x72, 0x6f, 0x73, 0x6f, 0x72, 0x6f, 0x72, 0x6f, 0x72, 0x70, - 0x72, 0x6e, 0x71, 0x6d, 0x72, 0x6f, 0x73, 0x6f, 0x73, 0x6e, 0x73, 0x6e, - 0x73, 0x6e, 0x71, 0x6d, 0x6d, 0x6e, 0x6a, 0x6c, 0x65, 0x69, 0x60, 0x68, - 0x5b, 0x66, 0x52, 0x65, 0x4b, 0x65, 0x42, 0x63, 0x41, 0x64, 0x4c, 0x6e, - 0x67, 0x86, 0x71, 0x82, 0x74, 0x7b, 0x79, 0x80, 0x82, 0x81, 0x7e, 0x83, - 0x79, 0x87, 0x76, 0x87, 0x6f, 0x88, 0x68, 0x89, 0x65, 0x84, 0x64, 0x7f, - 0x62, 0x7c, 0x47, 0x84, 0x32, 0x90, 0x3b, 0x96, 0x58, 0x8d, 0x67, 0x7f, - 0x66, 0x7d, 0x5f, 0x7f, 0x56, 0x83, 0x5b, 0x81, 0x66, 0x7a, 0x68, 0x76, - 0x68, 0x78, 0x68, 0x7b, 0x65, 0x7e, 0x65, 0x7e, 0x66, 0x7c, 0x66, 0x7b, - 0x65, 0x7b, 0x65, 0x7a, 0x64, 0x7b, 0x65, 0x7d, 0x66, 0x7d, 0x68, 0x80, - 0x66, 0x82, 0x62, 0x82, 0x5c, 0x81, 0x58, 0x81, 0x55, 0x80, 0x5a, 0x7f, - 0x5d, 0x80, 0x67, 0x80, 0x6f, 0x80, 0x70, 0x82, 0x73, 0x84, 0x73, 0x85, - 0x64, 0x8c, 0x72, 0x8e, 0x7a, 0x85, 0x70, 0x87, 0x6d, 0x83, 0x6f, 0x7e, - 0x6f, 0x7b, 0x6d, 0x7c, 0x72, 0x7b, 0x77, 0x7f, 0x7e, 0x7d, 0x75, 0x74, - 0x68, 0x6c, 0x6f, 0x6c, 0x76, 0x6f, 0x7d, 0x73, 0x7f, 0x73, 0x80, 0x73, - 0x7f, 0x75, 0x7f, 0x75, 0x7d, 0x75, 0x7e, 0x75, 0x7e, 0x75, 0x7e, 0x75, - 0x7c, 0x75, 0x7d, 0x75, 0x7d, 0x75, 0x7c, 0x75, 0x7d, 0x74, 0x7d, 0x74, - 0x7e, 0x73, 0x7f, 0x73, 0x80, 0x72, 0x80, 0x72, 0x80, 0x72, 0x82, 0x70, - 0x82, 0x70, 0x82, 0x6f, 0x82, 0x6f, 0x82, 0x70, 0x82, 0x70, 0x82, 0x70, - 0x82, 0x70, 0x83, 0x6f, 0x81, 0x71, 0x80, 0x73, 0x80, 0x78, 0x80, 0x7e, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x80, - 0x7f, 0x80, 0x7f, 0x80, 0x55, 0x63, 0x56, 0x63, 0x55, 0x65, 0x54, 0x68, - 0x53, 0x6a, 0x52, 0x6b, 0x50, 0x69, 0x4f, 0x69, 0x4d, 0x6a, 0x4d, 0x6b, - 0x4c, 0x6a, 0x4c, 0x6a, 0x4c, 0x6a, 0x4c, 0x67, 0x4c, 0x68, 0x4d, 0x66, - 0x4e, 0x66, 0x4e, 0x66, 0x4e, 0x66, 0x4e, 0x66, 0x4d, 0x66, 0x4c, 0x68, - 0x4c, 0x68, 0x4d, 0x68, 0x51, 0x68, 0x5a, 0x69, 0x63, 0x6a, 0x69, 0x6a, - 0x6d, 0x6c, 0x6f, 0x6e, 0x72, 0x70, 0x73, 0x70, 0x73, 0x6f, 0x73, 0x6f, - 0x73, 0x70, 0x73, 0x70, 0x72, 0x70, 0x72, 0x70, 0x72, 0x6e, 0x72, 0x6d, - 0x72, 0x6f, 0x71, 0x6f, 0x72, 0x6e, 0x71, 0x6c, 0x71, 0x6c, 0x71, 0x6e, - 0x71, 0x6e, 0x6f, 0x6e, 0x6a, 0x6b, 0x67, 0x6a, 0x62, 0x67, 0x5a, 0x65, - 0x56, 0x65, 0x4c, 0x62, 0x4d, 0x65, 0x5a, 0x77, 0x6f, 0x83, 0x73, 0x7c, - 0x74, 0x7b, 0x7c, 0x7d, 0x81, 0x7d, 0x85, 0x80, 0x86, 0x83, 0x75, 0x89, - 0x74, 0x89, 0x6e, 0x8b, 0x65, 0x89, 0x63, 0x84, 0x67, 0x80, 0x60, 0x79, - 0x4e, 0x7c, 0x30, 0x96, 0x3a, 0x97, 0x5d, 0x7b, 0x59, 0x81, 0x50, 0x8b, - 0x3c, 0x97, 0x3c, 0x99, 0x50, 0x89, 0x69, 0x73, 0x69, 0x75, 0x68, 0x7a, - 0x65, 0x7e, 0x65, 0x7e, 0x66, 0x7a, 0x66, 0x7a, 0x65, 0x7b, 0x65, 0x7b, - 0x63, 0x7d, 0x63, 0x7e, 0x63, 0x7d, 0x68, 0x82, 0x63, 0x82, 0x5e, 0x7f, - 0x58, 0x80, 0x58, 0x80, 0x57, 0x7f, 0x5b, 0x7f, 0x5f, 0x80, 0x6b, 0x80, - 0x6f, 0x80, 0x70, 0x82, 0x73, 0x84, 0x70, 0x85, 0x60, 0x8b, 0x7d, 0x8b, - 0x7e, 0x83, 0x6b, 0x84, 0x6a, 0x80, 0x6d, 0x7e, 0x6c, 0x7e, 0x6e, 0x7e, - 0x7c, 0x7e, 0x85, 0x7e, 0x83, 0x80, 0x80, 0x7d, 0x6a, 0x6e, 0x6b, 0x6b, - 0x71, 0x6e, 0x78, 0x73, 0x7d, 0x73, 0x80, 0x73, 0x7e, 0x74, 0x7f, 0x75, - 0x7d, 0x75, 0x7d, 0x75, 0x7e, 0x75, 0x7e, 0x74, 0x7d, 0x75, 0x7c, 0x75, - 0x7c, 0x75, 0x7c, 0x74, 0x7d, 0x75, 0x7d, 0x76, 0x7e, 0x74, 0x7f, 0x73, - 0x7f, 0x72, 0x80, 0x72, 0x81, 0x72, 0x82, 0x70, 0x82, 0x70, 0x82, 0x70, - 0x82, 0x6f, 0x82, 0x71, 0x82, 0x71, 0x84, 0x70, 0x84, 0x70, 0x83, 0x6f, - 0x81, 0x6f, 0x80, 0x70, 0x80, 0x78, 0x80, 0x7e, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, - 0x56, 0x60, 0x56, 0x61, 0x56, 0x63, 0x55, 0x66, 0x54, 0x67, 0x52, 0x6a, - 0x50, 0x69, 0x4f, 0x6a, 0x4d, 0x6b, 0x4d, 0x6b, 0x4c, 0x6a, 0x4b, 0x6a, - 0x4b, 0x6a, 0x4b, 0x69, 0x4b, 0x69, 0x4c, 0x67, 0x4d, 0x65, 0x4e, 0x66, - 0x4d, 0x65, 0x4d, 0x66, 0x4d, 0x67, 0x4c, 0x68, 0x4b, 0x68, 0x4c, 0x69, - 0x51, 0x69, 0x5c, 0x69, 0x63, 0x69, 0x69, 0x6b, 0x6d, 0x6d, 0x6f, 0x6d, - 0x71, 0x6e, 0x71, 0x6f, 0x73, 0x6e, 0x72, 0x6e, 0x71, 0x6f, 0x71, 0x6e, - 0x71, 0x6e, 0x71, 0x6f, 0x71, 0x6e, 0x71, 0x6e, 0x71, 0x6e, 0x71, 0x6e, - 0x71, 0x6d, 0x70, 0x6c, 0x6f, 0x6d, 0x70, 0x6e, 0x71, 0x6e, 0x70, 0x6e, - 0x6e, 0x6c, 0x6b, 0x6a, 0x66, 0x69, 0x61, 0x66, 0x5c, 0x64, 0x56, 0x63, - 0x57, 0x6a, 0x5f, 0x7b, 0x73, 0x7d, 0x78, 0x7c, 0x7a, 0x7d, 0x83, 0x7e, - 0x80, 0x80, 0x81, 0x80, 0x83, 0x82, 0x7f, 0x89, 0x77, 0x89, 0x72, 0x89, - 0x66, 0x8c, 0x62, 0x86, 0x60, 0x83, 0x61, 0x7c, 0x5e, 0x76, 0x4b, 0x7e, - 0x50, 0x80, 0x62, 0x6f, 0x55, 0x7b, 0x42, 0x8d, 0x31, 0x9e, 0x35, 0x9f, - 0x4f, 0x88, 0x6b, 0x72, 0x6b, 0x74, 0x67, 0x78, 0x66, 0x7a, 0x65, 0x7b, - 0x64, 0x7a, 0x64, 0x7a, 0x64, 0x7a, 0x63, 0x7a, 0x63, 0x7c, 0x62, 0x7c, - 0x63, 0x7d, 0x67, 0x82, 0x62, 0x83, 0x5b, 0x80, 0x57, 0x80, 0x5b, 0x80, - 0x5b, 0x82, 0x5c, 0x83, 0x62, 0x83, 0x6d, 0x80, 0x6e, 0x81, 0x70, 0x83, - 0x73, 0x85, 0x6e, 0x86, 0x61, 0x88, 0x83, 0x8a, 0x7a, 0x83, 0x67, 0x85, - 0x68, 0x81, 0x6a, 0x80, 0x6a, 0x80, 0x73, 0x7f, 0x84, 0x7d, 0x8b, 0x7c, - 0x84, 0x7f, 0x83, 0x7f, 0x6f, 0x73, 0x69, 0x6d, 0x6e, 0x6f, 0x74, 0x71, - 0x7a, 0x73, 0x7f, 0x74, 0x7f, 0x75, 0x7e, 0x74, 0x7d, 0x75, 0x7e, 0x75, - 0x7e, 0x75, 0x7e, 0x75, 0x7d, 0x75, 0x7d, 0x75, 0x7d, 0x75, 0x7d, 0x75, - 0x7e, 0x76, 0x7e, 0x76, 0x7f, 0x75, 0x7f, 0x74, 0x80, 0x73, 0x81, 0x72, - 0x81, 0x73, 0x83, 0x72, 0x82, 0x70, 0x83, 0x6f, 0x83, 0x6f, 0x84, 0x70, - 0x84, 0x6f, 0x85, 0x6f, 0x86, 0x70, 0x83, 0x70, 0x81, 0x6e, 0x81, 0x70, - 0x80, 0x76, 0x7f, 0x7d, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x57, 0x5e, 0x56, 0x61, - 0x56, 0x62, 0x56, 0x64, 0x55, 0x65, 0x52, 0x67, 0x50, 0x69, 0x4f, 0x6b, - 0x4d, 0x6b, 0x4c, 0x6b, 0x4b, 0x6a, 0x4a, 0x6b, 0x4b, 0x6a, 0x4b, 0x6a, - 0x4b, 0x6a, 0x4b, 0x69, 0x4b, 0x66, 0x4c, 0x66, 0x4c, 0x66, 0x4c, 0x67, - 0x4b, 0x68, 0x4b, 0x68, 0x4b, 0x68, 0x4c, 0x67, 0x51, 0x67, 0x5d, 0x68, - 0x64, 0x69, 0x68, 0x6c, 0x6e, 0x6d, 0x6f, 0x6d, 0x70, 0x6e, 0x70, 0x6e, - 0x72, 0x6d, 0x72, 0x6d, 0x70, 0x6e, 0x70, 0x6e, 0x70, 0x6e, 0x70, 0x6e, - 0x70, 0x6e, 0x70, 0x6e, 0x6f, 0x6d, 0x6f, 0x6d, 0x6f, 0x6d, 0x6f, 0x6d, - 0x6f, 0x6d, 0x6f, 0x6e, 0x6f, 0x6e, 0x70, 0x6e, 0x70, 0x6d, 0x6f, 0x6b, - 0x6b, 0x6c, 0x68, 0x69, 0x62, 0x66, 0x5e, 0x68, 0x60, 0x70, 0x6c, 0x7a, - 0x78, 0x7c, 0x7b, 0x7e, 0x7f, 0x7d, 0x7f, 0x80, 0x7e, 0x83, 0x77, 0x87, - 0x77, 0x8d, 0x81, 0x89, 0x7c, 0x88, 0x75, 0x86, 0x65, 0x8b, 0x61, 0x88, - 0x60, 0x83, 0x61, 0x80, 0x62, 0x7b, 0x5e, 0x76, 0x5e, 0x72, 0x60, 0x71, - 0x5d, 0x77, 0x4d, 0x82, 0x3a, 0x93, 0x43, 0x94, 0x5f, 0x82, 0x67, 0x78, - 0x67, 0x76, 0x66, 0x74, 0x65, 0x76, 0x65, 0x78, 0x63, 0x79, 0x63, 0x78, - 0x63, 0x77, 0x63, 0x78, 0x63, 0x78, 0x63, 0x79, 0x63, 0x7b, 0x65, 0x7e, - 0x65, 0x82, 0x5f, 0x80, 0x5a, 0x83, 0x5d, 0x85, 0x5e, 0x85, 0x5f, 0x85, - 0x69, 0x84, 0x6f, 0x7f, 0x6d, 0x84, 0x70, 0x86, 0x73, 0x87, 0x69, 0x8a, - 0x64, 0x88, 0x85, 0x88, 0x77, 0x82, 0x64, 0x85, 0x65, 0x82, 0x68, 0x80, - 0x68, 0x7f, 0x7c, 0x7f, 0x8a, 0x7d, 0x8d, 0x7c, 0x84, 0x7f, 0x82, 0x7f, - 0x74, 0x77, 0x65, 0x70, 0x69, 0x71, 0x6e, 0x71, 0x74, 0x73, 0x7a, 0x74, - 0x7e, 0x74, 0x7e, 0x74, 0x7d, 0x75, 0x7d, 0x75, 0x7d, 0x75, 0x7d, 0x75, - 0x7d, 0x75, 0x7d, 0x75, 0x7d, 0x75, 0x7d, 0x75, 0x7e, 0x75, 0x7f, 0x75, - 0x80, 0x75, 0x80, 0x75, 0x80, 0x74, 0x82, 0x73, 0x82, 0x73, 0x82, 0x73, - 0x83, 0x70, 0x85, 0x6f, 0x85, 0x6f, 0x85, 0x6e, 0x85, 0x6f, 0x86, 0x6f, - 0x85, 0x6f, 0x83, 0x70, 0x82, 0x6e, 0x82, 0x71, 0x80, 0x75, 0x7e, 0x7c, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x57, 0x5f, 0x56, 0x61, 0x56, 0x61, 0x56, 0x64, - 0x55, 0x65, 0x52, 0x66, 0x50, 0x69, 0x4f, 0x6b, 0x4e, 0x6b, 0x4d, 0x6a, - 0x4b, 0x6b, 0x4a, 0x6c, 0x4b, 0x6b, 0x4b, 0x69, 0x4b, 0x6a, 0x4a, 0x6a, - 0x4a, 0x68, 0x4b, 0x67, 0x4b, 0x68, 0x4c, 0x67, 0x4b, 0x67, 0x4b, 0x68, - 0x4b, 0x69, 0x4d, 0x66, 0x53, 0x66, 0x5e, 0x67, 0x63, 0x69, 0x69, 0x6c, - 0x6e, 0x6d, 0x6f, 0x6d, 0x70, 0x6e, 0x70, 0x6e, 0x71, 0x6e, 0x72, 0x6e, - 0x70, 0x6e, 0x70, 0x6e, 0x70, 0x6e, 0x70, 0x6e, 0x70, 0x6e, 0x71, 0x6e, - 0x6f, 0x6e, 0x6d, 0x6e, 0x6e, 0x6e, 0x6f, 0x6d, 0x6f, 0x6d, 0x6f, 0x6e, - 0x70, 0x6e, 0x70, 0x6e, 0x70, 0x6e, 0x72, 0x6d, 0x71, 0x6d, 0x6c, 0x6a, - 0x67, 0x6a, 0x62, 0x6b, 0x66, 0x73, 0x73, 0x79, 0x7a, 0x7b, 0x7c, 0x7e, - 0x7f, 0x7f, 0x7b, 0x81, 0x7d, 0x81, 0x75, 0x87, 0x72, 0x8e, 0x7b, 0x8b, - 0x80, 0x88, 0x7a, 0x86, 0x6b, 0x89, 0x61, 0x88, 0x60, 0x85, 0x61, 0x81, - 0x62, 0x7e, 0x5f, 0x7a, 0x5e, 0x74, 0x5f, 0x75, 0x5f, 0x79, 0x58, 0x7c, - 0x53, 0x81, 0x54, 0x81, 0x60, 0x7b, 0x64, 0x78, 0x63, 0x74, 0x63, 0x72, - 0x63, 0x75, 0x64, 0x77, 0x66, 0x78, 0x65, 0x77, 0x63, 0x76, 0x63, 0x76, - 0x63, 0x77, 0x62, 0x78, 0x61, 0x79, 0x63, 0x7d, 0x63, 0x81, 0x5f, 0x7e, - 0x5e, 0x81, 0x5e, 0x85, 0x60, 0x86, 0x62, 0x85, 0x6b, 0x82, 0x72, 0x7e, - 0x6f, 0x83, 0x6d, 0x87, 0x6c, 0x8a, 0x62, 0x8d, 0x68, 0x8a, 0x84, 0x84, - 0x76, 0x82, 0x62, 0x86, 0x62, 0x82, 0x69, 0x81, 0x71, 0x7f, 0x7f, 0x7f, - 0x89, 0x7d, 0x8b, 0x7d, 0x83, 0x7f, 0x81, 0x7f, 0x78, 0x79, 0x61, 0x72, - 0x64, 0x73, 0x6a, 0x72, 0x6f, 0x72, 0x76, 0x74, 0x7c, 0x75, 0x7f, 0x74, - 0x7e, 0x75, 0x7d, 0x75, 0x7d, 0x75, 0x7d, 0x75, 0x7d, 0x75, 0x7d, 0x75, - 0x7d, 0x75, 0x7d, 0x75, 0x7e, 0x75, 0x7f, 0x75, 0x7f, 0x75, 0x80, 0x75, - 0x80, 0x74, 0x82, 0x72, 0x82, 0x73, 0x82, 0x72, 0x83, 0x70, 0x85, 0x6f, - 0x86, 0x6f, 0x85, 0x6f, 0x85, 0x6f, 0x86, 0x6f, 0x85, 0x6f, 0x84, 0x70, - 0x83, 0x6e, 0x83, 0x71, 0x80, 0x75, 0x7f, 0x7d, 0x7f, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7e, - 0x58, 0x5e, 0x57, 0x5e, 0x57, 0x60, 0x56, 0x63, 0x55, 0x63, 0x54, 0x64, - 0x52, 0x69, 0x50, 0x6b, 0x4f, 0x6a, 0x4d, 0x6a, 0x4c, 0x6c, 0x4b, 0x6d, - 0x4a, 0x6c, 0x49, 0x6a, 0x49, 0x6a, 0x49, 0x6a, 0x4a, 0x6a, 0x4a, 0x69, - 0x4a, 0x68, 0x4b, 0x67, 0x4b, 0x67, 0x4b, 0x67, 0x4b, 0x67, 0x4e, 0x66, - 0x56, 0x65, 0x60, 0x66, 0x65, 0x69, 0x69, 0x6b, 0x6d, 0x6c, 0x6f, 0x6b, - 0x70, 0x6c, 0x70, 0x6c, 0x70, 0x6d, 0x70, 0x6d, 0x70, 0x6e, 0x6f, 0x6e, - 0x70, 0x6d, 0x70, 0x6d, 0x6f, 0x6d, 0x6f, 0x6d, 0x6e, 0x6d, 0x6d, 0x6d, - 0x6e, 0x6d, 0x6e, 0x6d, 0x6e, 0x6d, 0x6e, 0x6d, 0x6f, 0x6d, 0x70, 0x6d, - 0x72, 0x6d, 0x75, 0x6e, 0x75, 0x6e, 0x6f, 0x6d, 0x69, 0x6d, 0x67, 0x6e, - 0x6b, 0x75, 0x73, 0x7a, 0x77, 0x7c, 0x7b, 0x7d, 0x7f, 0x7e, 0x7d, 0x80, - 0x7a, 0x83, 0x78, 0x84, 0x76, 0x85, 0x71, 0x8c, 0x7f, 0x89, 0x81, 0x85, - 0x73, 0x87, 0x5f, 0x8b, 0x5e, 0x89, 0x60, 0x85, 0x60, 0x84, 0x5f, 0x7e, - 0x5f, 0x7a, 0x60, 0x7a, 0x5e, 0x7b, 0x5c, 0x7a, 0x5f, 0x74, 0x5e, 0x71, - 0x62, 0x70, 0x62, 0x6f, 0x62, 0x6f, 0x62, 0x6f, 0x62, 0x72, 0x64, 0x74, - 0x66, 0x77, 0x65, 0x77, 0x63, 0x75, 0x63, 0x74, 0x63, 0x74, 0x63, 0x76, - 0x61, 0x79, 0x60, 0x7b, 0x5b, 0x7b, 0x5a, 0x7b, 0x5e, 0x7d, 0x5d, 0x81, - 0x60, 0x83, 0x64, 0x83, 0x6a, 0x7f, 0x75, 0x7c, 0x74, 0x80, 0x6a, 0x88, - 0x63, 0x8b, 0x5d, 0x8b, 0x6d, 0x8b, 0x7b, 0x88, 0x74, 0x82, 0x62, 0x85, - 0x64, 0x83, 0x6e, 0x7f, 0x80, 0x7d, 0x82, 0x7f, 0x86, 0x7c, 0x89, 0x7b, - 0x82, 0x7f, 0x81, 0x80, 0x7b, 0x7b, 0x60, 0x73, 0x60, 0x73, 0x65, 0x72, - 0x69, 0x72, 0x71, 0x74, 0x79, 0x74, 0x7d, 0x75, 0x7e, 0x75, 0x7d, 0x75, - 0x7d, 0x75, 0x7e, 0x75, 0x7d, 0x75, 0x7e, 0x75, 0x7d, 0x75, 0x7d, 0x75, - 0x7e, 0x75, 0x7e, 0x75, 0x7f, 0x75, 0x80, 0x75, 0x80, 0x74, 0x82, 0x72, - 0x82, 0x73, 0x83, 0x71, 0x85, 0x6f, 0x87, 0x6f, 0x87, 0x6f, 0x86, 0x6f, - 0x86, 0x6f, 0x86, 0x6f, 0x87, 0x6f, 0x85, 0x70, 0x85, 0x70, 0x83, 0x71, - 0x7f, 0x75, 0x7e, 0x7c, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x80, 0x7f, 0x59, 0x5d, 0x58, 0x5d, - 0x57, 0x5f, 0x56, 0x61, 0x56, 0x61, 0x54, 0x63, 0x53, 0x68, 0x51, 0x69, - 0x4f, 0x68, 0x4d, 0x69, 0x4c, 0x6c, 0x4b, 0x6d, 0x49, 0x6d, 0x49, 0x6a, - 0x49, 0x6a, 0x49, 0x69, 0x49, 0x6a, 0x49, 0x69, 0x4a, 0x68, 0x49, 0x67, - 0x49, 0x67, 0x4b, 0x67, 0x4b, 0x67, 0x4e, 0x66, 0x57, 0x66, 0x62, 0x66, - 0x66, 0x68, 0x68, 0x6a, 0x6c, 0x6b, 0x6e, 0x6a, 0x6f, 0x6b, 0x6f, 0x6b, - 0x6f, 0x6d, 0x6f, 0x6d, 0x6f, 0x6d, 0x6f, 0x6d, 0x6f, 0x6d, 0x6f, 0x6c, - 0x6d, 0x6c, 0x6d, 0x6c, 0x6e, 0x6c, 0x6e, 0x6d, 0x6e, 0x6c, 0x6e, 0x6d, - 0x6e, 0x6d, 0x6d, 0x6c, 0x6e, 0x6c, 0x6f, 0x6c, 0x72, 0x6d, 0x75, 0x6e, - 0x75, 0x6e, 0x6e, 0x6e, 0x67, 0x6e, 0x69, 0x71, 0x70, 0x77, 0x76, 0x7c, - 0x78, 0x7d, 0x78, 0x7e, 0x79, 0x7d, 0x7a, 0x7f, 0x78, 0x85, 0x77, 0x86, - 0x77, 0x88, 0x6f, 0x89, 0x7a, 0x87, 0x80, 0x87, 0x70, 0x86, 0x5b, 0x8b, - 0x5e, 0x89, 0x61, 0x86, 0x5f, 0x87, 0x60, 0x81, 0x62, 0x7d, 0x63, 0x7c, - 0x5e, 0x7a, 0x5d, 0x77, 0x5f, 0x70, 0x60, 0x6e, 0x61, 0x6d, 0x62, 0x6e, - 0x62, 0x6e, 0x62, 0x6e, 0x62, 0x70, 0x62, 0x72, 0x62, 0x73, 0x62, 0x75, - 0x61, 0x75, 0x61, 0x75, 0x63, 0x73, 0x63, 0x76, 0x61, 0x79, 0x5d, 0x79, - 0x58, 0x76, 0x58, 0x78, 0x5a, 0x7d, 0x5a, 0x7f, 0x5f, 0x80, 0x63, 0x7f, - 0x6a, 0x7d, 0x78, 0x7c, 0x73, 0x80, 0x6a, 0x89, 0x62, 0x8a, 0x5c, 0x8a, - 0x6f, 0x8d, 0x75, 0x8f, 0x70, 0x84, 0x62, 0x84, 0x68, 0x83, 0x74, 0x7e, - 0x84, 0x7b, 0x85, 0x7d, 0x88, 0x7b, 0x89, 0x7a, 0x81, 0x7f, 0x81, 0x80, - 0x7b, 0x7c, 0x61, 0x73, 0x5f, 0x73, 0x62, 0x73, 0x65, 0x72, 0x6d, 0x74, - 0x76, 0x73, 0x7c, 0x75, 0x7e, 0x75, 0x7e, 0x75, 0x7e, 0x75, 0x7e, 0x75, - 0x7e, 0x74, 0x7e, 0x74, 0x7d, 0x75, 0x7c, 0x76, 0x7e, 0x75, 0x7f, 0x74, - 0x7f, 0x75, 0x80, 0x75, 0x80, 0x74, 0x82, 0x73, 0x82, 0x72, 0x84, 0x71, - 0x87, 0x6e, 0x87, 0x6e, 0x87, 0x6f, 0x87, 0x6f, 0x87, 0x6f, 0x87, 0x6f, - 0x88, 0x6f, 0x85, 0x6f, 0x84, 0x71, 0x83, 0x70, 0x7f, 0x75, 0x7e, 0x7c, - 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, - 0x80, 0x7f, 0x80, 0x7f, 0x57, 0x5e, 0x58, 0x5e, 0x57, 0x5e, 0x57, 0x61, - 0x57, 0x62, 0x54, 0x63, 0x53, 0x67, 0x52, 0x68, 0x50, 0x68, 0x4e, 0x69, - 0x4c, 0x6c, 0x4b, 0x6d, 0x49, 0x6d, 0x49, 0x6a, 0x49, 0x6b, 0x49, 0x6a, - 0x49, 0x6a, 0x49, 0x69, 0x49, 0x69, 0x49, 0x67, 0x49, 0x67, 0x4a, 0x67, - 0x4b, 0x67, 0x4e, 0x66, 0x57, 0x65, 0x61, 0x66, 0x64, 0x69, 0x66, 0x6b, - 0x6a, 0x6b, 0x6c, 0x6b, 0x6e, 0x6b, 0x6d, 0x6b, 0x6f, 0x6d, 0x6f, 0x6d, - 0x6f, 0x6e, 0x6f, 0x6d, 0x70, 0x6d, 0x70, 0x6d, 0x6e, 0x6d, 0x6e, 0x6d, - 0x6e, 0x6c, 0x6e, 0x6d, 0x6e, 0x6d, 0x6e, 0x6d, 0x6e, 0x6d, 0x6d, 0x6d, - 0x6d, 0x6d, 0x6f, 0x6c, 0x73, 0x6d, 0x75, 0x6e, 0x75, 0x6e, 0x6c, 0x6e, - 0x65, 0x6e, 0x69, 0x72, 0x77, 0x77, 0x80, 0x7a, 0x82, 0x7f, 0x7e, 0x80, - 0x78, 0x7f, 0x76, 0x7f, 0x73, 0x82, 0x75, 0x85, 0x72, 0x88, 0x6c, 0x8a, - 0x76, 0x89, 0x7b, 0x8b, 0x75, 0x85, 0x63, 0x87, 0x5e, 0x8a, 0x5f, 0x88, - 0x5e, 0x87, 0x62, 0x83, 0x68, 0x81, 0x65, 0x7d, 0x5e, 0x7b, 0x5d, 0x77, - 0x5f, 0x6e, 0x60, 0x6d, 0x61, 0x6c, 0x63, 0x6e, 0x63, 0x6e, 0x62, 0x6d, - 0x62, 0x6f, 0x61, 0x6f, 0x60, 0x70, 0x5f, 0x73, 0x60, 0x77, 0x5f, 0x79, - 0x5f, 0x76, 0x5f, 0x75, 0x5f, 0x77, 0x5b, 0x77, 0x58, 0x77, 0x58, 0x79, - 0x58, 0x7d, 0x5a, 0x7d, 0x60, 0x7c, 0x63, 0x7c, 0x6b, 0x7c, 0x76, 0x7e, - 0x6f, 0x83, 0x66, 0x8b, 0x5c, 0x8a, 0x57, 0x89, 0x6d, 0x8c, 0x73, 0x8f, - 0x71, 0x85, 0x5f, 0x86, 0x68, 0x81, 0x7b, 0x7e, 0x84, 0x7b, 0x88, 0x7b, - 0x8c, 0x79, 0x8a, 0x79, 0x81, 0x7f, 0x81, 0x80, 0x7a, 0x7c, 0x5f, 0x73, - 0x5d, 0x72, 0x61, 0x71, 0x63, 0x70, 0x67, 0x72, 0x72, 0x74, 0x7a, 0x75, - 0x7e, 0x75, 0x7e, 0x75, 0x7e, 0x75, 0x7d, 0x75, 0x7b, 0x75, 0x7b, 0x74, - 0x7d, 0x75, 0x7d, 0x75, 0x7e, 0x75, 0x7f, 0x74, 0x7f, 0x75, 0x80, 0x75, - 0x81, 0x74, 0x82, 0x73, 0x82, 0x73, 0x85, 0x71, 0x87, 0x6e, 0x87, 0x6f, - 0x87, 0x6f, 0x87, 0x6f, 0x87, 0x6f, 0x87, 0x6f, 0x87, 0x6f, 0x85, 0x6f, - 0x84, 0x71, 0x83, 0x70, 0x80, 0x75, 0x7f, 0x7c, 0x7f, 0x80, 0x7f, 0x7f, - 0x80, 0x7f, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7e, 0x80, 0x80, 0x80, 0x7f, - 0x57, 0x60, 0x58, 0x60, 0x57, 0x5e, 0x57, 0x61, 0x57, 0x62, 0x54, 0x64, - 0x53, 0x66, 0x51, 0x66, 0x4f, 0x67, 0x4e, 0x69, 0x4d, 0x6b, 0x4b, 0x6d, - 0x4a, 0x6c, 0x49, 0x6b, 0x49, 0x6b, 0x49, 0x6a, 0x49, 0x6a, 0x49, 0x69, - 0x49, 0x69, 0x49, 0x68, 0x49, 0x67, 0x4a, 0x68, 0x4b, 0x68, 0x4d, 0x66, - 0x57, 0x65, 0x60, 0x66, 0x63, 0x68, 0x65, 0x6a, 0x69, 0x6b, 0x6a, 0x6b, - 0x6c, 0x6b, 0x6c, 0x6b, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x6f, 0x6e, - 0x6f, 0x6d, 0x6f, 0x6d, 0x6e, 0x6d, 0x6e, 0x6c, 0x6e, 0x6d, 0x6e, 0x6c, - 0x6e, 0x6c, 0x6e, 0x6c, 0x6e, 0x6d, 0x6e, 0x6d, 0x6d, 0x6c, 0x6f, 0x6d, - 0x72, 0x6d, 0x75, 0x6e, 0x75, 0x6e, 0x6a, 0x6d, 0x64, 0x6d, 0x6a, 0x71, - 0x7c, 0x75, 0x88, 0x74, 0x89, 0x81, 0x86, 0x83, 0x7e, 0x80, 0x75, 0x80, - 0x6f, 0x84, 0x70, 0x82, 0x6f, 0x82, 0x6e, 0x8a, 0x71, 0x88, 0x74, 0x8c, - 0x74, 0x84, 0x64, 0x85, 0x58, 0x8e, 0x5b, 0x8c, 0x5c, 0x88, 0x63, 0x84, - 0x6c, 0x83, 0x67, 0x7f, 0x5f, 0x7e, 0x5d, 0x7b, 0x5f, 0x6e, 0x60, 0x6b, - 0x61, 0x6b, 0x62, 0x6e, 0x62, 0x6e, 0x62, 0x6c, 0x62, 0x6d, 0x62, 0x70, - 0x62, 0x73, 0x61, 0x74, 0x5f, 0x78, 0x5e, 0x7d, 0x5d, 0x79, 0x5d, 0x75, - 0x5d, 0x76, 0x5a, 0x76, 0x58, 0x77, 0x58, 0x79, 0x59, 0x7e, 0x5e, 0x7b, - 0x62, 0x79, 0x63, 0x79, 0x69, 0x7a, 0x71, 0x80, 0x6b, 0x85, 0x64, 0x8b, - 0x59, 0x88, 0x54, 0x84, 0x69, 0x88, 0x70, 0x8c, 0x74, 0x83, 0x5d, 0x87, - 0x67, 0x80, 0x7e, 0x7f, 0x85, 0x7b, 0x8b, 0x79, 0x8f, 0x77, 0x8c, 0x78, - 0x81, 0x7f, 0x81, 0x80, 0x7a, 0x7c, 0x5f, 0x73, 0x5c, 0x73, 0x60, 0x71, - 0x61, 0x6f, 0x63, 0x71, 0x6e, 0x73, 0x79, 0x75, 0x7e, 0x75, 0x7e, 0x75, - 0x7e, 0x74, 0x7d, 0x74, 0x7a, 0x75, 0x7a, 0x75, 0x7c, 0x75, 0x7d, 0x76, - 0x7e, 0x75, 0x7f, 0x75, 0x80, 0x75, 0x80, 0x75, 0x81, 0x74, 0x82, 0x73, - 0x82, 0x73, 0x84, 0x71, 0x86, 0x6e, 0x87, 0x6f, 0x87, 0x6f, 0x87, 0x6f, - 0x87, 0x6f, 0x87, 0x6f, 0x87, 0x6f, 0x85, 0x6f, 0x85, 0x71, 0x83, 0x71, - 0x7f, 0x75, 0x7f, 0x7b, 0x7f, 0x80, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80, - 0x7f, 0x7e, 0x80, 0x7e, 0x80, 0x7f, 0x80, 0x7f, 0x57, 0x5f, 0x57, 0x5f, - 0x57, 0x5f, 0x57, 0x61, 0x56, 0x62, 0x55, 0x64, 0x54, 0x65, 0x52, 0x65, - 0x50, 0x68, 0x4f, 0x69, 0x4d, 0x6b, 0x4b, 0x6d, 0x4a, 0x6c, 0x49, 0x6a, - 0x49, 0x6a, 0x49, 0x6a, 0x49, 0x6b, 0x49, 0x69, 0x49, 0x6a, 0x49, 0x69, - 0x49, 0x69, 0x49, 0x69, 0x4a, 0x68, 0x4e, 0x66, 0x58, 0x66, 0x60, 0x66, - 0x62, 0x68, 0x64, 0x6a, 0x68, 0x6a, 0x6a, 0x6a, 0x6b, 0x6a, 0x6c, 0x6a, - 0x6e, 0x6b, 0x6f, 0x6c, 0x6e, 0x6d, 0x6e, 0x6d, 0x6f, 0x6c, 0x6e, 0x6c, - 0x6e, 0x6b, 0x6d, 0x6b, 0x6d, 0x6b, 0x6d, 0x6b, 0x6d, 0x6c, 0x6d, 0x6d, - 0x6d, 0x6d, 0x6e, 0x6d, 0x6f, 0x6b, 0x70, 0x6b, 0x74, 0x6d, 0x76, 0x6e, - 0x75, 0x6e, 0x68, 0x6d, 0x61, 0x6e, 0x6b, 0x73, 0x80, 0x74, 0x8b, 0x75, - 0x91, 0x84, 0x8e, 0x82, 0x83, 0x80, 0x7c, 0x81, 0x72, 0x83, 0x6d, 0x82, - 0x6e, 0x84, 0x71, 0x87, 0x71, 0x89, 0x74, 0x8b, 0x74, 0x86, 0x5f, 0x89, - 0x56, 0x90, 0x5c, 0x89, 0x60, 0x86, 0x66, 0x83, 0x6a, 0x80, 0x68, 0x7e, - 0x61, 0x7f, 0x5c, 0x7b, 0x5d, 0x6d, 0x5f, 0x6b, 0x61, 0x6b, 0x62, 0x6c, - 0x62, 0x6c, 0x62, 0x6c, 0x62, 0x6d, 0x63, 0x70, 0x61, 0x74, 0x60, 0x74, - 0x5e, 0x76, 0x5c, 0x7b, 0x5d, 0x78, 0x5d, 0x74, 0x5d, 0x74, 0x5c, 0x75, - 0x5a, 0x77, 0x5a, 0x78, 0x5b, 0x7a, 0x5f, 0x79, 0x64, 0x7a, 0x64, 0x7b, - 0x67, 0x7c, 0x6d, 0x82, 0x68, 0x87, 0x63, 0x8b, 0x59, 0x86, 0x54, 0x84, - 0x66, 0x85, 0x72, 0x8a, 0x73, 0x84, 0x5b, 0x88, 0x6a, 0x81, 0x7f, 0x7f, - 0x86, 0x7c, 0x8a, 0x79, 0x8e, 0x79, 0x8a, 0x7a, 0x82, 0x7f, 0x80, 0x80, - 0x79, 0x7c, 0x60, 0x73, 0x5e, 0x72, 0x60, 0x71, 0x61, 0x70, 0x64, 0x71, - 0x6d, 0x72, 0x75, 0x75, 0x7d, 0x75, 0x7d, 0x75, 0x7c, 0x74, 0x7b, 0x74, - 0x7b, 0x74, 0x7b, 0x74, 0x7b, 0x74, 0x7c, 0x74, 0x7c, 0x74, 0x7e, 0x75, - 0x7f, 0x75, 0x80, 0x75, 0x82, 0x74, 0x83, 0x73, 0x84, 0x73, 0x85, 0x71, - 0x87, 0x6e, 0x88, 0x6f, 0x88, 0x6f, 0x87, 0x6e, 0x87, 0x6e, 0x88, 0x6f, - 0x87, 0x6f, 0x86, 0x6f, 0x86, 0x6f, 0x84, 0x70, 0x7f, 0x74, 0x7e, 0x7c, - 0x80, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7e, 0x7f, 0x7e, - 0x80, 0x7f, 0x80, 0x7f, 0x56, 0x60, 0x56, 0x60, 0x57, 0x61, 0x56, 0x60, - 0x56, 0x61, 0x55, 0x62, 0x54, 0x63, 0x52, 0x65, 0x50, 0x68, 0x50, 0x69, - 0x4d, 0x6a, 0x4c, 0x6b, 0x4b, 0x6b, 0x49, 0x69, 0x49, 0x6a, 0x48, 0x6b, - 0x48, 0x6b, 0x48, 0x6a, 0x48, 0x69, 0x48, 0x6a, 0x48, 0x6a, 0x48, 0x6a, - 0x49, 0x68, 0x50, 0x66, 0x59, 0x66, 0x5f, 0x66, 0x61, 0x69, 0x64, 0x6a, - 0x68, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6c, 0x6a, 0x6d, 0x6a, 0x6e, 0x6b, - 0x6d, 0x6d, 0x6d, 0x6c, 0x6e, 0x6a, 0x6e, 0x6b, 0x6d, 0x6b, 0x6d, 0x6b, - 0x6d, 0x6a, 0x6d, 0x6a, 0x6d, 0x6b, 0x6d, 0x6d, 0x6c, 0x6d, 0x6e, 0x6d, - 0x71, 0x6b, 0x73, 0x6c, 0x75, 0x6e, 0x75, 0x6f, 0x6e, 0x73, 0x66, 0x76, - 0x61, 0x75, 0x6f, 0x74, 0x84, 0x73, 0x8b, 0x78, 0x95, 0x86, 0x93, 0x81, - 0x8c, 0x81, 0x8d, 0x88, 0x7f, 0x83, 0x6b, 0x84, 0x6b, 0x85, 0x6c, 0x86, - 0x6c, 0x8c, 0x76, 0x89, 0x75, 0x87, 0x5b, 0x8c, 0x59, 0x8d, 0x64, 0x83, - 0x6a, 0x82, 0x70, 0x7f, 0x6e, 0x7d, 0x6a, 0x7d, 0x65, 0x7d, 0x5d, 0x7a, - 0x5c, 0x6e, 0x5f, 0x6b, 0x61, 0x6a, 0x62, 0x6a, 0x62, 0x6a, 0x62, 0x6b, - 0x62, 0x6b, 0x62, 0x6e, 0x5f, 0x72, 0x5e, 0x72, 0x5d, 0x74, 0x5b, 0x75, - 0x5d, 0x74, 0x5d, 0x72, 0x5d, 0x74, 0x5d, 0x75, 0x5c, 0x74, 0x5c, 0x74, - 0x5d, 0x75, 0x5f, 0x76, 0x66, 0x7b, 0x69, 0x7d, 0x68, 0x7d, 0x68, 0x82, - 0x63, 0x87, 0x5f, 0x8a, 0x5b, 0x84, 0x57, 0x81, 0x5d, 0x81, 0x6d, 0x86, - 0x75, 0x84, 0x5f, 0x86, 0x73, 0x81, 0x82, 0x7f, 0x88, 0x7d, 0x88, 0x7b, - 0x8a, 0x7b, 0x89, 0x7c, 0x83, 0x7f, 0x80, 0x80, 0x74, 0x7c, 0x5f, 0x72, - 0x5f, 0x72, 0x5f, 0x71, 0x60, 0x6f, 0x64, 0x6f, 0x6a, 0x71, 0x70, 0x74, - 0x7b, 0x75, 0x7d, 0x75, 0x7b, 0x73, 0x7a, 0x73, 0x7a, 0x72, 0x7a, 0x72, - 0x7a, 0x73, 0x7a, 0x72, 0x7b, 0x72, 0x7d, 0x73, 0x7e, 0x74, 0x80, 0x75, - 0x82, 0x74, 0x84, 0x73, 0x86, 0x73, 0x86, 0x71, 0x88, 0x6e, 0x88, 0x6f, - 0x89, 0x6f, 0x88, 0x6e, 0x88, 0x6e, 0x88, 0x6f, 0x88, 0x6f, 0x87, 0x70, - 0x87, 0x70, 0x85, 0x70, 0x80, 0x74, 0x7e, 0x7c, 0x80, 0x7f, 0x80, 0x7f, - 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7e, 0x7f, 0x7e, 0x7f, 0x7e, 0x7f, 0x7e, - 0x56, 0x61, 0x56, 0x61, 0x56, 0x60, 0x57, 0x61, 0x56, 0x61, 0x55, 0x61, - 0x55, 0x63, 0x53, 0x66, 0x51, 0x67, 0x51, 0x67, 0x4f, 0x69, 0x4d, 0x6a, - 0x4b, 0x6a, 0x49, 0x6a, 0x49, 0x6a, 0x48, 0x6b, 0x48, 0x6b, 0x49, 0x6a, - 0x4a, 0x6a, 0x49, 0x6a, 0x49, 0x6a, 0x48, 0x6a, 0x49, 0x68, 0x52, 0x66, - 0x5a, 0x65, 0x5d, 0x66, 0x62, 0x68, 0x65, 0x6a, 0x68, 0x6a, 0x69, 0x6a, - 0x6a, 0x6a, 0x6c, 0x6a, 0x6d, 0x6b, 0x6f, 0x6b, 0x6d, 0x6d, 0x6e, 0x6d, - 0x6e, 0x6b, 0x6e, 0x6b, 0x6d, 0x6b, 0x6d, 0x6b, 0x6d, 0x6b, 0x6d, 0x6a, - 0x6d, 0x6c, 0x6d, 0x6d, 0x6c, 0x6d, 0x6e, 0x6d, 0x72, 0x6d, 0x73, 0x6e, - 0x71, 0x71, 0x6e, 0x76, 0x68, 0x7d, 0x67, 0x81, 0x64, 0x7e, 0x74, 0x72, - 0x84, 0x72, 0x89, 0x78, 0x93, 0x86, 0x92, 0x84, 0x91, 0x85, 0x93, 0x88, - 0x8a, 0x83, 0x6f, 0x85, 0x6d, 0x83, 0x6a, 0x88, 0x65, 0x8b, 0x70, 0x86, - 0x73, 0x87, 0x62, 0x8c, 0x62, 0x87, 0x69, 0x80, 0x6e, 0x7f, 0x75, 0x7b, - 0x74, 0x7b, 0x6d, 0x7b, 0x66, 0x7b, 0x5f, 0x7a, 0x5d, 0x6f, 0x5f, 0x6a, - 0x61, 0x69, 0x63, 0x68, 0x62, 0x68, 0x62, 0x69, 0x62, 0x6a, 0x61, 0x6c, - 0x5d, 0x6e, 0x5d, 0x6f, 0x5d, 0x71, 0x5b, 0x6f, 0x5d, 0x70, 0x5d, 0x6f, - 0x5d, 0x73, 0x5d, 0x73, 0x5e, 0x71, 0x5e, 0x70, 0x5f, 0x71, 0x5f, 0x75, - 0x63, 0x7b, 0x6a, 0x7c, 0x6b, 0x7d, 0x68, 0x82, 0x60, 0x86, 0x5c, 0x88, - 0x59, 0x81, 0x58, 0x7e, 0x59, 0x7c, 0x65, 0x81, 0x78, 0x83, 0x68, 0x83, - 0x74, 0x7e, 0x82, 0x81, 0x86, 0x80, 0x85, 0x7e, 0x86, 0x7e, 0x88, 0x7c, - 0x84, 0x7e, 0x7e, 0x7f, 0x6f, 0x7a, 0x5f, 0x72, 0x5f, 0x73, 0x5f, 0x71, - 0x61, 0x6e, 0x63, 0x6e, 0x67, 0x70, 0x6d, 0x72, 0x78, 0x75, 0x7d, 0x75, - 0x7c, 0x72, 0x7a, 0x72, 0x78, 0x70, 0x78, 0x71, 0x78, 0x70, 0x78, 0x71, - 0x79, 0x71, 0x7c, 0x71, 0x7e, 0x73, 0x81, 0x75, 0x82, 0x74, 0x84, 0x73, - 0x86, 0x73, 0x86, 0x71, 0x88, 0x6e, 0x88, 0x6f, 0x88, 0x70, 0x88, 0x6e, - 0x88, 0x6e, 0x88, 0x6f, 0x88, 0x6f, 0x87, 0x71, 0x87, 0x72, 0x86, 0x71, - 0x82, 0x74, 0x7f, 0x7c, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80, 0x80, 0x7f, - 0x7f, 0x7e, 0x7f, 0x7e, 0x7f, 0x7f, 0x7f, 0x7e, 0x56, 0x63, 0x56, 0x62, - 0x56, 0x60, 0x57, 0x60, 0x57, 0x5f, 0x56, 0x60, 0x56, 0x62, 0x54, 0x65, - 0x52, 0x67, 0x52, 0x67, 0x50, 0x68, 0x4e, 0x6a, 0x4c, 0x69, 0x4b, 0x69, - 0x4a, 0x6a, 0x49, 0x6b, 0x48, 0x6b, 0x49, 0x6a, 0x49, 0x6a, 0x49, 0x6b, - 0x49, 0x6b, 0x48, 0x6a, 0x49, 0x68, 0x52, 0x67, 0x59, 0x67, 0x5e, 0x67, - 0x61, 0x68, 0x64, 0x69, 0x67, 0x68, 0x69, 0x69, 0x6a, 0x69, 0x6c, 0x6a, - 0x6e, 0x6a, 0x70, 0x6b, 0x6e, 0x6c, 0x6e, 0x6c, 0x6d, 0x6b, 0x6d, 0x6a, - 0x6c, 0x6a, 0x6c, 0x6b, 0x6c, 0x6b, 0x6c, 0x6a, 0x6c, 0x6b, 0x6c, 0x6c, - 0x6d, 0x6c, 0x70, 0x6c, 0x72, 0x6b, 0x6e, 0x6e, 0x69, 0x77, 0x67, 0x80, - 0x67, 0x84, 0x66, 0x86, 0x65, 0x82, 0x77, 0x73, 0x85, 0x73, 0x8a, 0x79, - 0x91, 0x82, 0x8f, 0x81, 0x8f, 0x84, 0x90, 0x85, 0x8e, 0x7e, 0x79, 0x82, - 0x71, 0x83, 0x6b, 0x87, 0x60, 0x8c, 0x6b, 0x86, 0x73, 0x86, 0x75, 0x88, - 0x6f, 0x81, 0x6a, 0x7c, 0x6f, 0x7b, 0x74, 0x79, 0x76, 0x7a, 0x71, 0x7a, - 0x69, 0x79, 0x62, 0x79, 0x60, 0x72, 0x60, 0x6c, 0x60, 0x6a, 0x61, 0x6a, - 0x62, 0x6a, 0x63, 0x68, 0x62, 0x68, 0x61, 0x69, 0x5e, 0x6b, 0x5d, 0x6c, - 0x5c, 0x6f, 0x5b, 0x6e, 0x5d, 0x6e, 0x5d, 0x6d, 0x5d, 0x6e, 0x5d, 0x6e, - 0x5e, 0x6e, 0x5f, 0x6e, 0x5e, 0x71, 0x60, 0x75, 0x62, 0x7b, 0x66, 0x7d, - 0x69, 0x7f, 0x68, 0x84, 0x60, 0x87, 0x59, 0x87, 0x56, 0x81, 0x56, 0x7d, - 0x5b, 0x79, 0x61, 0x7d, 0x77, 0x81, 0x6b, 0x81, 0x6c, 0x7e, 0x78, 0x81, - 0x80, 0x80, 0x82, 0x7f, 0x88, 0x7e, 0x8b, 0x7d, 0x81, 0x7e, 0x77, 0x7a, - 0x6b, 0x77, 0x60, 0x71, 0x5f, 0x71, 0x5f, 0x6e, 0x61, 0x6d, 0x62, 0x6d, - 0x65, 0x6f, 0x6a, 0x72, 0x75, 0x74, 0x7c, 0x74, 0x7b, 0x72, 0x79, 0x71, - 0x77, 0x71, 0x77, 0x71, 0x77, 0x70, 0x77, 0x6f, 0x77, 0x71, 0x7a, 0x71, - 0x7c, 0x72, 0x7f, 0x74, 0x81, 0x73, 0x83, 0x72, 0x85, 0x72, 0x87, 0x71, - 0x89, 0x6f, 0x89, 0x6e, 0x89, 0x6e, 0x89, 0x6e, 0x89, 0x6e, 0x88, 0x6f, - 0x88, 0x6e, 0x88, 0x70, 0x87, 0x70, 0x86, 0x6f, 0x81, 0x73, 0x7f, 0x7b, - 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7e, - 0x7f, 0x7e, 0x7f, 0x7f, 0x55, 0x66, 0x56, 0x63, 0x56, 0x61, 0x56, 0x61, - 0x57, 0x5e, 0x57, 0x60, 0x56, 0x62, 0x55, 0x64, 0x53, 0x66, 0x52, 0x66, - 0x51, 0x67, 0x50, 0x68, 0x4d, 0x67, 0x4b, 0x69, 0x4a, 0x6b, 0x49, 0x6a, - 0x48, 0x6a, 0x48, 0x6a, 0x48, 0x6a, 0x48, 0x6a, 0x47, 0x6a, 0x48, 0x6a, - 0x48, 0x68, 0x51, 0x67, 0x58, 0x68, 0x5f, 0x68, 0x5f, 0x68, 0x62, 0x67, - 0x64, 0x67, 0x66, 0x67, 0x68, 0x68, 0x6a, 0x68, 0x6d, 0x68, 0x6f, 0x6b, - 0x6e, 0x6a, 0x6e, 0x6b, 0x6d, 0x6a, 0x6d, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, - 0x6a, 0x6a, 0x6b, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6e, 0x6a, 0x70, 0x6b, - 0x6e, 0x6e, 0x69, 0x75, 0x65, 0x80, 0x65, 0x85, 0x65, 0x85, 0x64, 0x88, - 0x64, 0x84, 0x77, 0x78, 0x86, 0x77, 0x8a, 0x76, 0x8f, 0x78, 0x91, 0x78, - 0x8f, 0x7e, 0x92, 0x80, 0x95, 0x78, 0x88, 0x7d, 0x78, 0x81, 0x6d, 0x85, - 0x5f, 0x8d, 0x6a, 0x88, 0x75, 0x85, 0x7f, 0x81, 0x77, 0x7c, 0x70, 0x79, - 0x73, 0x78, 0x72, 0x78, 0x78, 0x7a, 0x77, 0x7a, 0x72, 0x79, 0x69, 0x78, - 0x63, 0x75, 0x60, 0x70, 0x5e, 0x6d, 0x60, 0x6b, 0x63, 0x6a, 0x63, 0x67, - 0x63, 0x67, 0x61, 0x67, 0x60, 0x68, 0x5f, 0x6a, 0x5d, 0x6b, 0x5d, 0x6b, - 0x5e, 0x6c, 0x5e, 0x6c, 0x5e, 0x6c, 0x5e, 0x6c, 0x5b, 0x6c, 0x5e, 0x6e, - 0x5f, 0x73, 0x62, 0x76, 0x66, 0x7c, 0x67, 0x7f, 0x67, 0x82, 0x62, 0x86, - 0x5c, 0x87, 0x58, 0x85, 0x54, 0x81, 0x56, 0x7d, 0x5b, 0x78, 0x5d, 0x79, - 0x74, 0x7e, 0x6c, 0x7c, 0x68, 0x7f, 0x69, 0x80, 0x72, 0x7e, 0x78, 0x7c, - 0x80, 0x7c, 0x80, 0x7d, 0x74, 0x7d, 0x73, 0x73, 0x68, 0x73, 0x5d, 0x70, - 0x5f, 0x6e, 0x60, 0x6c, 0x60, 0x6d, 0x61, 0x6c, 0x64, 0x6f, 0x68, 0x73, - 0x70, 0x74, 0x78, 0x72, 0x78, 0x71, 0x77, 0x71, 0x75, 0x70, 0x75, 0x70, - 0x75, 0x6f, 0x75, 0x6e, 0x76, 0x70, 0x78, 0x70, 0x7a, 0x70, 0x7d, 0x70, - 0x80, 0x71, 0x82, 0x72, 0x84, 0x72, 0x87, 0x71, 0x8a, 0x70, 0x8a, 0x6e, - 0x89, 0x6d, 0x8a, 0x6e, 0x89, 0x6e, 0x88, 0x6e, 0x88, 0x6e, 0x88, 0x6d, - 0x88, 0x6e, 0x86, 0x6d, 0x80, 0x73, 0x7e, 0x7a, 0x80, 0x80, 0x80, 0x81, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7e, 0x7f, 0x7e, 0x7f, 0x7e, - 0x56, 0x66, 0x56, 0x63, 0x56, 0x62, 0x56, 0x62, 0x57, 0x5f, 0x57, 0x60, - 0x56, 0x63, 0x55, 0x64, 0x54, 0x66, 0x53, 0x65, 0x52, 0x66, 0x51, 0x67, - 0x4e, 0x66, 0x4c, 0x69, 0x4b, 0x6b, 0x49, 0x6a, 0x48, 0x6a, 0x48, 0x6a, - 0x48, 0x6a, 0x47, 0x6a, 0x47, 0x6a, 0x48, 0x6a, 0x48, 0x68, 0x50, 0x67, - 0x56, 0x67, 0x5d, 0x68, 0x5e, 0x68, 0x60, 0x68, 0x63, 0x67, 0x65, 0x67, - 0x67, 0x68, 0x69, 0x68, 0x6b, 0x68, 0x6e, 0x6b, 0x6e, 0x6b, 0x6e, 0x6b, - 0x6d, 0x6a, 0x6d, 0x6a, 0x6b, 0x6b, 0x6a, 0x6b, 0x6a, 0x6a, 0x6b, 0x6a, - 0x6a, 0x6a, 0x6b, 0x6b, 0x6d, 0x6a, 0x6d, 0x6c, 0x68, 0x72, 0x63, 0x7a, - 0x63, 0x85, 0x64, 0x86, 0x64, 0x87, 0x60, 0x87, 0x62, 0x83, 0x76, 0x79, - 0x86, 0x79, 0x89, 0x77, 0x8e, 0x76, 0x90, 0x78, 0x92, 0x7b, 0x94, 0x7b, - 0x95, 0x78, 0x8f, 0x7a, 0x82, 0x7e, 0x6f, 0x83, 0x5e, 0x8b, 0x6a, 0x88, - 0x74, 0x84, 0x7b, 0x7e, 0x75, 0x7a, 0x72, 0x77, 0x74, 0x78, 0x72, 0x78, - 0x76, 0x7a, 0x78, 0x7a, 0x77, 0x79, 0x71, 0x78, 0x65, 0x78, 0x62, 0x75, - 0x60, 0x6f, 0x61, 0x6c, 0x62, 0x6a, 0x63, 0x68, 0x62, 0x69, 0x62, 0x68, - 0x61, 0x68, 0x61, 0x6a, 0x60, 0x68, 0x60, 0x69, 0x60, 0x6a, 0x60, 0x6b, - 0x60, 0x6c, 0x5f, 0x6d, 0x5c, 0x6e, 0x5f, 0x70, 0x63, 0x74, 0x65, 0x78, - 0x67, 0x7d, 0x68, 0x80, 0x68, 0x83, 0x5f, 0x88, 0x57, 0x87, 0x55, 0x84, - 0x53, 0x81, 0x54, 0x7e, 0x5a, 0x78, 0x5c, 0x78, 0x74, 0x7d, 0x70, 0x7b, - 0x69, 0x7d, 0x63, 0x80, 0x69, 0x7d, 0x6f, 0x7a, 0x76, 0x7a, 0x75, 0x7b, - 0x72, 0x7b, 0x75, 0x71, 0x65, 0x71, 0x5e, 0x6f, 0x5f, 0x6e, 0x60, 0x6d, - 0x61, 0x6d, 0x60, 0x6c, 0x62, 0x6f, 0x66, 0x72, 0x6d, 0x74, 0x74, 0x72, - 0x76, 0x70, 0x76, 0x70, 0x73, 0x6e, 0x73, 0x6e, 0x73, 0x6e, 0x73, 0x6d, - 0x74, 0x6e, 0x77, 0x6e, 0x79, 0x6f, 0x7c, 0x6f, 0x7e, 0x70, 0x82, 0x72, - 0x84, 0x72, 0x87, 0x70, 0x8a, 0x70, 0x8a, 0x6e, 0x89, 0x6e, 0x89, 0x6e, - 0x89, 0x6e, 0x88, 0x6d, 0x88, 0x6e, 0x88, 0x6e, 0x88, 0x6e, 0x86, 0x6f, - 0x80, 0x75, 0x7e, 0x7a, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x7f, 0x7f, 0x7f, 0x7e, 0x7f, 0x7e, 0x7f, 0x7e, 0x55, 0x65, 0x55, 0x62, - 0x56, 0x63, 0x57, 0x63, 0x57, 0x60, 0x56, 0x5f, 0x56, 0x61, 0x56, 0x63, - 0x55, 0x64, 0x54, 0x64, 0x53, 0x65, 0x52, 0x65, 0x50, 0x65, 0x4e, 0x69, - 0x4c, 0x6a, 0x4a, 0x69, 0x4a, 0x69, 0x49, 0x6a, 0x4a, 0x6a, 0x49, 0x6a, - 0x48, 0x6a, 0x48, 0x69, 0x49, 0x68, 0x4f, 0x68, 0x55, 0x67, 0x5b, 0x67, - 0x5d, 0x67, 0x60, 0x67, 0x63, 0x66, 0x64, 0x66, 0x66, 0x67, 0x68, 0x67, - 0x6a, 0x68, 0x6c, 0x6a, 0x6d, 0x6b, 0x6d, 0x6b, 0x6b, 0x69, 0x6c, 0x6a, - 0x6b, 0x6b, 0x6a, 0x6b, 0x6a, 0x6b, 0x6a, 0x6a, 0x69, 0x69, 0x6b, 0x6a, - 0x6e, 0x6b, 0x6a, 0x6d, 0x62, 0x75, 0x5e, 0x7c, 0x5f, 0x85, 0x62, 0x86, - 0x61, 0x85, 0x5c, 0x81, 0x5f, 0x7d, 0x75, 0x78, 0x84, 0x79, 0x87, 0x78, - 0x8d, 0x76, 0x8d, 0x78, 0x91, 0x78, 0x95, 0x77, 0x95, 0x78, 0x8f, 0x77, - 0x8b, 0x7a, 0x70, 0x82, 0x5c, 0x88, 0x67, 0x88, 0x72, 0x83, 0x74, 0x7a, - 0x6f, 0x78, 0x72, 0x77, 0x74, 0x77, 0x71, 0x78, 0x70, 0x79, 0x74, 0x79, - 0x77, 0x79, 0x77, 0x78, 0x70, 0x7a, 0x6b, 0x79, 0x67, 0x76, 0x63, 0x72, - 0x62, 0x71, 0x62, 0x6f, 0x62, 0x6d, 0x62, 0x6a, 0x62, 0x68, 0x62, 0x68, - 0x63, 0x66, 0x64, 0x67, 0x62, 0x69, 0x62, 0x6a, 0x63, 0x6c, 0x61, 0x6d, - 0x62, 0x6f, 0x64, 0x72, 0x66, 0x76, 0x65, 0x79, 0x63, 0x7e, 0x62, 0x82, - 0x63, 0x85, 0x5a, 0x89, 0x54, 0x87, 0x55, 0x82, 0x54, 0x7e, 0x54, 0x7d, - 0x59, 0x79, 0x5b, 0x77, 0x71, 0x7b, 0x71, 0x80, 0x6b, 0x7f, 0x6a, 0x7d, - 0x68, 0x7d, 0x6d, 0x7d, 0x70, 0x7d, 0x6d, 0x7b, 0x70, 0x78, 0x6e, 0x72, - 0x64, 0x73, 0x62, 0x70, 0x60, 0x6e, 0x60, 0x6c, 0x5f, 0x6b, 0x5f, 0x6c, - 0x61, 0x6f, 0x64, 0x73, 0x6a, 0x74, 0x71, 0x71, 0x75, 0x6f, 0x75, 0x6d, - 0x72, 0x6c, 0x73, 0x6d, 0x71, 0x6c, 0x72, 0x6c, 0x72, 0x6d, 0x75, 0x6d, - 0x77, 0x6d, 0x7a, 0x6f, 0x7d, 0x70, 0x82, 0x72, 0x83, 0x71, 0x86, 0x6f, - 0x8a, 0x6f, 0x8a, 0x6e, 0x89, 0x6e, 0x8a, 0x6d, 0x8a, 0x6d, 0x89, 0x6e, - 0x88, 0x6e, 0x89, 0x6e, 0x89, 0x6e, 0x87, 0x6e, 0x81, 0x74, 0x7f, 0x7a, - 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7e, - 0x7f, 0x7d, 0x7f, 0x7e, 0x55, 0x64, 0x55, 0x61, 0x55, 0x62, 0x57, 0x63, - 0x56, 0x63, 0x56, 0x5f, 0x57, 0x5d, 0x57, 0x5f, 0x55, 0x61, 0x55, 0x63, - 0x54, 0x65, 0x52, 0x65, 0x51, 0x66, 0x4e, 0x68, 0x4c, 0x68, 0x4b, 0x68, - 0x4b, 0x68, 0x4c, 0x6a, 0x4c, 0x6a, 0x4b, 0x69, 0x49, 0x69, 0x48, 0x68, - 0x49, 0x68, 0x4e, 0x68, 0x55, 0x67, 0x5b, 0x67, 0x5d, 0x66, 0x60, 0x66, - 0x63, 0x66, 0x65, 0x66, 0x66, 0x66, 0x69, 0x65, 0x6b, 0x68, 0x6b, 0x68, - 0x6b, 0x6a, 0x6b, 0x6a, 0x69, 0x68, 0x6b, 0x6a, 0x6c, 0x6c, 0x6a, 0x6c, - 0x6a, 0x6c, 0x68, 0x6a, 0x68, 0x68, 0x6b, 0x69, 0x6c, 0x6b, 0x66, 0x6f, - 0x5e, 0x78, 0x5d, 0x7e, 0x5d, 0x83, 0x5e, 0x82, 0x5b, 0x7f, 0x57, 0x7b, - 0x5a, 0x77, 0x72, 0x7a, 0x80, 0x7d, 0x88, 0x77, 0x8d, 0x75, 0x8e, 0x77, - 0x91, 0x77, 0x92, 0x76, 0x91, 0x77, 0x90, 0x78, 0x8c, 0x7b, 0x72, 0x84, - 0x61, 0x86, 0x69, 0x85, 0x6c, 0x80, 0x6c, 0x76, 0x6b, 0x77, 0x73, 0x77, - 0x74, 0x78, 0x6f, 0x78, 0x6e, 0x79, 0x71, 0x79, 0x74, 0x79, 0x76, 0x79, - 0x76, 0x7a, 0x72, 0x7a, 0x6b, 0x7a, 0x65, 0x78, 0x63, 0x77, 0x62, 0x76, - 0x62, 0x73, 0x62, 0x6c, 0x63, 0x68, 0x62, 0x68, 0x63, 0x6a, 0x65, 0x6c, - 0x63, 0x69, 0x64, 0x6a, 0x63, 0x6a, 0x61, 0x6b, 0x64, 0x6f, 0x65, 0x74, - 0x64, 0x78, 0x64, 0x79, 0x61, 0x7e, 0x5f, 0x82, 0x5f, 0x85, 0x58, 0x87, - 0x55, 0x86, 0x58, 0x80, 0x58, 0x7a, 0x58, 0x7b, 0x59, 0x7a, 0x59, 0x75, - 0x6b, 0x79, 0x73, 0x81, 0x67, 0x80, 0x6e, 0x7b, 0x69, 0x7b, 0x6f, 0x7e, - 0x6d, 0x7d, 0x6b, 0x7a, 0x6e, 0x76, 0x66, 0x75, 0x67, 0x76, 0x63, 0x73, - 0x61, 0x6f, 0x5e, 0x6c, 0x5d, 0x6a, 0x5e, 0x6b, 0x60, 0x70, 0x62, 0x74, - 0x68, 0x73, 0x6f, 0x6f, 0x74, 0x6e, 0x74, 0x6b, 0x72, 0x6c, 0x72, 0x6c, - 0x70, 0x6c, 0x70, 0x6c, 0x72, 0x6d, 0x74, 0x6c, 0x74, 0x6c, 0x79, 0x6e, - 0x7c, 0x70, 0x80, 0x70, 0x83, 0x70, 0x86, 0x6e, 0x89, 0x6f, 0x8a, 0x6e, - 0x8a, 0x6e, 0x8a, 0x6c, 0x8a, 0x6c, 0x8a, 0x6e, 0x89, 0x6e, 0x89, 0x6e, - 0x8a, 0x6e, 0x88, 0x6d, 0x83, 0x72, 0x80, 0x79, 0x7f, 0x7f, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7f, 0x7e, - 0x55, 0x66, 0x55, 0x63, 0x55, 0x64, 0x56, 0x65, 0x56, 0x63, 0x56, 0x5f, - 0x57, 0x5c, 0x57, 0x5d, 0x57, 0x5f, 0x56, 0x61, 0x54, 0x64, 0x53, 0x65, - 0x51, 0x66, 0x50, 0x66, 0x4e, 0x67, 0x4b, 0x68, 0x4b, 0x68, 0x4b, 0x6a, - 0x4c, 0x6a, 0x4b, 0x6a, 0x49, 0x6a, 0x48, 0x69, 0x48, 0x68, 0x4c, 0x68, - 0x53, 0x68, 0x5a, 0x66, 0x5c, 0x65, 0x5e, 0x66, 0x61, 0x66, 0x63, 0x66, - 0x66, 0x65, 0x68, 0x65, 0x6a, 0x68, 0x6a, 0x68, 0x69, 0x6a, 0x69, 0x6a, - 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6f, 0x6b, 0x70, 0x6b, 0x6f, 0x6d, 0x6e, - 0x6c, 0x6c, 0x69, 0x6b, 0x68, 0x6b, 0x61, 0x70, 0x5a, 0x79, 0x5b, 0x7e, - 0x5b, 0x7f, 0x59, 0x7d, 0x56, 0x7a, 0x55, 0x77, 0x58, 0x75, 0x6e, 0x7a, - 0x7e, 0x7e, 0x85, 0x7a, 0x8d, 0x77, 0x8e, 0x78, 0x90, 0x77, 0x92, 0x77, - 0x90, 0x7a, 0x8a, 0x7d, 0x81, 0x80, 0x6f, 0x82, 0x65, 0x87, 0x6c, 0x85, - 0x69, 0x7f, 0x66, 0x75, 0x6e, 0x77, 0x73, 0x77, 0x72, 0x78, 0x6f, 0x78, - 0x6e, 0x7a, 0x6d, 0x7b, 0x70, 0x7b, 0x73, 0x7b, 0x76, 0x7a, 0x76, 0x7a, - 0x72, 0x7a, 0x6b, 0x7a, 0x68, 0x7a, 0x64, 0x79, 0x63, 0x74, 0x62, 0x6f, - 0x62, 0x6d, 0x62, 0x6d, 0x61, 0x6f, 0x63, 0x71, 0x63, 0x6d, 0x63, 0x6c, - 0x63, 0x6c, 0x61, 0x6d, 0x66, 0x71, 0x66, 0x76, 0x66, 0x79, 0x66, 0x7b, - 0x61, 0x7f, 0x5f, 0x82, 0x5e, 0x84, 0x59, 0x83, 0x57, 0x81, 0x5a, 0x7a, - 0x5b, 0x75, 0x5b, 0x77, 0x5c, 0x79, 0x5a, 0x75, 0x62, 0x79, 0x77, 0x80, - 0x6a, 0x7e, 0x6c, 0x79, 0x71, 0x79, 0x6d, 0x7a, 0x6d, 0x79, 0x6e, 0x77, - 0x68, 0x75, 0x64, 0x75, 0x69, 0x76, 0x64, 0x73, 0x61, 0x71, 0x5e, 0x6e, - 0x5e, 0x6c, 0x5d, 0x6d, 0x5e, 0x70, 0x60, 0x74, 0x65, 0x73, 0x6c, 0x6f, - 0x72, 0x6e, 0x72, 0x6b, 0x70, 0x6b, 0x70, 0x6b, 0x6f, 0x6b, 0x6e, 0x6b, - 0x70, 0x6b, 0x72, 0x6b, 0x73, 0x6a, 0x76, 0x6c, 0x7b, 0x6e, 0x7e, 0x6f, - 0x81, 0x6f, 0x86, 0x6f, 0x89, 0x6f, 0x89, 0x6e, 0x89, 0x6e, 0x8a, 0x6c, - 0x8a, 0x6c, 0x8a, 0x6e, 0x89, 0x6e, 0x89, 0x6e, 0x8a, 0x6e, 0x88, 0x6d, - 0x83, 0x72, 0x80, 0x79, 0x7f, 0x7f, 0x80, 0x81, 0x80, 0x80, 0x80, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7f, 0x7e, 0x55, 0x67, 0x55, 0x65, - 0x55, 0x65, 0x55, 0x66, 0x56, 0x64, 0x56, 0x5f, 0x57, 0x5e, 0x57, 0x60, - 0x57, 0x60, 0x57, 0x60, 0x55, 0x62, 0x54, 0x64, 0x53, 0x65, 0x52, 0x65, - 0x50, 0x65, 0x4d, 0x67, 0x4b, 0x68, 0x4b, 0x6a, 0x4b, 0x6a, 0x4b, 0x6a, - 0x49, 0x6a, 0x49, 0x69, 0x49, 0x68, 0x4b, 0x67, 0x50, 0x67, 0x57, 0x66, - 0x5b, 0x65, 0x5c, 0x65, 0x60, 0x65, 0x62, 0x65, 0x66, 0x66, 0x69, 0x66, - 0x6a, 0x67, 0x69, 0x68, 0x68, 0x6b, 0x68, 0x6c, 0x6d, 0x6f, 0x6f, 0x71, - 0x70, 0x72, 0x6d, 0x73, 0x6d, 0x73, 0x72, 0x72, 0x70, 0x71, 0x68, 0x6e, - 0x64, 0x6b, 0x61, 0x71, 0x5c, 0x7a, 0x5a, 0x7d, 0x59, 0x7d, 0x58, 0x7d, - 0x57, 0x7a, 0x58, 0x77, 0x5a, 0x78, 0x69, 0x79, 0x74, 0x7b, 0x7e, 0x7d, - 0x85, 0x7d, 0x87, 0x7c, 0x89, 0x7c, 0x89, 0x7d, 0x82, 0x80, 0x78, 0x82, - 0x74, 0x82, 0x6d, 0x7f, 0x66, 0x85, 0x71, 0x84, 0x6a, 0x81, 0x69, 0x78, - 0x72, 0x78, 0x73, 0x78, 0x72, 0x78, 0x6f, 0x78, 0x6c, 0x7c, 0x68, 0x7d, - 0x6a, 0x7d, 0x6f, 0x7c, 0x72, 0x7c, 0x73, 0x7b, 0x75, 0x78, 0x75, 0x77, - 0x72, 0x79, 0x6a, 0x7a, 0x66, 0x77, 0x64, 0x73, 0x62, 0x72, 0x61, 0x71, - 0x60, 0x70, 0x63, 0x71, 0x63, 0x70, 0x64, 0x71, 0x67, 0x73, 0x67, 0x73, - 0x68, 0x74, 0x69, 0x78, 0x68, 0x7b, 0x68, 0x7d, 0x62, 0x7f, 0x60, 0x83, - 0x5d, 0x84, 0x5b, 0x7e, 0x59, 0x7a, 0x5b, 0x75, 0x5a, 0x70, 0x5a, 0x72, - 0x5d, 0x77, 0x5c, 0x75, 0x58, 0x78, 0x77, 0x7e, 0x71, 0x7d, 0x6b, 0x76, - 0x74, 0x72, 0x73, 0x77, 0x73, 0x72, 0x6e, 0x70, 0x62, 0x75, 0x65, 0x76, - 0x6a, 0x75, 0x64, 0x74, 0x60, 0x73, 0x5e, 0x70, 0x5e, 0x6e, 0x5d, 0x6e, - 0x5c, 0x71, 0x5e, 0x74, 0x62, 0x73, 0x68, 0x6e, 0x6f, 0x6d, 0x71, 0x6b, - 0x6e, 0x6a, 0x6f, 0x69, 0x6d, 0x69, 0x6d, 0x69, 0x6d, 0x69, 0x70, 0x69, - 0x71, 0x69, 0x75, 0x6a, 0x79, 0x6c, 0x7c, 0x6d, 0x80, 0x6e, 0x85, 0x6f, - 0x89, 0x6f, 0x8a, 0x6e, 0x8a, 0x6d, 0x8b, 0x6c, 0x8a, 0x6c, 0x8a, 0x6d, - 0x89, 0x6d, 0x89, 0x6e, 0x89, 0x6e, 0x89, 0x6d, 0x83, 0x73, 0x80, 0x79, - 0x80, 0x7f, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, - 0x7f, 0x7d, 0x7f, 0x7e, 0x54, 0x66, 0x55, 0x64, 0x55, 0x64, 0x55, 0x65, - 0x56, 0x63, 0x57, 0x60, 0x57, 0x5e, 0x57, 0x5f, 0x57, 0x60, 0x57, 0x60, - 0x56, 0x60, 0x55, 0x61, 0x54, 0x63, 0x53, 0x65, 0x50, 0x65, 0x4e, 0x67, - 0x4c, 0x67, 0x4b, 0x69, 0x4b, 0x69, 0x4b, 0x69, 0x4b, 0x6a, 0x4a, 0x68, - 0x4a, 0x68, 0x4c, 0x67, 0x4e, 0x66, 0x54, 0x65, 0x59, 0x65, 0x5b, 0x65, - 0x5f, 0x65, 0x63, 0x65, 0x66, 0x66, 0x68, 0x66, 0x68, 0x67, 0x68, 0x6a, - 0x67, 0x6d, 0x69, 0x6f, 0x6e, 0x71, 0x71, 0x73, 0x71, 0x73, 0x6f, 0x74, - 0x6f, 0x74, 0x73, 0x74, 0x73, 0x73, 0x6c, 0x71, 0x65, 0x6e, 0x63, 0x70, - 0x60, 0x78, 0x5b, 0x7b, 0x58, 0x7d, 0x57, 0x7c, 0x59, 0x79, 0x5a, 0x77, - 0x5a, 0x78, 0x67, 0x78, 0x6e, 0x7b, 0x78, 0x7d, 0x7d, 0x80, 0x7e, 0x81, - 0x7e, 0x80, 0x7b, 0x81, 0x79, 0x81, 0x70, 0x82, 0x6b, 0x82, 0x71, 0x80, - 0x6a, 0x81, 0x77, 0x7d, 0x6b, 0x7e, 0x71, 0x7b, 0x76, 0x7a, 0x74, 0x7a, - 0x74, 0x78, 0x6e, 0x78, 0x6a, 0x7d, 0x65, 0x7e, 0x65, 0x7d, 0x6a, 0x7c, - 0x6e, 0x7c, 0x6f, 0x7c, 0x72, 0x79, 0x73, 0x77, 0x74, 0x78, 0x71, 0x79, - 0x6c, 0x7a, 0x69, 0x77, 0x65, 0x75, 0x62, 0x74, 0x62, 0x72, 0x64, 0x70, - 0x63, 0x72, 0x66, 0x74, 0x68, 0x75, 0x6c, 0x74, 0x6a, 0x77, 0x6b, 0x7a, - 0x6a, 0x7c, 0x68, 0x7d, 0x62, 0x7e, 0x60, 0x85, 0x5e, 0x84, 0x5c, 0x7b, - 0x5a, 0x77, 0x5b, 0x75, 0x59, 0x70, 0x59, 0x71, 0x5d, 0x74, 0x5d, 0x74, - 0x55, 0x76, 0x6d, 0x7b, 0x77, 0x7e, 0x6e, 0x76, 0x71, 0x70, 0x74, 0x72, - 0x72, 0x70, 0x67, 0x70, 0x5f, 0x74, 0x67, 0x76, 0x6b, 0x75, 0x64, 0x74, - 0x5f, 0x73, 0x5d, 0x71, 0x5e, 0x6e, 0x5e, 0x6f, 0x5c, 0x72, 0x5d, 0x74, - 0x62, 0x72, 0x66, 0x6d, 0x6c, 0x6c, 0x6d, 0x6a, 0x6d, 0x69, 0x6d, 0x69, - 0x6b, 0x68, 0x6b, 0x68, 0x6b, 0x67, 0x6d, 0x67, 0x71, 0x69, 0x75, 0x6a, - 0x77, 0x6a, 0x7c, 0x6b, 0x80, 0x6d, 0x83, 0x6e, 0x88, 0x6e, 0x8a, 0x6c, - 0x8c, 0x6c, 0x8b, 0x6b, 0x8a, 0x6b, 0x8a, 0x6c, 0x8b, 0x6c, 0x8a, 0x6e, - 0x89, 0x6e, 0x89, 0x6d, 0x84, 0x74, 0x80, 0x7a, 0x7f, 0x7f, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7e, 0x7f, 0x7d, 0x7f, 0x7e, - 0x4f, 0x68, 0x54, 0x66, 0x55, 0x65, 0x55, 0x65, 0x56, 0x63, 0x57, 0x61, - 0x58, 0x5d, 0x57, 0x5f, 0x57, 0x61, 0x57, 0x60, 0x57, 0x60, 0x56, 0x61, - 0x54, 0x63, 0x53, 0x65, 0x51, 0x65, 0x50, 0x67, 0x4d, 0x68, 0x4c, 0x68, - 0x4c, 0x68, 0x4c, 0x69, 0x4b, 0x6a, 0x4a, 0x68, 0x4a, 0x67, 0x4b, 0x66, - 0x4c, 0x65, 0x51, 0x65, 0x55, 0x65, 0x58, 0x65, 0x5d, 0x65, 0x60, 0x65, - 0x62, 0x64, 0x65, 0x65, 0x64, 0x68, 0x64, 0x6b, 0x66, 0x6f, 0x6b, 0x72, - 0x71, 0x74, 0x72, 0x75, 0x73, 0x76, 0x71, 0x76, 0x6f, 0x76, 0x71, 0x76, - 0x73, 0x76, 0x71, 0x73, 0x6c, 0x70, 0x69, 0x71, 0x67, 0x75, 0x63, 0x77, - 0x5a, 0x79, 0x5a, 0x79, 0x5d, 0x77, 0x5e, 0x75, 0x5d, 0x76, 0x63, 0x74, - 0x73, 0x78, 0x71, 0x7b, 0x75, 0x7e, 0x76, 0x7f, 0x75, 0x7f, 0x74, 0x80, - 0x71, 0x81, 0x6b, 0x83, 0x6c, 0x81, 0x72, 0x80, 0x72, 0x7f, 0x7e, 0x77, - 0x6e, 0x7b, 0x74, 0x79, 0x77, 0x7a, 0x74, 0x7a, 0x72, 0x78, 0x6f, 0x78, - 0x6d, 0x7b, 0x69, 0x7c, 0x64, 0x7b, 0x65, 0x7b, 0x67, 0x7b, 0x69, 0x7b, - 0x6c, 0x79, 0x70, 0x78, 0x72, 0x78, 0x76, 0x79, 0x74, 0x7a, 0x6f, 0x79, - 0x6d, 0x78, 0x6c, 0x78, 0x67, 0x76, 0x67, 0x74, 0x68, 0x73, 0x6b, 0x76, - 0x6b, 0x76, 0x71, 0x76, 0x6f, 0x79, 0x69, 0x7c, 0x66, 0x7f, 0x64, 0x7f, - 0x61, 0x7f, 0x61, 0x85, 0x5f, 0x84, 0x5b, 0x7b, 0x5b, 0x76, 0x5b, 0x73, - 0x59, 0x6f, 0x58, 0x70, 0x5a, 0x71, 0x5c, 0x72, 0x57, 0x74, 0x5a, 0x76, - 0x6e, 0x7b, 0x76, 0x7b, 0x6f, 0x76, 0x6f, 0x71, 0x67, 0x70, 0x60, 0x70, - 0x5e, 0x72, 0x68, 0x75, 0x6b, 0x75, 0x64, 0x74, 0x5f, 0x73, 0x5e, 0x72, - 0x5e, 0x70, 0x5e, 0x71, 0x5a, 0x74, 0x59, 0x76, 0x60, 0x73, 0x65, 0x6f, - 0x69, 0x6c, 0x6a, 0x69, 0x6b, 0x67, 0x6b, 0x67, 0x6a, 0x68, 0x69, 0x68, - 0x69, 0x67, 0x6b, 0x67, 0x6f, 0x68, 0x73, 0x68, 0x75, 0x68, 0x7a, 0x6b, - 0x7e, 0x6d, 0x81, 0x6d, 0x87, 0x6c, 0x8a, 0x6c, 0x8c, 0x6c, 0x8a, 0x6b, - 0x8a, 0x6b, 0x8b, 0x6c, 0x8b, 0x6c, 0x8a, 0x6e, 0x89, 0x6e, 0x89, 0x6e, - 0x85, 0x74, 0x81, 0x7a, 0x7f, 0x7f, 0x80, 0x80, 0x80, 0x7f, 0x80, 0x7f, - 0x7f, 0x7e, 0x7f, 0x7e, 0x7f, 0x7e, 0x7f, 0x7e, 0x4b, 0x6a, 0x52, 0x68, - 0x55, 0x65, 0x55, 0x65, 0x56, 0x64, 0x56, 0x60, 0x58, 0x5d, 0x58, 0x5f, - 0x57, 0x60, 0x56, 0x60, 0x57, 0x61, 0x56, 0x61, 0x55, 0x64, 0x53, 0x65, - 0x52, 0x65, 0x51, 0x67, 0x4e, 0x67, 0x4c, 0x68, 0x4c, 0x68, 0x4b, 0x69, - 0x4b, 0x6a, 0x4a, 0x68, 0x4a, 0x67, 0x4b, 0x66, 0x4b, 0x65, 0x4f, 0x66, - 0x52, 0x65, 0x55, 0x64, 0x5b, 0x65, 0x5e, 0x65, 0x5f, 0x63, 0x61, 0x63, - 0x61, 0x69, 0x61, 0x6d, 0x64, 0x70, 0x6c, 0x73, 0x72, 0x74, 0x74, 0x76, - 0x75, 0x78, 0x73, 0x77, 0x6f, 0x77, 0x6e, 0x77, 0x71, 0x77, 0x70, 0x75, - 0x6e, 0x73, 0x6e, 0x71, 0x6d, 0x71, 0x69, 0x73, 0x5e, 0x76, 0x5d, 0x77, - 0x5f, 0x75, 0x61, 0x74, 0x61, 0x74, 0x60, 0x71, 0x72, 0x75, 0x73, 0x78, - 0x75, 0x78, 0x78, 0x78, 0x70, 0x7e, 0x70, 0x82, 0x71, 0x82, 0x6d, 0x81, - 0x71, 0x7f, 0x6d, 0x7e, 0x73, 0x81, 0x7c, 0x7b, 0x6a, 0x7a, 0x75, 0x77, - 0x77, 0x79, 0x74, 0x7a, 0x70, 0x79, 0x71, 0x78, 0x71, 0x7a, 0x6c, 0x7a, - 0x67, 0x79, 0x66, 0x79, 0x66, 0x7b, 0x68, 0x7b, 0x6c, 0x79, 0x6f, 0x78, - 0x70, 0x78, 0x75, 0x79, 0x74, 0x7a, 0x71, 0x7b, 0x74, 0x7c, 0x75, 0x7b, - 0x70, 0x79, 0x6d, 0x77, 0x6d, 0x75, 0x6f, 0x77, 0x6f, 0x77, 0x74, 0x77, - 0x72, 0x7b, 0x67, 0x7d, 0x62, 0x80, 0x61, 0x80, 0x60, 0x80, 0x60, 0x85, - 0x5e, 0x84, 0x5b, 0x7b, 0x5a, 0x75, 0x5a, 0x71, 0x5a, 0x6d, 0x58, 0x6e, - 0x57, 0x70, 0x5b, 0x70, 0x59, 0x72, 0x52, 0x73, 0x5a, 0x77, 0x6d, 0x7a, - 0x69, 0x76, 0x66, 0x71, 0x63, 0x70, 0x60, 0x6f, 0x5c, 0x70, 0x64, 0x74, - 0x67, 0x75, 0x62, 0x74, 0x5f, 0x73, 0x5d, 0x72, 0x5e, 0x72, 0x5e, 0x72, - 0x59, 0x75, 0x56, 0x77, 0x5e, 0x75, 0x62, 0x70, 0x66, 0x6c, 0x67, 0x69, - 0x69, 0x66, 0x69, 0x66, 0x68, 0x67, 0x68, 0x68, 0x67, 0x68, 0x6a, 0x68, - 0x6d, 0x68, 0x72, 0x67, 0x73, 0x68, 0x78, 0x6b, 0x7d, 0x6c, 0x80, 0x6b, - 0x86, 0x6b, 0x8a, 0x6c, 0x8c, 0x6d, 0x8a, 0x6a, 0x8a, 0x6b, 0x8a, 0x6c, - 0x8b, 0x6c, 0x8a, 0x6e, 0x8a, 0x6e, 0x89, 0x6e, 0x84, 0x74, 0x80, 0x7a, - 0x7f, 0x7e, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7e, 0x7f, 0x7e, - 0x7f, 0x7e, 0x7f, 0x7e, 0x4e, 0x6b, 0x4d, 0x6b, 0x52, 0x68, 0x54, 0x65, - 0x55, 0x64, 0x56, 0x62, 0x57, 0x60, 0x57, 0x62, 0x56, 0x63, 0x56, 0x62, - 0x56, 0x61, 0x56, 0x61, 0x56, 0x63, 0x54, 0x65, 0x52, 0x66, 0x51, 0x67, - 0x4e, 0x67, 0x4d, 0x67, 0x4b, 0x69, 0x4c, 0x6b, 0x4c, 0x69, 0x4b, 0x68, - 0x4a, 0x69, 0x4c, 0x67, 0x4c, 0x65, 0x50, 0x65, 0x52, 0x66, 0x53, 0x65, - 0x57, 0x65, 0x5b, 0x65, 0x5f, 0x63, 0x61, 0x65, 0x60, 0x6c, 0x63, 0x70, - 0x66, 0x72, 0x6c, 0x73, 0x72, 0x73, 0x75, 0x75, 0x77, 0x77, 0x77, 0x77, - 0x73, 0x76, 0x6d, 0x76, 0x6b, 0x76, 0x6e, 0x76, 0x6c, 0x74, 0x6e, 0x72, - 0x70, 0x72, 0x6f, 0x73, 0x64, 0x76, 0x5f, 0x76, 0x62, 0x75, 0x63, 0x73, - 0x63, 0x73, 0x62, 0x72, 0x6a, 0x72, 0x73, 0x76, 0x78, 0x76, 0x7b, 0x77, - 0x73, 0x7e, 0x6f, 0x83, 0x71, 0x81, 0x70, 0x80, 0x70, 0x7e, 0x6b, 0x80, - 0x76, 0x81, 0x72, 0x7e, 0x69, 0x7a, 0x75, 0x79, 0x77, 0x79, 0x76, 0x78, - 0x72, 0x77, 0x70, 0x77, 0x70, 0x78, 0x6d, 0x78, 0x68, 0x77, 0x67, 0x76, - 0x69, 0x7b, 0x6a, 0x7c, 0x6c, 0x7c, 0x6d, 0x7b, 0x6d, 0x7b, 0x71, 0x7a, - 0x71, 0x7a, 0x6e, 0x7c, 0x71, 0x7e, 0x75, 0x7e, 0x74, 0x7d, 0x70, 0x7a, - 0x70, 0x79, 0x71, 0x79, 0x70, 0x78, 0x70, 0x79, 0x6e, 0x7b, 0x64, 0x7f, - 0x61, 0x80, 0x60, 0x80, 0x5e, 0x81, 0x5e, 0x83, 0x5e, 0x81, 0x5d, 0x7c, - 0x5c, 0x78, 0x5a, 0x73, 0x5c, 0x6d, 0x59, 0x6d, 0x56, 0x70, 0x5a, 0x6e, - 0x58, 0x70, 0x54, 0x72, 0x54, 0x77, 0x60, 0x7b, 0x65, 0x76, 0x63, 0x70, - 0x66, 0x70, 0x61, 0x6f, 0x5a, 0x70, 0x62, 0x74, 0x63, 0x76, 0x60, 0x75, - 0x5e, 0x73, 0x5c, 0x71, 0x5d, 0x72, 0x5d, 0x72, 0x59, 0x75, 0x57, 0x77, - 0x5c, 0x75, 0x62, 0x74, 0x64, 0x70, 0x65, 0x6a, 0x66, 0x67, 0x66, 0x65, - 0x66, 0x66, 0x66, 0x66, 0x67, 0x65, 0x69, 0x66, 0x6c, 0x67, 0x71, 0x67, - 0x74, 0x68, 0x77, 0x69, 0x7a, 0x6a, 0x7f, 0x6a, 0x84, 0x6b, 0x88, 0x6d, - 0x8a, 0x6d, 0x8a, 0x6c, 0x8a, 0x6c, 0x8a, 0x6e, 0x8b, 0x6f, 0x8a, 0x70, - 0x8a, 0x6e, 0x88, 0x6e, 0x83, 0x76, 0x80, 0x7a, 0x80, 0x7f, 0x80, 0x80, - 0x80, 0x7f, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7f, 0x7d, 0x7f, 0x7d, - 0x55, 0x6b, 0x4a, 0x6b, 0x4e, 0x69, 0x54, 0x66, 0x55, 0x65, 0x56, 0x62, - 0x56, 0x61, 0x56, 0x63, 0x56, 0x65, 0x56, 0x63, 0x56, 0x62, 0x56, 0x62, - 0x56, 0x61, 0x54, 0x63, 0x52, 0x65, 0x51, 0x66, 0x4f, 0x65, 0x4f, 0x66, - 0x4c, 0x69, 0x4b, 0x6b, 0x4c, 0x69, 0x4b, 0x68, 0x4b, 0x69, 0x4c, 0x67, - 0x4d, 0x65, 0x4e, 0x65, 0x4e, 0x64, 0x4f, 0x64, 0x54, 0x63, 0x58, 0x64, - 0x5d, 0x65, 0x5f, 0x6a, 0x60, 0x6f, 0x64, 0x72, 0x67, 0x73, 0x6c, 0x73, - 0x72, 0x73, 0x76, 0x75, 0x79, 0x77, 0x7a, 0x77, 0x77, 0x76, 0x6f, 0x75, - 0x6a, 0x76, 0x6c, 0x75, 0x6c, 0x75, 0x6c, 0x74, 0x6f, 0x73, 0x73, 0x73, - 0x6a, 0x76, 0x62, 0x77, 0x63, 0x74, 0x63, 0x73, 0x63, 0x73, 0x67, 0x73, - 0x65, 0x71, 0x6a, 0x76, 0x74, 0x77, 0x79, 0x78, 0x75, 0x7d, 0x71, 0x80, - 0x71, 0x7f, 0x6e, 0x7f, 0x6c, 0x7d, 0x6d, 0x7f, 0x75, 0x82, 0x67, 0x7f, - 0x6c, 0x7a, 0x75, 0x7a, 0x77, 0x79, 0x77, 0x77, 0x73, 0x76, 0x70, 0x76, - 0x6f, 0x76, 0x6d, 0x76, 0x69, 0x75, 0x68, 0x74, 0x6a, 0x79, 0x6b, 0x7a, - 0x6b, 0x7a, 0x6c, 0x7b, 0x6d, 0x7c, 0x6e, 0x7e, 0x6d, 0x7f, 0x6a, 0x7f, - 0x6a, 0x80, 0x6d, 0x80, 0x6e, 0x7f, 0x6e, 0x7d, 0x6f, 0x7c, 0x6f, 0x7c, - 0x6e, 0x7b, 0x6b, 0x7c, 0x67, 0x7e, 0x61, 0x81, 0x60, 0x81, 0x60, 0x81, - 0x5f, 0x82, 0x5f, 0x82, 0x5f, 0x81, 0x5e, 0x7e, 0x5d, 0x7a, 0x5b, 0x73, - 0x5d, 0x6c, 0x5a, 0x6c, 0x54, 0x6f, 0x56, 0x6c, 0x56, 0x6e, 0x55, 0x70, - 0x54, 0x72, 0x5d, 0x79, 0x65, 0x76, 0x65, 0x71, 0x68, 0x70, 0x61, 0x71, - 0x57, 0x71, 0x5e, 0x74, 0x5e, 0x75, 0x5e, 0x76, 0x5c, 0x74, 0x5a, 0x72, - 0x5b, 0x73, 0x5c, 0x73, 0x59, 0x75, 0x57, 0x77, 0x5a, 0x77, 0x61, 0x76, - 0x64, 0x73, 0x63, 0x6c, 0x63, 0x68, 0x63, 0x65, 0x65, 0x65, 0x64, 0x66, - 0x65, 0x65, 0x67, 0x65, 0x6a, 0x66, 0x6f, 0x68, 0x73, 0x68, 0x76, 0x69, - 0x78, 0x68, 0x7d, 0x6a, 0x83, 0x6b, 0x86, 0x6d, 0x88, 0x6d, 0x89, 0x6d, - 0x8a, 0x6d, 0x89, 0x6d, 0x89, 0x6f, 0x88, 0x6e, 0x88, 0x6c, 0x88, 0x6b, - 0x84, 0x74, 0x81, 0x7c, 0x80, 0x80, 0x80, 0x81, 0x80, 0x7f, 0x80, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7d, 0x7f, 0x7e, 0x57, 0x6b, 0x4e, 0x6b, - 0x4c, 0x69, 0x53, 0x66, 0x55, 0x65, 0x56, 0x62, 0x56, 0x60, 0x56, 0x63, - 0x56, 0x65, 0x56, 0x64, 0x56, 0x61, 0x56, 0x62, 0x56, 0x61, 0x54, 0x61, - 0x53, 0x63, 0x51, 0x64, 0x50, 0x64, 0x4f, 0x64, 0x4c, 0x67, 0x4b, 0x6a, - 0x4b, 0x69, 0x4b, 0x68, 0x4b, 0x69, 0x4c, 0x67, 0x4d, 0x65, 0x4f, 0x64, - 0x4f, 0x63, 0x4f, 0x63, 0x53, 0x62, 0x57, 0x62, 0x5c, 0x65, 0x5e, 0x6d, - 0x60, 0x70, 0x63, 0x73, 0x67, 0x73, 0x6b, 0x73, 0x71, 0x73, 0x75, 0x75, - 0x7a, 0x77, 0x7b, 0x78, 0x79, 0x76, 0x72, 0x75, 0x6c, 0x75, 0x69, 0x75, - 0x6c, 0x75, 0x6b, 0x75, 0x6f, 0x74, 0x74, 0x73, 0x6e, 0x76, 0x65, 0x77, - 0x63, 0x74, 0x63, 0x73, 0x63, 0x73, 0x69, 0x72, 0x66, 0x71, 0x63, 0x76, - 0x6f, 0x77, 0x75, 0x78, 0x74, 0x7c, 0x70, 0x7e, 0x6f, 0x7e, 0x71, 0x7e, - 0x6d, 0x7b, 0x71, 0x7e, 0x6f, 0x84, 0x61, 0x7f, 0x6e, 0x7a, 0x75, 0x7a, - 0x77, 0x79, 0x77, 0x77, 0x73, 0x75, 0x70, 0x74, 0x6f, 0x75, 0x6d, 0x74, - 0x6a, 0x74, 0x69, 0x73, 0x6a, 0x78, 0x6b, 0x77, 0x6b, 0x77, 0x6d, 0x7a, - 0x6f, 0x7d, 0x71, 0x7f, 0x6e, 0x7f, 0x6b, 0x80, 0x6a, 0x81, 0x6a, 0x81, - 0x6e, 0x80, 0x70, 0x7e, 0x6e, 0x7e, 0x6d, 0x7d, 0x6b, 0x7e, 0x68, 0x7f, - 0x63, 0x81, 0x5f, 0x81, 0x61, 0x82, 0x60, 0x82, 0x60, 0x82, 0x60, 0x82, - 0x60, 0x82, 0x5e, 0x7f, 0x5e, 0x7b, 0x5d, 0x74, 0x5d, 0x6b, 0x59, 0x6a, - 0x55, 0x6d, 0x58, 0x6b, 0x57, 0x6d, 0x55, 0x6e, 0x53, 0x6e, 0x5b, 0x76, - 0x63, 0x76, 0x67, 0x71, 0x6a, 0x70, 0x63, 0x72, 0x55, 0x73, 0x5a, 0x74, - 0x5b, 0x75, 0x5b, 0x77, 0x5b, 0x76, 0x58, 0x74, 0x59, 0x74, 0x5b, 0x74, - 0x59, 0x75, 0x57, 0x77, 0x5b, 0x78, 0x62, 0x78, 0x63, 0x74, 0x62, 0x6d, - 0x62, 0x68, 0x62, 0x66, 0x63, 0x66, 0x63, 0x66, 0x63, 0x66, 0x66, 0x66, - 0x69, 0x67, 0x6d, 0x67, 0x71, 0x68, 0x73, 0x68, 0x77, 0x68, 0x7b, 0x6a, - 0x82, 0x6b, 0x85, 0x6d, 0x87, 0x6c, 0x89, 0x6c, 0x8a, 0x6c, 0x88, 0x6b, - 0x88, 0x6d, 0x88, 0x6d, 0x87, 0x6b, 0x86, 0x6a, 0x82, 0x70, 0x7f, 0x77, - 0x7e, 0x7e, 0x80, 0x80, 0x81, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7e, 0x7f, 0x7e, 0x59, 0x6c, 0x56, 0x6b, 0x50, 0x6a, 0x50, 0x68, - 0x53, 0x66, 0x56, 0x63, 0x56, 0x62, 0x56, 0x63, 0x55, 0x64, 0x56, 0x64, - 0x57, 0x62, 0x56, 0x62, 0x56, 0x62, 0x55, 0x61, 0x54, 0x62, 0x53, 0x63, - 0x51, 0x65, 0x50, 0x66, 0x4d, 0x68, 0x4c, 0x69, 0x4b, 0x68, 0x4b, 0x68, - 0x4b, 0x68, 0x4c, 0x67, 0x4d, 0x66, 0x4f, 0x63, 0x51, 0x62, 0x51, 0x61, - 0x54, 0x62, 0x57, 0x63, 0x5c, 0x67, 0x5e, 0x6f, 0x61, 0x72, 0x64, 0x73, - 0x67, 0x73, 0x6c, 0x73, 0x72, 0x74, 0x75, 0x75, 0x7a, 0x78, 0x7c, 0x78, - 0x7b, 0x77, 0x76, 0x77, 0x70, 0x77, 0x67, 0x75, 0x68, 0x74, 0x6a, 0x75, - 0x70, 0x75, 0x77, 0x75, 0x73, 0x77, 0x6a, 0x77, 0x65, 0x75, 0x64, 0x72, - 0x64, 0x72, 0x69, 0x73, 0x68, 0x72, 0x61, 0x74, 0x65, 0x77, 0x6b, 0x78, - 0x72, 0x79, 0x73, 0x79, 0x6f, 0x77, 0x71, 0x79, 0x71, 0x7c, 0x74, 0x80, - 0x66, 0x82, 0x64, 0x7d, 0x72, 0x7a, 0x77, 0x7a, 0x77, 0x78, 0x75, 0x75, - 0x72, 0x74, 0x70, 0x73, 0x6f, 0x73, 0x6f, 0x73, 0x6d, 0x73, 0x6d, 0x73, - 0x6d, 0x74, 0x6e, 0x73, 0x6c, 0x76, 0x6d, 0x79, 0x6f, 0x7c, 0x72, 0x7e, - 0x71, 0x7d, 0x6f, 0x7e, 0x6d, 0x81, 0x6c, 0x82, 0x6f, 0x81, 0x73, 0x7e, - 0x70, 0x7d, 0x6c, 0x7e, 0x6b, 0x7f, 0x66, 0x81, 0x62, 0x83, 0x5e, 0x82, - 0x5e, 0x83, 0x5f, 0x84, 0x61, 0x84, 0x63, 0x84, 0x60, 0x84, 0x5d, 0x82, - 0x5f, 0x7d, 0x5f, 0x73, 0x5f, 0x6c, 0x5c, 0x6b, 0x5b, 0x6a, 0x5b, 0x6a, - 0x5b, 0x6b, 0x57, 0x6d, 0x58, 0x6e, 0x5d, 0x73, 0x5f, 0x75, 0x64, 0x72, - 0x6b, 0x6f, 0x64, 0x6f, 0x56, 0x73, 0x57, 0x74, 0x59, 0x75, 0x59, 0x77, - 0x5a, 0x78, 0x5a, 0x78, 0x58, 0x76, 0x59, 0x77, 0x58, 0x77, 0x58, 0x77, - 0x5b, 0x78, 0x62, 0x78, 0x62, 0x76, 0x60, 0x70, 0x60, 0x6b, 0x60, 0x67, - 0x61, 0x66, 0x62, 0x66, 0x63, 0x66, 0x64, 0x66, 0x68, 0x67, 0x6d, 0x67, - 0x70, 0x67, 0x73, 0x68, 0x76, 0x68, 0x7a, 0x6a, 0x7f, 0x6a, 0x82, 0x6b, - 0x85, 0x6c, 0x87, 0x6d, 0x88, 0x6c, 0x86, 0x6c, 0x85, 0x6c, 0x84, 0x6d, - 0x82, 0x6c, 0x80, 0x6c, 0x7a, 0x6f, 0x77, 0x71, 0x77, 0x74, 0x78, 0x77, - 0x7c, 0x7b, 0x7f, 0x7e, 0x7f, 0x7e, 0x7f, 0x7f, 0x80, 0x7e, 0x7f, 0x7e, - 0x5c, 0x6d, 0x5a, 0x6b, 0x54, 0x6b, 0x4e, 0x69, 0x51, 0x66, 0x55, 0x63, - 0x56, 0x63, 0x55, 0x63, 0x55, 0x63, 0x56, 0x63, 0x56, 0x63, 0x56, 0x62, - 0x56, 0x62, 0x55, 0x62, 0x56, 0x62, 0x53, 0x64, 0x51, 0x66, 0x50, 0x68, - 0x4d, 0x67, 0x4c, 0x68, 0x4b, 0x68, 0x4b, 0x68, 0x4b, 0x68, 0x4c, 0x67, - 0x4d, 0x66, 0x4f, 0x63, 0x51, 0x62, 0x51, 0x62, 0x54, 0x63, 0x58, 0x64, - 0x5e, 0x69, 0x60, 0x70, 0x62, 0x72, 0x65, 0x72, 0x69, 0x73, 0x6e, 0x73, - 0x72, 0x75, 0x76, 0x76, 0x79, 0x78, 0x7c, 0x78, 0x7c, 0x77, 0x78, 0x78, - 0x73, 0x78, 0x68, 0x76, 0x67, 0x74, 0x69, 0x74, 0x6f, 0x75, 0x77, 0x76, - 0x77, 0x78, 0x6e, 0x77, 0x66, 0x74, 0x65, 0x72, 0x65, 0x72, 0x6a, 0x73, - 0x69, 0x72, 0x62, 0x73, 0x5f, 0x7b, 0x64, 0x7d, 0x6c, 0x78, 0x72, 0x75, - 0x72, 0x74, 0x74, 0x76, 0x74, 0x7d, 0x6a, 0x83, 0x62, 0x81, 0x6c, 0x7e, - 0x76, 0x7a, 0x76, 0x7a, 0x76, 0x78, 0x73, 0x75, 0x71, 0x74, 0x70, 0x73, - 0x70, 0x72, 0x70, 0x72, 0x6f, 0x72, 0x6f, 0x72, 0x70, 0x72, 0x70, 0x71, - 0x69, 0x78, 0x66, 0x7c, 0x69, 0x7d, 0x70, 0x7e, 0x72, 0x7d, 0x72, 0x7d, - 0x71, 0x7f, 0x6f, 0x81, 0x6f, 0x80, 0x73, 0x7e, 0x71, 0x7d, 0x6c, 0x7d, - 0x6a, 0x7f, 0x65, 0x81, 0x63, 0x82, 0x5e, 0x82, 0x5b, 0x83, 0x5d, 0x84, - 0x61, 0x85, 0x65, 0x85, 0x62, 0x83, 0x5f, 0x7f, 0x5f, 0x7c, 0x60, 0x72, - 0x5f, 0x6e, 0x5f, 0x6b, 0x5f, 0x69, 0x5e, 0x6a, 0x5f, 0x6a, 0x5d, 0x6d, - 0x5e, 0x70, 0x5e, 0x70, 0x5d, 0x72, 0x5f, 0x73, 0x6a, 0x71, 0x66, 0x70, - 0x56, 0x74, 0x56, 0x74, 0x5a, 0x75, 0x5a, 0x76, 0x5c, 0x78, 0x5e, 0x78, - 0x5c, 0x76, 0x5a, 0x77, 0x58, 0x78, 0x58, 0x78, 0x5b, 0x78, 0x62, 0x77, - 0x63, 0x78, 0x60, 0x72, 0x5f, 0x6c, 0x5f, 0x67, 0x5f, 0x65, 0x62, 0x66, - 0x63, 0x66, 0x64, 0x65, 0x68, 0x67, 0x6b, 0x68, 0x6e, 0x68, 0x72, 0x68, - 0x74, 0x69, 0x78, 0x6a, 0x7b, 0x6a, 0x7e, 0x6a, 0x81, 0x6b, 0x83, 0x6d, - 0x82, 0x6d, 0x82, 0x6d, 0x80, 0x6d, 0x7c, 0x6c, 0x7a, 0x6d, 0x78, 0x6d, - 0x74, 0x6e, 0x6f, 0x6f, 0x6e, 0x6f, 0x6f, 0x6f, 0x71, 0x72, 0x78, 0x76, - 0x7b, 0x7a, 0x7d, 0x7c, 0x7e, 0x7e, 0x7f, 0x7f, 0x5d, 0x6e, 0x5b, 0x6b, - 0x57, 0x6a, 0x4e, 0x68, 0x51, 0x66, 0x55, 0x63, 0x56, 0x62, 0x55, 0x63, - 0x55, 0x63, 0x56, 0x63, 0x55, 0x63, 0x55, 0x61, 0x55, 0x62, 0x55, 0x62, - 0x56, 0x62, 0x53, 0x64, 0x51, 0x66, 0x4f, 0x67, 0x4e, 0x67, 0x4c, 0x68, - 0x4b, 0x68, 0x4b, 0x68, 0x4b, 0x69, 0x4c, 0x68, 0x4d, 0x66, 0x4f, 0x64, - 0x50, 0x64, 0x52, 0x63, 0x54, 0x62, 0x58, 0x64, 0x5f, 0x6b, 0x62, 0x72, - 0x64, 0x72, 0x67, 0x72, 0x6a, 0x72, 0x6f, 0x72, 0x72, 0x76, 0x75, 0x76, - 0x79, 0x77, 0x7b, 0x78, 0x7c, 0x77, 0x77, 0x77, 0x73, 0x77, 0x69, 0x76, - 0x68, 0x74, 0x68, 0x74, 0x6d, 0x75, 0x75, 0x76, 0x79, 0x78, 0x71, 0x77, - 0x66, 0x74, 0x65, 0x72, 0x64, 0x72, 0x6a, 0x73, 0x69, 0x72, 0x62, 0x73, - 0x5d, 0x7a, 0x5f, 0x7d, 0x66, 0x7c, 0x6d, 0x7a, 0x73, 0x78, 0x6f, 0x7b, - 0x68, 0x80, 0x5f, 0x80, 0x61, 0x7f, 0x6f, 0x7e, 0x77, 0x7a, 0x74, 0x7a, - 0x74, 0x78, 0x72, 0x75, 0x70, 0x74, 0x70, 0x72, 0x70, 0x71, 0x70, 0x70, - 0x70, 0x70, 0x6f, 0x71, 0x71, 0x70, 0x70, 0x72, 0x65, 0x7b, 0x63, 0x7f, - 0x67, 0x7f, 0x70, 0x7e, 0x74, 0x7e, 0x75, 0x7d, 0x74, 0x7e, 0x72, 0x80, - 0x71, 0x80, 0x72, 0x7e, 0x71, 0x7d, 0x6b, 0x7d, 0x69, 0x7e, 0x63, 0x81, - 0x61, 0x82, 0x5c, 0x82, 0x5a, 0x83, 0x5b, 0x84, 0x5f, 0x84, 0x62, 0x85, - 0x61, 0x81, 0x60, 0x7c, 0x60, 0x79, 0x60, 0x72, 0x60, 0x6f, 0x60, 0x6b, - 0x60, 0x69, 0x61, 0x6a, 0x61, 0x6a, 0x5e, 0x6e, 0x5e, 0x73, 0x5e, 0x71, - 0x5e, 0x73, 0x5f, 0x76, 0x64, 0x74, 0x64, 0x72, 0x56, 0x75, 0x58, 0x75, - 0x5c, 0x76, 0x5d, 0x75, 0x5f, 0x77, 0x62, 0x77, 0x60, 0x74, 0x5b, 0x75, - 0x58, 0x78, 0x58, 0x78, 0x5b, 0x78, 0x62, 0x78, 0x64, 0x79, 0x61, 0x73, - 0x5f, 0x6c, 0x5f, 0x66, 0x60, 0x65, 0x62, 0x66, 0x63, 0x65, 0x65, 0x65, - 0x67, 0x67, 0x6a, 0x68, 0x6c, 0x68, 0x70, 0x69, 0x73, 0x68, 0x75, 0x6a, - 0x78, 0x6a, 0x7b, 0x6a, 0x7e, 0x6b, 0x7e, 0x6c, 0x7e, 0x6d, 0x7d, 0x6d, - 0x7b, 0x6d, 0x77, 0x6c, 0x74, 0x6d, 0x73, 0x6c, 0x6e, 0x6d, 0x69, 0x6e, - 0x67, 0x6e, 0x68, 0x6e, 0x69, 0x70, 0x6e, 0x71, 0x72, 0x74, 0x77, 0x77, - 0x7c, 0x7a, 0x7f, 0x7e, 0x60, 0x6e, 0x5c, 0x6b, 0x58, 0x6a, 0x4f, 0x69, - 0x50, 0x67, 0x55, 0x64, 0x56, 0x63, 0x56, 0x62, 0x55, 0x62, 0x55, 0x63, - 0x55, 0x63, 0x56, 0x62, 0x55, 0x62, 0x55, 0x62, 0x55, 0x63, 0x53, 0x62, - 0x52, 0x64, 0x50, 0x66, 0x4f, 0x66, 0x4e, 0x68, 0x4c, 0x69, 0x4b, 0x68, - 0x4c, 0x68, 0x4c, 0x67, 0x4e, 0x65, 0x50, 0x64, 0x50, 0x64, 0x52, 0x62, - 0x55, 0x62, 0x59, 0x64, 0x60, 0x6d, 0x62, 0x73, 0x64, 0x74, 0x67, 0x74, - 0x6b, 0x74, 0x70, 0x74, 0x73, 0x75, 0x76, 0x75, 0x79, 0x78, 0x7b, 0x78, - 0x7b, 0x78, 0x79, 0x79, 0x74, 0x79, 0x6b, 0x77, 0x69, 0x75, 0x67, 0x74, - 0x6a, 0x74, 0x73, 0x76, 0x7a, 0x78, 0x73, 0x77, 0x66, 0x75, 0x66, 0x71, - 0x67, 0x71, 0x6a, 0x73, 0x6a, 0x73, 0x62, 0x72, 0x5f, 0x74, 0x5d, 0x77, - 0x5e, 0x7f, 0x64, 0x81, 0x61, 0x7f, 0x60, 0x7f, 0x5f, 0x80, 0x5b, 0x7b, - 0x63, 0x7a, 0x6a, 0x7a, 0x71, 0x78, 0x71, 0x78, 0x73, 0x77, 0x72, 0x76, - 0x71, 0x72, 0x6f, 0x71, 0x70, 0x71, 0x71, 0x71, 0x71, 0x70, 0x6f, 0x70, - 0x70, 0x6f, 0x6f, 0x73, 0x68, 0x7b, 0x68, 0x7d, 0x6c, 0x7d, 0x74, 0x7c, - 0x77, 0x7d, 0x78, 0x7c, 0x77, 0x7c, 0x76, 0x7e, 0x74, 0x80, 0x72, 0x7f, - 0x6f, 0x7d, 0x6a, 0x7f, 0x68, 0x81, 0x63, 0x82, 0x5f, 0x82, 0x5b, 0x82, - 0x5a, 0x82, 0x5b, 0x83, 0x5c, 0x84, 0x5e, 0x81, 0x60, 0x7c, 0x63, 0x7a, - 0x62, 0x75, 0x61, 0x72, 0x61, 0x6f, 0x62, 0x6c, 0x62, 0x69, 0x64, 0x69, - 0x62, 0x6b, 0x5c, 0x71, 0x5d, 0x76, 0x5f, 0x76, 0x5f, 0x76, 0x5f, 0x78, - 0x5f, 0x76, 0x61, 0x74, 0x59, 0x77, 0x59, 0x76, 0x5a, 0x75, 0x5d, 0x73, - 0x61, 0x74, 0x65, 0x76, 0x62, 0x73, 0x5c, 0x74, 0x58, 0x77, 0x59, 0x78, - 0x5d, 0x78, 0x63, 0x78, 0x64, 0x7a, 0x63, 0x76, 0x60, 0x6e, 0x5f, 0x69, - 0x61, 0x66, 0x63, 0x66, 0x64, 0x66, 0x64, 0x66, 0x66, 0x66, 0x68, 0x67, - 0x6b, 0x67, 0x6f, 0x68, 0x71, 0x68, 0x72, 0x6a, 0x75, 0x6a, 0x78, 0x6a, - 0x79, 0x6b, 0x7a, 0x6b, 0x7a, 0x6b, 0x78, 0x6c, 0x76, 0x6c, 0x72, 0x6c, - 0x70, 0x6c, 0x6d, 0x6b, 0x68, 0x6b, 0x64, 0x6c, 0x60, 0x6b, 0x60, 0x6c, - 0x62, 0x6e, 0x64, 0x6e, 0x67, 0x6c, 0x6e, 0x6e, 0x75, 0x70, 0x7a, 0x78, - 0x60, 0x6e, 0x5b, 0x6b, 0x58, 0x6a, 0x50, 0x6a, 0x51, 0x68, 0x55, 0x65, - 0x56, 0x63, 0x55, 0x63, 0x55, 0x63, 0x55, 0x63, 0x55, 0x64, 0x56, 0x64, - 0x55, 0x62, 0x55, 0x63, 0x54, 0x63, 0x53, 0x60, 0x53, 0x62, 0x51, 0x65, - 0x50, 0x65, 0x4f, 0x67, 0x4c, 0x68, 0x4c, 0x67, 0x4c, 0x67, 0x4d, 0x67, - 0x4f, 0x65, 0x50, 0x64, 0x50, 0x63, 0x53, 0x62, 0x56, 0x63, 0x5a, 0x65, - 0x5f, 0x6e, 0x62, 0x74, 0x64, 0x74, 0x67, 0x75, 0x6a, 0x75, 0x70, 0x75, - 0x74, 0x74, 0x76, 0x76, 0x7a, 0x78, 0x7b, 0x78, 0x7b, 0x7a, 0x7a, 0x7a, - 0x75, 0x7a, 0x6c, 0x78, 0x68, 0x77, 0x67, 0x75, 0x69, 0x73, 0x71, 0x76, - 0x78, 0x78, 0x71, 0x77, 0x67, 0x74, 0x68, 0x70, 0x68, 0x70, 0x6b, 0x72, - 0x6a, 0x73, 0x62, 0x72, 0x61, 0x73, 0x5e, 0x76, 0x5d, 0x7c, 0x64, 0x80, - 0x5e, 0x7f, 0x5f, 0x7d, 0x5f, 0x7c, 0x5d, 0x7a, 0x64, 0x79, 0x67, 0x79, - 0x6b, 0x77, 0x6d, 0x77, 0x72, 0x75, 0x73, 0x74, 0x71, 0x71, 0x6e, 0x70, - 0x6d, 0x71, 0x6f, 0x72, 0x71, 0x71, 0x6f, 0x70, 0x6e, 0x70, 0x6e, 0x74, - 0x6d, 0x79, 0x70, 0x7a, 0x74, 0x7a, 0x78, 0x7b, 0x78, 0x7c, 0x78, 0x7c, - 0x78, 0x7c, 0x78, 0x7d, 0x75, 0x7f, 0x72, 0x7f, 0x6e, 0x7e, 0x69, 0x82, - 0x67, 0x83, 0x63, 0x83, 0x5e, 0x82, 0x5c, 0x82, 0x5a, 0x81, 0x5c, 0x83, - 0x5c, 0x83, 0x5e, 0x7d, 0x61, 0x7a, 0x64, 0x7a, 0x62, 0x75, 0x60, 0x71, - 0x63, 0x70, 0x65, 0x6e, 0x64, 0x6a, 0x65, 0x69, 0x62, 0x6c, 0x5c, 0x73, - 0x5d, 0x77, 0x5f, 0x76, 0x5f, 0x76, 0x60, 0x7a, 0x5f, 0x77, 0x60, 0x75, - 0x5b, 0x78, 0x57, 0x77, 0x58, 0x73, 0x5b, 0x71, 0x5e, 0x71, 0x64, 0x73, - 0x64, 0x73, 0x5f, 0x73, 0x58, 0x76, 0x59, 0x78, 0x5d, 0x78, 0x63, 0x78, - 0x64, 0x7a, 0x63, 0x78, 0x61, 0x6f, 0x61, 0x6a, 0x62, 0x68, 0x64, 0x67, - 0x65, 0x68, 0x65, 0x67, 0x65, 0x67, 0x68, 0x68, 0x6a, 0x68, 0x6d, 0x69, - 0x6f, 0x69, 0x70, 0x6a, 0x73, 0x6a, 0x76, 0x6a, 0x76, 0x6a, 0x77, 0x6a, - 0x77, 0x6a, 0x75, 0x6a, 0x72, 0x6a, 0x6f, 0x6b, 0x6d, 0x6a, 0x68, 0x6a, - 0x64, 0x6b, 0x61, 0x6b, 0x5d, 0x6b, 0x5c, 0x6b, 0x5d, 0x6c, 0x5e, 0x6c, - 0x60, 0x6b, 0x68, 0x6b, 0x6e, 0x6d, 0x73, 0x6f, 0x60, 0x6d, 0x5b, 0x6a, - 0x58, 0x6a, 0x51, 0x6a, 0x52, 0x68, 0x55, 0x65, 0x55, 0x65, 0x55, 0x65, - 0x55, 0x65, 0x55, 0x65, 0x55, 0x65, 0x55, 0x64, 0x55, 0x62, 0x54, 0x63, - 0x54, 0x63, 0x54, 0x60, 0x53, 0x61, 0x51, 0x65, 0x50, 0x65, 0x4f, 0x65, - 0x4d, 0x66, 0x4c, 0x67, 0x4c, 0x67, 0x4e, 0x67, 0x4f, 0x64, 0x50, 0x63, - 0x52, 0x64, 0x54, 0x62, 0x58, 0x65, 0x5b, 0x67, 0x5f, 0x70, 0x62, 0x75, - 0x64, 0x75, 0x67, 0x75, 0x6a, 0x75, 0x70, 0x74, 0x74, 0x73, 0x76, 0x76, - 0x7a, 0x78, 0x7b, 0x78, 0x7b, 0x79, 0x79, 0x7a, 0x74, 0x7b, 0x6c, 0x7a, - 0x68, 0x79, 0x67, 0x77, 0x68, 0x75, 0x6f, 0x76, 0x76, 0x78, 0x70, 0x77, - 0x68, 0x74, 0x68, 0x70, 0x68, 0x71, 0x6a, 0x72, 0x6b, 0x73, 0x64, 0x72, - 0x63, 0x73, 0x61, 0x75, 0x5f, 0x7b, 0x64, 0x7e, 0x5e, 0x7d, 0x5e, 0x7b, - 0x5e, 0x7b, 0x5e, 0x78, 0x63, 0x77, 0x67, 0x77, 0x6c, 0x77, 0x6e, 0x77, - 0x72, 0x74, 0x73, 0x73, 0x73, 0x71, 0x70, 0x70, 0x6d, 0x72, 0x70, 0x72, - 0x71, 0x71, 0x6f, 0x70, 0x6e, 0x71, 0x70, 0x74, 0x72, 0x77, 0x74, 0x78, - 0x76, 0x78, 0x78, 0x7b, 0x77, 0x7c, 0x78, 0x7c, 0x78, 0x7d, 0x78, 0x7d, - 0x74, 0x7e, 0x72, 0x7e, 0x6e, 0x80, 0x68, 0x83, 0x65, 0x83, 0x62, 0x82, - 0x5e, 0x82, 0x5b, 0x81, 0x5a, 0x81, 0x5c, 0x83, 0x5d, 0x82, 0x5e, 0x7c, - 0x61, 0x7b, 0x61, 0x7d, 0x5f, 0x78, 0x5e, 0x73, 0x61, 0x72, 0x65, 0x72, - 0x64, 0x6d, 0x65, 0x6a, 0x61, 0x6e, 0x5b, 0x73, 0x5b, 0x76, 0x5f, 0x75, - 0x5a, 0x78, 0x5e, 0x7b, 0x63, 0x79, 0x62, 0x78, 0x5d, 0x79, 0x58, 0x7a, - 0x56, 0x77, 0x56, 0x74, 0x58, 0x72, 0x5f, 0x71, 0x61, 0x73, 0x5f, 0x73, - 0x56, 0x76, 0x58, 0x78, 0x5d, 0x78, 0x5f, 0x78, 0x63, 0x7a, 0x63, 0x77, - 0x62, 0x70, 0x63, 0x6a, 0x63, 0x69, 0x65, 0x69, 0x67, 0x69, 0x66, 0x69, - 0x66, 0x69, 0x68, 0x69, 0x6a, 0x6a, 0x6b, 0x6a, 0x6d, 0x6a, 0x6f, 0x6a, - 0x72, 0x6a, 0x73, 0x6a, 0x73, 0x6a, 0x72, 0x6a, 0x72, 0x6b, 0x70, 0x69, - 0x6e, 0x68, 0x6b, 0x69, 0x68, 0x68, 0x64, 0x6a, 0x5f, 0x6b, 0x5c, 0x6b, - 0x57, 0x6a, 0x56, 0x6b, 0x57, 0x6c, 0x59, 0x6d, 0x5b, 0x6e, 0x5f, 0x6d, - 0x64, 0x6d, 0x69, 0x6c, 0x5d, 0x6c, 0x5b, 0x6a, 0x56, 0x6a, 0x52, 0x6a, - 0x54, 0x67, 0x55, 0x65, 0x56, 0x65, 0x55, 0x66, 0x54, 0x66, 0x55, 0x66, - 0x55, 0x65, 0x55, 0x63, 0x55, 0x63, 0x54, 0x64, 0x54, 0x64, 0x53, 0x63, - 0x53, 0x62, 0x51, 0x64, 0x50, 0x64, 0x4f, 0x65, 0x4d, 0x65, 0x4c, 0x66, - 0x4d, 0x66, 0x4e, 0x67, 0x4f, 0x65, 0x51, 0x63, 0x53, 0x63, 0x54, 0x63, - 0x58, 0x66, 0x5c, 0x68, 0x5f, 0x71, 0x63, 0x76, 0x65, 0x74, 0x67, 0x74, - 0x6a, 0x74, 0x6f, 0x75, 0x74, 0x76, 0x76, 0x77, 0x7a, 0x78, 0x7a, 0x78, - 0x7b, 0x79, 0x79, 0x7a, 0x74, 0x7b, 0x6c, 0x7b, 0x69, 0x7a, 0x68, 0x78, - 0x67, 0x76, 0x6c, 0x76, 0x73, 0x78, 0x6e, 0x77, 0x69, 0x74, 0x69, 0x70, - 0x68, 0x70, 0x69, 0x72, 0x69, 0x73, 0x63, 0x72, 0x64, 0x73, 0x65, 0x73, - 0x61, 0x78, 0x5e, 0x7c, 0x5b, 0x7b, 0x5c, 0x7a, 0x5f, 0x79, 0x61, 0x77, - 0x65, 0x77, 0x69, 0x78, 0x70, 0x78, 0x71, 0x78, 0x73, 0x74, 0x73, 0x72, - 0x73, 0x71, 0x72, 0x70, 0x70, 0x71, 0x71, 0x71, 0x70, 0x71, 0x6e, 0x71, - 0x6e, 0x71, 0x72, 0x74, 0x75, 0x76, 0x76, 0x78, 0x76, 0x78, 0x77, 0x7a, - 0x77, 0x7b, 0x77, 0x7b, 0x78, 0x7c, 0x77, 0x7b, 0x75, 0x7c, 0x73, 0x7c, - 0x6f, 0x80, 0x68, 0x83, 0x64, 0x83, 0x60, 0x83, 0x5e, 0x83, 0x5c, 0x83, - 0x5b, 0x83, 0x5b, 0x84, 0x5b, 0x82, 0x5e, 0x7b, 0x61, 0x7a, 0x5e, 0x7c, - 0x5b, 0x79, 0x5d, 0x78, 0x60, 0x75, 0x60, 0x74, 0x60, 0x73, 0x61, 0x70, - 0x5f, 0x70, 0x58, 0x72, 0x58, 0x77, 0x61, 0x77, 0x5b, 0x7c, 0x59, 0x7f, - 0x69, 0x7a, 0x66, 0x77, 0x5f, 0x7b, 0x56, 0x7d, 0x53, 0x7d, 0x53, 0x7a, - 0x56, 0x77, 0x5a, 0x74, 0x5c, 0x73, 0x5a, 0x74, 0x54, 0x77, 0x55, 0x78, - 0x5c, 0x79, 0x5e, 0x78, 0x60, 0x7b, 0x62, 0x78, 0x63, 0x6e, 0x64, 0x6a, - 0x66, 0x6a, 0x66, 0x6a, 0x67, 0x6a, 0x67, 0x6a, 0x68, 0x6a, 0x69, 0x6a, - 0x69, 0x6a, 0x69, 0x6a, 0x6a, 0x6a, 0x6d, 0x6a, 0x6e, 0x6a, 0x6f, 0x6a, - 0x6f, 0x6a, 0x6e, 0x69, 0x6c, 0x69, 0x69, 0x68, 0x67, 0x68, 0x64, 0x68, - 0x62, 0x68, 0x5f, 0x69, 0x5b, 0x6a, 0x58, 0x6a, 0x53, 0x6a, 0x53, 0x6b, - 0x54, 0x6d, 0x55, 0x6d, 0x56, 0x6e, 0x58, 0x6d, 0x5b, 0x6d, 0x60, 0x70, - 0x5c, 0x6c, 0x59, 0x6c, 0x54, 0x6b, 0x54, 0x69, 0x55, 0x67, 0x55, 0x66, - 0x55, 0x65, 0x54, 0x65, 0x53, 0x66, 0x54, 0x66, 0x54, 0x65, 0x54, 0x64, - 0x54, 0x65, 0x54, 0x65, 0x54, 0x65, 0x53, 0x65, 0x53, 0x63, 0x50, 0x64, - 0x50, 0x64, 0x4f, 0x64, 0x4d, 0x65, 0x4d, 0x66, 0x4d, 0x65, 0x4e, 0x66, - 0x50, 0x66, 0x52, 0x62, 0x53, 0x63, 0x53, 0x65, 0x58, 0x66, 0x5c, 0x69, - 0x5f, 0x70, 0x64, 0x75, 0x64, 0x73, 0x67, 0x73, 0x6a, 0x74, 0x6f, 0x76, - 0x75, 0x78, 0x77, 0x78, 0x79, 0x78, 0x7a, 0x78, 0x7a, 0x79, 0x78, 0x7a, - 0x74, 0x7a, 0x6e, 0x7b, 0x69, 0x7a, 0x67, 0x78, 0x65, 0x78, 0x69, 0x77, - 0x71, 0x77, 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x69, 0x6e, 0x69, 0x71, - 0x69, 0x71, 0x63, 0x72, 0x63, 0x72, 0x64, 0x72, 0x62, 0x76, 0x5e, 0x7a, - 0x5c, 0x7b, 0x5d, 0x79, 0x60, 0x78, 0x62, 0x78, 0x67, 0x78, 0x6c, 0x78, - 0x72, 0x78, 0x72, 0x78, 0x73, 0x75, 0x73, 0x74, 0x73, 0x72, 0x72, 0x72, - 0x70, 0x72, 0x70, 0x71, 0x6f, 0x71, 0x6d, 0x72, 0x6e, 0x72, 0x72, 0x74, - 0x76, 0x76, 0x77, 0x78, 0x77, 0x78, 0x77, 0x79, 0x77, 0x7a, 0x77, 0x7a, - 0x77, 0x7b, 0x76, 0x7b, 0x74, 0x7b, 0x75, 0x7b, 0x73, 0x7e, 0x6a, 0x84, - 0x64, 0x84, 0x5f, 0x84, 0x5e, 0x85, 0x5c, 0x84, 0x5b, 0x84, 0x5b, 0x84, - 0x59, 0x84, 0x5d, 0x7c, 0x61, 0x79, 0x5e, 0x79, 0x5b, 0x7a, 0x5d, 0x7a, - 0x60, 0x77, 0x60, 0x76, 0x5d, 0x78, 0x5d, 0x75, 0x5d, 0x73, 0x54, 0x77, - 0x52, 0x7b, 0x5e, 0x7d, 0x5c, 0x80, 0x59, 0x81, 0x68, 0x79, 0x66, 0x78, - 0x5f, 0x7f, 0x53, 0x7e, 0x4f, 0x7e, 0x54, 0x7d, 0x55, 0x7a, 0x59, 0x77, - 0x5b, 0x75, 0x59, 0x75, 0x55, 0x77, 0x55, 0x79, 0x5b, 0x7b, 0x5d, 0x7a, - 0x5f, 0x7b, 0x61, 0x77, 0x63, 0x6d, 0x65, 0x6a, 0x67, 0x6a, 0x67, 0x6a, - 0x68, 0x6b, 0x68, 0x6b, 0x69, 0x6b, 0x6a, 0x6b, 0x69, 0x6a, 0x68, 0x69, - 0x69, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6a, 0x6c, 0x6a, 0x6b, 0x68, - 0x68, 0x68, 0x66, 0x69, 0x64, 0x68, 0x61, 0x68, 0x5e, 0x68, 0x5c, 0x69, - 0x59, 0x6a, 0x56, 0x6a, 0x53, 0x6b, 0x53, 0x6b, 0x52, 0x6c, 0x52, 0x6d, - 0x55, 0x6f, 0x56, 0x6e, 0x58, 0x6c, 0x5d, 0x6e, 0x5b, 0x6d, 0x57, 0x69, - 0x57, 0x67, 0x57, 0x68, 0x56, 0x66, 0x55, 0x66, 0x54, 0x65, 0x54, 0x65, - 0x54, 0x65, 0x54, 0x65, 0x54, 0x66, 0x54, 0x66, 0x54, 0x66, 0x54, 0x65, - 0x54, 0x65, 0x53, 0x65, 0x52, 0x62, 0x50, 0x64, 0x50, 0x64, 0x4f, 0x65, - 0x4d, 0x66, 0x4d, 0x66, 0x4d, 0x66, 0x4e, 0x66, 0x50, 0x66, 0x52, 0x63, - 0x54, 0x63, 0x53, 0x65, 0x58, 0x67, 0x5b, 0x69, 0x5f, 0x6e, 0x64, 0x73, - 0x65, 0x73, 0x67, 0x72, 0x6a, 0x73, 0x6f, 0x76, 0x75, 0x78, 0x76, 0x78, - 0x79, 0x78, 0x7a, 0x77, 0x7a, 0x79, 0x77, 0x7a, 0x76, 0x7a, 0x71, 0x79, - 0x6c, 0x78, 0x68, 0x78, 0x66, 0x78, 0x68, 0x77, 0x6c, 0x77, 0x69, 0x77, - 0x68, 0x74, 0x6b, 0x71, 0x6c, 0x71, 0x68, 0x70, 0x64, 0x70, 0x63, 0x71, - 0x64, 0x72, 0x64, 0x72, 0x62, 0x76, 0x5f, 0x7b, 0x5e, 0x7b, 0x5f, 0x79, - 0x60, 0x78, 0x64, 0x78, 0x6b, 0x78, 0x6f, 0x78, 0x73, 0x78, 0x73, 0x78, - 0x73, 0x77, 0x73, 0x75, 0x72, 0x74, 0x72, 0x74, 0x72, 0x73, 0x73, 0x74, - 0x71, 0x73, 0x6f, 0x74, 0x6d, 0x74, 0x72, 0x76, 0x78, 0x78, 0x77, 0x78, - 0x77, 0x78, 0x77, 0x79, 0x77, 0x7a, 0x77, 0x7b, 0x77, 0x7b, 0x76, 0x7b, - 0x75, 0x7b, 0x75, 0x7a, 0x77, 0x7e, 0x6d, 0x84, 0x65, 0x86, 0x5f, 0x86, - 0x5e, 0x86, 0x5b, 0x86, 0x5b, 0x86, 0x5b, 0x86, 0x58, 0x85, 0x5b, 0x7e, - 0x61, 0x7a, 0x60, 0x7a, 0x5d, 0x7a, 0x60, 0x7a, 0x60, 0x79, 0x5d, 0x7a, - 0x5c, 0x7c, 0x5c, 0x7b, 0x5a, 0x79, 0x51, 0x7d, 0x50, 0x7e, 0x57, 0x83, - 0x5b, 0x82, 0x61, 0x7c, 0x64, 0x79, 0x65, 0x7c, 0x5e, 0x81, 0x50, 0x7e, - 0x4c, 0x7d, 0x51, 0x7e, 0x53, 0x7c, 0x57, 0x7a, 0x5a, 0x79, 0x5d, 0x79, - 0x5b, 0x79, 0x59, 0x7c, 0x5a, 0x7c, 0x5d, 0x79, 0x5f, 0x79, 0x62, 0x76, - 0x64, 0x6d, 0x67, 0x6a, 0x69, 0x6d, 0x69, 0x6d, 0x6a, 0x6d, 0x6a, 0x6d, - 0x6a, 0x6d, 0x6a, 0x6d, 0x69, 0x6c, 0x68, 0x6b, 0x69, 0x6b, 0x69, 0x6b, - 0x69, 0x6b, 0x68, 0x6a, 0x69, 0x6a, 0x67, 0x68, 0x65, 0x68, 0x62, 0x68, - 0x60, 0x68, 0x5d, 0x68, 0x5b, 0x69, 0x58, 0x69, 0x55, 0x6a, 0x53, 0x6a, - 0x53, 0x6a, 0x52, 0x6a, 0x51, 0x6a, 0x52, 0x6b, 0x55, 0x6e, 0x57, 0x6d, - 0x58, 0x6a, 0x59, 0x6c, 0x5a, 0x69, 0x5b, 0x64, 0x5b, 0x64, 0x58, 0x67, - 0x56, 0x66, 0x55, 0x65, 0x54, 0x66, 0x54, 0x66, 0x54, 0x66, 0x54, 0x66, - 0x54, 0x66, 0x54, 0x67, 0x54, 0x67, 0x54, 0x64, 0x54, 0x64, 0x53, 0x65, - 0x53, 0x63, 0x51, 0x65, 0x50, 0x65, 0x4f, 0x65, 0x4d, 0x66, 0x4e, 0x66, - 0x4e, 0x66, 0x4f, 0x66, 0x51, 0x66, 0x53, 0x63, 0x54, 0x62, 0x54, 0x65, - 0x58, 0x67, 0x5b, 0x69, 0x5e, 0x6d, 0x64, 0x72, 0x64, 0x73, 0x67, 0x73, - 0x69, 0x74, 0x6e, 0x76, 0x74, 0x78, 0x76, 0x78, 0x79, 0x78, 0x7a, 0x78, - 0x7a, 0x79, 0x77, 0x79, 0x76, 0x79, 0x74, 0x78, 0x70, 0x78, 0x6e, 0x78, - 0x6b, 0x77, 0x6a, 0x77, 0x6a, 0x77, 0x67, 0x77, 0x67, 0x75, 0x6b, 0x72, - 0x6d, 0x72, 0x63, 0x6f, 0x5c, 0x6f, 0x61, 0x71, 0x64, 0x72, 0x64, 0x72, - 0x62, 0x76, 0x60, 0x7a, 0x5f, 0x7b, 0x5f, 0x7a, 0x60, 0x78, 0x65, 0x78, - 0x6e, 0x78, 0x72, 0x78, 0x75, 0x78, 0x75, 0x78, 0x73, 0x78, 0x73, 0x77, - 0x72, 0x76, 0x73, 0x75, 0x74, 0x75, 0x74, 0x75, 0x73, 0x75, 0x71, 0x75, - 0x6d, 0x76, 0x73, 0x78, 0x79, 0x78, 0x77, 0x78, 0x77, 0x78, 0x77, 0x79, - 0x77, 0x7a, 0x77, 0x7a, 0x77, 0x7b, 0x76, 0x7b, 0x75, 0x7a, 0x75, 0x7b, - 0x75, 0x7e, 0x6a, 0x84, 0x64, 0x87, 0x5f, 0x87, 0x5e, 0x87, 0x5d, 0x87, - 0x5c, 0x87, 0x5c, 0x88, 0x57, 0x87, 0x5a, 0x7f, 0x5e, 0x7b, 0x5c, 0x7a, - 0x5d, 0x7a, 0x61, 0x7a, 0x60, 0x7c, 0x5c, 0x7d, 0x5b, 0x7f, 0x5c, 0x7e, - 0x5a, 0x7d, 0x54, 0x7d, 0x54, 0x7c, 0x57, 0x83, 0x61, 0x7f, 0x67, 0x78, - 0x63, 0x79, 0x66, 0x7c, 0x5d, 0x7e, 0x4e, 0x7c, 0x4a, 0x7d, 0x4f, 0x7d, - 0x52, 0x7d, 0x55, 0x7c, 0x59, 0x7c, 0x5f, 0x7c, 0x5e, 0x7b, 0x5d, 0x7d, - 0x5b, 0x7c, 0x5c, 0x79, 0x5f, 0x78, 0x62, 0x75, 0x66, 0x6c, 0x68, 0x69, - 0x6b, 0x6e, 0x6b, 0x6e, 0x6b, 0x6e, 0x6c, 0x6e, 0x6b, 0x6e, 0x6a, 0x6e, - 0x6a, 0x6e, 0x69, 0x6d, 0x68, 0x6d, 0x67, 0x6c, 0x67, 0x6b, 0x66, 0x6a, - 0x65, 0x6a, 0x64, 0x69, 0x61, 0x68, 0x5f, 0x68, 0x5d, 0x69, 0x5a, 0x69, - 0x58, 0x68, 0x56, 0x6a, 0x53, 0x6b, 0x52, 0x6a, 0x53, 0x6a, 0x54, 0x6a, - 0x54, 0x69, 0x54, 0x6a, 0x55, 0x6a, 0x58, 0x6a, 0x58, 0x6a, 0x58, 0x6c, - 0x5e, 0x66, 0x5d, 0x66, 0x5b, 0x64, 0x58, 0x67, 0x56, 0x66, 0x55, 0x65, - 0x54, 0x67, 0x54, 0x68, 0x54, 0x68, 0x54, 0x67, 0x54, 0x66, 0x54, 0x65, - 0x54, 0x66, 0x53, 0x66, 0x53, 0x65, 0x53, 0x65, 0x53, 0x65, 0x51, 0x65, - 0x51, 0x64, 0x4f, 0x63, 0x4e, 0x65, 0x4e, 0x66, 0x4e, 0x66, 0x4f, 0x66, - 0x51, 0x64, 0x54, 0x62, 0x54, 0x64, 0x55, 0x66, 0x59, 0x67, 0x5b, 0x68, - 0x5e, 0x6d, 0x62, 0x72, 0x63, 0x73, 0x66, 0x74, 0x6a, 0x75, 0x6c, 0x75, - 0x72, 0x77, 0x73, 0x77, 0x77, 0x77, 0x7a, 0x78, 0x79, 0x78, 0x77, 0x78, - 0x77, 0x78, 0x78, 0x78, 0x72, 0x78, 0x6f, 0x77, 0x6d, 0x77, 0x6f, 0x78, - 0x6e, 0x78, 0x6c, 0x78, 0x6a, 0x78, 0x69, 0x75, 0x6a, 0x73, 0x5d, 0x70, - 0x56, 0x72, 0x5e, 0x73, 0x61, 0x74, 0x62, 0x74, 0x61, 0x77, 0x60, 0x79, - 0x5e, 0x7a, 0x5c, 0x7b, 0x5e, 0x7a, 0x65, 0x79, 0x6d, 0x7b, 0x71, 0x7a, - 0x73, 0x78, 0x73, 0x78, 0x73, 0x78, 0x73, 0x78, 0x72, 0x78, 0x74, 0x77, - 0x75, 0x78, 0x75, 0x78, 0x75, 0x77, 0x75, 0x77, 0x73, 0x79, 0x78, 0x7a, - 0x78, 0x79, 0x77, 0x79, 0x77, 0x7a, 0x76, 0x7a, 0x77, 0x7a, 0x78, 0x7a, - 0x77, 0x7b, 0x75, 0x7a, 0x74, 0x7a, 0x74, 0x7c, 0x73, 0x7f, 0x68, 0x85, - 0x62, 0x88, 0x5f, 0x88, 0x60, 0x88, 0x5f, 0x88, 0x5e, 0x88, 0x5e, 0x88, - 0x59, 0x87, 0x58, 0x7f, 0x5c, 0x7c, 0x5d, 0x7c, 0x5f, 0x7d, 0x60, 0x7d, - 0x60, 0x7d, 0x5b, 0x7e, 0x5a, 0x7e, 0x5d, 0x7f, 0x5a, 0x7e, 0x57, 0x7e, - 0x5a, 0x7f, 0x64, 0x7d, 0x71, 0x78, 0x6e, 0x79, 0x6a, 0x7c, 0x6d, 0x7e, - 0x5c, 0x7c, 0x50, 0x7b, 0x4d, 0x7b, 0x53, 0x79, 0x53, 0x79, 0x54, 0x7b, - 0x58, 0x7c, 0x5d, 0x7d, 0x60, 0x7c, 0x61, 0x7c, 0x60, 0x7c, 0x60, 0x7a, - 0x60, 0x77, 0x63, 0x73, 0x67, 0x6c, 0x69, 0x6a, 0x6b, 0x6e, 0x6b, 0x6e, - 0x6b, 0x6f, 0x6b, 0x6f, 0x6b, 0x6f, 0x6b, 0x6f, 0x6a, 0x6f, 0x67, 0x6e, - 0x66, 0x6d, 0x65, 0x6c, 0x63, 0x6c, 0x63, 0x6b, 0x60, 0x6a, 0x60, 0x6a, - 0x5d, 0x6a, 0x5c, 0x69, 0x5a, 0x6a, 0x57, 0x6a, 0x56, 0x69, 0x56, 0x6a, - 0x54, 0x6b, 0x54, 0x6b, 0x55, 0x6a, 0x55, 0x6a, 0x55, 0x6b, 0x55, 0x6b, - 0x56, 0x6a, 0x56, 0x6b, 0x58, 0x6c, 0x5a, 0x6c, 0x60, 0x62, 0x5e, 0x62, - 0x5b, 0x63, 0x58, 0x65, 0x55, 0x65, 0x55, 0x66, 0x54, 0x66, 0x54, 0x66, - 0x54, 0x66, 0x54, 0x65, 0x54, 0x65, 0x54, 0x65, 0x53, 0x66, 0x53, 0x67, - 0x53, 0x65, 0x53, 0x65, 0x53, 0x65, 0x51, 0x65, 0x51, 0x64, 0x50, 0x63, - 0x4e, 0x65, 0x4e, 0x64, 0x4f, 0x63, 0x51, 0x64, 0x53, 0x62, 0x55, 0x62, - 0x53, 0x64, 0x55, 0x67, 0x5a, 0x68, 0x5b, 0x68, 0x5e, 0x6b, 0x62, 0x70, - 0x63, 0x73, 0x66, 0x74, 0x68, 0x75, 0x6a, 0x75, 0x70, 0x77, 0x72, 0x77, - 0x76, 0x78, 0x79, 0x78, 0x78, 0x78, 0x77, 0x78, 0x77, 0x79, 0x77, 0x7a, - 0x6d, 0x7a, 0x68, 0x78, 0x6b, 0x78, 0x6e, 0x78, 0x72, 0x78, 0x73, 0x78, - 0x73, 0x78, 0x6e, 0x79, 0x6b, 0x77, 0x5f, 0x72, 0x58, 0x77, 0x5b, 0x77, - 0x5f, 0x76, 0x5f, 0x76, 0x5f, 0x79, 0x5f, 0x7b, 0x5e, 0x7c, 0x5b, 0x7d, - 0x5c, 0x7c, 0x63, 0x7a, 0x69, 0x7b, 0x6d, 0x7b, 0x71, 0x7a, 0x71, 0x7a, - 0x71, 0x7a, 0x71, 0x7a, 0x70, 0x7a, 0x72, 0x7a, 0x74, 0x7b, 0x73, 0x7c, - 0x74, 0x7b, 0x75, 0x7a, 0x76, 0x7b, 0x7b, 0x7c, 0x78, 0x7c, 0x77, 0x7b, - 0x77, 0x7b, 0x76, 0x7b, 0x77, 0x7a, 0x79, 0x7a, 0x77, 0x7b, 0x74, 0x7b, - 0x73, 0x7c, 0x73, 0x7e, 0x6d, 0x81, 0x64, 0x87, 0x62, 0x88, 0x5f, 0x88, - 0x60, 0x86, 0x5f, 0x86, 0x5f, 0x86, 0x60, 0x86, 0x5d, 0x87, 0x59, 0x83, - 0x5a, 0x7f, 0x60, 0x7e, 0x60, 0x7e, 0x5f, 0x7e, 0x5e, 0x7e, 0x59, 0x7e, - 0x58, 0x7d, 0x5c, 0x7d, 0x5b, 0x7d, 0x61, 0x7e, 0x68, 0x7b, 0x73, 0x73, - 0x79, 0x75, 0x75, 0x7c, 0x70, 0x7e, 0x6e, 0x7c, 0x5b, 0x77, 0x51, 0x78, - 0x53, 0x77, 0x57, 0x74, 0x57, 0x75, 0x56, 0x78, 0x58, 0x7a, 0x5b, 0x7c, - 0x60, 0x7e, 0x62, 0x7e, 0x63, 0x7c, 0x63, 0x7a, 0x5f, 0x77, 0x61, 0x73, - 0x66, 0x6f, 0x68, 0x6d, 0x69, 0x6d, 0x6a, 0x6e, 0x69, 0x6f, 0x69, 0x6f, - 0x6a, 0x6f, 0x69, 0x6f, 0x69, 0x6f, 0x65, 0x6e, 0x64, 0x6d, 0x64, 0x6c, - 0x61, 0x6c, 0x5f, 0x6b, 0x5c, 0x6a, 0x5c, 0x6a, 0x59, 0x6a, 0x58, 0x6a, - 0x56, 0x69, 0x54, 0x6b, 0x54, 0x6b, 0x54, 0x6b, 0x55, 0x6b, 0x55, 0x6b, - 0x55, 0x6b, 0x55, 0x6b, 0x57, 0x6b, 0x56, 0x6a, 0x55, 0x6a, 0x56, 0x6b, - 0x58, 0x6b, 0x5b, 0x6a, 0x61, 0x5f, 0x5e, 0x5f, 0x5b, 0x62, 0x58, 0x63, - 0x56, 0x65, 0x55, 0x65, 0x55, 0x65, 0x55, 0x65, 0x55, 0x64, 0x55, 0x64, - 0x54, 0x64, 0x54, 0x65, 0x54, 0x66, 0x53, 0x66, 0x53, 0x65, 0x53, 0x65, - 0x53, 0x65, 0x51, 0x64, 0x51, 0x64, 0x50, 0x63, 0x4f, 0x64, 0x4e, 0x63, - 0x50, 0x62, 0x52, 0x63, 0x53, 0x62, 0x55, 0x61, 0x53, 0x65, 0x55, 0x67, - 0x5a, 0x67, 0x5c, 0x67, 0x5e, 0x6b, 0x62, 0x70, 0x63, 0x73, 0x66, 0x74, - 0x66, 0x75, 0x69, 0x75, 0x6e, 0x77, 0x71, 0x77, 0x74, 0x78, 0x77, 0x78, - 0x77, 0x78, 0x77, 0x78, 0x77, 0x7a, 0x71, 0x7b, 0x66, 0x7b, 0x63, 0x7a, - 0x67, 0x79, 0x69, 0x78, 0x6f, 0x78, 0x72, 0x77, 0x76, 0x78, 0x76, 0x7b, - 0x72, 0x79, 0x66, 0x77, 0x5e, 0x78, 0x5b, 0x77, 0x5f, 0x77, 0x5f, 0x77, - 0x5d, 0x7a, 0x5e, 0x7d, 0x5e, 0x7e, 0x5b, 0x7e, 0x5b, 0x7d, 0x61, 0x7b, - 0x67, 0x7b, 0x6b, 0x7b, 0x70, 0x7b, 0x70, 0x7c, 0x70, 0x7b, 0x6f, 0x7b, - 0x6f, 0x7b, 0x71, 0x7c, 0x73, 0x7d, 0x73, 0x7e, 0x75, 0x7d, 0x75, 0x7c, - 0x75, 0x7d, 0x78, 0x7e, 0x76, 0x7d, 0x77, 0x7c, 0x78, 0x7c, 0x76, 0x7b, - 0x77, 0x7a, 0x79, 0x7a, 0x77, 0x7a, 0x74, 0x7b, 0x72, 0x7e, 0x71, 0x80, - 0x68, 0x82, 0x62, 0x87, 0x62, 0x88, 0x5f, 0x88, 0x5f, 0x85, 0x5f, 0x85, - 0x60, 0x85, 0x60, 0x85, 0x5f, 0x86, 0x59, 0x85, 0x58, 0x81, 0x5e, 0x7f, - 0x5f, 0x7e, 0x5d, 0x7d, 0x5c, 0x7d, 0x58, 0x7e, 0x59, 0x7d, 0x60, 0x7c, - 0x60, 0x7c, 0x69, 0x79, 0x71, 0x75, 0x74, 0x75, 0x75, 0x7a, 0x75, 0x7d, - 0x70, 0x7a, 0x6b, 0x78, 0x5a, 0x75, 0x52, 0x76, 0x58, 0x75, 0x59, 0x72, - 0x5a, 0x73, 0x59, 0x76, 0x58, 0x78, 0x58, 0x7b, 0x5c, 0x7f, 0x5e, 0x7f, - 0x60, 0x7c, 0x60, 0x79, 0x5e, 0x7a, 0x60, 0x78, 0x65, 0x72, 0x66, 0x70, - 0x68, 0x6e, 0x68, 0x6e, 0x67, 0x6f, 0x68, 0x6f, 0x68, 0x6f, 0x68, 0x6f, - 0x68, 0x6e, 0x64, 0x6e, 0x63, 0x6d, 0x63, 0x6c, 0x5f, 0x6c, 0x5d, 0x6b, - 0x5a, 0x6a, 0x59, 0x6a, 0x56, 0x6a, 0x55, 0x6a, 0x53, 0x6a, 0x53, 0x6c, - 0x53, 0x6c, 0x54, 0x6b, 0x55, 0x6b, 0x56, 0x6c, 0x55, 0x6d, 0x56, 0x6c, - 0x58, 0x6b, 0x57, 0x6b, 0x56, 0x6b, 0x56, 0x6a, 0x58, 0x6a, 0x5a, 0x6a, - 0x62, 0x5d, 0x5e, 0x5f, 0x5b, 0x63, 0x58, 0x63, 0x56, 0x65, 0x56, 0x65, - 0x56, 0x65, 0x55, 0x65, 0x55, 0x65, 0x55, 0x65, 0x55, 0x65, 0x54, 0x66, - 0x54, 0x66, 0x53, 0x65, 0x53, 0x65, 0x51, 0x65, 0x51, 0x65, 0x51, 0x64, - 0x51, 0x62, 0x51, 0x63, 0x50, 0x64, 0x4f, 0x63, 0x51, 0x63, 0x53, 0x62, - 0x54, 0x61, 0x55, 0x63, 0x54, 0x66, 0x56, 0x67, 0x5a, 0x68, 0x5c, 0x68, - 0x5e, 0x6c, 0x61, 0x71, 0x63, 0x72, 0x66, 0x74, 0x67, 0x75, 0x69, 0x76, - 0x6e, 0x77, 0x72, 0x78, 0x73, 0x79, 0x75, 0x79, 0x76, 0x79, 0x76, 0x78, - 0x76, 0x79, 0x6e, 0x7a, 0x66, 0x7a, 0x61, 0x7b, 0x60, 0x7b, 0x62, 0x7b, - 0x68, 0x78, 0x6d, 0x78, 0x73, 0x78, 0x7a, 0x7b, 0x7c, 0x7b, 0x74, 0x7c, - 0x6b, 0x7a, 0x60, 0x78, 0x5c, 0x7b, 0x5d, 0x7b, 0x5c, 0x7c, 0x5b, 0x7f, - 0x5b, 0x80, 0x5a, 0x80, 0x5b, 0x81, 0x5f, 0x7e, 0x65, 0x7b, 0x69, 0x7d, - 0x6e, 0x7c, 0x6f, 0x7c, 0x6e, 0x7b, 0x6a, 0x7b, 0x69, 0x7c, 0x6c, 0x7c, - 0x6f, 0x7c, 0x71, 0x7e, 0x71, 0x7f, 0x72, 0x7e, 0x73, 0x7f, 0x71, 0x7f, - 0x6f, 0x7e, 0x71, 0x7d, 0x72, 0x7d, 0x71, 0x7c, 0x72, 0x7c, 0x74, 0x7c, - 0x71, 0x7c, 0x6f, 0x7d, 0x6c, 0x82, 0x68, 0x84, 0x63, 0x86, 0x62, 0x87, - 0x61, 0x87, 0x60, 0x87, 0x5f, 0x85, 0x5f, 0x85, 0x5f, 0x84, 0x5f, 0x84, - 0x60, 0x85, 0x5a, 0x85, 0x58, 0x84, 0x5a, 0x7f, 0x5c, 0x7c, 0x5c, 0x7c, - 0x5c, 0x7c, 0x5b, 0x7c, 0x5d, 0x7c, 0x67, 0x7c, 0x6c, 0x7c, 0x71, 0x78, - 0x74, 0x78, 0x76, 0x7b, 0x79, 0x77, 0x77, 0x77, 0x6d, 0x74, 0x65, 0x74, - 0x57, 0x77, 0x56, 0x74, 0x5a, 0x74, 0x5b, 0x73, 0x5a, 0x74, 0x5a, 0x76, - 0x58, 0x77, 0x56, 0x7a, 0x57, 0x7d, 0x59, 0x7c, 0x5c, 0x7d, 0x5e, 0x7c, - 0x5d, 0x7e, 0x5e, 0x82, 0x62, 0x7b, 0x65, 0x76, 0x66, 0x72, 0x64, 0x73, - 0x62, 0x72, 0x64, 0x70, 0x66, 0x6f, 0x66, 0x6e, 0x66, 0x6e, 0x63, 0x6d, - 0x61, 0x6d, 0x5f, 0x6c, 0x5d, 0x6c, 0x5b, 0x6c, 0x56, 0x69, 0x55, 0x6b, - 0x53, 0x6b, 0x52, 0x6b, 0x52, 0x6b, 0x52, 0x6c, 0x52, 0x6c, 0x53, 0x6d, - 0x54, 0x6c, 0x54, 0x6d, 0x54, 0x6d, 0x54, 0x6d, 0x55, 0x6c, 0x56, 0x6c, - 0x57, 0x6b, 0x57, 0x6a, 0x57, 0x6a, 0x58, 0x6a, 0x63, 0x5b, 0x5e, 0x5e, - 0x5b, 0x63, 0x59, 0x63, 0x57, 0x64, 0x55, 0x65, 0x55, 0x65, 0x55, 0x65, - 0x55, 0x65, 0x55, 0x65, 0x54, 0x65, 0x54, 0x66, 0x53, 0x66, 0x53, 0x65, - 0x52, 0x65, 0x51, 0x65, 0x51, 0x65, 0x51, 0x64, 0x51, 0x62, 0x51, 0x62, - 0x50, 0x63, 0x4f, 0x64, 0x51, 0x64, 0x54, 0x62, 0x54, 0x61, 0x55, 0x63, - 0x53, 0x66, 0x55, 0x67, 0x58, 0x68, 0x5b, 0x68, 0x5d, 0x6b, 0x5f, 0x70, - 0x62, 0x72, 0x65, 0x74, 0x66, 0x75, 0x68, 0x76, 0x6c, 0x77, 0x70, 0x78, - 0x73, 0x7a, 0x75, 0x7a, 0x76, 0x79, 0x74, 0x78, 0x73, 0x79, 0x70, 0x79, - 0x6e, 0x79, 0x69, 0x77, 0x60, 0x78, 0x5e, 0x79, 0x64, 0x79, 0x68, 0x79, - 0x6f, 0x79, 0x74, 0x7b, 0x7b, 0x7b, 0x7f, 0x7b, 0x79, 0x7b, 0x67, 0x7a, - 0x57, 0x7c, 0x58, 0x7d, 0x5a, 0x7f, 0x59, 0x81, 0x59, 0x81, 0x59, 0x82, - 0x59, 0x83, 0x5d, 0x80, 0x63, 0x7d, 0x66, 0x7f, 0x69, 0x7d, 0x6b, 0x7d, - 0x69, 0x7d, 0x66, 0x7d, 0x65, 0x7e, 0x65, 0x7e, 0x66, 0x7d, 0x68, 0x7f, - 0x6a, 0x80, 0x6e, 0x80, 0x6f, 0x80, 0x6a, 0x80, 0x67, 0x7f, 0x68, 0x7f, - 0x69, 0x7f, 0x6b, 0x7e, 0x6c, 0x7f, 0x6a, 0x80, 0x66, 0x81, 0x65, 0x81, - 0x64, 0x85, 0x62, 0x87, 0x62, 0x87, 0x62, 0x87, 0x61, 0x87, 0x60, 0x87, - 0x60, 0x85, 0x60, 0x85, 0x60, 0x84, 0x60, 0x84, 0x60, 0x85, 0x5c, 0x85, - 0x59, 0x85, 0x5b, 0x7f, 0x5d, 0x7b, 0x5d, 0x7b, 0x5e, 0x79, 0x60, 0x77, - 0x65, 0x7b, 0x70, 0x7c, 0x72, 0x7d, 0x75, 0x7e, 0x76, 0x7c, 0x79, 0x75, - 0x78, 0x75, 0x73, 0x74, 0x6c, 0x72, 0x62, 0x75, 0x54, 0x79, 0x57, 0x75, - 0x5a, 0x75, 0x5b, 0x75, 0x5a, 0x76, 0x59, 0x77, 0x57, 0x78, 0x55, 0x7b, - 0x57, 0x7c, 0x59, 0x7c, 0x59, 0x7d, 0x5b, 0x80, 0x5c, 0x83, 0x5c, 0x88, - 0x5c, 0x84, 0x61, 0x7f, 0x60, 0x79, 0x5f, 0x78, 0x60, 0x75, 0x62, 0x74, - 0x64, 0x72, 0x63, 0x6f, 0x64, 0x6e, 0x63, 0x6e, 0x61, 0x6f, 0x5e, 0x6f, - 0x5c, 0x6f, 0x5a, 0x6d, 0x55, 0x6a, 0x53, 0x6a, 0x51, 0x6b, 0x51, 0x6b, - 0x51, 0x6b, 0x50, 0x6c, 0x50, 0x6d, 0x52, 0x6d, 0x52, 0x6d, 0x53, 0x6d, - 0x53, 0x6d, 0x53, 0x6d, 0x55, 0x6c, 0x55, 0x6c, 0x56, 0x6a, 0x56, 0x6a, - 0x55, 0x6b, 0x56, 0x6b, 0x63, 0x5a, 0x5f, 0x5c, 0x5c, 0x62, 0x59, 0x63, - 0x57, 0x64, 0x55, 0x65, 0x55, 0x65, 0x55, 0x65, 0x55, 0x65, 0x55, 0x65, - 0x54, 0x65, 0x54, 0x65, 0x53, 0x65, 0x53, 0x65, 0x52, 0x65, 0x51, 0x65, - 0x51, 0x65, 0x51, 0x64, 0x51, 0x62, 0x51, 0x62, 0x50, 0x63, 0x50, 0x63, - 0x51, 0x63, 0x54, 0x62, 0x55, 0x62, 0x53, 0x63, 0x53, 0x65, 0x54, 0x67, - 0x56, 0x67, 0x58, 0x68, 0x5b, 0x69, 0x5e, 0x6e, 0x61, 0x72, 0x63, 0x74, - 0x64, 0x75, 0x67, 0x75, 0x6b, 0x77, 0x6e, 0x78, 0x73, 0x7a, 0x75, 0x7a, - 0x76, 0x79, 0x72, 0x78, 0x6d, 0x78, 0x6c, 0x7a, 0x6f, 0x79, 0x70, 0x78, - 0x6b, 0x78, 0x66, 0x78, 0x60, 0x7b, 0x63, 0x7b, 0x6a, 0x7b, 0x70, 0x7b, - 0x74, 0x7b, 0x7a, 0x7a, 0x7c, 0x7c, 0x74, 0x7c, 0x5f, 0x7e, 0x58, 0x80, - 0x59, 0x82, 0x57, 0x83, 0x57, 0x83, 0x57, 0x83, 0x57, 0x84, 0x5b, 0x82, - 0x60, 0x81, 0x63, 0x82, 0x65, 0x7f, 0x67, 0x7e, 0x64, 0x80, 0x62, 0x80, - 0x65, 0x7f, 0x63, 0x7f, 0x62, 0x7e, 0x65, 0x80, 0x65, 0x81, 0x69, 0x81, - 0x6f, 0x81, 0x69, 0x81, 0x64, 0x81, 0x65, 0x80, 0x66, 0x80, 0x67, 0x80, - 0x65, 0x81, 0x63, 0x83, 0x61, 0x86, 0x60, 0x86, 0x61, 0x88, 0x62, 0x89, - 0x62, 0x87, 0x62, 0x87, 0x61, 0x87, 0x61, 0x87, 0x62, 0x85, 0x61, 0x85, - 0x62, 0x84, 0x62, 0x84, 0x62, 0x85, 0x5d, 0x85, 0x5b, 0x84, 0x5d, 0x7f, - 0x5f, 0x7a, 0x5f, 0x79, 0x62, 0x78, 0x66, 0x79, 0x6c, 0x7d, 0x72, 0x7c, - 0x74, 0x7c, 0x78, 0x78, 0x79, 0x74, 0x77, 0x70, 0x70, 0x70, 0x6e, 0x6f, - 0x69, 0x71, 0x60, 0x76, 0x58, 0x7a, 0x59, 0x77, 0x5a, 0x77, 0x5b, 0x76, - 0x5a, 0x77, 0x59, 0x7a, 0x55, 0x7a, 0x55, 0x7c, 0x58, 0x7c, 0x5a, 0x7c, - 0x5c, 0x7e, 0x5f, 0x83, 0x5f, 0x87, 0x60, 0x8d, 0x5e, 0x8d, 0x5a, 0x88, - 0x59, 0x80, 0x5b, 0x7c, 0x5e, 0x78, 0x60, 0x77, 0x61, 0x74, 0x60, 0x71, - 0x62, 0x70, 0x63, 0x70, 0x61, 0x70, 0x5e, 0x72, 0x5c, 0x71, 0x59, 0x6f, - 0x54, 0x6c, 0x52, 0x6b, 0x4f, 0x6b, 0x4f, 0x6b, 0x50, 0x6a, 0x4f, 0x6b, - 0x50, 0x6c, 0x50, 0x6c, 0x50, 0x6d, 0x51, 0x6d, 0x54, 0x6d, 0x54, 0x6c, - 0x55, 0x6c, 0x55, 0x6b, 0x55, 0x6a, 0x55, 0x6b, 0x55, 0x6b, 0x54, 0x6b, - 0x63, 0x5d, 0x5f, 0x5e, 0x5d, 0x61, 0x59, 0x64, 0x57, 0x65, 0x55, 0x65, - 0x55, 0x64, 0x56, 0x63, 0x56, 0x62, 0x55, 0x63, 0x54, 0x65, 0x54, 0x65, - 0x53, 0x65, 0x52, 0x65, 0x52, 0x65, 0x51, 0x66, 0x51, 0x66, 0x51, 0x64, - 0x51, 0x63, 0x50, 0x63, 0x51, 0x63, 0x51, 0x62, 0x52, 0x62, 0x55, 0x61, - 0x55, 0x62, 0x53, 0x64, 0x52, 0x65, 0x53, 0x65, 0x54, 0x65, 0x54, 0x67, - 0x58, 0x68, 0x5e, 0x6d, 0x61, 0x73, 0x63, 0x75, 0x64, 0x75, 0x67, 0x75, - 0x6a, 0x77, 0x6c, 0x78, 0x71, 0x7a, 0x73, 0x7a, 0x73, 0x78, 0x6f, 0x78, - 0x6b, 0x79, 0x6a, 0x79, 0x6e, 0x7a, 0x71, 0x7b, 0x71, 0x7a, 0x6e, 0x79, - 0x65, 0x7b, 0x60, 0x7d, 0x64, 0x7e, 0x6e, 0x7d, 0x73, 0x7b, 0x71, 0x7b, - 0x71, 0x7d, 0x77, 0x7d, 0x71, 0x7d, 0x62, 0x81, 0x63, 0x8a, 0x69, 0x89, - 0x61, 0x86, 0x58, 0x88, 0x57, 0x89, 0x55, 0x88, 0x5c, 0x85, 0x63, 0x85, - 0x68, 0x84, 0x69, 0x7e, 0x67, 0x7f, 0x65, 0x82, 0x68, 0x7f, 0x67, 0x7c, - 0x67, 0x7d, 0x68, 0x7e, 0x68, 0x7f, 0x69, 0x7f, 0x6d, 0x7f, 0x6d, 0x7f, - 0x69, 0x7f, 0x66, 0x7f, 0x64, 0x7e, 0x63, 0x81, 0x61, 0x83, 0x5f, 0x86, - 0x5f, 0x89, 0x5f, 0x89, 0x60, 0x89, 0x63, 0x89, 0x65, 0x86, 0x62, 0x86, - 0x62, 0x87, 0x65, 0x87, 0x66, 0x86, 0x66, 0x86, 0x64, 0x85, 0x64, 0x85, - 0x63, 0x86, 0x60, 0x84, 0x5d, 0x81, 0x5f, 0x7c, 0x61, 0x7a, 0x64, 0x7b, - 0x68, 0x7e, 0x6b, 0x80, 0x71, 0x7d, 0x75, 0x79, 0x78, 0x75, 0x78, 0x70, - 0x75, 0x6e, 0x6f, 0x6f, 0x6a, 0x70, 0x67, 0x71, 0x62, 0x73, 0x5e, 0x77, - 0x5a, 0x7a, 0x56, 0x7a, 0x56, 0x79, 0x59, 0x76, 0x59, 0x76, 0x57, 0x79, - 0x53, 0x7b, 0x54, 0x7d, 0x5a, 0x7d, 0x5b, 0x7c, 0x5e, 0x7f, 0x62, 0x85, - 0x64, 0x8a, 0x68, 0x8e, 0x66, 0x90, 0x58, 0x8d, 0x55, 0x84, 0x5a, 0x7f, - 0x5d, 0x78, 0x5e, 0x77, 0x5d, 0x77, 0x5d, 0x73, 0x62, 0x73, 0x63, 0x75, - 0x61, 0x75, 0x60, 0x76, 0x5e, 0x75, 0x5a, 0x72, 0x56, 0x70, 0x53, 0x70, - 0x51, 0x6e, 0x4c, 0x6d, 0x4c, 0x6c, 0x4c, 0x6b, 0x4d, 0x6b, 0x4e, 0x6b, - 0x50, 0x6b, 0x51, 0x6b, 0x53, 0x6b, 0x55, 0x6c, 0x54, 0x6d, 0x54, 0x6c, - 0x54, 0x6c, 0x54, 0x6c, 0x54, 0x6d, 0x54, 0x6c, 0x62, 0x5e, 0x5e, 0x60, - 0x5d, 0x61, 0x59, 0x64, 0x57, 0x65, 0x55, 0x65, 0x55, 0x64, 0x56, 0x63, - 0x56, 0x61, 0x56, 0x62, 0x54, 0x65, 0x53, 0x65, 0x53, 0x65, 0x52, 0x65, - 0x52, 0x65, 0x51, 0x65, 0x51, 0x65, 0x51, 0x63, 0x51, 0x63, 0x50, 0x63, - 0x51, 0x64, 0x51, 0x62, 0x53, 0x62, 0x55, 0x61, 0x55, 0x61, 0x53, 0x65, - 0x52, 0x66, 0x52, 0x65, 0x53, 0x65, 0x53, 0x67, 0x56, 0x67, 0x5d, 0x6d, - 0x60, 0x72, 0x63, 0x75, 0x64, 0x75, 0x66, 0x75, 0x69, 0x77, 0x6b, 0x77, - 0x6f, 0x78, 0x70, 0x79, 0x70, 0x77, 0x6e, 0x79, 0x6c, 0x7a, 0x6b, 0x7a, - 0x6e, 0x7b, 0x70, 0x7c, 0x6f, 0x7b, 0x70, 0x7a, 0x6b, 0x7a, 0x62, 0x7a, - 0x5f, 0x80, 0x68, 0x7e, 0x73, 0x7c, 0x73, 0x7c, 0x6c, 0x7d, 0x70, 0x7d, - 0x7a, 0x7d, 0x71, 0x7f, 0x68, 0x88, 0x76, 0x8a, 0x74, 0x87, 0x6a, 0x8b, - 0x65, 0x8e, 0x5c, 0x8e, 0x5d, 0x8c, 0x62, 0x8c, 0x6a, 0x88, 0x6a, 0x82, - 0x6b, 0x81, 0x68, 0x83, 0x66, 0x80, 0x69, 0x7b, 0x69, 0x7c, 0x69, 0x7d, - 0x6a, 0x7e, 0x6a, 0x7f, 0x6b, 0x7d, 0x6b, 0x7c, 0x68, 0x7c, 0x64, 0x7c, - 0x64, 0x7c, 0x64, 0x7f, 0x63, 0x82, 0x61, 0x86, 0x61, 0x87, 0x61, 0x87, - 0x62, 0x87, 0x65, 0x87, 0x66, 0x85, 0x63, 0x85, 0x64, 0x86, 0x66, 0x86, - 0x68, 0x86, 0x68, 0x86, 0x66, 0x85, 0x66, 0x85, 0x65, 0x85, 0x62, 0x82, - 0x61, 0x80, 0x63, 0x7e, 0x65, 0x7f, 0x6a, 0x80, 0x70, 0x7e, 0x72, 0x7c, - 0x74, 0x78, 0x76, 0x74, 0x77, 0x71, 0x74, 0x70, 0x70, 0x6f, 0x6b, 0x6f, - 0x67, 0x71, 0x65, 0x72, 0x61, 0x74, 0x60, 0x77, 0x58, 0x7b, 0x51, 0x7d, - 0x54, 0x7a, 0x5c, 0x76, 0x59, 0x76, 0x54, 0x79, 0x54, 0x7b, 0x54, 0x7d, - 0x59, 0x7c, 0x5b, 0x7c, 0x5f, 0x7f, 0x65, 0x83, 0x67, 0x88, 0x6a, 0x8c, - 0x69, 0x8d, 0x58, 0x8d, 0x54, 0x85, 0x58, 0x7f, 0x5d, 0x79, 0x5e, 0x78, - 0x5c, 0x78, 0x5a, 0x77, 0x5e, 0x77, 0x63, 0x79, 0x64, 0x7b, 0x61, 0x7d, - 0x60, 0x7c, 0x5d, 0x79, 0x5a, 0x77, 0x59, 0x76, 0x57, 0x74, 0x50, 0x71, - 0x4d, 0x6f, 0x4c, 0x6c, 0x4b, 0x6c, 0x4c, 0x6b, 0x4f, 0x6b, 0x50, 0x6b, - 0x51, 0x6b, 0x54, 0x6b, 0x53, 0x6d, 0x53, 0x6c, 0x54, 0x6d, 0x54, 0x6d, - 0x54, 0x6d, 0x54, 0x6c, 0x63, 0x60, 0x5f, 0x61, 0x5d, 0x61, 0x59, 0x64, - 0x58, 0x65, 0x56, 0x65, 0x56, 0x64, 0x57, 0x63, 0x56, 0x62, 0x56, 0x63, - 0x54, 0x65, 0x53, 0x65, 0x53, 0x65, 0x53, 0x65, 0x53, 0x65, 0x52, 0x63, - 0x51, 0x63, 0x51, 0x63, 0x51, 0x63, 0x50, 0x63, 0x51, 0x63, 0x51, 0x62, - 0x54, 0x62, 0x54, 0x61, 0x54, 0x61, 0x53, 0x65, 0x53, 0x66, 0x53, 0x65, - 0x53, 0x66, 0x53, 0x67, 0x55, 0x64, 0x5b, 0x6b, 0x60, 0x73, 0x63, 0x75, - 0x62, 0x75, 0x64, 0x75, 0x67, 0x77, 0x69, 0x77, 0x6c, 0x77, 0x6c, 0x77, - 0x6b, 0x77, 0x6d, 0x78, 0x6c, 0x7a, 0x6b, 0x7a, 0x6d, 0x7a, 0x6e, 0x7b, - 0x6c, 0x7b, 0x6d, 0x7c, 0x6c, 0x7b, 0x66, 0x79, 0x61, 0x7c, 0x5d, 0x80, - 0x68, 0x7e, 0x74, 0x7c, 0x73, 0x7c, 0x6c, 0x7d, 0x71, 0x7d, 0x76, 0x7d, - 0x72, 0x80, 0x6a, 0x87, 0x71, 0x8b, 0x7b, 0x89, 0x7c, 0x89, 0x78, 0x8a, - 0x72, 0x8b, 0x70, 0x8a, 0x71, 0x87, 0x71, 0x85, 0x71, 0x85, 0x6e, 0x88, - 0x6d, 0x86, 0x6d, 0x82, 0x70, 0x83, 0x70, 0x82, 0x6f, 0x82, 0x6e, 0x81, - 0x6c, 0x80, 0x6c, 0x80, 0x6d, 0x7f, 0x6b, 0x7d, 0x69, 0x7d, 0x66, 0x7e, - 0x67, 0x80, 0x66, 0x83, 0x63, 0x85, 0x64, 0x85, 0x66, 0x85, 0x69, 0x85, - 0x68, 0x83, 0x65, 0x83, 0x66, 0x84, 0x68, 0x84, 0x6c, 0x84, 0x6c, 0x84, - 0x6a, 0x83, 0x6a, 0x82, 0x69, 0x83, 0x66, 0x81, 0x66, 0x80, 0x68, 0x83, - 0x6e, 0x82, 0x74, 0x7c, 0x79, 0x76, 0x78, 0x73, 0x76, 0x72, 0x78, 0x74, - 0x75, 0x72, 0x6e, 0x6e, 0x6b, 0x6f, 0x69, 0x6f, 0x65, 0x71, 0x63, 0x72, - 0x62, 0x74, 0x60, 0x76, 0x56, 0x7d, 0x55, 0x80, 0x58, 0x7a, 0x5c, 0x74, - 0x59, 0x76, 0x54, 0x79, 0x54, 0x7b, 0x55, 0x7d, 0x57, 0x7c, 0x5c, 0x7c, - 0x69, 0x77, 0x73, 0x77, 0x72, 0x79, 0x6f, 0x7c, 0x6a, 0x80, 0x5a, 0x88, - 0x53, 0x85, 0x56, 0x7f, 0x5c, 0x7a, 0x5e, 0x7b, 0x5c, 0x7b, 0x55, 0x7e, - 0x58, 0x80, 0x62, 0x85, 0x6b, 0x8a, 0x6b, 0x89, 0x6a, 0x88, 0x68, 0x85, - 0x65, 0x82, 0x63, 0x7f, 0x61, 0x7e, 0x5b, 0x7a, 0x56, 0x74, 0x4d, 0x6e, - 0x48, 0x6e, 0x48, 0x6c, 0x4d, 0x6b, 0x4e, 0x6b, 0x4f, 0x6b, 0x51, 0x6b, - 0x50, 0x6c, 0x51, 0x6d, 0x52, 0x6d, 0x52, 0x6d, 0x52, 0x6c, 0x52, 0x6c, - 0x64, 0x61, 0x60, 0x61, 0x5d, 0x62, 0x59, 0x64, 0x58, 0x63, 0x57, 0x63, - 0x57, 0x63, 0x57, 0x62, 0x56, 0x61, 0x56, 0x62, 0x56, 0x62, 0x55, 0x64, - 0x53, 0x65, 0x53, 0x64, 0x53, 0x64, 0x51, 0x62, 0x51, 0x63, 0x51, 0x63, - 0x50, 0x63, 0x50, 0x63, 0x51, 0x63, 0x51, 0x61, 0x54, 0x60, 0x54, 0x60, - 0x53, 0x61, 0x53, 0x65, 0x53, 0x65, 0x53, 0x64, 0x54, 0x64, 0x54, 0x64, - 0x55, 0x63, 0x58, 0x67, 0x60, 0x72, 0x63, 0x77, 0x62, 0x76, 0x63, 0x75, - 0x67, 0x77, 0x69, 0x78, 0x68, 0x77, 0x6a, 0x76, 0x67, 0x76, 0x6a, 0x79, - 0x6a, 0x7a, 0x6c, 0x7a, 0x6d, 0x7a, 0x6e, 0x7a, 0x6b, 0x7b, 0x69, 0x7c, - 0x67, 0x7c, 0x69, 0x7b, 0x66, 0x7a, 0x5b, 0x7f, 0x5d, 0x82, 0x70, 0x7f, - 0x79, 0x7c, 0x71, 0x7d, 0x65, 0x7f, 0x6a, 0x7e, 0x76, 0x7e, 0x6e, 0x84, - 0x65, 0x8c, 0x71, 0x8a, 0x7d, 0x86, 0x7f, 0x86, 0x7f, 0x86, 0x7e, 0x85, - 0x7e, 0x85, 0x80, 0x83, 0x7e, 0x85, 0x7e, 0x86, 0x7f, 0x84, 0x7e, 0x86, - 0x7b, 0x86, 0x7a, 0x87, 0x79, 0x8a, 0x75, 0x8c, 0x73, 0x8b, 0x78, 0x8a, - 0x7c, 0x88, 0x7a, 0x84, 0x76, 0x84, 0x6e, 0x82, 0x6a, 0x80, 0x67, 0x81, - 0x64, 0x83, 0x65, 0x84, 0x6a, 0x83, 0x6d, 0x84, 0x6b, 0x82, 0x69, 0x82, - 0x69, 0x84, 0x6a, 0x84, 0x6e, 0x81, 0x6f, 0x82, 0x6d, 0x80, 0x6d, 0x80, - 0x6b, 0x81, 0x68, 0x82, 0x68, 0x84, 0x6d, 0x85, 0x75, 0x7d, 0x79, 0x74, - 0x78, 0x70, 0x72, 0x71, 0x75, 0x74, 0x78, 0x76, 0x72, 0x70, 0x6c, 0x6d, - 0x69, 0x6f, 0x67, 0x6f, 0x65, 0x71, 0x63, 0x71, 0x65, 0x73, 0x5f, 0x75, - 0x58, 0x7f, 0x5c, 0x83, 0x5d, 0x7a, 0x5b, 0x75, 0x57, 0x77, 0x54, 0x79, - 0x54, 0x7b, 0x56, 0x7e, 0x57, 0x7f, 0x5f, 0x7c, 0x70, 0x70, 0x7a, 0x6a, - 0x79, 0x6a, 0x77, 0x6c, 0x73, 0x72, 0x64, 0x7e, 0x56, 0x84, 0x57, 0x81, - 0x5b, 0x7d, 0x5b, 0x7e, 0x5b, 0x7f, 0x54, 0x81, 0x54, 0x84, 0x62, 0x8d, - 0x6c, 0x92, 0x70, 0x91, 0x72, 0x8e, 0x71, 0x8d, 0x70, 0x89, 0x6b, 0x86, - 0x6a, 0x86, 0x67, 0x82, 0x5f, 0x79, 0x51, 0x70, 0x48, 0x6d, 0x49, 0x6c, - 0x4c, 0x6d, 0x4b, 0x6d, 0x4c, 0x6c, 0x4c, 0x6c, 0x4e, 0x6d, 0x4e, 0x6d, - 0x4f, 0x6e, 0x4e, 0x6e, 0x4f, 0x6b, 0x50, 0x6c, 0x63, 0x60, 0x60, 0x60, - 0x5d, 0x62, 0x59, 0x64, 0x58, 0x63, 0x56, 0x63, 0x56, 0x63, 0x56, 0x61, - 0x56, 0x60, 0x56, 0x61, 0x56, 0x60, 0x56, 0x62, 0x54, 0x64, 0x53, 0x63, - 0x53, 0x63, 0x51, 0x63, 0x51, 0x63, 0x51, 0x63, 0x50, 0x63, 0x50, 0x63, - 0x51, 0x63, 0x52, 0x61, 0x53, 0x60, 0x54, 0x60, 0x53, 0x61, 0x52, 0x64, - 0x52, 0x64, 0x52, 0x64, 0x54, 0x63, 0x53, 0x63, 0x53, 0x63, 0x56, 0x66, - 0x5f, 0x70, 0x63, 0x76, 0x63, 0x75, 0x63, 0x75, 0x67, 0x77, 0x68, 0x78, - 0x66, 0x76, 0x68, 0x75, 0x65, 0x77, 0x67, 0x7b, 0x69, 0x7c, 0x6c, 0x7b, - 0x6d, 0x7b, 0x70, 0x7b, 0x6d, 0x7c, 0x68, 0x7d, 0x65, 0x7c, 0x69, 0x7b, - 0x67, 0x7b, 0x66, 0x7a, 0x5d, 0x7d, 0x66, 0x81, 0x73, 0x80, 0x76, 0x7f, - 0x6b, 0x7f, 0x65, 0x80, 0x6e, 0x81, 0x70, 0x83, 0x60, 0x8d, 0x63, 0x91, - 0x71, 0x8d, 0x7a, 0x86, 0x7a, 0x87, 0x7a, 0x87, 0x7d, 0x84, 0x80, 0x82, - 0x80, 0x82, 0x80, 0x81, 0x80, 0x81, 0x80, 0x83, 0x7f, 0x81, 0x7e, 0x82, - 0x7e, 0x86, 0x7c, 0x88, 0x76, 0x8a, 0x78, 0x8a, 0x7b, 0x89, 0x7c, 0x89, - 0x7d, 0x89, 0x7a, 0x89, 0x75, 0x87, 0x6f, 0x85, 0x69, 0x85, 0x69, 0x84, - 0x6d, 0x82, 0x6e, 0x82, 0x6c, 0x83, 0x69, 0x83, 0x69, 0x84, 0x69, 0x84, - 0x6a, 0x84, 0x6c, 0x83, 0x6c, 0x82, 0x6c, 0x82, 0x6a, 0x83, 0x6d, 0x7f, - 0x70, 0x7d, 0x74, 0x78, 0x78, 0x74, 0x72, 0x75, 0x6a, 0x74, 0x68, 0x72, - 0x72, 0x74, 0x73, 0x72, 0x6f, 0x6e, 0x6b, 0x6d, 0x67, 0x6e, 0x64, 0x6f, - 0x63, 0x72, 0x63, 0x72, 0x63, 0x74, 0x5d, 0x76, 0x5b, 0x85, 0x5f, 0x84, - 0x5e, 0x7b, 0x5a, 0x76, 0x57, 0x77, 0x55, 0x7a, 0x53, 0x7b, 0x55, 0x7e, - 0x59, 0x7f, 0x64, 0x79, 0x76, 0x68, 0x80, 0x5f, 0x7e, 0x5f, 0x7e, 0x60, - 0x79, 0x67, 0x6b, 0x76, 0x5a, 0x82, 0x58, 0x82, 0x59, 0x7f, 0x59, 0x81, - 0x59, 0x82, 0x54, 0x81, 0x56, 0x81, 0x63, 0x89, 0x6c, 0x90, 0x6f, 0x92, - 0x72, 0x90, 0x72, 0x90, 0x72, 0x8e, 0x71, 0x8c, 0x72, 0x8c, 0x6d, 0x86, - 0x66, 0x7b, 0x5d, 0x6d, 0x56, 0x67, 0x54, 0x68, 0x53, 0x6a, 0x52, 0x6a, - 0x52, 0x68, 0x52, 0x69, 0x51, 0x6a, 0x50, 0x6a, 0x50, 0x6b, 0x50, 0x6b, - 0x50, 0x69, 0x53, 0x69, 0x62, 0x60, 0x60, 0x60, 0x5c, 0x63, 0x5a, 0x63, - 0x59, 0x63, 0x57, 0x63, 0x57, 0x63, 0x56, 0x61, 0x56, 0x61, 0x56, 0x61, - 0x56, 0x5f, 0x55, 0x61, 0x54, 0x62, 0x53, 0x63, 0x53, 0x63, 0x51, 0x63, - 0x51, 0x63, 0x51, 0x63, 0x50, 0x63, 0x50, 0x63, 0x51, 0x63, 0x52, 0x61, - 0x53, 0x60, 0x54, 0x60, 0x53, 0x61, 0x53, 0x62, 0x53, 0x62, 0x52, 0x62, - 0x51, 0x63, 0x52, 0x63, 0x51, 0x63, 0x53, 0x66, 0x5b, 0x6f, 0x63, 0x75, - 0x63, 0x75, 0x63, 0x75, 0x65, 0x77, 0x66, 0x77, 0x64, 0x76, 0x66, 0x75, - 0x63, 0x78, 0x65, 0x7d, 0x66, 0x7e, 0x66, 0x7d, 0x68, 0x7d, 0x6c, 0x7d, - 0x6a, 0x7d, 0x67, 0x7c, 0x63, 0x7c, 0x69, 0x7d, 0x6e, 0x7d, 0x6a, 0x7d, - 0x62, 0x7e, 0x62, 0x7f, 0x6a, 0x81, 0x70, 0x81, 0x67, 0x80, 0x69, 0x80, - 0x6a, 0x85, 0x67, 0x8a, 0x5c, 0x95, 0x61, 0x97, 0x65, 0x92, 0x68, 0x8c, - 0x75, 0x87, 0x79, 0x85, 0x79, 0x82, 0x7a, 0x7f, 0x7e, 0x7d, 0x7f, 0x7d, - 0x7e, 0x7d, 0x7d, 0x7c, 0x80, 0x7c, 0x80, 0x7e, 0x7f, 0x7f, 0x7f, 0x80, - 0x7d, 0x84, 0x7c, 0x84, 0x7c, 0x85, 0x7b, 0x86, 0x7c, 0x87, 0x79, 0x88, - 0x78, 0x8a, 0x77, 0x8a, 0x71, 0x89, 0x6e, 0x89, 0x6f, 0x87, 0x6d, 0x87, - 0x69, 0x85, 0x66, 0x85, 0x66, 0x85, 0x67, 0x85, 0x67, 0x85, 0x6a, 0x7f, - 0x6d, 0x7c, 0x6e, 0x7c, 0x6e, 0x79, 0x72, 0x74, 0x74, 0x72, 0x75, 0x75, - 0x76, 0x77, 0x6b, 0x79, 0x60, 0x78, 0x64, 0x76, 0x73, 0x73, 0x6f, 0x71, - 0x6b, 0x6e, 0x67, 0x6c, 0x64, 0x6e, 0x61, 0x71, 0x62, 0x74, 0x65, 0x74, - 0x61, 0x76, 0x5b, 0x7a, 0x5e, 0x87, 0x5e, 0x80, 0x5e, 0x7b, 0x5d, 0x77, - 0x5f, 0x78, 0x58, 0x7a, 0x54, 0x7b, 0x57, 0x7d, 0x5d, 0x7b, 0x6c, 0x72, - 0x7e, 0x60, 0x83, 0x57, 0x82, 0x56, 0x81, 0x56, 0x7c, 0x60, 0x6e, 0x73, - 0x5e, 0x82, 0x5a, 0x81, 0x57, 0x80, 0x58, 0x83, 0x57, 0x84, 0x54, 0x81, - 0x5a, 0x7e, 0x69, 0x7d, 0x72, 0x7e, 0x75, 0x83, 0x72, 0x8a, 0x71, 0x8d, - 0x71, 0x8f, 0x73, 0x8f, 0x73, 0x8f, 0x72, 0x83, 0x71, 0x74, 0x70, 0x64, - 0x6d, 0x5f, 0x6c, 0x60, 0x69, 0x62, 0x68, 0x63, 0x68, 0x62, 0x68, 0x63, - 0x66, 0x64, 0x64, 0x64, 0x63, 0x65, 0x63, 0x65, 0x63, 0x65, 0x65, 0x65, - 0x61, 0x61, 0x60, 0x60, 0x5d, 0x62, 0x5a, 0x63, 0x57, 0x63, 0x56, 0x63, - 0x56, 0x63, 0x56, 0x62, 0x56, 0x60, 0x56, 0x60, 0x57, 0x5e, 0x56, 0x5f, - 0x54, 0x62, 0x53, 0x62, 0x53, 0x63, 0x51, 0x64, 0x51, 0x63, 0x51, 0x63, - 0x51, 0x63, 0x50, 0x63, 0x51, 0x63, 0x51, 0x61, 0x53, 0x60, 0x53, 0x61, - 0x52, 0x62, 0x52, 0x62, 0x52, 0x61, 0x52, 0x62, 0x50, 0x63, 0x50, 0x64, - 0x50, 0x65, 0x52, 0x66, 0x5a, 0x6d, 0x62, 0x74, 0x63, 0x76, 0x63, 0x76, - 0x64, 0x77, 0x65, 0x77, 0x64, 0x76, 0x65, 0x76, 0x62, 0x79, 0x65, 0x7d, - 0x62, 0x7d, 0x60, 0x7e, 0x62, 0x7f, 0x66, 0x80, 0x66, 0x7f, 0x66, 0x7d, - 0x61, 0x7c, 0x69, 0x7e, 0x74, 0x81, 0x69, 0x89, 0x5f, 0x86, 0x64, 0x7e, - 0x6c, 0x7f, 0x69, 0x7f, 0x63, 0x7f, 0x6e, 0x7e, 0x6d, 0x89, 0x6e, 0x8c, - 0x61, 0x8e, 0x61, 0x90, 0x61, 0x8f, 0x5b, 0x90, 0x68, 0x8d, 0x70, 0x88, - 0x7b, 0x82, 0x80, 0x7e, 0x80, 0x7e, 0x80, 0x7e, 0x7f, 0x7b, 0x7d, 0x76, - 0x7e, 0x73, 0x80, 0x73, 0x7e, 0x76, 0x7e, 0x78, 0x80, 0x7d, 0x80, 0x7f, - 0x7f, 0x80, 0x7d, 0x82, 0x7b, 0x83, 0x7a, 0x83, 0x7b, 0x85, 0x7b, 0x88, - 0x76, 0x89, 0x72, 0x89, 0x70, 0x8a, 0x6d, 0x89, 0x6a, 0x86, 0x67, 0x85, - 0x68, 0x83, 0x69, 0x82, 0x6c, 0x7f, 0x6d, 0x7a, 0x70, 0x74, 0x71, 0x73, - 0x71, 0x70, 0x6f, 0x72, 0x6c, 0x76, 0x6c, 0x7e, 0x71, 0x80, 0x6c, 0x7c, - 0x62, 0x7a, 0x68, 0x78, 0x71, 0x73, 0x6c, 0x71, 0x69, 0x6e, 0x65, 0x6d, - 0x62, 0x6f, 0x60, 0x73, 0x63, 0x75, 0x67, 0x74, 0x60, 0x76, 0x5c, 0x7b, - 0x5e, 0x82, 0x5d, 0x7c, 0x5f, 0x7b, 0x62, 0x79, 0x63, 0x78, 0x58, 0x7a, - 0x55, 0x7c, 0x59, 0x7c, 0x62, 0x78, 0x71, 0x6f, 0x80, 0x5e, 0x83, 0x56, - 0x82, 0x54, 0x80, 0x56, 0x7b, 0x60, 0x6e, 0x76, 0x62, 0x84, 0x5c, 0x82, - 0x58, 0x81, 0x57, 0x84, 0x56, 0x85, 0x55, 0x81, 0x5c, 0x7c, 0x6f, 0x72, - 0x7a, 0x6d, 0x7c, 0x72, 0x76, 0x7e, 0x75, 0x83, 0x74, 0x89, 0x72, 0x8a, - 0x72, 0x8a, 0x76, 0x7d, 0x78, 0x6d, 0x79, 0x5f, 0x78, 0x5b, 0x79, 0x5c, - 0x78, 0x5e, 0x77, 0x5f, 0x76, 0x5f, 0x76, 0x60, 0x76, 0x62, 0x75, 0x62, - 0x73, 0x62, 0x73, 0x62, 0x72, 0x63, 0x74, 0x63, 0x60, 0x64, 0x60, 0x62, - 0x5d, 0x61, 0x59, 0x63, 0x57, 0x63, 0x56, 0x63, 0x57, 0x62, 0x57, 0x62, - 0x56, 0x60, 0x57, 0x5f, 0x57, 0x5e, 0x57, 0x5f, 0x55, 0x61, 0x54, 0x61, - 0x53, 0x61, 0x51, 0x63, 0x51, 0x61, 0x51, 0x63, 0x51, 0x63, 0x51, 0x61, - 0x51, 0x63, 0x51, 0x61, 0x52, 0x60, 0x51, 0x62, 0x51, 0x63, 0x50, 0x62, - 0x4f, 0x61, 0x4f, 0x63, 0x4d, 0x65, 0x4e, 0x65, 0x53, 0x67, 0x56, 0x67, - 0x5b, 0x6a, 0x61, 0x74, 0x64, 0x78, 0x62, 0x77, 0x62, 0x76, 0x63, 0x77, - 0x64, 0x76, 0x63, 0x77, 0x63, 0x7a, 0x62, 0x7a, 0x60, 0x7d, 0x64, 0x84, - 0x64, 0x83, 0x66, 0x83, 0x66, 0x82, 0x67, 0x80, 0x64, 0x7e, 0x6a, 0x80, - 0x6d, 0x82, 0x60, 0x83, 0x64, 0x7e, 0x6d, 0x7c, 0x6d, 0x7c, 0x67, 0x7c, - 0x6a, 0x83, 0x6a, 0x85, 0x6c, 0x93, 0x7c, 0x90, 0x71, 0x8d, 0x64, 0x8b, - 0x5c, 0x8a, 0x57, 0x8c, 0x5a, 0x8f, 0x5d, 0x8f, 0x6a, 0x8a, 0x71, 0x84, - 0x74, 0x83, 0x77, 0x83, 0x7b, 0x7d, 0x82, 0x6e, 0x80, 0x69, 0x80, 0x6a, - 0x84, 0x67, 0x84, 0x64, 0x84, 0x64, 0x83, 0x68, 0x83, 0x6a, 0x84, 0x6e, - 0x82, 0x70, 0x81, 0x73, 0x81, 0x74, 0x80, 0x75, 0x7d, 0x7b, 0x7b, 0x7e, - 0x77, 0x7e, 0x75, 0x7d, 0x73, 0x7a, 0x71, 0x77, 0x71, 0x77, 0x72, 0x74, - 0x72, 0x73, 0x72, 0x70, 0x74, 0x6e, 0x74, 0x71, 0x70, 0x75, 0x65, 0x79, - 0x60, 0x7f, 0x61, 0x80, 0x66, 0x81, 0x6a, 0x7f, 0x65, 0x7c, 0x6e, 0x78, - 0x6e, 0x72, 0x6a, 0x71, 0x67, 0x6e, 0x62, 0x6f, 0x5f, 0x72, 0x60, 0x74, - 0x66, 0x74, 0x68, 0x72, 0x5e, 0x76, 0x5b, 0x7b, 0x5d, 0x7d, 0x5e, 0x7c, - 0x61, 0x7b, 0x64, 0x79, 0x62, 0x78, 0x59, 0x7a, 0x58, 0x7b, 0x60, 0x78, - 0x6c, 0x70, 0x79, 0x67, 0x82, 0x59, 0x84, 0x54, 0x83, 0x54, 0x80, 0x57, - 0x7c, 0x63, 0x70, 0x7c, 0x67, 0x89, 0x61, 0x87, 0x5d, 0x83, 0x5a, 0x83, - 0x58, 0x80, 0x56, 0x7d, 0x5d, 0x78, 0x74, 0x67, 0x81, 0x60, 0x84, 0x60, - 0x81, 0x66, 0x7f, 0x6b, 0x7b, 0x73, 0x79, 0x76, 0x79, 0x75, 0x7d, 0x6c, - 0x7f, 0x63, 0x82, 0x59, 0x83, 0x58, 0x82, 0x5a, 0x83, 0x5b, 0x82, 0x5c, - 0x81, 0x5c, 0x80, 0x5d, 0x80, 0x60, 0x80, 0x60, 0x7f, 0x5e, 0x7f, 0x5f, - 0x7e, 0x60, 0x7e, 0x5f, 0x60, 0x66, 0x60, 0x63, 0x5d, 0x63, 0x59, 0x65, - 0x57, 0x64, 0x56, 0x63, 0x57, 0x62, 0x56, 0x62, 0x57, 0x60, 0x57, 0x5f, - 0x57, 0x5e, 0x57, 0x5f, 0x55, 0x60, 0x54, 0x60, 0x54, 0x60, 0x52, 0x62, - 0x51, 0x60, 0x51, 0x61, 0x51, 0x61, 0x51, 0x5f, 0x51, 0x62, 0x51, 0x61, - 0x51, 0x60, 0x50, 0x62, 0x4f, 0x63, 0x4f, 0x63, 0x4d, 0x63, 0x4d, 0x64, - 0x4f, 0x67, 0x52, 0x66, 0x58, 0x68, 0x5a, 0x67, 0x5d, 0x69, 0x63, 0x73, - 0x64, 0x78, 0x62, 0x77, 0x60, 0x75, 0x62, 0x77, 0x63, 0x76, 0x63, 0x77, - 0x64, 0x78, 0x61, 0x7b, 0x63, 0x81, 0x6d, 0x88, 0x6c, 0x85, 0x6a, 0x85, - 0x67, 0x84, 0x66, 0x82, 0x66, 0x7f, 0x64, 0x80, 0x64, 0x7d, 0x67, 0x78, - 0x6e, 0x7b, 0x70, 0x81, 0x69, 0x84, 0x68, 0x8b, 0x6b, 0x96, 0x68, 0x99, - 0x68, 0x9d, 0x7a, 0x98, 0x7a, 0x94, 0x6e, 0x8e, 0x62, 0x8c, 0x5a, 0x88, - 0x60, 0x87, 0x62, 0x87, 0x61, 0x86, 0x60, 0x86, 0x60, 0x86, 0x63, 0x86, - 0x68, 0x84, 0x7e, 0x6c, 0x85, 0x60, 0x84, 0x63, 0x8d, 0x5f, 0x8e, 0x5b, - 0x8c, 0x56, 0x89, 0x57, 0x88, 0x5a, 0x89, 0x5a, 0x8a, 0x5a, 0x88, 0x5b, - 0x88, 0x5a, 0x88, 0x58, 0x85, 0x5e, 0x83, 0x64, 0x80, 0x68, 0x7d, 0x68, - 0x77, 0x6b, 0x74, 0x69, 0x75, 0x6a, 0x76, 0x67, 0x79, 0x64, 0x79, 0x68, - 0x79, 0x77, 0x79, 0x7d, 0x72, 0x7e, 0x62, 0x7a, 0x60, 0x7d, 0x5e, 0x7e, - 0x5f, 0x7e, 0x63, 0x7e, 0x6b, 0x7e, 0x73, 0x79, 0x6d, 0x70, 0x69, 0x6f, - 0x65, 0x70, 0x5f, 0x71, 0x5e, 0x73, 0x61, 0x74, 0x68, 0x70, 0x66, 0x71, - 0x5d, 0x76, 0x5b, 0x7a, 0x5d, 0x7c, 0x60, 0x7b, 0x62, 0x7b, 0x64, 0x79, - 0x62, 0x78, 0x5c, 0x78, 0x60, 0x77, 0x68, 0x74, 0x75, 0x6b, 0x7f, 0x5f, - 0x85, 0x54, 0x84, 0x53, 0x83, 0x54, 0x80, 0x58, 0x7d, 0x66, 0x70, 0x7f, - 0x69, 0x8e, 0x67, 0x8c, 0x62, 0x87, 0x5f, 0x82, 0x5c, 0x7e, 0x59, 0x7b, - 0x60, 0x78, 0x76, 0x66, 0x83, 0x5c, 0x87, 0x56, 0x88, 0x57, 0x86, 0x59, - 0x83, 0x5d, 0x82, 0x60, 0x82, 0x60, 0x84, 0x5c, 0x86, 0x58, 0x88, 0x54, - 0x89, 0x54, 0x89, 0x56, 0x89, 0x57, 0x89, 0x58, 0x89, 0x59, 0x88, 0x59, - 0x87, 0x5a, 0x87, 0x5b, 0x87, 0x5b, 0x87, 0x5b, 0x86, 0x5b, 0x86, 0x5a, - 0x60, 0x67, 0x5f, 0x65, 0x5c, 0x64, 0x59, 0x66, 0x57, 0x65, 0x56, 0x63, - 0x56, 0x62, 0x56, 0x62, 0x57, 0x61, 0x57, 0x5f, 0x57, 0x5e, 0x57, 0x5e, - 0x56, 0x5f, 0x55, 0x5e, 0x54, 0x5f, 0x52, 0x60, 0x52, 0x5f, 0x51, 0x5f, - 0x51, 0x5f, 0x51, 0x5f, 0x51, 0x61, 0x52, 0x60, 0x51, 0x60, 0x4f, 0x62, - 0x4d, 0x63, 0x4c, 0x65, 0x4d, 0x65, 0x4f, 0x65, 0x56, 0x67, 0x5a, 0x67, - 0x5c, 0x67, 0x5e, 0x67, 0x5f, 0x68, 0x64, 0x71, 0x64, 0x77, 0x62, 0x77, - 0x5e, 0x76, 0x5f, 0x78, 0x62, 0x77, 0x63, 0x78, 0x61, 0x78, 0x62, 0x7c, - 0x68, 0x83, 0x73, 0x87, 0x71, 0x83, 0x6d, 0x85, 0x6b, 0x84, 0x6a, 0x82, - 0x6c, 0x81, 0x6f, 0x82, 0x71, 0x82, 0x74, 0x87, 0x72, 0x8e, 0x6e, 0x93, - 0x6b, 0x97, 0x6d, 0x9b, 0x6c, 0xa0, 0x6b, 0xa3, 0x67, 0xa4, 0x70, 0x9e, - 0x76, 0x98, 0x73, 0x91, 0x6d, 0x8e, 0x67, 0x87, 0x69, 0x85, 0x6a, 0x86, - 0x67, 0x8a, 0x67, 0x8d, 0x67, 0x8a, 0x69, 0x8a, 0x6a, 0x8b, 0x7c, 0x6e, - 0x86, 0x5d, 0x87, 0x5f, 0x8d, 0x5b, 0x8f, 0x56, 0x8e, 0x51, 0x8b, 0x52, - 0x89, 0x56, 0x8a, 0x56, 0x8c, 0x54, 0x8f, 0x51, 0x8f, 0x51, 0x8e, 0x50, - 0x8b, 0x52, 0x88, 0x55, 0x84, 0x5b, 0x81, 0x5e, 0x7f, 0x61, 0x80, 0x5e, - 0x84, 0x58, 0x86, 0x55, 0x87, 0x54, 0x81, 0x67, 0x7c, 0x81, 0x7b, 0x82, - 0x77, 0x80, 0x65, 0x78, 0x62, 0x7a, 0x60, 0x7d, 0x5d, 0x7d, 0x5d, 0x7e, - 0x6d, 0x7e, 0x74, 0x79, 0x6b, 0x70, 0x68, 0x6f, 0x63, 0x72, 0x5e, 0x72, - 0x5d, 0x74, 0x62, 0x73, 0x68, 0x6e, 0x64, 0x71, 0x5b, 0x77, 0x59, 0x79, - 0x5d, 0x7a, 0x61, 0x7a, 0x63, 0x7b, 0x64, 0x79, 0x61, 0x77, 0x60, 0x76, - 0x64, 0x77, 0x6c, 0x73, 0x7d, 0x65, 0x86, 0x57, 0x87, 0x51, 0x85, 0x51, - 0x83, 0x55, 0x80, 0x58, 0x7c, 0x63, 0x71, 0x7d, 0x6b, 0x91, 0x6b, 0x90, - 0x67, 0x8c, 0x64, 0x87, 0x60, 0x82, 0x5d, 0x80, 0x61, 0x7c, 0x71, 0x6c, - 0x7e, 0x5f, 0x85, 0x59, 0x89, 0x56, 0x8a, 0x56, 0x88, 0x57, 0x88, 0x59, - 0x88, 0x59, 0x89, 0x55, 0x8b, 0x55, 0x8b, 0x53, 0x8b, 0x52, 0x8a, 0x53, - 0x8a, 0x54, 0x8a, 0x55, 0x8b, 0x56, 0x8b, 0x57, 0x8b, 0x58, 0x8b, 0x58, - 0x8a, 0x5a, 0x89, 0x59, 0x89, 0x57, 0x88, 0x57, 0x61, 0x68, 0x5d, 0x65, - 0x5b, 0x65, 0x58, 0x65, 0x56, 0x66, 0x55, 0x64, 0x56, 0x63, 0x56, 0x62, - 0x57, 0x60, 0x58, 0x5f, 0x58, 0x5d, 0x58, 0x5d, 0x57, 0x5d, 0x56, 0x5e, - 0x55, 0x5d, 0x52, 0x60, 0x53, 0x60, 0x53, 0x5f, 0x53, 0x5d, 0x53, 0x5f, - 0x51, 0x62, 0x51, 0x61, 0x50, 0x61, 0x4e, 0x61, 0x4b, 0x62, 0x4c, 0x65, - 0x51, 0x66, 0x57, 0x66, 0x5d, 0x67, 0x5e, 0x68, 0x5e, 0x67, 0x61, 0x67, - 0x61, 0x68, 0x63, 0x6f, 0x64, 0x75, 0x62, 0x77, 0x5c, 0x77, 0x5d, 0x78, - 0x62, 0x77, 0x62, 0x79, 0x60, 0x7a, 0x63, 0x7d, 0x6d, 0x83, 0x74, 0x86, - 0x70, 0x87, 0x6e, 0x8a, 0x77, 0x8b, 0x7c, 0x88, 0x79, 0x89, 0x7b, 0x8d, - 0x78, 0x93, 0x72, 0x97, 0x6f, 0x99, 0x6f, 0x9c, 0x6f, 0x9d, 0x71, 0x9e, - 0x70, 0xa2, 0x6e, 0xa4, 0x6b, 0xa4, 0x71, 0x9f, 0x76, 0x9a, 0x73, 0x95, - 0x6f, 0x93, 0x6e, 0x8d, 0x6e, 0x8d, 0x6e, 0x8f, 0x71, 0x90, 0x71, 0x91, - 0x70, 0x8e, 0x71, 0x8c, 0x72, 0x8b, 0x7b, 0x6f, 0x85, 0x5c, 0x87, 0x5d, - 0x8b, 0x5b, 0x8d, 0x56, 0x90, 0x50, 0x8f, 0x4f, 0x8b, 0x53, 0x8a, 0x58, - 0x8c, 0x56, 0x90, 0x50, 0x93, 0x4d, 0x93, 0x4b, 0x91, 0x49, 0x8e, 0x4b, - 0x87, 0x59, 0x81, 0x63, 0x80, 0x68, 0x85, 0x5f, 0x8c, 0x50, 0x8c, 0x4f, - 0x8d, 0x50, 0x88, 0x5d, 0x7b, 0x80, 0x7b, 0x80, 0x79, 0x80, 0x6d, 0x7b, - 0x63, 0x79, 0x63, 0x7d, 0x61, 0x7d, 0x5d, 0x7d, 0x6c, 0x7f, 0x70, 0x7a, - 0x68, 0x72, 0x67, 0x70, 0x62, 0x73, 0x5d, 0x73, 0x5e, 0x73, 0x66, 0x71, - 0x67, 0x6e, 0x61, 0x72, 0x5b, 0x78, 0x59, 0x79, 0x5f, 0x78, 0x63, 0x79, - 0x63, 0x79, 0x62, 0x79, 0x62, 0x77, 0x63, 0x75, 0x65, 0x7b, 0x6f, 0x75, - 0x84, 0x5b, 0x8a, 0x4f, 0x87, 0x50, 0x87, 0x50, 0x83, 0x55, 0x80, 0x59, - 0x7d, 0x5d, 0x76, 0x77, 0x6e, 0x90, 0x6e, 0x92, 0x6e, 0x8f, 0x6c, 0x8b, - 0x69, 0x88, 0x63, 0x87, 0x60, 0x84, 0x66, 0x79, 0x71, 0x6e, 0x7c, 0x62, - 0x88, 0x57, 0x8b, 0x53, 0x8b, 0x53, 0x8c, 0x54, 0x8c, 0x52, 0x8d, 0x50, - 0x8d, 0x52, 0x8c, 0x53, 0x8d, 0x52, 0x8c, 0x52, 0x8c, 0x53, 0x8c, 0x54, - 0x8c, 0x54, 0x8c, 0x55, 0x8d, 0x56, 0x8c, 0x56, 0x8c, 0x57, 0x8c, 0x57, - 0x8c, 0x56, 0x8d, 0x56, 0x64, 0x68, 0x5d, 0x65, 0x5b, 0x65, 0x58, 0x65, - 0x56, 0x65, 0x55, 0x64, 0x56, 0x63, 0x57, 0x62, 0x57, 0x60, 0x58, 0x5e, - 0x58, 0x5c, 0x58, 0x5d, 0x57, 0x5d, 0x56, 0x5d, 0x55, 0x5c, 0x52, 0x60, - 0x53, 0x61, 0x53, 0x5f, 0x53, 0x5c, 0x53, 0x5e, 0x51, 0x61, 0x50, 0x61, - 0x4e, 0x60, 0x4c, 0x61, 0x4b, 0x62, 0x4f, 0x65, 0x55, 0x65, 0x5a, 0x66, - 0x5d, 0x68, 0x5f, 0x6a, 0x60, 0x69, 0x62, 0x69, 0x62, 0x69, 0x64, 0x6d, - 0x64, 0x72, 0x62, 0x76, 0x5e, 0x77, 0x5e, 0x77, 0x63, 0x77, 0x61, 0x79, - 0x5f, 0x7a, 0x62, 0x7d, 0x6c, 0x83, 0x75, 0x80, 0x70, 0x88, 0x6e, 0x91, - 0x76, 0x93, 0x7b, 0x91, 0x79, 0x91, 0x79, 0x93, 0x76, 0x97, 0x72, 0x97, - 0x71, 0x99, 0x70, 0x9c, 0x70, 0x9c, 0x71, 0x9d, 0x70, 0xa0, 0x6e, 0xa2, - 0x6b, 0xa3, 0x72, 0x9c, 0x77, 0x98, 0x75, 0x96, 0x71, 0x96, 0x70, 0x93, - 0x72, 0x92, 0x73, 0x92, 0x77, 0x8e, 0x76, 0x8f, 0x73, 0x8e, 0x73, 0x8c, - 0x75, 0x89, 0x7b, 0x6f, 0x83, 0x5d, 0x85, 0x5b, 0x87, 0x5e, 0x88, 0x5a, - 0x8d, 0x53, 0x8f, 0x4f, 0x8d, 0x50, 0x8b, 0x55, 0x8b, 0x57, 0x8e, 0x53, - 0x93, 0x4c, 0x95, 0x49, 0x95, 0x44, 0x95, 0x44, 0x8c, 0x51, 0x82, 0x60, - 0x80, 0x67, 0x87, 0x5a, 0x8e, 0x4a, 0x8b, 0x50, 0x8c, 0x51, 0x8a, 0x56, - 0x7b, 0x7c, 0x7a, 0x81, 0x7a, 0x80, 0x72, 0x7b, 0x67, 0x79, 0x64, 0x7b, - 0x62, 0x7c, 0x5f, 0x7d, 0x6c, 0x7e, 0x6c, 0x7a, 0x65, 0x72, 0x65, 0x72, - 0x62, 0x74, 0x5e, 0x74, 0x60, 0x74, 0x67, 0x71, 0x65, 0x6e, 0x61, 0x71, - 0x5b, 0x78, 0x5a, 0x78, 0x60, 0x77, 0x64, 0x77, 0x63, 0x78, 0x63, 0x78, - 0x63, 0x78, 0x63, 0x7a, 0x65, 0x80, 0x72, 0x74, 0x86, 0x54, 0x89, 0x4c, - 0x87, 0x4f, 0x87, 0x4f, 0x84, 0x52, 0x82, 0x59, 0x81, 0x57, 0x7a, 0x6d, - 0x70, 0x8c, 0x6f, 0x92, 0x71, 0x90, 0x71, 0x8d, 0x71, 0x8d, 0x69, 0x8d, - 0x63, 0x8b, 0x63, 0x84, 0x68, 0x7e, 0x74, 0x6c, 0x86, 0x58, 0x8b, 0x52, - 0x8b, 0x52, 0x8c, 0x53, 0x8c, 0x51, 0x8d, 0x4f, 0x8d, 0x51, 0x8c, 0x52, - 0x8d, 0x52, 0x8d, 0x53, 0x8c, 0x53, 0x8c, 0x53, 0x8c, 0x52, 0x8c, 0x53, - 0x8d, 0x55, 0x8c, 0x55, 0x8d, 0x56, 0x8d, 0x55, 0x8c, 0x54, 0x8c, 0x54, - 0x67, 0x68, 0x5e, 0x66, 0x59, 0x65, 0x58, 0x64, 0x56, 0x65, 0x55, 0x64, - 0x55, 0x63, 0x56, 0x62, 0x57, 0x5e, 0x58, 0x5c, 0x58, 0x5c, 0x58, 0x5d, - 0x57, 0x5d, 0x56, 0x5a, 0x55, 0x5a, 0x53, 0x5f, 0x53, 0x60, 0x53, 0x5f, - 0x53, 0x5c, 0x52, 0x5c, 0x50, 0x60, 0x4f, 0x61, 0x4d, 0x61, 0x4a, 0x62, - 0x4b, 0x63, 0x54, 0x64, 0x5b, 0x65, 0x5e, 0x67, 0x60, 0x6a, 0x61, 0x6b, - 0x62, 0x6a, 0x63, 0x6a, 0x64, 0x6b, 0x66, 0x6b, 0x64, 0x6e, 0x63, 0x76, - 0x5f, 0x78, 0x60, 0x77, 0x65, 0x77, 0x60, 0x7a, 0x5c, 0x7b, 0x63, 0x7c, - 0x6f, 0x7f, 0x7d, 0x77, 0x7c, 0x7e, 0x74, 0x90, 0x75, 0x91, 0x76, 0x91, - 0x77, 0x92, 0x77, 0x93, 0x75, 0x95, 0x74, 0x96, 0x73, 0x97, 0x72, 0x98, - 0x72, 0x98, 0x72, 0x9b, 0x70, 0x9e, 0x6f, 0xa0, 0x6b, 0xa0, 0x71, 0x9a, - 0x79, 0x96, 0x7a, 0x95, 0x7a, 0x92, 0x77, 0x94, 0x76, 0x93, 0x76, 0x90, - 0x78, 0x8d, 0x78, 0x8d, 0x78, 0x8e, 0x77, 0x8c, 0x79, 0x87, 0x7b, 0x6f, - 0x81, 0x5f, 0x84, 0x59, 0x83, 0x60, 0x83, 0x60, 0x89, 0x57, 0x8e, 0x4f, - 0x91, 0x4b, 0x8f, 0x4d, 0x8c, 0x51, 0x8b, 0x55, 0x91, 0x4e, 0x97, 0x46, - 0x9a, 0x40, 0x9c, 0x3d, 0x93, 0x45, 0x86, 0x58, 0x80, 0x64, 0x8c, 0x52, - 0x93, 0x42, 0x8c, 0x4e, 0x8c, 0x51, 0x8d, 0x4f, 0x7c, 0x75, 0x7a, 0x81, - 0x7a, 0x7f, 0x77, 0x7c, 0x6e, 0x78, 0x63, 0x79, 0x61, 0x7b, 0x60, 0x7d, - 0x6b, 0x7e, 0x67, 0x7a, 0x62, 0x73, 0x62, 0x73, 0x61, 0x76, 0x5f, 0x76, - 0x62, 0x75, 0x68, 0x71, 0x64, 0x6f, 0x61, 0x72, 0x5a, 0x78, 0x5d, 0x77, - 0x62, 0x75, 0x63, 0x76, 0x63, 0x77, 0x65, 0x77, 0x65, 0x79, 0x64, 0x81, - 0x66, 0x84, 0x77, 0x73, 0x88, 0x51, 0x89, 0x4d, 0x87, 0x4e, 0x88, 0x4d, - 0x86, 0x4f, 0x83, 0x58, 0x85, 0x55, 0x80, 0x5e, 0x73, 0x80, 0x71, 0x8c, - 0x70, 0x8e, 0x72, 0x8f, 0x73, 0x91, 0x71, 0x8f, 0x6e, 0x8e, 0x6a, 0x8d, - 0x69, 0x8d, 0x72, 0x78, 0x87, 0x57, 0x8b, 0x50, 0x8a, 0x50, 0x8c, 0x52, - 0x8c, 0x4f, 0x8d, 0x4e, 0x8d, 0x4f, 0x8d, 0x52, 0x8d, 0x53, 0x8d, 0x52, - 0x8d, 0x53, 0x8d, 0x53, 0x8d, 0x52, 0x8c, 0x52, 0x8d, 0x53, 0x8c, 0x52, - 0x8d, 0x54, 0x8d, 0x54, 0x8c, 0x53, 0x8c, 0x53, 0x68, 0x68, 0x61, 0x68, - 0x58, 0x66, 0x56, 0x64, 0x55, 0x65, 0x54, 0x65, 0x53, 0x64, 0x55, 0x62, - 0x56, 0x5e, 0x57, 0x5d, 0x57, 0x5d, 0x56, 0x5e, 0x56, 0x5d, 0x56, 0x5a, - 0x55, 0x5a, 0x54, 0x5e, 0x54, 0x5d, 0x52, 0x5f, 0x53, 0x5c, 0x52, 0x5b, - 0x50, 0x61, 0x4d, 0x62, 0x4b, 0x63, 0x49, 0x65, 0x4f, 0x65, 0x5b, 0x64, - 0x5e, 0x65, 0x61, 0x68, 0x63, 0x6a, 0x63, 0x6a, 0x64, 0x6b, 0x64, 0x6a, - 0x66, 0x6b, 0x65, 0x6a, 0x65, 0x6d, 0x65, 0x73, 0x61, 0x78, 0x60, 0x79, - 0x63, 0x79, 0x5e, 0x7b, 0x5f, 0x7a, 0x71, 0x77, 0x7f, 0x75, 0x84, 0x73, - 0x80, 0x7a, 0x76, 0x91, 0x75, 0x90, 0x76, 0x8f, 0x78, 0x91, 0x79, 0x91, - 0x77, 0x93, 0x76, 0x95, 0x76, 0x96, 0x74, 0x97, 0x74, 0x98, 0x73, 0x98, - 0x71, 0x9b, 0x6e, 0x9f, 0x6a, 0x96, 0x6d, 0x9b, 0x79, 0x97, 0x7b, 0x93, - 0x7a, 0x91, 0x77, 0x93, 0x76, 0x94, 0x76, 0x92, 0x78, 0x8f, 0x78, 0x8d, - 0x7a, 0x8c, 0x79, 0x8b, 0x79, 0x84, 0x7b, 0x6c, 0x7f, 0x61, 0x84, 0x58, - 0x83, 0x5b, 0x82, 0x5f, 0x88, 0x57, 0x8e, 0x4c, 0x95, 0x47, 0x95, 0x46, - 0x91, 0x49, 0x8c, 0x52, 0x8e, 0x52, 0x97, 0x47, 0x9d, 0x3e, 0x9c, 0x3b, - 0x9a, 0x3f, 0x8d, 0x4b, 0x82, 0x5f, 0x8f, 0x4d, 0x98, 0x3d, 0x8e, 0x4b, - 0x8b, 0x52, 0x8e, 0x4b, 0x7f, 0x6d, 0x7a, 0x7e, 0x7b, 0x7f, 0x7b, 0x7d, - 0x74, 0x7c, 0x64, 0x7a, 0x61, 0x7a, 0x5f, 0x7e, 0x69, 0x7f, 0x63, 0x7b, - 0x60, 0x74, 0x60, 0x74, 0x5f, 0x75, 0x60, 0x75, 0x65, 0x73, 0x68, 0x70, - 0x64, 0x71, 0x60, 0x73, 0x5b, 0x77, 0x62, 0x76, 0x63, 0x74, 0x63, 0x74, - 0x64, 0x75, 0x67, 0x78, 0x68, 0x7d, 0x67, 0x86, 0x6c, 0x82, 0x7c, 0x6d, - 0x87, 0x50, 0x87, 0x4e, 0x87, 0x4f, 0x89, 0x4d, 0x86, 0x4f, 0x83, 0x57, - 0x85, 0x55, 0x85, 0x56, 0x7a, 0x72, 0x75, 0x83, 0x71, 0x8b, 0x72, 0x8e, - 0x72, 0x91, 0x72, 0x91, 0x72, 0x90, 0x6f, 0x92, 0x6f, 0x8e, 0x77, 0x77, - 0x86, 0x53, 0x8a, 0x4d, 0x8b, 0x4e, 0x8c, 0x50, 0x8c, 0x50, 0x8e, 0x4e, - 0x8e, 0x50, 0x8d, 0x52, 0x8e, 0x54, 0x8e, 0x53, 0x8e, 0x53, 0x8d, 0x52, - 0x8d, 0x51, 0x8d, 0x51, 0x8d, 0x50, 0x8d, 0x4f, 0x8d, 0x52, 0x8c, 0x54, - 0x8b, 0x54, 0x8b, 0x53, 0x68, 0x68, 0x61, 0x68, 0x58, 0x68, 0x55, 0x65, - 0x54, 0x65, 0x53, 0x66, 0x53, 0x64, 0x55, 0x62, 0x56, 0x60, 0x57, 0x5f, - 0x57, 0x5d, 0x57, 0x5e, 0x56, 0x5d, 0x56, 0x5c, 0x55, 0x5c, 0x54, 0x5e, - 0x54, 0x5d, 0x53, 0x5e, 0x53, 0x5d, 0x52, 0x5d, 0x50, 0x60, 0x4d, 0x61, - 0x4b, 0x63, 0x4e, 0x65, 0x54, 0x65, 0x5d, 0x65, 0x60, 0x66, 0x63, 0x69, - 0x64, 0x6a, 0x64, 0x6a, 0x65, 0x6a, 0x66, 0x6b, 0x67, 0x6b, 0x67, 0x6b, - 0x66, 0x6e, 0x66, 0x70, 0x62, 0x78, 0x60, 0x78, 0x68, 0x76, 0x6f, 0x72, - 0x79, 0x72, 0x82, 0x73, 0x85, 0x73, 0x85, 0x73, 0x82, 0x76, 0x7b, 0x88, - 0x77, 0x91, 0x78, 0x90, 0x78, 0x8d, 0x7a, 0x8e, 0x77, 0x92, 0x76, 0x97, - 0x76, 0x97, 0x75, 0x96, 0x75, 0x97, 0x73, 0x98, 0x6f, 0x96, 0x70, 0x8d, - 0x76, 0x7c, 0x79, 0x85, 0x7b, 0x8e, 0x78, 0x97, 0x77, 0x97, 0x75, 0x96, - 0x75, 0x95, 0x76, 0x93, 0x78, 0x90, 0x78, 0x8f, 0x79, 0x8c, 0x7b, 0x81, - 0x7c, 0x71, 0x7e, 0x65, 0x80, 0x65, 0x83, 0x5b, 0x88, 0x51, 0x87, 0x57, - 0x8a, 0x55, 0x92, 0x48, 0x98, 0x42, 0x99, 0x3f, 0x97, 0x41, 0x92, 0x4c, - 0x8e, 0x52, 0x94, 0x4b, 0x9d, 0x3f, 0x9d, 0x3c, 0x9c, 0x41, 0x98, 0x40, - 0x88, 0x56, 0x90, 0x49, 0x9a, 0x38, 0x8f, 0x47, 0x8a, 0x52, 0x90, 0x49, - 0x84, 0x64, 0x7d, 0x77, 0x7c, 0x7e, 0x7c, 0x7d, 0x78, 0x7e, 0x69, 0x7b, - 0x64, 0x7b, 0x5f, 0x7f, 0x66, 0x7f, 0x60, 0x7b, 0x5e, 0x75, 0x5f, 0x74, - 0x62, 0x75, 0x64, 0x74, 0x67, 0x72, 0x67, 0x70, 0x64, 0x71, 0x5f, 0x74, - 0x5e, 0x78, 0x63, 0x76, 0x63, 0x74, 0x63, 0x74, 0x65, 0x75, 0x68, 0x7b, - 0x6a, 0x82, 0x6e, 0x82, 0x78, 0x77, 0x82, 0x61, 0x87, 0x51, 0x87, 0x50, - 0x87, 0x4f, 0x89, 0x4d, 0x87, 0x4e, 0x83, 0x56, 0x86, 0x55, 0x86, 0x50, - 0x84, 0x58, 0x7c, 0x6e, 0x74, 0x84, 0x72, 0x8a, 0x72, 0x8e, 0x72, 0x8e, - 0x71, 0x8d, 0x73, 0x8c, 0x75, 0x84, 0x7d, 0x6b, 0x88, 0x50, 0x8a, 0x4e, - 0x8b, 0x4e, 0x8c, 0x4e, 0x8c, 0x4e, 0x8d, 0x4d, 0x8e, 0x4f, 0x8d, 0x51, - 0x8d, 0x53, 0x8e, 0x52, 0x8e, 0x51, 0x8e, 0x51, 0x8e, 0x50, 0x8e, 0x50, - 0x8e, 0x4f, 0x8e, 0x4d, 0x8e, 0x4e, 0x8e, 0x52, 0x8c, 0x52, 0x8c, 0x52, - 0x67, 0x68, 0x61, 0x68, 0x59, 0x6a, 0x53, 0x67, 0x52, 0x66, 0x51, 0x66, - 0x52, 0x64, 0x54, 0x61, 0x56, 0x61, 0x56, 0x61, 0x56, 0x5e, 0x57, 0x5d, - 0x56, 0x5d, 0x55, 0x5e, 0x55, 0x5e, 0x54, 0x5e, 0x54, 0x5e, 0x54, 0x5c, - 0x53, 0x5f, 0x52, 0x60, 0x4f, 0x5f, 0x4c, 0x60, 0x4e, 0x63, 0x56, 0x65, - 0x5b, 0x65, 0x5f, 0x66, 0x63, 0x68, 0x65, 0x6a, 0x65, 0x6a, 0x66, 0x6a, - 0x67, 0x6b, 0x67, 0x6b, 0x67, 0x6b, 0x68, 0x6b, 0x69, 0x6d, 0x6b, 0x6d, - 0x72, 0x71, 0x75, 0x71, 0x81, 0x70, 0x86, 0x70, 0x87, 0x71, 0x85, 0x75, - 0x85, 0x76, 0x85, 0x77, 0x84, 0x77, 0x81, 0x7c, 0x7a, 0x89, 0x79, 0x8e, - 0x79, 0x8d, 0x7a, 0x8e, 0x77, 0x90, 0x74, 0x95, 0x75, 0x93, 0x77, 0x8f, - 0x79, 0x89, 0x7d, 0x82, 0x82, 0x77, 0x84, 0x6f, 0x8a, 0x68, 0x8b, 0x6a, - 0x88, 0x72, 0x7c, 0x82, 0x78, 0x89, 0x76, 0x90, 0x75, 0x95, 0x75, 0x93, - 0x78, 0x8e, 0x79, 0x89, 0x7d, 0x77, 0x83, 0x5d, 0x87, 0x51, 0x8b, 0x4f, - 0x85, 0x5a, 0x82, 0x5f, 0x91, 0x4c, 0x94, 0x4b, 0x90, 0x50, 0x99, 0x42, - 0x9d, 0x3e, 0x9c, 0x3d, 0x9d, 0x3c, 0x99, 0x41, 0x90, 0x4b, 0x90, 0x4d, - 0x9d, 0x41, 0xa0, 0x3a, 0x9b, 0x41, 0x9b, 0x48, 0x91, 0x48, 0x90, 0x49, - 0x9b, 0x39, 0x91, 0x46, 0x8b, 0x52, 0x93, 0x47, 0x8a, 0x58, 0x80, 0x6d, - 0x7d, 0x7b, 0x7e, 0x7d, 0x7c, 0x7e, 0x6f, 0x7e, 0x68, 0x7c, 0x60, 0x7e, - 0x63, 0x7f, 0x5b, 0x7b, 0x5a, 0x75, 0x5f, 0x75, 0x68, 0x74, 0x6a, 0x71, - 0x69, 0x6f, 0x65, 0x6f, 0x62, 0x71, 0x5d, 0x76, 0x62, 0x79, 0x63, 0x77, - 0x63, 0x74, 0x65, 0x74, 0x67, 0x75, 0x6a, 0x7b, 0x6e, 0x7f, 0x7a, 0x70, - 0x87, 0x5e, 0x89, 0x52, 0x87, 0x52, 0x87, 0x52, 0x87, 0x4e, 0x89, 0x4c, - 0x89, 0x4c, 0x86, 0x53, 0x88, 0x54, 0x88, 0x52, 0x8a, 0x4a, 0x87, 0x54, - 0x80, 0x6b, 0x7b, 0x76, 0x79, 0x7f, 0x79, 0x83, 0x78, 0x82, 0x7a, 0x7d, - 0x7e, 0x71, 0x85, 0x59, 0x8a, 0x4d, 0x8a, 0x4e, 0x8a, 0x4d, 0x8d, 0x4c, - 0x8c, 0x4c, 0x8d, 0x4b, 0x8e, 0x4c, 0x8d, 0x4e, 0x8e, 0x51, 0x8e, 0x50, - 0x8d, 0x4f, 0x8e, 0x4e, 0x90, 0x4d, 0x90, 0x4e, 0x90, 0x4c, 0x90, 0x4a, - 0x90, 0x4b, 0x90, 0x4e, 0x8f, 0x50, 0x8f, 0x4f, 0x66, 0x6a, 0x60, 0x6a, - 0x5b, 0x69, 0x52, 0x68, 0x51, 0x67, 0x51, 0x65, 0x51, 0x64, 0x53, 0x62, - 0x55, 0x60, 0x55, 0x60, 0x56, 0x60, 0x57, 0x5d, 0x56, 0x5d, 0x55, 0x5e, - 0x55, 0x5e, 0x54, 0x5f, 0x53, 0x5f, 0x54, 0x5c, 0x53, 0x5e, 0x52, 0x5e, - 0x4f, 0x5e, 0x4d, 0x61, 0x51, 0x64, 0x5b, 0x65, 0x5f, 0x66, 0x62, 0x69, - 0x65, 0x6a, 0x67, 0x6a, 0x66, 0x6b, 0x66, 0x6b, 0x69, 0x6d, 0x67, 0x6b, - 0x68, 0x6a, 0x70, 0x6a, 0x77, 0x68, 0x7d, 0x6a, 0x85, 0x6e, 0x86, 0x6f, - 0x86, 0x72, 0x85, 0x72, 0x85, 0x76, 0x85, 0x78, 0x84, 0x78, 0x84, 0x79, - 0x84, 0x79, 0x84, 0x73, 0x80, 0x7b, 0x7a, 0x89, 0x77, 0x8f, 0x78, 0x90, - 0x76, 0x90, 0x77, 0x8c, 0x7c, 0x86, 0x81, 0x79, 0x87, 0x71, 0x8b, 0x6d, - 0x8d, 0x6c, 0x8c, 0x6e, 0x8a, 0x6e, 0x8a, 0x6d, 0x8a, 0x6b, 0x87, 0x6b, - 0x85, 0x6b, 0x83, 0x6e, 0x7d, 0x7b, 0x7d, 0x7a, 0x7c, 0x70, 0x7f, 0x67, - 0x86, 0x57, 0x8d, 0x4a, 0x93, 0x47, 0x98, 0x47, 0x92, 0x47, 0x89, 0x58, - 0x92, 0x4e, 0x9a, 0x4b, 0x95, 0x4f, 0x9c, 0x42, 0x9d, 0x43, 0x9d, 0x45, - 0x9d, 0x41, 0x9b, 0x3b, 0x94, 0x42, 0x91, 0x4c, 0x98, 0x46, 0x9f, 0x3b, - 0xa0, 0x3b, 0x99, 0x51, 0x97, 0x42, 0x8f, 0x49, 0x99, 0x3d, 0x95, 0x42, - 0x8b, 0x51, 0x93, 0x46, 0x8d, 0x4f, 0x83, 0x63, 0x7f, 0x75, 0x7e, 0x7e, - 0x7d, 0x7e, 0x74, 0x80, 0x6a, 0x7d, 0x63, 0x7e, 0x60, 0x7f, 0x59, 0x7a, - 0x5a, 0x77, 0x61, 0x76, 0x69, 0x72, 0x6d, 0x6e, 0x69, 0x6c, 0x64, 0x70, - 0x60, 0x73, 0x5c, 0x78, 0x62, 0x78, 0x64, 0x76, 0x63, 0x73, 0x66, 0x72, - 0x67, 0x75, 0x6e, 0x7a, 0x77, 0x74, 0x87, 0x5e, 0x8d, 0x52, 0x8a, 0x4d, - 0x86, 0x52, 0x87, 0x51, 0x89, 0x4b, 0x89, 0x49, 0x89, 0x4b, 0x86, 0x52, - 0x88, 0x53, 0x88, 0x53, 0x89, 0x4d, 0x8b, 0x47, 0x89, 0x51, 0x86, 0x61, - 0x82, 0x6a, 0x81, 0x70, 0x82, 0x70, 0x83, 0x6a, 0x85, 0x5f, 0x8a, 0x4c, - 0x89, 0x4a, 0x8a, 0x4c, 0x8a, 0x4c, 0x8d, 0x4b, 0x8d, 0x4b, 0x8f, 0x4a, - 0x8f, 0x4a, 0x8f, 0x4c, 0x8e, 0x4f, 0x8f, 0x4f, 0x8f, 0x4c, 0x8f, 0x4a, - 0x91, 0x4a, 0x91, 0x4b, 0x92, 0x4b, 0x91, 0x48, 0x91, 0x49, 0x91, 0x4b, - 0x90, 0x4e, 0x93, 0x49, 0x65, 0x6a, 0x61, 0x6a, 0x5d, 0x69, 0x52, 0x68, - 0x50, 0x67, 0x50, 0x65, 0x51, 0x64, 0x52, 0x63, 0x54, 0x60, 0x55, 0x60, - 0x55, 0x60, 0x56, 0x5e, 0x55, 0x5c, 0x55, 0x5e, 0x55, 0x5d, 0x54, 0x5e, - 0x54, 0x5e, 0x54, 0x5b, 0x53, 0x5d, 0x52, 0x5d, 0x4f, 0x5e, 0x4e, 0x61, - 0x55, 0x64, 0x5d, 0x65, 0x60, 0x66, 0x63, 0x69, 0x66, 0x6a, 0x67, 0x6a, - 0x67, 0x6a, 0x67, 0x6a, 0x6c, 0x6b, 0x72, 0x67, 0x79, 0x69, 0x82, 0x6b, - 0x86, 0x6c, 0x86, 0x6f, 0x86, 0x72, 0x85, 0x74, 0x84, 0x76, 0x85, 0x76, - 0x84, 0x77, 0x85, 0x77, 0x84, 0x77, 0x84, 0x76, 0x83, 0x76, 0x85, 0x70, - 0x8a, 0x6b, 0x87, 0x72, 0x80, 0x7d, 0x7f, 0x7f, 0x82, 0x79, 0x87, 0x6f, - 0x89, 0x6d, 0x8b, 0x6c, 0x8b, 0x6d, 0x8b, 0x6f, 0x8a, 0x70, 0x8a, 0x71, - 0x88, 0x71, 0x88, 0x70, 0x88, 0x6f, 0x89, 0x6d, 0x8a, 0x6a, 0x8a, 0x66, - 0x8f, 0x5b, 0x92, 0x5c, 0x8a, 0x5b, 0x89, 0x54, 0x8f, 0x54, 0x94, 0x55, - 0x95, 0x55, 0x97, 0x54, 0x99, 0x51, 0x95, 0x4c, 0x95, 0x4c, 0x9a, 0x4a, - 0x96, 0x56, 0x97, 0x47, 0x9b, 0x48, 0x9b, 0x4b, 0x9b, 0x48, 0x9c, 0x3f, - 0x9a, 0x3d, 0x96, 0x46, 0x95, 0x4b, 0x9b, 0x45, 0x9f, 0x3b, 0x9b, 0x43, - 0x97, 0x48, 0x93, 0x41, 0x95, 0x40, 0x95, 0x40, 0x8c, 0x50, 0x93, 0x46, - 0x91, 0x49, 0x88, 0x5b, 0x86, 0x65, 0x83, 0x74, 0x7d, 0x7e, 0x78, 0x80, - 0x72, 0x80, 0x67, 0x80, 0x5b, 0x7f, 0x58, 0x79, 0x5e, 0x79, 0x63, 0x78, - 0x6a, 0x72, 0x6c, 0x6e, 0x68, 0x6d, 0x62, 0x72, 0x5e, 0x74, 0x5e, 0x79, - 0x64, 0x77, 0x65, 0x76, 0x65, 0x74, 0x67, 0x6f, 0x6b, 0x73, 0x7a, 0x6f, - 0x83, 0x64, 0x8c, 0x57, 0x8d, 0x4f, 0x8a, 0x4d, 0x88, 0x51, 0x88, 0x50, - 0x89, 0x4b, 0x89, 0x49, 0x8a, 0x48, 0x88, 0x50, 0x88, 0x51, 0x88, 0x51, - 0x89, 0x4f, 0x8b, 0x4a, 0x8d, 0x46, 0x8d, 0x4e, 0x8c, 0x53, 0x8b, 0x56, - 0x8c, 0x57, 0x8d, 0x52, 0x8d, 0x4d, 0x8d, 0x45, 0x8b, 0x47, 0x8b, 0x4a, - 0x8b, 0x4a, 0x8e, 0x4a, 0x8f, 0x4a, 0x8f, 0x4a, 0x8f, 0x4a, 0x8f, 0x4b, - 0x8e, 0x4d, 0x8f, 0x4e, 0x8f, 0x4c, 0x90, 0x4a, 0x90, 0x4a, 0x90, 0x4b, - 0x91, 0x4a, 0x92, 0x46, 0x92, 0x45, 0x92, 0x46, 0x92, 0x47, 0x94, 0x41, - 0x66, 0x69, 0x60, 0x6a, 0x5e, 0x69, 0x54, 0x68, 0x50, 0x67, 0x4f, 0x65, - 0x51, 0x64, 0x53, 0x63, 0x54, 0x61, 0x54, 0x61, 0x54, 0x60, 0x55, 0x5e, - 0x54, 0x5d, 0x55, 0x5d, 0x55, 0x5d, 0x54, 0x5c, 0x53, 0x5c, 0x54, 0x59, - 0x54, 0x5b, 0x52, 0x5c, 0x4f, 0x5e, 0x51, 0x61, 0x59, 0x63, 0x5f, 0x65, - 0x62, 0x67, 0x63, 0x69, 0x65, 0x6a, 0x66, 0x69, 0x6c, 0x68, 0x75, 0x68, - 0x7f, 0x6a, 0x85, 0x6e, 0x86, 0x6f, 0x85, 0x70, 0x84, 0x72, 0x84, 0x74, - 0x85, 0x72, 0x85, 0x74, 0x85, 0x76, 0x84, 0x76, 0x84, 0x77, 0x84, 0x78, - 0x85, 0x78, 0x84, 0x79, 0x84, 0x78, 0x84, 0x77, 0x86, 0x71, 0x87, 0x6f, - 0x89, 0x6f, 0x8a, 0x6f, 0x89, 0x6e, 0x8b, 0x6c, 0x8a, 0x6c, 0x8a, 0x6d, - 0x8a, 0x70, 0x89, 0x71, 0x88, 0x71, 0x87, 0x73, 0x86, 0x74, 0x86, 0x74, - 0x86, 0x74, 0x86, 0x73, 0x87, 0x71, 0x87, 0x6d, 0x8a, 0x64, 0x8f, 0x5c, - 0x8e, 0x62, 0x90, 0x53, 0x96, 0x57, 0x95, 0x66, 0x92, 0x65, 0x94, 0x5e, - 0x95, 0x59, 0x99, 0x52, 0x99, 0x49, 0x9b, 0x48, 0x96, 0x5b, 0x94, 0x54, - 0x99, 0x4a, 0x99, 0x52, 0x99, 0x51, 0x9a, 0x49, 0x9a, 0x3e, 0x99, 0x3e, - 0x92, 0x49, 0x96, 0x4b, 0x9e, 0x3f, 0x9e, 0x36, 0x9a, 0x4b, 0x9a, 0x3b, - 0x9a, 0x36, 0x95, 0x40, 0x8d, 0x51, 0x93, 0x46, 0x96, 0x43, 0x8d, 0x51, - 0x8d, 0x55, 0x8f, 0x58, 0x85, 0x6b, 0x7c, 0x7c, 0x74, 0x83, 0x66, 0x82, - 0x57, 0x7d, 0x5a, 0x78, 0x5f, 0x7b, 0x65, 0x7a, 0x6b, 0x75, 0x69, 0x6e, - 0x66, 0x6d, 0x61, 0x74, 0x5e, 0x77, 0x5f, 0x79, 0x65, 0x77, 0x67, 0x76, - 0x67, 0x73, 0x67, 0x70, 0x70, 0x72, 0x87, 0x5f, 0x8c, 0x56, 0x8d, 0x51, - 0x8c, 0x4c, 0x8a, 0x4c, 0x8a, 0x4f, 0x8a, 0x4e, 0x89, 0x4b, 0x89, 0x49, - 0x8c, 0x45, 0x89, 0x4c, 0x88, 0x4f, 0x88, 0x4f, 0x89, 0x52, 0x8b, 0x51, - 0x8f, 0x45, 0x91, 0x43, 0x93, 0x47, 0x93, 0x49, 0x93, 0x49, 0x93, 0x48, - 0x93, 0x46, 0x91, 0x42, 0x8e, 0x46, 0x8d, 0x49, 0x8e, 0x49, 0x91, 0x4a, - 0x91, 0x4a, 0x8f, 0x4b, 0x8f, 0x4a, 0x8f, 0x4a, 0x8f, 0x4b, 0x8f, 0x4e, - 0x8f, 0x4c, 0x8f, 0x4a, 0x90, 0x4b, 0x90, 0x4a, 0x91, 0x48, 0x92, 0x45, - 0x94, 0x45, 0x93, 0x45, 0x94, 0x43, 0x97, 0x3e, 0x63, 0x6a, 0x5f, 0x6a, - 0x5c, 0x68, 0x53, 0x67, 0x4f, 0x67, 0x4f, 0x66, 0x50, 0x65, 0x52, 0x64, - 0x54, 0x62, 0x54, 0x61, 0x54, 0x60, 0x54, 0x5f, 0x54, 0x5d, 0x54, 0x5d, - 0x54, 0x5e, 0x54, 0x5c, 0x53, 0x5c, 0x54, 0x59, 0x54, 0x5b, 0x52, 0x5b, - 0x4e, 0x5f, 0x51, 0x62, 0x58, 0x64, 0x60, 0x66, 0x63, 0x67, 0x63, 0x68, - 0x66, 0x68, 0x6c, 0x67, 0x7b, 0x68, 0x84, 0x6b, 0x87, 0x70, 0x87, 0x73, - 0x86, 0x74, 0x84, 0x74, 0x84, 0x74, 0x85, 0x75, 0x85, 0x74, 0x84, 0x74, - 0x85, 0x76, 0x84, 0x76, 0x84, 0x77, 0x85, 0x78, 0x84, 0x79, 0x83, 0x7a, - 0x83, 0x79, 0x84, 0x78, 0x83, 0x76, 0x85, 0x76, 0x88, 0x77, 0x87, 0x75, - 0x86, 0x75, 0x87, 0x73, 0x87, 0x72, 0x87, 0x70, 0x88, 0x70, 0x88, 0x70, - 0x87, 0x6f, 0x87, 0x71, 0x86, 0x74, 0x86, 0x74, 0x85, 0x75, 0x85, 0x75, - 0x86, 0x73, 0x86, 0x70, 0x87, 0x6c, 0x89, 0x62, 0x8e, 0x5e, 0x91, 0x58, - 0x96, 0x55, 0x92, 0x6a, 0x90, 0x69, 0x91, 0x61, 0x93, 0x5b, 0x96, 0x5a, - 0x98, 0x4b, 0x9a, 0x47, 0x98, 0x58, 0x92, 0x63, 0x96, 0x4e, 0x9a, 0x50, - 0x9a, 0x53, 0x98, 0x4f, 0x99, 0x46, 0x99, 0x3f, 0x94, 0x43, 0x94, 0x4a, - 0x9e, 0x40, 0xa0, 0x36, 0x9c, 0x44, 0x9a, 0x48, 0x9c, 0x3b, 0x96, 0x3f, - 0x8c, 0x50, 0x91, 0x48, 0x96, 0x41, 0x91, 0x4a, 0x8f, 0x51, 0x94, 0x4b, - 0x8e, 0x57, 0x7d, 0x75, 0x70, 0x86, 0x60, 0x84, 0x57, 0x7c, 0x5b, 0x77, - 0x5e, 0x7c, 0x65, 0x7b, 0x6a, 0x74, 0x68, 0x6e, 0x63, 0x6f, 0x60, 0x76, - 0x5e, 0x78, 0x63, 0x79, 0x67, 0x76, 0x66, 0x74, 0x66, 0x73, 0x69, 0x73, - 0x76, 0x6e, 0x8b, 0x59, 0x8f, 0x53, 0x8d, 0x4e, 0x8b, 0x4d, 0x89, 0x4d, - 0x89, 0x4e, 0x8a, 0x4d, 0x8a, 0x4b, 0x8c, 0x48, 0x8d, 0x44, 0x8a, 0x49, - 0x8a, 0x4f, 0x8a, 0x4e, 0x8a, 0x51, 0x8a, 0x51, 0x8d, 0x4b, 0x91, 0x44, - 0x92, 0x43, 0x94, 0x43, 0x95, 0x44, 0x96, 0x44, 0x96, 0x43, 0x93, 0x42, - 0x8e, 0x48, 0x8e, 0x49, 0x8f, 0x49, 0x90, 0x4a, 0x90, 0x4a, 0x91, 0x4a, - 0x91, 0x4a, 0x90, 0x49, 0x8f, 0x4c, 0x8f, 0x4d, 0x8f, 0x4c, 0x90, 0x4a, - 0x91, 0x4b, 0x91, 0x4a, 0x92, 0x47, 0x92, 0x46, 0x92, 0x47, 0x93, 0x47, - 0x94, 0x45, 0x97, 0x40, 0x60, 0x6a, 0x5e, 0x6a, 0x5a, 0x69, 0x52, 0x66, - 0x4d, 0x66, 0x4e, 0x67, 0x50, 0x66, 0x50, 0x65, 0x53, 0x63, 0x53, 0x62, - 0x54, 0x61, 0x54, 0x5f, 0x54, 0x5f, 0x54, 0x5d, 0x54, 0x5f, 0x54, 0x5d, - 0x54, 0x5d, 0x54, 0x5a, 0x54, 0x5a, 0x51, 0x5a, 0x4d, 0x5f, 0x52, 0x63, - 0x58, 0x65, 0x5f, 0x67, 0x5f, 0x67, 0x67, 0x67, 0x74, 0x68, 0x7f, 0x6b, - 0x86, 0x70, 0x86, 0x72, 0x85, 0x73, 0x85, 0x72, 0x86, 0x75, 0x85, 0x75, - 0x84, 0x75, 0x84, 0x74, 0x85, 0x75, 0x84, 0x75, 0x84, 0x77, 0x85, 0x77, - 0x84, 0x77, 0x84, 0x76, 0x83, 0x76, 0x82, 0x76, 0x83, 0x76, 0x85, 0x77, - 0x85, 0x75, 0x86, 0x73, 0x86, 0x73, 0x86, 0x74, 0x86, 0x74, 0x87, 0x75, - 0x87, 0x75, 0x87, 0x73, 0x87, 0x73, 0x87, 0x72, 0x87, 0x72, 0x87, 0x73, - 0x87, 0x73, 0x86, 0x73, 0x85, 0x75, 0x86, 0x75, 0x87, 0x73, 0x87, 0x70, - 0x87, 0x6d, 0x87, 0x6b, 0x8c, 0x61, 0x8e, 0x5e, 0x94, 0x52, 0x93, 0x60, - 0x90, 0x6a, 0x90, 0x65, 0x92, 0x61, 0x95, 0x5c, 0x97, 0x54, 0x98, 0x4b, - 0x9a, 0x4d, 0x95, 0x61, 0x93, 0x5f, 0x99, 0x49, 0x9a, 0x49, 0x98, 0x54, - 0x98, 0x50, 0x9a, 0x47, 0x98, 0x3d, 0x95, 0x44, 0x9b, 0x44, 0xa3, 0x38, - 0x9f, 0x39, 0x97, 0x52, 0x96, 0x4f, 0x95, 0x45, 0x8c, 0x4e, 0x8f, 0x4a, - 0x94, 0x43, 0x94, 0x44, 0x93, 0x4b, 0x96, 0x46, 0x95, 0x4b, 0x7a, 0x72, - 0x63, 0x8a, 0x59, 0x85, 0x5b, 0x7b, 0x5c, 0x79, 0x60, 0x7d, 0x67, 0x7b, - 0x68, 0x72, 0x66, 0x6e, 0x62, 0x72, 0x60, 0x77, 0x5f, 0x79, 0x65, 0x78, - 0x68, 0x76, 0x66, 0x73, 0x68, 0x73, 0x6e, 0x73, 0x80, 0x63, 0x8f, 0x52, - 0x8f, 0x4f, 0x8d, 0x4a, 0x8a, 0x4d, 0x89, 0x4d, 0x89, 0x4c, 0x89, 0x4c, - 0x8b, 0x4a, 0x8d, 0x45, 0x8e, 0x41, 0x8b, 0x44, 0x8a, 0x4d, 0x8b, 0x4e, - 0x8b, 0x51, 0x8a, 0x51, 0x8c, 0x4e, 0x8e, 0x48, 0x91, 0x43, 0x94, 0x41, - 0x95, 0x41, 0x95, 0x43, 0x95, 0x45, 0x92, 0x47, 0x8e, 0x4b, 0x8f, 0x4a, - 0x8f, 0x4a, 0x8f, 0x4b, 0x90, 0x4a, 0x91, 0x48, 0x92, 0x49, 0x91, 0x49, - 0x90, 0x4b, 0x90, 0x4b, 0x90, 0x4a, 0x91, 0x4a, 0x91, 0x49, 0x92, 0x49, - 0x91, 0x49, 0x91, 0x49, 0x91, 0x48, 0x92, 0x48, 0x93, 0x46, 0x95, 0x43, - 0x5f, 0x6a, 0x5d, 0x6a, 0x5b, 0x69, 0x52, 0x66, 0x4d, 0x66, 0x4e, 0x67, - 0x50, 0x66, 0x50, 0x65, 0x52, 0x63, 0x53, 0x62, 0x53, 0x61, 0x54, 0x5f, - 0x54, 0x5f, 0x54, 0x5e, 0x54, 0x5c, 0x54, 0x5d, 0x54, 0x5d, 0x54, 0x5a, - 0x54, 0x5a, 0x52, 0x5a, 0x4e, 0x60, 0x54, 0x63, 0x5a, 0x65, 0x5e, 0x67, - 0x61, 0x67, 0x77, 0x69, 0x82, 0x6f, 0x86, 0x73, 0x86, 0x74, 0x86, 0x74, - 0x86, 0x72, 0x86, 0x72, 0x86, 0x75, 0x86, 0x75, 0x84, 0x75, 0x84, 0x74, - 0x85, 0x75, 0x85, 0x75, 0x84, 0x77, 0x84, 0x78, 0x84, 0x77, 0x84, 0x76, - 0x83, 0x77, 0x82, 0x77, 0x83, 0x77, 0x84, 0x78, 0x84, 0x77, 0x84, 0x76, - 0x85, 0x76, 0x84, 0x76, 0x84, 0x76, 0x86, 0x74, 0x87, 0x74, 0x87, 0x73, - 0x87, 0x73, 0x87, 0x73, 0x87, 0x74, 0x87, 0x74, 0x87, 0x73, 0x86, 0x74, - 0x85, 0x75, 0x86, 0x75, 0x87, 0x73, 0x87, 0x70, 0x87, 0x70, 0x87, 0x71, - 0x89, 0x68, 0x8b, 0x5f, 0x93, 0x54, 0x94, 0x56, 0x90, 0x67, 0x90, 0x68, - 0x91, 0x64, 0x93, 0x5f, 0x95, 0x59, 0x97, 0x52, 0x99, 0x48, 0x99, 0x51, - 0x93, 0x67, 0x95, 0x52, 0x98, 0x48, 0x97, 0x52, 0x96, 0x53, 0x98, 0x4d, - 0x9b, 0x40, 0x99, 0x3c, 0x98, 0x45, 0xa2, 0x38, 0xa2, 0x33, 0x99, 0x4d, - 0x95, 0x54, 0x96, 0x46, 0x8c, 0x4c, 0x8f, 0x4b, 0x92, 0x45, 0x94, 0x42, - 0x95, 0x45, 0x98, 0x44, 0x96, 0x4c, 0x72, 0x77, 0x57, 0x8a, 0x56, 0x82, - 0x5d, 0x7b, 0x5e, 0x7b, 0x63, 0x7e, 0x6a, 0x7a, 0x68, 0x6f, 0x64, 0x70, - 0x62, 0x73, 0x61, 0x77, 0x62, 0x79, 0x66, 0x79, 0x67, 0x75, 0x65, 0x73, - 0x6a, 0x73, 0x74, 0x71, 0x87, 0x59, 0x8e, 0x4e, 0x8e, 0x4b, 0x8d, 0x46, - 0x8a, 0x4c, 0x89, 0x4b, 0x89, 0x4a, 0x89, 0x4b, 0x8b, 0x4a, 0x8d, 0x41, - 0x8f, 0x3d, 0x8d, 0x40, 0x8a, 0x4b, 0x8b, 0x4f, 0x8b, 0x53, 0x8b, 0x53, - 0x8a, 0x50, 0x8c, 0x4d, 0x8f, 0x48, 0x92, 0x44, 0x93, 0x45, 0x92, 0x48, - 0x91, 0x4b, 0x8f, 0x4d, 0x8f, 0x4d, 0x8f, 0x4b, 0x8f, 0x4b, 0x90, 0x4b, - 0x90, 0x4b, 0x91, 0x49, 0x91, 0x49, 0x90, 0x48, 0x90, 0x49, 0x91, 0x49, - 0x92, 0x49, 0x92, 0x48, 0x91, 0x47, 0x91, 0x48, 0x91, 0x49, 0x91, 0x49, - 0x92, 0x4a, 0x91, 0x49, 0x91, 0x46, 0x94, 0x46, 0x5e, 0x6a, 0x5c, 0x69, - 0x59, 0x67, 0x51, 0x66, 0x4c, 0x67, 0x4c, 0x66, 0x4f, 0x66, 0x4f, 0x66, - 0x51, 0x64, 0x52, 0x63, 0x53, 0x61, 0x54, 0x5f, 0x54, 0x60, 0x54, 0x5f, - 0x54, 0x5c, 0x55, 0x5b, 0x55, 0x5a, 0x54, 0x59, 0x54, 0x5a, 0x52, 0x5a, - 0x4e, 0x60, 0x53, 0x62, 0x5b, 0x64, 0x64, 0x65, 0x71, 0x68, 0x83, 0x70, - 0x85, 0x73, 0x84, 0x75, 0x84, 0x74, 0x85, 0x73, 0x85, 0x73, 0x85, 0x73, - 0x85, 0x75, 0x85, 0x75, 0x84, 0x74, 0x84, 0x75, 0x85, 0x76, 0x85, 0x76, - 0x85, 0x78, 0x85, 0x78, 0x84, 0x78, 0x83, 0x78, 0x83, 0x78, 0x82, 0x79, - 0x83, 0x79, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x79, - 0x84, 0x78, 0x85, 0x77, 0x85, 0x77, 0x86, 0x74, 0x86, 0x73, 0x87, 0x73, - 0x87, 0x72, 0x87, 0x72, 0x88, 0x73, 0x86, 0x73, 0x85, 0x73, 0x86, 0x74, - 0x87, 0x73, 0x87, 0x71, 0x87, 0x70, 0x87, 0x70, 0x88, 0x6c, 0x89, 0x66, - 0x8e, 0x5b, 0x95, 0x50, 0x92, 0x5f, 0x8f, 0x6a, 0x8f, 0x65, 0x92, 0x61, - 0x94, 0x5c, 0x96, 0x57, 0x97, 0x4b, 0x98, 0x48, 0x96, 0x59, 0x93, 0x61, - 0x96, 0x54, 0x97, 0x4d, 0x96, 0x54, 0x98, 0x52, 0x9a, 0x47, 0x9c, 0x3b, - 0x99, 0x3f, 0x9c, 0x3d, 0xa1, 0x33, 0x9a, 0x48, 0x96, 0x50, 0x99, 0x41, - 0x8d, 0x4a, 0x8f, 0x4a, 0x91, 0x46, 0x94, 0x42, 0x97, 0x42, 0x98, 0x42, - 0x8f, 0x52, 0x66, 0x81, 0x54, 0x86, 0x55, 0x81, 0x5b, 0x7c, 0x5f, 0x7d, - 0x64, 0x7d, 0x6a, 0x76, 0x68, 0x6e, 0x62, 0x72, 0x61, 0x76, 0x61, 0x77, - 0x61, 0x7a, 0x66, 0x79, 0x66, 0x74, 0x64, 0x73, 0x6c, 0x73, 0x7e, 0x64, - 0x8d, 0x52, 0x8f, 0x4b, 0x8f, 0x46, 0x8e, 0x46, 0x8b, 0x49, 0x8b, 0x49, - 0x8a, 0x49, 0x8a, 0x49, 0x8b, 0x48, 0x8e, 0x41, 0x90, 0x3c, 0x8e, 0x41, - 0x8b, 0x4a, 0x8a, 0x50, 0x8a, 0x55, 0x8a, 0x54, 0x8b, 0x50, 0x8c, 0x4d, - 0x8d, 0x4a, 0x8f, 0x4b, 0x90, 0x4c, 0x8f, 0x4f, 0x8e, 0x51, 0x8d, 0x50, - 0x8e, 0x4d, 0x8f, 0x4a, 0x8f, 0x49, 0x91, 0x49, 0x91, 0x4a, 0x92, 0x49, - 0x92, 0x49, 0x91, 0x48, 0x90, 0x49, 0x91, 0x49, 0x93, 0x48, 0x92, 0x47, - 0x92, 0x46, 0x92, 0x46, 0x91, 0x48, 0x92, 0x48, 0x92, 0x49, 0x92, 0x49, - 0x91, 0x46, 0x92, 0x47, 0x5d, 0x6b, 0x5b, 0x68, 0x57, 0x66, 0x4f, 0x66, - 0x4a, 0x67, 0x4b, 0x64, 0x4d, 0x65, 0x4f, 0x65, 0x50, 0x65, 0x50, 0x63, - 0x52, 0x61, 0x53, 0x5f, 0x53, 0x5e, 0x54, 0x5e, 0x54, 0x5c, 0x56, 0x59, - 0x56, 0x57, 0x55, 0x57, 0x53, 0x5a, 0x50, 0x5a, 0x4e, 0x60, 0x53, 0x62, - 0x5c, 0x60, 0x79, 0x66, 0x84, 0x6e, 0x84, 0x75, 0x85, 0x75, 0x85, 0x75, - 0x85, 0x75, 0x84, 0x74, 0x84, 0x75, 0x84, 0x75, 0x84, 0x75, 0x84, 0x75, - 0x84, 0x76, 0x85, 0x76, 0x85, 0x78, 0x85, 0x78, 0x85, 0x79, 0x85, 0x78, - 0x83, 0x78, 0x83, 0x78, 0x83, 0x78, 0x83, 0x78, 0x83, 0x78, 0x83, 0x78, - 0x84, 0x78, 0x85, 0x78, 0x84, 0x78, 0x85, 0x78, 0x85, 0x78, 0x84, 0x78, - 0x84, 0x78, 0x84, 0x77, 0x85, 0x77, 0x86, 0x75, 0x86, 0x73, 0x87, 0x70, - 0x88, 0x70, 0x87, 0x71, 0x86, 0x71, 0x86, 0x72, 0x87, 0x72, 0x87, 0x71, - 0x87, 0x70, 0x87, 0x70, 0x88, 0x6c, 0x87, 0x6b, 0x8a, 0x65, 0x91, 0x51, - 0x92, 0x53, 0x8f, 0x68, 0x8f, 0x67, 0x91, 0x63, 0x93, 0x5f, 0x95, 0x5b, - 0x96, 0x53, 0x97, 0x4a, 0x99, 0x48, 0x96, 0x59, 0x95, 0x5c, 0x97, 0x4b, - 0x98, 0x4f, 0x96, 0x54, 0x98, 0x4e, 0x9b, 0x41, 0x9c, 0x39, 0x99, 0x41, - 0x9e, 0x37, 0x9b, 0x44, 0x97, 0x51, 0x9a, 0x3e, 0x91, 0x48, 0x8f, 0x4a, - 0x91, 0x46, 0x94, 0x42, 0x98, 0x3f, 0x96, 0x44, 0x82, 0x62, 0x5a, 0x88, - 0x55, 0x83, 0x57, 0x80, 0x5b, 0x7d, 0x60, 0x7f, 0x65, 0x7b, 0x66, 0x72, - 0x66, 0x6e, 0x5e, 0x75, 0x60, 0x79, 0x63, 0x79, 0x60, 0x7b, 0x64, 0x79, - 0x62, 0x73, 0x60, 0x76, 0x6f, 0x72, 0x87, 0x56, 0x91, 0x4b, 0x90, 0x45, - 0x90, 0x41, 0x8f, 0x44, 0x8d, 0x45, 0x8e, 0x45, 0x8c, 0x46, 0x8c, 0x46, - 0x8d, 0x44, 0x8f, 0x40, 0x90, 0x3c, 0x8e, 0x43, 0x8c, 0x4d, 0x8a, 0x51, - 0x8a, 0x56, 0x8b, 0x54, 0x8b, 0x50, 0x8d, 0x4c, 0x8d, 0x4b, 0x8d, 0x4d, - 0x8d, 0x4f, 0x8d, 0x51, 0x8d, 0x52, 0x8d, 0x4f, 0x8e, 0x4b, 0x90, 0x48, - 0x90, 0x46, 0x92, 0x47, 0x92, 0x49, 0x92, 0x49, 0x92, 0x48, 0x92, 0x48, - 0x92, 0x48, 0x93, 0x48, 0x93, 0x46, 0x93, 0x44, 0x95, 0x44, 0x94, 0x44, - 0x93, 0x45, 0x93, 0x46, 0x93, 0x46, 0x93, 0x46, 0x93, 0x45, 0x93, 0x45, - 0x5a, 0x6b, 0x57, 0x68, 0x55, 0x66, 0x4d, 0x66, 0x48, 0x65, 0x4a, 0x62, - 0x4d, 0x63, 0x4f, 0x63, 0x50, 0x63, 0x51, 0x61, 0x52, 0x60, 0x53, 0x5f, - 0x53, 0x5d, 0x54, 0x5c, 0x54, 0x5a, 0x56, 0x59, 0x56, 0x57, 0x55, 0x57, - 0x52, 0x5a, 0x50, 0x5a, 0x4d, 0x60, 0x53, 0x64, 0x67, 0x61, 0x83, 0x6d, - 0x86, 0x73, 0x84, 0x76, 0x85, 0x76, 0x85, 0x76, 0x85, 0x76, 0x85, 0x76, - 0x85, 0x76, 0x85, 0x76, 0x84, 0x75, 0x84, 0x75, 0x84, 0x78, 0x85, 0x78, - 0x85, 0x77, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x83, 0x78, 0x83, 0x78, - 0x83, 0x78, 0x83, 0x78, 0x83, 0x78, 0x82, 0x78, 0x84, 0x78, 0x85, 0x78, - 0x84, 0x78, 0x84, 0x78, 0x85, 0x78, 0x85, 0x77, 0x85, 0x76, 0x85, 0x77, - 0x85, 0x77, 0x85, 0x77, 0x85, 0x74, 0x85, 0x71, 0x86, 0x6f, 0x87, 0x70, - 0x87, 0x70, 0x87, 0x71, 0x87, 0x72, 0x87, 0x72, 0x87, 0x70, 0x87, 0x70, - 0x88, 0x6e, 0x89, 0x6c, 0x89, 0x69, 0x8d, 0x5c, 0x8f, 0x54, 0x90, 0x65, - 0x8f, 0x6a, 0x92, 0x64, 0x92, 0x61, 0x93, 0x5e, 0x95, 0x59, 0x96, 0x51, - 0x97, 0x48, 0x99, 0x4a, 0x99, 0x52, 0x97, 0x4e, 0x97, 0x47, 0x95, 0x52, - 0x97, 0x53, 0x9a, 0x4a, 0x9b, 0x39, 0x9b, 0x3f, 0x9b, 0x3d, 0x9d, 0x3e, - 0x97, 0x4f, 0x9a, 0x3d, 0x94, 0x44, 0x90, 0x4a, 0x91, 0x46, 0x94, 0x42, - 0x97, 0x3e, 0x91, 0x4c, 0x75, 0x73, 0x58, 0x88, 0x57, 0x84, 0x59, 0x81, - 0x5d, 0x7f, 0x61, 0x80, 0x65, 0x79, 0x63, 0x71, 0x63, 0x70, 0x5b, 0x77, - 0x5e, 0x7a, 0x66, 0x7a, 0x5f, 0x79, 0x62, 0x77, 0x5f, 0x75, 0x5e, 0x7a, - 0x73, 0x6e, 0x8b, 0x50, 0x92, 0x47, 0x90, 0x42, 0x90, 0x3e, 0x8f, 0x41, - 0x8f, 0x42, 0x8f, 0x42, 0x8e, 0x44, 0x8e, 0x44, 0x8f, 0x41, 0x91, 0x3d, - 0x91, 0x3b, 0x8e, 0x43, 0x8c, 0x4e, 0x8a, 0x53, 0x8a, 0x56, 0x8b, 0x54, - 0x8b, 0x51, 0x8d, 0x4e, 0x8d, 0x4d, 0x8d, 0x4f, 0x8d, 0x51, 0x8d, 0x51, - 0x8e, 0x4f, 0x8f, 0x4d, 0x90, 0x49, 0x90, 0x47, 0x90, 0x44, 0x91, 0x45, - 0x91, 0x48, 0x92, 0x49, 0x92, 0x49, 0x92, 0x47, 0x93, 0x47, 0x94, 0x46, - 0x94, 0x43, 0x95, 0x41, 0x96, 0x41, 0x96, 0x42, 0x95, 0x44, 0x94, 0x44, - 0x94, 0x43, 0x94, 0x44, 0x95, 0x44, 0x95, 0x44, 0x57, 0x6a, 0x54, 0x68, - 0x52, 0x66, 0x4a, 0x65, 0x47, 0x65, 0x49, 0x63, 0x4c, 0x62, 0x4e, 0x62, - 0x50, 0x62, 0x51, 0x61, 0x52, 0x5f, 0x52, 0x5e, 0x53, 0x5d, 0x55, 0x59, - 0x55, 0x58, 0x55, 0x58, 0x55, 0x56, 0x55, 0x56, 0x52, 0x58, 0x50, 0x59, - 0x4f, 0x5f, 0x5c, 0x60, 0x7c, 0x69, 0x83, 0x74, 0x84, 0x75, 0x85, 0x78, - 0x85, 0x78, 0x85, 0x78, 0x85, 0x78, 0x85, 0x78, 0x85, 0x77, 0x85, 0x77, - 0x85, 0x77, 0x85, 0x77, 0x85, 0x78, 0x85, 0x78, 0x84, 0x78, 0x84, 0x78, - 0x83, 0x79, 0x83, 0x79, 0x83, 0x79, 0x83, 0x79, 0x83, 0x79, 0x82, 0x78, - 0x83, 0x78, 0x83, 0x78, 0x84, 0x78, 0x85, 0x78, 0x85, 0x78, 0x84, 0x77, - 0x84, 0x78, 0x84, 0x75, 0x84, 0x76, 0x84, 0x74, 0x85, 0x74, 0x85, 0x75, - 0x84, 0x74, 0x85, 0x73, 0x85, 0x73, 0x86, 0x71, 0x87, 0x6f, 0x87, 0x70, - 0x87, 0x70, 0x88, 0x70, 0x87, 0x70, 0x87, 0x70, 0x88, 0x6f, 0x88, 0x6d, - 0x88, 0x6a, 0x89, 0x64, 0x8c, 0x5e, 0x91, 0x5e, 0x90, 0x67, 0x91, 0x66, - 0x91, 0x61, 0x92, 0x60, 0x93, 0x5c, 0x94, 0x56, 0x96, 0x50, 0x97, 0x46, - 0x99, 0x46, 0x99, 0x50, 0x96, 0x49, 0x96, 0x4f, 0x96, 0x57, 0x97, 0x55, - 0x9a, 0x43, 0x9b, 0x39, 0x97, 0x44, 0x9d, 0x3a, 0x9a, 0x4a, 0x9a, 0x3e, - 0x96, 0x3e, 0x90, 0x4a, 0x91, 0x47, 0x93, 0x44, 0x97, 0x40, 0x7f, 0x64, - 0x61, 0x84, 0x58, 0x85, 0x5a, 0x83, 0x5b, 0x80, 0x5e, 0x80, 0x63, 0x80, - 0x65, 0x76, 0x62, 0x6f, 0x5f, 0x73, 0x5a, 0x79, 0x5f, 0x7b, 0x66, 0x7b, - 0x61, 0x78, 0x5f, 0x75, 0x5c, 0x76, 0x5d, 0x7a, 0x7d, 0x62, 0x8f, 0x49, - 0x92, 0x43, 0x90, 0x3f, 0x91, 0x3d, 0x90, 0x3e, 0x91, 0x3f, 0x91, 0x3f, - 0x90, 0x41, 0x90, 0x40, 0x90, 0x3e, 0x91, 0x3b, 0x91, 0x3b, 0x8e, 0x43, - 0x8b, 0x51, 0x8a, 0x55, 0x8a, 0x57, 0x8b, 0x55, 0x8c, 0x52, 0x8d, 0x4f, - 0x8d, 0x4e, 0x8e, 0x50, 0x8d, 0x51, 0x8d, 0x50, 0x8e, 0x4d, 0x90, 0x4a, - 0x90, 0x4a, 0x8f, 0x47, 0x91, 0x41, 0x92, 0x42, 0x92, 0x45, 0x93, 0x48, - 0x93, 0x47, 0x94, 0x45, 0x95, 0x43, 0x95, 0x42, 0x96, 0x3f, 0x96, 0x3e, - 0x97, 0x3d, 0x97, 0x3f, 0x96, 0x42, 0x96, 0x41, 0x96, 0x40, 0x96, 0x41, - 0x96, 0x42, 0x97, 0x43, 0x55, 0x6a, 0x53, 0x67, 0x51, 0x64, 0x49, 0x64, - 0x46, 0x64, 0x49, 0x65, 0x4c, 0x62, 0x4e, 0x62, 0x4f, 0x60, 0x50, 0x60, - 0x51, 0x5f, 0x51, 0x5e, 0x52, 0x5d, 0x55, 0x57, 0x55, 0x56, 0x54, 0x56, - 0x54, 0x58, 0x55, 0x55, 0x52, 0x57, 0x52, 0x59, 0x55, 0x5b, 0x73, 0x62, - 0x83, 0x71, 0x84, 0x74, 0x85, 0x75, 0x85, 0x78, 0x85, 0x77, 0x85, 0x77, - 0x85, 0x77, 0x85, 0x78, 0x85, 0x77, 0x85, 0x77, 0x85, 0x79, 0x84, 0x78, - 0x84, 0x78, 0x84, 0x78, 0x83, 0x7a, 0x82, 0x7a, 0x82, 0x7a, 0x82, 0x7a, - 0x83, 0x7b, 0x83, 0x7a, 0x83, 0x7a, 0x83, 0x77, 0x84, 0x78, 0x84, 0x77, - 0x85, 0x77, 0x86, 0x79, 0x85, 0x78, 0x84, 0x77, 0x84, 0x77, 0x84, 0x77, - 0x84, 0x77, 0x85, 0x75, 0x86, 0x75, 0x86, 0x73, 0x86, 0x72, 0x85, 0x73, - 0x85, 0x73, 0x86, 0x72, 0x87, 0x70, 0x88, 0x6f, 0x88, 0x6d, 0x87, 0x6e, - 0x88, 0x70, 0x88, 0x70, 0x88, 0x6e, 0x88, 0x6c, 0x89, 0x6a, 0x8a, 0x68, - 0x8b, 0x63, 0x8e, 0x58, 0x90, 0x5f, 0x90, 0x65, 0x92, 0x62, 0x93, 0x5f, - 0x92, 0x5d, 0x93, 0x58, 0x95, 0x52, 0x97, 0x4a, 0x98, 0x44, 0x98, 0x4a, - 0x97, 0x4b, 0x97, 0x4b, 0x96, 0x57, 0x95, 0x57, 0x99, 0x4c, 0x9a, 0x3a, - 0x96, 0x44, 0x9c, 0x3b, 0x9d, 0x44, 0x99, 0x44, 0x96, 0x3b, 0x90, 0x4a, - 0x91, 0x48, 0x93, 0x45, 0x97, 0x47, 0x6e, 0x79, 0x58, 0x88, 0x57, 0x85, - 0x59, 0x82, 0x5c, 0x80, 0x60, 0x81, 0x64, 0x7f, 0x65, 0x74, 0x62, 0x6e, - 0x5d, 0x75, 0x5c, 0x7a, 0x60, 0x7a, 0x64, 0x7b, 0x62, 0x78, 0x5f, 0x75, - 0x5c, 0x77, 0x62, 0x78, 0x87, 0x58, 0x91, 0x45, 0x91, 0x41, 0x92, 0x3e, - 0x91, 0x3e, 0x92, 0x3e, 0x93, 0x3e, 0x93, 0x3f, 0x91, 0x40, 0x91, 0x3f, - 0x91, 0x3c, 0x91, 0x3b, 0x90, 0x3c, 0x8e, 0x43, 0x89, 0x55, 0x89, 0x57, - 0x89, 0x58, 0x8a, 0x55, 0x8c, 0x50, 0x8e, 0x4f, 0x8e, 0x50, 0x8d, 0x50, - 0x8d, 0x50, 0x8f, 0x4f, 0x8f, 0x4c, 0x90, 0x4a, 0x8f, 0x4d, 0x90, 0x49, - 0x92, 0x3f, 0x92, 0x3e, 0x92, 0x43, 0x94, 0x46, 0x94, 0x44, 0x96, 0x43, - 0x95, 0x40, 0x96, 0x3f, 0x97, 0x3e, 0x97, 0x3c, 0x98, 0x3c, 0x98, 0x3f, - 0x97, 0x40, 0x97, 0x3f, 0x97, 0x3e, 0x97, 0x3e, 0x97, 0x3e, 0x97, 0x40, - 0x54, 0x68, 0x51, 0x65, 0x4f, 0x63, 0x4a, 0x63, 0x47, 0x63, 0x49, 0x63, - 0x4b, 0x62, 0x4d, 0x62, 0x50, 0x60, 0x50, 0x60, 0x51, 0x5f, 0x51, 0x5d, - 0x52, 0x5d, 0x53, 0x5b, 0x54, 0x58, 0x54, 0x57, 0x54, 0x5c, 0x53, 0x59, - 0x52, 0x57, 0x52, 0x59, 0x63, 0x5b, 0x80, 0x6e, 0x83, 0x76, 0x85, 0x74, - 0x85, 0x75, 0x85, 0x78, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, - 0x85, 0x77, 0x85, 0x77, 0x84, 0x78, 0x85, 0x77, 0x85, 0x77, 0x84, 0x77, - 0x83, 0x7a, 0x83, 0x7a, 0x82, 0x7a, 0x82, 0x7a, 0x82, 0x7a, 0x83, 0x7a, - 0x83, 0x79, 0x83, 0x78, 0x84, 0x78, 0x85, 0x78, 0x85, 0x77, 0x85, 0x76, - 0x86, 0x76, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, - 0x86, 0x75, 0x85, 0x73, 0x85, 0x73, 0x85, 0x72, 0x85, 0x72, 0x86, 0x71, - 0x87, 0x70, 0x87, 0x6f, 0x88, 0x6d, 0x88, 0x6e, 0x88, 0x6f, 0x88, 0x6f, - 0x88, 0x6e, 0x88, 0x6c, 0x89, 0x6b, 0x89, 0x69, 0x8a, 0x66, 0x8d, 0x5c, - 0x90, 0x58, 0x90, 0x5f, 0x92, 0x62, 0x92, 0x5f, 0x92, 0x5d, 0x94, 0x59, - 0x95, 0x55, 0x95, 0x51, 0x96, 0x49, 0x97, 0x46, 0x98, 0x4e, 0x97, 0x48, - 0x96, 0x54, 0x95, 0x58, 0x97, 0x54, 0x99, 0x46, 0x98, 0x41, 0x9a, 0x3f, - 0x9d, 0x3e, 0x98, 0x4a, 0x98, 0x3a, 0x90, 0x4b, 0x90, 0x4c, 0x92, 0x4a, - 0x88, 0x5d, 0x60, 0x85, 0x59, 0x88, 0x58, 0x84, 0x5a, 0x82, 0x5f, 0x82, - 0x66, 0x81, 0x66, 0x7d, 0x62, 0x74, 0x61, 0x73, 0x5d, 0x78, 0x5e, 0x7a, - 0x62, 0x7a, 0x64, 0x7b, 0x62, 0x78, 0x5f, 0x75, 0x62, 0x75, 0x70, 0x6d, - 0x8c, 0x4e, 0x91, 0x42, 0x91, 0x3f, 0x91, 0x3d, 0x91, 0x3e, 0x91, 0x3e, - 0x92, 0x3e, 0x92, 0x3e, 0x92, 0x3e, 0x93, 0x3e, 0x92, 0x3c, 0x91, 0x3c, - 0x90, 0x3c, 0x8e, 0x46, 0x89, 0x56, 0x89, 0x59, 0x8a, 0x57, 0x8c, 0x54, - 0x8e, 0x4e, 0x8f, 0x4d, 0x90, 0x4c, 0x8e, 0x4a, 0x90, 0x4b, 0x91, 0x49, - 0x91, 0x47, 0x91, 0x49, 0x90, 0x4c, 0x8f, 0x48, 0x92, 0x3f, 0x92, 0x3c, - 0x93, 0x41, 0x94, 0x46, 0x95, 0x44, 0x95, 0x41, 0x95, 0x3e, 0x96, 0x3d, - 0x97, 0x3c, 0x97, 0x3b, 0x98, 0x3c, 0x98, 0x3f, 0x97, 0x40, 0x97, 0x3f, - 0x97, 0x3c, 0x97, 0x3c, 0x97, 0x3c, 0x97, 0x3f, 0x52, 0x66, 0x50, 0x64, - 0x4e, 0x62, 0x4b, 0x61, 0x48, 0x61, 0x49, 0x62, 0x4b, 0x61, 0x4c, 0x62, - 0x4f, 0x62, 0x50, 0x61, 0x51, 0x5f, 0x51, 0x5e, 0x52, 0x5d, 0x52, 0x5d, - 0x53, 0x5b, 0x54, 0x5a, 0x54, 0x5a, 0x52, 0x5a, 0x51, 0x58, 0x56, 0x57, - 0x78, 0x66, 0x84, 0x73, 0x85, 0x75, 0x84, 0x74, 0x85, 0x75, 0x85, 0x77, - 0x85, 0x78, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, - 0x84, 0x78, 0x85, 0x78, 0x85, 0x78, 0x84, 0x78, 0x82, 0x79, 0x83, 0x7a, - 0x83, 0x7a, 0x83, 0x7a, 0x83, 0x7a, 0x83, 0x7a, 0x83, 0x79, 0x83, 0x78, - 0x83, 0x78, 0x85, 0x78, 0x85, 0x77, 0x85, 0x75, 0x85, 0x76, 0x86, 0x74, - 0x86, 0x73, 0x87, 0x73, 0x87, 0x73, 0x86, 0x74, 0x86, 0x75, 0x86, 0x74, - 0x86, 0x73, 0x86, 0x72, 0x86, 0x70, 0x86, 0x70, 0x87, 0x70, 0x87, 0x6f, - 0x88, 0x6e, 0x88, 0x6e, 0x88, 0x6d, 0x88, 0x6d, 0x88, 0x6f, 0x88, 0x6d, - 0x89, 0x6d, 0x89, 0x69, 0x89, 0x66, 0x8b, 0x62, 0x8e, 0x58, 0x8f, 0x58, - 0x91, 0x61, 0x93, 0x5f, 0x92, 0x5c, 0x93, 0x5b, 0x94, 0x58, 0x94, 0x57, - 0x95, 0x53, 0x96, 0x49, 0x97, 0x46, 0x96, 0x46, 0x97, 0x50, 0x95, 0x5a, - 0x95, 0x5c, 0x97, 0x53, 0x99, 0x41, 0x97, 0x43, 0x9c, 0x3c, 0x98, 0x4b, - 0x9a, 0x3f, 0x91, 0x4d, 0x8b, 0x58, 0x84, 0x61, 0x6b, 0x7e, 0x5b, 0x8b, - 0x5c, 0x88, 0x5a, 0x85, 0x5b, 0x84, 0x62, 0x84, 0x6c, 0x81, 0x67, 0x7b, - 0x5f, 0x74, 0x5f, 0x78, 0x5d, 0x7a, 0x61, 0x79, 0x63, 0x79, 0x63, 0x7b, - 0x63, 0x77, 0x5f, 0x74, 0x69, 0x71, 0x80, 0x5d, 0x91, 0x45, 0x91, 0x40, - 0x91, 0x3e, 0x91, 0x3d, 0x92, 0x3e, 0x92, 0x3e, 0x93, 0x3f, 0x93, 0x3e, - 0x94, 0x3c, 0x94, 0x3e, 0x92, 0x3d, 0x91, 0x3b, 0x91, 0x3d, 0x8d, 0x4b, - 0x89, 0x58, 0x88, 0x5b, 0x8b, 0x58, 0x8e, 0x52, 0x91, 0x48, 0x92, 0x40, - 0x94, 0x3d, 0x95, 0x3e, 0x95, 0x3e, 0x95, 0x3e, 0x95, 0x3d, 0x94, 0x40, - 0x93, 0x44, 0x91, 0x45, 0x92, 0x40, 0x93, 0x3d, 0x93, 0x40, 0x93, 0x44, - 0x93, 0x44, 0x95, 0x42, 0x96, 0x3d, 0x97, 0x3c, 0x97, 0x3a, 0x98, 0x3b, - 0x98, 0x3d, 0x97, 0x3f, 0x97, 0x40, 0x97, 0x42, 0x96, 0x41, 0x96, 0x40, - 0x97, 0x41, 0x97, 0x42, 0x4f, 0x65, 0x4f, 0x64, 0x4d, 0x62, 0x49, 0x62, - 0x47, 0x62, 0x49, 0x62, 0x4a, 0x60, 0x4c, 0x61, 0x4e, 0x63, 0x50, 0x61, - 0x51, 0x5f, 0x51, 0x5e, 0x52, 0x5c, 0x53, 0x5b, 0x53, 0x5b, 0x53, 0x59, - 0x53, 0x57, 0x52, 0x5a, 0x51, 0x57, 0x5d, 0x56, 0x81, 0x6d, 0x85, 0x73, - 0x86, 0x74, 0x84, 0x75, 0x85, 0x75, 0x85, 0x76, 0x85, 0x78, 0x85, 0x77, - 0x85, 0x77, 0x85, 0x77, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x85, 0x78, - 0x85, 0x7a, 0x84, 0x7a, 0x82, 0x7a, 0x83, 0x7a, 0x83, 0x7a, 0x83, 0x7a, - 0x83, 0x7a, 0x83, 0x7a, 0x83, 0x79, 0x83, 0x78, 0x84, 0x78, 0x85, 0x78, - 0x85, 0x78, 0x85, 0x77, 0x85, 0x77, 0x85, 0x75, 0x86, 0x73, 0x87, 0x72, - 0x87, 0x72, 0x88, 0x71, 0x88, 0x74, 0x88, 0x73, 0x88, 0x72, 0x88, 0x71, - 0x88, 0x71, 0x87, 0x70, 0x87, 0x6f, 0x87, 0x6f, 0x88, 0x6e, 0x88, 0x6d, - 0x88, 0x6c, 0x87, 0x6c, 0x88, 0x6f, 0x88, 0x6e, 0x89, 0x6d, 0x8a, 0x69, - 0x8a, 0x66, 0x8b, 0x63, 0x8c, 0x5c, 0x8d, 0x56, 0x91, 0x5d, 0x93, 0x5e, - 0x93, 0x5c, 0x92, 0x5b, 0x94, 0x58, 0x95, 0x56, 0x95, 0x55, 0x95, 0x4d, - 0x97, 0x45, 0x96, 0x45, 0x98, 0x4e, 0x96, 0x59, 0x95, 0x5d, 0x95, 0x59, - 0x98, 0x44, 0x96, 0x44, 0x9b, 0x3e, 0x9b, 0x47, 0x9a, 0x47, 0x91, 0x4e, - 0x78, 0x6a, 0x6d, 0x79, 0x5f, 0x88, 0x5c, 0x88, 0x5e, 0x88, 0x63, 0x88, - 0x64, 0x86, 0x65, 0x84, 0x6e, 0x80, 0x65, 0x7a, 0x5e, 0x76, 0x60, 0x79, - 0x5e, 0x7b, 0x62, 0x79, 0x63, 0x7b, 0x63, 0x7b, 0x63, 0x75, 0x61, 0x73, - 0x72, 0x68, 0x89, 0x53, 0x92, 0x43, 0x91, 0x3f, 0x90, 0x3e, 0x92, 0x3e, - 0x94, 0x3e, 0x94, 0x3f, 0x94, 0x40, 0x95, 0x3e, 0x95, 0x3c, 0x93, 0x40, - 0x91, 0x3f, 0x91, 0x3b, 0x91, 0x3e, 0x8c, 0x50, 0x89, 0x59, 0x88, 0x5c, - 0x8c, 0x55, 0x91, 0x4a, 0x95, 0x3f, 0x95, 0x3b, 0x96, 0x39, 0x97, 0x39, - 0x96, 0x3b, 0x95, 0x3c, 0x95, 0x3c, 0x96, 0x3b, 0x96, 0x3d, 0x95, 0x40, - 0x92, 0x42, 0x94, 0x43, 0x94, 0x41, 0x92, 0x41, 0x92, 0x44, 0x96, 0x42, - 0x98, 0x3d, 0x98, 0x39, 0x98, 0x39, 0x98, 0x3a, 0x98, 0x3b, 0x98, 0x3e, - 0x97, 0x41, 0x96, 0x44, 0x95, 0x43, 0x95, 0x42, 0x97, 0x42, 0x97, 0x43, - 0x4a, 0x63, 0x49, 0x63, 0x47, 0x61, 0x47, 0x61, 0x47, 0x62, 0x49, 0x62, - 0x4a, 0x60, 0x4c, 0x61, 0x4e, 0x62, 0x4f, 0x60, 0x51, 0x5f, 0x51, 0x5e, - 0x52, 0x5b, 0x53, 0x5b, 0x53, 0x5b, 0x53, 0x59, 0x53, 0x57, 0x52, 0x58, - 0x57, 0x57, 0x6f, 0x5d, 0x85, 0x71, 0x86, 0x73, 0x86, 0x74, 0x84, 0x76, - 0x84, 0x75, 0x84, 0x76, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, - 0x84, 0x78, 0x84, 0x78, 0x85, 0x78, 0x85, 0x78, 0x85, 0x7a, 0x85, 0x7a, - 0x82, 0x7a, 0x82, 0x7a, 0x82, 0x7a, 0x82, 0x7a, 0x82, 0x7a, 0x83, 0x7a, - 0x83, 0x79, 0x83, 0x78, 0x83, 0x78, 0x84, 0x78, 0x85, 0x77, 0x85, 0x77, - 0x85, 0x78, 0x85, 0x75, 0x86, 0x73, 0x87, 0x72, 0x87, 0x72, 0x88, 0x6f, - 0x88, 0x6e, 0x88, 0x6f, 0x88, 0x71, 0x88, 0x70, 0x88, 0x6f, 0x88, 0x6e, - 0x88, 0x6e, 0x87, 0x6d, 0x88, 0x6c, 0x88, 0x6c, 0x88, 0x6c, 0x88, 0x6c, - 0x88, 0x6c, 0x88, 0x6c, 0x89, 0x6b, 0x89, 0x6b, 0x8a, 0x68, 0x8a, 0x65, - 0x8b, 0x61, 0x8e, 0x5b, 0x8f, 0x55, 0x91, 0x59, 0x93, 0x5d, 0x92, 0x5b, - 0x94, 0x59, 0x95, 0x57, 0x95, 0x56, 0x95, 0x51, 0x97, 0x4a, 0x97, 0x44, - 0x95, 0x4a, 0x96, 0x52, 0x95, 0x5d, 0x95, 0x5c, 0x97, 0x48, 0x97, 0x43, - 0x99, 0x40, 0x9c, 0x40, 0x98, 0x4f, 0x8d, 0x4f, 0x63, 0x7e, 0x5b, 0x86, - 0x5b, 0x85, 0x5d, 0x88, 0x60, 0x89, 0x70, 0x89, 0x6f, 0x87, 0x69, 0x84, - 0x6b, 0x80, 0x63, 0x7a, 0x5f, 0x7b, 0x5c, 0x7c, 0x5d, 0x7c, 0x5f, 0x7d, - 0x61, 0x7f, 0x64, 0x7b, 0x64, 0x72, 0x66, 0x6e, 0x82, 0x57, 0x90, 0x49, - 0x93, 0x41, 0x93, 0x3e, 0x92, 0x3d, 0x94, 0x3e, 0x95, 0x3e, 0x95, 0x3e, - 0x94, 0x3e, 0x95, 0x3e, 0x94, 0x3d, 0x92, 0x42, 0x92, 0x44, 0x92, 0x40, - 0x8f, 0x44, 0x8c, 0x55, 0x8a, 0x5b, 0x8d, 0x54, 0x92, 0x45, 0x95, 0x3e, - 0x94, 0x3d, 0x93, 0x40, 0x94, 0x41, 0x95, 0x40, 0x95, 0x41, 0x95, 0x42, - 0x96, 0x42, 0x98, 0x3d, 0x98, 0x3a, 0x96, 0x3c, 0x94, 0x43, 0x94, 0x44, - 0x94, 0x41, 0x94, 0x3f, 0x94, 0x3f, 0x96, 0x3a, 0x98, 0x39, 0x98, 0x39, - 0x98, 0x3b, 0x97, 0x3c, 0x96, 0x3c, 0x96, 0x3f, 0x97, 0x42, 0x96, 0x42, - 0x95, 0x42, 0x96, 0x42, 0x97, 0x41, 0x97, 0x40, 0x45, 0x61, 0x45, 0x61, - 0x44, 0x5f, 0x46, 0x5f, 0x47, 0x61, 0x49, 0x62, 0x4b, 0x60, 0x4c, 0x62, - 0x4e, 0x62, 0x4f, 0x60, 0x51, 0x5f, 0x51, 0x5e, 0x52, 0x5b, 0x53, 0x5b, - 0x53, 0x5b, 0x53, 0x59, 0x53, 0x57, 0x53, 0x56, 0x61, 0x58, 0x7a, 0x66, - 0x86, 0x71, 0x86, 0x72, 0x86, 0x74, 0x84, 0x75, 0x84, 0x75, 0x84, 0x76, - 0x84, 0x78, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x84, 0x78, 0x84, 0x78, - 0x84, 0x78, 0x85, 0x78, 0x85, 0x7a, 0x85, 0x7a, 0x82, 0x7a, 0x83, 0x7a, - 0x82, 0x7a, 0x83, 0x7a, 0x83, 0x7a, 0x83, 0x7a, 0x82, 0x79, 0x82, 0x78, - 0x83, 0x78, 0x84, 0x78, 0x84, 0x78, 0x85, 0x77, 0x85, 0x77, 0x85, 0x75, - 0x85, 0x73, 0x87, 0x73, 0x87, 0x72, 0x88, 0x71, 0x88, 0x6f, 0x88, 0x6e, - 0x88, 0x6f, 0x88, 0x6e, 0x88, 0x6d, 0x89, 0x6d, 0x8a, 0x6c, 0x88, 0x6b, - 0x88, 0x6a, 0x88, 0x6c, 0x88, 0x6d, 0x88, 0x6c, 0x88, 0x6a, 0x88, 0x6b, - 0x89, 0x69, 0x89, 0x6c, 0x8a, 0x6a, 0x8a, 0x66, 0x8c, 0x61, 0x8e, 0x5f, - 0x8e, 0x55, 0x8f, 0x56, 0x92, 0x5c, 0x92, 0x5c, 0x93, 0x5a, 0x95, 0x58, - 0x96, 0x57, 0x95, 0x53, 0x96, 0x4d, 0x98, 0x44, 0x94, 0x45, 0x97, 0x4c, - 0x95, 0x5c, 0x95, 0x5f, 0x97, 0x4b, 0x97, 0x41, 0x97, 0x40, 0x9d, 0x39, - 0x97, 0x4f, 0x93, 0x4f, 0x66, 0x7f, 0x5b, 0x88, 0x59, 0x82, 0x5e, 0x87, - 0x5f, 0x8a, 0x68, 0x8b, 0x6b, 0x88, 0x66, 0x85, 0x67, 0x7f, 0x61, 0x7a, - 0x61, 0x7e, 0x5a, 0x7f, 0x5b, 0x7c, 0x5e, 0x80, 0x60, 0x82, 0x66, 0x7b, - 0x65, 0x6f, 0x6e, 0x67, 0x8b, 0x4e, 0x92, 0x45, 0x95, 0x3f, 0x95, 0x3d, - 0x94, 0x3d, 0x94, 0x3e, 0x94, 0x3e, 0x95, 0x3d, 0x94, 0x3c, 0x95, 0x3d, - 0x95, 0x3f, 0x93, 0x43, 0x92, 0x49, 0x92, 0x44, 0x8c, 0x4a, 0x8c, 0x58, - 0x8b, 0x58, 0x91, 0x48, 0x94, 0x3d, 0x93, 0x3f, 0x91, 0x43, 0x91, 0x43, - 0x93, 0x43, 0x94, 0x43, 0x94, 0x44, 0x95, 0x44, 0x96, 0x42, 0x99, 0x3e, - 0x99, 0x38, 0x98, 0x3a, 0x95, 0x42, 0x94, 0x44, 0x94, 0x41, 0x95, 0x3e, - 0x95, 0x3b, 0x97, 0x38, 0x98, 0x3b, 0x98, 0x3d, 0x98, 0x40, 0x97, 0x41, - 0x95, 0x42, 0x95, 0x44, 0x97, 0x43, 0x96, 0x41, 0x95, 0x42, 0x95, 0x42, - 0x97, 0x40, 0x97, 0x3f, 0x44, 0x60, 0x43, 0x5e, 0x44, 0x5d, 0x47, 0x5f, - 0x48, 0x60, 0x49, 0x61, 0x4c, 0x60, 0x4d, 0x62, 0x4f, 0x64, 0x50, 0x62, - 0x51, 0x61, 0x51, 0x5f, 0x52, 0x5c, 0x53, 0x5d, 0x53, 0x5d, 0x53, 0x57, - 0x53, 0x55, 0x54, 0x55, 0x6d, 0x5d, 0x83, 0x6c, 0x85, 0x71, 0x86, 0x74, - 0x85, 0x76, 0x85, 0x74, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x76, - 0x85, 0x77, 0x85, 0x77, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x85, 0x78, - 0x85, 0x78, 0x85, 0x78, 0x84, 0x78, 0x84, 0x79, 0x84, 0x79, 0x84, 0x78, - 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x85, 0x78, - 0x84, 0x78, 0x84, 0x78, 0x85, 0x78, 0x85, 0x77, 0x85, 0x76, 0x86, 0x75, - 0x86, 0x75, 0x86, 0x73, 0x86, 0x70, 0x87, 0x6f, 0x88, 0x6d, 0x88, 0x6c, - 0x88, 0x6c, 0x88, 0x6c, 0x89, 0x6b, 0x8a, 0x69, 0x8b, 0x6a, 0x88, 0x6a, - 0x89, 0x6c, 0x89, 0x6b, 0x8a, 0x6b, 0x8a, 0x6b, 0x89, 0x6a, 0x89, 0x6b, - 0x8a, 0x6b, 0x8b, 0x67, 0x8d, 0x63, 0x8e, 0x60, 0x8e, 0x59, 0x8f, 0x53, - 0x90, 0x59, 0x92, 0x5b, 0x94, 0x59, 0x95, 0x58, 0x94, 0x58, 0x95, 0x56, - 0x95, 0x51, 0x97, 0x47, 0x95, 0x43, 0x95, 0x4a, 0x96, 0x59, 0x94, 0x60, - 0x97, 0x4f, 0x96, 0x41, 0x99, 0x40, 0x9e, 0x39, 0x9a, 0x44, 0x97, 0x4f, - 0x73, 0x7b, 0x61, 0x8a, 0x5b, 0x81, 0x5e, 0x85, 0x5c, 0x89, 0x64, 0x8c, - 0x6e, 0x8c, 0x6a, 0x86, 0x63, 0x81, 0x60, 0x80, 0x5d, 0x81, 0x5a, 0x7f, - 0x5c, 0x7e, 0x5d, 0x82, 0x60, 0x81, 0x65, 0x78, 0x68, 0x6f, 0x77, 0x62, - 0x8f, 0x4a, 0x92, 0x44, 0x94, 0x3f, 0x95, 0x3e, 0x95, 0x3f, 0x94, 0x41, - 0x94, 0x40, 0x95, 0x3e, 0x94, 0x3d, 0x94, 0x3f, 0x93, 0x43, 0x90, 0x49, - 0x90, 0x4c, 0x90, 0x46, 0x8e, 0x4c, 0x8d, 0x55, 0x8f, 0x4f, 0x93, 0x40, - 0x92, 0x41, 0x92, 0x44, 0x93, 0x45, 0x94, 0x43, 0x95, 0x42, 0x96, 0x43, - 0x95, 0x45, 0x96, 0x44, 0x97, 0x41, 0x9a, 0x3c, 0x9a, 0x38, 0x9a, 0x38, - 0x99, 0x3f, 0x95, 0x45, 0x94, 0x40, 0x95, 0x3c, 0x96, 0x3c, 0x96, 0x3d, - 0x96, 0x40, 0x95, 0x42, 0x95, 0x44, 0x94, 0x44, 0x94, 0x45, 0x94, 0x46, - 0x96, 0x45, 0x96, 0x43, 0x97, 0x42, 0x97, 0x40, 0x98, 0x40, 0x98, 0x40, - 0x43, 0x60, 0x44, 0x5d, 0x46, 0x5c, 0x47, 0x5e, 0x49, 0x61, 0x4a, 0x61, - 0x4d, 0x60, 0x4e, 0x62, 0x50, 0x64, 0x51, 0x62, 0x51, 0x5f, 0x52, 0x5f, - 0x52, 0x5e, 0x53, 0x5d, 0x54, 0x5d, 0x53, 0x59, 0x53, 0x57, 0x58, 0x56, - 0x7b, 0x63, 0x87, 0x6f, 0x86, 0x72, 0x85, 0x74, 0x85, 0x75, 0x85, 0x75, - 0x86, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x76, 0x85, 0x77, 0x85, 0x77, - 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, - 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x85, 0x78, 0x84, 0x78, 0x84, 0x78, - 0x84, 0x78, 0x85, 0x78, 0x84, 0x78, 0x84, 0x78, 0x85, 0x78, 0x84, 0x78, - 0x84, 0x78, 0x85, 0x77, 0x84, 0x78, 0x85, 0x75, 0x85, 0x75, 0x86, 0x74, - 0x85, 0x72, 0x86, 0x70, 0x87, 0x6e, 0x87, 0x6d, 0x88, 0x6c, 0x89, 0x6c, - 0x8a, 0x6a, 0x8a, 0x68, 0x8b, 0x69, 0x8a, 0x69, 0x8a, 0x6a, 0x8a, 0x6a, - 0x8b, 0x6a, 0x8b, 0x6a, 0x8a, 0x6a, 0x8a, 0x6a, 0x8a, 0x69, 0x8b, 0x66, - 0x8d, 0x65, 0x8d, 0x61, 0x8f, 0x5b, 0x8f, 0x55, 0x90, 0x56, 0x92, 0x58, - 0x94, 0x58, 0x94, 0x58, 0x94, 0x58, 0x95, 0x57, 0x95, 0x54, 0x97, 0x4c, - 0x96, 0x44, 0x94, 0x46, 0x95, 0x54, 0x93, 0x5e, 0x97, 0x52, 0x95, 0x43, - 0x98, 0x3f, 0x9e, 0x3a, 0x9c, 0x3d, 0x98, 0x51, 0x80, 0x70, 0x6a, 0x85, - 0x61, 0x82, 0x60, 0x83, 0x5f, 0x86, 0x63, 0x89, 0x72, 0x8b, 0x72, 0x89, - 0x67, 0x8a, 0x5d, 0x8d, 0x56, 0x85, 0x5a, 0x80, 0x5f, 0x82, 0x61, 0x84, - 0x65, 0x80, 0x68, 0x77, 0x6f, 0x6a, 0x83, 0x57, 0x94, 0x46, 0x94, 0x42, - 0x94, 0x3f, 0x94, 0x3d, 0x94, 0x3e, 0x94, 0x42, 0x94, 0x42, 0x94, 0x40, - 0x94, 0x41, 0x93, 0x44, 0x90, 0x4a, 0x90, 0x4c, 0x8f, 0x4b, 0x90, 0x48, - 0x91, 0x4a, 0x91, 0x48, 0x94, 0x40, 0x91, 0x42, 0x91, 0x46, 0x92, 0x46, - 0x94, 0x44, 0x97, 0x41, 0x97, 0x40, 0x98, 0x41, 0x97, 0x43, 0x98, 0x42, - 0x99, 0x3f, 0x9a, 0x3c, 0x9a, 0x3b, 0x9a, 0x3a, 0x9a, 0x3c, 0x96, 0x43, - 0x96, 0x41, 0x96, 0x3a, 0x94, 0x3c, 0x94, 0x45, 0x94, 0x48, 0x93, 0x48, - 0x92, 0x47, 0x93, 0x47, 0x94, 0x46, 0x94, 0x46, 0x95, 0x45, 0x96, 0x43, - 0x97, 0x42, 0x97, 0x3f, 0x98, 0x3d, 0x98, 0x3d, 0x44, 0x60, 0x44, 0x5d, - 0x46, 0x5c, 0x48, 0x5e, 0x49, 0x61, 0x4c, 0x61, 0x4f, 0x60, 0x4f, 0x62, - 0x50, 0x63, 0x51, 0x62, 0x52, 0x5e, 0x52, 0x5e, 0x52, 0x5f, 0x53, 0x5d, - 0x53, 0x5d, 0x53, 0x5a, 0x52, 0x58, 0x5c, 0x59, 0x83, 0x67, 0x88, 0x6f, - 0x86, 0x71, 0x85, 0x74, 0x85, 0x75, 0x85, 0x75, 0x86, 0x75, 0x86, 0x75, - 0x85, 0x75, 0x85, 0x76, 0x84, 0x78, 0x84, 0x77, 0x85, 0x78, 0x84, 0x78, - 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, - 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x85, 0x78, 0x84, 0x77, 0x84, 0x78, - 0x84, 0x78, 0x85, 0x78, 0x85, 0x78, 0x84, 0x78, 0x84, 0x78, 0x85, 0x77, - 0x85, 0x77, 0x85, 0x75, 0x85, 0x75, 0x86, 0x76, 0x86, 0x73, 0x85, 0x72, - 0x85, 0x6f, 0x86, 0x6e, 0x88, 0x6d, 0x89, 0x6c, 0x8a, 0x6a, 0x89, 0x68, - 0x8a, 0x67, 0x8c, 0x68, 0x8a, 0x69, 0x8a, 0x68, 0x8b, 0x68, 0x8a, 0x68, - 0x8a, 0x6a, 0x89, 0x6a, 0x8a, 0x68, 0x8b, 0x65, 0x8d, 0x66, 0x8d, 0x62, - 0x8e, 0x5d, 0x8f, 0x58, 0x90, 0x53, 0x93, 0x54, 0x94, 0x58, 0x94, 0x58, - 0x94, 0x58, 0x95, 0x58, 0x95, 0x54, 0x97, 0x50, 0x96, 0x46, 0x94, 0x44, - 0x95, 0x50, 0x93, 0x5d, 0x97, 0x54, 0x94, 0x44, 0x97, 0x3f, 0x9c, 0x3b, - 0x9c, 0x40, 0x98, 0x50, 0x84, 0x66, 0x6c, 0x82, 0x64, 0x84, 0x63, 0x82, - 0x63, 0x83, 0x62, 0x86, 0x6c, 0x89, 0x72, 0x8c, 0x70, 0x91, 0x61, 0x96, - 0x56, 0x88, 0x5a, 0x80, 0x63, 0x85, 0x66, 0x87, 0x69, 0x81, 0x6b, 0x78, - 0x74, 0x65, 0x8a, 0x4f, 0x94, 0x45, 0x94, 0x42, 0x95, 0x3f, 0x93, 0x3c, - 0x94, 0x3d, 0x94, 0x40, 0x94, 0x3f, 0x94, 0x3d, 0x94, 0x3f, 0x93, 0x43, - 0x93, 0x46, 0x95, 0x44, 0x95, 0x40, 0x95, 0x40, 0x94, 0x40, 0x94, 0x40, - 0x94, 0x41, 0x91, 0x46, 0x92, 0x48, 0x92, 0x47, 0x95, 0x43, 0x98, 0x3f, - 0x99, 0x3e, 0x99, 0x40, 0x98, 0x42, 0x99, 0x40, 0x9b, 0x3d, 0x9b, 0x3c, - 0x9a, 0x3e, 0x9a, 0x3c, 0x99, 0x3a, 0x98, 0x3d, 0x98, 0x3d, 0x98, 0x3d, - 0x94, 0x42, 0x91, 0x48, 0x92, 0x4b, 0x92, 0x4b, 0x91, 0x4a, 0x92, 0x48, - 0x94, 0x47, 0x94, 0x47, 0x95, 0x45, 0x96, 0x43, 0x97, 0x42, 0x97, 0x3e, - 0x98, 0x3a, 0x98, 0x3a, 0x45, 0x61, 0x44, 0x60, 0x46, 0x60, 0x49, 0x5f, - 0x4b, 0x5f, 0x4e, 0x60, 0x50, 0x60, 0x51, 0x62, 0x52, 0x64, 0x53, 0x62, - 0x52, 0x5f, 0x51, 0x60, 0x51, 0x60, 0x52, 0x5f, 0x52, 0x5e, 0x50, 0x5c, - 0x51, 0x5c, 0x5f, 0x5c, 0x84, 0x6c, 0x88, 0x6f, 0x88, 0x70, 0x87, 0x73, - 0x86, 0x73, 0x87, 0x73, 0x87, 0x74, 0x86, 0x74, 0x86, 0x75, 0x85, 0x75, - 0x85, 0x78, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x84, 0x78, 0x84, 0x78, - 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x85, 0x79, 0x85, 0x78, - 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x78, 0x85, 0x78, 0x84, 0x77, - 0x84, 0x77, 0x84, 0x77, 0x83, 0x78, 0x86, 0x77, 0x86, 0x77, 0x85, 0x76, - 0x85, 0x76, 0x86, 0x76, 0x86, 0x75, 0x85, 0x73, 0x85, 0x72, 0x86, 0x71, - 0x87, 0x6e, 0x88, 0x6c, 0x89, 0x6b, 0x89, 0x69, 0x89, 0x67, 0x8c, 0x65, - 0x8b, 0x65, 0x89, 0x66, 0x89, 0x67, 0x8c, 0x66, 0x8c, 0x68, 0x8b, 0x69, - 0x8a, 0x68, 0x8a, 0x66, 0x8c, 0x65, 0x8d, 0x62, 0x8e, 0x5d, 0x8e, 0x5b, - 0x8e, 0x55, 0x91, 0x51, 0x93, 0x55, 0x93, 0x58, 0x93, 0x58, 0x94, 0x59, - 0x96, 0x55, 0x96, 0x52, 0x96, 0x4a, 0x95, 0x44, 0x96, 0x4b, 0x96, 0x5b, - 0x97, 0x54, 0x94, 0x45, 0x95, 0x41, 0x9c, 0x3c, 0x9d, 0x47, 0x99, 0x4f, - 0x8b, 0x5b, 0x71, 0x79, 0x67, 0x83, 0x67, 0x83, 0x65, 0x82, 0x64, 0x83, - 0x65, 0x87, 0x6f, 0x8e, 0x7a, 0x95, 0x68, 0x9a, 0x58, 0x8a, 0x59, 0x83, - 0x64, 0x86, 0x68, 0x87, 0x6b, 0x80, 0x6d, 0x75, 0x7d, 0x5d, 0x8f, 0x4a, - 0x92, 0x45, 0x93, 0x41, 0x94, 0x3e, 0x94, 0x3c, 0x95, 0x3c, 0x95, 0x3c, - 0x96, 0x3a, 0x96, 0x3b, 0x96, 0x3c, 0x96, 0x3d, 0x97, 0x3e, 0x98, 0x3c, - 0x99, 0x3a, 0x97, 0x39, 0x95, 0x3d, 0x93, 0x43, 0x91, 0x49, 0x91, 0x49, - 0x92, 0x48, 0x93, 0x47, 0x97, 0x43, 0x9a, 0x3f, 0x99, 0x3d, 0x99, 0x3f, - 0x99, 0x40, 0x99, 0x3f, 0x9a, 0x3d, 0x9a, 0x3f, 0x9a, 0x3e, 0x9a, 0x3b, - 0x9a, 0x3b, 0x9a, 0x3b, 0x9a, 0x3b, 0x98, 0x40, 0x94, 0x47, 0x91, 0x4a, - 0x91, 0x4c, 0x91, 0x4d, 0x92, 0x4c, 0x92, 0x4b, 0x92, 0x49, 0x93, 0x48, - 0x95, 0x46, 0x96, 0x42, 0x96, 0x3e, 0x97, 0x3c, 0x99, 0x39, 0x98, 0x36, - 0x47, 0x61, 0x45, 0x61, 0x47, 0x62, 0x49, 0x5f, 0x4c, 0x5f, 0x4f, 0x60, - 0x52, 0x5f, 0x53, 0x61, 0x53, 0x64, 0x54, 0x63, 0x53, 0x60, 0x51, 0x60, - 0x51, 0x60, 0x52, 0x5f, 0x51, 0x5f, 0x50, 0x5e, 0x51, 0x5d, 0x69, 0x5f, - 0x87, 0x6c, 0x88, 0x6e, 0x88, 0x6f, 0x87, 0x73, 0x87, 0x73, 0x87, 0x72, - 0x87, 0x73, 0x86, 0x74, 0x85, 0x74, 0x85, 0x75, 0x85, 0x77, 0x85, 0x77, - 0x85, 0x77, 0x85, 0x77, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x78, - 0x84, 0x78, 0x84, 0x78, 0x86, 0x78, 0x86, 0x78, 0x86, 0x77, 0x86, 0x77, - 0x86, 0x77, 0x85, 0x78, 0x85, 0x77, 0x85, 0x75, 0x85, 0x76, 0x85, 0x76, - 0x85, 0x76, 0x86, 0x76, 0x86, 0x75, 0x86, 0x75, 0x85, 0x75, 0x86, 0x75, - 0x86, 0x75, 0x85, 0x73, 0x85, 0x73, 0x86, 0x73, 0x87, 0x6f, 0x87, 0x6d, - 0x88, 0x6c, 0x89, 0x6a, 0x89, 0x68, 0x8b, 0x64, 0x8c, 0x61, 0x8b, 0x61, - 0x8b, 0x65, 0x8c, 0x66, 0x8c, 0x66, 0x8d, 0x66, 0x8c, 0x66, 0x8b, 0x66, - 0x8d, 0x64, 0x8c, 0x61, 0x8d, 0x5e, 0x8d, 0x5c, 0x8d, 0x59, 0x8f, 0x53, - 0x91, 0x51, 0x92, 0x55, 0x92, 0x57, 0x94, 0x58, 0x96, 0x56, 0x95, 0x53, - 0x95, 0x4c, 0x95, 0x44, 0x96, 0x48, 0x96, 0x57, 0x97, 0x54, 0x94, 0x45, - 0x94, 0x44, 0x9c, 0x3a, 0x9d, 0x44, 0x99, 0x52, 0x91, 0x56, 0x78, 0x70, - 0x69, 0x82, 0x67, 0x82, 0x64, 0x81, 0x64, 0x82, 0x65, 0x85, 0x70, 0x8f, - 0x7e, 0x95, 0x6f, 0x99, 0x5c, 0x8c, 0x5a, 0x85, 0x62, 0x85, 0x69, 0x85, - 0x6a, 0x7f, 0x6f, 0x70, 0x84, 0x57, 0x92, 0x48, 0x92, 0x43, 0x94, 0x41, - 0x94, 0x3e, 0x95, 0x3d, 0x96, 0x3c, 0x97, 0x3c, 0x97, 0x3c, 0x96, 0x3c, - 0x97, 0x3c, 0x97, 0x3d, 0x97, 0x3e, 0x97, 0x3d, 0x98, 0x3b, 0x95, 0x3d, - 0x94, 0x42, 0x91, 0x47, 0x91, 0x4a, 0x91, 0x4a, 0x93, 0x48, 0x95, 0x46, - 0x98, 0x41, 0x99, 0x3d, 0x99, 0x3d, 0x99, 0x3f, 0x99, 0x40, 0x99, 0x3e, - 0x99, 0x3d, 0x99, 0x40, 0x99, 0x3e, 0x9a, 0x3b, 0x9a, 0x3c, 0x9a, 0x3d, - 0x9a, 0x3c, 0x97, 0x3d, 0x95, 0x42, 0x93, 0x48, 0x92, 0x4b, 0x93, 0x4e, - 0x93, 0x4c, 0x93, 0x4b, 0x93, 0x48, 0x94, 0x46, 0x96, 0x42, 0x96, 0x3d, - 0x97, 0x3b, 0x98, 0x3a, 0x99, 0x39, 0x99, 0x38, 0x4a, 0x61, 0x48, 0x61, - 0x48, 0x61, 0x4c, 0x60, 0x4e, 0x5f, 0x52, 0x5f, 0x54, 0x60, 0x54, 0x61, - 0x55, 0x65, 0x56, 0x65, 0x54, 0x62, 0x51, 0x60, 0x51, 0x60, 0x51, 0x5f, - 0x51, 0x5f, 0x50, 0x60, 0x52, 0x5f, 0x70, 0x63, 0x87, 0x6b, 0x87, 0x6c, - 0x88, 0x70, 0x87, 0x73, 0x87, 0x73, 0x86, 0x73, 0x87, 0x73, 0x86, 0x74, - 0x85, 0x75, 0x85, 0x75, 0x85, 0x77, 0x85, 0x77, 0x84, 0x77, 0x85, 0x77, - 0x84, 0x79, 0x84, 0x79, 0x84, 0x79, 0x84, 0x79, 0x84, 0x78, 0x84, 0x78, - 0x85, 0x78, 0x86, 0x78, 0x85, 0x77, 0x85, 0x77, 0x85, 0x76, 0x85, 0x75, - 0x85, 0x75, 0x86, 0x74, 0x87, 0x74, 0x86, 0x73, 0x86, 0x74, 0x85, 0x74, - 0x86, 0x74, 0x85, 0x73, 0x86, 0x73, 0x85, 0x73, 0x85, 0x73, 0x85, 0x73, - 0x85, 0x73, 0x86, 0x73, 0x87, 0x71, 0x87, 0x6f, 0x87, 0x6e, 0x88, 0x6a, - 0x8a, 0x68, 0x8a, 0x66, 0x8c, 0x63, 0x8d, 0x5f, 0x8e, 0x62, 0x8c, 0x66, - 0x8c, 0x65, 0x8d, 0x65, 0x8d, 0x65, 0x8d, 0x65, 0x8d, 0x64, 0x8c, 0x61, - 0x8d, 0x5f, 0x8d, 0x5d, 0x8c, 0x5b, 0x8d, 0x57, 0x90, 0x4f, 0x93, 0x4f, - 0x92, 0x53, 0x94, 0x57, 0x95, 0x56, 0x95, 0x54, 0x95, 0x4c, 0x95, 0x43, - 0x96, 0x44, 0x96, 0x50, 0x97, 0x54, 0x94, 0x45, 0x92, 0x46, 0x9a, 0x3c, - 0x9d, 0x3d, 0x99, 0x53, 0x95, 0x55, 0x81, 0x67, 0x6a, 0x81, 0x66, 0x80, - 0x62, 0x80, 0x62, 0x81, 0x65, 0x85, 0x75, 0x8f, 0x82, 0x95, 0x79, 0x97, - 0x61, 0x8f, 0x5b, 0x86, 0x5f, 0x83, 0x6a, 0x81, 0x6b, 0x7b, 0x73, 0x69, - 0x8c, 0x50, 0x92, 0x45, 0x92, 0x41, 0x93, 0x41, 0x94, 0x3f, 0x95, 0x3e, - 0x95, 0x3e, 0x96, 0x3e, 0x97, 0x3e, 0x97, 0x3e, 0x97, 0x3e, 0x97, 0x3f, - 0x97, 0x3f, 0x97, 0x3e, 0x96, 0x3e, 0x94, 0x42, 0x93, 0x47, 0x90, 0x49, - 0x91, 0x4a, 0x92, 0x4a, 0x94, 0x47, 0x96, 0x44, 0x99, 0x3f, 0x99, 0x3b, - 0x99, 0x3c, 0x99, 0x3f, 0x99, 0x41, 0x99, 0x3e, 0x99, 0x3d, 0x99, 0x42, - 0x9a, 0x3f, 0x9a, 0x3d, 0x9a, 0x3d, 0x9a, 0x3e, 0x9a, 0x3e, 0x99, 0x3e, - 0x97, 0x3f, 0x95, 0x41, 0x95, 0x43, 0x95, 0x46, 0x95, 0x46, 0x96, 0x43, - 0x98, 0x40, 0x98, 0x3e, 0x97, 0x3b, 0x98, 0x39, 0x99, 0x39, 0x99, 0x39, - 0x99, 0x39, 0x99, 0x3b, 0x4d, 0x61, 0x4b, 0x61, 0x4a, 0x60, 0x4e, 0x60, - 0x51, 0x5f, 0x55, 0x5d, 0x57, 0x5e, 0x56, 0x61, 0x58, 0x64, 0x58, 0x65, - 0x55, 0x63, 0x53, 0x62, 0x53, 0x61, 0x52, 0x60, 0x51, 0x60, 0x51, 0x60, - 0x56, 0x5d, 0x78, 0x64, 0x88, 0x6c, 0x88, 0x6b, 0x89, 0x6f, 0x87, 0x71, - 0x87, 0x71, 0x87, 0x72, 0x87, 0x72, 0x87, 0x73, 0x86, 0x74, 0x86, 0x74, - 0x85, 0x76, 0x85, 0x76, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x84, 0x77, - 0x84, 0x77, 0x85, 0x77, 0x85, 0x78, 0x85, 0x79, 0x85, 0x78, 0x85, 0x78, - 0x85, 0x78, 0x85, 0x77, 0x85, 0x77, 0x86, 0x75, 0x86, 0x75, 0x87, 0x74, - 0x87, 0x74, 0x88, 0x73, 0x87, 0x73, 0x87, 0x73, 0x87, 0x72, 0x87, 0x71, - 0x87, 0x71, 0x87, 0x72, 0x87, 0x73, 0x87, 0x72, 0x86, 0x73, 0x87, 0x72, - 0x87, 0x71, 0x87, 0x70, 0x86, 0x6f, 0x87, 0x6e, 0x88, 0x6c, 0x88, 0x69, - 0x8a, 0x65, 0x8b, 0x61, 0x8d, 0x5f, 0x8d, 0x62, 0x8c, 0x64, 0x8e, 0x62, - 0x8e, 0x62, 0x8e, 0x63, 0x8d, 0x64, 0x8d, 0x62, 0x8d, 0x60, 0x8d, 0x5e, - 0x8d, 0x5b, 0x8d, 0x5a, 0x8f, 0x52, 0x92, 0x4c, 0x92, 0x50, 0x94, 0x56, - 0x95, 0x57, 0x95, 0x54, 0x95, 0x4e, 0x96, 0x44, 0x96, 0x42, 0x97, 0x4a, - 0x98, 0x52, 0x95, 0x46, 0x91, 0x48, 0x98, 0x41, 0x9c, 0x3d, 0x98, 0x4f, - 0x97, 0x5b, 0x89, 0x62, 0x69, 0x80, 0x63, 0x7f, 0x61, 0x7f, 0x62, 0x81, - 0x66, 0x86, 0x7b, 0x8f, 0x8a, 0x93, 0x86, 0x94, 0x6d, 0x91, 0x60, 0x88, - 0x5d, 0x81, 0x67, 0x7d, 0x68, 0x7a, 0x78, 0x64, 0x92, 0x4b, 0x92, 0x44, - 0x92, 0x42, 0x93, 0x41, 0x94, 0x40, 0x95, 0x40, 0x95, 0x41, 0x95, 0x40, - 0x95, 0x3f, 0x95, 0x3f, 0x95, 0x3e, 0x95, 0x40, 0x97, 0x3f, 0x97, 0x3d, - 0x96, 0x41, 0x93, 0x47, 0x91, 0x4a, 0x90, 0x4a, 0x91, 0x4a, 0x92, 0x48, - 0x96, 0x45, 0x97, 0x42, 0x99, 0x3d, 0x99, 0x3d, 0x99, 0x3c, 0x98, 0x3e, - 0x99, 0x40, 0x99, 0x40, 0x98, 0x41, 0x99, 0x44, 0x9a, 0x40, 0x9a, 0x3d, - 0x9a, 0x3e, 0x9b, 0x3e, 0x9a, 0x3f, 0x98, 0x42, 0x96, 0x44, 0x96, 0x41, - 0x97, 0x3e, 0x96, 0x3d, 0x97, 0x3c, 0x98, 0x3b, 0x99, 0x3a, 0x99, 0x39, - 0x99, 0x3a, 0x99, 0x3b, 0x98, 0x3c, 0x97, 0x3c, 0x98, 0x3d, 0x98, 0x3e, - 0x4f, 0x62, 0x4d, 0x62, 0x4c, 0x60, 0x50, 0x61, 0x53, 0x60, 0x57, 0x5d, - 0x59, 0x5e, 0x58, 0x61, 0x59, 0x63, 0x5a, 0x63, 0x56, 0x63, 0x55, 0x63, - 0x55, 0x60, 0x55, 0x61, 0x55, 0x60, 0x54, 0x5f, 0x5c, 0x5c, 0x81, 0x63, - 0x89, 0x6d, 0x89, 0x6c, 0x8a, 0x6e, 0x88, 0x70, 0x88, 0x70, 0x88, 0x71, - 0x88, 0x72, 0x87, 0x72, 0x87, 0x73, 0x87, 0x73, 0x85, 0x75, 0x85, 0x75, - 0x86, 0x78, 0x86, 0x77, 0x86, 0x77, 0x86, 0x77, 0x86, 0x77, 0x86, 0x77, - 0x86, 0x78, 0x86, 0x79, 0x85, 0x78, 0x84, 0x78, 0x84, 0x78, 0x84, 0x77, - 0x84, 0x77, 0x85, 0x77, 0x85, 0x76, 0x86, 0x76, 0x86, 0x75, 0x86, 0x74, - 0x87, 0x74, 0x88, 0x73, 0x88, 0x73, 0x88, 0x72, 0x88, 0x72, 0x88, 0x72, - 0x88, 0x72, 0x88, 0x72, 0x87, 0x72, 0x87, 0x71, 0x87, 0x70, 0x87, 0x70, - 0x87, 0x6f, 0x87, 0x70, 0x87, 0x6f, 0x87, 0x6b, 0x89, 0x66, 0x89, 0x64, - 0x8b, 0x5d, 0x8e, 0x5d, 0x8e, 0x60, 0x8d, 0x62, 0x8d, 0x61, 0x8d, 0x62, - 0x8d, 0x65, 0x8d, 0x63, 0x8e, 0x61, 0x8d, 0x5f, 0x8d, 0x5c, 0x8d, 0x5a, - 0x8e, 0x56, 0x90, 0x4e, 0x92, 0x4f, 0x94, 0x54, 0x95, 0x57, 0x95, 0x53, - 0x95, 0x50, 0x96, 0x47, 0x96, 0x41, 0x96, 0x46, 0x98, 0x50, 0x96, 0x46, - 0x91, 0x49, 0x96, 0x43, 0x9b, 0x43, 0x98, 0x4f, 0x98, 0x5d, 0x8c, 0x61, - 0x68, 0x7e, 0x63, 0x7e, 0x60, 0x7f, 0x60, 0x82, 0x67, 0x86, 0x7c, 0x8f, - 0x89, 0x92, 0x88, 0x93, 0x74, 0x90, 0x64, 0x88, 0x5e, 0x81, 0x61, 0x7c, - 0x63, 0x7a, 0x79, 0x62, 0x91, 0x49, 0x91, 0x45, 0x92, 0x44, 0x93, 0x43, - 0x94, 0x42, 0x94, 0x42, 0x95, 0x42, 0x95, 0x40, 0x95, 0x3f, 0x95, 0x3e, - 0x95, 0x3e, 0x95, 0x40, 0x96, 0x40, 0x96, 0x3f, 0x95, 0x44, 0x92, 0x49, - 0x92, 0x4b, 0x91, 0x4b, 0x91, 0x4a, 0x93, 0x47, 0x97, 0x44, 0x97, 0x41, - 0x98, 0x3f, 0x99, 0x43, 0x98, 0x3f, 0x98, 0x3e, 0x98, 0x40, 0x98, 0x40, - 0x98, 0x43, 0x99, 0x43, 0x9a, 0x3f, 0x9a, 0x3d, 0x9b, 0x3e, 0x9c, 0x3f, - 0x99, 0x41, 0x96, 0x46, 0x94, 0x49, 0x95, 0x48, 0x95, 0x44, 0x95, 0x42, - 0x96, 0x40, 0x96, 0x3f, 0x97, 0x3e, 0x97, 0x3e, 0x98, 0x3f, 0x97, 0x40, - 0x96, 0x41, 0x95, 0x41, 0x96, 0x41, 0x96, 0x43, 0x53, 0x62, 0x51, 0x62, - 0x4f, 0x61, 0x54, 0x61, 0x57, 0x60, 0x5b, 0x5d, 0x5c, 0x5e, 0x5a, 0x61, - 0x5c, 0x63, 0x5c, 0x64, 0x59, 0x63, 0x59, 0x62, 0x59, 0x60, 0x5b, 0x61, - 0x5b, 0x61, 0x5a, 0x60, 0x66, 0x5d, 0x87, 0x67, 0x89, 0x6d, 0x89, 0x6c, - 0x8a, 0x6f, 0x88, 0x71, 0x88, 0x70, 0x88, 0x71, 0x88, 0x72, 0x87, 0x73, - 0x87, 0x73, 0x86, 0x73, 0x85, 0x76, 0x85, 0x75, 0x85, 0x78, 0x85, 0x78, - 0x85, 0x78, 0x85, 0x77, 0x85, 0x78, 0x85, 0x78, 0x86, 0x78, 0x86, 0x78, - 0x84, 0x79, 0x84, 0x78, 0x84, 0x78, 0x84, 0x77, 0x84, 0x78, 0x83, 0x79, - 0x83, 0x78, 0x85, 0x78, 0x85, 0x77, 0x84, 0x76, 0x85, 0x76, 0x86, 0x75, - 0x86, 0x75, 0x86, 0x74, 0x86, 0x74, 0x86, 0x72, 0x86, 0x72, 0x86, 0x72, - 0x87, 0x72, 0x87, 0x71, 0x87, 0x71, 0x88, 0x71, 0x87, 0x6f, 0x87, 0x6f, - 0x87, 0x6f, 0x87, 0x6c, 0x87, 0x6b, 0x87, 0x69, 0x89, 0x63, 0x8b, 0x5e, - 0x8e, 0x5c, 0x8c, 0x5f, 0x8d, 0x60, 0x8d, 0x60, 0x8d, 0x62, 0x8e, 0x63, - 0x8d, 0x62, 0x8d, 0x5f, 0x8d, 0x5d, 0x8d, 0x5c, 0x8d, 0x59, 0x8e, 0x51, - 0x8f, 0x4e, 0x93, 0x4f, 0x94, 0x55, 0x95, 0x53, 0x95, 0x52, 0x96, 0x4c, - 0x96, 0x42, 0x95, 0x44, 0x98, 0x4d, 0x96, 0x46, 0x91, 0x49, 0x92, 0x47, - 0x9a, 0x43, 0x98, 0x4e, 0x9a, 0x55, 0x8d, 0x57, 0x68, 0x7c, 0x67, 0x7d, - 0x64, 0x7d, 0x64, 0x82, 0x6b, 0x88, 0x7c, 0x8f, 0x84, 0x92, 0x84, 0x93, - 0x76, 0x91, 0x68, 0x8a, 0x61, 0x7f, 0x5f, 0x7c, 0x60, 0x7a, 0x77, 0x63, - 0x8f, 0x4a, 0x91, 0x46, 0x92, 0x46, 0x93, 0x45, 0x94, 0x44, 0x94, 0x43, - 0x95, 0x42, 0x95, 0x41, 0x96, 0x41, 0x95, 0x40, 0x95, 0x40, 0x95, 0x41, - 0x94, 0x42, 0x94, 0x44, 0x93, 0x49, 0x90, 0x4a, 0x91, 0x4b, 0x91, 0x4b, - 0x93, 0x48, 0x95, 0x46, 0x97, 0x42, 0x98, 0x41, 0x97, 0x44, 0x97, 0x47, - 0x97, 0x40, 0x97, 0x3f, 0x97, 0x40, 0x97, 0x41, 0x98, 0x42, 0x99, 0x41, - 0x9a, 0x3e, 0x9a, 0x3e, 0x9b, 0x41, 0x9a, 0x43, 0x97, 0x45, 0x92, 0x4c, - 0x90, 0x4e, 0x90, 0x4f, 0x90, 0x4d, 0x91, 0x4d, 0x92, 0x4b, 0x92, 0x4a, - 0x93, 0x48, 0x93, 0x48, 0x93, 0x48, 0x94, 0x48, 0x94, 0x49, 0x95, 0x49, - 0x95, 0x49, 0x94, 0x4b, 0x55, 0x63, 0x53, 0x63, 0x51, 0x61, 0x56, 0x5f, - 0x59, 0x5f, 0x5e, 0x5d, 0x5e, 0x5e, 0x5a, 0x61, 0x5c, 0x63, 0x5c, 0x63, - 0x5b, 0x63, 0x5b, 0x61, 0x5c, 0x60, 0x5f, 0x61, 0x5f, 0x61, 0x5e, 0x5f, - 0x6d, 0x5e, 0x88, 0x69, 0x8a, 0x6c, 0x8a, 0x6c, 0x89, 0x6e, 0x89, 0x71, - 0x88, 0x70, 0x88, 0x71, 0x88, 0x72, 0x88, 0x73, 0x87, 0x74, 0x87, 0x73, - 0x86, 0x75, 0x86, 0x75, 0x85, 0x76, 0x86, 0x77, 0x85, 0x77, 0x85, 0x77, - 0x86, 0x77, 0x86, 0x77, 0x86, 0x77, 0x86, 0x77, 0x85, 0x78, 0x85, 0x77, - 0x85, 0x77, 0x85, 0x77, 0x84, 0x78, 0x83, 0x79, 0x83, 0x78, 0x84, 0x78, - 0x84, 0x78, 0x84, 0x77, 0x84, 0x76, 0x85, 0x75, 0x84, 0x75, 0x85, 0x74, - 0x85, 0x74, 0x85, 0x72, 0x85, 0x72, 0x86, 0x71, 0x87, 0x71, 0x87, 0x70, - 0x87, 0x70, 0x87, 0x6f, 0x87, 0x6f, 0x87, 0x6e, 0x87, 0x6d, 0x87, 0x6c, - 0x86, 0x6c, 0x86, 0x6c, 0x87, 0x69, 0x89, 0x64, 0x8b, 0x5e, 0x8e, 0x59, - 0x8e, 0x5b, 0x8e, 0x5e, 0x8f, 0x60, 0x8e, 0x64, 0x8d, 0x63, 0x8d, 0x5f, - 0x8e, 0x5e, 0x8e, 0x5d, 0x8d, 0x5b, 0x8d, 0x55, 0x8d, 0x4f, 0x92, 0x4c, - 0x95, 0x53, 0x95, 0x53, 0x95, 0x52, 0x96, 0x4f, 0x97, 0x43, 0x95, 0x42, - 0x98, 0x4b, 0x96, 0x45, 0x92, 0x49, 0x90, 0x49, 0x9a, 0x3f, 0x9b, 0x4a, - 0x9b, 0x4c, 0x8f, 0x4e, 0x68, 0x7a, 0x69, 0x7a, 0x69, 0x7a, 0x69, 0x83, - 0x6d, 0x88, 0x7d, 0x8f, 0x85, 0x93, 0x83, 0x93, 0x75, 0x91, 0x6a, 0x8a, - 0x64, 0x7e, 0x62, 0x7b, 0x62, 0x7b, 0x74, 0x69, 0x8e, 0x4c, 0x91, 0x48, - 0x92, 0x47, 0x92, 0x46, 0x93, 0x44, 0x95, 0x43, 0x96, 0x42, 0x95, 0x41, - 0x95, 0x42, 0x95, 0x42, 0x96, 0x42, 0x94, 0x43, 0x92, 0x45, 0x92, 0x47, - 0x91, 0x4b, 0x90, 0x4a, 0x90, 0x4b, 0x91, 0x4a, 0x93, 0x47, 0x97, 0x43, - 0x97, 0x3f, 0x97, 0x41, 0x97, 0x45, 0x96, 0x44, 0x96, 0x3f, 0x97, 0x41, - 0x97, 0x41, 0x98, 0x41, 0x98, 0x42, 0x9a, 0x3f, 0x9a, 0x3e, 0x99, 0x40, - 0x99, 0x43, 0x97, 0x46, 0x95, 0x49, 0x90, 0x50, 0x8e, 0x52, 0x8e, 0x51, - 0x8e, 0x51, 0x8f, 0x51, 0x8f, 0x50, 0x8f, 0x4f, 0x91, 0x4f, 0x91, 0x4e, - 0x91, 0x4d, 0x92, 0x4d, 0x93, 0x4e, 0x93, 0x4e, 0x93, 0x4e, 0x93, 0x50, - 0x56, 0x63, 0x54, 0x63, 0x54, 0x60, 0x59, 0x5d, 0x5c, 0x5c, 0x60, 0x5b, - 0x5f, 0x5c, 0x5b, 0x60, 0x5b, 0x63, 0x5c, 0x63, 0x5c, 0x62, 0x5d, 0x60, - 0x5d, 0x61, 0x60, 0x62, 0x62, 0x62, 0x60, 0x5f, 0x72, 0x60, 0x87, 0x68, - 0x8a, 0x6b, 0x89, 0x6b, 0x89, 0x6d, 0x89, 0x6f, 0x8a, 0x6f, 0x89, 0x70, - 0x88, 0x70, 0x88, 0x72, 0x88, 0x73, 0x88, 0x73, 0x88, 0x74, 0x88, 0x74, - 0x87, 0x75, 0x86, 0x75, 0x87, 0x75, 0x87, 0x75, 0x87, 0x76, 0x86, 0x76, - 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, - 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x76, - 0x85, 0x75, 0x85, 0x74, 0x85, 0x74, 0x85, 0x73, 0x85, 0x73, 0x86, 0x73, - 0x86, 0x73, 0x86, 0x71, 0x87, 0x70, 0x86, 0x70, 0x86, 0x70, 0x86, 0x6f, - 0x86, 0x6f, 0x87, 0x6f, 0x87, 0x6d, 0x87, 0x6b, 0x87, 0x6b, 0x87, 0x6b, - 0x87, 0x6b, 0x87, 0x68, 0x89, 0x64, 0x8c, 0x5c, 0x8e, 0x5a, 0x8f, 0x5c, - 0x91, 0x5d, 0x8f, 0x60, 0x8f, 0x62, 0x8f, 0x60, 0x8e, 0x5f, 0x8d, 0x5e, - 0x8d, 0x5c, 0x8d, 0x58, 0x8d, 0x54, 0x90, 0x4b, 0x94, 0x4e, 0x95, 0x51, - 0x96, 0x4f, 0x96, 0x4f, 0x97, 0x43, 0x98, 0x40, 0x98, 0x48, 0x96, 0x43, - 0x92, 0x48, 0x90, 0x4a, 0x99, 0x41, 0x9e, 0x40, 0x9b, 0x44, 0x92, 0x4b, - 0x6a, 0x7a, 0x68, 0x76, 0x6b, 0x77, 0x69, 0x81, 0x69, 0x85, 0x7d, 0x8f, - 0x85, 0x93, 0x84, 0x92, 0x75, 0x90, 0x66, 0x88, 0x63, 0x7f, 0x63, 0x7c, - 0x63, 0x7c, 0x6e, 0x6e, 0x8c, 0x4f, 0x91, 0x48, 0x91, 0x47, 0x92, 0x46, - 0x92, 0x45, 0x95, 0x43, 0x95, 0x42, 0x95, 0x42, 0x94, 0x43, 0x94, 0x43, - 0x95, 0x43, 0x94, 0x45, 0x91, 0x47, 0x91, 0x49, 0x91, 0x4b, 0x91, 0x4b, - 0x90, 0x4b, 0x92, 0x48, 0x93, 0x44, 0x98, 0x41, 0x98, 0x41, 0x98, 0x44, - 0x98, 0x44, 0x98, 0x40, 0x97, 0x40, 0x96, 0x42, 0x97, 0x41, 0x98, 0x41, - 0x98, 0x40, 0x9a, 0x40, 0x97, 0x42, 0x97, 0x44, 0x96, 0x48, 0x94, 0x4a, - 0x91, 0x4d, 0x8f, 0x52, 0x8f, 0x53, 0x8e, 0x53, 0x8e, 0x53, 0x8f, 0x52, - 0x8f, 0x51, 0x90, 0x51, 0x90, 0x51, 0x90, 0x50, 0x91, 0x50, 0x90, 0x50, - 0x90, 0x51, 0x90, 0x52, 0x90, 0x52, 0x90, 0x53, 0x56, 0x61, 0x54, 0x61, - 0x57, 0x60, 0x5b, 0x5c, 0x5e, 0x59, 0x61, 0x5a, 0x61, 0x5c, 0x5c, 0x61, - 0x5c, 0x64, 0x5c, 0x63, 0x5e, 0x62, 0x60, 0x60, 0x60, 0x61, 0x62, 0x62, - 0x63, 0x62, 0x63, 0x61, 0x79, 0x61, 0x89, 0x68, 0x8b, 0x6b, 0x89, 0x6b, - 0x89, 0x6e, 0x89, 0x6f, 0x89, 0x6f, 0x88, 0x70, 0x88, 0x70, 0x88, 0x71, - 0x88, 0x71, 0x88, 0x72, 0x88, 0x72, 0x88, 0x73, 0x86, 0x74, 0x87, 0x75, - 0x87, 0x76, 0x87, 0x75, 0x87, 0x76, 0x87, 0x75, 0x85, 0x76, 0x85, 0x75, - 0x85, 0x74, 0x85, 0x74, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, - 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x86, 0x75, - 0x86, 0x76, 0x85, 0x74, 0x85, 0x74, 0x84, 0x75, 0x85, 0x75, 0x84, 0x74, - 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x74, 0x85, 0x73, 0x85, 0x72, - 0x87, 0x71, 0x87, 0x6e, 0x87, 0x6b, 0x87, 0x6c, 0x87, 0x6c, 0x87, 0x6a, - 0x87, 0x6c, 0x8a, 0x67, 0x8b, 0x62, 0x8b, 0x5f, 0x8d, 0x5c, 0x8e, 0x5b, - 0x8f, 0x5d, 0x8f, 0x5e, 0x8d, 0x60, 0x8d, 0x5e, 0x8d, 0x5c, 0x8d, 0x59, - 0x8d, 0x57, 0x8e, 0x4e, 0x92, 0x49, 0x94, 0x4e, 0x95, 0x4e, 0x95, 0x4d, - 0x97, 0x43, 0x99, 0x3e, 0x99, 0x41, 0x96, 0x42, 0x93, 0x47, 0x90, 0x4b, - 0x95, 0x47, 0x9c, 0x3c, 0x9d, 0x40, 0x98, 0x47, 0x72, 0x75, 0x69, 0x76, - 0x6b, 0x75, 0x6b, 0x7d, 0x69, 0x82, 0x7b, 0x8d, 0x84, 0x91, 0x83, 0x90, - 0x74, 0x8e, 0x64, 0x87, 0x61, 0x81, 0x64, 0x7e, 0x66, 0x7e, 0x6c, 0x73, - 0x8a, 0x53, 0x91, 0x4a, 0x91, 0x48, 0x92, 0x49, 0x93, 0x47, 0x93, 0x44, - 0x93, 0x44, 0x94, 0x44, 0x94, 0x44, 0x94, 0x45, 0x92, 0x45, 0x93, 0x48, - 0x91, 0x49, 0x91, 0x4b, 0x91, 0x4c, 0x91, 0x4c, 0x91, 0x4a, 0x94, 0x46, - 0x97, 0x42, 0x99, 0x41, 0x98, 0x45, 0x98, 0x45, 0x98, 0x42, 0x98, 0x40, - 0x97, 0x42, 0x96, 0x43, 0x97, 0x43, 0x98, 0x42, 0x98, 0x42, 0x96, 0x45, - 0x93, 0x49, 0x93, 0x4b, 0x93, 0x4e, 0x92, 0x4f, 0x8f, 0x51, 0x8f, 0x54, - 0x8e, 0x54, 0x8e, 0x55, 0x8e, 0x54, 0x8f, 0x52, 0x90, 0x51, 0x90, 0x51, - 0x90, 0x52, 0x8f, 0x52, 0x90, 0x53, 0x8f, 0x55, 0x8e, 0x55, 0x8e, 0x56, - 0x8e, 0x57, 0x8d, 0x57, 0x55, 0x61, 0x55, 0x5f, 0x58, 0x5e, 0x5c, 0x5d, - 0x5f, 0x5b, 0x62, 0x5c, 0x63, 0x5c, 0x5e, 0x60, 0x5f, 0x64, 0x5e, 0x63, - 0x60, 0x62, 0x63, 0x60, 0x62, 0x61, 0x63, 0x62, 0x65, 0x62, 0x65, 0x62, - 0x7d, 0x62, 0x8a, 0x68, 0x8a, 0x6b, 0x89, 0x6b, 0x89, 0x6d, 0x89, 0x6f, - 0x89, 0x6f, 0x89, 0x70, 0x88, 0x70, 0x88, 0x70, 0x88, 0x6f, 0x88, 0x70, - 0x88, 0x71, 0x88, 0x72, 0x87, 0x74, 0x87, 0x74, 0x87, 0x75, 0x87, 0x76, - 0x87, 0x76, 0x87, 0x75, 0x85, 0x76, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, - 0x85, 0x75, 0x86, 0x75, 0x86, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, - 0x85, 0x76, 0x85, 0x75, 0x86, 0x76, 0x86, 0x78, 0x86, 0x78, 0x85, 0x76, - 0x85, 0x76, 0x83, 0x76, 0x83, 0x76, 0x83, 0x76, 0x84, 0x77, 0x84, 0x77, - 0x84, 0x77, 0x84, 0x76, 0x84, 0x75, 0x85, 0x74, 0x87, 0x73, 0x87, 0x71, - 0x87, 0x70, 0x87, 0x70, 0x87, 0x6e, 0x87, 0x6c, 0x86, 0x6c, 0x88, 0x6b, - 0x89, 0x69, 0x88, 0x64, 0x8a, 0x60, 0x8d, 0x5d, 0x8f, 0x5a, 0x8f, 0x5d, - 0x8e, 0x5f, 0x8d, 0x5e, 0x8d, 0x5b, 0x8e, 0x58, 0x8e, 0x58, 0x8e, 0x54, - 0x90, 0x49, 0x94, 0x4a, 0x95, 0x4c, 0x95, 0x4b, 0x98, 0x42, 0x99, 0x3c, - 0x99, 0x3e, 0x95, 0x41, 0x92, 0x47, 0x90, 0x4b, 0x93, 0x49, 0x9a, 0x3f, - 0x9e, 0x3e, 0x9c, 0x43, 0x7a, 0x72, 0x6e, 0x77, 0x6d, 0x73, 0x6b, 0x7a, - 0x68, 0x80, 0x7a, 0x8c, 0x83, 0x8f, 0x83, 0x8e, 0x76, 0x8c, 0x68, 0x86, - 0x63, 0x81, 0x64, 0x7f, 0x68, 0x7f, 0x6b, 0x75, 0x89, 0x55, 0x91, 0x4b, - 0x91, 0x4a, 0x92, 0x4a, 0x92, 0x48, 0x92, 0x46, 0x92, 0x46, 0x93, 0x46, - 0x94, 0x45, 0x93, 0x46, 0x91, 0x47, 0x92, 0x49, 0x91, 0x4a, 0x91, 0x4c, - 0x91, 0x4c, 0x91, 0x4b, 0x93, 0x49, 0x96, 0x44, 0x9a, 0x41, 0x99, 0x42, - 0x99, 0x43, 0x99, 0x41, 0x98, 0x40, 0x98, 0x41, 0x97, 0x44, 0x96, 0x45, - 0x97, 0x45, 0x98, 0x46, 0x96, 0x48, 0x93, 0x4a, 0x91, 0x4e, 0x90, 0x50, - 0x90, 0x52, 0x90, 0x52, 0x8e, 0x53, 0x8f, 0x55, 0x8e, 0x55, 0x8e, 0x55, - 0x8e, 0x53, 0x8f, 0x52, 0x90, 0x51, 0x90, 0x51, 0x90, 0x52, 0x8f, 0x54, - 0x8e, 0x56, 0x8d, 0x57, 0x8d, 0x58, 0x8c, 0x58, 0x8c, 0x59, 0x8c, 0x5a, - 0x54, 0x62, 0x58, 0x5d, 0x5b, 0x5b, 0x5f, 0x5b, 0x62, 0x5c, 0x64, 0x5d, - 0x63, 0x5d, 0x5f, 0x5f, 0x61, 0x64, 0x62, 0x63, 0x63, 0x62, 0x64, 0x61, - 0x63, 0x62, 0x64, 0x63, 0x66, 0x63, 0x67, 0x62, 0x82, 0x64, 0x8b, 0x69, - 0x8a, 0x6a, 0x8a, 0x6a, 0x8a, 0x6b, 0x89, 0x6e, 0x89, 0x6f, 0x89, 0x6f, - 0x89, 0x6f, 0x8a, 0x6f, 0x8a, 0x6f, 0x8a, 0x70, 0x89, 0x70, 0x89, 0x71, - 0x88, 0x73, 0x88, 0x73, 0x86, 0x74, 0x87, 0x75, 0x87, 0x75, 0x87, 0x74, - 0x87, 0x76, 0x87, 0x75, 0x86, 0x77, 0x86, 0x77, 0x86, 0x77, 0x86, 0x77, - 0x86, 0x77, 0x85, 0x77, 0x85, 0x77, 0x84, 0x77, 0x84, 0x77, 0x85, 0x77, - 0x85, 0x78, 0x85, 0x78, 0x85, 0x78, 0x84, 0x77, 0x84, 0x77, 0x84, 0x77, - 0x84, 0x78, 0x85, 0x76, 0x86, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, - 0x85, 0x75, 0x85, 0x74, 0x85, 0x73, 0x85, 0x73, 0x85, 0x73, 0x86, 0x73, - 0x87, 0x70, 0x87, 0x70, 0x87, 0x6e, 0x87, 0x6d, 0x87, 0x6c, 0x87, 0x68, - 0x89, 0x68, 0x8a, 0x62, 0x8c, 0x5b, 0x8f, 0x5b, 0x8f, 0x5d, 0x8f, 0x5e, - 0x8f, 0x5d, 0x8f, 0x5a, 0x8f, 0x59, 0x8d, 0x57, 0x8e, 0x4d, 0x95, 0x48, - 0x95, 0x49, 0x96, 0x49, 0x99, 0x3f, 0x99, 0x3b, 0x9a, 0x3c, 0x93, 0x43, - 0x91, 0x48, 0x91, 0x4b, 0x92, 0x4a, 0x99, 0x42, 0x9d, 0x3f, 0x9b, 0x41, - 0x81, 0x6f, 0x72, 0x7c, 0x70, 0x75, 0x6d, 0x76, 0x6b, 0x7b, 0x79, 0x88, - 0x83, 0x8f, 0x83, 0x8d, 0x7b, 0x8b, 0x6e, 0x85, 0x67, 0x7d, 0x66, 0x7f, - 0x68, 0x7e, 0x67, 0x76, 0x86, 0x55, 0x90, 0x4d, 0x90, 0x4c, 0x91, 0x4b, - 0x91, 0x47, 0x91, 0x47, 0x91, 0x48, 0x92, 0x46, 0x93, 0x47, 0x91, 0x47, - 0x8f, 0x49, 0x90, 0x4a, 0x90, 0x4b, 0x90, 0x4c, 0x90, 0x4c, 0x91, 0x4a, - 0x94, 0x47, 0x98, 0x43, 0x9a, 0x40, 0x9a, 0x41, 0x9c, 0x40, 0x9a, 0x3f, - 0x98, 0x43, 0x96, 0x46, 0x94, 0x48, 0x94, 0x49, 0x93, 0x4a, 0x92, 0x4d, - 0x91, 0x4f, 0x8f, 0x51, 0x8e, 0x54, 0x8d, 0x55, 0x8f, 0x53, 0x8e, 0x52, - 0x8e, 0x53, 0x8f, 0x56, 0x8e, 0x56, 0x8f, 0x55, 0x8f, 0x52, 0x90, 0x51, - 0x90, 0x51, 0x90, 0x51, 0x90, 0x54, 0x8e, 0x56, 0x8e, 0x58, 0x8c, 0x5a, - 0x8a, 0x5a, 0x8b, 0x5b, 0x8c, 0x5c, 0x8c, 0x5b, 0x56, 0x61, 0x5a, 0x5c, - 0x5d, 0x5b, 0x61, 0x5b, 0x63, 0x5c, 0x64, 0x5d, 0x64, 0x5d, 0x60, 0x5f, - 0x63, 0x64, 0x64, 0x64, 0x63, 0x62, 0x64, 0x62, 0x64, 0x62, 0x64, 0x63, - 0x66, 0x63, 0x6a, 0x62, 0x86, 0x65, 0x8b, 0x6a, 0x8a, 0x69, 0x8a, 0x6a, - 0x8a, 0x6b, 0x8a, 0x6d, 0x8a, 0x6e, 0x89, 0x6e, 0x8a, 0x6f, 0x89, 0x6f, - 0x89, 0x6f, 0x8a, 0x70, 0x8a, 0x71, 0x8a, 0x71, 0x88, 0x73, 0x87, 0x72, - 0x86, 0x74, 0x87, 0x75, 0x87, 0x74, 0x87, 0x75, 0x87, 0x75, 0x87, 0x75, - 0x85, 0x77, 0x85, 0x77, 0x86, 0x78, 0x86, 0x78, 0x85, 0x77, 0x85, 0x77, - 0x85, 0x77, 0x84, 0x78, 0x84, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, - 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x76, - 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x85, 0x75, 0x86, 0x73, - 0x85, 0x72, 0x85, 0x72, 0x85, 0x73, 0x86, 0x73, 0x87, 0x70, 0x87, 0x70, - 0x87, 0x6f, 0x87, 0x6f, 0x87, 0x6f, 0x87, 0x6c, 0x88, 0x6c, 0x88, 0x69, - 0x89, 0x64, 0x8b, 0x5e, 0x8e, 0x5c, 0x8f, 0x5e, 0x8f, 0x5d, 0x8f, 0x5b, - 0x8f, 0x5a, 0x8e, 0x57, 0x8c, 0x52, 0x91, 0x47, 0x95, 0x45, 0x97, 0x46, - 0x9a, 0x3c, 0x9a, 0x3b, 0x9a, 0x3b, 0x93, 0x43, 0x90, 0x48, 0x91, 0x4b, - 0x92, 0x4a, 0x98, 0x42, 0x9c, 0x42, 0x9b, 0x3f, 0x85, 0x6a, 0x76, 0x7e, - 0x74, 0x79, 0x71, 0x77, 0x70, 0x79, 0x78, 0x84, 0x82, 0x8d, 0x83, 0x8b, - 0x7d, 0x89, 0x73, 0x87, 0x6a, 0x7c, 0x68, 0x7c, 0x66, 0x7e, 0x64, 0x78, - 0x84, 0x57, 0x8f, 0x4d, 0x90, 0x4d, 0x91, 0x4c, 0x92, 0x48, 0x91, 0x48, - 0x91, 0x48, 0x91, 0x48, 0x91, 0x48, 0x90, 0x48, 0x8f, 0x4a, 0x8f, 0x4c, - 0x8f, 0x4c, 0x90, 0x4c, 0x90, 0x4c, 0x92, 0x4a, 0x95, 0x46, 0x98, 0x42, - 0x99, 0x3e, 0x99, 0x3f, 0x99, 0x41, 0x97, 0x44, 0x95, 0x47, 0x93, 0x49, - 0x91, 0x4c, 0x90, 0x4e, 0x90, 0x4f, 0x8e, 0x51, 0x8e, 0x55, 0x8d, 0x58, - 0x8d, 0x57, 0x8d, 0x55, 0x8f, 0x52, 0x8e, 0x51, 0x8f, 0x53, 0x8e, 0x56, - 0x8e, 0x56, 0x8f, 0x54, 0x90, 0x52, 0x8f, 0x52, 0x90, 0x52, 0x90, 0x52, - 0x8e, 0x55, 0x8c, 0x57, 0x8c, 0x59, 0x8c, 0x5b, 0x8a, 0x5b, 0x8a, 0x5c, - 0x8c, 0x5c, 0x8c, 0x5c, 0x58, 0x60, 0x5c, 0x5b, 0x5f, 0x5b, 0x62, 0x5b, - 0x64, 0x5c, 0x64, 0x5d, 0x64, 0x5d, 0x5f, 0x5f, 0x63, 0x64, 0x65, 0x64, - 0x63, 0x62, 0x63, 0x62, 0x63, 0x62, 0x64, 0x63, 0x65, 0x63, 0x6c, 0x62, - 0x86, 0x66, 0x8a, 0x6a, 0x8a, 0x6a, 0x8a, 0x6a, 0x8a, 0x6b, 0x89, 0x6c, - 0x89, 0x6c, 0x89, 0x6e, 0x89, 0x6f, 0x89, 0x6f, 0x89, 0x6f, 0x8a, 0x6f, - 0x8a, 0x70, 0x8a, 0x71, 0x88, 0x72, 0x88, 0x72, 0x87, 0x74, 0x87, 0x75, - 0x87, 0x75, 0x87, 0x75, 0x87, 0x75, 0x87, 0x75, 0x85, 0x77, 0x85, 0x77, - 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x84, 0x77, - 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, - 0x85, 0x77, 0x85, 0x77, 0x85, 0x77, 0x85, 0x76, 0x85, 0x75, 0x85, 0x75, - 0x85, 0x75, 0x85, 0x75, 0x86, 0x75, 0x86, 0x74, 0x85, 0x72, 0x86, 0x72, - 0x85, 0x72, 0x85, 0x72, 0x87, 0x70, 0x87, 0x70, 0x87, 0x71, 0x87, 0x71, - 0x87, 0x71, 0x87, 0x6f, 0x87, 0x6c, 0x86, 0x6a, 0x87, 0x69, 0x89, 0x68, - 0x8d, 0x60, 0x8f, 0x5d, 0x8f, 0x5d, 0x8f, 0x5b, 0x8f, 0x59, 0x8e, 0x57, - 0x8a, 0x57, 0x8e, 0x4a, 0x95, 0x41, 0x99, 0x3f, 0x9a, 0x3b, 0x9a, 0x3c, - 0x9a, 0x3b, 0x93, 0x44, 0x91, 0x4a, 0x91, 0x4b, 0x92, 0x4a, 0x98, 0x42, - 0x9c, 0x3f, 0x9b, 0x3f, 0x87, 0x63, 0x7a, 0x7a, 0x79, 0x7b, 0x76, 0x78, - 0x74, 0x78, 0x77, 0x80, 0x82, 0x8c, 0x83, 0x8a, 0x7f, 0x88, 0x77, 0x88, - 0x6c, 0x7c, 0x6a, 0x79, 0x63, 0x7e, 0x63, 0x79, 0x83, 0x58, 0x8f, 0x4d, - 0x90, 0x4c, 0x91, 0x4c, 0x92, 0x4a, 0x91, 0x49, 0x91, 0x4a, 0x90, 0x4a, - 0x8f, 0x49, 0x8f, 0x4a, 0x8f, 0x4c, 0x8f, 0x4d, 0x8f, 0x4d, 0x8f, 0x4c, - 0x90, 0x4c, 0x92, 0x4a, 0x95, 0x44, 0x97, 0x41, 0x97, 0x41, 0x97, 0x42, - 0x96, 0x45, 0x95, 0x49, 0x92, 0x4c, 0x90, 0x4e, 0x8f, 0x50, 0x8e, 0x52, - 0x8d, 0x53, 0x8b, 0x55, 0x8c, 0x58, 0x8b, 0x59, 0x8c, 0x56, 0x8d, 0x55, - 0x8f, 0x52, 0x8e, 0x52, 0x8f, 0x54, 0x8e, 0x57, 0x8e, 0x56, 0x8f, 0x54, - 0x8f, 0x53, 0x90, 0x53, 0x90, 0x53, 0x8f, 0x54, 0x8d, 0x57, 0x8a, 0x59, - 0x89, 0x5a, 0x8a, 0x5c, 0x8a, 0x5c, 0x8b, 0x5c, 0x8c, 0x5c, 0x8c, 0x5c -}; -unsigned int test_d3d9_nv12_yuv_len = 153600; diff --git a/tests/d3d9/test_d3d9_triangle.cpp b/tests/d3d9/test_d3d9_triangle.cpp deleted file mode 100644 index 5a1bb4a2d..000000000 --- a/tests/d3d9/test_d3d9_triangle.cpp +++ /dev/null @@ -1,529 +0,0 @@ -#include - -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -struct Extent2D { - uint32_t w, h; -}; - -const std::string g_vertexShaderCode = R"( - -struct VS_INPUT { - float3 Position : POSITION; -}; - -struct VS_OUTPUT { - float4 Position : POSITION; -}; - -VS_OUTPUT main( VS_INPUT IN ) { - VS_OUTPUT OUT; - OUT.Position = float4(IN.Position, 0.6f); - - return OUT; -} - -)"; - -const std::string g_pixelShaderCode = R"( - -struct VS_OUTPUT { - float4 Position : POSITION; -}; - -struct PS_OUTPUT { - float4 Colour : COLOR; -}; - -sampler g_texDepth : register( s0 ); - -PS_OUTPUT main( VS_OUTPUT IN ) { - PS_OUTPUT OUT; - - OUT.Colour = tex2D(g_texDepth, float2(0, 0)); - OUT.Colour = 1.0; - - return OUT; -} - - -)"; - -Logger Logger::s_instance("triangle.log"); - -class TriangleApp { - -public: - - TriangleApp(HINSTANCE instance, HWND window) - : m_window(window) { - HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 interface"); - - UINT adapter = D3DADAPTER_DEFAULT; - - D3DADAPTER_IDENTIFIER9 adapterId; - m_d3d->GetAdapterIdentifier(adapter, 0, &adapterId); - - Logger::info(str::format("Using adapter: ", adapterId.Description)); - - auto CheckSRGBFormat = [&](D3DFORMAT fmt, const char* name) { - HRESULT status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt); - Logger::warn(str::format("(linear) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope")); - - status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, fmt); - Logger::warn(str::format("(srgb) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope")); - }; - - CheckSRGBFormat(D3DFMT_R5G6B5, "R5G6B5"); - CheckSRGBFormat(D3DFMT_X1R5G5B5, "X1R5G5B5"); - CheckSRGBFormat(D3DFMT_A1R5G5B5, "A1R5G5B5"); - CheckSRGBFormat(D3DFMT_A4R4G4B4, "A4R4G4B4"); - CheckSRGBFormat(D3DFMT_X4R4G4B4, "X4R4G4B4"); - CheckSRGBFormat(D3DFMT_G16R16, "G16R16"); - CheckSRGBFormat(D3DFMT_A2R10G10B10, "A2R10G10B10"); - CheckSRGBFormat(D3DFMT_A16B16G16R16, "A16B16G16R16"); - - // - - DWORD quality; - status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_D24S8); - status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8); - status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8); - status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality); - status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality); - status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE); - status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE); - - // NULL - constexpr D3DFORMAT NullFormat = D3DFORMAT(MAKEFOURCC('N', 'U', 'L', 'L')); - - status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, D3DFMT_D24S8); - status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, NullFormat); - status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, NullFormat); - status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat); - status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, false); - status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, true); - // - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - - status = m_d3d->CreateDeviceEx( - adapter, - D3DDEVTYPE_HAL, - m_window, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - ¶ms, - nullptr, - &m_device); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 device"); - - // Funny Swapchain Refcounting - // "One of the things COM does really well, is lifecycle management" - // Implicit Swapchain - { - IDirect3DSurface9* pSurface1 = nullptr; - IDirect3DSurface9* pSurface2 = nullptr; - status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface1); - D3DPRESENT_PARAMETERS newParams = params; - newParams.BackBufferWidth = 10; - newParams.BackBufferHeight = 10; - status = m_device->Reset(&newParams); - status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface2); - - IDirect3DSwapChain9* pSwapChain2 = nullptr; - IDirect3DSwapChain9* pSwapChain3 = nullptr; - status = pSurface1->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast(&pSwapChain2)); - status = pSurface2->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast(&pSwapChain3)); - - printf("E_NOINTERFACE! for pSwapchain2"); - status = m_device->Reset(¶ms); - } - // Additional swapchain - { - IDirect3DSwapChain9* pSwapChain2 = nullptr; - IDirect3DSwapChain9* pSwapChain3 = nullptr; - IDirect3DSwapChain9* pSwapChain4 = nullptr; - IDirect3DSurface9* pSurface = nullptr; - status = m_device->CreateAdditionalSwapChain(¶ms, &pSwapChain2); - status = pSwapChain2->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface); - status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast(&pSwapChain3)); - pSwapChain2->Release(); - UINT count = pSwapChain2->Release(); - printf("Count: %u - Should be 0 and swapchain dead!", count); - status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast(&pSwapChain4)); - // E_NOINTERFACE ! - printf("E_NOINTERFACE!"); - } - - m_device->AddRef(); - - Com backbuffer; - m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); - - m_device->AddRef(); - - Com swapchain; - m_device->GetSwapChain(0, &swapchain); - - m_device->AddRef(); - - DWORD bias = 0xDEADBEEF; - status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias); - status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '4')); - status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias); - status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '1')); - status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias); - - // Vertex Shader - { - Com blob; - - status = D3DCompile( - g_vertexShaderCode.data(), - g_vertexShaderCode.length(), - nullptr, nullptr, nullptr, - "main", - "vs_2_0", - 0, 0, &blob, - nullptr); - - if (FAILED(status)) - throw DxvkError("Failed to compile vertex shader"); - - status = m_device->CreateVertexShader(reinterpret_cast(blob->GetBufferPointer()), &m_vs); - - if (FAILED(status)) - throw DxvkError("Failed to create vertex shader"); - } - - // Pixel Shader - { - Com blob; - - status = D3DCompile( - g_pixelShaderCode.data(), - g_pixelShaderCode.length(), - nullptr, nullptr, nullptr, - "main", - "ps_2_0", - 0, 0, &blob, - nullptr); - - if (FAILED(status)) - throw DxvkError("Failed to compile pixel shader"); - - status = m_device->CreatePixelShader(reinterpret_cast(blob->GetBufferPointer()), &m_ps); - - if (FAILED(status)) - throw DxvkError("Failed to create pixel shader"); - } - - m_device->SetVertexShader(m_vs.ptr()); - m_device->SetPixelShader(m_ps.ptr()); - - m_device->AddRef(); - - Com nullSurface; - status = m_device->CreateRenderTarget(64, 64, D3DFORMAT(MAKEFOURCC('N', 'U', 'L', 'L')), D3DMULTISAMPLE_NONE, 0, FALSE, &nullSurface, nullptr); - - status = m_device->ColorFill(nullSurface.ptr(), nullptr, D3DCOLOR_RGBA(255, 0, 0, 255)); - - Com defaultTexture; - status = m_device->CreateTexture(64, 64, 1, 0, D3DFMT_DXT3, D3DPOOL_DEFAULT, &defaultTexture, nullptr); - - m_device->AddRef(); - - Com surface; - status = defaultTexture->GetSurfaceLevel(0, &surface); - - m_device->AddRef(); - - Com sysmemTexture; - status = m_device->CreateTexture(64, 64, 1, 0, D3DFMT_DXT3, D3DPOOL_SYSTEMMEM, &sysmemTexture, nullptr); - - Com offscreenSurface; - status = m_device->CreateOffscreenPlainSurfaceEx(64, 64, D3DFMT_DXT3, D3DPOOL_DEFAULT, &offscreenSurface, nullptr, 0); - - D3DLOCKED_RECT offscreenLock; - status = offscreenSurface->LockRect(&offscreenLock, nullptr, 0); - - std::memset(offscreenLock.pBits, 0xFF, offscreenLock.Pitch * (64 / 4)); - - status = offscreenSurface->UnlockRect(); - - //status = m_device->ColorFill(offscreenSurface.ptr(), nullptr, D3DCOLOR_ARGB(255, 255, 0, 0)); - - D3DLOCKED_RECT sysmemLock; - status = sysmemTexture->LockRect(0, &sysmemLock, nullptr, 0); - - //D3DLOCKED_RECT offscreenLock; - status = offscreenSurface->LockRect(&offscreenLock, nullptr, 0); - - std::memcpy(sysmemLock.pBits, offscreenLock.pBits, offscreenLock.Pitch * (64 / 4)); - - sysmemTexture->UnlockRect(0); - offscreenSurface->UnlockRect(); - - status = m_device->UpdateTexture(sysmemTexture.ptr(), defaultTexture.ptr()); - - status = m_device->SetTexture(0, defaultTexture.ptr()); - - Com rt; - status = m_device->CreateRenderTarget(1280, 720, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, nullptr); - - m_device->AddRef(); - - Com rt2; - status = m_device->CreateRenderTarget(1280, 720, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, nullptr); - - m_device->AddRef(); - - rt2 = nullptr; - - m_device->AddRef(); - - RECT stretchRect1 = { 0, 0, 640, 720 }; - RECT stretchRect2 = { 640, 0, 1280, 720 }; - status = m_device->StretchRect(rt.ptr(), &stretchRect1, rt.ptr(), &stretchRect2, D3DTEXF_LINEAR); - - /// - - Com ds; - //status = m_device->CreateDepthStencilSurface(1274, 695, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, FALSE, &ds, nullptr); - status = m_device->CreateDepthStencilSurface(1280, 720, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, FALSE, &ds, nullptr); - - status = m_device->SetDepthStencilSurface(ds.ptr()); - status = m_device->SetRenderState(D3DRS_ZWRITEENABLE, 1); - status = m_device->SetRenderState(D3DRS_ZENABLE, 1); - status = m_device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - - - - std::array vertices = { - 0.0f, 0.5f, 0.0f, - 0.5f, -0.5f, 0.0f, - -0.5f, -0.5f, 0.0f, - }; - - const size_t vbSize = vertices.size() * sizeof(float); - - status = m_device->CreateVertexBuffer(vbSize, 0, 0, D3DPOOL_DEFAULT, &m_vb, nullptr); - if (FAILED(status)) - throw DxvkError("Failed to create vertex buffer"); - - void* data = nullptr; - status = m_vb->Lock(0, 0, &data, 0); - if (FAILED(status)) - throw DxvkError("Failed to lock vertex buffer"); - - std::memcpy(data, vertices.data(), vbSize); - - status = m_vb->Unlock(); - if (FAILED(status)) - throw DxvkError("Failed to unlock vertex buffer"); - - m_device->SetStreamSource(0, m_vb.ptr(), 0, 3 * sizeof(float)); - - std::array elements; - - elements[0].Method = 0; - elements[0].Offset = 0; - elements[0].Stream = 0; - elements[0].Type = D3DDECLTYPE_FLOAT3; - elements[0].Usage = D3DDECLUSAGE_POSITION; - elements[0].UsageIndex = 0; - - elements[1] = D3DDECL_END(); - - HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl); - if (FAILED(result)) - throw DxvkError("Failed to create vertex decl"); - - m_device->SetVertexDeclaration(m_decl.ptr()); - - /// - - Com myRT; - status = m_device->CreateTexture(512, 256, 1, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &myRT, nullptr); - - Com myRTSurf; - myRT->GetSurfaceLevel(0, &myRTSurf); - - Com myCopyThing; - status = m_device->CreateTexture(512, 256, 1, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &myCopyThing, nullptr); - - Com myCopyThingSurf; - myCopyThing->GetSurfaceLevel(0, &myCopyThingSurf); - - status = m_device->StretchRect(myRTSurf.ptr(), nullptr, myCopyThingSurf.ptr(), nullptr, D3DTEXF_NONE); - - D3DLOCKED_RECT rect; - status = myCopyThing->LockRect(0, &rect, nullptr, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); - - m_device->SetRenderState(D3DRS_ALPHAREF, 256 + 255); - m_device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_LESSEQUAL); - m_device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); - } - - void run() { - this->adjustBackBuffer(); - - m_device->BeginScene(); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_TARGET, - D3DCOLOR_RGBA(44, 62, 80, 0), - 0, - 0); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_ZBUFFER, - 0, - 0.5f, - 0); - - m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); - - m_device->EndScene(); - - m_device->PresentEx( - nullptr, - nullptr, - nullptr, - nullptr, - 0); - } - - void adjustBackBuffer() { - RECT windowRect = { 0, 0, 1024, 600 }; - GetClientRect(m_window, &windowRect); - - Extent2D newSize = { - static_cast(windowRect.right - windowRect.left), - static_cast(windowRect.bottom - windowRect.top), - }; - - if (m_windowSize.w != newSize.w - || m_windowSize.h != newSize.h) { - m_windowSize = newSize; - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - HRESULT status = m_device->ResetEx(¶ms, nullptr); - - if (FAILED(status)) - throw DxvkError("Device reset failed"); - } - } - - void getPresentParams(D3DPRESENT_PARAMETERS& params) { - params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - params.BackBufferCount = 1; - params.BackBufferFormat = D3DFMT_X8R8G8B8; - params.BackBufferWidth = m_windowSize.w; - params.BackBufferHeight = m_windowSize.h; - params.EnableAutoDepthStencil = 0; - params.Flags = 0; - params.FullScreen_RefreshRateInHz = 0; - params.hDeviceWindow = m_window; - params.MultiSampleQuality = 0; - params.MultiSampleType = D3DMULTISAMPLE_NONE; - params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - params.SwapEffect = D3DSWAPEFFECT_DISCARD; - params.Windowed = TRUE; - } - -private: - - HWND m_window; - Extent2D m_windowSize = { 1024, 600 }; - - Com m_d3d; - Com m_device; - - Com m_vs; - Com m_ps; - Com m_vb; - Com m_decl; - -}; - -LRESULT CALLBACK WindowProc(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - HWND hWnd; - WNDCLASSEXW wc; - ZeroMemory(&wc, sizeof(WNDCLASSEX)); - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = WindowProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"WindowClass1"; - RegisterClassExW(&wc); - - hWnd = CreateWindowExW(0, - L"WindowClass1", - L"Our First Windowed Program", - WS_OVERLAPPEDWINDOW, - 300, 300, - 640, 480, - nullptr, - nullptr, - hInstance, - nullptr); - ShowWindow(hWnd, nCmdShow); - - MSG msg; - - try { - TriangleApp app(hInstance, hWnd); - - while (true) { - if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - return msg.wParam; - } else { - app.run(); - } - } - } catch (const dxvk::DxvkError& e) { - std::cerr << e.message() << std::endl; - return msg.wParam; - } -} - -LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} diff --git a/tests/d3d9/test_d3d9_up.cpp b/tests/d3d9/test_d3d9_up.cpp deleted file mode 100644 index 8ef137c9a..000000000 --- a/tests/d3d9/test_d3d9_up.cpp +++ /dev/null @@ -1,429 +0,0 @@ -#include - -#include -#include - -#include "../test_utils.h" - -using namespace dxvk; - -struct Extent2D { - uint32_t w, h; -}; - -const std::string g_vertexShaderCode = R"( - -struct VS_INPUT { - float3 Position : POSITION; - float3 TexCoord : TEXCOORD0; -}; - -struct VS_OUTPUT { - float4 Position : POSITION; - float3 TexCoord : TEXCOORD0; -}; - -VS_OUTPUT main( VS_INPUT IN ) { - VS_OUTPUT OUT; - OUT.Position = float4(IN.Position, 0.6f); - OUT.TexCoord = IN.TexCoord; - - return OUT; -} - -)"; - -const std::string g_pixelShaderCode = R"( - -struct VS_OUTPUT { - float4 Position : POSITION; - float3 TexCoord : TEXCOORD0; -}; - -struct PS_OUTPUT { - float4 Colour : COLOR; -}; - -sampler g_texDepth : register( s0 ); - -PS_OUTPUT main( VS_OUTPUT IN ) { - PS_OUTPUT OUT; - - //OUT.Colour = tex2D(g_texDepth, float2(0, 0)); - //OUT.Colour = 1.0; - - OUT.Colour = float4(IN.TexCoord.xyz, 1.0); - - return OUT; -} - - -)"; - -Logger Logger::s_instance("triangle.log"); - -class TriangleApp { - -public: - - TriangleApp(HINSTANCE instance, HWND window) - : m_window(window) { - HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 interface"); - - UINT adapter = D3DADAPTER_DEFAULT; - - D3DADAPTER_IDENTIFIER9 adapterId; - m_d3d->GetAdapterIdentifier(adapter, 0, &adapterId); - - Logger::info(str::format("Using adapter: ", adapterId.Description)); - - auto CheckSRGBFormat = [&](D3DFORMAT fmt, const char* name) { - HRESULT status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt); - Logger::warn(str::format("(linear) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope")); - - status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, fmt); - Logger::warn(str::format("(srgb) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope")); - }; - - CheckSRGBFormat(D3DFMT_R5G6B5, "R5G6B5"); - CheckSRGBFormat(D3DFMT_X1R5G5B5, "X1R5G5B5"); - CheckSRGBFormat(D3DFMT_A1R5G5B5, "A1R5G5B5"); - CheckSRGBFormat(D3DFMT_A4R4G4B4, "A4R4G4B4"); - CheckSRGBFormat(D3DFMT_X4R4G4B4, "X4R4G4B4"); - CheckSRGBFormat(D3DFMT_G16R16, "G16R16"); - CheckSRGBFormat(D3DFMT_A2R10G10B10, "A2R10G10B10"); - CheckSRGBFormat(D3DFMT_A16B16G16R16, "A16B16G16R16"); - - // - - DWORD quality; - status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_D24S8); - status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8); - status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8); - status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality); - status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality); - status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE); - status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE); - - // NULL - constexpr D3DFORMAT NullFormat = D3DFORMAT(MAKEFOURCC('N', 'U', 'L', 'L')); - - status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, D3DFMT_D24S8); - status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, NullFormat); - status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, NullFormat); - status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat); - status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, false); - status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, true); - // - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - - status = m_d3d->CreateDeviceEx( - adapter, - D3DDEVTYPE_HAL, - m_window, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - ¶ms, - nullptr, - &m_device); - - if (FAILED(status)) - throw DxvkError("Failed to create D3D9 device"); - - // Funny Swapchain Refcounting - // "One of the things COM does really well, is lifecycle management" - // Implicit Swapchain - { - IDirect3DSurface9* pSurface1 = nullptr; - IDirect3DSurface9* pSurface2 = nullptr; - status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface1); - D3DPRESENT_PARAMETERS newParams = params; - newParams.BackBufferWidth = 10; - newParams.BackBufferHeight = 10; - status = m_device->Reset(&newParams); - status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface2); - - IDirect3DSwapChain9* pSwapChain2 = nullptr; - IDirect3DSwapChain9* pSwapChain3 = nullptr; - status = pSurface1->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast(&pSwapChain2)); - status = pSurface2->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast(&pSwapChain3)); - - printf("E_NOINTERFACE! for pSwapchain2"); - status = m_device->Reset(¶ms); - } - // Additional swapchain - { - IDirect3DSwapChain9* pSwapChain2 = nullptr; - IDirect3DSwapChain9* pSwapChain3 = nullptr; - IDirect3DSwapChain9* pSwapChain4 = nullptr; - IDirect3DSurface9* pSurface = nullptr; - status = m_device->CreateAdditionalSwapChain(¶ms, &pSwapChain2); - status = pSwapChain2->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface); - status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast(&pSwapChain3)); - pSwapChain2->Release(); - UINT count = pSwapChain2->Release(); - printf("Count: %u - Should be 0 and swapchain dead!", count); - status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast(&pSwapChain4)); - // E_NOINTERFACE ! - printf("E_NOINTERFACE!"); - } - - m_device->AddRef(); - - Com backbuffer; - m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); - - m_device->AddRef(); - - Com swapchain; - m_device->GetSwapChain(0, &swapchain); - - m_device->AddRef(); - - DWORD bias = 0xDEADBEEF; - status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias); - status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '4')); - status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias); - status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '1')); - status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias); - - // Vertex Shader - { - Com blob; - - status = D3DCompile( - g_vertexShaderCode.data(), - g_vertexShaderCode.length(), - nullptr, nullptr, nullptr, - "main", - "vs_2_0", - 0, 0, &blob, - nullptr); - - if (FAILED(status)) - throw DxvkError("Failed to compile vertex shader"); - - status = m_device->CreateVertexShader(reinterpret_cast(blob->GetBufferPointer()), &m_vs); - - if (FAILED(status)) - throw DxvkError("Failed to create vertex shader"); - } - - // Pixel Shader - { - Com blob; - - status = D3DCompile( - g_pixelShaderCode.data(), - g_pixelShaderCode.length(), - nullptr, nullptr, nullptr, - "main", - "ps_2_0", - 0, 0, &blob, - nullptr); - - if (FAILED(status)) - throw DxvkError("Failed to compile pixel shader"); - - status = m_device->CreatePixelShader(reinterpret_cast(blob->GetBufferPointer()), &m_ps); - - if (FAILED(status)) - throw DxvkError("Failed to create pixel shader"); - } - - m_device->SetVertexShader(m_vs.ptr()); - m_device->SetPixelShader(m_ps.ptr()); - - m_device->AddRef(); - } - - void run() { - this->adjustBackBuffer(); - - m_device->BeginScene(); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_TARGET, - D3DCOLOR_RGBA(44, 62, 80, 0), - 0, - 0); - - m_device->Clear( - 0, - nullptr, - D3DCLEAR_ZBUFFER, - 0, - 0.5f, - 0); - - m_decl = nullptr; - - std::array elements; - - elements[0].Method = 0; - elements[0].Offset = 0; - elements[0].Stream = 0; - elements[0].Type = D3DDECLTYPE_FLOAT3; - elements[0].Usage = D3DDECLUSAGE_POSITION; - elements[0].UsageIndex = 0; - - elements[1].Method = 0; - elements[1].Offset = 12; - elements[1].Stream = 0; - elements[1].Type = D3DDECLTYPE_FLOAT3; - elements[1].Usage = D3DDECLUSAGE_TEXCOORD; - elements[1].UsageIndex = 0; - - elements[2] = D3DDECL_END(); - - HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl); - if (FAILED(result)) - throw DxvkError("Failed to create vertex decl"); - - m_device->SetVertexDeclaration(m_decl.ptr()); - - float vertexData[] = { - -1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, -1, 0, 1, 1, -1, -1, 0, 0, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - }; - - m_device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, vertexData, 20); - //m_device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 3, vertexData, 20); - - //m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); - - m_device->EndScene(); - - m_device->PresentEx( - nullptr, - nullptr, - nullptr, - nullptr, - 0); - } - - void adjustBackBuffer() { - RECT windowRect = { 0, 0, 1024, 600 }; - GetClientRect(m_window, &windowRect); - - Extent2D newSize = { - static_cast(windowRect.right - windowRect.left), - static_cast(windowRect.bottom - windowRect.top), - }; - - if (m_windowSize.w != newSize.w - || m_windowSize.h != newSize.h) { - m_windowSize = newSize; - - D3DPRESENT_PARAMETERS params; - getPresentParams(params); - HRESULT status = m_device->ResetEx(¶ms, nullptr); - - if (FAILED(status)) - throw DxvkError("Device reset failed"); - } - } - - void getPresentParams(D3DPRESENT_PARAMETERS& params) { - params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - params.BackBufferCount = 1; - params.BackBufferFormat = D3DFMT_X8R8G8B8; - params.BackBufferWidth = m_windowSize.w; - params.BackBufferHeight = m_windowSize.h; - params.EnableAutoDepthStencil = 0; - params.Flags = 0; - params.FullScreen_RefreshRateInHz = 0; - params.hDeviceWindow = m_window; - params.MultiSampleQuality = 0; - params.MultiSampleType = D3DMULTISAMPLE_NONE; - params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - params.SwapEffect = D3DSWAPEFFECT_DISCARD; - params.Windowed = TRUE; - } - -private: - - HWND m_window; - Extent2D m_windowSize = { 1024, 600 }; - - Com m_d3d; - Com m_device; - - Com m_vs; - Com m_ps; - Com m_vb; - Com m_decl; - -}; - -LRESULT CALLBACK WindowProc(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - -int WINAPI WinMain(HINSTANCE hInstance, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) { - HWND hWnd; - WNDCLASSEXW wc; - ZeroMemory(&wc, sizeof(WNDCLASSEX)); - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = WindowProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(nullptr, IDC_ARROW); - wc.hbrBackground = (HBRUSH)COLOR_WINDOW; - wc.lpszClassName = L"WindowClass1"; - RegisterClassExW(&wc); - - hWnd = CreateWindowExW(0, - L"WindowClass1", - L"Our First Windowed Program", - WS_OVERLAPPEDWINDOW, - 300, 300, - 640, 480, - nullptr, - nullptr, - hInstance, - nullptr); - ShowWindow(hWnd, nCmdShow); - - MSG msg; - - try { - TriangleApp app(hInstance, hWnd); - - while (true) { - if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - - if (msg.message == WM_QUIT) - return msg.wParam; - } else { - app.run(); - } - } - } catch (const dxvk::DxvkError& e) { - std::cerr << e.message() << std::endl; - return msg.wParam; - } -} - -LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - - return DefWindowProc(hWnd, message, wParam, lParam); -} diff --git a/tests/meson.build b/tests/meson.build deleted file mode 100644 index d2ec1394a..000000000 --- a/tests/meson.build +++ /dev/null @@ -1 +0,0 @@ -subdir('d3d9') diff --git a/tests/test_utils.h b/tests/test_utils.h deleted file mode 100644 index 363aa95fb..000000000 --- a/tests/test_utils.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -#include "../src/util/com/com_guid.h" -#include "../src/util/com/com_object.h" -#include "../src/util/com/com_pointer.h" - -#include "../src/util/log/log.h" -#include "../src/util/log/log_debug.h" - -#include "../src/util/rc/util_rc.h" -#include "../src/util/rc/util_rc_ptr.h" - -#include "../src/util/util_enum.h" -#include "../src/util/util_error.h" -#include "../src/util/util_string.h" From c3c6dbf669b210ab4c0327063285b2b38d6e7d01 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Aug 2022 23:48:34 +0200 Subject: [PATCH 0733/1348] [dxvk] Fix potential buffer lifetime issues --- src/dxvk/dxvk_buffer.cpp | 26 ++++++++++---------------- src/dxvk/dxvk_buffer.h | 4 +++- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index eeb7afade..00dde9d70 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -11,7 +11,7 @@ namespace dxvk { const DxvkBufferCreateInfo& createInfo, DxvkMemoryAllocator& memAlloc, VkMemoryPropertyFlags memFlags) - : m_device (device), + : m_vkd (device->vkd()), m_info (createInfo), m_memAlloc (&memAlloc), m_memFlags (memFlags), @@ -19,7 +19,7 @@ namespace dxvk { if (!(m_info.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)) { // Align slices so that we don't violate any alignment // requirements imposed by the Vulkan device/driver - VkDeviceSize sliceAlignment = computeSliceAlignment(); + VkDeviceSize sliceAlignment = computeSliceAlignment(device); m_physSliceLength = createInfo.size; m_physSliceStride = align(createInfo.size, sliceAlignment); m_physSliceCount = std::max(1, 256 / m_physSliceStride); @@ -63,17 +63,13 @@ namespace dxvk { DxvkBuffer::~DxvkBuffer() { - auto vkd = m_device->vkd(); - for (const auto& buffer : m_buffers) - vkd->vkDestroyBuffer(vkd->device(), buffer.buffer, nullptr); - vkd->vkDestroyBuffer(vkd->device(), m_buffer.buffer, nullptr); + m_vkd->vkDestroyBuffer(m_vkd->device(), buffer.buffer, nullptr); + m_vkd->vkDestroyBuffer(m_vkd->device(), m_buffer.buffer, nullptr); } DxvkBufferHandle DxvkBuffer::allocBuffer(VkDeviceSize sliceCount, bool clear) const { - auto vkd = m_device->vkd(); - VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; info.flags = m_info.flags; info.size = m_physSliceStride * sliceCount; @@ -82,7 +78,7 @@ namespace dxvk { DxvkBufferHandle handle; - if (vkd->vkCreateBuffer(vkd->device(), &info, nullptr, &handle.buffer)) { + if (m_vkd->vkCreateBuffer(m_vkd->device(), &info, nullptr, &handle.buffer)) { throw DxvkError(str::format( "DxvkBuffer: Failed to create buffer:" "\n flags: ", std::hex, info.flags, @@ -98,7 +94,7 @@ namespace dxvk { VkBufferMemoryRequirementsInfo2 memoryRequirementInfo = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 }; memoryRequirementInfo.buffer = handle.buffer; - vkd->vkGetBufferMemoryRequirements2(vkd->device(), + m_vkd->vkGetBufferMemoryRequirements2(m_vkd->device(), &memoryRequirementInfo, &memoryRequirements.core); // Fill in desired memory properties @@ -129,7 +125,7 @@ namespace dxvk { handle.memory = m_memAlloc->alloc(memoryRequirements, memoryProperties, hints); - if (vkd->vkBindBufferMemory(vkd->device(), handle.buffer, + if (m_vkd->vkBindBufferMemory(m_vkd->device(), handle.buffer, handle.memory.memory(), handle.memory.offset()) != VK_SUCCESS) throw DxvkError("DxvkBuffer: Failed to bind device memory"); @@ -141,8 +137,6 @@ namespace dxvk { DxvkBufferHandle DxvkBuffer::createSparseBuffer() const { - auto vkd = m_device->vkd(); - VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; info.flags = m_info.flags; info.size = m_info.size; @@ -151,7 +145,7 @@ namespace dxvk { DxvkBufferHandle handle = { }; - if (vkd->vkCreateBuffer(vkd->device(), + if (m_vkd->vkCreateBuffer(m_vkd->device(), &info, nullptr, &handle.buffer) != VK_SUCCESS) { throw DxvkError(str::format( "DxvkBuffer: Failed to create buffer:" @@ -164,8 +158,8 @@ namespace dxvk { } - VkDeviceSize DxvkBuffer::computeSliceAlignment() const { - const auto& devInfo = m_device->properties(); + VkDeviceSize DxvkBuffer::computeSliceAlignment(DxvkDevice* device) const { + const auto& devInfo = device->properties(); VkDeviceSize result = sizeof(uint32_t); diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 5ea4ca91c..0688068d1 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -297,6 +297,7 @@ namespace dxvk { private: DxvkDevice* m_device; + Rc m_vkd; DxvkBufferCreateInfo m_info; DxvkMemoryAllocator* m_memAlloc; VkMemoryPropertyFlags m_memFlags; @@ -337,7 +338,8 @@ namespace dxvk { DxvkBufferHandle createSparseBuffer() const; - VkDeviceSize computeSliceAlignment() const; + VkDeviceSize computeSliceAlignment( + DxvkDevice* device) const; }; From 7b4925dc453bb8130688c5aec8744e9a8550bf0f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Aug 2022 23:48:46 +0200 Subject: [PATCH 0734/1348] [dxvk] Fix potential sparse allocator lifetime issues --- src/dxvk/dxvk_device.cpp | 2 +- src/dxvk/dxvk_sparse.cpp | 3 +-- src/dxvk/dxvk_sparse.h | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 4820cf778..94cc0e528 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -217,7 +217,7 @@ namespace dxvk { Rc DxvkDevice::createSparsePageAllocator() { - return new DxvkSparsePageAllocator(this, m_objects.memoryManager()); + return new DxvkSparsePageAllocator(m_objects.memoryManager()); } diff --git a/src/dxvk/dxvk_sparse.cpp b/src/dxvk/dxvk_sparse.cpp index c022b8063..373906edf 100644 --- a/src/dxvk/dxvk_sparse.cpp +++ b/src/dxvk/dxvk_sparse.cpp @@ -79,9 +79,8 @@ namespace dxvk { DxvkSparsePageAllocator::DxvkSparsePageAllocator( - DxvkDevice* device, DxvkMemoryAllocator& memoryAllocator) - : m_device(device), m_memory(&memoryAllocator) { + : m_memory(&memoryAllocator) { } diff --git a/src/dxvk/dxvk_sparse.h b/src/dxvk/dxvk_sparse.h index 158a2b5a7..2e8e5becb 100644 --- a/src/dxvk/dxvk_sparse.h +++ b/src/dxvk/dxvk_sparse.h @@ -271,7 +271,6 @@ namespace dxvk { public: DxvkSparsePageAllocator( - DxvkDevice* device, DxvkMemoryAllocator& memoryAllocator); ~DxvkSparsePageAllocator(); @@ -300,7 +299,6 @@ namespace dxvk { private: - DxvkDevice* m_device; DxvkMemoryAllocator* m_memory; dxvk::mutex m_mutex; From 321338af00f1e9f0e8dd0848e216104bcc9ceff2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 1 Sep 2022 00:07:23 +0200 Subject: [PATCH 0735/1348] [dxvk] Remove unused m_device member from DxvkBuffer --- src/dxvk/dxvk_buffer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 0688068d1..a82fbd0e8 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -296,7 +296,6 @@ namespace dxvk { private: - DxvkDevice* m_device; Rc m_vkd; DxvkBufferCreateInfo m_info; DxvkMemoryAllocator* m_memAlloc; From f8781e1c4ca04e22a8f50f443ffe7bfe46fe3401 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Aug 2022 21:27:35 +0200 Subject: [PATCH 0736/1348] [vulkan] Add missing VK_EXT_debug_utils entry points --- src/vulkan/vulkan_loader.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index cf9ec1e6a..8701ca588 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -145,16 +145,13 @@ namespace dxvk::vk { VULKAN_FN(vkGetPhysicalDeviceSurfacePresentModesKHR); #endif - #ifdef VK_EXT_debug_report - VULKAN_FN(vkCreateDebugReportCallbackEXT); - VULKAN_FN(vkDestroyDebugReportCallbackEXT); - VULKAN_FN(vkDebugReportMessageEXT); - #endif - #ifdef VK_EXT_debug_utils VULKAN_FN(vkCmdBeginDebugUtilsLabelEXT); VULKAN_FN(vkCmdEndDebugUtilsLabelEXT); VULKAN_FN(vkCmdInsertDebugUtilsLabelEXT); + VULKAN_FN(vkCreateDebugUtilsMessengerEXT); + VULKAN_FN(vkDestroyDebugUtilsMessengerEXT); + VULKAN_FN(vkSubmitDebugUtilsMessageEXT); #endif #ifdef VK_EXT_full_screen_exclusive @@ -353,6 +350,14 @@ namespace dxvk::vk { VULKAN_FN(vkCmdEndConditionalRenderingEXT); #endif + #ifdef VK_EXT_debug_utils + VULKAN_FN(vkQueueBeginDebugUtilsLabelEXT); + VULKAN_FN(vkQueueEndDebugUtilsLabelEXT); + VULKAN_FN(vkQueueInsertDebugUtilsLabelEXT); + VULKAN_FN(vkSetDebugUtilsObjectNameEXT); + VULKAN_FN(vkSetDebugUtilsObjectTagEXT); + #endif + #ifdef VK_EXT_full_screen_exclusive VULKAN_FN(vkAcquireFullScreenExclusiveModeEXT); VULKAN_FN(vkReleaseFullScreenExclusiveModeEXT); From 2f39ae792a9522186e14f41618a4597fb43fb1ae Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Aug 2022 21:11:53 +0200 Subject: [PATCH 0737/1348] [dxvk] Change DXVK_PERF_EVENTS environment variable to DXVK_DEBUG --- README.md | 2 +- dxvk.conf | 2 +- src/dxvk/dxvk_instance.cpp | 3 +-- src/dxvk/dxvk_options.h | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 12260af61..bddaff165 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ The following environment variables can be used for **debugging** purposes. - `DXVK_LOG_LEVEL=none|error|warn|info|debug` Controls message logging. - `DXVK_LOG_PATH=/some/directory` Changes path where log files are stored. Set to `none` to disable log file creation entirely, without disabling logging. - `DXVK_CONFIG_FILE=/xxx/dxvk.conf` Sets path to the configuration file. -- `DXVK_PERF_EVENTS=1` Enables use of the VK_EXT_debug_utils extension for translating performance event markers. +- `DXVK_DEBUG=markers|validation` Enables use of the `VK_EXT_debug_utils` extension for translating performance event markers, or to enable Vulkan validation, respecticely. ## Troubleshooting DXVK requires threading support from your mingw-w64 build environment. If you diff --git a/dxvk.conf b/dxvk.conf index 5c123f57d..5f64091fc 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -558,7 +558,7 @@ # Debug Utils # # Enables debug utils as this is off by default, this enables user annotations like BeginEvent()/EndEvent(). -# Alternatively could be enabled with DXVK_PERF_EVENTS=1 environment variable. +# Alternatively could be enabled with DXVK_DEBUG=markers environment variable. # # Supported values: # - True/False diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index 8010e740b..0fc2e0b6f 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -98,8 +98,7 @@ namespace dxvk { // Hide VK_EXT_debug_utils behind an environment variable. This extension // adds additional overhead to winevulkan - if ((env::getEnvVar("DXVK_PERF_EVENTS") == "1") || - (m_options.enableDebugUtils)) { + if ((!env::getEnvVar("DXVK_DEBUG").empty()) || (m_options.enableDebugUtils)) { insExtensionList.push_back(&insExtensions.extDebugUtils); Logger::warn("DXVK: Debug Utils are enabled, perf events are ON. May affect performance!"); } diff --git a/src/dxvk/dxvk_options.h b/src/dxvk/dxvk_options.h index da5bf406e..015fea0cf 100644 --- a/src/dxvk/dxvk_options.h +++ b/src/dxvk/dxvk_options.h @@ -8,7 +8,7 @@ namespace dxvk { DxvkOptions() { } DxvkOptions(const Config& config); - /// Enable debug utils (alternative to DXVK_PERF_EVENTS=1) + /// Enable debug utils bool enableDebugUtils; /// Enable state cache From 097d3edd059cc83f19b6188cd2b6f8eaf22df3c6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 31 Aug 2022 22:12:03 +0200 Subject: [PATCH 0738/1348] [dxvk] Create debug messenger if DXVK_DEBUG=validation is set --- src/dxvk/dxvk_instance.cpp | 91 +++++++++++++++++++++++++++++++++++--- src/dxvk/dxvk_instance.h | 13 +++++- 2 files changed, 98 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index 0fc2e0b6f..4808fa45c 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -6,6 +6,7 @@ #include "dxvk_platform_exts.h" #include +#include namespace dxvk { @@ -37,6 +38,19 @@ namespace dxvk { throw DxvkError("Failed to load vulkan-1 library."); m_vki = new vk::InstanceFn(m_vkl, true, this->createInstance()); + if (m_enableValidation) { + VkDebugUtilsMessengerCreateInfoEXT messengerInfo = { VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT }; + messengerInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + messengerInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT; + messengerInfo.pfnUserCallback = &debugCallback; + + if (m_vki->vkCreateDebugUtilsMessengerEXT(m_vki->instance(), &messengerInfo, nullptr, &m_messenger)) + Logger::err("DxvkInstance::createInstance: Failed to create debug messenger, proceeding without."); + } + m_adapters = this->queryAdapters(); for (const auto& provider : m_extProviders) @@ -52,7 +66,8 @@ namespace dxvk { DxvkInstance::~DxvkInstance() { - + if (m_messenger) + m_vki->vkDestroyDebugUtilsMessengerEXT(m_vki->instance(), m_messenger, nullptr); } @@ -98,9 +113,28 @@ namespace dxvk { // Hide VK_EXT_debug_utils behind an environment variable. This extension // adds additional overhead to winevulkan - if ((!env::getEnvVar("DXVK_DEBUG").empty()) || (m_options.enableDebugUtils)) { - insExtensionList.push_back(&insExtensions.extDebugUtils); - Logger::warn("DXVK: Debug Utils are enabled, perf events are ON. May affect performance!"); + std::string debugEnv = env::getEnvVar("DXVK_DEBUG"); + DxvkNameList layerNameList; + + m_enablePerfEvents = debugEnv == "markers"; + m_enableValidation = debugEnv == "validation"; + + if (m_enablePerfEvents || m_enableValidation || m_options.enableDebugUtils) { + insExtensionList.push_back(&insExtensions.extDebugUtils); + Logger::warn("Debug Utils are enabled. May affect performance."); + + if (m_enableValidation) { + const char* layerName = "VK_LAYER_KHRONOS_validation"; + DxvkNameSet layers = DxvkNameSet::enumInstanceLayers(m_vkl); + + if (layers.supports(layerName)) { + layerNameList.add(layerName); + Logger::warn(str::format("Enabled instance layer ", layerName)); + } else { + // This can happen on winevulkan since it does not support layers + Logger::warn(str::format("Validation layers not found, set VK_INSTANCE_LAYERS=", layerName)); + } + } } DxvkNameSet extensionsEnabled; @@ -133,6 +167,8 @@ namespace dxvk { VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; info.pApplicationInfo = &appInfo; + info.enabledLayerCount = layerNameList.count(); + info.ppEnabledLayerNames = layerNameList.names(); info.enabledExtensionCount = extensionNameList.count(); info.ppEnabledExtensionNames = extensionNameList.names(); @@ -141,7 +177,7 @@ namespace dxvk { if (status != VK_SUCCESS) throw DxvkError("DxvkInstance::createInstance: Failed to create Vulkan 1.1 instance"); - + return result; } @@ -206,4 +242,49 @@ namespace dxvk { Logger::info(str::format(" ", names.name(i))); } + + VkBool32 VKAPI_CALL DxvkInstance::debugCallback( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageTypes, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData) { + LogLevel logLevel; + + switch (messageSeverity) { + default: + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: logLevel = LogLevel::Info; break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: logLevel = LogLevel::Debug; break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: logLevel = LogLevel::Warn; break; + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: logLevel = LogLevel::Error; break; + } + + static const std::array ignoredIds = { + // Ignore image format features for depth-compare instructions. + // These errors are expected in D3D9 and some D3D11 apps. + 0x4b9d1597, + // Ignore vkCmdBindPipeline errors related to dynamic rendering. + // Validation layers are buggy here and will complain about any + // command buffer with more than one render pass. + 0x11b37e31, + 0x151f5e5a, + 0x6c16bfb4, + 0xd6d77e1e, + }; + + for (auto id : ignoredIds) { + if (uint32_t(pCallbackData->messageIdNumber) == id) + return VK_FALSE; + } + + std::stringstream str; + + if (pCallbackData->pMessageIdName) + str << pCallbackData->pMessageIdName << ": " << std::endl; + + str << pCallbackData->pMessage; + + Logger::log(logLevel, str.str()); + return VK_FALSE; + } + } diff --git a/src/dxvk/dxvk_instance.h b/src/dxvk/dxvk_instance.h index f945ed6d2..7027c4c57 100644 --- a/src/dxvk/dxvk_instance.h +++ b/src/dxvk/dxvk_instance.h @@ -115,6 +115,11 @@ namespace dxvk { Rc m_vki; DxvkInstanceExtensions m_extensions; + bool m_enablePerfEvents = false; + bool m_enableValidation = false; + + VkDebugUtilsMessengerEXT m_messenger = VK_NULL_HANDLE; + std::vector m_extProviders; std::vector> m_adapters; @@ -123,7 +128,13 @@ namespace dxvk { std::vector> queryAdapters(); static void logNameList(const DxvkNameList& names); - + + static VkBool32 VKAPI_CALL debugCallback( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageTypes, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData); + }; } From 735349bf1b5dea4db1f699eec0c3ccad9f4013a8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 1 Sep 2022 03:35:58 +0200 Subject: [PATCH 0739/1348] [dxvk] Fix barrier typo --- src/dxvk/dxvk_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index c6ceda9db..1bb99be28 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -3964,7 +3964,7 @@ namespace dxvk { m_cmd->cmdCopyBufferToImage(DxvkCmdBuffer::ExecBuffer, &info); } - m_execAcquires.accessImage(sparse, sparseSubresources, + m_execBarriers.accessImage(sparse, sparseSubresources, transferLayout, VK_PIPELINE_STAGE_TRANSFER_BIT, transferAccess, From 4fc5ba66ed3b3ab04797eff3b7294b75da9ed47e Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Wed, 31 Aug 2022 22:34:00 +0200 Subject: [PATCH 0740/1348] [util] Add missing feature level in example config --- dxvk.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dxvk.conf b/dxvk.conf index 5f64091fc..366d25a0e 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -127,7 +127,7 @@ # with. Setting this to a higher value may allow some applications to run # that would otherwise fail to create a D3D11 device. # -# Supported values: 9_1, 9_2, 9_3, 10_0, 10_1, 11_0, 11_1 +# Supported values: 9_1, 9_2, 9_3, 10_0, 10_1, 11_0, 11_1, 12_0, 12_1 # d3d11.maxFeatureLevel = 12_0 From b05ae332734597b5ef72fd0aa579a5823b610d14 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 1 Sep 2022 02:14:22 +0000 Subject: [PATCH 0741/1348] [util] Return null if HMODULE is nullptr in GetProcAddress compat dlsym with NULL will try to find the symbol from anything currently loaded. --- src/util/util_win32_compat.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/util/util_win32_compat.h b/src/util/util_win32_compat.h index 05597bd74..cc05b1b16 100644 --- a/src/util/util_win32_compat.h +++ b/src/util/util_win32_compat.h @@ -16,6 +16,9 @@ inline void FreeLibrary(HMODULE module) { } inline void* GetProcAddress(HMODULE module, LPCSTR lpProcName) { + if (!module) + return nullptr; + return dlsym(module, lpProcName); } From 36f523bbf5cf5308ea4b18af3a5dc1c646d9e415 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 1 Sep 2022 02:16:56 +0000 Subject: [PATCH 0742/1348] [vulkan] Fix loading libvulkan natively --- src/vulkan/vulkan_loader.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/vulkan/vulkan_loader.cpp b/src/vulkan/vulkan_loader.cpp index c2b419e0e..b435b22ae 100644 --- a/src/vulkan/vulkan_loader.cpp +++ b/src/vulkan/vulkan_loader.cpp @@ -4,8 +4,19 @@ namespace dxvk::vk { + static HMODULE loadVulkanLibrary() { +#ifdef _WIN32 + return LoadLibraryA("vulkan-1.dll"); +#else + HMODULE library = LoadLibraryA("libvulkan.so"); + if (!library) + library = LoadLibraryA("libvulkan.so.1"); + return library; +#endif + } + LibraryLoader::LibraryLoader() - : m_library(LoadLibraryA("vulkan-1")) + : m_library(loadVulkanLibrary()) , m_getInstanceProcAddr(reinterpret_cast( GetProcAddress(m_library, "vkGetInstanceProcAddr"))) { } From fa743f162bfbe164fb0d71bda2a13d0bf9464a52 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 2 Sep 2022 11:04:48 +0200 Subject: [PATCH 0743/1348] [dxvk] Don't create queues with QUEUE_FAMILY_IGNORED We accidentally broke drivers which don't support sparse. Closes #2891. Closes #2890. Reported-by: mykhailo.skorokhodov@globallogic.com --- src/dxvk/dxvk_adapter.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 09d2c7994..6d44fd21a 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -477,7 +477,10 @@ namespace dxvk { DxvkAdapterQueueIndices queueFamilies = findQueueFamilies(); queueFamiliySet.insert(queueFamilies.graphics); queueFamiliySet.insert(queueFamilies.transfer); - queueFamiliySet.insert(queueFamilies.sparse); + + if (queueFamilies.sparse != VK_QUEUE_FAMILY_IGNORED) + queueFamiliySet.insert(queueFamilies.sparse); + this->logQueueFamilies(queueFamilies); for (uint32_t family : queueFamiliySet) { From 2659cfc6744a59763776fe3bc42940f9c9b40901 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 1 Sep 2022 16:35:49 +0200 Subject: [PATCH 0744/1348] [native] Add defines for DuplicateHandle flags --- include/native/windows/windows_base.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/native/windows/windows_base.h b/include/native/windows/windows_base.h index 7f0990031..5cdcb9ab6 100644 --- a/include/native/windows/windows_base.h +++ b/include/native/windows/windows_base.h @@ -94,6 +94,7 @@ typedef HANDLE HMODULE; typedef HANDLE HINSTANCE; typedef HANDLE HWND; typedef HANDLE HKEY; +typedef HANDLE *LPHANDLE; typedef DWORD COLORREF; #if INTPTR_MAX == INT64_MAX @@ -321,5 +322,8 @@ typedef struct RGNDATA { #define INVALID_HANDLE_VALUE ((HANDLE)-1) +#define DUPLICATE_CLOSE_SOURCE ((DWORD)0x1) +#define DUPLICATE_SAME_ACCESS ((DWORD)0x2) + #define FAILED(hr) ((HRESULT)(hr) < 0) #define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) From 11ef172c79c73e3af7a55760483a9ea84ddb3775 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 1 Sep 2022 16:36:24 +0200 Subject: [PATCH 0745/1348] [util] Add stubs for DuplicateHandle and GetCurrentProcess --- src/util/util_win32_compat.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/util/util_win32_compat.h b/src/util/util_win32_compat.h index cc05b1b16..74ea6ecea 100644 --- a/src/util/util_win32_compat.h +++ b/src/util/util_win32_compat.h @@ -45,11 +45,28 @@ inline BOOL SetEvent(HANDLE hEvent) { return FALSE; } +inline BOOL DuplicateHandle( + HANDLE hSourceProcessHandle, + HANDLE hSourceHandle, + HANDLE hTargetProcessHandle, + HANDLE* lpTargetHandle, + DWORD dwDesiredAccess, + BOOL bInheritHandle, + DWORD dwOptions) { + dxvk::Logger::warn("DuplicateHandle not implemented."); + return FALSE; +} + inline BOOL CloseHandle(HANDLE hObject) { dxvk::Logger::warn("CloseHandle not implemented."); return FALSE; } +inline HANDLE GetCurrentProcess() { + dxvk::Logger::warn("GetCurrentProcess not implemented."); + return nullptr; +} + inline HDC CreateCompatibleDC(HDC hdc) { dxvk::Logger::warn("CreateCompatibleDC not implemented."); return nullptr; From 17320776f0d1cb642fdf35b592bfe7309cb0fa74 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 1 Sep 2022 16:36:47 +0200 Subject: [PATCH 0746/1348] [dxgi] Duplicate frame latency handle Apps can call CloseHandle on this. --- src/d3d11/d3d11_swapchain.cpp | 13 ++++++++++++- src/d3d11/d3d11_swapchain.h | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 8e007e7d5..21772d539 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -115,7 +115,18 @@ namespace dxvk { HANDLE STDMETHODCALLTYPE D3D11SwapChain::GetFrameLatencyEvent() { - return m_frameLatencyEvent; + HANDLE result = nullptr; + + if (!m_processHandle) + m_processHandle = GetCurrentProcess(); + + if (!DuplicateHandle(m_processHandle, m_frameLatencyEvent, + m_processHandle, &result, 0, FALSE, DUPLICATE_SAME_ACCESS)) { + Logger::err("DxgiSwapChain::GetFrameLatencyWaitableObject: DuplicateHandle failed"); + return nullptr; + } + + return result; } diff --git a/src/d3d11/d3d11_swapchain.h b/src/d3d11/d3d11_swapchain.h index f4debea14..8a006a153 100644 --- a/src/d3d11/d3d11_swapchain.h +++ b/src/d3d11/d3d11_swapchain.h @@ -109,6 +109,8 @@ namespace dxvk { HANDLE m_frameLatencyEvent = nullptr; Rc m_frameLatencySignal; + HANDLE m_processHandle = nullptr; + bool m_dirty = true; bool m_vsync = true; From 439043ddb4db3b03a4f0b3448b1c9b682f978dbf Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 2 Sep 2022 14:29:38 +0200 Subject: [PATCH 0747/1348] [d3d11] Do not implicitly stall waitable swap chains --- src/d3d11/d3d11_swapchain.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 21772d539..7b2ce118d 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -572,7 +572,10 @@ namespace dxvk { uint32_t D3D11SwapChain::GetActualFrameLatency() { - uint32_t maxFrameLatency = m_frameLatency; + // DXGI does not seem to implicitly synchronize waitable swap chains, + // so in that case we should just respect the user config. For regular + // swap chains, pick the latency from the DXGI device. + uint32_t maxFrameLatency = DXGI_MAX_SWAP_CHAIN_BUFFERS; if (!(m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)) m_dxgiDevice->GetMaximumFrameLatency(&maxFrameLatency); From 1b66b8c9f369d2d38d93c2dbe59b333f632a0dea Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 4 Sep 2022 18:05:33 +0200 Subject: [PATCH 0748/1348] [dxvk] Go back to fence-based command list synchronization Timeline semaphores are too unreliable on 32-bit Proton builds. --- src/dxvk/dxvk_cmdlist.cpp | 29 +++++++++++++++++++++++++++-- src/dxvk/dxvk_cmdlist.h | 15 +++++++++++++++ src/dxvk/dxvk_queue.cpp | 34 +++------------------------------- src/dxvk/dxvk_queue.h | 4 ---- 4 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 2026a9162..86c3acbdf 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -39,6 +39,12 @@ namespace dxvk { } + void DxvkCommandSubmission::signalFence( + VkFence fence) { + m_fence = fence; + } + + void DxvkCommandSubmission::executeCommandBuffer( VkCommandBuffer commandBuffer) { VkCommandBufferSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO }; @@ -73,7 +79,7 @@ namespace dxvk { VkResult vr = VK_SUCCESS; if (!this->isEmpty()) - vr = vk->vkQueueSubmit2(queue, 1, &submitInfo, VK_NULL_HANDLE); + vr = vk->vkQueueSubmit2(queue, 1, &submitInfo, m_fence); this->reset(); return vr; @@ -81,6 +87,7 @@ namespace dxvk { void DxvkCommandSubmission::reset() { + m_fence = VK_NULL_HANDLE; m_semaphoreWaits.clear(); m_semaphoreSignals.clear(); m_commandBuffers.clear(); @@ -88,7 +95,8 @@ namespace dxvk { bool DxvkCommandSubmission::isEmpty() const { - return m_semaphoreWaits.empty() + return m_fence == VK_NULL_HANDLE + && m_semaphoreWaits.empty() && m_semaphoreSignals.empty() && m_commandBuffers.empty(); } @@ -171,6 +179,11 @@ namespace dxvk { if (m_vkd->vkCreateSemaphore(m_vkd->device(), &semaphoreInfo, nullptr, &m_sdmaSemaphore)) throw DxvkError("DxvkCommandList: Failed to create semaphore"); + VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; + + if (m_vkd->vkCreateFence(m_vkd->device(), &fenceInfo, nullptr, &m_fence)) + throw DxvkError("DxvkCommandList: Failed to create fence"); + m_graphicsPool = new DxvkCommandPool(device, graphicsQueue.queueFamily); if (transferQueue.queueFamily != graphicsQueue.queueFamily) @@ -286,6 +299,9 @@ namespace dxvk { m_commandSubmission.signalSemaphore(m_wsiSemaphores.present, 0, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); } + + // Signal synchronization fence on final submission + m_commandSubmission.signalFence(m_fence); } // Finally, submit all graphics commands of the current submission @@ -350,6 +366,11 @@ namespace dxvk { } + VkResult DxvkCommandList::synchronizeFence() { + return m_vkd->vkWaitForFences(m_vkd->device(), 1, &m_fence, VK_TRUE, ~0ull); + } + + void DxvkCommandList::reset() { // Free resources and other objects // that are no longer in use @@ -389,6 +410,10 @@ namespace dxvk { // Reset actual command buffers and pools m_graphicsPool->reset(); m_transferPool->reset(); + + // Reset fence + if (m_vkd->vkResetFences(m_vkd->device(), 1, &m_fence)) + Logger::err("DxvkCommandList: Failed to reset fence"); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index fc096b016..45f67c6d4 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -72,6 +72,13 @@ namespace dxvk { uint64_t value, VkPipelineStageFlags2 stageMask); + /** + * \brief Adds a fence to signal + * \param [in] fence The fence + */ + void signalFence( + VkFence fence); + /** * \brief Adds a command buffer to execute * \param [in] commandBuffer The command buffer @@ -105,6 +112,7 @@ namespace dxvk { private: + VkFence m_fence = VK_NULL_HANDLE; std::vector m_semaphoreWaits; std::vector m_semaphoreSignals; std::vector m_commandBuffers; @@ -359,6 +367,12 @@ namespace dxvk { m_wsiSemaphores = wsiSemaphores; } + /** + * \brief Synchronizes with command list fence + * \returns Return value of vkWaitForFences call + */ + VkResult synchronizeFence(); + /** * \brief Resets the command list * @@ -996,6 +1010,7 @@ namespace dxvk { Rc m_transferPool; VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE; + VkFence m_fence = VK_NULL_HANDLE; DxvkCommandSubmissionInfo m_cmd; diff --git a/src/dxvk/dxvk_queue.cpp b/src/dxvk/dxvk_queue.cpp index 2db3fdd36..520a901e3 100644 --- a/src/dxvk/dxvk_queue.cpp +++ b/src/dxvk/dxvk_queue.cpp @@ -32,8 +32,6 @@ namespace dxvk { m_submitThread.join(); m_finishThread.join(); - synchronizeSemaphore(m_semaphoreValue); - vk->vkDestroySemaphore(vk->device(), m_semaphore, nullptr); } @@ -95,30 +93,6 @@ namespace dxvk { } - VkResult DxvkSubmissionQueue::synchronizeSemaphore( - uint64_t semaphoreValue) { - auto vk = m_device->vkd(); - - VkSemaphoreWaitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO }; - waitInfo.semaphoreCount = 1; - waitInfo.pSemaphores = &m_semaphore; - waitInfo.pValues = &semaphoreValue; - - // 32-bit winevulkan on Proton seems to be broken here - // and returns with VK_TIMEOUT, even though the timeout - // is infinite. Work around this by spinning. - VkResult vr = VK_TIMEOUT; - - while (vr == VK_TIMEOUT) - vr = vk->vkWaitSemaphores(vk->device(), &waitInfo, ~0ull); - - if (vr) - Logger::err(str::format("Failed to synchronize with global timeline semaphore: ", vr)); - - return vr; - } - - void DxvkSubmissionQueue::submitCmdLists() { env::setThreadName("dxvk-submit"); @@ -141,12 +115,10 @@ namespace dxvk { if (m_lastError != VK_ERROR_DEVICE_LOST) { std::lock_guard lock(m_mutexQueue); - if (entry.submit.cmdList != nullptr) { + if (entry.submit.cmdList != nullptr) status = entry.submit.cmdList->submit(m_semaphore, m_semaphoreValue); - entry.submit.semaphoreValue = m_semaphoreValue; - } else if (entry.present.presenter != nullptr) { + else if (entry.present.presenter != nullptr) status = entry.present.presenter->presentImage(); - } } else { // Don't submit anything after device loss // so that drivers get a chance to recover @@ -200,7 +172,7 @@ namespace dxvk { VkResult status = m_lastError.load(); if (status != VK_ERROR_DEVICE_LOST) - status = synchronizeSemaphore(entry.submit.semaphoreValue); + status = entry.submit.cmdList->synchronizeFence(); if (status != VK_SUCCESS) { m_lastError = status; diff --git a/src/dxvk/dxvk_queue.h b/src/dxvk/dxvk_queue.h index 370c763b1..8f589b558 100644 --- a/src/dxvk/dxvk_queue.h +++ b/src/dxvk/dxvk_queue.h @@ -33,7 +33,6 @@ namespace dxvk { */ struct DxvkSubmitInfo { Rc cmdList; - uint64_t semaphoreValue; }; @@ -200,9 +199,6 @@ namespace dxvk { dxvk::thread m_submitThread; dxvk::thread m_finishThread; - VkResult synchronizeSemaphore( - uint64_t semaphoreValue); - void submitCmdLists(); void finishCmdLists(); From 019ebeeaf72a01c5b19022602140775c90bfc51f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 3 Sep 2022 21:15:36 +0200 Subject: [PATCH 0749/1348] [dxvk] Introduce pseudo-features for extensions with no feature struct Makes it easier to keep track of supported extensions. --- src/dxvk/dxvk_adapter.cpp | 105 +++++++++++++++++++++++++++++++----- src/dxvk/dxvk_device_info.h | 9 ++++ 2 files changed, 101 insertions(+), 13 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 6d44fd21a..03792a198 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -252,6 +252,8 @@ namespace dxvk { || !required.vk13.maintenance4) && (m_deviceFeatures.extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout || !required.extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout) + && (m_deviceFeatures.extConservativeRasterization + || !required.extConservativeRasterization) && (m_deviceFeatures.extCustomBorderColor.customBorderColors || !required.extCustomBorderColor.customBorderColors) && (m_deviceFeatures.extCustomBorderColor.customBorderColorWithoutFormat @@ -260,6 +262,8 @@ namespace dxvk { || !required.extDepthClipEnable.depthClipEnable) && (m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary || !required.extGraphicsPipelineLibrary.graphicsPipelineLibrary) + && (m_deviceFeatures.extMemoryBudget + || !required.extMemoryBudget) && (m_deviceFeatures.extMemoryPriority.memoryPriority || !required.extMemoryPriority.memoryPriority) && (m_deviceFeatures.extNonSeamlessCubeMap.nonSeamlessCubeMap @@ -272,6 +276,8 @@ namespace dxvk { || !required.extRobustness2.nullDescriptor) && (m_deviceFeatures.extShaderModuleIdentifier.shaderModuleIdentifier || !required.extShaderModuleIdentifier.shaderModuleIdentifier) + && (m_deviceFeatures.extShaderStencilExport + || !required.extShaderStencilExport) && (m_deviceFeatures.extTransformFeedback.transformFeedback || !required.extTransformFeedback.transformFeedback) && (m_deviceFeatures.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor @@ -390,17 +396,6 @@ namespace dxvk { enabledFeatures.extShaderModuleIdentifier.shaderModuleIdentifier = m_deviceFeatures.extShaderModuleIdentifier.shaderModuleIdentifier; - Logger::info(str::format("Device properties:" - "\n Device name: : ", m_deviceInfo.core.properties.deviceName, - "\n Driver version : ", - VK_VERSION_MAJOR(m_deviceInfo.core.properties.driverVersion), ".", - VK_VERSION_MINOR(m_deviceInfo.core.properties.driverVersion), ".", - VK_VERSION_PATCH(m_deviceInfo.core.properties.driverVersion))); - - Logger::info("Enabled device extensions:"); - this->logNameList(extensionNameList); - this->logFeatures(enabledFeatures); - // Create pNext chain for additional device features enabledFeatures.core.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; enabledFeatures.core.pNext = nullptr; @@ -414,11 +409,17 @@ namespace dxvk { enabledFeatures.vk13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; enabledFeatures.vk13.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.vk13); + if (devExtensions.amdShaderFragmentMask) + enabledFeatures.amdShaderFragmentMask = VK_TRUE; + if (devExtensions.extAttachmentFeedbackLoopLayout) { enabledFeatures.extAttachmentFeedbackLoopLayout.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT; enabledFeatures.extAttachmentFeedbackLoopLayout.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extAttachmentFeedbackLoopLayout); } + if (devExtensions.extConservativeRasterization) + enabledFeatures.extConservativeRasterization = VK_TRUE; + if (devExtensions.extCustomBorderColor) { enabledFeatures.extCustomBorderColor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT; enabledFeatures.extCustomBorderColor.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extCustomBorderColor); @@ -429,11 +430,17 @@ namespace dxvk { enabledFeatures.extDepthClipEnable.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extDepthClipEnable); } + if (devExtensions.extFullScreenExclusive) + enabledFeatures.extFullScreenExclusive = VK_TRUE; + if (devExtensions.extGraphicsPipelineLibrary) { enabledFeatures.extGraphicsPipelineLibrary.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT; enabledFeatures.extGraphicsPipelineLibrary.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extGraphicsPipelineLibrary); } + if (devExtensions.extMemoryBudget) + enabledFeatures.extMemoryBudget = VK_TRUE; + if (devExtensions.extMemoryPriority) { enabledFeatures.extMemoryPriority.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT; enabledFeatures.extMemoryPriority.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extMemoryPriority); @@ -454,6 +461,9 @@ namespace dxvk { enabledFeatures.extRobustness2.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extRobustness2); } + if (devExtensions.extShaderStencilExport) + enabledFeatures.extShaderStencilExport = VK_TRUE; + if (devExtensions.extTransformFeedback) { enabledFeatures.extTransformFeedback.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; enabledFeatures.extTransformFeedback.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extTransformFeedback); @@ -464,10 +474,34 @@ namespace dxvk { enabledFeatures.extVertexAttributeDivisor.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extVertexAttributeDivisor); } + if (devExtensions.khrExternalMemoryWin32) + enabledFeatures.khrExternalMemoryWin32 = VK_TRUE; + + if (devExtensions.khrExternalSemaphoreWin32) + enabledFeatures.khrExternalSemaphoreWin32 = VK_TRUE; + + if (devExtensions.nvxBinaryImport) + enabledFeatures.nvxBinaryImport = VK_TRUE; + + if (devExtensions.nvxImageViewHandle) + enabledFeatures.nvxImageViewHandle = VK_TRUE; + + // Log feature support info an extension list + Logger::info(str::format("Device properties:" + "\n Device name: : ", m_deviceInfo.core.properties.deviceName, + "\n Driver version : ", + VK_VERSION_MAJOR(m_deviceInfo.core.properties.driverVersion), ".", + VK_VERSION_MINOR(m_deviceInfo.core.properties.driverVersion), ".", + VK_VERSION_PATCH(m_deviceInfo.core.properties.driverVersion))); + + Logger::info("Enabled device extensions:"); + this->logNameList(extensionNameList); + this->logFeatures(enabledFeatures); + // Report the desired overallocation behaviour to the driver VkDeviceMemoryOverallocationCreateInfoAMD overallocInfo = { VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD }; overallocInfo.overallocationBehavior = VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD; - + // Create the requested queues float queuePriority = 1.0f; std::vector queueInfos; @@ -698,11 +732,17 @@ namespace dxvk { m_deviceFeatures.vk13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; m_deviceFeatures.vk13.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.vk13); + if (m_deviceExtensions.supports(VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME)) + m_deviceFeatures.amdShaderFragmentMask = VK_TRUE; + if (m_deviceExtensions.supports(VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME)) { m_deviceFeatures.extAttachmentFeedbackLoopLayout.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT; m_deviceFeatures.extAttachmentFeedbackLoopLayout.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extAttachmentFeedbackLoopLayout); } + if (m_deviceExtensions.supports(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) + m_deviceFeatures.extConservativeRasterization = VK_TRUE; + if (m_deviceExtensions.supports(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME)) { m_deviceFeatures.extCustomBorderColor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT; m_deviceFeatures.extCustomBorderColor.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extCustomBorderColor); @@ -713,11 +753,17 @@ namespace dxvk { m_deviceFeatures.extDepthClipEnable.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extDepthClipEnable); } + if (m_deviceExtensions.supports(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)) + m_deviceFeatures.extFullScreenExclusive = VK_TRUE; + if (m_deviceExtensions.supports(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME)) { m_deviceFeatures.extGraphicsPipelineLibrary.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT; m_deviceFeatures.extGraphicsPipelineLibrary.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extGraphicsPipelineLibrary); } + if (m_deviceExtensions.supports(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME)) + m_deviceFeatures.extMemoryBudget = VK_TRUE; + if (m_deviceExtensions.supports(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME)) { m_deviceFeatures.extMemoryPriority.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT; m_deviceFeatures.extMemoryPriority.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extMemoryPriority); @@ -738,6 +784,9 @@ namespace dxvk { m_deviceFeatures.extShaderModuleIdentifier.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extShaderModuleIdentifier); } + if (m_deviceExtensions.supports(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME)) + m_deviceFeatures.extShaderStencilExport = VK_TRUE; + if (m_deviceExtensions.supports(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) { m_deviceFeatures.extTransformFeedback.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; m_deviceFeatures.extTransformFeedback.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extTransformFeedback); @@ -748,6 +797,18 @@ namespace dxvk { m_deviceFeatures.extVertexAttributeDivisor.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extVertexAttributeDivisor); } + if (m_deviceExtensions.supports(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME)) + m_deviceFeatures.khrExternalMemoryWin32 = VK_TRUE; + + if (m_deviceExtensions.supports(VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME)) + m_deviceFeatures.khrExternalSemaphoreWin32 = VK_TRUE; + + if (m_deviceExtensions.supports(VK_NVX_BINARY_IMPORT_EXTENSION_NAME)) + m_deviceFeatures.nvxBinaryImport = VK_TRUE; + + if (m_deviceExtensions.supports(VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME)) + m_deviceFeatures.nvxImageViewHandle = VK_TRUE; + m_vki->vkGetPhysicalDeviceFeatures2(m_handle, &m_deviceFeatures.core); } @@ -840,15 +901,23 @@ namespace dxvk { "\n shaderZeroInitializeWorkgroupMemory : ", features.vk13.shaderZeroInitializeWorkgroupMemory, "\n synchronization2 : ", features.vk13.synchronization2, "\n dynamicRendering : ", features.vk13.dynamicRendering, + "\n", VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME, + "\n extension supported : ", features.amdShaderFragmentMask ? "1" : "0", "\n", VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME, "\n attachmentFeedbackLoopLayout : ", features.extAttachmentFeedbackLoopLayout.attachmentFeedbackLoopLayout ? "1" : "0", + "\n", VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, + "\n extension supported : ", features.extConservativeRasterization ? "1" : "0", "\n", VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, "\n customBorderColors : ", features.extCustomBorderColor.customBorderColors ? "1" : "0", "\n customBorderColorWithoutFormat : ", features.extCustomBorderColor.customBorderColorWithoutFormat ? "1" : "0", "\n", VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, "\n depthClipEnable : ", features.extDepthClipEnable.depthClipEnable ? "1" : "0", + "\n", VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, + "\n extension supported : ", features.extFullScreenExclusive ? "1" : "0", "\n", VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, "\n graphicsPipelineLibrary : ", features.extGraphicsPipelineLibrary.graphicsPipelineLibrary ? "1" : "0", + "\n", VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, + "\n extension supported : ", features.extMemoryBudget ? "1" : "0", "\n", VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, "\n memoryPriority : ", features.extMemoryPriority.memoryPriority ? "1" : "0", "\n", VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME, @@ -859,12 +928,22 @@ namespace dxvk { "\n nullDescriptor : ", features.extRobustness2.nullDescriptor ? "1" : "0", "\n", VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME, "\n shaderModuleIdentifier : ", features.extShaderModuleIdentifier.shaderModuleIdentifier ? "1" : "0", + "\n", VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, + "\n extension supported : ", features.extShaderStencilExport ? "1" : "0", "\n", VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, "\n transformFeedback : ", features.extTransformFeedback.transformFeedback ? "1" : "0", "\n geometryStreams : ", features.extTransformFeedback.geometryStreams ? "1" : "0", "\n", VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, "\n vertexAttributeInstanceRateDivisor : ", features.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor ? "1" : "0", - "\n vertexAttributeInstanceRateZeroDivisor : ", features.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor ? "1" : "0")); + "\n vertexAttributeInstanceRateZeroDivisor : ", features.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor ? "1" : "0", + "\n", VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, + "\n extension supported : ", features.khrExternalMemoryWin32 ? "1" : "0", + "\n", VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, + "\n extension supported : ", features.khrExternalSemaphoreWin32 ? "1" : "0", + "\n", VK_NVX_BINARY_IMPORT_EXTENSION_NAME, + "\n extension supported : ", features.nvxBinaryImport ? "1" : "0", + "\n", VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME, + "\n extension supported : ", features.nvxImageViewHandle ? "1" : "0")); } diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 895dfcb84..b5f8f587e 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -38,16 +38,25 @@ namespace dxvk { VkPhysicalDeviceVulkan11Features vk11; VkPhysicalDeviceVulkan12Features vk12; VkPhysicalDeviceVulkan13Features vk13; + VkBool32 amdShaderFragmentMask; VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT extAttachmentFeedbackLoopLayout; + VkBool32 extConservativeRasterization; VkPhysicalDeviceCustomBorderColorFeaturesEXT extCustomBorderColor; VkPhysicalDeviceDepthClipEnableFeaturesEXT extDepthClipEnable; + VkBool32 extFullScreenExclusive; VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT extGraphicsPipelineLibrary; + VkBool32 extMemoryBudget; VkPhysicalDeviceMemoryPriorityFeaturesEXT extMemoryPriority; VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT extNonSeamlessCubeMap; VkPhysicalDeviceRobustness2FeaturesEXT extRobustness2; VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT extShaderModuleIdentifier; + VkBool32 extShaderStencilExport; VkPhysicalDeviceTransformFeedbackFeaturesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT extVertexAttributeDivisor; + VkBool32 khrExternalMemoryWin32; + VkBool32 khrExternalSemaphoreWin32; + VkBool32 nvxBinaryImport; + VkBool32 nvxImageViewHandle; }; } \ No newline at end of file From 51e0a56243a11ab538d33413599800b82e09c6f8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 3 Sep 2022 21:20:35 +0200 Subject: [PATCH 0750/1348] [dxvk] Use new pseudo-features where applicable --- src/dxvk/dxvk_device.cpp | 4 ++-- src/dxvk/dxvk_graphics.cpp | 2 +- src/dxvk/dxvk_image.cpp | 2 +- src/dxvk/dxvk_memory.cpp | 2 +- src/dxvk/dxvk_meta_copy.cpp | 2 +- src/dxvk/dxvk_meta_resolve.cpp | 4 ++-- src/dxvk/dxvk_swapchain_blitter.cpp | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 94cc0e528..769635b48 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -323,11 +323,11 @@ namespace dxvk { DxvkDevicePerfHints DxvkDevice::getPerfHints() { DxvkDevicePerfHints hints; - hints.preferFbDepthStencilCopy = m_extensions.extShaderStencilExport + hints.preferFbDepthStencilCopy = m_features.extShaderStencilExport && (m_adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV_KHR, 0, 0) || m_adapter->matchesDriver(VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR, 0, 0) || m_adapter->matchesDriver(VK_DRIVER_ID_AMD_PROPRIETARY_KHR, 0, 0)); - hints.preferFbResolve = m_extensions.amdShaderFragmentMask + hints.preferFbResolve = m_features.amdShaderFragmentMask && (m_adapter->matchesDriver(VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR, 0, 0) || m_adapter->matchesDriver(VK_DRIVER_ID_AMD_PROPRIETARY_KHR, 0, 0)); return hints; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 4285d04e1..8b0a65502 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -1362,7 +1362,7 @@ namespace dxvk { // Validate rasterization state if (state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT) { - if (!m_device->extensions().extConservativeRasterization) + if (!m_device->features().extConservativeRasterization) return false; if (state.rs.conservativeMode() == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index 0cf60e3da..8c3a1bc89 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -182,7 +182,7 @@ namespace dxvk { if (sharingInfo.mode == DxvkSharedHandleMode::None) return false; - if (!m_device->extensions().khrExternalMemoryWin32) { + if (!m_device->features().khrExternalMemoryWin32) { Logger::err("Failed to create shared resource: VK_KHR_EXTERNAL_MEMORY_WIN32 not supported"); return false; } diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 135bf9991..c51f2ea7d 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -278,7 +278,7 @@ namespace dxvk { Logger::err(str::format("Heap ", i, ": ", (m_memHeaps[i].stats.memoryAllocated >> 20), " MB allocated, ", (m_memHeaps[i].stats.memoryUsed >> 20), " MB used, ", - m_device->extensions().extMemoryBudget + m_device->features().extMemoryBudget ? str::format( (memHeapInfo.heaps[i].memoryAllocated >> 20), " MB allocated (driver), ", (memHeapInfo.heaps[i].memoryBudget >> 20), " MB budget (driver), ", diff --git a/src/dxvk/dxvk_meta_copy.cpp b/src/dxvk/dxvk_meta_copy.cpp index 4368f13da..a3be19c82 100644 --- a/src/dxvk/dxvk_meta_copy.cpp +++ b/src/dxvk/dxvk_meta_copy.cpp @@ -96,7 +96,7 @@ namespace dxvk { m_shaderGeom = createShaderModule(dxvk_fullscreen_geom); } - if (device->extensions().extShaderStencilExport) { + if (device->features().extShaderStencilExport) { m_depthStencil = { createShaderModule(dxvk_copy_depth_stencil_1d), createShaderModule(dxvk_copy_depth_stencil_2d), diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index 26cde48e5..7e3dfd2e8 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -55,13 +55,13 @@ namespace dxvk { DxvkMetaResolveObjects::DxvkMetaResolveObjects(const DxvkDevice* device) : m_vkd (device->vkd()), m_sampler (createSampler()), - m_shaderFragF (device->extensions().amdShaderFragmentMask + m_shaderFragF (device->features().amdShaderFragmentMask ? createShaderModule(dxvk_resolve_frag_f_amd) : createShaderModule(dxvk_resolve_frag_f)), m_shaderFragU (createShaderModule(dxvk_resolve_frag_u)), m_shaderFragI (createShaderModule(dxvk_resolve_frag_i)), m_shaderFragD (createShaderModule(dxvk_resolve_frag_d)) { - if (device->extensions().extShaderStencilExport) + if (device->features().extShaderStencilExport) m_shaderFragDS = createShaderModule(dxvk_resolve_frag_ds); if (device->features().vk12.shaderOutputLayer) { diff --git a/src/dxvk/dxvk_swapchain_blitter.cpp b/src/dxvk/dxvk_swapchain_blitter.cpp index d1c03a7f5..f71bd732b 100644 --- a/src/dxvk/dxvk_swapchain_blitter.cpp +++ b/src/dxvk/dxvk_swapchain_blitter.cpp @@ -342,7 +342,7 @@ namespace dxvk { fsInfo.inputMask = 0; m_fsCopy = new DxvkShader(fsInfo, std::move(fsCodeCopy)); - m_fsResolve = new DxvkShader(fsInfo, m_device->extensions().amdShaderFragmentMask + m_fsResolve = new DxvkShader(fsInfo, m_device->features().amdShaderFragmentMask ? std::move(fsCodeResolveAmd) : std::move(fsCodeResolve)); } From ff6a6e2d378d858da2d669fc6a27a40136866114 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 3 Sep 2022 21:21:02 +0200 Subject: [PATCH 0751/1348] [d3d11] Use new pseudo-features where applicable --- src/d3d11/d3d11_device.cpp | 15 ++++++--------- src/d3d11/d3d11_swapchain.cpp | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 0865f0e77..0aa9355cc 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1134,7 +1134,7 @@ namespace dxvk { return E_INVALIDARG; if (desc.ConservativeRaster != D3D11_CONSERVATIVE_RASTERIZATION_MODE_OFF - && !m_dxvkDevice->extensions().extConservativeRasterization) + && !m_dxvkDevice->features().extConservativeRasterization) return E_INVALIDARG; if (!ppRasterizerState) @@ -1700,9 +1700,7 @@ namespace dxvk { if (FeatureSupportDataSize != sizeof(*info)) return E_INVALIDARG; - const auto& extensions = m_dxvkDevice->extensions(); - - info->PSSpecifiedStencilRefSupported = extensions.extShaderStencilExport; + info->PSSpecifiedStencilRefSupported = m_dxvkDevice->features().extShaderStencilExport; info->TypedUAVLoadAdditionalFormats = m_dxbcOptions.supportsTypedUavLoadExtended; info->ROVsSupported = FALSE; info->ConservativeRasterizationTier = D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED; @@ -1711,7 +1709,7 @@ namespace dxvk { info->StandardSwizzle = FALSE; info->UnifiedMemoryArchitecture = m_dxvkDevice->isUnifiedMemoryArchitecture(); - if (m_dxvkDevice->extensions().extConservativeRasterization) { + if (m_dxvkDevice->features().extConservativeRasterization) { // We don't have a way to query uncertainty regions, so just check degenerate triangle behaviour info->ConservativeRasterizationTier = m_dxvkDevice->properties().extConservativeRasterization.degenerateTrianglesRasterized ? D3D11_CONSERVATIVE_RASTERIZATION_TIER_2 : D3D11_CONSERVATIVE_RASTERIZATION_TIER_1; @@ -2150,7 +2148,7 @@ namespace dxvk { auto shader = commonShader.GetShader(); if (shader->flags().test(DxvkShaderFlag::ExportsStencilRef) - && !m_dxvkDevice->extensions().extShaderStencilExport) + && !m_dxvkDevice->features().extShaderStencilExport) return E_INVALIDARG; if (shader->flags().test(DxvkShaderFlag::ExportsViewportIndexLayerFromVertexStage) @@ -2655,7 +2653,6 @@ namespace dxvk { BOOL STDMETHODCALLTYPE D3D11DeviceExt::GetExtensionSupport( D3D11_VK_EXTENSION Extension) { const auto& deviceFeatures = m_device->GetDXVKDevice()->features(); - const auto& deviceExtensions = m_device->GetDXVKDevice()->extensions(); switch (Extension) { case D3D11_VK_EXT_BARRIER_CONTROL: @@ -2672,10 +2669,10 @@ namespace dxvk { return deviceFeatures.core.features.depthBounds; case D3D11_VK_NVX_IMAGE_VIEW_HANDLE: - return deviceExtensions.nvxImageViewHandle; + return deviceFeatures.nvxImageViewHandle; case D3D11_VK_NVX_BINARY_IMPORT: - return deviceExtensions.nvxBinaryImport + return deviceFeatures.nvxBinaryImport && deviceFeatures.vk12.bufferDeviceAddress; default: diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 7b2ce118d..cc128411b 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -401,7 +401,7 @@ namespace dxvk { presenterDevice.queueFamily = graphicsQueue.queueFamily; presenterDevice.queue = graphicsQueue.queueHandle; presenterDevice.adapter = m_device->adapter()->handle(); - presenterDevice.features.fullScreenExclusive = m_device->extensions().extFullScreenExclusive; + presenterDevice.features.fullScreenExclusive = m_device->features().extFullScreenExclusive; vk::PresenterDesc presenterDesc; presenterDesc.imageExtent = { m_desc.Width, m_desc.Height }; From 8d9d9912ff1e6ef8706eeaaa26709d8f602c0858 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 3 Sep 2022 21:21:21 +0200 Subject: [PATCH 0752/1348] [dxvk] Remove extension info from DXVK device --- src/dxvk/dxvk_adapter.cpp | 2 +- src/dxvk/dxvk_device.cpp | 2 -- src/dxvk/dxvk_device.h | 10 ---------- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 03792a198..e90378fae 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -561,7 +561,7 @@ namespace dxvk { return new DxvkDevice(instance, this, new vk::DeviceFn(m_vki, true, device), - devExtensions, enabledFeatures); + enabledFeatures); } diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 769635b48..79c39c868 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -7,13 +7,11 @@ namespace dxvk { const Rc& instance, const Rc& adapter, const Rc& vkd, - const DxvkDeviceExtensions& extensions, const DxvkDeviceFeatures& features) : m_options (instance->options()), m_instance (instance), m_adapter (adapter), m_vkd (vkd), - m_extensions (extensions), m_features (features), m_properties (adapter->devicePropertiesExt()), m_perfHints (getPerfHints()), diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 9ee2744a9..8f9265f48 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -88,7 +88,6 @@ namespace dxvk { const Rc& instance, const Rc& adapter, const Rc& vkd, - const DxvkDeviceExtensions& extensions, const DxvkDeviceFeatures& features); ~DxvkDevice(); @@ -158,14 +157,6 @@ namespace dxvk { return m_adapter; } - /** - * \brief Enabled device extensions - * \returns Enabled device extensions - */ - const DxvkDeviceExtensions& extensions() const { - return m_extensions; - } - /** * \brief Enabled device features * \returns Enabled features @@ -524,7 +515,6 @@ namespace dxvk { Rc m_instance; Rc m_adapter; Rc m_vkd; - DxvkDeviceExtensions m_extensions; DxvkDeviceFeatures m_features; DxvkDeviceInfo m_properties; From c4516c5b04aa7805ca0031727f379a20f49d69d8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 4 Sep 2022 15:41:37 +0200 Subject: [PATCH 0753/1348] [dxvk] Improve behaviour when variableMultisampleRate is not supported --- src/dxvk/dxvk_adapter.cpp | 7 +++++++ src/dxvk/dxvk_context.cpp | 12 ++++++++++++ src/dxvk/dxvk_context_state.h | 1 + 3 files changed, 20 insertions(+) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index e90378fae..0d9336849 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -349,6 +349,13 @@ namespace dxvk { extensionsEnabled.merge(m_extraExtensions); DxvkNameList extensionNameList = extensionsEnabled.toNameList(); + // Always enable robust buffer access + enabledFeatures.core.features.robustBufferAccess = VK_TRUE; + + // Enable variable multisample rate if supported + enabledFeatures.core.features.variableMultisampleRate = + m_deviceFeatures.core.features.variableMultisampleRate; + // Optionally used by some client API extensions enabledFeatures.vk12.drawIndirectCount = m_deviceFeatures.vk12.drawIndirectCount; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 1bb99be28..b79e47717 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -54,6 +54,13 @@ namespace dxvk { // that we don't have to scan device features at draw time if (m_device->mustTrackPipelineLifetime()) m_features.set(DxvkContextFeature::TrackGraphicsPipeline); + + // Variable multisample rate is needed to efficiently support + // rendering without bound render targets, otherwise we may + // have to interrupt the current render pass whenever the + // requested rasterizer sample count changes + if (m_device->features().core.features.variableMultisampleRate) + m_features.set(DxvkContextFeature::VariableMultisampleRate); } @@ -2458,6 +2465,11 @@ namespace dxvk { m_flags.set(DxvkContextFlag::GpDirtyRasterizerState); } + if (unlikely(!m_features.test(DxvkContextFeature::VariableMultisampleRate))) { + if (rs.sampleCount != m_state.gp.state.rs.sampleCount()) + m_flags.set(DxvkContextFlag::GpDirtyFramebuffer); + } + DxvkRsInfo rsInfo( rs.depthClipEnable, rs.depthBiasEnable, diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index c13d996ca..922d2fb72 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -62,6 +62,7 @@ namespace dxvk { */ enum class DxvkContextFeature : uint32_t { TrackGraphicsPipeline, + VariableMultisampleRate, FeatureCount }; From 5490aa936baee49ff5ffbd76ac7370eba1783819 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 3 Sep 2022 15:24:40 +0200 Subject: [PATCH 0754/1348] [d3d11] Rework D3D11 feature enablement Rather than enabling based on requested feature levels, always enable all supported features that we might use, and report the maximum feature level based on that. This fixes an issue in CreateDeviceContextState which may raise the device feature level, and another issue wherein the feature level override is ignored if tiled resources are not supported. --- src/d3d11/d3d11_device.cpp | 285 +++++++++++++++++-------------------- src/d3d11/d3d11_device.h | 14 +- src/d3d11/d3d11_main.cpp | 36 ++--- src/dxvk/dxvk_adapter.cpp | 4 + 4 files changed, 158 insertions(+), 181 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 0aa9355cc..b58349dd3 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -38,14 +38,15 @@ namespace dxvk { D3D11DXGIDevice* pContainer, D3D_FEATURE_LEVEL FeatureLevel, UINT FeatureFlags) - : m_container (pContainer), - m_featureLevel (FeatureLevel), - m_featureFlags (FeatureFlags), - m_dxvkDevice (pContainer->GetDXVKDevice()), - m_dxvkAdapter (m_dxvkDevice->adapter()), - m_d3d11Formats (m_dxvkDevice), - m_d3d11Options (m_dxvkDevice->instance()->config(), m_dxvkDevice), - m_dxbcOptions (m_dxvkDevice, m_d3d11Options), + : m_container (pContainer), + m_featureLevel (FeatureLevel), + m_featureFlags (FeatureFlags), + m_dxvkDevice (pContainer->GetDXVKDevice()), + m_dxvkAdapter (m_dxvkDevice->adapter()), + m_d3d11Formats (m_dxvkDevice), + m_d3d11Options (m_dxvkDevice->instance()->config(), m_dxvkDevice), + m_dxbcOptions (m_dxvkDevice, m_d3d11Options), + m_maxFeatureLevel (GetMaxFeatureLevel(m_dxvkDevice->instance(), m_dxvkDevice->adapter())), m_tiledResourcesTier(DetermineTiledResourcesTier(m_dxvkDevice->features(), m_dxvkDevice->properties())) { m_initializer = new D3D11Initializer(this); m_context = new D3D11ImmediateContext(this, m_dxvkDevice); @@ -1308,33 +1309,36 @@ namespace dxvk { ID3DDeviceContextState** ppContextState) { InitReturnPtr(ppContextState); - if (!pFeatureLevels || FeatureLevels == 0) + if (!pFeatureLevels || !FeatureLevels) return E_INVALIDARG; - + if (EmulatedInterface != __uuidof(ID3D10Device) && EmulatedInterface != __uuidof(ID3D10Device1) && EmulatedInterface != __uuidof(ID3D11Device) && EmulatedInterface != __uuidof(ID3D11Device1)) return E_INVALIDARG; - - UINT flId; - for (flId = 0; flId < FeatureLevels; flId++) { - if (CheckFeatureLevelSupport(m_dxvkDevice->instance(), m_dxvkAdapter, pFeatureLevels[flId])) + + D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL(); + + for (uint32_t flId = 0; flId < FeatureLevels; flId++) { + if (pFeatureLevels[flId] <= m_maxFeatureLevel) { + featureLevel = pFeatureLevels[flId]; break; + } } - if (flId == FeatureLevels) + if (!featureLevel) return E_INVALIDARG; - if (pFeatureLevels[flId] > m_featureLevel) - m_featureLevel = pFeatureLevels[flId]; - + if (m_featureLevel < featureLevel) + m_featureLevel = featureLevel; + if (pChosenFeatureLevel) - *pChosenFeatureLevel = pFeatureLevels[flId]; - + *pChosenFeatureLevel = featureLevel; + if (!ppContextState) return S_FALSE; - + *ppContextState = ref(new D3D11DeviceContextState(this)); return S_OK; } @@ -1991,43 +1995,86 @@ namespace dxvk { } - bool D3D11Device::CheckFeatureLevelSupport( - const Rc& instance, - const Rc& adapter, - D3D_FEATURE_LEVEL featureLevel) { - if (featureLevel > GetMaxFeatureLevel(instance)) - return false; + D3D_FEATURE_LEVEL D3D11Device::GetMaxFeatureLevel( + const Rc& Instance, + const Rc& Adapter) { + // Check whether baseline features are supported by the device + DxvkDeviceFeatures features = GetDeviceFeatures(Adapter); - // Check whether all features are supported - const DxvkDeviceFeatures features - = GetDeviceFeatures(adapter, featureLevel); - - if (!adapter->checkFeatureSupport(features)) - return false; - - if (featureLevel >= D3D_FEATURE_LEVEL_12_0) { - D3D11_TILED_RESOURCES_TIER tiledResourcesTier = DetermineTiledResourcesTier( - adapter->features(), - adapter->devicePropertiesExt()); + if (!Adapter->checkFeatureSupport(features)) + return D3D_FEATURE_LEVEL(); - if (tiledResourcesTier < D3D11_TILED_RESOURCES_TIER_2) - return false; - } + // The feature level override always takes precedence + static const std::array, 9> s_featureLevels = {{ + { "12_1", D3D_FEATURE_LEVEL_12_1 }, + { "12_0", D3D_FEATURE_LEVEL_12_0 }, + { "11_1", D3D_FEATURE_LEVEL_11_1 }, + { "11_0", D3D_FEATURE_LEVEL_11_0 }, + { "10_1", D3D_FEATURE_LEVEL_10_1 }, + { "10_0", D3D_FEATURE_LEVEL_10_0 }, + { "9_3", D3D_FEATURE_LEVEL_9_3 }, + { "9_2", D3D_FEATURE_LEVEL_9_2 }, + { "9_1", D3D_FEATURE_LEVEL_9_1 }, + }}; + + std::string maxLevel = Instance->config().getOption("d3d11.maxFeatureLevel"); - // TODO also check for required limits - return true; + auto entry = std::find_if(s_featureLevels.begin(), s_featureLevels.end(), + [&] (const std::pair& pair) { + return pair.first == maxLevel; + }); + + if (entry != s_featureLevels.end()) + return entry->second; + + // Check Feature Level 11_0 features + if (!features.core.features.drawIndirectFirstInstance + || !features.core.features.fragmentStoresAndAtomics + || !features.core.features.multiDrawIndirect + || !features.core.features.tessellationShader) + return D3D_FEATURE_LEVEL_10_1; + + // Check Feature Level 11_1 features + if (!features.core.features.logicOp + || !features.core.features.variableMultisampleRate + || !features.core.features.vertexPipelineStoresAndAtomics) + return D3D_FEATURE_LEVEL_11_0; + + // Check Feature Level 12_0 features + D3D11_TILED_RESOURCES_TIER tiledResourcesTier = DetermineTiledResourcesTier( + Adapter->features(), + Adapter->devicePropertiesExt()); + + if (tiledResourcesTier < D3D11_TILED_RESOURCES_TIER_2) + return D3D_FEATURE_LEVEL_11_1; + + return D3D_FEATURE_LEVEL_12_0; } DxvkDeviceFeatures D3D11Device::GetDeviceFeatures( - const Rc& adapter, - D3D_FEATURE_LEVEL featureLevel) { - DxvkDeviceFeatures supported = adapter->features(); + const Rc& Adapter) { + DxvkDeviceFeatures supported = Adapter->features(); DxvkDeviceFeatures enabled = {}; + // Required for feature level 10_1 + enabled.core.features.depthBiasClamp = VK_TRUE; + enabled.core.features.depthClamp = VK_TRUE; + enabled.core.features.dualSrcBlend = VK_TRUE; + enabled.core.features.fillModeNonSolid = VK_TRUE; + enabled.core.features.fullDrawIndexUint32 = VK_TRUE; enabled.core.features.geometryShader = VK_TRUE; - enabled.core.features.robustBufferAccess = VK_TRUE; - enabled.core.features.depthBounds = supported.core.features.depthBounds; + enabled.core.features.imageCubeArray = VK_TRUE; + enabled.core.features.independentBlend = VK_TRUE; + enabled.core.features.multiViewport = VK_TRUE; + enabled.core.features.occlusionQueryPrecise = VK_TRUE; + enabled.core.features.pipelineStatisticsQuery = supported.core.features.pipelineStatisticsQuery; + enabled.core.features.sampleRateShading = VK_TRUE; + enabled.core.features.samplerAnisotropy = supported.core.features.samplerAnisotropy; + enabled.core.features.shaderClipDistance = VK_TRUE; + enabled.core.features.shaderCullDistance = VK_TRUE; + enabled.core.features.shaderImageGatherExtended = VK_TRUE; + enabled.core.features.textureCompressionBC = VK_TRUE; enabled.vk11.shaderDrawParameters = VK_TRUE; @@ -2035,92 +2082,46 @@ namespace dxvk { enabled.vk13.shaderDemoteToHelperInvocation = VK_TRUE; - enabled.extMemoryPriority.memoryPriority = supported.extMemoryPriority.memoryPriority; + enabled.extCustomBorderColor.customBorderColors = supported.extCustomBorderColor.customBorderColorWithoutFormat; + enabled.extCustomBorderColor.customBorderColorWithoutFormat = supported.extCustomBorderColor.customBorderColorWithoutFormat; + + enabled.extDepthClipEnable.depthClipEnable = supported.extDepthClipEnable.depthClipEnable; + + enabled.extTransformFeedback.transformFeedback = VK_TRUE; + enabled.extTransformFeedback.geometryStreams = VK_TRUE; enabled.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor = supported.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor; enabled.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor = supported.extVertexAttributeDivisor.vertexAttributeInstanceRateZeroDivisor; - D3D11_TILED_RESOURCES_TIER sparseTier = DetermineTiledResourcesTier(supported, adapter->devicePropertiesExt()); - VkBool32 hasSparseTier1 = sparseTier >= D3D11_TILED_RESOURCES_TIER_1; - VkBool32 hasSparseTier2 = sparseTier >= D3D11_TILED_RESOURCES_TIER_2; + // Required for Feature Level 11_0 + enabled.core.features.drawIndirectFirstInstance = supported.core.features.drawIndirectFirstInstance; + enabled.core.features.fragmentStoresAndAtomics = supported.core.features.fragmentStoresAndAtomics; + enabled.core.features.multiDrawIndirect = supported.core.features.multiDrawIndirect; + enabled.core.features.tessellationShader = supported.core.features.tessellationShader; - if (supported.extCustomBorderColor.customBorderColorWithoutFormat) { - enabled.extCustomBorderColor.customBorderColors = VK_TRUE; - enabled.extCustomBorderColor.customBorderColorWithoutFormat = VK_TRUE; - } + // Required for Feature Level 11_1 + enabled.core.features.logicOp = supported.core.features.logicOp; + enabled.core.features.variableMultisampleRate = supported.core.features.variableMultisampleRate; + enabled.core.features.vertexPipelineStoresAndAtomics = supported.core.features.vertexPipelineStoresAndAtomics; - if (featureLevel >= D3D_FEATURE_LEVEL_9_1) { - enabled.core.features.depthClamp = VK_TRUE; - enabled.core.features.depthBiasClamp = VK_TRUE; - enabled.core.features.fillModeNonSolid = VK_TRUE; - enabled.core.features.pipelineStatisticsQuery = supported.core.features.pipelineStatisticsQuery; - enabled.core.features.sampleRateShading = VK_TRUE; - enabled.core.features.samplerAnisotropy = supported.core.features.samplerAnisotropy; - enabled.core.features.shaderClipDistance = VK_TRUE; - enabled.core.features.shaderCullDistance = VK_TRUE; - enabled.core.features.textureCompressionBC = VK_TRUE; - enabled.extDepthClipEnable.depthClipEnable = supported.extDepthClipEnable.depthClipEnable; - } - - if (featureLevel >= D3D_FEATURE_LEVEL_9_2) { - enabled.core.features.occlusionQueryPrecise = VK_TRUE; - } - - if (featureLevel >= D3D_FEATURE_LEVEL_9_3) { - enabled.core.features.independentBlend = VK_TRUE; - enabled.core.features.multiViewport = VK_TRUE; - } - - if (featureLevel >= D3D_FEATURE_LEVEL_10_0) { - enabled.core.features.fullDrawIndexUint32 = VK_TRUE; - enabled.core.features.logicOp = supported.core.features.logicOp; - enabled.core.features.shaderImageGatherExtended = VK_TRUE; - enabled.core.features.variableMultisampleRate = supported.core.features.variableMultisampleRate; - enabled.extTransformFeedback.transformFeedback = VK_TRUE; - enabled.extTransformFeedback.geometryStreams = VK_TRUE; - } - - if (featureLevel >= D3D_FEATURE_LEVEL_10_1) { - enabled.core.features.dualSrcBlend = VK_TRUE; - enabled.core.features.imageCubeArray = VK_TRUE; - } - - if (featureLevel >= D3D_FEATURE_LEVEL_11_0) { - enabled.core.features.drawIndirectFirstInstance = VK_TRUE; - enabled.core.features.fragmentStoresAndAtomics = VK_TRUE; - enabled.core.features.multiDrawIndirect = VK_TRUE; - enabled.core.features.shaderFloat64 = supported.core.features.shaderFloat64; - enabled.core.features.shaderInt64 = supported.core.features.shaderInt64; - enabled.core.features.tessellationShader = VK_TRUE; - enabled.core.features.sparseBinding = hasSparseTier1; - enabled.core.features.sparseResidencyBuffer = hasSparseTier1; - enabled.core.features.sparseResidencyImage2D = hasSparseTier1; - enabled.core.features.sparseResidencyImage3D = hasSparseTier1 && supported.core.features.sparseResidencyImage3D; - enabled.core.features.sparseResidency2Samples = hasSparseTier1 && supported.core.features.sparseResidency2Samples; - enabled.core.features.sparseResidency4Samples = hasSparseTier1 && supported.core.features.sparseResidency4Samples; - enabled.core.features.sparseResidency8Samples = hasSparseTier1 && supported.core.features.sparseResidency8Samples; - enabled.core.features.sparseResidency16Samples = hasSparseTier1 && supported.core.features.sparseResidency16Samples; - enabled.core.features.sparseResidencyAliased = hasSparseTier1; - } - - if (featureLevel >= D3D_FEATURE_LEVEL_11_1) { - enabled.core.features.logicOp = VK_TRUE; - enabled.core.features.variableMultisampleRate = VK_TRUE; - enabled.core.features.vertexPipelineStoresAndAtomics = VK_TRUE; - enabled.core.features.shaderResourceResidency = hasSparseTier2; - enabled.core.features.shaderResourceMinLod = hasSparseTier2; - enabled.vk12.samplerFilterMinmax = hasSparseTier2; - } + // Required for Feature Level 12_0 + enabled.core.features.sparseBinding = supported.core.features.sparseBinding; + enabled.core.features.sparseResidencyBuffer = supported.core.features.sparseResidencyBuffer; + enabled.core.features.sparseResidencyImage2D = supported.core.features.sparseResidencyImage2D; + enabled.core.features.sparseResidencyImage3D = supported.core.features.sparseResidencyImage3D; + enabled.core.features.sparseResidency2Samples = supported.core.features.sparseResidency2Samples; + enabled.core.features.sparseResidency4Samples = supported.core.features.sparseResidency4Samples; + enabled.core.features.sparseResidency8Samples = supported.core.features.sparseResidency8Samples; + enabled.core.features.sparseResidency16Samples = supported.core.features.sparseResidency16Samples; + enabled.core.features.sparseResidencyAliased = supported.core.features.sparseResidencyAliased; + enabled.core.features.shaderResourceResidency = supported.core.features.shaderResourceResidency; + enabled.core.features.shaderResourceMinLod = supported.core.features.shaderResourceMinLod; + enabled.vk12.samplerFilterMinmax = supported.vk12.samplerFilterMinmax; - if (featureLevel >= D3D_FEATURE_LEVEL_12_0) { - enabled.core.features.shaderResourceResidency = VK_TRUE; - enabled.core.features.shaderResourceMinLod = VK_TRUE; - enabled.core.features.sparseBinding = VK_TRUE; - enabled.core.features.sparseResidencyBuffer = VK_TRUE; - enabled.core.features.sparseResidencyImage2D = VK_TRUE; - enabled.core.features.sparseResidencyAliased = VK_TRUE; - enabled.vk12.samplerFilterMinmax = VK_TRUE; - } + // Optional in any feature level + enabled.core.features.depthBounds = supported.core.features.depthBounds; + enabled.core.features.shaderFloat64 = supported.core.features.shaderFloat64; + enabled.core.features.shaderInt64 = supported.core.features.shaderInt64; return enabled; } @@ -2593,34 +2594,6 @@ namespace dxvk { return D3D11_TILED_RESOURCES_TIER_3; } - - - D3D_FEATURE_LEVEL D3D11Device::GetMaxFeatureLevel(const Rc& pInstance) { - static const std::array, 9> s_featureLevels = {{ - { "12_1", D3D_FEATURE_LEVEL_12_1 }, - { "12_0", D3D_FEATURE_LEVEL_12_0 }, - { "11_1", D3D_FEATURE_LEVEL_11_1 }, - { "11_0", D3D_FEATURE_LEVEL_11_0 }, - { "10_1", D3D_FEATURE_LEVEL_10_1 }, - { "10_0", D3D_FEATURE_LEVEL_10_0 }, - { "9_3", D3D_FEATURE_LEVEL_9_3 }, - { "9_2", D3D_FEATURE_LEVEL_9_2 }, - { "9_1", D3D_FEATURE_LEVEL_9_1 }, - }}; - - const std::string maxLevel = pInstance->config() - .getOption("d3d11.maxFeatureLevel"); - - auto entry = std::find_if(s_featureLevels.begin(), s_featureLevels.end(), - [&] (const std::pair& pair) { - return pair.first == maxLevel; - }); - - if (entry != s_featureLevels.end()) - return entry->second; - - return D3D_FEATURE_LEVEL_12_0; - } @@ -3648,7 +3621,7 @@ namespace dxvk { Rc D3D11DXGIDevice::CreateDevice(D3D_FEATURE_LEVEL FeatureLevel) { - DxvkDeviceFeatures deviceFeatures = D3D11Device::GetDeviceFeatures(m_dxvkAdapter, FeatureLevel); + DxvkDeviceFeatures deviceFeatures = D3D11Device::GetDeviceFeatures(m_dxvkAdapter); return m_dxvkAdapter->createDevice(m_dxvkInstance, deviceFeatures); } diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 8d25a9ed7..2a8433e81 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -420,14 +420,12 @@ namespace dxvk { return m_d3d10Device; } - static bool CheckFeatureLevelSupport( - const Rc& instance, - const Rc& adapter, - D3D_FEATURE_LEVEL featureLevel); + static D3D_FEATURE_LEVEL GetMaxFeatureLevel( + const Rc& Instance, + const Rc& Adapter); static DxvkDeviceFeatures GetDeviceFeatures( - const Rc& adapter, - D3D_FEATURE_LEVEL featureLevel); + const Rc& Adapter); private: @@ -455,6 +453,7 @@ namespace dxvk { D3D11StateObjectSet m_samplerObjects; D3D11ShaderModuleSet m_shaderModules; + D3D_FEATURE_LEVEL m_maxFeatureLevel; D3D11_TILED_RESOURCES_TIER m_tiledResourcesTier; HRESULT CreateShaderModule( @@ -498,9 +497,6 @@ namespace dxvk { const DxvkDeviceFeatures& Features, const DxvkDeviceInfo& Properties); - static D3D_FEATURE_LEVEL GetMaxFeatureLevel( - const Rc& pInstance); - }; diff --git a/src/d3d11/d3d11_main.cpp b/src/d3d11/d3d11_main.cpp index d80d5dec4..365375399 100644 --- a/src/d3d11/d3d11_main.cpp +++ b/src/d3d11/d3d11_main.cpp @@ -59,35 +59,39 @@ extern "C" { D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1, }; - if (pFeatureLevels == nullptr || FeatureLevels == 0) { + if (!pFeatureLevels || !FeatureLevels) { pFeatureLevels = defaultFeatureLevels.data(); FeatureLevels = defaultFeatureLevels.size(); } // Find the highest feature level supported by the device. // This works because the feature level array is ordered. - UINT flId; + D3D_FEATURE_LEVEL maxFeatureLevel = D3D11Device::GetMaxFeatureLevel(dxvkInstance, dxvkAdapter); + D3D_FEATURE_LEVEL minFeatureLevel = D3D_FEATURE_LEVEL(); + D3D_FEATURE_LEVEL devFeatureLevel = D3D_FEATURE_LEVEL(); - for (flId = 0 ; flId < FeatureLevels; flId++) { - Logger::info(str::format("D3D11CoreCreateDevice: Probing ", pFeatureLevels[flId])); - - if (D3D11Device::CheckFeatureLevelSupport(dxvkInstance, dxvkAdapter, pFeatureLevels[flId])) + Logger::info(str::format("D3D11CoreCreateDevice: Maximum supported feature level: ", maxFeatureLevel)); + + for (uint32_t flId = 0 ; flId < FeatureLevels; flId++) { + minFeatureLevel = pFeatureLevels[flId]; + + if (minFeatureLevel <= maxFeatureLevel) { + devFeatureLevel = minFeatureLevel; break; + } } - - if (flId == FeatureLevels) { - Logger::err("D3D11CoreCreateDevice: Requested feature level not supported"); + + if (!devFeatureLevel) { + Logger::err(str::format("D3D11CoreCreateDevice: Minimum required feature level ", minFeatureLevel, " not supported")); return E_INVALIDARG; } - - // Try to create the device with the given parameters. - const D3D_FEATURE_LEVEL fl = pFeatureLevels[flId]; - + try { - Logger::info(str::format("D3D11CoreCreateDevice: Using feature level ", fl)); + Logger::info(str::format("D3D11CoreCreateDevice: Using feature level ", devFeatureLevel)); + Com device = new D3D11DXGIDevice( - pAdapter, dxvkInstance, dxvkAdapter, fl, Flags); - + pAdapter, dxvkInstance, dxvkAdapter, devFeatureLevel, Flags); + return device->QueryInterface( __uuidof(ID3D11Device), reinterpret_cast(ppDevice)); diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 0d9336849..0872211d0 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -392,6 +392,10 @@ namespace dxvk { enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = m_deviceFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary; + // Enable memory priority if supported to improve memory management + enabledFeatures.extMemoryPriority.memoryPriority = + m_deviceFeatures.extMemoryPriority.memoryPriority; + // Require robustBufferAccess2 since we use the robustness alignment // info in a number of places, and require null descriptor support // since we no longer have a fallback for those in the backend From 71d6e8f8495da9f0baf825f8d7b3dce5ff4f9f04 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 3 Sep 2022 22:45:58 +0200 Subject: [PATCH 0755/1348] [d3d11] Introduce D3D11DeviceFeatures --- src/d3d11/d3d11_features.cpp | 268 +++++++++++++++++++++++++++++++++++ src/d3d11/d3d11_features.h | 89 ++++++++++++ src/d3d11/meson.build | 1 + 3 files changed, 358 insertions(+) create mode 100644 src/d3d11/d3d11_features.cpp create mode 100644 src/d3d11/d3d11_features.h diff --git a/src/d3d11/d3d11_features.cpp b/src/d3d11/d3d11_features.cpp new file mode 100644 index 000000000..88ed7bd9e --- /dev/null +++ b/src/d3d11/d3d11_features.cpp @@ -0,0 +1,268 @@ +#include + +#include "d3d11_features.h" + +namespace dxvk { + + D3D11DeviceFeatures::D3D11DeviceFeatures() { + + } + + + D3D11DeviceFeatures::D3D11DeviceFeatures( + const Rc& Instance, + const Rc& Adapter, + D3D_FEATURE_LEVEL FeatureLevel) + : m_features (Adapter->features()), + m_properties (Adapter->devicePropertiesExt()) { + // Assume no TBDR. DXVK does not optimize for TBDR architectures + // anyway, and D3D11 does not really provide meaningful support. + m_architectureInfo.TileBasedDeferredRenderer = FALSE; + + // D3D9 options. We unconditionally support all of these. + m_d3d9Options.FullNonPow2TextureSupport = TRUE; + + m_d3d9Options1.FullNonPow2TextureSupported = TRUE; + m_d3d9Options1.DepthAsTextureWithLessEqualComparisonFilterSupported = TRUE; + m_d3d9Options1.SimpleInstancingSupported = TRUE; + m_d3d9Options1.TextureCubeFaceRenderTargetWithNonCubeDepthStencilSupported = TRUE; + + m_d3d9Shadow.SupportsDepthAsTextureWithLessEqualComparisonFilter = TRUE; + + m_d3d9SimpleInstancing.SimpleInstancingSupported = TRUE; + + // D3D10 options. We unconditionally support compute shaders. + m_d3d10Options.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = TRUE; + + // D3D11.1 options. All of these are required for Feature Level 11_1. + bool hasDoublePrecisionSupport = m_features.core.features.shaderFloat64 + && m_features.core.features.shaderInt64; + + m_d3d11Options.DiscardAPIsSeenByDriver = TRUE; + m_d3d11Options.FlagsForUpdateAndCopySeenByDriver = TRUE; + m_d3d11Options.ClearView = TRUE; + m_d3d11Options.CopyWithOverlap = TRUE; + m_d3d11Options.ConstantBufferPartialUpdate = TRUE; + m_d3d11Options.ConstantBufferOffsetting = TRUE; + m_d3d11Options.MapNoOverwriteOnDynamicConstantBuffer = TRUE; + m_d3d11Options.MapNoOverwriteOnDynamicBufferSRV = TRUE; + m_d3d11Options.ExtendedResourceSharing = TRUE; + + if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0) { + m_d3d11Options.OutputMergerLogicOp = m_features.core.features.logicOp; + m_d3d11Options.MultisampleRTVWithForcedSampleCountOne = TRUE; // Not really + } + + if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0) { + m_d3d11Options.UAVOnlyRenderingForcedSampleCount = TRUE; + m_d3d11Options.SAD4ShaderInstructions = TRUE; + m_d3d11Options.ExtendedDoublesShaderInstructions = hasDoublePrecisionSupport; + } + + // D3D11.2 options. + auto tiledResourcesTier = DetermineTiledResourcesTier(FeatureLevel); + m_d3d11Options1.TiledResourcesTier = tiledResourcesTier; + m_d3d11Options1.MinMaxFiltering = tiledResourcesTier >= D3D11_TILED_RESOURCES_TIER_2; + m_d3d11Options1.ClearViewAlsoSupportsDepthOnlyFormats = TRUE; + + if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0) + m_d3d11Options1.MapOnDefaultBuffers = TRUE; + + // D3D11.3 options + m_d3d11Options2.TypedUAVLoadAdditionalFormats = DetermineUavExtendedTypedLoadSupport(Adapter, FeatureLevel); + m_d3d11Options2.ConservativeRasterizationTier = DetermineConservativeRasterizationTier(FeatureLevel); + m_d3d11Options2.TiledResourcesTier = tiledResourcesTier; + m_d3d11Options2.StandardSwizzle = FALSE; + m_d3d11Options2.UnifiedMemoryArchitecture = FALSE; + + if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0) + m_d3d11Options2.MapOnDefaultTextures = TRUE; + + if (FeatureLevel >= D3D_FEATURE_LEVEL_11_1) { + m_d3d11Options2.ROVsSupported = FALSE; + m_d3d11Options2.PSSpecifiedStencilRefSupported = m_features.extShaderStencilExport; + } + + // More D3D11.3 options + if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0) { + m_d3d11Options3.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer = + m_features.vk12.shaderOutputViewportIndex && + m_features.vk12.shaderOutputLayer; + } + + // D3D11.4 options + m_d3d11Options4.ExtendedNV12SharedTextureSupported = TRUE; + + // More D3D11.4 options + m_d3d11Options5.SharedResourceTier = DetermineSharedResourceTier(FeatureLevel); + + // Double-precision support + if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0) + m_doubles.DoublePrecisionFloatShaderOps = hasDoublePrecisionSupport; + + // These numbers are not accurate, but we have no real way to query these + m_gpuVirtualAddress.MaxGPUVirtualAddressBitsPerResource = 32; + m_gpuVirtualAddress.MaxGPUVirtualAddressBitsPerProcess = 40; + + // Marker support only depends on the debug utils extension + m_marker.Profile = Instance->extensions().extDebugUtils; + + // DXVK will keep all shaders in memory once created, and all Vulkan + // drivers that we know of that can run DXVK have an on-disk cache. + m_shaderCache.SupportFlags = D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE + | D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE; + + // DXVK does not support min precision + m_shaderMinPrecision.PixelShaderMinPrecision = 0; + m_shaderMinPrecision.AllOtherShaderStagesMinPrecision = 0; + + // Report native support for command lists here so that we do not actually have + // to re-implement the UpdateSubresource bug from the D3D11 runtime, see MSDN: + // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476486(v=vs.85).aspx) + m_threading.DriverConcurrentCreates = TRUE; + m_threading.DriverCommandLists = TRUE; + } + + + D3D11DeviceFeatures::~D3D11DeviceFeatures() { + + } + + + HRESULT D3D11DeviceFeatures::GetFeatureData( + D3D11_FEATURE Feature, + UINT FeatureDataSize, + void* pFeatureData) const { + switch (Feature) { + case D3D11_FEATURE_ARCHITECTURE_INFO: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_architectureInfo); + case D3D11_FEATURE_D3D9_OPTIONS: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9Options); + case D3D11_FEATURE_D3D9_OPTIONS1: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9Options1); + case D3D11_FEATURE_D3D9_SHADOW_SUPPORT: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9Shadow); + case D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9SimpleInstancing); + case D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d10Options); + case D3D11_FEATURE_D3D11_OPTIONS: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options); + case D3D11_FEATURE_D3D11_OPTIONS1: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options1); + case D3D11_FEATURE_D3D11_OPTIONS2: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options2); + case D3D11_FEATURE_D3D11_OPTIONS3: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options3); + case D3D11_FEATURE_D3D11_OPTIONS4: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options4); + case D3D11_FEATURE_D3D11_OPTIONS5: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options5); + case D3D11_FEATURE_DOUBLES: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_doubles); + case D3D11_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_gpuVirtualAddress); + case D3D11_FEATURE_MARKER_SUPPORT: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_marker); + case D3D11_FEATURE_SHADER_CACHE: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_shaderCache); + case D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_shaderMinPrecision); + case D3D11_FEATURE_THREADING: + return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_threading); + default: + Logger::err(str::format("D3D11: Unknown feature: ", Feature)); + return E_INVALIDARG; + } + } + + + D3D11_CONSERVATIVE_RASTERIZATION_TIER D3D11DeviceFeatures::DetermineConservativeRasterizationTier( + D3D_FEATURE_LEVEL FeatureLevel) { + if (FeatureLevel < D3D_FEATURE_LEVEL_11_1 + || !m_features.extConservativeRasterization) + return D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED; + + // We don't really have a way to query uncertainty regions, + // so just check degenerate triangle behaviour + if (!m_properties.extConservativeRasterization.degenerateTrianglesRasterized) + return D3D11_CONSERVATIVE_RASTERIZATION_TIER_1; + + return D3D11_CONSERVATIVE_RASTERIZATION_TIER_2; + } + + + D3D11_SHARED_RESOURCE_TIER D3D11DeviceFeatures::DetermineSharedResourceTier( + D3D_FEATURE_LEVEL FeatureLevel) { + // Shared resources are all sorts of wonky for obvious + // reasons, so don't over-promise things here for now + return D3D11_SHARED_RESOURCE_TIER_1; + } + + + D3D11_TILED_RESOURCES_TIER D3D11DeviceFeatures::DetermineTiledResourcesTier( + D3D_FEATURE_LEVEL FeatureLevel) { + if (FeatureLevel < D3D_FEATURE_LEVEL_11_0 + || !m_features.core.features.sparseBinding + || !m_features.core.features.sparseResidencyBuffer + || !m_features.core.features.sparseResidencyImage2D + || !m_features.core.features.sparseResidencyAliased + || !m_properties.core.properties.sparseProperties.residencyStandard2DBlockShape) + return D3D11_TILED_RESOURCES_NOT_SUPPORTED; + + if (FeatureLevel < D3D_FEATURE_LEVEL_11_1 + || !m_features.core.features.shaderResourceResidency + || !m_features.core.features.shaderResourceMinLod + || !m_features.vk12.samplerFilterMinmax + || !m_properties.vk12.filterMinmaxSingleComponentFormats + || !m_properties.core.properties.sparseProperties.residencyNonResidentStrict + || m_properties.core.properties.sparseProperties.residencyAlignedMipSize) + return D3D11_TILED_RESOURCES_TIER_1; + + if (!m_features.core.features.sparseResidencyImage3D + || !m_properties.core.properties.sparseProperties.residencyStandard3DBlockShape) + return D3D11_TILED_RESOURCES_TIER_2; + + return D3D11_TILED_RESOURCES_TIER_3; + } + + + BOOL D3D11DeviceFeatures::DetermineUavExtendedTypedLoadSupport( + const Rc& Adapter, + D3D_FEATURE_LEVEL FeatureLevel) { + static const std::array s_formats = {{ + VK_FORMAT_R32_SFLOAT, + VK_FORMAT_R32_UINT, + VK_FORMAT_R32_SINT, + VK_FORMAT_R32G32B32A32_SFLOAT, + VK_FORMAT_R32G32B32A32_UINT, + VK_FORMAT_R32G32B32A32_SINT, + VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_R16G16B16A16_UINT, + VK_FORMAT_R16G16B16A16_SINT, + VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R8G8B8A8_UINT, + VK_FORMAT_R8G8B8A8_SINT, + VK_FORMAT_R16_SFLOAT, + VK_FORMAT_R16_UINT, + VK_FORMAT_R16_SINT, + VK_FORMAT_R8_UNORM, + VK_FORMAT_R8_UINT, + VK_FORMAT_R8_SINT, + }}; + + if (FeatureLevel < D3D_FEATURE_LEVEL_11_0) + return FALSE; + + for (auto f : s_formats) { + DxvkFormatFeatures features = Adapter->getFormatFeatures(f); + VkFormatFeatureFlags2 imgFeatures = features.optimal | features.linear; + + if (!(imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT)) + return FALSE; + } + + return TRUE; + } + +} diff --git a/src/d3d11/d3d11_features.h b/src/d3d11/d3d11_features.h new file mode 100644 index 000000000..51dab32bd --- /dev/null +++ b/src/d3d11/d3d11_features.h @@ -0,0 +1,89 @@ +#pragma once + +#include "d3d11_include.h" + +#include "../dxvk/dxvk_adapter.h" +#include "../dxvk/dxvk_instance.h" + +namespace dxvk { + + /** + * \brief Device features + * + * Stores D3D device feature structs. + */ + class D3D11DeviceFeatures { + + public: + + D3D11DeviceFeatures(); + + D3D11DeviceFeatures( + const Rc& Instance, + const Rc& Adapter, + D3D_FEATURE_LEVEL FeatureLevel); + + ~D3D11DeviceFeatures(); + + /** + * \brief Retrieves feature support data + * + * \param [in] Feature D3D feature to query + * \param [in] FeatureDataSize Data size, in bytes + * \param [out] pFeatureData Data + * \returns Status of the operation + */ + HRESULT GetFeatureData( + D3D11_FEATURE Feature, + UINT FeatureDataSize, + void* pFeatureData) const; + + private: + + DxvkDeviceFeatures m_features; + DxvkDeviceInfo m_properties; + + D3D11_FEATURE_DATA_ARCHITECTURE_INFO m_architectureInfo = { }; + D3D11_FEATURE_DATA_D3D9_OPTIONS m_d3d9Options = { }; + D3D11_FEATURE_DATA_D3D9_OPTIONS1 m_d3d9Options1 = { }; + D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT m_d3d9Shadow = { }; + D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT m_d3d9SimpleInstancing = { }; + D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS m_d3d10Options = { }; + D3D11_FEATURE_DATA_D3D11_OPTIONS m_d3d11Options = { }; + D3D11_FEATURE_DATA_D3D11_OPTIONS1 m_d3d11Options1 = { }; + D3D11_FEATURE_DATA_D3D11_OPTIONS2 m_d3d11Options2 = { }; + D3D11_FEATURE_DATA_D3D11_OPTIONS3 m_d3d11Options3 = { }; + D3D11_FEATURE_DATA_D3D11_OPTIONS4 m_d3d11Options4 = { }; + D3D11_FEATURE_DATA_D3D11_OPTIONS5 m_d3d11Options5 = { }; + D3D11_FEATURE_DATA_DOUBLES m_doubles = { }; + D3D11_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT m_gpuVirtualAddress = { }; + D3D11_FEATURE_DATA_MARKER_SUPPORT m_marker = { }; + D3D11_FEATURE_DATA_SHADER_CACHE m_shaderCache = { }; + D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT m_shaderMinPrecision = { }; + D3D11_FEATURE_DATA_THREADING m_threading = { }; + + template + static HRESULT GetTypedFeatureData(UINT Size, void* pDstData, const T* pSrcData) { + if (Size != sizeof(T)) + return E_INVALIDARG; + + *(reinterpret_cast(pDstData)) = *pSrcData; + return S_OK; + } + + D3D11_CONSERVATIVE_RASTERIZATION_TIER DetermineConservativeRasterizationTier( + D3D_FEATURE_LEVEL FeatureLevel); + + D3D11_SHARED_RESOURCE_TIER DetermineSharedResourceTier( + D3D_FEATURE_LEVEL FeatureLevel); + + D3D11_TILED_RESOURCES_TIER DetermineTiledResourcesTier( + D3D_FEATURE_LEVEL FeatureLevel); + + BOOL DetermineUavExtendedTypedLoadSupport( + const Rc& Adapter, + D3D_FEATURE_LEVEL FeatureLevel); + + }; + +} \ No newline at end of file diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 0b99f695f..7727387d6 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -37,6 +37,7 @@ d3d11_src = [ 'd3d11_depth_stencil.cpp', 'd3d11_device.cpp', 'd3d11_enums.cpp', + 'd3d11_features.cpp', 'd3d11_fence.cpp', 'd3d11_gdi.cpp', 'd3d11_initializer.cpp', From 0e70398d4ed212e25061c4ef90b87fcaa9a181da Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 3 Sep 2022 23:06:04 +0200 Subject: [PATCH 0756/1348] [d3d11] Use D3D11DeviceFeatures in CheckFeatureSupport --- src/d3d11/d3d11_device.cpp | 233 +++---------------------------------- src/d3d11/d3d11_device.h | 2 + 2 files changed, 15 insertions(+), 220 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index b58349dd3..ea6c0f3bd 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -47,6 +47,7 @@ namespace dxvk { m_d3d11Options (m_dxvkDevice->instance()->config(), m_dxvkDevice), m_dxbcOptions (m_dxvkDevice, m_d3d11Options), m_maxFeatureLevel (GetMaxFeatureLevel(m_dxvkDevice->instance(), m_dxvkDevice->adapter())), + m_deviceFeatures (m_dxvkDevice->instance(), m_dxvkDevice->adapter(), m_featureLevel), m_tiledResourcesTier(DetermineTiledResourcesTier(m_dxvkDevice->features(), m_dxvkDevice->properties())) { m_initializer = new D3D11Initializer(this); m_context = new D3D11ImmediateContext(this, m_dxvkDevice); @@ -1330,8 +1331,13 @@ namespace dxvk { if (!featureLevel) return E_INVALIDARG; - if (m_featureLevel < featureLevel) + if (m_featureLevel < featureLevel) { m_featureLevel = featureLevel; + m_deviceFeatures = D3D11DeviceFeatures( + m_dxvkDevice->instance(), + m_dxvkDevice->adapter(), + m_featureLevel); + } if (pChosenFeatureLevel) *pChosenFeatureLevel = featureLevel; @@ -1541,29 +1547,8 @@ namespace dxvk { void* pFeatureSupportData, UINT FeatureSupportDataSize) { switch (Feature) { - case D3D11_FEATURE_THREADING: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - // We report native support for command lists here so that we do not actually - // have to re-implement the UpdateSubresource bug from the D3D11 runtime, see - // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476486(v=vs.85).aspx) - info->DriverConcurrentCreates = TRUE; - info->DriverCommandLists = TRUE; - } return S_OK; - - case D3D11_FEATURE_DOUBLES: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - info->DoublePrecisionFloatShaderOps = m_dxvkDevice->features().core.features.shaderFloat64 - && m_dxvkDevice->features().core.features.shaderInt64; - } return S_OK; - + // Format support queries are special in that they use in-out + // structs, and we need the Vulkan device to query them at all case D3D11_FEATURE_FORMAT_SUPPORT: { auto info = static_cast(pFeatureSupportData); @@ -1572,7 +1557,7 @@ namespace dxvk { return GetFormatSupportFlags(info->InFormat, &info->OutFormatSupport, nullptr); } return S_OK; - + case D3D11_FEATURE_FORMAT_SUPPORT2: { auto info = static_cast(pFeatureSupportData); @@ -1581,203 +1566,11 @@ namespace dxvk { return GetFormatSupportFlags(info->InFormat, nullptr, &info->OutFormatSupport2); } return S_OK; - - case D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - info->ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = TRUE; - } return S_OK; - - case D3D11_FEATURE_D3D11_OPTIONS: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404457(v=vs.85).aspx - const auto& features = m_dxvkDevice->features(); - - info->OutputMergerLogicOp = features.core.features.logicOp; - info->UAVOnlyRenderingForcedSampleCount = features.core.features.variableMultisampleRate; - info->DiscardAPIsSeenByDriver = TRUE; - info->FlagsForUpdateAndCopySeenByDriver = TRUE; - info->ClearView = TRUE; - info->CopyWithOverlap = TRUE; - info->ConstantBufferPartialUpdate = TRUE; - info->ConstantBufferOffsetting = TRUE; - info->MapNoOverwriteOnDynamicConstantBuffer = TRUE; - info->MapNoOverwriteOnDynamicBufferSRV = TRUE; - info->MultisampleRTVWithForcedSampleCountOne = TRUE; /* not really */ - info->SAD4ShaderInstructions = TRUE; - info->ExtendedDoublesShaderInstructions = TRUE; - info->ExtendedResourceSharing = TRUE; - } return S_OK; - - case D3D11_FEATURE_ARCHITECTURE_INFO: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - info->TileBasedDeferredRenderer = FALSE; - } return S_OK; - - case D3D11_FEATURE_D3D9_OPTIONS: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - info->FullNonPow2TextureSupport = TRUE; - } return S_OK; - - case D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - // Report that we only support full 32-bit operations - info->PixelShaderMinPrecision = 0; - info->AllOtherShaderStagesMinPrecision = 0; - } return S_OK; - - case D3D11_FEATURE_D3D9_SHADOW_SUPPORT: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - info->SupportsDepthAsTextureWithLessEqualComparisonFilter = TRUE; - } return S_OK; - - case D3D11_FEATURE_D3D11_OPTIONS1: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - // Min/Max filtering requires Tiled Resources Tier 2 for some reason, - // so we cannot support it even though Vulkan exposes this feature - info->TiledResourcesTier = m_tiledResourcesTier; - info->MinMaxFiltering = m_tiledResourcesTier >= D3D11_TILED_RESOURCES_TIER_2; - info->ClearViewAlsoSupportsDepthOnlyFormats = TRUE; - info->MapOnDefaultBuffers = TRUE; - } return S_OK; - - case D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - info->SimpleInstancingSupported = TRUE; - } return S_OK; - - case D3D11_FEATURE_MARKER_SUPPORT: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - info->Profile = m_context->IsAnnotationEnabled(); - } return S_OK; - - case D3D11_FEATURE_D3D9_OPTIONS1: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - info->FullNonPow2TextureSupported = TRUE; - info->DepthAsTextureWithLessEqualComparisonFilterSupported = TRUE; - info->SimpleInstancingSupported = TRUE; - info->TextureCubeFaceRenderTargetWithNonCubeDepthStencilSupported = TRUE; - } return S_OK; - - case D3D11_FEATURE_D3D11_OPTIONS2: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - info->PSSpecifiedStencilRefSupported = m_dxvkDevice->features().extShaderStencilExport; - info->TypedUAVLoadAdditionalFormats = m_dxbcOptions.supportsTypedUavLoadExtended; - info->ROVsSupported = FALSE; - info->ConservativeRasterizationTier = D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED; - info->MapOnDefaultTextures = TRUE; - info->TiledResourcesTier = m_tiledResourcesTier; - info->StandardSwizzle = FALSE; - info->UnifiedMemoryArchitecture = m_dxvkDevice->isUnifiedMemoryArchitecture(); - - if (m_dxvkDevice->features().extConservativeRasterization) { - // We don't have a way to query uncertainty regions, so just check degenerate triangle behaviour - info->ConservativeRasterizationTier = m_dxvkDevice->properties().extConservativeRasterization.degenerateTrianglesRasterized - ? D3D11_CONSERVATIVE_RASTERIZATION_TIER_2 : D3D11_CONSERVATIVE_RASTERIZATION_TIER_1; - } - } return S_OK; - - case D3D11_FEATURE_D3D11_OPTIONS3: { - if (FeatureSupportDataSize != sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS3)) - return E_INVALIDARG; - - const auto& features = m_dxvkDevice->features(); - - auto info = static_cast(pFeatureSupportData); - info->VPAndRTArrayIndexFromAnyShaderFeedingRasterizer = - features.vk12.shaderOutputViewportIndex && - features.vk12.shaderOutputLayer; - } return S_OK; - - case D3D11_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - // These numbers are not accurate, but it should not have any effect on D3D11 apps - info->MaxGPUVirtualAddressBitsPerResource = 32; - info->MaxGPUVirtualAddressBitsPerProcess = 40; - } return S_OK; - - case D3D11_FEATURE_D3D11_OPTIONS4: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - info->ExtendedNV12SharedTextureSupported = TRUE; - } return S_OK; - - case D3D11_FEATURE_SHADER_CACHE: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - // DXVK will keep all shaders in memory once created, and all Vulkan - // drivers that we know of that can run DXVK have an on-disk cache. - info->SupportFlags = D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE - | D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE; - } return S_OK; - - case D3D11_FEATURE_D3D11_OPTIONS5: { - auto info = static_cast(pFeatureSupportData); - - if (FeatureSupportDataSize != sizeof(*info)) - return E_INVALIDARG; - - // Shared resources are all sorts of wonky for obvious - // reasons, so don't over-promise things here for now - info->SharedResourceTier = D3D11_SHARED_RESOURCE_TIER_1; - } return S_OK; default: - Logger::err(str::format("D3D11Device: CheckFeatureSupport: Unknown feature: ", Feature)); - return E_INVALIDARG; + // For everything else, we can use the device feature struct + // that we already initialized during device creation. + return m_deviceFeatures.GetFeatureData(Feature, FeatureSupportDataSize, pFeatureSupportData); } } diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 2a8433e81..48221c2a0 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -16,6 +16,7 @@ #include "d3d11_cmdlist.h" #include "d3d11_cuda.h" +#include "d3d11_features.h" #include "d3d11_initializer.h" #include "d3d11_interfaces.h" #include "d3d11_interop.h" @@ -454,6 +455,7 @@ namespace dxvk { D3D11ShaderModuleSet m_shaderModules; D3D_FEATURE_LEVEL m_maxFeatureLevel; + D3D11DeviceFeatures m_deviceFeatures; D3D11_TILED_RESOURCES_TIER m_tiledResourcesTier; HRESULT CreateShaderModule( From 59dd2d54cd4e701997f295e49f343a59500de6b4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 3 Sep 2022 23:27:40 +0200 Subject: [PATCH 0757/1348] [d3d11] Add convenience query for Tiled Resources tier --- src/d3d11/d3d11_device.cpp | 21 +++++++++++++-------- src/d3d11/d3d11_device.h | 1 - src/d3d11/d3d11_features.h | 8 ++++++++ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index ea6c0f3bd..d2ed9b5ec 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -47,8 +47,7 @@ namespace dxvk { m_d3d11Options (m_dxvkDevice->instance()->config(), m_dxvkDevice), m_dxbcOptions (m_dxvkDevice, m_d3d11Options), m_maxFeatureLevel (GetMaxFeatureLevel(m_dxvkDevice->instance(), m_dxvkDevice->adapter())), - m_deviceFeatures (m_dxvkDevice->instance(), m_dxvkDevice->adapter(), m_featureLevel), - m_tiledResourcesTier(DetermineTiledResourcesTier(m_dxvkDevice->features(), m_dxvkDevice->properties())) { + m_deviceFeatures (m_dxvkDevice->instance(), m_dxvkDevice->adapter(), m_featureLevel) { m_initializer = new D3D11Initializer(this); m_context = new D3D11ImmediateContext(this, m_dxvkDevice); m_d3d10Device = new D3D10Device(this, m_context.ptr()); @@ -87,7 +86,8 @@ namespace dxvk { return E_INVALIDARG; D3D11_BUFFER_DESC desc = *pDesc; - HRESULT hr = D3D11Buffer::NormalizeBufferProperties(&desc, m_tiledResourcesTier); + HRESULT hr = D3D11Buffer::NormalizeBufferProperties(&desc, + m_deviceFeatures.GetTiledResourcesTier()); if (FAILED(hr)) return hr; @@ -210,7 +210,8 @@ namespace dxvk { desc.MiscFlags = pDesc->MiscFlags; desc.TextureLayout = pDesc->TextureLayout; - HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, m_tiledResourcesTier); + HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, + m_deviceFeatures.GetTiledResourcesTier()); if (FAILED(hr)) return hr; @@ -285,13 +286,14 @@ namespace dxvk { desc.MiscFlags = pDesc->MiscFlags; desc.TextureLayout = pDesc->TextureLayout; - HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, m_tiledResourcesTier); + D3D11_TILED_RESOURCES_TIER tiledResourcesTier = m_deviceFeatures.GetTiledResourcesTier(); + HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, tiledResourcesTier); if (FAILED(hr)) return hr; if ((desc.MiscFlags & D3D11_RESOURCE_MISC_TILED) - && (m_tiledResourcesTier < D3D11_TILED_RESOURCES_TIER_3)) + && (tiledResourcesTier < D3D11_TILED_RESOURCES_TIER_3)) return E_INVALIDARG; if (!ppTexture3D) @@ -1160,7 +1162,9 @@ namespace dxvk { if (FAILED(D3D11SamplerState::NormalizeDesc(&desc))) return E_INVALIDARG; - if (IsMinMaxFilter(desc.Filter) && m_tiledResourcesTier < D3D11_TILED_RESOURCES_TIER_2) + D3D11_TILED_RESOURCES_TIER tiledResourcesTier = m_deviceFeatures.GetTiledResourcesTier(); + + if (IsMinMaxFilter(desc.Filter) && tiledResourcesTier < D3D11_TILED_RESOURCES_TIER_2) return E_INVALIDARG; if (!ppSamplerState) @@ -2035,9 +2039,10 @@ namespace dxvk { if (GetImageTypeSupport(fmtMapping.Format, VK_IMAGE_TYPE_3D, 0)) flags1 |= D3D11_FORMAT_SUPPORT_TEXTURE3D; // We only support tiled resources with a single aspect + D3D11_TILED_RESOURCES_TIER tiledResourcesTier = m_deviceFeatures.GetTiledResourcesTier(); VkImageAspectFlags sparseAspects = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT; - if (m_tiledResourcesTier && !(fmtProperties->aspectMask & ~sparseAspects)) { + if (tiledResourcesTier && !(fmtProperties->aspectMask & ~sparseAspects)) { VkImageCreateFlags flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT; diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 48221c2a0..cfa2369c3 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -456,7 +456,6 @@ namespace dxvk { D3D_FEATURE_LEVEL m_maxFeatureLevel; D3D11DeviceFeatures m_deviceFeatures; - D3D11_TILED_RESOURCES_TIER m_tiledResourcesTier; HRESULT CreateShaderModule( D3D11CommonShader* pShaderModule, diff --git a/src/d3d11/d3d11_features.h b/src/d3d11/d3d11_features.h index 51dab32bd..b17dd824e 100644 --- a/src/d3d11/d3d11_features.h +++ b/src/d3d11/d3d11_features.h @@ -38,6 +38,14 @@ namespace dxvk { UINT FeatureDataSize, void* pFeatureData) const; + /** + * \brief Queries tiled resources tier + * \returns Tiled resources tier + */ + D3D11_TILED_RESOURCES_TIER GetTiledResourcesTier() const { + return m_d3d11Options2.TiledResourcesTier; + } + private: DxvkDeviceFeatures m_features; From c082e7f0a9b99579e3b99feec5ba06593c931763 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 3 Sep 2022 23:28:00 +0200 Subject: [PATCH 0758/1348] [d3d11] Add convenience query for Conservative Rasterization tier --- src/d3d11/d3d11_device.cpp | 2 +- src/d3d11/d3d11_features.h | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index d2ed9b5ec..b052c3e34 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1138,7 +1138,7 @@ namespace dxvk { return E_INVALIDARG; if (desc.ConservativeRaster != D3D11_CONSERVATIVE_RASTERIZATION_MODE_OFF - && !m_dxvkDevice->features().extConservativeRasterization) + && !m_deviceFeatures.GetConservativeRasterizationTier()) return E_INVALIDARG; if (!ppRasterizerState) diff --git a/src/d3d11/d3d11_features.h b/src/d3d11/d3d11_features.h index b17dd824e..bf5e48305 100644 --- a/src/d3d11/d3d11_features.h +++ b/src/d3d11/d3d11_features.h @@ -46,6 +46,14 @@ namespace dxvk { return m_d3d11Options2.TiledResourcesTier; } + /** + * \brief Queries conservative rasterization tier + * \returns Conservative rasterization tier + */ + D3D11_CONSERVATIVE_RASTERIZATION_TIER GetConservativeRasterizationTier() const { + return m_d3d11Options2.ConservativeRasterizationTier; + } + private: DxvkDeviceFeatures m_features; From 882072e13404c597ca79fef63d1f3e4cb9725a75 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 3 Sep 2022 23:39:51 +0200 Subject: [PATCH 0759/1348] [d3d11] Move maximum feature level check to D3D11DeviceFeatures --- src/d3d11/d3d11_device.cpp | 51 ++---------------------------------- src/d3d11/d3d11_device.h | 4 --- src/d3d11/d3d11_features.cpp | 35 +++++++++++++++++++++++++ src/d3d11/d3d11_features.h | 13 +++++++++ 4 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index b052c3e34..daaa5475f 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1824,28 +1824,8 @@ namespace dxvk { if (entry != s_featureLevels.end()) return entry->second; - // Check Feature Level 11_0 features - if (!features.core.features.drawIndirectFirstInstance - || !features.core.features.fragmentStoresAndAtomics - || !features.core.features.multiDrawIndirect - || !features.core.features.tessellationShader) - return D3D_FEATURE_LEVEL_10_1; - - // Check Feature Level 11_1 features - if (!features.core.features.logicOp - || !features.core.features.variableMultisampleRate - || !features.core.features.vertexPipelineStoresAndAtomics) - return D3D_FEATURE_LEVEL_11_0; - - // Check Feature Level 12_0 features - D3D11_TILED_RESOURCES_TIER tiledResourcesTier = DetermineTiledResourcesTier( - Adapter->features(), - Adapter->devicePropertiesExt()); - - if (tiledResourcesTier < D3D11_TILED_RESOURCES_TIER_2) - return D3D_FEATURE_LEVEL_11_1; - - return D3D_FEATURE_LEVEL_12_0; + // Otherwise, check the actually available device features + return D3D11DeviceFeatures::GetMaxFeatureLevel(Instance, Adapter); } @@ -2368,33 +2348,6 @@ namespace dxvk { } - D3D11_TILED_RESOURCES_TIER D3D11Device::DetermineTiledResourcesTier( - const DxvkDeviceFeatures& Features, - const DxvkDeviceInfo& Properties) { - if (!Features.core.features.sparseBinding - || !Features.core.features.sparseResidencyBuffer - || !Features.core.features.sparseResidencyImage2D - || !Features.core.features.sparseResidencyAliased - || !Properties.core.properties.sparseProperties.residencyStandard2DBlockShape) - return D3D11_TILED_RESOURCES_NOT_SUPPORTED; - - if (!Features.core.features.shaderResourceResidency - || !Features.core.features.shaderResourceMinLod - || !Features.vk12.samplerFilterMinmax - || !Properties.vk12.filterMinmaxSingleComponentFormats - || !Properties.core.properties.sparseProperties.residencyNonResidentStrict - || Properties.core.properties.sparseProperties.residencyAlignedMipSize) - return D3D11_TILED_RESOURCES_TIER_1; - - if (!Features.core.features.sparseResidencyImage3D - || !Properties.core.properties.sparseProperties.residencyStandard3DBlockShape) - return D3D11_TILED_RESOURCES_TIER_2; - - return D3D11_TILED_RESOURCES_TIER_3; - } - - - D3D11DeviceExt::D3D11DeviceExt( D3D11DXGIDevice* pContainer, diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index cfa2369c3..5da3ae3f2 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -494,10 +494,6 @@ namespace dxvk { UINT Subresource, const D3D11_BOX* pBox); - static D3D11_TILED_RESOURCES_TIER DetermineTiledResourcesTier( - const DxvkDeviceFeatures& Features, - const DxvkDeviceInfo& Properties); - }; diff --git a/src/d3d11/d3d11_features.cpp b/src/d3d11/d3d11_features.cpp index 88ed7bd9e..65b21b002 100644 --- a/src/d3d11/d3d11_features.cpp +++ b/src/d3d11/d3d11_features.cpp @@ -177,6 +177,14 @@ namespace dxvk { } + D3D_FEATURE_LEVEL D3D11DeviceFeatures::GetMaxFeatureLevel( + const Rc& Instance, + const Rc& Adapter) { + D3D11DeviceFeatures features(Instance, Adapter, D3D_FEATURE_LEVEL_12_1); + return features.GetMaxFeatureLevel(); + } + + D3D11_CONSERVATIVE_RASTERIZATION_TIER D3D11DeviceFeatures::DetermineConservativeRasterizationTier( D3D_FEATURE_LEVEL FeatureLevel) { if (FeatureLevel < D3D_FEATURE_LEVEL_11_1 @@ -265,4 +273,31 @@ namespace dxvk { return TRUE; } + + D3D_FEATURE_LEVEL D3D11DeviceFeatures::GetMaxFeatureLevel() const { + // Check Feature Level 11_0 features + if (!m_features.core.features.drawIndirectFirstInstance + || !m_features.core.features.fragmentStoresAndAtomics + || !m_features.core.features.multiDrawIndirect + || !m_features.core.features.tessellationShader) + return D3D_FEATURE_LEVEL_10_1; + + // Check Feature Level 11_1 features + if (!m_d3d11Options.OutputMergerLogicOp + || !m_features.core.features.vertexPipelineStoresAndAtomics) + return D3D_FEATURE_LEVEL_11_0; + + // Check Feature Level 12_0 features + if (m_d3d11Options2.TiledResourcesTier < D3D11_TILED_RESOURCES_TIER_2 + || !m_d3d11Options2.TypedUAVLoadAdditionalFormats) + return D3D_FEATURE_LEVEL_11_1; + + // Check Feature Level 12_1 features + if (!m_d3d11Options2.ConservativeRasterizationTier + || !m_d3d11Options2.ROVsSupported) + return D3D_FEATURE_LEVEL_12_0; + + return D3D_FEATURE_LEVEL_12_1; + } + } diff --git a/src/d3d11/d3d11_features.h b/src/d3d11/d3d11_features.h index bf5e48305..052eec6a5 100644 --- a/src/d3d11/d3d11_features.h +++ b/src/d3d11/d3d11_features.h @@ -54,6 +54,17 @@ namespace dxvk { return m_d3d11Options2.ConservativeRasterizationTier; } + /** + * \brief Tests maximum supported feature level + * + * \param [in] Instance DXVK instance + * \param [in] Adapter DXVK adapter + * \returns Highest supported feature level + */ + static D3D_FEATURE_LEVEL GetMaxFeatureLevel( + const Rc& Instance, + const Rc& Adapter); + private: DxvkDeviceFeatures m_features; @@ -100,6 +111,8 @@ namespace dxvk { const Rc& Adapter, D3D_FEATURE_LEVEL FeatureLevel); + D3D_FEATURE_LEVEL GetMaxFeatureLevel() const; + }; } \ No newline at end of file From 6d9353f4e907d634e09e11ae810a9a22342cd14d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 4 Sep 2022 15:52:23 +0200 Subject: [PATCH 0760/1348] [d3d11] Don't depend on variableMultisampleRate feature --- VP_DXVK_requirements.json | 4 +--- src/d3d11/d3d11_device.cpp | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/VP_DXVK_requirements.json b/VP_DXVK_requirements.json index 6317a829e..c2bfc445a 100644 --- a/VP_DXVK_requirements.json +++ b/VP_DXVK_requirements.json @@ -268,8 +268,7 @@ "d3d11_level10_0_optional": { "features": { "VkPhysicalDeviceFeatures": { - "logicOp": true, - "variableMultisampleRate": true + "logicOp": true } } }, @@ -303,7 +302,6 @@ "features": { "VkPhysicalDeviceFeatures": { "logicOp": true, - "variableMultisampleRate": true, "vertexPipelineStoresAndAtomics": true } } diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index daaa5475f..5940995be 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1878,7 +1878,6 @@ namespace dxvk { // Required for Feature Level 11_1 enabled.core.features.logicOp = supported.core.features.logicOp; - enabled.core.features.variableMultisampleRate = supported.core.features.variableMultisampleRate; enabled.core.features.vertexPipelineStoresAndAtomics = supported.core.features.vertexPipelineStoresAndAtomics; // Required for Feature Level 12_0 From e8c1a8e7341c9f346f0bd5ca42e4dce281c0073c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 4 Sep 2022 15:17:38 +0200 Subject: [PATCH 0761/1348] [dxbc] Clean up support check for R32 reads without format --- src/dxbc/dxbc_options.cpp | 37 +++++-------------------------------- src/dxbc/dxbc_options.h | 1 - 2 files changed, 5 insertions(+), 33 deletions(-) diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index b02351633..ba373dde1 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -21,39 +21,12 @@ namespace dxvk { = (devInfo.vk11.subgroupSupportedStages & VK_SHADER_STAGE_COMPUTE_BIT) && (devInfo.vk11.subgroupSupportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); - supportsTypedUavLoadR32 = true; - supportsTypedUavLoadExtended = true; + VkFormatFeatureFlags2 r32Features + = device->getFormatFeatures(VK_FORMAT_R32_SFLOAT).optimal + & device->getFormatFeatures(VK_FORMAT_R32_UINT).optimal + & device->getFormatFeatures(VK_FORMAT_R32_SINT).optimal; - static const std::array, 18> s_typedUavFormats = { - std::make_pair(VK_FORMAT_R32_SFLOAT, false), - std::make_pair(VK_FORMAT_R32_UINT, false), - std::make_pair(VK_FORMAT_R32_SINT, false), - std::make_pair(VK_FORMAT_R32G32B32A32_SFLOAT, true), - std::make_pair(VK_FORMAT_R32G32B32A32_UINT, true), - std::make_pair(VK_FORMAT_R32G32B32A32_SINT, true), - std::make_pair(VK_FORMAT_R16G16B16A16_SFLOAT, true), - std::make_pair(VK_FORMAT_R16G16B16A16_UINT, true), - std::make_pair(VK_FORMAT_R16G16B16A16_SINT, true), - std::make_pair(VK_FORMAT_R8G8B8A8_UNORM, true), - std::make_pair(VK_FORMAT_R8G8B8A8_UINT, true), - std::make_pair(VK_FORMAT_R8G8B8A8_SINT, true), - std::make_pair(VK_FORMAT_R16_SFLOAT, true), - std::make_pair(VK_FORMAT_R16_UINT, true), - std::make_pair(VK_FORMAT_R16_SINT, true), - std::make_pair(VK_FORMAT_R8_UNORM, true), - std::make_pair(VK_FORMAT_R8_UINT, true), - std::make_pair(VK_FORMAT_R8_SINT, true), - }; - - for (const auto& f : s_typedUavFormats) { - DxvkFormatFeatures features = device->getFormatFeatures(f.first); - VkFormatFeatureFlags2 imgFeatures = features.optimal | features.linear; - - if (!(imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT)) { - supportsTypedUavLoadR32 &= f.second; - supportsTypedUavLoadExtended = false; - } - } + supportsTypedUavLoadR32 = (r32Features & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT); switch (device->config().useRawSsbo) { case Tristate::Auto: minSsboAlignment = devInfo.core.properties.limits.minStorageBufferOffsetAlignment; break; diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index 336526da0..d472b3588 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -26,7 +26,6 @@ namespace dxvk { /// Determines whether format qualifiers /// on typed UAV loads are required bool supportsTypedUavLoadR32 = false; - bool supportsTypedUavLoadExtended = false; /// Use subgroup operations to reduce the number of /// atomic operations for append/consume buffers. From d42df372579a14cbb8f55e088d8c0d08a8ee8f65 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 4 Sep 2022 16:14:19 +0200 Subject: [PATCH 0762/1348] [meta] Clean up obsolete feature levels in Vulkan profile --- VP_DXVK_requirements.json | 147 +++++++------------------------------- 1 file changed, 24 insertions(+), 123 deletions(-) diff --git a/VP_DXVK_requirements.json b/VP_DXVK_requirements.json index c2bfc445a..6dee56330 100644 --- a/VP_DXVK_requirements.json +++ b/VP_DXVK_requirements.json @@ -143,27 +143,26 @@ }, "d3d11_baseline": { "extensions": { - "VK_EXT_robustness2": 1 + "VK_EXT_robustness2": 1, + "VK_EXT_transform_feedback": 1 }, "features": { "VkPhysicalDeviceFeatures": { - "geometryShader": true, - "depthBounds": true, - - "imageCubeArray": true, - "depthClamp": true, "depthBiasClamp": true, + "depthClamp": true, + "dualSrcBlend": true, "fillModeNonSolid": true, + "fullDrawIndexUint32": true, + "geometryShader": true, + "imageCubeArray": true, + "independentBlend": true, + "multiViewport": true, + "occlusionQueryPrecise": true, "sampleRateShading": true, "shaderClipDistance": true, "shaderCullDistance": true, - "textureCompressionBC": true, - "occlusionQueryPrecise": true, - "multiViewport": true, - "independentBlend": true, - "fullDrawIndexUint32": true, - - "shaderImageGatherExtended": true + "shaderImageGatherExtended": true, + "textureCompressionBC": true }, "VkPhysicalDeviceVulkan11Features": { "shaderDrawParameters": true @@ -174,6 +173,10 @@ "VkPhysicalDeviceRobustness2FeaturesEXT": { "nullDescriptor": true, "robustBufferAccess2": true + }, + "VkPhysicalDeviceTransformFeedbackFeaturesEXT": { + "transformFeedback": true, + "geometryStreams": true } } }, @@ -181,11 +184,15 @@ "extensions": { "VK_EXT_memory_priority": 1, "VK_EXT_vertex_attribute_divisor": 1, - "VK_EXT_custom_border_color": 1 + "VK_EXT_custom_border_color": 1, + "VK_EXT_depth_clip_enable": 1 }, "features": { "VkPhysicalDeviceFeatures": { - "depthBounds": true + "depthBounds": true, + "pipelineStatisticsQuery": true, + "logicOp": true, + "samplerAnisotropy": true }, "VkPhysicalDeviceMemoryPriorityFeaturesEXT": { "memoryPriority": true @@ -194,92 +201,15 @@ "vertexAttributeInstanceRateDivisor": true, "vertexAttributeInstanceRateZeroDivisor": true }, - "VkPhysicalDeviceCustomBorderColorFeaturesEXT": { "customBorderColors": true, "customBorderColorWithoutFormat": true - } - } - }, - "d3d11_level9_1": { - "extensions": { - "VK_EXT_transform_feedback": 1, - "VK_EXT_depth_clip_enable": 1 - }, - "features": { - "VkPhysicalDeviceFeatures": { - "depthClamp": true, - "depthBiasClamp": true, - "fillModeNonSolid": true, - "sampleRateShading": true, - "shaderClipDistance": true, - "shaderCullDistance": true, - "textureCompressionBC": true }, "VkPhysicalDeviceDepthClipEnableFeaturesEXT": { "depthClipEnable": true } } }, - "d3d11_level9_1_optional": { - "extensions": { - "VK_EXT_depth_clip_enable": 1 - }, - "features": { - "VkPhysicalDeviceFeatures": { - "pipelineStatisticsQuery": true, - "samplerAnisotropy": true - }, - "VkPhysicalDeviceDepthClipEnableFeaturesEXT": { - "depthClipEnable": true - } - } - }, - "d3d11_level9_2": { - "features": { - "VkPhysicalDeviceFeatures": { - "occlusionQueryPrecise": true - } - } - }, - "d3d11_level9_3": { - "features": { - "VkPhysicalDeviceFeatures": { - "independentBlend": true, - "multiViewport": true - } - } - }, - "d3d11_level10_0": { - "extensions": { - "VK_EXT_transform_feedback": 1 - }, - "features": { - "VkPhysicalDeviceFeatures": { - "fullDrawIndexUint32": true, - "shaderImageGatherExtended": true - }, - "VkPhysicalDeviceTransformFeedbackFeaturesEXT": { - "transformFeedback": true, - "geometryStreams": true - } - } - }, - "d3d11_level10_0_optional": { - "features": { - "VkPhysicalDeviceFeatures": { - "logicOp": true - } - } - }, - "d3d11_level10_1": { - "features": { - "VkPhysicalDeviceFeatures": { - "dualSrcBlend": true, - "imageCubeArray": true - } - } - }, "d3d11_level11_0": { "features": { "VkPhysicalDeviceFeatures": { @@ -444,12 +374,7 @@ "vulkan11requirements", "vulkan12requirements", "vulkan13requirements", - "d3d11_baseline", - "d3d11_level9_1", - "d3d11_level9_2", - "d3d11_level9_3", - "d3d11_level10_0", - "d3d11_level10_1" + "d3d11_baseline" ] }, "VP_DXVK_d3d11_level_11_0_baseline": { @@ -488,11 +413,6 @@ "vulkan12requirements", "vulkan13requirements", "d3d11_baseline", - "d3d11_level9_1", - "d3d11_level9_2", - "d3d11_level9_3", - "d3d11_level10_0", - "d3d11_level10_1", "d3d11_level11_0" ] }, @@ -531,12 +451,7 @@ "vulkan11requirements", "vulkan12requirements", "vulkan13requirements", - "baseline", - "d3d11_level9_1", - "d3d11_level9_2", - "d3d11_level9_3", - "d3d11_level10_0", - "d3d11_level10_1", + "d3d11_baseline", "d3d11_level11_0", "d3d11_level11_1" ] @@ -578,13 +493,6 @@ "vulkan13requirements", "d3d11_baseline", "d3d11_baseline_optional", - "d3d11_level9_1", - "d3d11_level9_1_optional", - "d3d11_level9_2", - "d3d11_level9_3", - "d3d11_level10_0", - "d3d11_level10_0_optional", - "d3d11_level10_1", "d3d11_level11_0", "d3d11_level11_0_optional", "d3d11_level11_1" @@ -627,13 +535,6 @@ "vulkan13requirements", "d3d11_baseline", "d3d11_baseline_optional", - "d3d11_level9_1", - "d3d11_level9_1_optional", - "d3d11_level9_2", - "d3d11_level9_3", - "d3d11_level10_0", - "d3d11_level10_0_optional", - "d3d11_level10_1", "d3d11_level11_0", "d3d11_level11_0_optional", "d3d11_level11_1", From 957d99ed8d4650cd29f2c2b8c874db6db4b8f7ed Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 03:39:04 +0200 Subject: [PATCH 0763/1348] [dxvk] Fix broken layer handling in packImageData --- src/dxvk/dxvk_util.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_util.cpp b/src/dxvk/dxvk_util.cpp index 1c2296984..4066c20fb 100644 --- a/src/dxvk/dxvk_util.cpp +++ b/src/dxvk/dxvk_util.cpp @@ -66,10 +66,10 @@ namespace dxvk::util { uint32_t imageLayers, const DxvkFormatInfo* formatInfo, VkImageAspectFlags aspectMask) { - for (uint32_t i = 0; i < imageLayers; i++) { - auto dstData = reinterpret_cast< char*>(dstBytes); - auto srcData = reinterpret_cast(srcBytes); + auto dstData = reinterpret_cast< char*>(dstBytes); + auto srcData = reinterpret_cast(srcBytes); + for (uint32_t k = 0; k < imageLayers; k++) { for (auto aspects = aspectMask; aspects; ) { auto aspect = vk::getNextAspect(aspects); auto extent = imageExtent; From e9851bee861f4b8dbee7b5bf7213b55234581c77 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 04:30:38 +0200 Subject: [PATCH 0764/1348] [dxvk] Introduce per-aspect version of computeImageDataSize --- src/dxvk/dxvk_util.cpp | 8 +++++++- src/dxvk/dxvk_util.h | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_util.cpp b/src/dxvk/dxvk_util.cpp index 4066c20fb..4f9879c4f 100644 --- a/src/dxvk/dxvk_util.cpp +++ b/src/dxvk/dxvk_util.cpp @@ -145,10 +145,16 @@ namespace dxvk::util { VkDeviceSize computeImageDataSize(VkFormat format, VkExtent3D extent) { const DxvkFormatInfo* formatInfo = lookupFormatInfo(format); + return computeImageDataSize(format, extent, formatInfo->aspectMask); + } + + + VkDeviceSize computeImageDataSize(VkFormat format, VkExtent3D extent, VkImageAspectFlags aspects) { + const DxvkFormatInfo* formatInfo = lookupFormatInfo(format); VkDeviceSize size = 0; - for (auto aspects = formatInfo->aspectMask; aspects; ) { + while (aspects) { auto aspect = vk::getNextAspect(aspects); auto elementSize = formatInfo->elementSize; auto planeExtent = extent; diff --git a/src/dxvk/dxvk_util.h b/src/dxvk/dxvk_util.h index a9a4b7ee4..967458faf 100644 --- a/src/dxvk/dxvk_util.h +++ b/src/dxvk/dxvk_util.h @@ -298,6 +298,19 @@ namespace dxvk::util { */ VkDeviceSize computeImageDataSize(VkFormat format, VkExtent3D extent); + /** + * \brief Computes image data size, in bytes + * + * Convenience method that can be used to compute the number + * of bytes required to store image data in a given format + * for the given aspects. + * \param [in] format The image format + * \param [in] extent Image size, in pixels + * \param [in] aspects Aspect mask + * \returns Data size, in bytes + */ + VkDeviceSize computeImageDataSize(VkFormat format, VkExtent3D extent, VkImageAspectFlags aspects); + /** * \brief Applies a component mapping to a component mask * From ca833082b5578ca1af41e76451c21d655de3b9c0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 01:56:54 +0200 Subject: [PATCH 0765/1348] [d3d11] Fix broken image readback for mapped default images --- src/d3d11/d3d11_context_imm.cpp | 44 +++++++++++++++++++++++++++++++-- src/d3d11/d3d11_context_imm.h | 4 +++ src/d3d11/d3d11_texture.h | 2 +- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 3aa4d3613..0670fdac3 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -478,6 +478,13 @@ namespace dxvk { constexpr uint32_t DoWait = (1u << 2); uint32_t doFlags; + if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) { + // If the image can be written by the GPU, we need to update the + // mapped staging buffer to reflect the current image contents. + if (pResource->Desc()->Usage == D3D11_USAGE_DEFAULT) + ReadbackImageBuffer(pResource, Subresource); + } + if (MapType == D3D11_MAP_READ) { // Reads will not change the image content, so we only need // to wait for the GPU to finish writing to the mapped buffer. @@ -583,8 +590,7 @@ namespace dxvk { // the given subresource is actually mapped right now m_mappedImageCount -= 1; - if ((mapType != D3D11_MAP_READ) && - (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER)) { + if ((mapType != D3D11_MAP_READ) && (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER)) { // Now that data has been written into the buffer, // we need to copy its contents into the image VkImageAspectFlags aspectMask = lookupFormatInfo(pResource->GetPackedFormat())->aspectMask; @@ -597,6 +603,40 @@ namespace dxvk { } + void D3D11ImmediateContext::ReadbackImageBuffer( + D3D11CommonTexture* pResource, + UINT Subresource) { + VkImageAspectFlags aspectMask = lookupFormatInfo(pResource->GetPackedFormat())->aspectMask; + VkImageSubresource subresource = pResource->GetSubresourceFromIndex(aspectMask, Subresource); + + EmitCs([ + cSrcImage = pResource->GetImage(), + cSrcSubresource = vk::makeSubresourceLayers(subresource), + cDstBuffer = pResource->GetMappedBuffer(Subresource), + cPackedFormat = pResource->GetPackedFormat() + ] (DxvkContext* ctx) { + VkOffset3D offset = { 0, 0, 0 }; + VkExtent3D extent = cSrcImage->mipLevelExtent(cSrcSubresource.mipLevel); + + if (cSrcSubresource.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + ctx->copyImageToBuffer(cDstBuffer, 0, 0, 0, + cSrcImage, cSrcSubresource, offset, extent); + } else { + ctx->copyDepthStencilImageToPackedBuffer(cDstBuffer, 0, + VkOffset2D { 0, 0 }, + VkExtent2D { extent.width, extent.height }, + cSrcImage, cSrcSubresource, + VkOffset2D { 0, 0 }, + VkExtent2D { extent.width, extent.height }, + cPackedFormat); + } + }); + + if (pResource->HasSequenceNumber()) + TrackTextureSequenceNumber(pResource, Subresource); + } + + void D3D11ImmediateContext::UpdateMappedBuffer( D3D11Buffer* pDstBuffer, UINT Offset, diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index e64c2d620..888e1eeca 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -120,6 +120,10 @@ namespace dxvk { D3D11CommonTexture* pResource, UINT Subresource); + void ReadbackImageBuffer( + D3D11CommonTexture* pResource, + UINT Subresource); + void UpdateMappedBuffer( D3D11Buffer* pDstBuffer, UINT Offset, diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index 0bb25b916..c510ae952 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -256,7 +256,7 @@ namespace dxvk { // For buffer-mapped images we only need to track copies to // and from that buffer, so we can safely ignore bind flags if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) - return true; + return m_desc.Usage != D3D11_USAGE_DEFAULT; // Otherwise we can only do accurate tracking if the // image cannot be used in the rendering pipeline. From 1bed39f2664faf5ba9291dd52a22218db3473fa6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 02:45:26 +0200 Subject: [PATCH 0766/1348] [d3d11] Rework ReadFromSubresource and WriteToSubresource Mainly changes the code to use existing helpers where possible, and adds support for planar images, which was previously completely broken for these functions. --- src/d3d11/d3d11_device.cpp | 146 +++++++++++++++++++------------------ src/d3d11/d3d11_device.h | 2 +- 2 files changed, 76 insertions(+), 72 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 5940995be..26a73dc8f 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1378,9 +1378,25 @@ namespace dxvk { ID3D11Resource* pSrcResource, UINT SrcSubresource, const D3D11_BOX* pSrcBox) { + auto texture = GetCommonTexture(pSrcResource); + + if (!texture) + return; + + if (texture->Desc()->Usage != D3D11_USAGE_DEFAULT + || texture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE + || texture->CountSubresources() <= SrcSubresource) + return; + + D3D11_MAP map = texture->GetMapType(SrcSubresource); + + if (map != D3D11_MAP_READ + && map != D3D11_MAP_READ_WRITE) + return; + CopySubresourceData( pDstData, DstRowPitch, DstDepthPitch, - pSrcResource, SrcSubresource, pSrcBox); + texture, SrcSubresource, pSrcBox); } @@ -1391,9 +1407,26 @@ namespace dxvk { const void* pSrcData, UINT SrcRowPitch, UINT SrcDepthPitch) { + auto texture = GetCommonTexture(pDstResource); + + if (!texture) + return; + + if (texture->Desc()->Usage != D3D11_USAGE_DEFAULT + || texture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE + || texture->CountSubresources() <= DstSubresource) + return; + + D3D11_MAP map = texture->GetMapType(DstSubresource); + + if (map != D3D11_MAP_WRITE + && map != D3D11_MAP_WRITE_NO_OVERWRITE + && map != D3D11_MAP_READ_WRITE) + return; + CopySubresourceData( pSrcData, SrcRowPitch, SrcRowPitch, - pDstResource, DstSubresource, pDstBox); + texture, DstSubresource, pDstBox); } @@ -2240,36 +2273,16 @@ namespace dxvk { Void* pData, UINT RowPitch, UINT DepthPitch, - ID3D11Resource* pResource, + D3D11CommonTexture* pTexture, UINT Subresource, const D3D11_BOX* pBox) { - auto texture = GetCommonTexture(pResource); - - if (!texture) - return; - - // Validate texture state and skip invalid calls - if (texture->Desc()->Usage != D3D11_USAGE_DEFAULT - || texture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE - || texture->CountSubresources() <= Subresource - || texture->GetMapType(Subresource) == D3D11_MAP(~0u)) - return; - - // Retrieve image format information - VkFormat packedFormat = LookupPackedFormat( - texture->Desc()->Format, - texture->GetFormatMode()).Format; - - auto formatInfo = lookupFormatInfo(packedFormat); - // Validate box against subresource dimensions - Rc image = texture->GetImage(); - - auto subresource = texture->GetSubresourceFromIndex( + auto formatInfo = lookupFormatInfo(pTexture->GetPackedFormat()); + auto subresource = pTexture->GetSubresourceFromIndex( formatInfo->aspectMask, Subresource); - + VkOffset3D offset = { 0, 0, 0 }; - VkExtent3D extent = image->mipLevelExtent(subresource.mipLevel); + VkExtent3D extent = pTexture->MipLevelExtent(subresource.mipLevel); if (pBox) { if (pBox->left >= pBox->right @@ -2293,56 +2306,47 @@ namespace dxvk { pBox->back - pBox->front }; } - // We can only operate on full blocks of compressed images - offset = util::computeBlockOffset(offset, formatInfo->blockSize); - extent = util::computeBlockCount(extent, formatInfo->blockSize); + // Copy image data, one plane at a time for multi-plane formats + Rc image = pTexture->GetImage(); + VkDeviceSize dataOffset = 0; - // Determine the memory layout of the image data - D3D11_MAPPED_SUBRESOURCE subresourceData = { }; + for (uint32_t i = 0; i < pTexture->GetPlaneCount(); i++) { + // Find current image aspects to process + VkImageAspectFlags aspect = formatInfo->aspectMask; - if (texture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) { - VkSubresourceLayout layout = image->querySubresourceLayout(subresource); - subresourceData.pData = image->mapPtr(layout.offset); - subresourceData.RowPitch = layout.rowPitch; - subresourceData.DepthPitch = layout.depthPitch; - } else { - subresourceData.pData = texture->GetMappedBuffer(Subresource)->mapPtr(0); - subresourceData.RowPitch = formatInfo->elementSize * extent.width; - subresourceData.DepthPitch = formatInfo->elementSize * extent.width * extent.height; - } + if (formatInfo->flags.test(DxvkFormatFlag::MultiPlane)) + aspect = vk::getPlaneAspect(i); - if constexpr (std::is_const::value) { - // WriteToSubresource - auto src = reinterpret_cast(pData); - auto dst = reinterpret_cast< char*>(subresourceData.pData); + // Compute data layout of the current subresource + D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT layout = pTexture->GetSubresourceLayout(aspect, Subresource); - for (uint32_t z = 0; z < extent.depth; z++) { - for (uint32_t y = 0; y < extent.height; y++) { - std::memcpy( - dst + (offset.z + z) * subresourceData.DepthPitch - + (offset.y + y) * subresourceData.RowPitch - + (offset.x) * formatInfo->elementSize, - src + z * DepthPitch - + y * RowPitch, - formatInfo->elementSize * extent.width); - } + // Compute actual map pointer, accounting for the region offset + VkDeviceSize mapOffset = pTexture->ComputeMappedOffset(Subresource, i, offset); + + void* mapPtr = pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER + ? pTexture->GetMappedBuffer(Subresource)->mapPtr(mapOffset) + : image->mapPtr(mapOffset); + + if constexpr (std::is_const::value) { + // WriteToSubresource + auto srcData = reinterpret_cast(pData) + dataOffset; + + util::packImageData(mapPtr, srcData, RowPitch, DepthPitch, + layout.RowPitch, layout.DepthPitch, image->info().type, + extent, 1, formatInfo, aspect); + } else { + // ReadFromSubresource + auto dstData = reinterpret_cast(pData) + dataOffset; + + util::packImageData(dstData, mapPtr, + layout.RowPitch, layout.DepthPitch, + RowPitch, DepthPitch, image->info().type, + extent, 1, formatInfo, aspect); } - } else { - // ReadFromSubresource - auto src = reinterpret_cast(subresourceData.pData); - auto dst = reinterpret_cast< char*>(pData); - for (uint32_t z = 0; z < extent.depth; z++) { - for (uint32_t y = 0; y < extent.height; y++) { - std::memcpy( - dst + z * DepthPitch - + y * RowPitch, - src + (offset.z + z) * subresourceData.DepthPitch - + (offset.y + y) * subresourceData.RowPitch - + (offset.x) * formatInfo->elementSize, - formatInfo->elementSize * extent.width); - } - } + // Advance linear data pointer by the size of the current aspect + dataOffset += util::computeImageDataSize( + pTexture->GetPackedFormat(), extent, aspect); } } diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 5da3ae3f2..3db1c2ee3 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -490,7 +490,7 @@ namespace dxvk { Void* pData, UINT RowPitch, UINT DepthPitch, - ID3D11Resource* pResource, + D3D11CommonTexture* pTexture, UINT Subresource, const D3D11_BOX* pBox); From 40ffac72d9bc2a010b96f5de30a0f12186ca3a52 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 04:57:31 +0200 Subject: [PATCH 0767/1348] [d3d11] Introduce methods for dirty region tracking for mapped images --- src/d3d11/d3d11_texture.h | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index c510ae952..b8324c81e 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -61,6 +61,15 @@ namespace dxvk { }; + /** + * \brief Region + */ + struct D3D11_COMMON_TEXTURE_REGION { + VkOffset3D Offset; + VkExtent3D Extent; + }; + + /** * \brief D3D11 common texture object * @@ -292,6 +301,72 @@ namespace dxvk { } } + /** + * \brief Adds a dirty region + * + * This region will be updated on Unmap. + * \param [in] Subresource Subresource index + * \param [in] Offset Region offset + * \param [in] Extent Region extent + */ + void AddDirtyRegion(UINT Subresource, VkOffset3D Offset, VkExtent3D Extent) { + D3D11_COMMON_TEXTURE_REGION region; + region.Offset = Offset; + region.Extent = Extent; + + if (Subresource < m_buffers.size()) + m_buffers[Subresource].dirtyRegions.push_back(region); + } + + /** + * \brief Clears dirty regions + * + * Removes all dirty regions from the given subresource. + * \param [in] Subresource Subresource index + */ + void ClearDirtyRegions(UINT Subresource) { + if (Subresource < m_buffers.size()) + m_buffers[Subresource].dirtyRegions.clear(); + } + + /** + * \brief Counts dirty regions + * + * \param [in] Subresource Subresource index + * \returns Dirty region count + */ + UINT GetDirtyRegionCount(UINT Subresource) { + return (Subresource < m_buffers.size()) + ? UINT(m_buffers[Subresource].dirtyRegions.size()) + : UINT(0); + } + + /** + * \brief Retrieves dirty regions + * + * \param [in] Subresource Subresource index + * \param [in] Region Region index + * \returns Dirty region + */ + D3D11_COMMON_TEXTURE_REGION GetDirtyRegionCount(UINT Subresource, UINT Region) { + return m_buffers[Subresource].dirtyRegions[Region]; + } + + /** + * \brief Checks whether or not to track dirty regions + * + * If this returns true, then any functions that update the + * mapped staging buffer must also track dirty regions while + * the image is mapped. Otherwise, the entire image is dirty. + * \returns \c true if dirty regions must be tracked + */ + bool NeedsDirtyRegionTracking() const { + // Only set this for images where Map can't return a pointer + return m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER + && m_desc.Usage == D3D11_USAGE_DEFAULT + && m_desc.TextureLayout == D3D11_TEXTURE_LAYOUT_UNDEFINED; + } + /** * \brief Computes pixel offset into mapped buffer * @@ -379,6 +454,8 @@ namespace dxvk { struct MappedBuffer { Rc buffer; DxvkBufferSliceHandle slice; + + std::vector dirtyRegions; }; struct MappedInfo { From fdcbdeb28f615f30e24ea19674a1a23dd60c5f2c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 05:35:16 +0200 Subject: [PATCH 0768/1348] [d3d11] Implement dirty trackig for default-mapped images Avoids GPU synchronization when using WriteToSubresource, and also reduces bandwidth. --- src/d3d11/d3d11_context_imm.cpp | 88 +++++++++++++++++++++++++++++---- src/d3d11/d3d11_context_imm.h | 5 ++ src/d3d11/d3d11_device.cpp | 4 ++ src/d3d11/d3d11_texture.h | 4 +- 4 files changed, 90 insertions(+), 11 deletions(-) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 0670fdac3..f5e436621 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -481,8 +481,15 @@ namespace dxvk { if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) { // If the image can be written by the GPU, we need to update the // mapped staging buffer to reflect the current image contents. - if (pResource->Desc()->Usage == D3D11_USAGE_DEFAULT) - ReadbackImageBuffer(pResource, Subresource); + if (pResource->Desc()->Usage == D3D11_USAGE_DEFAULT) { + bool needsReadback = !pResource->NeedsDirtyRegionTracking(); + + needsReadback |= MapType == D3D11_MAP_READ + || MapType == D3D11_MAP_READ_WRITE; + + if (needsReadback) + ReadbackImageBuffer(pResource, Subresource); + } } if (MapType == D3D11_MAP_READ) { @@ -591,14 +598,16 @@ namespace dxvk { m_mappedImageCount -= 1; if ((mapType != D3D11_MAP_READ) && (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER)) { - // Now that data has been written into the buffer, - // we need to copy its contents into the image - VkImageAspectFlags aspectMask = lookupFormatInfo(pResource->GetPackedFormat())->aspectMask; - VkImageSubresource subresource = pResource->GetSubresourceFromIndex(aspectMask, Subresource); + if (pResource->NeedsDirtyRegionTracking()) { + for (uint32_t i = 0; i < pResource->GetDirtyRegionCount(Subresource); i++) { + D3D11_COMMON_TEXTURE_REGION region = pResource->GetDirtyRegion(Subresource, i); + UpdateDirtyImageRegion(pResource, Subresource, ®ion); + } - UpdateImage(pResource, &subresource, VkOffset3D { 0, 0, 0 }, - pResource->MipLevelExtent(subresource.mipLevel), - DxvkBufferSlice(pResource->GetMappedBuffer(Subresource))); + pResource->ClearDirtyRegions(Subresource); + } else { + UpdateDirtyImageRegion(pResource, Subresource, nullptr); + } } } @@ -637,6 +646,67 @@ namespace dxvk { } + void D3D11ImmediateContext::UpdateDirtyImageRegion( + D3D11CommonTexture* pResource, + UINT Subresource, + const D3D11_COMMON_TEXTURE_REGION* pRegion) { + auto formatInfo = lookupFormatInfo(pResource->GetPackedFormat()); + auto subresource = vk::makeSubresourceLayers( + pResource->GetSubresourceFromIndex(formatInfo->aspectMask, Subresource)); + + // Update the entire image if no dirty region was specified + D3D11_COMMON_TEXTURE_REGION region; + + if (pRegion) { + region = *pRegion; + } else { + region.Offset = VkOffset3D { 0, 0, 0 }; + region.Extent = pResource->MipLevelExtent(subresource.mipLevel); + } + + auto subresourceLayout = pResource->GetSubresourceLayout(formatInfo->aspectMask, Subresource); + + // Update dirty region one aspect at a time, due to + // how the data is laid out in the staging buffer. + for (uint32_t i = 0; i < pResource->GetPlaneCount(); i++) { + subresource.aspectMask = formatInfo->aspectMask; + + if (formatInfo->flags.test(DxvkFormatFlag::MultiPlane)) + subresource.aspectMask = vk::getPlaneAspect(i); + + EmitCs([ + cDstImage = pResource->GetImage(), + cDstSubresource = subresource, + cDstOffset = region.Offset, + cDstExtent = region.Extent, + cSrcBuffer = pResource->GetMappedBuffer(Subresource), + cSrcOffset = pResource->ComputeMappedOffset(Subresource, i, region.Offset), + cSrcRowPitch = subresourceLayout.RowPitch, + cSrcDepthPitch = subresourceLayout.DepthPitch, + cPackedFormat = pResource->GetPackedFormat() + ] (DxvkContext* ctx) { + if (cDstSubresource.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + ctx->copyBufferToImage( + cDstImage, cDstSubresource, cDstOffset, cDstExtent, + cSrcBuffer, cSrcOffset, cSrcRowPitch, cSrcDepthPitch); + } else { + ctx->copyPackedBufferToDepthStencilImage( + cDstImage, cDstSubresource, + VkOffset2D { cDstOffset.x, cDstOffset.y }, + VkExtent2D { cDstExtent.width, cDstExtent.height }, + cSrcBuffer, 0, + VkOffset2D { cDstOffset.x, cDstOffset.y }, + VkExtent2D { cDstExtent.width, cDstExtent.height }, + cPackedFormat); + } + }); + } + + if (pResource->HasSequenceNumber()) + TrackTextureSequenceNumber(pResource, Subresource); + } + + void D3D11ImmediateContext::UpdateMappedBuffer( D3D11Buffer* pDstBuffer, UINT Offset, diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 888e1eeca..b00a81118 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -124,6 +124,11 @@ namespace dxvk { D3D11CommonTexture* pResource, UINT Subresource); + void UpdateDirtyImageRegion( + D3D11CommonTexture* pResource, + UINT Subresource, + const D3D11_COMMON_TEXTURE_REGION* pRegion); + void UpdateMappedBuffer( D3D11Buffer* pDstBuffer, UINT Offset, diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 26a73dc8f..be7c275b5 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2348,6 +2348,10 @@ namespace dxvk { dataOffset += util::computeImageDataSize( pTexture->GetPackedFormat(), extent, aspect); } + + // Track dirty texture region if necessary + if constexpr (std::is_const::value) + pTexture->AddDirtyRegion(Subresource, offset, extent); } diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index b8324c81e..217051785 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -342,13 +342,13 @@ namespace dxvk { } /** - * \brief Retrieves dirty regions + * \brief Queries a dirty regions * * \param [in] Subresource Subresource index * \param [in] Region Region index * \returns Dirty region */ - D3D11_COMMON_TEXTURE_REGION GetDirtyRegionCount(UINT Subresource, UINT Region) { + D3D11_COMMON_TEXTURE_REGION GetDirtyRegion(UINT Subresource, UINT Region) { return m_buffers[Subresource].dirtyRegions[Region]; } From bd912212b5f83eb190dc1ace85d5c0cb9a47d9a1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 04:44:25 +0200 Subject: [PATCH 0769/1348] [d3d11] Adjust preferred mapping modes for default images --- src/d3d11/d3d11_texture.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index fd05fd532..007d47f24 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -599,10 +599,18 @@ namespace dxvk { // If supported and requested, create a linear image. Default images // can be used for resolves and other operations regardless of bind // flags, so we need to use a proper image for those. - if (m_desc.TextureLayout == D3D11_TEXTURE_LAYOUT_ROW_MAJOR - || m_desc.Usage == D3D11_USAGE_DEFAULT) + if (m_desc.TextureLayout == D3D11_TEXTURE_LAYOUT_ROW_MAJOR) return D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT; + // For default images, prefer direct mapping if the image is CPU readable + // since mapping for reads would have to stall otherwise. If the image is + // only writable, prefer a write-through buffer. + if (m_desc.Usage == D3D11_USAGE_DEFAULT) { + return (m_desc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) + ? D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT + : D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER; + } + // The overhead of frequently uploading large dynamic images may outweigh // the benefit of linear tiling, so use a linear image in those cases. VkDeviceSize threshold = m_device->GetOptions()->maxDynamicImageBufferSize; From 3401964ee27fea5d0baa9810161f27c9c55f5756 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 07:21:47 +0200 Subject: [PATCH 0770/1348] [dxbc] Implement support for SV_InnerCoverage --- src/dxbc/dxbc_compiler.cpp | 37 ++++++++++++++++++++++++++++++++++++- src/dxbc/dxbc_compiler.h | 1 + src/dxbc/dxbc_enums.h | 1 + 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 5fafe7672..f2a14e43c 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -635,6 +635,34 @@ namespace dxvk { "vInstanceID"); } break; + case DxbcOperandType::InputInnerCoverage: { + m_module.enableExtension("SPV_EXT_fragment_fully_covered"); + m_module.enableCapability(spv::CapabilityFragmentFullyCoveredEXT); + + // This is bool in SPIR-V but uint32 in DXBC. A bool value of + // false must be 0, and bit 1 must be set to represent true. + uint32_t builtinId = emitNewBuiltinVariable({ + { DxbcScalarType::Bool, 1, 0 }, + spv::StorageClassInput }, + spv::BuiltInFullyCoveredEXT, + nullptr); + + m_ps.builtinInnerCoverageId = emitNewVariable({ + { DxbcScalarType::Uint32, 1, 0 }, + spv::StorageClassPrivate }); + + m_module.setDebugName(m_ps.builtinInnerCoverageId, "vInnerCoverage"); + + uint32_t boolTypeId = m_module.defBoolType(); + uint32_t uintTypeId = m_module.defIntType(32, 0); + + m_module.opStore(m_ps.builtinInnerCoverageId, + m_module.opSelect(uintTypeId, + m_module.opLoad(boolTypeId, builtinId), + m_module.constu32(1), + m_module.constu32(0))); + } break; + default: Logger::err(str::format( "DxbcCompiler: Unsupported operand type declaration: ", @@ -5039,6 +5067,11 @@ namespace dxvk { { DxbcScalarType::Uint32, 1 }, m_gs.builtinInvocationId }; + case DxbcOperandType::InputInnerCoverage: + return DxbcRegisterPointer { + { DxbcScalarType::Uint32, 1 }, + m_ps.builtinInnerCoverageId }; + default: throw DxvkError(str::format( "DxbcCompiler: Unhandled operand type: ", @@ -7400,7 +7433,9 @@ namespace dxvk { const char* name) { const uint32_t varId = emitNewVariable(info); - m_module.setDebugName(varId, name); + if (name) + m_module.setDebugName(varId, name); + m_module.decorateBuiltIn(varId, builtIn); if (m_programInfo.type() == DxbcProgramType::PixelShader diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 771a4c623..fe45c6ec8 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -180,6 +180,7 @@ namespace dxvk { uint32_t builtinSampleMaskOut = 0; uint32_t builtinLayer = 0; uint32_t builtinViewportId = 0; + uint32_t builtinInnerCoverageId = 0; uint32_t pushConstantId = 0; }; diff --git a/src/dxbc/dxbc_enums.h b/src/dxbc/dxbc_enums.h index ead8fd4fe..287271e41 100644 --- a/src/dxbc/dxbc_enums.h +++ b/src/dxbc/dxbc_enums.h @@ -306,6 +306,7 @@ namespace dxvk { OutputDepthLe = 39, CycleCounter = 40, OutputStencilRef = 41, + InputInnerCoverage = 42, }; From d14d70af05f83de54abb064c940b0f6b7dd242c7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 07:26:23 +0200 Subject: [PATCH 0771/1348] [dxvk] Check whether FragmentFullyCoveredEXT capability is used in a shader --- src/dxvk/dxvk_shader.cpp | 3 +++ src/dxvk/dxvk_shader.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 9c06b96c3..ca12995fe 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -138,6 +138,9 @@ namespace dxvk { if (ins.arg(1) == spv::CapabilityShaderViewportIndex || ins.arg(1) == spv::CapabilityShaderLayer) m_flags.set(DxvkShaderFlag::ExportsViewportIndexLayerFromVertexStage); + + if (ins.arg(1) == spv::CapabilityFragmentFullyCoveredEXT) + m_flags.set(DxvkShaderFlag::UsesFragmentCoverage); } // Ignore the actual shader code, there's nothing interesting for us in there. diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 6f820050a..4aa7b97c3 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -30,6 +30,7 @@ namespace dxvk { ExportsPosition, ExportsStencilRef, ExportsViewportIndexLayerFromVertexStage, + UsesFragmentCoverage, }; using DxvkShaderFlags = Flags; From 02600706fe391526c02ece00a012dedce020c034 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 07:27:00 +0200 Subject: [PATCH 0772/1348] [d3d11] Enable Conservative Rasterization Tier 3 Mostly to bring this in line with vkd3d-proton. --- src/d3d11/d3d11_device.cpp | 4 ++++ src/d3d11/d3d11_features.cpp | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index be7c275b5..120a2bc33 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1966,6 +1966,10 @@ namespace dxvk { || !m_dxvkDevice->features().vk12.shaderOutputLayer)) return E_INVALIDARG; + if (shader->flags().test(DxvkShaderFlag::UsesFragmentCoverage) + && !m_dxvkDevice->properties().extConservativeRasterization.fullyCoveredFragmentShaderInputVariable) + return E_INVALIDARG; + *pShaderModule = std::move(commonShader); return S_OK; } diff --git a/src/d3d11/d3d11_features.cpp b/src/d3d11/d3d11_features.cpp index 65b21b002..a3fe2cce0 100644 --- a/src/d3d11/d3d11_features.cpp +++ b/src/d3d11/d3d11_features.cpp @@ -196,7 +196,11 @@ namespace dxvk { if (!m_properties.extConservativeRasterization.degenerateTrianglesRasterized) return D3D11_CONSERVATIVE_RASTERIZATION_TIER_1; - return D3D11_CONSERVATIVE_RASTERIZATION_TIER_2; + // Inner coverage is required for Tier 3 support + if (!m_properties.extConservativeRasterization.fullyCoveredFragmentShaderInputVariable) + return D3D11_CONSERVATIVE_RASTERIZATION_TIER_2; + + return D3D11_CONSERVATIVE_RASTERIZATION_TIER_3; } From b12e4fc59f93a70fc78b4efd381d3e2757507a68 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 07:49:04 +0200 Subject: [PATCH 0773/1348] [dxvk] Check whether SparseResidency capability is used in a shader --- src/dxvk/dxvk_shader.cpp | 3 +++ src/dxvk/dxvk_shader.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index ca12995fe..9bacd838f 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -139,6 +139,9 @@ namespace dxvk { || ins.arg(1) == spv::CapabilityShaderLayer) m_flags.set(DxvkShaderFlag::ExportsViewportIndexLayerFromVertexStage); + if (ins.arg(1) == spv::CapabilitySparseResidency) + m_flags.set(DxvkShaderFlag::UsesSparseResidency); + if (ins.arg(1) == spv::CapabilityFragmentFullyCoveredEXT) m_flags.set(DxvkShaderFlag::UsesFragmentCoverage); } diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 4aa7b97c3..6e5a21057 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -31,6 +31,7 @@ namespace dxvk { ExportsStencilRef, ExportsViewportIndexLayerFromVertexStage, UsesFragmentCoverage, + UsesSparseResidency, }; using DxvkShaderFlags = Flags; From df5756c9a52a30f58c7364499a3523385004ec82 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 07:37:57 +0200 Subject: [PATCH 0774/1348] [d3d11] Do not report Tiled Resources Tier 3 Neither Nvidia nor AMD drivers report Tier 3 support on Windows, so this is likely a D3D11 runtime limitation, even though the API could technically support it. --- src/d3d11/d3d11_features.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/d3d11/d3d11_features.cpp b/src/d3d11/d3d11_features.cpp index a3fe2cce0..099435340 100644 --- a/src/d3d11/d3d11_features.cpp +++ b/src/d3d11/d3d11_features.cpp @@ -231,11 +231,7 @@ namespace dxvk { || m_properties.core.properties.sparseProperties.residencyAlignedMipSize) return D3D11_TILED_RESOURCES_TIER_1; - if (!m_features.core.features.sparseResidencyImage3D - || !m_properties.core.properties.sparseProperties.residencyStandard3DBlockShape) - return D3D11_TILED_RESOURCES_TIER_2; - - return D3D11_TILED_RESOURCES_TIER_3; + return D3D11_TILED_RESOURCES_TIER_2; } From 9964e4a632b944e0271836d31aec755fb6046dd7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 5 Sep 2022 07:44:17 +0200 Subject: [PATCH 0775/1348] [d3d11] Clean up resource validation around tiled resources --- src/d3d11/d3d11_buffer.cpp | 8 +++----- src/d3d11/d3d11_buffer.h | 4 +--- src/d3d11/d3d11_device.cpp | 32 +++++++++++++++++++++----------- src/d3d11/d3d11_interop.cpp | 3 +-- src/d3d11/d3d11_texture.cpp | 5 ++--- src/d3d11/d3d11_texture.h | 4 +--- 6 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index cbcbb1e71..d860d0c07 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -177,7 +177,7 @@ namespace dxvk { } - HRESULT D3D11Buffer::NormalizeBufferProperties(D3D11_BUFFER_DESC* pDesc, D3D11_TILED_RESOURCES_TIER TiledTier) { + HRESULT D3D11Buffer::NormalizeBufferProperties(D3D11_BUFFER_DESC* pDesc) { // Zero-sized buffers are illegal if (!pDesc->ByteWidth && !(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) return E_INVALIDARG; @@ -207,8 +207,7 @@ namespace dxvk { if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILED) { if ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL) || (pDesc->Usage != D3D11_USAGE_DEFAULT) - || (pDesc->CPUAccessFlags) - || (!TiledTier)) + || (pDesc->CPUAccessFlags)) return E_INVALIDARG; } @@ -218,8 +217,7 @@ namespace dxvk { || (pDesc->ByteWidth % SparseMemoryPageSize) || (pDesc->Usage != D3D11_USAGE_DEFAULT) || (pDesc->BindFlags) - || (pDesc->CPUAccessFlags) - || (!TiledTier)) + || (pDesc->CPUAccessFlags)) return E_INVALIDARG; } diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index b3420dc21..a169c4409 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -146,12 +146,10 @@ namespace dxvk { * \brief Normalizes buffer description * * \param [in] pDesc Buffer description - * \param [in] TiledTier Tiled resources tier * \returns \c S_OK if the parameters are valid */ static HRESULT NormalizeBufferProperties( - D3D11_BUFFER_DESC* pDesc, - D3D11_TILED_RESOURCES_TIER TiledTier); + D3D11_BUFFER_DESC* pDesc); private: diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 120a2bc33..d1c3c795c 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -86,12 +86,15 @@ namespace dxvk { return E_INVALIDARG; D3D11_BUFFER_DESC desc = *pDesc; - HRESULT hr = D3D11Buffer::NormalizeBufferProperties(&desc, - m_deviceFeatures.GetTiledResourcesTier()); + HRESULT hr = D3D11Buffer::NormalizeBufferProperties(&desc); if (FAILED(hr)) return hr; + if ((desc.MiscFlags & (D3D11_RESOURCE_MISC_TILED | D3D11_RESOURCE_MISC_TILE_POOL)) + && !m_deviceFeatures.GetTiledResourcesTier()) + return E_INVALIDARG; + if (!ppBuffer) return S_FALSE; @@ -133,12 +136,14 @@ namespace dxvk { desc.MiscFlags = pDesc->MiscFlags; desc.TextureLayout = D3D11_TEXTURE_LAYOUT_UNDEFINED; - HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, - D3D11_TILED_RESOURCES_NOT_SUPPORTED); + HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc); if (FAILED(hr)) return hr; - + + if (desc.MiscFlags & D3D11_RESOURCE_MISC_TILED) + return E_INVALIDARG; + if (!ppTexture1D) return S_FALSE; @@ -210,8 +215,11 @@ namespace dxvk { desc.MiscFlags = pDesc->MiscFlags; desc.TextureLayout = pDesc->TextureLayout; - HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, - m_deviceFeatures.GetTiledResourcesTier()); + HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc); + + if ((desc.MiscFlags & D3D11_RESOURCE_MISC_TILED) + && !m_deviceFeatures.GetTiledResourcesTier()) + return E_INVALIDARG; if (FAILED(hr)) return hr; @@ -286,14 +294,12 @@ namespace dxvk { desc.MiscFlags = pDesc->MiscFlags; desc.TextureLayout = pDesc->TextureLayout; - D3D11_TILED_RESOURCES_TIER tiledResourcesTier = m_deviceFeatures.GetTiledResourcesTier(); - HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, tiledResourcesTier); + HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc); if (FAILED(hr)) return hr; - if ((desc.MiscFlags & D3D11_RESOURCE_MISC_TILED) - && (tiledResourcesTier < D3D11_TILED_RESOURCES_TIER_3)) + if (desc.MiscFlags & D3D11_RESOURCE_MISC_TILED) return E_INVALIDARG; if (!ppTexture3D) @@ -1966,6 +1972,10 @@ namespace dxvk { || !m_dxvkDevice->features().vk12.shaderOutputLayer)) return E_INVALIDARG; + if (shader->flags().test(DxvkShaderFlag::UsesSparseResidency) + && !m_dxvkDevice->features().core.features.shaderResourceResidency) + return E_INVALIDARG; + if (shader->flags().test(DxvkShaderFlag::UsesFragmentCoverage) && !m_dxvkDevice->properties().extConservativeRasterization.fullyCoveredFragmentShaderInputVariable) return E_INVALIDARG; diff --git a/src/d3d11/d3d11_interop.cpp b/src/d3d11/d3d11_interop.cpp index b6cb129d4..8fa50288b 100644 --- a/src/d3d11/d3d11_interop.cpp +++ b/src/d3d11/d3d11_interop.cpp @@ -146,8 +146,7 @@ namespace dxvk { desc.MiscFlags = pDesc->MiscFlags; desc.TextureLayout = pDesc->TextureLayout; - HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc, - D3D11_TILED_RESOURCES_NOT_SUPPORTED); + HRESULT hr = D3D11CommonTexture::NormalizeTextureProperties(&desc); if (FAILED(hr)) return hr; diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 007d47f24..5289202a6 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -402,7 +402,7 @@ namespace dxvk { } - HRESULT D3D11CommonTexture::NormalizeTextureProperties(D3D11_COMMON_TEXTURE_DESC* pDesc, D3D11_TILED_RESOURCES_TIER TiledTier) { + HRESULT D3D11CommonTexture::NormalizeTextureProperties(D3D11_COMMON_TEXTURE_DESC* pDesc) { if (pDesc->Width == 0 || pDesc->Height == 0 || pDesc->Depth == 0 || pDesc->ArraySize == 0) return E_INVALIDARG; @@ -434,8 +434,7 @@ namespace dxvk { if ((pDesc->MiscFlags & invalidFlags) || (pDesc->Usage != D3D11_USAGE_DEFAULT) - || (pDesc->CPUAccessFlags) - || (!TiledTier)) + || (pDesc->CPUAccessFlags)) return E_INVALIDARG; } diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index 217051785..bd778d71f 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -442,12 +442,10 @@ namespace dxvk { * parameters. Any error returned by this method should * be forwarded to the application. * \param [in,out] pDesc Texture description - * \param [in] TiledTier Tiled resources tier * \returns \c S_OK if the parameters are valid */ static HRESULT NormalizeTextureProperties( - D3D11_COMMON_TEXTURE_DESC* pDesc, - D3D11_TILED_RESOURCES_TIER TiledTier); + D3D11_COMMON_TEXTURE_DESC* pDesc); private: From 846db795f862f66bf27780210d0ca0fb9ab12620 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 7 Sep 2022 14:47:33 +0000 Subject: [PATCH 0776/1348] [dxvk] Link against dl for native builds Fixes build under Steam Runtime Sniper --- src/dxvk/meson.build | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 8c4b81784..387bc4d45 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -129,11 +129,14 @@ elif dxvk_wsi == 'sdl2' ] endif -thread_dep = dependency('threads') +dxvk_extra_deps = [ dependency('threads') ] +if platform == 'linux' + dxvk_extra_deps += [ cpp.find_library('dl', required: false) ] +endif dxvk_lib = static_library('dxvk', dxvk_src, glsl_generator.process(dxvk_shaders), dxvk_version, link_with : [ util_lib, spirv_lib, wsi_lib ], - dependencies : [ thread_dep, vkcommon_dep ], + dependencies : [ vkcommon_dep ] + dxvk_extra_deps, include_directories : [ dxvk_include_path ], ) From 1ea48558e5fba944a54e537080cdac38991da50e Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 7 Sep 2022 17:56:24 +0000 Subject: [PATCH 0777/1348] [wsi] Fix return value of setMonitorDisplayMode --- src/wsi/win32/wsi_window_win32.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wsi/win32/wsi_window_win32.cpp b/src/wsi/win32/wsi_window_win32.cpp index 364c0c0ef..ba52c06e9 100644 --- a/src/wsi/win32/wsi_window_win32.cpp +++ b/src/wsi/win32/wsi_window_win32.cpp @@ -30,7 +30,7 @@ namespace dxvk::wsi { if (!::GetMonitorInfoW(hMonitor, reinterpret_cast(&monInfo))) { Logger::err("Failed to query monitor info"); - return E_FAIL; + return false; } Logger::info(str::format("Setting display mode: ", From 2b16134b641cb951349e4f951850dcff682702b0 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Wed, 7 Sep 2022 18:28:37 +0200 Subject: [PATCH 0778/1348] [util] Enable d3d9.memoryTrackTest for The Ship --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index a428654f7..d2a41db97 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -602,6 +602,10 @@ namespace dxvk { { "d3d9.memoryTrackTest", "True" }, { "d3d9.maxAvailableMemory", "2048" }, }} }, + /* The Ship (2004) */ + { R"(\\ship\.exe$)", {{ + { "d3d9.memoryTrackTest", "True" }, + }} }, }}; From 912b06f37c3a15fc0fca5d59a8089c06dbdb9eae Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 8 Sep 2022 12:08:32 +0200 Subject: [PATCH 0779/1348] [meta] Bump MinGW version requirement to 10.0 in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bddaff165..1b26173d9 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ git clone --recursive https://github.com/doitsujin/dxvk.git ### Requirements: - [wine 3.10](https://www.winehq.org/) or newer - [Meson](https://mesonbuild.com/) build system (at least version 0.49) -- [Mingw-w64](https://www.mingw-w64.org) compiler and headers (at least version 8.0) +- [Mingw-w64](https://www.mingw-w64.org) compiler and headers (at least version 10.0) - [glslang](https://github.com/KhronosGroup/glslang) compiler ### Building DLLs From 72de8a1dc1acb2fe8f6926f48bd698a47f6e3e02 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 8 Sep 2022 19:26:33 +0200 Subject: [PATCH 0780/1348] [dxvk] Destroy command list fences Fixes a validation error. --- src/dxvk/dxvk_cmdlist.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index 86c3acbdf..a59b7707d 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -197,6 +197,7 @@ namespace dxvk { this->reset(); m_vkd->vkDestroySemaphore(m_vkd->device(), m_sdmaSemaphore, nullptr); + m_vkd->vkDestroyFence(m_vkd->device(), m_fence, nullptr); } From 044e2e9dff1e561fbbf48acb0682b4950b4c98d7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 8 Sep 2022 18:36:21 +0200 Subject: [PATCH 0781/1348] [dxvk] Defer host barriers until the end of the current command buffer --- src/dxvk/dxvk_barrier.cpp | 115 +++++++++++++++++++++++++++++++------- src/dxvk/dxvk_barrier.h | 6 ++ src/dxvk/dxvk_context.cpp | 6 +- 3 files changed, 103 insertions(+), 24 deletions(-) diff --git a/src/dxvk/dxvk_barrier.cpp b/src/dxvk/dxvk_barrier.cpp index 546e871ee..3d1755c85 100644 --- a/src/dxvk/dxvk_barrier.cpp +++ b/src/dxvk/dxvk_barrier.cpp @@ -12,7 +12,6 @@ namespace dxvk { | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_TRANSFER_READ_BIT - | VK_ACCESS_HOST_READ_BIT | VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT; @@ -21,11 +20,36 @@ namespace dxvk { | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT - | VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_MEMORY_WRITE_BIT | VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT | VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT; - + + constexpr static VkAccessFlags AccessDeviceMask + = AccessWriteMask | AccessReadMask; + + constexpr static VkAccessFlags AccessHostMask + = VK_ACCESS_HOST_READ_BIT + | VK_ACCESS_HOST_WRITE_BIT; + + constexpr static VkPipelineStageFlags StageDeviceMask + = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT + | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT + | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT + | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT + | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT + | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT + | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT + | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT + | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT + | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT + | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT + | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT + | VK_PIPELINE_STAGE_TRANSFER_BIT + | VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT + | VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT + | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT + | VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT; + DxvkBarrierSet:: DxvkBarrierSet(DxvkCmdBuffer cmdBuffer) : m_cmdBuffer(cmdBuffer) { @@ -45,12 +69,18 @@ namespace dxvk { DxvkAccessFlags access = this->getAccessTypes(srcAccess); m_allBarrierSrcStages |= srcStages; - m_memBarrier.srcStageMask |= srcStages; + m_memBarrier.srcStageMask |= srcStages & StageDeviceMask; m_memBarrier.srcAccessMask |= srcAccess & AccessWriteMask; - m_memBarrier.dstStageMask |= dstStages; + m_memBarrier.dstStageMask |= dstStages & StageDeviceMask; - if (access.test(DxvkAccess::Write)) - m_memBarrier.dstAccessMask |= dstAccess; + if (access.test(DxvkAccess::Write)) { + m_memBarrier.dstAccessMask |= dstAccess & AccessDeviceMask; + + if (dstAccess & AccessHostMask) { + m_hostBarrierSrcStages |= srcStages & StageDeviceMask; + m_hostBarrierDstAccess |= dstAccess & AccessHostMask; + } + } } @@ -63,12 +93,18 @@ namespace dxvk { DxvkAccessFlags access = this->getAccessTypes(srcAccess); m_allBarrierSrcStages |= srcStages; - m_memBarrier.srcStageMask |= srcStages; + m_memBarrier.srcStageMask |= srcStages & StageDeviceMask; m_memBarrier.srcAccessMask |= srcAccess & AccessWriteMask; - m_memBarrier.dstStageMask |= dstStages; + m_memBarrier.dstStageMask |= dstStages & StageDeviceMask; - if (access.test(DxvkAccess::Write)) - m_memBarrier.dstAccessMask |= dstAccess; + if (access.test(DxvkAccess::Write)) { + m_memBarrier.dstAccessMask |= dstAccess & AccessDeviceMask; + + if (dstAccess & AccessHostMask) { + m_hostBarrierSrcStages |= srcStages & StageDeviceMask; + m_hostBarrierDstAccess |= dstAccess & AccessHostMask; + } + } m_bufSlices.insert(bufSlice.handle, DxvkBarrierBufferSlice(bufSlice.offset, bufSlice.length, access)); @@ -86,21 +122,27 @@ namespace dxvk { VkAccessFlags dstAccess) { DxvkAccessFlags access = this->getAccessTypes(srcAccess); - m_allBarrierSrcStages |= srcStages; + m_allBarrierSrcStages |= srcStages & StageDeviceMask; if (srcLayout == dstLayout) { - m_memBarrier.srcStageMask |= srcStages; + m_memBarrier.srcStageMask |= srcStages & StageDeviceMask; m_memBarrier.srcAccessMask |= srcAccess & AccessWriteMask; - m_memBarrier.dstStageMask |= dstStages; + m_memBarrier.dstStageMask |= dstStages & StageDeviceMask; - if (access.test(DxvkAccess::Write)) + if (access.test(DxvkAccess::Write)) { m_memBarrier.dstAccessMask |= dstAccess; + + if (dstAccess & AccessHostMask) { + m_hostBarrierSrcStages |= srcStages & StageDeviceMask; + m_hostBarrierDstAccess |= dstAccess & AccessHostMask; + } + } } else { VkImageMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; - barrier.srcStageMask = srcStages; + barrier.srcStageMask = srcStages & StageDeviceMask; barrier.srcAccessMask = srcAccess & AccessWriteMask; - barrier.dstStageMask = dstStages; - barrier.dstAccessMask = dstAccess; + barrier.dstStageMask = dstStages & StageDeviceMask; + barrier.dstAccessMask = dstAccess & AccessDeviceMask; barrier.oldLayout = srcLayout; barrier.newLayout = dstLayout; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; @@ -110,6 +152,11 @@ namespace dxvk { barrier.subresourceRange.aspectMask = image->formatInfo()->aspectMask; m_imgBarriers.push_back(barrier); + if (dstAccess & AccessHostMask) { + m_hostBarrierSrcStages |= srcStages; + m_hostBarrierDstAccess |= dstAccess & AccessHostMask; + } + access.set(DxvkAccess::Write); } @@ -132,7 +179,7 @@ namespace dxvk { m_allBarrierSrcStages |= srcStages; VkBufferMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 }; - barrier.srcStageMask = srcStages; + barrier.srcStageMask = srcStages & StageDeviceMask; barrier.srcAccessMask = srcAccess & AccessWriteMask; barrier.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; barrier.dstAccessMask = 0; @@ -149,6 +196,11 @@ namespace dxvk { barrier.dstAccessMask = dstAccess; acquire.m_bufBarriers.push_back(barrier); + if (dstAccess & AccessHostMask) { + acquire.m_hostBarrierSrcStages |= srcStages & StageDeviceMask; + acquire.m_hostBarrierDstAccess |= dstAccess & AccessHostMask; + } + DxvkAccessFlags access(DxvkAccess::Read, DxvkAccess::Write); release.m_bufSlices.insert(bufSlice.handle, DxvkBarrierBufferSlice(bufSlice.offset, bufSlice.length, access)); @@ -174,7 +226,7 @@ namespace dxvk { m_allBarrierSrcStages |= srcStages; VkImageMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; - barrier.srcStageMask = srcStages; + barrier.srcStageMask = srcStages & StageDeviceMask; barrier.srcAccessMask = srcAccess & AccessWriteMask; barrier.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; barrier.dstAccessMask = 0; @@ -196,6 +248,11 @@ namespace dxvk { barrier.dstAccessMask = dstAccess; acquire.m_imgBarriers.push_back(barrier); + if (dstAccess & AccessHostMask) { + acquire.m_hostBarrierSrcStages |= srcStages & StageDeviceMask; + acquire.m_hostBarrierDstAccess |= dstAccess & AccessHostMask; + } + DxvkAccessFlags access(DxvkAccess::Read, DxvkAccess::Write); release.m_imgSlices.insert(image->handle(), DxvkBarrierImageSlice(subresources, access)); @@ -236,6 +293,22 @@ namespace dxvk { } + void DxvkBarrierSet::finalize(const Rc& commandList) { + // Emit host barrier if necessary + if (m_hostBarrierSrcStages) { + m_memBarrier.srcStageMask |= m_hostBarrierSrcStages; + m_memBarrier.srcAccessMask |= VK_ACCESS_MEMORY_WRITE_BIT; + m_memBarrier.dstStageMask |= VK_PIPELINE_STAGE_HOST_BIT; + m_memBarrier.dstAccessMask |= m_hostBarrierDstAccess; + + m_hostBarrierSrcStages = 0; + m_hostBarrierDstAccess = 0; + } + + this->recordCommands(commandList); + } + + void DxvkBarrierSet::recordCommands(const Rc& commandList) { VkDependencyInfo depInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; @@ -270,7 +343,7 @@ namespace dxvk { m_memBarrier.srcAccessMask = 0; m_memBarrier.dstStageMask = 0; m_memBarrier.dstAccessMask = 0; - + m_bufBarriers.resize(0); m_imgBarriers.resize(0); diff --git a/src/dxvk/dxvk_barrier.h b/src/dxvk/dxvk_barrier.h index 9b83ee390..4e9484386 100644 --- a/src/dxvk/dxvk_barrier.h +++ b/src/dxvk/dxvk_barrier.h @@ -576,6 +576,9 @@ namespace dxvk { return m_allBarrierSrcStages; } + void finalize( + const Rc& commandList); + void recordCommands( const Rc& commandList); @@ -603,6 +606,9 @@ namespace dxvk { DxvkCmdBuffer m_cmdBuffer; + VkPipelineStageFlags2 m_hostBarrierSrcStages = 0; + VkAccessFlags2 m_hostBarrierDstAccess = 0; + VkPipelineStageFlags2 m_allBarrierSrcStages = 0; VkMemoryBarrier2 m_memBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 }; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b79e47717..a99659f21 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -6226,9 +6226,9 @@ namespace dxvk { this->spillRenderPass(true); this->flushSharedImages(); - m_sdmaBarriers.recordCommands(m_cmd); - m_initBarriers.recordCommands(m_cmd); - m_execBarriers.recordCommands(m_cmd); + m_sdmaBarriers.finalize(m_cmd); + m_initBarriers.finalize(m_cmd); + m_execBarriers.finalize(m_cmd); } From 4b8387c9b12048ffb52f86b54f07c2ae3e3c07a7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 8 Sep 2022 19:12:07 +0200 Subject: [PATCH 0782/1348] [d3d9] Set host stage and access bits for image staging buffers This is already being done for buffers. --- src/d3d9/d3d9_common_texture.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 65910e074..6f6a164f7 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -190,9 +190,12 @@ namespace dxvk { info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT; + info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT + | VK_PIPELINE_STAGE_HOST_BIT; info.access = VK_ACCESS_TRANSFER_READ_BIT - | VK_ACCESS_TRANSFER_WRITE_BIT; + | VK_ACCESS_TRANSFER_WRITE_BIT + | VK_ACCESS_HOST_WRITE_BIT + | VK_ACCESS_HOST_READ_BIT; if (m_mapping.ConversionFormatInfo.FormatType != D3D9ConversionFormat_None) { info.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; From 5babb29922e94019986aa44b51296d1d7816c1a9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 8 Sep 2022 19:01:27 +0200 Subject: [PATCH 0783/1348] [d3d11] Set host stage and access bits for staging resources We don't need this for resources that we'll never read back from. --- src/d3d11/d3d11_buffer.cpp | 10 ++++++++++ src/d3d11/d3d11_texture.cpp | 20 +++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index d860d0c07..8296f6d6b 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -73,6 +73,16 @@ namespace dxvk { | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT; } + // Set host read bit as necessary. We may internally read staging + // buffer contents even if the buffer is not marked for reading. + if (pDesc->CPUAccessFlags && pDesc->Usage != D3D11_USAGE_DYNAMIC) { + info.stages |= VK_PIPELINE_STAGE_HOST_BIT; + info.access |= VK_ACCESS_HOST_READ_BIT; + + if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_WRITE) + info.access |= VK_ACCESS_HOST_WRITE_BIT; + } + if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) { // Create the buffer and set the entire buffer slice as mapped, // so that we only have to update it when invalidating the buffer diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 5289202a6..ba6ad0cc1 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -168,6 +168,14 @@ namespace dxvk { if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) { imageInfo.tiling = VK_IMAGE_TILING_LINEAR; imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + + if (pDesc->Usage != D3D11_USAGE_DYNAMIC) { + imageInfo.stages |= VK_PIPELINE_STAGE_HOST_BIT; + imageInfo.access |= VK_ACCESS_HOST_READ_BIT; + + if (pDesc->CPUAccessFlags & D3D11_CPU_ACCESS_WRITE) + imageInfo.access |= VK_ACCESS_HOST_WRITE_BIT; + } } // If necessary, create the mapped linear buffer @@ -684,7 +692,17 @@ namespace dxvk { | VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; - + + // We may read mapped buffers even if it is + // marked as CPU write-only on the D3D11 side. + if (m_desc.Usage != D3D11_USAGE_DYNAMIC) { + info.stages |= VK_PIPELINE_STAGE_HOST_BIT; + info.access |= VK_ACCESS_HOST_READ_BIT; + + if (m_desc.CPUAccessFlags & D3D11_CPU_ACCESS_WRITE) + info.access |= VK_ACCESS_HOST_WRITE_BIT; + } + VkMemoryPropertyFlags memType = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; From 1bc6f9660afb22e7ccabcfb78f309cf1e554cd00 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Thu, 1 Sep 2022 17:30:12 +0200 Subject: [PATCH 0784/1348] [d3d9] Force D3DTADDRESS_CLAMP for cubes. --- src/d3d9/d3d9_device.cpp | 13 +++++++++++++ src/d3d9/d3d9_device.h | 1 + 2 files changed, 14 insertions(+) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index a661cc005..83c00f399 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3786,7 +3786,13 @@ namespace dxvk { m_depthTextures &= ~(1u << StateSampler); if (newDepth) m_depthTextures |= 1u << StateSampler; + m_dirtySamplerStates |= 1u << StateSampler; + } + const bool oldCube = m_cubeTextures & (1u << StateSampler); + const bool newCube = newTexture->GetType() == D3DRTYPE_CUBETEXTURE; + if (oldCube != newCube) { + m_cubeTextures ^= 1u << StateSampler; m_dirtySamplerStates |= 1u << StateSampler; } @@ -5941,6 +5947,12 @@ namespace dxvk { key.BorderColor = D3DCOLOR(state[D3DSAMP_BORDERCOLOR]); key.Depth = m_depthTextures & (1u << Sampler); + if (m_cubeTextures & (1u << Sampler)) { + key.AddressU = D3DTADDRESS_CLAMP; + key.AddressV = D3DTADDRESS_CLAMP; + key.AddressW = D3DTADDRESS_CLAMP; + } + if (m_d3d9Options.samplerAnisotropy != -1) { if (key.MagFilter == D3DTEXF_LINEAR) key.MagFilter = D3DTEXF_ANISOTROPIC; @@ -7196,6 +7208,7 @@ namespace dxvk { m_dirtyTextures = 0; m_depthTextures = 0; + m_cubeTextures = 0; auto& ss = m_state.samplerStates; for (uint32_t i = 0; i < ss.size(); i++) { diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 883d3de03..1e3750e69 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1235,6 +1235,7 @@ namespace dxvk { uint32_t m_instancedData = 0; uint32_t m_depthTextures = 0; + uint32_t m_cubeTextures = 0; uint32_t m_textureTypes = 0; uint32_t m_projectionBitfield = 0; From bd5d9d90c9d74023166ef476eb29bad447c5f1de Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Tue, 6 Sep 2022 00:23:24 +0200 Subject: [PATCH 0785/1348] [d3d9] Use xor to swap bit in depth mask. --- src/d3d9/d3d9_device.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 83c00f399..c8dee1152 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3783,9 +3783,7 @@ namespace dxvk { const bool newDepth = newTexture->IsShadow(); if (oldDepth != newDepth) { - m_depthTextures &= ~(1u << StateSampler); - if (newDepth) - m_depthTextures |= 1u << StateSampler; + m_depthTextures ^= 1u << StateSampler; m_dirtySamplerStates |= 1u << StateSampler; } From 2ec25f588f597a39cfab36928bc5824b675466b0 Mon Sep 17 00:00:00 2001 From: xpander69 Date: Sat, 10 Sep 2022 13:47:15 +0300 Subject: [PATCH 0786/1348] Cap Warhammer Online to 100 FPS Animations break with 100+ FPS. Engine Limitation. WAR-64.exe is affected by this. WAR.exe is capped to 100 by default. --- src/util/config/config.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index d2a41db97..51dcf5a98 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -439,6 +439,7 @@ namespace dxvk { /* Warhammer: Online */ { R"(\\WAR(-64)?\.exe$)", {{ { "d3d9.customVendorId", "1002" }, + { "d3d9.maxFrameRate", "100" }, }} }, /* Dragon Nest */ { R"(\\DragonNest_x64\.exe$)", {{ From 0f9a042952bfd88f1d960584a357ed4b6cdf0cb3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 10 Sep 2022 14:25:45 +0200 Subject: [PATCH 0787/1348] [d3d11] Report Tiled Resources Tier 3 again Partially reverts df5756c9a52a30f58c7364499a3523385004ec82. Turns out that WARP does this, so we might as well expose it too. --- src/d3d11/d3d11_device.cpp | 3 ++- src/d3d11/d3d11_features.cpp | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index d1c3c795c..eb6d9e679 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -299,7 +299,8 @@ namespace dxvk { if (FAILED(hr)) return hr; - if (desc.MiscFlags & D3D11_RESOURCE_MISC_TILED) + if ((desc.MiscFlags & D3D11_RESOURCE_MISC_TILED) + && (m_deviceFeatures.GetTiledResourcesTier() < D3D11_TILED_RESOURCES_TIER_3)) return E_INVALIDARG; if (!ppTexture3D) diff --git a/src/d3d11/d3d11_features.cpp b/src/d3d11/d3d11_features.cpp index 099435340..a3fe2cce0 100644 --- a/src/d3d11/d3d11_features.cpp +++ b/src/d3d11/d3d11_features.cpp @@ -231,7 +231,11 @@ namespace dxvk { || m_properties.core.properties.sparseProperties.residencyAlignedMipSize) return D3D11_TILED_RESOURCES_TIER_1; - return D3D11_TILED_RESOURCES_TIER_2; + if (!m_features.core.features.sparseResidencyImage3D + || !m_properties.core.properties.sparseProperties.residencyStandard3DBlockShape) + return D3D11_TILED_RESOURCES_TIER_2; + + return D3D11_TILED_RESOURCES_TIER_3; } From d564be68d6fc43126e73931a32e64362021ad7ab Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 9 Sep 2022 01:00:00 +0200 Subject: [PATCH 0788/1348] [spirv] Handle availability and visibility image operands --- src/spirv/spirv_module.cpp | 28 ++++++++++++++++++---------- src/spirv/spirv_module.h | 2 ++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 75fef45e8..10744ccef 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -3756,22 +3756,24 @@ namespace dxvk { uint32_t SpirvModule::getImageOperandWordCount(const SpirvImageOperands& op) const { // Each flag may add one or more operands const uint32_t result - = ((op.flags & spv::ImageOperandsBiasMask) ? 1 : 0) - + ((op.flags & spv::ImageOperandsLodMask) ? 1 : 0) - + ((op.flags & spv::ImageOperandsConstOffsetMask) ? 1 : 0) - + ((op.flags & spv::ImageOperandsGradMask) ? 2 : 0) - + ((op.flags & spv::ImageOperandsOffsetMask) ? 1 : 0) - + ((op.flags & spv::ImageOperandsConstOffsetsMask)? 1 : 0) - + ((op.flags & spv::ImageOperandsSampleMask) ? 1 : 0) - + ((op.flags & spv::ImageOperandsMinLodMask) ? 1 : 0); + = ((op.flags & spv::ImageOperandsBiasMask) ? 1 : 0) + + ((op.flags & spv::ImageOperandsLodMask) ? 1 : 0) + + ((op.flags & spv::ImageOperandsConstOffsetMask) ? 1 : 0) + + ((op.flags & spv::ImageOperandsGradMask) ? 2 : 0) + + ((op.flags & spv::ImageOperandsOffsetMask) ? 1 : 0) + + ((op.flags & spv::ImageOperandsConstOffsetsMask) ? 1 : 0) + + ((op.flags & spv::ImageOperandsSampleMask) ? 1 : 0) + + ((op.flags & spv::ImageOperandsMinLodMask) ? 1 : 0) + + ((op.flags & spv::ImageOperandsMakeTexelAvailableMask) ? 1 : 0) + + ((op.flags & spv::ImageOperandsMakeTexelVisibleMask) ? 1 : 0); // Add a DWORD for the operand mask if it is non-zero - return result != 0 ? result + 1 : 0; + return op.flags ? result + 1 : 0; } void SpirvModule::putImageOperands(const SpirvImageOperands& op) { - if (op.flags != 0) { + if (op.flags) { m_code.putWord(op.flags); if (op.flags & spv::ImageOperandsBiasMask) @@ -3799,6 +3801,12 @@ namespace dxvk { if (op.flags & spv::ImageOperandsMinLodMask) m_code.putWord(op.sMinLod); + + if (op.flags & spv::ImageOperandsMakeTexelAvailableMask) + m_code.putWord(op.makeAvailable); + + if (op.flags & spv::ImageOperandsMakeTexelVisibleMask) + m_code.putWord(op.makeVisible); } } diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index 8e52806e8..20a564b7d 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -27,6 +27,8 @@ namespace dxvk { uint32_t gConstOffsets = 0; uint32_t sSampleId = 0; uint32_t sMinLod = 0; + uint32_t makeAvailable = 0; + uint32_t makeVisible = 0; bool sparse = false; }; From 0b891a93b2cb4d504baf28ed7cdf9770a3d2229e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 9 Sep 2022 01:14:03 +0200 Subject: [PATCH 0789/1348] [spirv] Add support for memory operands on load/store operations --- src/spirv/spirv_module.cpp | 56 +++++++++++++++++++++++++++++++++++--- src/spirv/spirv_module.h | 27 ++++++++++++++++-- 2 files changed, 77 insertions(+), 6 deletions(-) diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 10744ccef..281c2af14 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -2994,12 +2994,22 @@ namespace dxvk { uint32_t SpirvModule::opLoad( uint32_t typeId, uint32_t pointerId) { + return opLoad(typeId, pointerId, SpirvMemoryOperands()); + } + + + uint32_t SpirvModule::opLoad( + uint32_t typeId, + uint32_t pointerId, + const SpirvMemoryOperands& operands) { uint32_t resultId = this->allocateId(); - m_code.putIns (spv::OpLoad, 4); + m_code.putIns (spv::OpLoad, 4 + getMemoryOperandWordCount(operands)); m_code.putWord(typeId); m_code.putWord(resultId); m_code.putWord(pointerId); + + putMemoryOperands(operands); return resultId; } @@ -3007,12 +3017,22 @@ namespace dxvk { void SpirvModule::opStore( uint32_t pointerId, uint32_t valueId) { - m_code.putIns (spv::OpStore, 3); + opStore(pointerId, valueId, SpirvMemoryOperands()); + } + + + void SpirvModule::opStore( + uint32_t pointerId, + uint32_t valueId, + const SpirvMemoryOperands& operands) { + m_code.putIns (spv::OpStore, 3 + getMemoryOperandWordCount(operands)); m_code.putWord(pointerId); m_code.putWord(valueId); + + putMemoryOperands(operands); } - - + + uint32_t SpirvModule::opInterpolateAtCentroid( uint32_t resultType, uint32_t interpolant) { @@ -3753,6 +3773,34 @@ namespace dxvk { } + uint32_t SpirvModule::getMemoryOperandWordCount( + const SpirvMemoryOperands& op) const { + const uint32_t result + = ((op.flags & spv::MemoryAccessAlignedMask) ? 1 : 0) + + ((op.flags & spv::MemoryAccessMakePointerAvailableMask) ? 1 : 0) + + ((op.flags & spv::MemoryAccessMakePointerVisibleMask) ? 1 : 0); + + return op.flags ? result + 1 : 0; + } + + + void SpirvModule::putMemoryOperands( + const SpirvMemoryOperands& op) { + if (op.flags) { + m_code.putWord(op.flags); + + if (op.flags & spv::MemoryAccessAlignedMask) + m_code.putWord(op.alignment); + + if (op.flags & spv::MemoryAccessMakePointerAvailableMask) + m_code.putWord(op.makeAvailable); + + if (op.flags & spv::MemoryAccessMakePointerVisibleMask) + m_code.putWord(op.makeVisible); + } + } + + uint32_t SpirvModule::getImageOperandWordCount(const SpirvImageOperands& op) const { // Each flag may add one or more operands const uint32_t result diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index 20a564b7d..ecf3cce50 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -15,6 +15,13 @@ namespace dxvk { uint32_t literal = 0; uint32_t labelId = 0; }; + + struct SpirvMemoryOperands { + uint32_t flags = 0; + uint32_t alignment = 0; + uint32_t makeAvailable = 0; + uint32_t makeVisible = 0; + }; struct SpirvImageOperands { uint32_t flags = 0; @@ -1032,11 +1039,21 @@ namespace dxvk { uint32_t opLoad( uint32_t typeId, uint32_t pointerId); - + + uint32_t opLoad( + uint32_t typeId, + uint32_t pointerId, + const SpirvMemoryOperands& operands); + void opStore( uint32_t pointerId, uint32_t valueId); - + + void opStore( + uint32_t pointerId, + uint32_t valueId, + const SpirvMemoryOperands& operands); + uint32_t opInterpolateAtCentroid( uint32_t resultType, uint32_t interpolant); @@ -1281,6 +1298,12 @@ namespace dxvk { void instImportGlsl450(); + uint32_t getMemoryOperandWordCount( + const SpirvMemoryOperands& op) const; + + void putMemoryOperands( + const SpirvMemoryOperands& op); + uint32_t getImageOperandWordCount( const SpirvImageOperands& op) const; From 68cfc843291e48efd9cf0600bf8161896cc2e5b3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 8 Sep 2022 23:33:21 +0200 Subject: [PATCH 0790/1348] [dxvk] Enable vulkanMemoryModel feature --- src/dxvk/dxvk_adapter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 0872211d0..9d3328ac0 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -356,6 +356,9 @@ namespace dxvk { enabledFeatures.core.features.variableMultisampleRate = m_deviceFeatures.core.features.variableMultisampleRate; + // Always enable memory model so client APIs can use it + enabledFeatures.vk12.vulkanMemoryModel = VK_TRUE; + // Optionally used by some client API extensions enabledFeatures.vk12.drawIndirectCount = m_deviceFeatures.vk12.drawIndirectCount; @@ -905,6 +908,7 @@ namespace dxvk { "\n bufferDeviceAddress : ", features.vk12.bufferDeviceAddress, "\n shaderOutputViewportIndex : ", features.vk12.shaderOutputViewportIndex, "\n shaderOutputLayer : ", features.vk12.shaderOutputLayer, + "\n vulkanMemoryModel : ", features.vk12.vulkanMemoryModel, "\nVulkan 1.3", "\n robustImageAccess : ", features.vk13.robustImageAccess, "\n pipelineCreationCacheControl : ", features.vk13.pipelineCreationCacheControl, From 81761012280cd029f3cb0e372e4c6fd45d8215e6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 8 Sep 2022 23:59:06 +0200 Subject: [PATCH 0791/1348] [dxbc] Enable Vulkan memory model --- src/dxbc/dxbc_compiler.cpp | 139 ++++++++++++++++++++++++++++--------- src/dxbc/dxbc_compiler.h | 5 ++ src/dxbc/dxbc_decoder.h | 1 + 3 files changed, 112 insertions(+), 33 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index f2a14e43c..926a42549 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -50,9 +50,12 @@ namespace dxvk { } // Set the memory model. This is the same for all shaders. + m_module.enableCapability( + spv::CapabilityVulkanMemoryModel); + m_module.setMemoryModel( spv::AddressingModelLogical, - spv::MemoryModelGLSL450); + spv::MemoryModelVulkan); // Make sure our interface registers are clear for (uint32_t i = 0; i < DxbcMaxInterfaceRegs; i++) { @@ -1013,9 +1016,6 @@ namespace dxvk { m_module.decorateDescriptorSet(varId, 0); m_module.decorateBinding(varId, bindingId); - if (ins.controls.uavFlags().test(DxbcUavFlag::GloballyCoherent)) - m_module.decorate(varId, spv::DecorationCoherent); - // Declare a specialization constant which will // store whether or not the resource is bound. if (isUav) { @@ -1028,6 +1028,7 @@ namespace dxvk { uav.sampledTypeId = sampledTypeId; uav.imageTypeId = imageTypeId; uav.structStride = 0; + uav.coherence = getUavCoherence(registerId, ins.controls.uavFlags()); uav.isRawSsbo = false; m_uavs.at(registerId) = uav; } else { @@ -1168,9 +1169,6 @@ namespace dxvk { m_module.decorateDescriptorSet(varId, 0); m_module.decorateBinding(varId, bindingId); - if (ins.controls.uavFlags().test(DxbcUavFlag::GloballyCoherent)) - m_module.decorate(varId, spv::DecorationCoherent); - if (isUav) { DxbcUav uav; uav.type = resType; @@ -1181,6 +1179,7 @@ namespace dxvk { uav.sampledTypeId = sampledTypeId; uav.imageTypeId = resTypeId; uav.structStride = resStride; + uav.coherence = getUavCoherence(registerId, ins.controls.uavFlags()); uav.isRawSsbo = useRawSsbo; m_uavs.at(registerId) = uav; } else { @@ -2323,7 +2322,7 @@ namespace dxvk { uint32_t semantics = 0; if (isUav) { - scope = spv::ScopeDevice; + scope = spv::ScopeQueueFamily; semantics = spv::MemorySemanticsAcquireReleaseMask; semantics |= isSsbo @@ -2334,7 +2333,7 @@ namespace dxvk { semantics = spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsAcquireReleaseMask; } - + const uint32_t scopeId = m_module.constu32(scope); const uint32_t semanticsId = m_module.constu32(semantics); @@ -2506,7 +2505,7 @@ namespace dxvk { 1, &zeroId); // Define memory scope and semantics based on the operands - uint32_t scope = spv::ScopeDevice; + uint32_t scope = spv::ScopeQueueFamily; uint32_t semantics = spv::MemorySemanticsUniformMemoryMask | spv::MemorySemanticsAcquireReleaseMask; @@ -2579,7 +2578,9 @@ namespace dxvk { if (flags.test(DxbcSyncFlag::ThreadGroupSharedMemory)) { memoryScope = spv::ScopeWorkgroup; memorySemantics |= spv::MemorySemanticsWorkgroupMemoryMask - | spv::MemorySemanticsAcquireReleaseMask; + | spv::MemorySemanticsAcquireReleaseMask + | spv::MemorySemanticsMakeAvailableMask + | spv::MemorySemanticsMakeVisibleMask; } if (flags.test(DxbcSyncFlag::UavMemoryGroup)) { @@ -2590,7 +2591,7 @@ namespace dxvk { } if (flags.test(DxbcSyncFlag::UavMemoryGlobal)) { - memoryScope = spv::ScopeDevice; + memoryScope = spv::ScopeQueueFamily; memorySemantics |= spv::MemorySemanticsImageMemoryMask | spv::MemorySemanticsUniformMemoryMask | spv::MemorySemanticsAcquireReleaseMask; @@ -3774,6 +3775,12 @@ namespace dxvk { SpirvImageOperands imageOperands; imageOperands.sparse = ins.dstCount == 2; + if (uavInfo.coherence) { + imageOperands.flags |= spv::ImageOperandsNonPrivateTexelMask + | spv::ImageOperandsMakeTexelVisibleMask; + imageOperands.makeVisible = m_module.constu32(uavInfo.coherence); + } + DxbcVectorType texelType; texelType.ctype = uavInfo.sampledType; texelType.ccount = 4; @@ -3813,7 +3820,16 @@ namespace dxvk { // (src0) The texture or buffer coordinates // (src1) The value to store const DxbcBufferInfo uavInfo = getBufferInfo(ins.dst[0]); - + + // Set image operands for coherent access if necessary + SpirvImageOperands imageOperands; + + if (uavInfo.coherence) { + imageOperands.flags |= spv::ImageOperandsNonPrivateTexelMask + | spv::ImageOperandsMakeTexelAvailableMask; + imageOperands.makeAvailable = m_module.constu32(uavInfo.coherence); + } + // Load texture coordinates DxbcRegisterValue texCoord = emitLoadTexCoord(ins.src[0], uavInfo.image); @@ -3826,7 +3842,7 @@ namespace dxvk { // Write the given value to the image m_module.opImageWrite( m_module.opLoad(uavInfo.typeId, uavInfo.varId), - texCoord.id, texValue.id, SpirvImageOperands()); + texCoord.id, texValue.id, imageOperands); } @@ -5170,9 +5186,23 @@ namespace dxvk { // The sparse feedback ID will be non-zero for sparse // instructions on input. We need to reset it to 0. + SpirvMemoryOperands memoryOperands; SpirvImageOperands imageOperands; imageOperands.sparse = sparseFeedbackId != 0; + if (isTgsm) + memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask; + + if (bufferInfo.coherence) { + memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask + | spv::MemoryAccessMakePointerVisibleMask; + memoryOperands.makeVisible = m_module.constu32(bufferInfo.coherence); + + imageOperands.flags = spv::ImageOperandsNonPrivateTexelMask + | spv::ImageOperandsMakeTexelVisibleMask; + imageOperands.makeVisible = m_module.constu32(bufferInfo.coherence); + } + sparseFeedbackId = 0; for (uint32_t i = 0; i < 4; i++) { @@ -5192,12 +5222,14 @@ namespace dxvk { if (isTgsm) { ccomps[sindex] = m_module.opLoad(scalarTypeId, m_module.opAccessChain(bufferInfo.typeId, - bufferInfo.varId, 1, &elementIndexAdjusted)); + bufferInfo.varId, 1, &elementIndexAdjusted), + memoryOperands); } else if (isSsbo) { uint32_t indices[2] = { m_module.constu32(0), elementIndexAdjusted }; ccomps[sindex] = m_module.opLoad(scalarTypeId, m_module.opAccessChain(bufferInfo.typeId, - bufferInfo.varId, 2, indices)); + bufferInfo.varId, 2, indices), + memoryOperands); } else { uint32_t resultTypeId = vectorTypeId; uint32_t resultId = 0; @@ -5271,7 +5303,24 @@ namespace dxvk { uint32_t vectorTypeId = getVectorTypeId({ DxbcScalarType::Uint32, 4 }); uint32_t srcComponentIndex = 0; - + + // Set memory operands according to resource properties + SpirvMemoryOperands memoryOperands; + SpirvImageOperands imageOperands; + + if (isTgsm) + memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask; + + if (bufferInfo.coherence) { + memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask + | spv::MemoryAccessMakePointerAvailableMask; + memoryOperands.makeAvailable = m_module.constu32(bufferInfo.coherence); + + imageOperands.flags = spv::ImageOperandsNonPrivateTexelMask + | spv::ImageOperandsMakeTexelAvailableMask; + imageOperands.makeAvailable = m_module.constu32(bufferInfo.coherence); + } + for (uint32_t i = 0; i < 4; i++) { if (operand.mask[i]) { uint32_t srcComponentId = value.type.ccount > 1 @@ -5289,13 +5338,13 @@ namespace dxvk { m_module.opStore( m_module.opAccessChain(bufferInfo.typeId, bufferInfo.varId, 1, &elementIndexAdjusted), - srcComponentId); + srcComponentId, memoryOperands); } else if (isSsbo) { uint32_t indices[2] = { m_module.constu32(0), elementIndexAdjusted }; m_module.opStore( m_module.opAccessChain(bufferInfo.typeId, bufferInfo.varId, 2, indices), - srcComponentId); + srcComponentId, memoryOperands); } else if (operand.type == DxbcOperandType::UnorderedAccessView) { const std::array srcVectorIds = { srcComponentId, srcComponentId, @@ -5306,7 +5355,7 @@ namespace dxvk { bufferId, elementIndexAdjusted, m_module.opCompositeConstruct(vectorTypeId, 4, srcVectorIds.data()), - SpirvImageOperands()); + imageOperands); } else { throw DxvkError("DxbcCompiler: Invalid operand type for strucured/raw store"); } @@ -5315,15 +5364,6 @@ namespace dxvk { srcComponentIndex += 1; } } - - // Make sure that shared memory stores are made visible in - // case the game does not synchronize invocations properly - if (isTgsm && m_moduleInfo.options.forceTgsmBarriers) { - m_module.opMemoryBarrier( - m_module.constu32(spv::ScopeWorkgroup), - m_module.constu32(spv::MemorySemanticsWorkgroupMemoryMask - | spv::MemorySemanticsAcquireReleaseMask)); - } } @@ -5949,6 +5989,11 @@ namespace dxvk { void DxbcCompiler::emitInitWorkgroupMemory() { bool hasTgsm = false; + SpirvMemoryOperands memoryOperands; + memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask + | spv::MemoryAccessMakePointerAvailableMask; + memoryOperands.makeAvailable = m_module.constu32(spv::ScopeWorkgroup); + for (uint32_t i = 0; i < m_gRegs.size(); i++) { if (!m_gRegs[i].varId) continue; @@ -5989,7 +6034,7 @@ namespace dxvk { uint32_t ptrId = m_module.opAccessChain( ptrTypeId, m_gRegs[i].varId, 1, &ofsId); - m_module.opStore(ptrId, zeroId); + m_module.opStore(ptrId, zeroId, memoryOperands); } if (numElementsRemaining) { @@ -6013,7 +6058,7 @@ namespace dxvk { uint32_t ptrId = m_module.opAccessChain( ptrTypeId, m_gRegs[i].varId, 1, &ofsId); - m_module.opStore(ptrId, zeroId); + m_module.opStore(ptrId, zeroId, memoryOperands); m_module.opBranch(cond.labelEnd); m_module.opLabel (cond.labelEnd); @@ -7204,8 +7249,12 @@ namespace dxvk { void DxbcCompiler::emitHsPhaseBarrier() { uint32_t exeScopeId = m_module.constu32(spv::ScopeWorkgroup); - uint32_t memScopeId = m_module.constu32(spv::ScopeInvocation); - uint32_t semanticId = m_module.constu32(spv::MemorySemanticsMaskNone); + uint32_t memScopeId = m_module.constu32(spv::ScopeWorkgroup); + uint32_t semanticId = m_module.constu32( + spv::MemorySemanticsOutputMemoryMask | + spv::MemorySemanticsAcquireReleaseMask | + spv::MemorySemanticsMakeAvailableMask | + spv::MemorySemanticsMakeVisibleMask); m_module.opControlBarrier(exeScopeId, memScopeId, semanticId); } @@ -7518,6 +7567,7 @@ namespace dxvk { result.typeId = texture.imageTypeId; result.varId = texture.varId; result.stride = texture.structStride; + result.coherence = 0; result.isSsbo = texture.isRawSsbo; return result; } break; @@ -7532,6 +7582,7 @@ namespace dxvk { result.typeId = uav.imageTypeId; result.varId = uav.varId; result.stride = uav.structStride; + result.coherence = uav.coherence; result.isSsbo = uav.isRawSsbo; return result; } break; @@ -7546,6 +7597,7 @@ namespace dxvk { spv::StorageClassWorkgroup); result.varId = m_gRegs.at(registerId).varId; result.stride = m_gRegs.at(registerId).elementStride; + result.coherence = 0; result.isSsbo = false; return result; } break; @@ -7734,6 +7786,27 @@ namespace dxvk { } + uint32_t DxbcCompiler::getUavCoherence(uint32_t registerId, DxbcUavFlags flags) const { + // Ignore any resources that can't both be read and written in + // the current shader, explicit availability/visibility operands + // are not useful in that case. + if (m_analysis->uavInfos[registerId].accessFlags != (VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT)) + return 0; + + // If the globally coherent flag is set, the resource must be + // coherent across multiple workgroups of the same dispatch + if (flags.test(DxbcUavFlag::GloballyCoherent)) + return spv::ScopeQueueFamily; + + // In compute shaders, UAVs are implicitly workgroup coherent. + // In all other stage, there are no coherence guarantees. + if (m_programInfo.type() == DxbcProgramType::ComputeShader) + return spv::ScopeWorkgroup; + + return 0; + } + + uint32_t DxbcCompiler::getScalarTypeId(DxbcScalarType type) { if (type == DxbcScalarType::Float64) m_module.enableCapability(spv::CapabilityFloat64); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index fe45c6ec8..d59457ad1 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -347,6 +347,7 @@ namespace dxvk { uint32_t typeId; uint32_t varId; uint32_t stride; + uint32_t coherence; bool isSsbo; }; @@ -1222,6 +1223,10 @@ namespace dxvk { bool caseBlockIsFallthrough() const; + uint32_t getUavCoherence( + uint32_t registerId, + DxbcUavFlags flags) const; + /////////////////////////// // Type definition methods uint32_t getScalarTypeId( diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index 3a605029f..5f64cf225 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -100,6 +100,7 @@ namespace dxvk { uint32_t sampledTypeId = 0; uint32_t imageTypeId = 0; uint32_t structStride = 0; + uint32_t coherence = 0; bool isRawSsbo = false; }; From ccfb986e725faf154ab2d4db374b71c846dd3111 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 9 Sep 2022 13:59:58 +0200 Subject: [PATCH 0792/1348] [dxbc] Rework TGSM workaround --- src/d3d11/d3d11_options.cpp | 2 +- src/d3d11/d3d11_options.h | 4 ++-- src/dxbc/dxbc_compiler.cpp | 36 ++++++++++++++++++++++++------------ src/dxbc/dxbc_options.cpp | 2 +- src/dxbc/dxbc_options.h | 2 +- src/util/config/config.cpp | 2 +- 6 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index 83c321de0..6a3f371cc 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -16,7 +16,7 @@ namespace dxvk { this->dcSingleUseMode = config.getOption("d3d11.dcSingleUseMode", true); this->enableRtOutputNanFixup = config.getOption("d3d11.enableRtOutputNanFixup", false); this->zeroInitWorkgroupMemory = config.getOption("d3d11.zeroInitWorkgroupMemory", false); - this->forceTgsmBarriers = config.getOption("d3d11.forceTgsmBarriers", false); + this->forceVolatileTgsmAccess = config.getOption("d3d11.forceVolatileTgsmAccess", false); this->relaxedBarriers = config.getOption("d3d11.relaxedBarriers", false); this->ignoreGraphicsBarriers = config.getOption("d3d11.ignoreGraphicsBarriers", false); this->maxTessFactor = config.getOption("d3d11.maxTessFactor", 0); diff --git a/src/d3d11/d3d11_options.h b/src/d3d11/d3d11_options.h index 67bceaa54..594580200 100644 --- a/src/d3d11/d3d11_options.h +++ b/src/d3d11/d3d11_options.h @@ -30,12 +30,12 @@ namespace dxvk { /// TGSM in compute shaders before reading it. bool zeroInitWorkgroupMemory; - /// Force thread-group shared memory barriers + /// Force thread-group shared memory accesses to be volatile /// /// Workaround for compute shaders that read and /// write from the same shared memory location /// without explicit synchronization. - bool forceTgsmBarriers; + bool forceVolatileTgsmAccess; /// Use relaxed memory barriers /// diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 926a42549..b45dce512 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -5190,17 +5190,23 @@ namespace dxvk { SpirvImageOperands imageOperands; imageOperands.sparse = sparseFeedbackId != 0; - if (isTgsm) + uint32_t coherence = bufferInfo.coherence; + + if (isTgsm || coherence) memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask; - if (bufferInfo.coherence) { - memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask - | spv::MemoryAccessMakePointerVisibleMask; - memoryOperands.makeVisible = m_module.constu32(bufferInfo.coherence); + if (isTgsm && m_moduleInfo.options.forceVolatileTgsmAccess) { + memoryOperands.flags |= spv::MemoryAccessVolatileMask; + coherence = spv::ScopeWorkgroup; + } + + if (coherence) { + memoryOperands.flags |= spv::MemoryAccessMakePointerVisibleMask; + memoryOperands.makeVisible = m_module.constu32(coherence); imageOperands.flags = spv::ImageOperandsNonPrivateTexelMask | spv::ImageOperandsMakeTexelVisibleMask; - imageOperands.makeVisible = m_module.constu32(bufferInfo.coherence); + imageOperands.makeVisible = m_module.constu32(coherence); } sparseFeedbackId = 0; @@ -5308,17 +5314,23 @@ namespace dxvk { SpirvMemoryOperands memoryOperands; SpirvImageOperands imageOperands; - if (isTgsm) + uint32_t coherence = bufferInfo.coherence; + + if (isTgsm || coherence) memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask; - if (bufferInfo.coherence) { - memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask - | spv::MemoryAccessMakePointerAvailableMask; - memoryOperands.makeAvailable = m_module.constu32(bufferInfo.coherence); + if (isTgsm && m_moduleInfo.options.forceVolatileTgsmAccess) { + memoryOperands.flags |= spv::MemoryAccessVolatileMask; + coherence = spv::ScopeWorkgroup; + } + + if (coherence) { + memoryOperands.flags |= spv::MemoryAccessMakePointerAvailableMask; + memoryOperands.makeAvailable = m_module.constu32(coherence); imageOperands.flags = spv::ImageOperandsNonPrivateTexelMask | spv::ImageOperandsMakeTexelAvailableMask; - imageOperands.makeAvailable = m_module.constu32(bufferInfo.coherence); + imageOperands.makeAvailable = m_module.constu32(coherence); } for (uint32_t i = 0; i < 4; i++) { diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index ba373dde1..51c565bd4 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -37,7 +37,7 @@ namespace dxvk { invariantPosition = options.invariantPosition; enableRtOutputNanFixup = options.enableRtOutputNanFixup; zeroInitWorkgroupMemory = options.zeroInitWorkgroupMemory; - forceTgsmBarriers = options.forceTgsmBarriers; + forceVolatileTgsmAccess = options.forceVolatileTgsmAccess; disableMsaa = options.disableMsaa; // Figure out float control flags to match D3D11 rules diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index d472b3588..0949a6e10 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -41,7 +41,7 @@ namespace dxvk { bool invariantPosition = false; /// Insert memory barriers after TGSM stoes - bool forceTgsmBarriers = false; + bool forceVolatileTgsmAccess = false; /// Replace ld_ms with ld bool disableMsaa = false; diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 51dcf5a98..9460b6186 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -181,7 +181,7 @@ namespace dxvk { /* F1 games - do not synchronize TGSM access * * in a compute shader, causing artifacts */ { R"(\\F1_20(1[89]|[2-9][0-9])\.exe$)", {{ - { "d3d11.forceTgsmBarriers", "True" }, + { "d3d11.forceVolatileTgsmAccess", "True" }, }} }, /* Darksiders Warmastered - apparently reads * * from write-only mapped buffers */ From cbbc4a595e008e5d91c7df9724dc77647f5c5d3e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 10 Sep 2022 21:21:54 +0200 Subject: [PATCH 0793/1348] [meta] Update issue template --- .github/ISSUE_TEMPLATE/bug_report.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 236add1f7..19f71713f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,14 +7,9 @@ assignees: '' --- -Please describe your issue as accurately as possible. If you run into a problem with a binary release, make sure to test with latest `master` as well. +Please describe your issue as accurately as possible. -**Important:** When reporting an issue with a specific game or application, such as crashes or rendering issues, please include log files and, if possible, a D3D11/D3D9 Apitrace (see https://github.com/apitrace/apitrace) so that the issue can be reproduced. -In order to create a trace for **D3D11/D3D10**: Run `wine apitrace.exe trace -a dxgi YOURGAME.exe`. -In order to create a trace for **D3D9**: Follow https://github.com/doitsujin/dxvk/wiki/Making-a-Trace. -Preferably record the trace on Windows, or wined3d if possible. - -**Reports with no log files will be ignored.** +If you use Windows, please check the following page: https://github.com/doitsujin/dxvk/wiki/Windows ### Software information Name of the game, settings used etc. @@ -28,6 +23,8 @@ Name of the game, settings used etc. ### Apitrace file(s) - Put a link here +For instructions on how to use apitrace, see: https://github.com/doitsujin/dxvk/wiki/Using-Apitrace + ### Log files - d3d9.log: - d3d11.log: From ec6ad90f220e7c49b3dd718783fa7377df10c4f4 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 21:53:50 +0100 Subject: [PATCH 0794/1348] [dxvk] Fix value type in QueueItem This was being truncated from uint64_t -> uint32_t then stored in a uint64_t which seems unintentional... --- src/dxvk/dxvk_fence.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_fence.h b/src/dxvk/dxvk_fence.h index 0c6693693..99e0880e7 100644 --- a/src/dxvk/dxvk_fence.h +++ b/src/dxvk/dxvk_fence.h @@ -94,7 +94,7 @@ namespace dxvk { struct QueueItem { QueueItem() { } - QueueItem(uint32_t v, DxvkFenceEvent&& e) + QueueItem(uint64_t v, DxvkFenceEvent&& e) : value(v), event(std::move(e)) { } uint64_t value; From f42df87937305e68e2d3791bc4ea0b65e3148cbe Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 20:59:00 +0000 Subject: [PATCH 0795/1348] [dxvk] Remove useless const qualifier on getColorAttachmentIndex return type This does nothing. --- src/dxvk/dxvk_framebuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_framebuffer.h b/src/dxvk/dxvk_framebuffer.h index b7cb1d2b4..402b1e5fb 100644 --- a/src/dxvk/dxvk_framebuffer.h +++ b/src/dxvk/dxvk_framebuffer.h @@ -156,7 +156,7 @@ namespace dxvk { * \brief Queries color attachment index of a given attachment * \returns The index, or -1 if the given attachment is the depth attachment */ - const int32_t getColorAttachmentIndex(uint32_t id) const { + int32_t getColorAttachmentIndex(uint32_t id) const { return m_attachments[id]; } From b0ac267fd56850ab727ebe6754f18fd9c1df486b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 20:59:53 +0000 Subject: [PATCH 0796/1348] [d3d9] Explicitly cast to D3DRENDERSTATETYPE in ColorWriteIndex Need this to silence warnings after doing some arithmetic on an enum. --- src/d3d9/d3d9_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_util.h b/src/d3d9/d3d9_util.h index ab564f907..4358233f8 100644 --- a/src/d3d9/d3d9_util.h +++ b/src/d3d9/d3d9_util.h @@ -241,7 +241,7 @@ namespace dxvk { } inline D3DRENDERSTATETYPE ColorWriteIndex(uint32_t i) { - return D3DRENDERSTATETYPE(i ? D3DRS_COLORWRITEENABLE1 + i - 1 : D3DRS_COLORWRITEENABLE); + return D3DRENDERSTATETYPE(i ? D3DRENDERSTATETYPE(D3DRS_COLORWRITEENABLE1 + i - 1) : D3DRS_COLORWRITEENABLE); } inline bool AreFormatsSimilar(D3D9Format srcFormat, D3D9Format dstFormat) { From ce5e7ad4278985b122c297f6621df5715b78319f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 21:01:09 +0000 Subject: [PATCH 0797/1348] [d3d11] Remove MaxAnisotropy < 0 check This type is unsigned, this is impossible. --- src/d3d11/d3d11_sampler.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_sampler.cpp b/src/d3d11/d3d11_sampler.cpp index 27767b5a0..f0cd292f9 100644 --- a/src/d3d11/d3d11_sampler.cpp +++ b/src/d3d11/d3d11_sampler.cpp @@ -106,8 +106,7 @@ namespace dxvk { return E_INVALIDARG; } - if (pDesc->MaxAnisotropy < 0 - || pDesc->MaxAnisotropy > 16) { + if (pDesc->MaxAnisotropy > 16) { return E_INVALIDARG; } else if ((filterBits & 0x40) == 0 /* not anisotropic */) { // Reset anisotropy if it is not used From aa06e71dee81fa7e51e746ebd52ae33c00cb8e49 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 21:01:51 +0000 Subject: [PATCH 0798/1348] [d3d11] Remove useless const qualifiers on IsYCbCr and NeedsCopy return values --- src/d3d11/d3d11_video.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_video.h b/src/d3d11/d3d11_video.h index e883bbb00..fd3b3387b 100644 --- a/src/d3d11/d3d11_video.h +++ b/src/d3d11/d3d11_video.h @@ -134,11 +134,11 @@ namespace dxvk { void STDMETHODCALLTYPE GetDesc( D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC* pDesc); - const bool IsYCbCr() const { + bool IsYCbCr() const { return m_isYCbCr; } - const bool NeedsCopy() const { + bool NeedsCopy() const { return m_copy != nullptr; } From 64d88c684d23a51cc734bedc51cade08017cb0e0 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 21:04:18 +0000 Subject: [PATCH 0799/1348] [dxbc] Explicitly cast down to VkAccessFlags when assinging binding.access Otherwise both halves of the terniary are differing types causing a warning. --- src/dxbc/dxbc_compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index b45dce512..88f12098a 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -1206,7 +1206,7 @@ namespace dxvk { binding.resourceBinding = bindingId; binding.access = isUav ? m_analysis->uavInfos[registerId].accessFlags - : VK_ACCESS_SHADER_READ_BIT; + : VkAccessFlags(VK_ACCESS_SHADER_READ_BIT); if (useRawSsbo || isUav) { if (!(binding.access & VK_ACCESS_SHADER_WRITE_BIT)) From f9bd1a5d7965d945b8a5783c09c01e0a7f3d3b74 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 21:04:36 +0000 Subject: [PATCH 0800/1348] [build] Enable warning_level 2 Compiles cleanly with GCC 12 --- meson.build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index b6efedce8..ca51272e1 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('dxvk', ['c', 'cpp'], version : 'v1.10.1', meson_version : '>= 0.49', default_options : [ 'cpp_std=c++17' ]) +project('dxvk', ['c', 'cpp'], version : 'v1.10.1', meson_version : '>= 0.49', default_options : [ 'cpp_std=c++17', 'warning_level=2' ]) cpu_family = target_machine.cpu_family() platform = target_machine.system() @@ -13,6 +13,10 @@ compiler_args = [ '-msse3', '-mfpmath=sse', '-Wimplicit-fallthrough', + # gcc + '-Wno-missing-field-initializers', + '-Wno-unused-parameter', + '-Wno-cast-function-type', # Needed for GetProcAddress. # clang '-Wno-unused-private-field', '-Wno-microsoft-exception-spec', From a3727ebd42432cb7a153bbbe3379e88ecdbb1401 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 21:22:48 +0000 Subject: [PATCH 0801/1348] [d3d11] Fix UNKNOWN enum in video view dimension switch cases --- src/d3d11/d3d11_video.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 8635f63d6..185547118 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -174,7 +174,7 @@ namespace dxvk { viewInfo.numLayers = 1; break; - case D3D11_RTV_DIMENSION_UNKNOWN: + case D3D11_VPIV_DIMENSION_UNKNOWN: throw DxvkError("Invalid view dimension"); } @@ -277,7 +277,7 @@ namespace dxvk { viewInfo.numLayers = m_desc.Texture2DArray.ArraySize; break; - case D3D11_RTV_DIMENSION_UNKNOWN: + case D3D11_VPOV_DIMENSION_UNKNOWN: throw DxvkError("Invalid view dimension"); } From 9adc6f2d3ee4abd2b36a746b25e9db47ea885698 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 21:23:09 +0000 Subject: [PATCH 0802/1348] [d3d11] Remove unused this capture in UnbindResources --- src/d3d11/d3d11_video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 185547118..0e0a4897a 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1312,7 +1312,7 @@ namespace dxvk { void D3D11VideoContext::UnbindResources() { - m_ctx->EmitCs([this] (DxvkContext* ctx) { + m_ctx->EmitCs([] (DxvkContext* ctx) { ctx->bindRenderTargets(DxvkRenderTargets(), 0u); ctx->bindShader(nullptr); From 99e01d64f73e46a7b6ad9c4335c44c3003b1b011 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 21:25:25 +0000 Subject: [PATCH 0803/1348] [dxso] Make fallthrough for extra params explicit --- src/dxso/dxso_decoder.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dxso/dxso_decoder.cpp b/src/dxso/dxso_decoder.cpp index 42d8d64b7..3dd5bb456 100644 --- a/src/dxso/dxso_decoder.cpp +++ b/src/dxso/dxso_decoder.cpp @@ -45,8 +45,11 @@ namespace dxvk { && info.minorVersion() == 4) { switch (opcode) { case DxsoOpcode::TexCoord: - case DxsoOpcode::Tex: length += 1; - default: break; + case DxsoOpcode::Tex: + length += 1; + break; + default: + break; } } From 935541bcb019fb3cf485dc8b0120dac76412852e Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 21:26:03 +0000 Subject: [PATCH 0804/1348] [util] Make math types have implicit copy assignments We define implicit copy constructors, should also define implicit copy assignments. --- src/util/util_matrix.h | 1 + src/util/util_vector.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/util/util_matrix.h b/src/util/util_matrix.h index 98f260f88..559c7b989 100644 --- a/src/util/util_matrix.h +++ b/src/util/util_matrix.h @@ -43,6 +43,7 @@ namespace dxvk { } Matrix4(const Matrix4& other) = default; + Matrix4& operator=(const Matrix4& other) = default; Vector4& operator[](size_t index); const Vector4& operator[](size_t index) const; diff --git a/src/util/util_vector.h b/src/util/util_vector.h index 77cdf2942..43deeb922 100644 --- a/src/util/util_vector.h +++ b/src/util/util_vector.h @@ -22,6 +22,7 @@ namespace dxvk { : x(xyzw[0]), y(xyzw[1]), z(xyzw[2]), w(xyzw[3]) { } Vector4Base(const Vector4Base& other) = default; + Vector4Base& operator=(const Vector4Base& other) = default; inline T& operator[](size_t index) { return data[index]; } inline const T& operator[](size_t index) const { return data[index]; } From 10bb285f2eb064a34b5ce72f3d38113c4d619c08 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 21:29:28 +0000 Subject: [PATCH 0805/1348] [d3d9] Remove unused dstExtent + friends in GetRenderTargetData --- src/d3d9/d3d9_device.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index c8dee1152..a90bc5e5b 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -911,19 +911,11 @@ namespace dxvk { srcSubresource.mipLevel, srcSubresource.arrayLayer, 1 }; - - VkExtent3D texLevelExtentBlockCount = util::computeBlockCount(srcTexExtent, srcFormatInfo->blockSize); - VkDeviceSize pitch = align(texLevelExtentBlockCount.width * uint32_t(srcFormatInfo->elementSize), 4); - uint32_t pitchBlocks = uint32_t(pitch / srcFormatInfo->elementSize); - VkExtent2D dstExtent = VkExtent2D{ pitchBlocks, - texLevelExtentBlockCount.height * pitchBlocks }; - EmitCs([ cBuffer = dstBuffer, cImage = srcImage, cSubresources = srcSubresourceLayers, - cLevelExtent = srcTexExtent, - cDstExtent = dstExtent + cLevelExtent = srcTexExtent ] (DxvkContext* ctx) { ctx->copyImageToBuffer(cBuffer, 0, 4, 0, cImage, cSubresources, VkOffset3D { 0, 0, 0 }, From ce47bf4264ed020c4c132cdeae8a430ecff4fb9d Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 21:26:18 +0000 Subject: [PATCH 0806/1348] [build] Disable some dumb clang warnings --- meson.build | 3 +++ 1 file changed, 3 insertions(+) diff --git a/meson.build b/meson.build index ca51272e1..ba5f88bb5 100644 --- a/meson.build +++ b/meson.build @@ -20,6 +20,9 @@ compiler_args = [ # clang '-Wno-unused-private-field', '-Wno-microsoft-exception-spec', + '-Wno-extern-c-compat', + '-Wno-unused-const-variable', + '-Wno-missing-braces', ] link_args = [] From 3a636f60940d64a29f025de5e9ba6e2fcdc9a1e2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 11 Sep 2022 15:09:23 +0200 Subject: [PATCH 0807/1348] [dxvk] Introduce DxvkFormatQuery --- src/d3d11/d3d11_device.cpp | 39 +++++++++++++++++++++++--------- src/d3d11/d3d11_texture.cpp | 12 ++++++---- src/d3d9/d3d9_common_texture.cpp | 11 ++++++--- src/dxvk/dxvk_device.cpp | 16 +++++-------- src/dxvk/dxvk_device.h | 12 ++-------- src/dxvk/dxvk_format.h | 11 +++++++++ 6 files changed, 63 insertions(+), 38 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index eb6d9e679..a9ffd8560 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1554,9 +1554,15 @@ namespace dxvk { // Check if the device supports the given combination of format // and sample count. D3D exposes the opaque concept of quality // levels to the application, we'll just define one such level. - auto properties = m_dxvkDevice->getFormatLimits(format, - VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, flags); - + DxvkFormatQuery formatQuery = { }; + formatQuery.format = format; + formatQuery.type = VK_IMAGE_TYPE_2D; + formatQuery.tiling = VK_IMAGE_TILING_OPTIMAL; + formatQuery.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + formatQuery.flags = flags; + + auto properties = m_dxvkDevice->getFormatLimits(formatQuery); + if (properties && (properties->sampleCounts & sampleCountFlag)) *pNumQualityLevels = 1; return S_OK; @@ -2128,8 +2134,13 @@ namespace dxvk { ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT : VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - auto limits = m_dxvkDevice->getFormatLimits(fmtMapping.Format, - VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage, 0); + DxvkFormatQuery formatQuery = { }; + formatQuery.format = fmtMapping.Format; + formatQuery.type = VK_IMAGE_TYPE_2D; + formatQuery.tiling = VK_IMAGE_TILING_OPTIMAL; + formatQuery.usage = usage; + + auto limits = m_dxvkDevice->getFormatLimits(formatQuery); if (limits && limits->sampleCounts > VK_SAMPLE_COUNT_1_BIT) { flags1 |= D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET @@ -2185,14 +2196,20 @@ namespace dxvk { BOOL D3D11Device::GetImageTypeSupport(VkFormat Format, VkImageType Type, VkImageCreateFlags Flags) const { - auto properties = m_dxvkDevice->getFormatLimits(Format, - Type, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT, Flags); - + DxvkFormatQuery formatQuery = { }; + formatQuery.format = Format; + formatQuery.type = Type; + formatQuery.tiling = VK_IMAGE_TILING_OPTIMAL; + formatQuery.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + formatQuery.flags = Flags; + + auto properties = m_dxvkDevice->getFormatLimits(formatQuery); + if (!properties) { - properties = m_dxvkDevice->getFormatLimits(Format, - Type, VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_SAMPLED_BIT, Flags); + formatQuery.tiling = VK_IMAGE_TILING_LINEAR; + properties = m_dxvkDevice->getFormatLimits(formatQuery); } - + return properties.has_value(); } diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index ba6ad0cc1..631fceb6d 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -472,13 +472,17 @@ namespace dxvk { BOOL D3D11CommonTexture::CheckImageSupport( const DxvkImageCreateInfo* pImageInfo, VkImageTiling Tiling) const { - VkImageUsageFlags usage = pImageInfo->usage; + DxvkFormatQuery formatQuery = { }; + formatQuery.format = pImageInfo->format; + formatQuery.type = pImageInfo->type; + formatQuery.tiling = Tiling; + formatQuery.usage = pImageInfo->usage; + formatQuery.flags = pImageInfo->flags; if (pImageInfo->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) - usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + formatQuery.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - auto properties = m_device->GetDXVKDevice()->getFormatLimits( - pImageInfo->format, pImageInfo->type, Tiling, usage, pImageInfo->flags); + auto properties = m_device->GetDXVKDevice()->getFormatLimits(formatQuery); if (!properties) return FALSE; diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 6f6a164f7..5b5c07115 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -397,9 +397,14 @@ namespace dxvk { BOOL D3D9CommonTexture::CheckImageSupport( const DxvkImageCreateInfo* pImageInfo, VkImageTiling Tiling) const { - auto properties = m_device->GetDXVKDevice()->getFormatLimits( - pImageInfo->format, pImageInfo->type, Tiling, - pImageInfo->usage, pImageInfo->flags); + DxvkFormatQuery formatQuery = { }; + formatQuery.format = pImageInfo->format; + formatQuery.type = pImageInfo->type; + formatQuery.tiling = Tiling; + formatQuery.usage = pImageInfo->usage; + formatQuery.flags = pImageInfo->flags; + + auto properties = m_device->GetDXVKDevice()->getFormatLimits(formatQuery); if (!properties) return FALSE; diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 79c39c868..6657d6881 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -43,19 +43,15 @@ namespace dxvk { std::optional DxvkDevice::getFormatLimits( - VkFormat format, - VkImageType type, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkImageCreateFlags flags) const { + const DxvkFormatQuery& query) const { auto vk = m_adapter->vki(); VkPhysicalDeviceImageFormatInfo2 info = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 }; - info.format = format; - info.type = type; - info.tiling = tiling; - info.usage = usage; - info.flags = flags; + info.format = query.format; + info.type = query.type; + info.tiling = query.tiling; + info.usage = query.usage; + info.flags = query.flags; VkImageFormatProperties2 properties = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 }; diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 8f9265f48..7de704634 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -186,19 +186,11 @@ namespace dxvk { /** * \brief Queries format limits * - * \param [in] format Image format to quers - * \param [in] type Image type - * \param [in] tiling Image tiling - * \param [in] usage Image usage flags - * \param [in] flags Image create flags + * \param [in] query Format query info * \returns Format limits if the given image is supported */ std::optional getFormatLimits( - VkFormat format, - VkImageType type, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkImageCreateFlags flags) const; + const DxvkFormatQuery& query) const; /** * \brief Get device status diff --git a/src/dxvk/dxvk_format.h b/src/dxvk/dxvk_format.h index 6585deac5..c6d0c9fba 100644 --- a/src/dxvk/dxvk_format.h +++ b/src/dxvk/dxvk_format.h @@ -34,6 +34,17 @@ namespace dxvk { VkDeviceSize maxResourceSize; }; + /** + * \brief Format query info + */ + struct DxvkFormatQuery { + VkFormat format; + VkImageType type; + VkImageTiling tiling; + VkImageUsageFlags usage; + VkImageCreateFlags flags; + }; + /** * \brief Planar format info */ From c0fdf1449c0d28563ed4a8fc252b684adb5e7dc0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 11 Sep 2022 15:28:14 +0200 Subject: [PATCH 0808/1348] [dxvk] Allow querying external memory features for image formats --- src/dxvk/dxvk_device.cpp | 13 ++++++++++++- src/dxvk/dxvk_format.h | 22 ++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 6657d6881..25b2e45cb 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -46,6 +46,9 @@ namespace dxvk { const DxvkFormatQuery& query) const { auto vk = m_adapter->vki(); + VkPhysicalDeviceExternalImageFormatInfo externalInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO }; + externalInfo.handleType = query.handleType; + VkPhysicalDeviceImageFormatInfo2 info = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 }; info.format = query.format; info.type = query.type; @@ -53,20 +56,28 @@ namespace dxvk { info.usage = query.usage; info.flags = query.flags; + if (externalInfo.handleType) + externalInfo.pNext = std::exchange(info.pNext, &externalInfo); + + VkExternalImageFormatProperties externalProperties = { VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES }; VkImageFormatProperties2 properties = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 }; + if (externalInfo.handleType) + externalProperties.pNext = std::exchange(properties.pNext, &externalProperties); + VkResult vr = vk->vkGetPhysicalDeviceImageFormatProperties2( m_adapter->handle(), &info, &properties); if (vr != VK_SUCCESS) return std::nullopt; - DxvkFormatLimits result; + DxvkFormatLimits result = { }; result.maxExtent = properties.imageFormatProperties.maxExtent; result.maxMipLevels = properties.imageFormatProperties.maxMipLevels; result.maxArrayLayers = properties.imageFormatProperties.maxArrayLayers; result.sampleCounts = properties.imageFormatProperties.sampleCounts; result.maxResourceSize = properties.imageFormatProperties.maxResourceSize; + result.externalFeatures = externalProperties.externalMemoryProperties.externalMemoryFeatures; return result; } diff --git a/src/dxvk/dxvk_format.h b/src/dxvk/dxvk_format.h index c6d0c9fba..34084642a 100644 --- a/src/dxvk/dxvk_format.h +++ b/src/dxvk/dxvk_format.h @@ -27,22 +27,24 @@ namespace dxvk { * \brief Format support limits for a given set of image usage flags */ struct DxvkFormatLimits { - VkExtent3D maxExtent; - uint32_t maxMipLevels; - uint32_t maxArrayLayers; - VkSampleCountFlags sampleCounts; - VkDeviceSize maxResourceSize; + VkExtent3D maxExtent; + uint32_t maxMipLevels; + uint32_t maxArrayLayers; + VkSampleCountFlags sampleCounts; + VkDeviceSize maxResourceSize; + VkExternalMemoryFeatureFlags externalFeatures; }; /** * \brief Format query info */ struct DxvkFormatQuery { - VkFormat format; - VkImageType type; - VkImageTiling tiling; - VkImageUsageFlags usage; - VkImageCreateFlags flags; + VkFormat format; + VkImageType type; + VkImageTiling tiling; + VkImageUsageFlags usage; + VkImageCreateFlags flags; + VkExternalMemoryHandleTypeFlagBits handleType; }; /** From 0123e844b2b5728094adf28cbcee206fea92ff23 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 11 Sep 2022 16:08:40 +0200 Subject: [PATCH 0809/1348] [dxvk] Move getFormatLimits back to DxvkAdapter --- src/dxvk/dxvk_adapter.cpp | 38 +++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_adapter.h | 11 +++++++++++ src/dxvk/dxvk_device.cpp | 40 --------------------------------------- src/dxvk/dxvk_device.h | 6 +++--- 4 files changed, 52 insertions(+), 43 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 9d3328ac0..7e6c45250 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -73,6 +73,44 @@ namespace dxvk { } + std::optional DxvkAdapter::getFormatLimits( + const DxvkFormatQuery& query) const { + VkPhysicalDeviceExternalImageFormatInfo externalInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO }; + externalInfo.handleType = query.handleType; + + VkPhysicalDeviceImageFormatInfo2 info = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 }; + info.format = query.format; + info.type = query.type; + info.tiling = query.tiling; + info.usage = query.usage; + info.flags = query.flags; + + if (externalInfo.handleType) + externalInfo.pNext = std::exchange(info.pNext, &externalInfo); + + VkExternalImageFormatProperties externalProperties = { VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES }; + VkImageFormatProperties2 properties = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 }; + + if (externalInfo.handleType) + externalProperties.pNext = std::exchange(properties.pNext, &externalProperties); + + VkResult vr = m_vki->vkGetPhysicalDeviceImageFormatProperties2( + m_handle, &info, &properties); + + if (vr != VK_SUCCESS) + return std::nullopt; + + DxvkFormatLimits result = { }; + result.maxExtent = properties.imageFormatProperties.maxExtent; + result.maxMipLevels = properties.imageFormatProperties.maxMipLevels; + result.maxArrayLayers = properties.imageFormatProperties.maxArrayLayers; + result.sampleCounts = properties.imageFormatProperties.sampleCounts; + result.maxResourceSize = properties.imageFormatProperties.maxResourceSize; + result.externalFeatures = externalProperties.externalMemoryProperties.externalMemoryFeatures; + return result; + } + + DxvkAdapterQueueIndices DxvkAdapter::findQueueFamilies() const { uint32_t graphicsQueue = findQueueFamily( VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, diff --git a/src/dxvk/dxvk_adapter.h b/src/dxvk/dxvk_adapter.h index 52cebcab9..56f15ffe5 100644 --- a/src/dxvk/dxvk_adapter.h +++ b/src/dxvk/dxvk_adapter.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "dxvk_device_info.h" #include "dxvk_extensions.h" #include "dxvk_include.h" @@ -146,6 +148,15 @@ namespace dxvk { DxvkFormatFeatures getFormatFeatures( VkFormat format) const; + /** + * \brief Queries format limits + * + * \param [in] query Format query info + * \returns Format limits if the given image is supported + */ + std::optional getFormatLimits( + const DxvkFormatQuery& query) const; + /** * \brief Retrieves queue family indices * \returns Indices for all queue families diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 25b2e45cb..e059f9012 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -42,46 +42,6 @@ namespace dxvk { } - std::optional DxvkDevice::getFormatLimits( - const DxvkFormatQuery& query) const { - auto vk = m_adapter->vki(); - - VkPhysicalDeviceExternalImageFormatInfo externalInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO }; - externalInfo.handleType = query.handleType; - - VkPhysicalDeviceImageFormatInfo2 info = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 }; - info.format = query.format; - info.type = query.type; - info.tiling = query.tiling; - info.usage = query.usage; - info.flags = query.flags; - - if (externalInfo.handleType) - externalInfo.pNext = std::exchange(info.pNext, &externalInfo); - - VkExternalImageFormatProperties externalProperties = { VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES }; - VkImageFormatProperties2 properties = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 }; - - if (externalInfo.handleType) - externalProperties.pNext = std::exchange(properties.pNext, &externalProperties); - - VkResult vr = vk->vkGetPhysicalDeviceImageFormatProperties2( - m_adapter->handle(), &info, &properties); - - if (vr != VK_SUCCESS) - return std::nullopt; - - DxvkFormatLimits result = { }; - result.maxExtent = properties.imageFormatProperties.maxExtent; - result.maxMipLevels = properties.imageFormatProperties.maxMipLevels; - result.maxArrayLayers = properties.imageFormatProperties.maxArrayLayers; - result.sampleCounts = properties.imageFormatProperties.sampleCounts; - result.maxResourceSize = properties.imageFormatProperties.maxResourceSize; - result.externalFeatures = externalProperties.externalMemoryProperties.externalMemoryFeatures; - return result; - } - - bool DxvkDevice::isUnifiedMemoryArchitecture() const { return m_adapter->isUnifiedMemoryArchitecture(); } diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 7de704634..659353d5f 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -1,7 +1,5 @@ #pragma once -#include - #include "dxvk_adapter.h" #include "dxvk_buffer.h" #include "dxvk_compute.h" @@ -190,7 +188,9 @@ namespace dxvk { * \returns Format limits if the given image is supported */ std::optional getFormatLimits( - const DxvkFormatQuery& query) const; + const DxvkFormatQuery& query) const { + return m_adapter->getFormatLimits(query); + } /** * \brief Get device status From 443cb658f767b9215172f3643e8325e43f0d66d3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 11 Sep 2022 15:32:16 +0200 Subject: [PATCH 0810/1348] [dxvk] Clean up DxvkImage::canShareImage --- src/dxvk/dxvk_image.cpp | 57 +++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index 8c3a1bc89..69b745477 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -187,45 +187,34 @@ namespace dxvk { return false; } - if (createInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) - return false; - - VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO }; - externalImageFormatInfo.handleType = sharingInfo.type; - - VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, &externalImageFormatInfo }; - imageFormatInfo.format = createInfo.format; - imageFormatInfo.type = createInfo.imageType; - imageFormatInfo.tiling = createInfo.tiling; - imageFormatInfo.usage = createInfo.usage; - imageFormatInfo.flags = createInfo.flags; - - VkExternalImageFormatProperties externalImageFormatProperties = { VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES }; - VkImageFormatProperties2 imageFormatProperties = { VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, &externalImageFormatProperties }; - - VkResult vr = m_device->adapter()->vki()->vkGetPhysicalDeviceImageFormatProperties2( - m_device->adapter()->handle(), &imageFormatInfo, &imageFormatProperties); - - if (vr != VK_SUCCESS) { - Logger::err(str::format("Failed to create shared resource: getImageProperties failed:", vr)); + if (createInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) { + Logger::err("Failed to create shared resource: Sharing sparse resources not supported"); return false; } - if (sharingInfo.mode == DxvkSharedHandleMode::Export) { - bool ret = externalImageFormatProperties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT; - if (!ret) - Logger::err("Failed to create shared resource: image cannot be exported"); - return ret; + DxvkFormatQuery formatQuery = { }; + formatQuery.format = createInfo.format; + formatQuery.type = createInfo.imageType; + formatQuery.tiling = createInfo.tiling; + formatQuery.usage = createInfo.usage; + formatQuery.flags = createInfo.flags; + formatQuery.handleType = sharingInfo.type; + + auto limits = m_device->getFormatLimits(formatQuery); + + if (!limits) + return false; + + VkExternalMemoryFeatureFlagBits requiredFeature = sharingInfo.mode == DxvkSharedHandleMode::Export + ? VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT + : VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; + + if (!(limits->externalFeatures & requiredFeature)) { + Logger::err("Failed to create shared resource: Image cannot be shared"); + return false; } - if (sharingInfo.mode == DxvkSharedHandleMode::Import) { - bool ret = externalImageFormatProperties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; - if (!ret) - Logger::err("Failed to create shared resource: image cannot be imported"); - return ret; - } - - return false; + return true; } From 299fc4c4cfa365c52a5663354ad83b0a03b37728 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 11 Sep 2022 16:03:57 +0200 Subject: [PATCH 0811/1348] [d3d11] Determine shared resources tier more accurately --- src/d3d11/d3d11_features.cpp | 104 +++++++++++++++++++++++++++++++++-- src/d3d11/d3d11_features.h | 6 ++ 2 files changed, 104 insertions(+), 6 deletions(-) diff --git a/src/d3d11/d3d11_features.cpp b/src/d3d11/d3d11_features.cpp index a3fe2cce0..3b764cae6 100644 --- a/src/d3d11/d3d11_features.cpp +++ b/src/d3d11/d3d11_features.cpp @@ -35,6 +35,8 @@ namespace dxvk { m_d3d10Options.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = TRUE; // D3D11.1 options. All of these are required for Feature Level 11_1. + auto sharedResourceTier = DetermineSharedResourceTier(Adapter, FeatureLevel); + bool hasDoublePrecisionSupport = m_features.core.features.shaderFloat64 && m_features.core.features.shaderInt64; @@ -46,7 +48,7 @@ namespace dxvk { m_d3d11Options.ConstantBufferOffsetting = TRUE; m_d3d11Options.MapNoOverwriteOnDynamicConstantBuffer = TRUE; m_d3d11Options.MapNoOverwriteOnDynamicBufferSRV = TRUE; - m_d3d11Options.ExtendedResourceSharing = TRUE; + m_d3d11Options.ExtendedResourceSharing = sharedResourceTier > D3D11_SHARED_RESOURCE_TIER_0; if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0) { m_d3d11Options.OutputMergerLogicOp = m_features.core.features.logicOp; @@ -91,10 +93,10 @@ namespace dxvk { } // D3D11.4 options - m_d3d11Options4.ExtendedNV12SharedTextureSupported = TRUE; + m_d3d11Options4.ExtendedNV12SharedTextureSupported = sharedResourceTier > D3D11_SHARED_RESOURCE_TIER_0; // More D3D11.4 options - m_d3d11Options5.SharedResourceTier = DetermineSharedResourceTier(FeatureLevel); + m_d3d11Options5.SharedResourceTier = sharedResourceTier; // Double-precision support if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0) @@ -205,10 +207,80 @@ namespace dxvk { D3D11_SHARED_RESOURCE_TIER D3D11DeviceFeatures::DetermineSharedResourceTier( + const Rc& Adapter, D3D_FEATURE_LEVEL FeatureLevel) { - // Shared resources are all sorts of wonky for obvious - // reasons, so don't over-promise things here for now - return D3D11_SHARED_RESOURCE_TIER_1; + static std::atomic s_errorShown = { false }; + + // Lie about supporting Tier 1 since that's the + // minimum required tier for Feature Level 11_1 + if (!Adapter->features().khrExternalMemoryWin32) { + if (!s_errorShown.exchange(true)) + Logger::warn("D3D11DeviceFeatures: External memory features not supported"); + + return D3D11_SHARED_RESOURCE_TIER_1; + } + + // Check support for extended formats. Ignore multi-plane + // formats here since driver support varies too much. + std::array requiredFormats = {{ + VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_R32G32B32A32_SFLOAT, + VK_FORMAT_R32G32B32A32_UINT, + VK_FORMAT_R32G32B32A32_SINT, + VK_FORMAT_R16G16B16A16_SFLOAT, + VK_FORMAT_R16G16B16A16_UNORM, + VK_FORMAT_R16G16B16A16_UINT, + VK_FORMAT_R16G16B16A16_SNORM, + VK_FORMAT_R16G16B16A16_SINT, + VK_FORMAT_A2B10G10R10_UNORM_PACK32, + VK_FORMAT_A2B10G10R10_UINT_PACK32, + VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R8G8B8A8_SRGB, + VK_FORMAT_R8G8B8A8_UINT, + VK_FORMAT_R8G8B8A8_SNORM, + VK_FORMAT_R8G8B8A8_SINT, + VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_B8G8R8A8_SRGB, + VK_FORMAT_R32_SFLOAT, + VK_FORMAT_R32_UINT, + VK_FORMAT_R32_SINT, + VK_FORMAT_R16_SFLOAT, + VK_FORMAT_R16_UNORM, + VK_FORMAT_R16_UINT, + VK_FORMAT_R16_SNORM, + VK_FORMAT_R16_SINT, + VK_FORMAT_R8_UNORM, + VK_FORMAT_R8_UINT, + VK_FORMAT_R8_SNORM, + VK_FORMAT_R8_SINT, + }}; + + bool allKmtHandlesSupported = true; + bool allNtHandlesSupported = true; + + for (auto f : requiredFormats) { + allKmtHandlesSupported &= CheckFormatSharingSupport(Adapter, f, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT); + allNtHandlesSupported &= CheckFormatSharingSupport(Adapter, f, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT); + } + + // Again, lie about at least tier 1 support + if (!allKmtHandlesSupported) { + if (!s_errorShown.exchange(true)) + Logger::warn("D3D11DeviceFeatures: Some formats not supported for resource sharing"); + return D3D11_SHARED_RESOURCE_TIER_1; + } + + // Tier 2 requires all the above formats to be shareable + // with NT handles in order to support D3D12 interop + if (!allNtHandlesSupported) + return D3D11_SHARED_RESOURCE_TIER_1; + + // Tier 3 additionally requires R11G11B10 to be + // shareable with D3D12 + if (!CheckFormatSharingSupport(Adapter, VK_FORMAT_B10G11R11_UFLOAT_PACK32, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT)) + return D3D11_SHARED_RESOURCE_TIER_2; + + return D3D11_SHARED_RESOURCE_TIER_3; } @@ -278,6 +350,26 @@ namespace dxvk { } + BOOL D3D11DeviceFeatures::CheckFormatSharingSupport( + const Rc& Adapter, + VkFormat Format, + VkExternalMemoryHandleTypeFlagBits HandleType) { + DxvkFormatQuery query = { }; + query.format = Format; + query.type = VK_IMAGE_TYPE_2D; + query.tiling = VK_IMAGE_TILING_OPTIMAL; + query.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + query.handleType = HandleType; + + constexpr VkExternalMemoryFeatureFlags featureMask + = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT + | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; + + auto limits = Adapter->getFormatLimits(query); + return limits && (limits->externalFeatures & featureMask); + } + + D3D_FEATURE_LEVEL D3D11DeviceFeatures::GetMaxFeatureLevel() const { // Check Feature Level 11_0 features if (!m_features.core.features.drawIndirectFirstInstance diff --git a/src/d3d11/d3d11_features.h b/src/d3d11/d3d11_features.h index 052eec6a5..9bdd7c318 100644 --- a/src/d3d11/d3d11_features.h +++ b/src/d3d11/d3d11_features.h @@ -102,6 +102,7 @@ namespace dxvk { D3D_FEATURE_LEVEL FeatureLevel); D3D11_SHARED_RESOURCE_TIER DetermineSharedResourceTier( + const Rc& Adapter, D3D_FEATURE_LEVEL FeatureLevel); D3D11_TILED_RESOURCES_TIER DetermineTiledResourcesTier( @@ -111,6 +112,11 @@ namespace dxvk { const Rc& Adapter, D3D_FEATURE_LEVEL FeatureLevel); + BOOL CheckFormatSharingSupport( + const Rc& Adapter, + VkFormat Format, + VkExternalMemoryHandleTypeFlagBits HandleType); + D3D_FEATURE_LEVEL GetMaxFeatureLevel() const; }; From 8dc940004508b0f5a512faf805683f8c514f5401 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 11 Sep 2022 15:41:47 +0200 Subject: [PATCH 0812/1348] [d3d11] Report D3D11_FORMAT_SUPPORT2_SHAREABLE appropriately --- src/d3d11/d3d11_device.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index a9ffd8560..417eadcfe 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2147,6 +2147,20 @@ namespace dxvk { | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE | D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD; } + + // Query whether the format is shareable + if ((fmtProperties->aspectMask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_PLANE_0_BIT)) + && (m_dxvkDevice->features().khrExternalMemoryWin32)) { + constexpr VkExternalMemoryFeatureFlags featureMask + = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT + | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; + + formatQuery.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT; + limits = m_dxvkDevice->getFormatLimits(formatQuery); + + if (limits && (limits->externalFeatures & featureMask)) + flags2 |= D3D11_FORMAT_SUPPORT2_SHAREABLE; + } } // Format can be used for storage images or storage texel buffers From 8842af2ad6c96204cf3f8b5d45ad8f5dfb484294 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 12 Sep 2022 14:20:30 +0200 Subject: [PATCH 0813/1348] [dxvk] Get rid of sampler for pack operations --- src/dxvk/dxvk_meta_pack.cpp | 33 +++++---------------------- src/dxvk/dxvk_meta_pack.h | 4 ---- src/dxvk/shaders/dxvk_pack_d24s8.comp | 6 +++-- src/dxvk/shaders/dxvk_pack_d32s8.comp | 6 +++-- 4 files changed, 14 insertions(+), 35 deletions(-) diff --git a/src/dxvk/dxvk_meta_pack.cpp b/src/dxvk/dxvk_meta_pack.cpp index f18bb7cc2..0a5475f8a 100644 --- a/src/dxvk/dxvk_meta_pack.cpp +++ b/src/dxvk/dxvk_meta_pack.cpp @@ -12,7 +12,6 @@ namespace dxvk { DxvkMetaPackObjects::DxvkMetaPackObjects(const DxvkDevice* device) : m_vkd (device->vkd()), - m_sampler (createSampler()), m_dsetLayoutPack (createPackDescriptorSetLayout()), m_dsetLayoutUnpack(createUnpackDescriptorSetLayout()), m_pipeLayoutPack (createPipelineLayout(m_dsetLayoutPack, sizeof(DxvkMetaPackArgs))), @@ -44,8 +43,6 @@ namespace dxvk { m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_dsetLayoutPack, nullptr); m_vkd->vkDestroyDescriptorSetLayout(m_vkd->device(), m_dsetLayoutUnpack, nullptr); - - m_vkd->vkDestroySampler(m_vkd->device(), m_sampler, nullptr); } @@ -91,29 +88,11 @@ namespace dxvk { } - VkSampler DxvkMetaPackObjects::createSampler() { - VkSamplerCreateInfo info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; - info.magFilter = VK_FILTER_NEAREST; - info.minFilter = VK_FILTER_NEAREST; - info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; - info.unnormalizedCoordinates = VK_FALSE; - - VkSampler result = VK_NULL_HANDLE; - if (m_vkd->vkCreateSampler(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaPackObjects: Failed to create sampler"); - return result; - } - - VkDescriptorSetLayout DxvkMetaPackObjects::createPackDescriptorSetLayout() { std::array bindings = {{ - { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, - { 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, &m_sampler }, - { 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, &m_sampler }, + { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, + { 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, + { 2, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr }, }}; VkDescriptorSetLayoutCreateInfo dsetInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; @@ -165,9 +144,9 @@ namespace dxvk { VkDescriptorUpdateTemplate DxvkMetaPackObjects::createPackDescriptorUpdateTemplate() { std::array bindings = {{ - { 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, offsetof(DxvkMetaPackDescriptors, dstBuffer), 0 }, - { 1, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, offsetof(DxvkMetaPackDescriptors, srcDepth), 0 }, - { 2, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, offsetof(DxvkMetaPackDescriptors, srcStencil), 0 }, + { 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, offsetof(DxvkMetaPackDescriptors, dstBuffer), 0 }, + { 1, 0, 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, offsetof(DxvkMetaPackDescriptors, srcDepth), 0 }, + { 2, 0, 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, offsetof(DxvkMetaPackDescriptors, srcStencil), 0 }, }}; VkDescriptorUpdateTemplateCreateInfo templateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO }; diff --git a/src/dxvk/dxvk_meta_pack.h b/src/dxvk/dxvk_meta_pack.h index 133ce24b2..1e3df7764 100644 --- a/src/dxvk/dxvk_meta_pack.h +++ b/src/dxvk/dxvk_meta_pack.h @@ -92,8 +92,6 @@ namespace dxvk { Rc m_vkd; - VkSampler m_sampler; - VkDescriptorSetLayout m_dsetLayoutPack; VkDescriptorSetLayout m_dsetLayoutUnpack; @@ -110,8 +108,6 @@ namespace dxvk { VkPipeline m_pipeUnpackD24S8; VkPipeline m_pipeUnpackD32S8; - VkSampler createSampler(); - VkDescriptorSetLayout createPackDescriptorSetLayout(); VkDescriptorSetLayout createUnpackDescriptorSetLayout(); diff --git a/src/dxvk/shaders/dxvk_pack_d24s8.comp b/src/dxvk/shaders/dxvk_pack_d24s8.comp index c32fae581..b828c24a8 100644 --- a/src/dxvk/shaders/dxvk_pack_d24s8.comp +++ b/src/dxvk/shaders/dxvk_pack_d24s8.comp @@ -1,5 +1,7 @@ #version 450 +#extension GL_EXT_samplerless_texture_functions : require + layout( local_size_x = 8, local_size_y = 8, @@ -10,8 +12,8 @@ writeonly buffer s_buffer_t { uint data[]; } s_buffer; -layout(binding = 1) uniform sampler2DArray u_depth; -layout(binding = 2) uniform usampler2DArray u_stencil; +layout(binding = 1) uniform texture2DArray u_depth; +layout(binding = 2) uniform utexture2DArray u_stencil; layout(push_constant) uniform u_info_t { diff --git a/src/dxvk/shaders/dxvk_pack_d32s8.comp b/src/dxvk/shaders/dxvk_pack_d32s8.comp index a0332f02c..89bafe63d 100644 --- a/src/dxvk/shaders/dxvk_pack_d32s8.comp +++ b/src/dxvk/shaders/dxvk_pack_d32s8.comp @@ -1,5 +1,7 @@ #version 450 +#extension GL_EXT_samplerless_texture_functions : require + layout( local_size_x = 8, local_size_y = 8, @@ -15,8 +17,8 @@ writeonly buffer s_buffer_t { d32s8_t data[]; } s_buffer; -layout(binding = 1) uniform sampler2DArray u_depth; -layout(binding = 2) uniform usampler2DArray u_stencil; +layout(binding = 1) uniform texture2DArray u_depth; +layout(binding = 2) uniform utexture2DArray u_stencil; layout(push_constant) uniform u_info_t { From eda366662c469c5a5ac6211e936eece636cf3fac Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 12 Sep 2022 18:18:39 +0200 Subject: [PATCH 0814/1348] [dxbc] Handle workgroup-coherent UAVs more efficiently Some drivers don't handle the workgroup scope on stores and loads properly, so let's just do the availability and visibility operation on barriers. --- src/dxbc/dxbc_compiler.cpp | 59 ++++++++++++++++++++++---------------- src/dxbc/dxbc_compiler.h | 6 ++-- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 88f12098a..036f88e3a 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -2587,14 +2587,18 @@ namespace dxvk { memoryScope = spv::ScopeWorkgroup; memorySemantics |= spv::MemorySemanticsImageMemoryMask | spv::MemorySemanticsUniformMemoryMask - | spv::MemorySemanticsAcquireReleaseMask; + | spv::MemorySemanticsAcquireReleaseMask + | spv::MemorySemanticsMakeAvailableMask + | spv::MemorySemanticsMakeVisibleMask; } if (flags.test(DxbcSyncFlag::UavMemoryGlobal)) { - memoryScope = spv::ScopeQueueFamily; + memoryScope = m_hasGloballyCoherentUav ? spv::ScopeQueueFamily : spv::ScopeWorkgroup; memorySemantics |= spv::MemorySemanticsImageMemoryMask | spv::MemorySemanticsUniformMemoryMask - | spv::MemorySemanticsAcquireReleaseMask; + | spv::MemorySemanticsAcquireReleaseMask + | spv::MemorySemanticsMakeAvailableMask + | spv::MemorySemanticsMakeVisibleMask; } if (executionScope != spv::ScopeInvocation) { @@ -5192,21 +5196,22 @@ namespace dxvk { uint32_t coherence = bufferInfo.coherence; - if (isTgsm || coherence) - memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask; - if (isTgsm && m_moduleInfo.options.forceVolatileTgsmAccess) { memoryOperands.flags |= spv::MemoryAccessVolatileMask; coherence = spv::ScopeWorkgroup; } if (coherence) { - memoryOperands.flags |= spv::MemoryAccessMakePointerVisibleMask; - memoryOperands.makeVisible = m_module.constu32(coherence); + memoryOperands.flags |= spv::MemoryAccessNonPrivatePointerMask; - imageOperands.flags = spv::ImageOperandsNonPrivateTexelMask - | spv::ImageOperandsMakeTexelVisibleMask; - imageOperands.makeVisible = m_module.constu32(coherence); + if (coherence != spv::ScopeInvocation) { + memoryOperands.flags |= spv::MemoryAccessMakePointerVisibleMask; + memoryOperands.makeVisible = m_module.constu32(coherence); + + imageOperands.flags = spv::ImageOperandsNonPrivateTexelMask + | spv::ImageOperandsMakeTexelVisibleMask; + imageOperands.makeVisible = m_module.constu32(coherence); + } } sparseFeedbackId = 0; @@ -5316,21 +5321,22 @@ namespace dxvk { uint32_t coherence = bufferInfo.coherence; - if (isTgsm || coherence) - memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask; - if (isTgsm && m_moduleInfo.options.forceVolatileTgsmAccess) { memoryOperands.flags |= spv::MemoryAccessVolatileMask; coherence = spv::ScopeWorkgroup; } if (coherence) { - memoryOperands.flags |= spv::MemoryAccessMakePointerAvailableMask; - memoryOperands.makeAvailable = m_module.constu32(coherence); + memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask; - imageOperands.flags = spv::ImageOperandsNonPrivateTexelMask - | spv::ImageOperandsMakeTexelAvailableMask; - imageOperands.makeAvailable = m_module.constu32(coherence); + if (coherence != spv::ScopeInvocation) { + memoryOperands.flags |= spv::MemoryAccessMakePointerAvailableMask; + memoryOperands.makeAvailable = m_module.constu32(coherence); + + imageOperands.flags = spv::ImageOperandsNonPrivateTexelMask + | spv::ImageOperandsMakeTexelAvailableMask; + imageOperands.makeAvailable = m_module.constu32(coherence); + } } for (uint32_t i = 0; i < 4; i++) { @@ -7609,7 +7615,7 @@ namespace dxvk { spv::StorageClassWorkgroup); result.varId = m_gRegs.at(registerId).varId; result.stride = m_gRegs.at(registerId).elementStride; - result.coherence = 0; + result.coherence = spv::ScopeInvocation; result.isSsbo = false; return result; } break; @@ -7798,7 +7804,7 @@ namespace dxvk { } - uint32_t DxbcCompiler::getUavCoherence(uint32_t registerId, DxbcUavFlags flags) const { + uint32_t DxbcCompiler::getUavCoherence(uint32_t registerId, DxbcUavFlags flags) { // Ignore any resources that can't both be read and written in // the current shader, explicit availability/visibility operands // are not useful in that case. @@ -7807,13 +7813,16 @@ namespace dxvk { // If the globally coherent flag is set, the resource must be // coherent across multiple workgroups of the same dispatch - if (flags.test(DxbcUavFlag::GloballyCoherent)) + if (flags.test(DxbcUavFlag::GloballyCoherent)) { + m_hasGloballyCoherentUav = true; return spv::ScopeQueueFamily; + } - // In compute shaders, UAVs are implicitly workgroup coherent. - // In all other stage, there are no coherence guarantees. + // In compute shaders, UAVs are implicitly workgroup coherent, + // but we can rely on memory barrier instructions to make any + // access available and visible to the entire workgroup. if (m_programInfo.type() == DxbcProgramType::ComputeShader) - return spv::ScopeWorkgroup; + return spv::ScopeInvocation; return 0; } diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index d59457ad1..73e29e750 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -450,7 +450,9 @@ namespace dxvk { std::array m_samplers; std::array m_textures; std::array m_uavs; - + + bool m_hasGloballyCoherentUav = false; + /////////////////////////////////////////////// // Control flow information. Stores labels for // currently active if-else blocks and loops. @@ -1225,7 +1227,7 @@ namespace dxvk { uint32_t getUavCoherence( uint32_t registerId, - DxbcUavFlags flags) const; + DxbcUavFlags flags); /////////////////////////// // Type definition methods From e05e063df05255b21f283f21e78028ead3ca2781 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Mon, 12 Sep 2022 17:45:26 +0200 Subject: [PATCH 0815/1348] [util] Enable memoryTrackTest for SiN Episodes Emergence --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 9460b6186..fe5242b53 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -607,6 +607,10 @@ namespace dxvk { { R"(\\ship\.exe$)", {{ { "d3d9.memoryTrackTest", "True" }, }} }, + /* SiN Episodes Emergence */ + { R"(\\SinEpisodes\.exe$)", {{ + { "d3d9.memoryTrackTest", "True" }, + }} }, }}; From 26c8f46b6bf67e4206c46315e60e97d5274d93ea Mon Sep 17 00:00:00 2001 From: Riesi Date: Thu, 18 Aug 2022 12:13:49 +0200 Subject: [PATCH 0816/1348] [util] Limit King Of Fighters XIII to 60 FPS Game speed is tied to FPS fixes #2647 --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index fe5242b53..f6e325d51 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -577,6 +577,11 @@ namespace dxvk { { R"(\\BGE\.exe$)", {{ { "d3d9.maxFrameRate", "60" }, }} }, + /* King Of Fighters XIII * + * In-game speed increases on high FPS */ + { R"(\\kofxiii\.exe$)", {{ + { "d3d9.maxFrameRate", "60" }, + }} }, /* YS Origin * * Helps very bad frametimes in some areas */ { R"(\\yso_win\.exe$)", {{ From d9466eb2b99f210b1afc465d83bdfdc4b01e6cd5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 12 Sep 2022 16:00:36 +0200 Subject: [PATCH 0817/1348] [dxvk] Get rid of immutable sampler for resolve operations --- src/dxvk/dxvk_context.cpp | 2 +- src/dxvk/dxvk_meta_resolve.cpp | 24 ++----------------- src/dxvk/dxvk_meta_resolve.h | 4 ---- src/dxvk/shaders/dxvk_resolve_frag_d.frag | 4 +++- src/dxvk/shaders/dxvk_resolve_frag_ds.frag | 5 ++-- src/dxvk/shaders/dxvk_resolve_frag_f.frag | 4 +++- src/dxvk/shaders/dxvk_resolve_frag_f_amd.frag | 19 +++++++++++---- src/dxvk/shaders/dxvk_resolve_frag_i.frag | 4 +++- src/dxvk/shaders/dxvk_resolve_frag_u.frag | 4 +++- 9 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index a99659f21..b4215ddbb 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -4281,7 +4281,7 @@ namespace dxvk { descriptorWrites[i].dstSet = descriptorSet; descriptorWrites[i].dstBinding = i; descriptorWrites[i].descriptorCount = 1; - descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; descriptorWrites[i].pImageInfo = &descriptorImages[i]; } diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index 7e3dfd2e8..f611fbaf9 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -54,7 +54,6 @@ namespace dxvk { DxvkMetaResolveObjects::DxvkMetaResolveObjects(const DxvkDevice* device) : m_vkd (device->vkd()), - m_sampler (createSampler()), m_shaderFragF (device->features().amdShaderFragmentMask ? createShaderModule(dxvk_resolve_frag_f_amd) : createShaderModule(dxvk_resolve_frag_f)), @@ -87,8 +86,6 @@ namespace dxvk { m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderFragU, nullptr); m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderGeom, nullptr); m_vkd->vkDestroyShaderModule(m_vkd->device(), m_shaderVert, nullptr); - - m_vkd->vkDestroySampler(m_vkd->device(), m_sampler, nullptr); } @@ -115,23 +112,6 @@ namespace dxvk { } - VkSampler DxvkMetaResolveObjects::createSampler() const { - VkSamplerCreateInfo info = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; - info.magFilter = VK_FILTER_NEAREST; - info.minFilter = VK_FILTER_NEAREST; - info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; - - VkSampler result = VK_NULL_HANDLE; - if (m_vkd->vkCreateSampler(m_vkd->device(), &info, nullptr, &result) != VK_SUCCESS) - throw DxvkError("DxvkMetaResolveObjects: Failed to create sampler"); - return result; - } - - VkShaderModule DxvkMetaResolveObjects::createShaderModule( const SpirvCodeBuffer& code) const { VkShaderModuleCreateInfo info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; @@ -158,8 +138,8 @@ namespace dxvk { VkDescriptorSetLayout DxvkMetaResolveObjects::createDescriptorSetLayout( const DxvkMetaResolvePipelineKey& key) { std::array bindings = {{ - { 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, &m_sampler }, - { 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, &m_sampler }, + { 0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr }, + { 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr }, }}; VkDescriptorSetLayoutCreateInfo info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; diff --git a/src/dxvk/dxvk_meta_resolve.h b/src/dxvk/dxvk_meta_resolve.h index 5bf26301a..c481cee68 100644 --- a/src/dxvk/dxvk_meta_resolve.h +++ b/src/dxvk/dxvk_meta_resolve.h @@ -112,8 +112,6 @@ namespace dxvk { Rc m_vkd; - VkSampler m_sampler; - VkShaderModule m_shaderVert = VK_NULL_HANDLE; VkShaderModule m_shaderGeom = VK_NULL_HANDLE; VkShaderModule m_shaderFragF = VK_NULL_HANDLE; @@ -129,8 +127,6 @@ namespace dxvk { DxvkMetaResolvePipeline, DxvkHash, DxvkEq> m_pipelines; - VkSampler createSampler() const; - VkShaderModule createShaderModule( const SpirvCodeBuffer& code) const; diff --git a/src/dxvk/shaders/dxvk_resolve_frag_d.frag b/src/dxvk/shaders/dxvk_resolve_frag_d.frag index dd913bee9..70152d014 100644 --- a/src/dxvk/shaders/dxvk_resolve_frag_d.frag +++ b/src/dxvk/shaders/dxvk_resolve_frag_d.frag @@ -1,5 +1,7 @@ #version 450 +#extension GL_EXT_samplerless_texture_functions : enable + #define VK_RESOLVE_MODE_NONE (0) #define VK_RESOLVE_MODE_SAMPLE_ZERO_BIT (1 << 0) #define VK_RESOLVE_MODE_AVERAGE_BIT (1 << 1) @@ -9,7 +11,7 @@ layout(constant_id = 0) const int c_samples = 1; layout(constant_id = 1) const int c_mode_d = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; -layout(binding = 0) uniform sampler2DMSArray s_depth; +layout(binding = 0) uniform texture2DMSArray s_depth; layout(push_constant) uniform u_info_t { diff --git a/src/dxvk/shaders/dxvk_resolve_frag_ds.frag b/src/dxvk/shaders/dxvk_resolve_frag_ds.frag index 3c9564685..b92a03d71 100644 --- a/src/dxvk/shaders/dxvk_resolve_frag_ds.frag +++ b/src/dxvk/shaders/dxvk_resolve_frag_ds.frag @@ -1,6 +1,7 @@ #version 450 #extension GL_ARB_shader_stencil_export : enable +#extension GL_EXT_samplerless_texture_functions : enable #define VK_RESOLVE_MODE_NONE (0) #define VK_RESOLVE_MODE_SAMPLE_ZERO_BIT (1 << 0) @@ -12,8 +13,8 @@ layout(constant_id = 0) const int c_samples = 1; layout(constant_id = 1) const int c_mode_d = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; layout(constant_id = 2) const int c_mode_s = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; -layout(binding = 0) uniform sampler2DMSArray s_depth; -layout(binding = 1) uniform usampler2DMSArray s_stencil; +layout(binding = 0) uniform texture2DMSArray s_depth; +layout(binding = 1) uniform utexture2DMSArray s_stencil; layout(push_constant) uniform u_info_t { diff --git a/src/dxvk/shaders/dxvk_resolve_frag_f.frag b/src/dxvk/shaders/dxvk_resolve_frag_f.frag index 645a2f9bf..2c7442c14 100644 --- a/src/dxvk/shaders/dxvk_resolve_frag_f.frag +++ b/src/dxvk/shaders/dxvk_resolve_frag_f.frag @@ -1,8 +1,10 @@ #version 450 +#extension GL_EXT_samplerless_texture_functions : enable + layout(constant_id = 0) const int c_samples = 1; -layout(binding = 0) uniform sampler2DMSArray s_image; +layout(binding = 0) uniform texture2DMSArray s_image; layout(location = 0) out vec4 o_color; diff --git a/src/dxvk/shaders/dxvk_resolve_frag_f_amd.frag b/src/dxvk/shaders/dxvk_resolve_frag_f_amd.frag index a9cf9ee48..a550e3507 100644 --- a/src/dxvk/shaders/dxvk_resolve_frag_f_amd.frag +++ b/src/dxvk/shaders/dxvk_resolve_frag_f_amd.frag @@ -1,11 +1,20 @@ #version 450 -#extension GL_AMD_shader_fragment_mask: enable +#extension GL_EXT_samplerless_texture_functions : enable +#extension GL_EXT_spirv_intrinsics : enable + +// GL_AMD_shader_fragment_mask was never updated to support +// sampler-less functions, so we have to define these manually +spirv_instruction(extensions = ["SPV_AMD_shader_fragment_mask"], capabilities = [5010], id = 5011) +uint fragment_mask_fetch(texture2DMSArray tex, ivec3 coord); + +spirv_instruction(extensions = ["SPV_AMD_shader_fragment_mask"], capabilities = [5010], id = 5012) +vec4 fragment_fetch(texture2DMSArray tex, ivec3 coord, uint index); layout(constant_id = 0) const int c_samples = 1; layout(set = 0, binding = 0) -uniform sampler2DMSArray s_image; +uniform texture2DMSArray s_image; layout(location = 0) out vec4 o_color; @@ -18,7 +27,7 @@ void main() { ivec3 coord = ivec3(gl_FragCoord.xy + u_info.offset, gl_Layer); // get a four-bit fragment index for each sample - uint fragMask = fragmentMaskFetchAMD(s_image, coord); + uint fragMask = fragment_mask_fetch(s_image, coord); // count number of occurences of each fragment // index in one four-bit counter for each sample @@ -37,11 +46,11 @@ void main() { int fragIndex = findLSB(fragCount) >> 2; int fragShift = fragIndex << 2; - o_color += fragmentFetchAMD(s_image, coord, fragIndex) + o_color += fragment_fetch(s_image, coord, fragIndex) * float(bitfieldExtract(fragCount, fragShift, 4)); fragCount = bitfieldInsert(fragCount, 0, fragShift, 4); } o_color /= float(c_samples); -} \ No newline at end of file +} diff --git a/src/dxvk/shaders/dxvk_resolve_frag_i.frag b/src/dxvk/shaders/dxvk_resolve_frag_i.frag index 021980d64..a721897a5 100644 --- a/src/dxvk/shaders/dxvk_resolve_frag_i.frag +++ b/src/dxvk/shaders/dxvk_resolve_frag_i.frag @@ -1,6 +1,8 @@ #version 450 -layout(binding = 0) uniform isampler2DMSArray s_image; +#extension GL_EXT_samplerless_texture_functions : enable + +layout(binding = 0) uniform itexture2DMSArray s_image; layout(location = 0) out ivec4 o_color; diff --git a/src/dxvk/shaders/dxvk_resolve_frag_u.frag b/src/dxvk/shaders/dxvk_resolve_frag_u.frag index 3d3cfdf36..f7b4e73da 100644 --- a/src/dxvk/shaders/dxvk_resolve_frag_u.frag +++ b/src/dxvk/shaders/dxvk_resolve_frag_u.frag @@ -1,6 +1,8 @@ #version 450 -layout(binding = 0) uniform usampler2DMSArray s_image; +#extension GL_EXT_samplerless_texture_functions : enable + +layout(binding = 0) uniform utexture2DMSArray s_image; layout(location = 0) out uvec4 o_color; From 944a945822dd51c9c6aea19458614318b1b6fd97 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 12 Sep 2022 16:16:37 +0200 Subject: [PATCH 0818/1348] [dxvk] Fix validation error on FS resolve path --- src/dxvk/dxvk_meta_resolve.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dxvk/dxvk_meta_resolve.cpp b/src/dxvk/dxvk_meta_resolve.cpp index f611fbaf9..1f99cc0ab 100644 --- a/src/dxvk/dxvk_meta_resolve.cpp +++ b/src/dxvk/dxvk_meta_resolve.cpp @@ -237,8 +237,6 @@ namespace dxvk { iaState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; VkPipelineViewportStateCreateInfo vpState = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; - vpState.viewportCount = 1; - vpState.scissorCount = 1; VkPipelineRasterizationStateCreateInfo rsState = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; rsState.depthClampEnable = VK_TRUE; From 0502a0464f49bf7ba38c875a0b9b862a76cb4847 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 12 Sep 2022 22:05:21 +0200 Subject: [PATCH 0819/1348] [dxbc] Fix broken barrier around TGSM init code --- src/dxbc/dxbc_compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 036f88e3a..9d6eaa372 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -6087,7 +6087,7 @@ namespace dxvk { if (hasTgsm) { m_module.opControlBarrier( - m_module.constu32(spv::ScopeInvocation), + m_module.constu32(spv::ScopeWorkgroup), m_module.constu32(spv::ScopeWorkgroup), m_module.constu32(spv::MemorySemanticsWorkgroupMemoryMask | spv::MemorySemanticsAcquireReleaseMask)); From 05f36fd97b7187ae2e8336433ec02d340ef20855 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 12 Sep 2022 22:04:16 +0200 Subject: [PATCH 0820/1348] [dxbc] Only use workgroup scope in compute shaders Turns out that global barriers can be used in graphics shaders. --- src/dxbc/dxbc_compiler.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 9d6eaa372..53afe3451 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -2593,7 +2593,11 @@ namespace dxvk { } if (flags.test(DxbcSyncFlag::UavMemoryGlobal)) { - memoryScope = m_hasGloballyCoherentUav ? spv::ScopeQueueFamily : spv::ScopeWorkgroup; + memoryScope = spv::ScopeQueueFamily; + + if (m_programInfo.type() == DxbcProgramType::ComputeShader && !m_hasGloballyCoherentUav) + memoryScope = spv::ScopeWorkgroup; + memorySemantics |= spv::MemorySemanticsImageMemoryMask | spv::MemorySemanticsUniformMemoryMask | spv::MemorySemanticsAcquireReleaseMask From af208ceb9e7c785565cf16ccfe5efe88755e4a0b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 12 Sep 2022 22:33:40 +0200 Subject: [PATCH 0821/1348] [dxbc] Optimize write pattern for TGSM initialization Reduces bank conflicts. --- src/dxbc/dxbc_compiler.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 53afe3451..f145ef3de 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -6012,9 +6012,7 @@ namespace dxvk { bool hasTgsm = false; SpirvMemoryOperands memoryOperands; - memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask - | spv::MemoryAccessMakePointerAvailableMask; - memoryOperands.makeAvailable = m_module.constu32(spv::ScopeWorkgroup); + memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask; for (uint32_t i = 0; i < m_gRegs.size(); i++) { if (!m_gRegs[i].varId) @@ -6045,13 +6043,12 @@ namespace dxvk { uint32_t threadId = m_module.opLoad( intTypeId, m_cs.builtinLocalInvocationIndex); - uint32_t strideId = m_module.constu32(numElementsPerThread); + uint32_t strideId = m_module.constu32(numThreads); uint32_t zeroId = m_module.constu32(0); for (uint32_t e = 0; e < numElementsPerThread; e++) { - uint32_t ofsId = m_module.opIAdd(intTypeId, - m_module.opIMul(intTypeId, strideId, threadId), - m_module.constu32(e)); + uint32_t ofsId = m_module.opIAdd(intTypeId, threadId, + m_module.opIMul(intTypeId, strideId, m_module.constu32(e))); uint32_t ptrId = m_module.opAccessChain( ptrTypeId, m_gRegs[i].varId, 1, &ofsId); @@ -6094,7 +6091,9 @@ namespace dxvk { m_module.constu32(spv::ScopeWorkgroup), m_module.constu32(spv::ScopeWorkgroup), m_module.constu32(spv::MemorySemanticsWorkgroupMemoryMask - | spv::MemorySemanticsAcquireReleaseMask)); + | spv::MemorySemanticsAcquireReleaseMask + | spv::MemorySemanticsMakeAvailableMask + | spv::MemorySemanticsMakeVisibleMask)); } } From 21a521361e6c87ff77fa91a11d9df68f9ddac745 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 13 Sep 2022 15:30:13 +0200 Subject: [PATCH 0822/1348] [spirv] Remove OpKill helper This is deprecated, so make sure we never accidentally use it in the future. --- src/spirv/spirv_module.cpp | 6 ------ src/spirv/spirv_module.h | 2 -- 2 files changed, 8 deletions(-) diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 281c2af14..b90e1edce 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -3666,12 +3666,6 @@ namespace dxvk { } - void SpirvModule::opKill() { - m_code.putIns (spv::OpKill, 1); - m_blockId = 0; - } - - void SpirvModule::opDemoteToHelperInvocation() { m_code.putIns (spv::OpDemoteToHelperInvocation, 1); } diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index ecf3cce50..2113101bb 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -1252,8 +1252,6 @@ namespace dxvk { void opReturn(); - void opKill(); - void opDemoteToHelperInvocation(); void opEmitVertex( From 736f91fad1aeb3da7e40cdbd60c98a819ce3731f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 13 Sep 2022 18:41:16 +0100 Subject: [PATCH 0823/1348] [util] Add macro to determine CPU arch --- src/util/util_bit.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index 4acd9c23a..5ebfe032f 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -1,5 +1,16 @@ #pragma once +#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) + #define DXVK_ARCH_X86 + #if defined(__x86_64__) || defined(_M_X64) + #define DXVK_ARCH_X86_64 + #endif +#elif defined(__aarch64__) || defined(_M_ARM64) + #define DXVK_ARCH_ARM64 +#else +#error "Unknown CPU Architecture" +#endif + #ifndef _MSC_VER #if defined(__WINE__) && defined(__clang__) #pragma push_macro("_WIN32") From 466026632d23cafc45d1186c2a2f61e0eccaaf80 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 13 Sep 2022 18:41:53 +0100 Subject: [PATCH 0824/1348] [util] Only include x86 intrinsics headers on x86 --- src/util/util_bit.h | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index 5ebfe032f..490f745b9 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -11,17 +11,19 @@ #error "Unknown CPU Architecture" #endif -#ifndef _MSC_VER -#if defined(__WINE__) && defined(__clang__) -#pragma push_macro("_WIN32") -#undef _WIN32 -#endif -#include -#if defined(__WINE__) && defined(__clang__) -#pragma pop_macro("_WIN32") -#endif -#else -#include +#ifdef DXVK_ARCH_X86 + #ifndef _MSC_VER + #if defined(__WINE__) && defined(__clang__) + #pragma push_macro("_WIN32") + #undef _WIN32 + #endif + #include + #if defined(__WINE__) && defined(__clang__) + #pragma pop_macro("_WIN32") + #endif + #else + #include + #endif #endif #include "util_likely.h" From c3093b546ea984ad7a843f06dc3db81dc3f14d14 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 13 Sep 2022 18:42:14 +0100 Subject: [PATCH 0825/1348] [util] Implement tzcnt for non-x86 platforms --- src/util/util_bit.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index 490f745b9..0bc17b7c5 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -68,7 +68,7 @@ namespace dxvk::bit { return _tzcnt_u32(n); #elif defined(__BMI__) return __tzcnt_u32(n); - #elif defined(__GNUC__) || defined(__clang__) + #elif defined(DXVK_ARCH_X86) && (defined(__GNUC__) || defined(__clang__)) // tzcnt is encoded as rep bsf, so we can use it on all // processors, but the behaviour of zero inputs differs: // - bsf: zf = 1, cf = ?, result = ? @@ -85,6 +85,8 @@ namespace dxvk::bit { : "r" (n) : "cc"); return res; + #elif defined(__GNUC__) || defined(__clang__) + return n != 0 ? __builtin_ctz(n) : 32; #else uint32_t r = 31; n &= -n; @@ -98,11 +100,11 @@ namespace dxvk::bit { } inline uint32_t tzcnt(uint64_t n) { - #if defined(_M_X64) && defined(_MSC_VER) && !defined(__clang__) + #if defined(DXVK_ARCH_X86_64) && defined(_MSC_VER) && !defined(__clang__) return _tzcnt_u64(n); - #elif defined(__x86_64__) && defined(__BMI__) + #elif defined(DXVK_ARCH_X86_64) && defined(__BMI__) return __tzcnt_u64(n); - #elif defined(__x86_64__) && defined(__GNUC__) || defined(__clang__) + #elif defined(DXVK_ARCH_X86_64) && defined(__GNUC__) || defined(__clang__) uint64_t res; uint64_t tmp; asm ( @@ -114,6 +116,8 @@ namespace dxvk::bit { : "r" (n) : "cc"); return res; + #elif defined(__GNUC__) || defined(__clang__) + return n != 0 ? __builtin_ctzll(n) : 64; #else uint32_t lo = uint32_t(n); if (lo) { From 2d8e14fcf40c2e9156d88c6e76eaf166889c3640 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 13 Sep 2022 18:44:50 +0100 Subject: [PATCH 0826/1348] [util] Implement bcmpeq for non-x86 platforms --- src/util/util_bit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index 0bc17b7c5..21c0de2d4 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -177,7 +177,7 @@ namespace dxvk::bit { template bool bcmpeq(const T* a, const T* b) { static_assert(alignof(T) >= 16); - #if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) + #if defined(DXVK_ARCH_X86) && (defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)) auto ai = reinterpret_cast(a); auto bi = reinterpret_cast(b); From 57cee691b389fd426247b19b417066b59d1603a2 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 13 Sep 2022 18:46:40 +0100 Subject: [PATCH 0827/1348] [util] Implement replaceNaN for non-x86 platforms --- src/util/util_vector.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/util/util_vector.h b/src/util/util_vector.h index 43deeb922..ace6cde76 100644 --- a/src/util/util_vector.h +++ b/src/util/util_vector.h @@ -151,12 +151,18 @@ namespace dxvk { static_assert(sizeof(Vector4i) == sizeof(int) * 4); inline Vector4 replaceNaN(Vector4 a) { + #ifdef DXVK_ARCH_X86 Vector4 result; __m128 value = _mm_load_ps(a.data); __m128 mask = _mm_cmpeq_ps(value, value); value = _mm_and_ps(value, mask); _mm_store_ps(result.data, value); return result; + #else + for (int i = 0; i < 4; i++) + a[i] = std::isnan(a[i]) ? 0.0f : a[i]; + return a; + #endif } } From 2218462ff225670991b02eb696a7b222995ba3cf Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 13 Sep 2022 18:50:19 +0100 Subject: [PATCH 0828/1348] [util] Implement spin on ARM64 --- src/util/sync/sync_spinlock.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/util/sync/sync_spinlock.h b/src/util/sync/sync_spinlock.h index 27157929f..a04c79258 100644 --- a/src/util/sync/sync_spinlock.h +++ b/src/util/sync/sync_spinlock.h @@ -21,7 +21,13 @@ namespace dxvk::sync { void spin(uint32_t spinCount, const Fn& fn) { while (unlikely(!fn())) { for (uint32_t i = 1; i < spinCount; i++) { + #if defined(DXVK_ARCH_X86) _mm_pause(); + #elif defined(DXVK_ARCH_ARM64) + __asm__ __volatile__ ("yield"); + #else + #error "Pause/Yield not implemented for this architecture." + #endif if (fn()) return; } From 68c528d34525b637499e7e787e39b3d2b629488f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 13 Sep 2022 18:52:08 +0100 Subject: [PATCH 0829/1348] [util] Implement bitmask iterator on non-x86 platforms --- src/util/util_bit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index 21c0de2d4..d6832871b 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -353,7 +353,7 @@ namespace dxvk::bit { } uint32_t operator * () const { -#if (defined(__GNUC__) || defined(__clang__)) && !defined(__BMI__) +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__BMI__) && defined(DXVK_ARCH_X86) uint32_t res; asm ("tzcnt %1,%0" : "=r" (res) From 63ca34bb297fd0799618f968d7e9d72a4e02de11 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Tue, 13 Sep 2022 20:32:24 +0100 Subject: [PATCH 0830/1348] [dxbc] Fix forceVolatileTgsmAccess for stores Signed-off-by: Rhys Perry --- src/dxbc/dxbc_compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index f145ef3de..1a921de2a 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -5331,7 +5331,7 @@ namespace dxvk { } if (coherence) { - memoryOperands.flags = spv::MemoryAccessNonPrivatePointerMask; + memoryOperands.flags |= spv::MemoryAccessNonPrivatePointerMask; if (coherence != spv::ScopeInvocation) { memoryOperands.flags |= spv::MemoryAccessMakePointerAvailableMask; From 18a801de843931e96141bd789637540038268b99 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Tue, 13 Sep 2022 23:09:33 +0200 Subject: [PATCH 0831/1348] [dxso] Use a * (y - x) + x for lerp. Fixes Alice: Madness Returns. --- src/dxso/dxso_compiler.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index d80ad019e..6da68189c 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -1429,14 +1429,11 @@ namespace dxvk { if (m_moduleInfo.options.d3d9FloatEmulation != D3D9FloatEmulation::Strict) return {x.type, m_module.opFMix(typeId, x.id, y.id, a.id)}; - uint32_t oneId = m_module.constfReplicant(1.0f, a.type.ccount); + DxsoRegisterValue ySubx; + ySubx.type = x.type; + ySubx.id = m_module.opFSub(typeId, y.id, x.id); - DxsoRegisterValue revA; - revA.type = a.type; - revA.id = m_module.opFSub(typeId, oneId, a.id); - - DxsoRegisterValue xRevA = emitMul(x, revA); - return emitFma(a, y, xRevA); + return emitFma(a, ySubx, x); } From 2890f690f654e129ac55aeb6d027a558b41b1fed Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Wed, 14 Sep 2022 15:21:12 +0200 Subject: [PATCH 0832/1348] [meta] remove --with-d3d10 from readme --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 1b26173d9..9a5793361 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ This will **copy** the DLLs into the `system32` and `syswow64` directories of yo The setup script optionally takes the following arguments: - `--symlink`: Create symbolic links to the DLL files instead of copying them. This is especially useful for development. -- `--with-d3d10`: Install the `d3d10{_1}.dll` helper libraries. - `--without-dxgi`: Do not install DXVK's DXGI implementation and use the one provided by wine instead. Verify that your application uses DXVK instead of wined3d by checking for the presence of the log file `d3d9.log` or `d3d11.log` in the application's directory, or by enabling the HUD (see notes below). From 19b76825d0f8fb1c4c95f411c7880fa267d693ac Mon Sep 17 00:00:00 2001 From: Krzysztof Dobrowolski Date: Wed, 24 Aug 2022 11:29:16 +0200 Subject: [PATCH 0833/1348] [d3d9] Fix for missing restriction check in UpdateSurface. The spec of IDirect3DDevice9::UpdateSurface contains the following restriction: - Neither surface can be created with multisampling. The only valid flag for both surfaces is D3DMULTISAMPLE_NONE. This commit adds this check and returns D3DERR_INVALIDCALL when source or destination surfaces are multisampled. --- src/d3d9/d3d9_device.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index a90bc5e5b..cbe5404f2 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -746,6 +746,12 @@ namespace dxvk { if (unlikely(srcTextureInfo->Desc()->Format != dstTextureInfo->Desc()->Format)) return D3DERR_INVALIDCALL; + if (unlikely(srcTextureInfo->Desc()->MultiSample != D3DMULTISAMPLE_NONE)) + return D3DERR_INVALIDCALL; + + if (unlikely(dstTextureInfo->Desc()->MultiSample != D3DMULTISAMPLE_NONE)) + return D3DERR_INVALIDCALL; + const DxvkFormatInfo* formatInfo = lookupFormatInfo(dstTextureInfo->GetFormatMapping().FormatColor); VkOffset3D srcOffset = { 0u, 0u, 0u }; From 10d6e15646b45052c4ba0c238f17d592a25dfd48 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Wed, 14 Sep 2022 17:18:16 -0500 Subject: [PATCH 0834/1348] [d3d9] Do not set window size and position when restoring from fullscreen state Closes #2920. --- src/d3d9/d3d9_swapchain.cpp | 2 +- src/dxgi/dxgi_swapchain.cpp | 2 +- src/wsi/sdl2/wsi_window_sdl2.cpp | 5 +++-- src/wsi/win32/wsi_window_win32.cpp | 12 ++++++++---- src/wsi/wsi_window.h | 3 ++- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 634567d80..8e078cf40 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -1055,7 +1055,7 @@ namespace dxvk { ResetWindowProc(m_window); - if (!wsi::leaveFullscreenMode(m_window, &m_windowState)) { + if (!wsi::leaveFullscreenMode(m_window, &m_windowState, false)) { Logger::err("D3D9: LeaveFullscreenMode: Failed to exit fullscreen mode"); return D3DERR_NOTAVAILABLE; } diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 520700df0..df2823509 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -616,7 +616,7 @@ namespace dxvk { if (!wsi::isWindow(m_window)) return S_OK; - if (!wsi::leaveFullscreenMode(m_window, &m_windowState)) { + if (!wsi::leaveFullscreenMode(m_window, &m_windowState, true)) { Logger::err("DXGI: LeaveFullscreenMode: Failed to exit fullscreen mode"); return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; } diff --git a/src/wsi/sdl2/wsi_window_sdl2.cpp b/src/wsi/sdl2/wsi_window_sdl2.cpp index 7fbbb0ae2..a3b3247bd 100644 --- a/src/wsi/sdl2/wsi_window_sdl2.cpp +++ b/src/wsi/sdl2/wsi_window_sdl2.cpp @@ -101,7 +101,8 @@ namespace dxvk::wsi { bool leaveFullscreenMode( HWND hWindow, - DxvkWindowState* pState) { + DxvkWindowState* pState, + bool restoreCoordinates) { SDL_Window* window = fromHwnd(hWindow); if (SDL_SetWindowFullscreen(window, 0) != 0) { @@ -152,4 +153,4 @@ namespace dxvk::wsi { : VK_ERROR_OUT_OF_HOST_MEMORY; } -} \ No newline at end of file +} diff --git a/src/wsi/win32/wsi_window_win32.cpp b/src/wsi/win32/wsi_window_win32.cpp index ba52c06e9..94a228e35 100644 --- a/src/wsi/win32/wsi_window_win32.cpp +++ b/src/wsi/win32/wsi_window_win32.cpp @@ -198,7 +198,8 @@ namespace dxvk::wsi { bool leaveFullscreenMode( HWND hWindow, - DxvkWindowState* pState) { + DxvkWindowState* pState, + bool restoreCoordinates) { // Only restore the window style if the application hasn't // changed them. This is in line with what native DXGI does. LONG curStyle = ::GetWindowLongW(hWindow, GWL_STYLE) & ~WS_VISIBLE; @@ -211,11 +212,14 @@ namespace dxvk::wsi { } // Restore window position and apply the style + UINT flags = SWP_FRAMECHANGED | SWP_NOACTIVATE; const RECT rect = pState->rect; + + if (!restoreCoordinates) + flags |= SWP_NOSIZE | SWP_NOMOVE; ::SetWindowPos(hWindow, (pState->exstyle & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_NOTOPMOST, - rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, - SWP_FRAMECHANGED | SWP_NOACTIVATE); + rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, flags); return true; } @@ -285,4 +289,4 @@ namespace dxvk::wsi { vki->instance(), &info, nullptr, pSurface); } -} \ No newline at end of file +} diff --git a/src/wsi/wsi_window.h b/src/wsi/wsi_window.h index 9928b43d6..af4b23e51 100644 --- a/src/wsi/wsi_window.h +++ b/src/wsi/wsi_window.h @@ -73,7 +73,8 @@ namespace dxvk::wsi { */ bool leaveFullscreenMode( HWND hWindow, - DxvkWindowState* pState); + DxvkWindowState* pState, + bool restoreCoordinates); /** * \brief Restores the display mode if necessary From 1c33d8be1fa28035ccc6e0993a7621b4eef03b25 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 15 Sep 2022 15:35:54 +0200 Subject: [PATCH 0835/1348] [dxgi] Fix return value of ChangeDisplayMode --- src/dxgi/dxgi_swapchain.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index df2823509..678f3f69e 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -663,7 +663,10 @@ namespace dxvk { selectedMode1.Scaling = selectedMode.Scaling; selectedMode1.Stereo = false; - return wsi::setWindowMode(outputDesc.Monitor, m_window, ConvertDisplayMode(selectedMode1)); + if (!wsi::setWindowMode(outputDesc.Monitor, m_window, ConvertDisplayMode(selectedMode1))) + return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; + + return S_OK; } @@ -671,9 +674,10 @@ namespace dxvk { if (!hMonitor) return DXGI_ERROR_INVALID_CALL; - return wsi::restoreDisplayMode() - ? S_OK - : DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; + if (!wsi::restoreDisplayMode()) + return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; + + return S_OK; } From 3a6f8fa4139cfcd488a605ad0205f27e0db65c39 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 16 Sep 2022 06:10:06 +0000 Subject: [PATCH 0836/1348] [d3d11] Assign ForcedSampleCount to correct value in ApplyRasterizerSampleCount ForcedSampleCount was never being respected as it would always be replaced with 1 as it was being assigned to the wrong variable. This was also probably causing a bunch of redundant CS work as it was changing state that was dirty checked. --- src/d3d11/d3d11_context.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 6173068ef..26d8e5446 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3229,7 +3229,7 @@ namespace dxvk { if (unlikely(!m_state.om.sampleCount)) { pc.rasterizerSampleCount = m_state.rs.state->Desc()->ForcedSampleCount; - if (!m_state.om.sampleCount) + if (!pc.rasterizerSampleCount) pc.rasterizerSampleCount = 1; } From 699d56e35dc2944b6a224fed13e7f8941e89f8a9 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 16 Sep 2022 06:11:05 +0000 Subject: [PATCH 0837/1348] [d3d11] Handle nullptr RasterizerState in ApplyRasterizerSampleCount This broke as of a637134c56aea39ef031d9141224548df384269b is causing a crash in the BGFX d3d11 samples. --- src/d3d11/d3d11_context.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 26d8e5446..3c649c050 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3227,7 +3227,9 @@ namespace dxvk { pc.rasterizerSampleCount = m_state.om.sampleCount; if (unlikely(!m_state.om.sampleCount)) { - pc.rasterizerSampleCount = m_state.rs.state->Desc()->ForcedSampleCount; + pc.rasterizerSampleCount = m_state.rs.state + ? m_state.rs.state->Desc()->ForcedSampleCount + : 0; if (!pc.rasterizerSampleCount) pc.rasterizerSampleCount = 1; From 8758bcedae4cd95827acb801be0aba2ae3edc3f1 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 16 Sep 2022 06:42:52 +0000 Subject: [PATCH 0838/1348] [d3d11] Store private refs to context shaders --- src/d3d11/d3d11_context_state.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 8e67b53d3..d9564bb25 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -307,12 +307,12 @@ namespace dxvk { * \brief Context state */ struct D3D11ContextState { - Com vs; - Com hs; - Com ds; - Com gs; - Com ps; - Com cs; + Com vs; + Com hs; + Com ds; + Com gs; + Com ps; + Com cs; D3D11ContextStateID id; D3D11ContextStateIA ia; From 241922645698e5036fc8ec44ad03f60b0be2b467 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 16 Sep 2022 06:44:02 +0000 Subject: [PATCH 0839/1348] [d3d11] Store private refs for constant buffer bindings --- src/d3d11/d3d11_context_state.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index d9564bb25..54c2692de 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -51,7 +51,7 @@ namespace dxvk { * as well as the range that is actually bound to the context. */ struct D3D11ConstantBufferBinding { - Com buffer = nullptr; + Com buffer = nullptr; UINT constantOffset = 0; UINT constantCount = 0; UINT constantBound = 0; From 9bfe46ac508d4022dd83656cf9748c94990d3814 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 16 Sep 2022 06:50:43 +0000 Subject: [PATCH 0840/1348] [d3d11] Store private refs for srv and rtv bindings --- src/d3d11/d3d11_context_state.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 54c2692de..8e7a21360 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -79,7 +79,7 @@ namespace dxvk { * set of views that are potentially hazardous. */ struct D3D11ShaderStageSrvBinding { - std::array, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> views = { }; + std::array, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT> views = { }; DxvkBindingSet hazardous = { }; uint32_t maxCount = 0; @@ -121,7 +121,7 @@ namespace dxvk { * Stores bound UAVs. For compute shader UAVs, * we also store a bit mask of bound UAVs. */ - using D3D11ShaderStageUavBinding = std::array, D3D11_1_UAV_SLOT_COUNT>; + using D3D11ShaderStageUavBinding = std::array, D3D11_1_UAV_SLOT_COUNT>; struct D3D11UavBindings { D3D11ShaderStageUavBinding views = { }; From 95452815428f9df6e1cdab9bb8104ad92f5ea154 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 16 Sep 2022 06:51:51 +0000 Subject: [PATCH 0841/1348] [d3d11] Store private refs for VB + IB bindings --- src/d3d11/d3d11_context_state.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 8e7a21360..e8b2deffb 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -145,15 +145,15 @@ namespace dxvk { * input layout, and the dynamic primitive topology. */ struct D3D11VertexBufferBinding { - Com buffer = nullptr; - UINT offset = 0; - UINT stride = 0; + Com buffer = nullptr; + UINT offset = 0; + UINT stride = 0; }; struct D3D11IndexBufferBinding { - Com buffer = nullptr; - UINT offset = 0; - DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + Com buffer = nullptr; + UINT offset = 0; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; }; struct D3D11ContextStateIA { From ca38cebe0b4a1e78dfb425bc140c1e51ca3a0234 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 16 Sep 2022 06:53:58 +0000 Subject: [PATCH 0842/1348] [d3d11] Store private refs for IA layout --- src/d3d11/d3d11_context_state.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index e8b2deffb..055d15101 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -157,8 +157,8 @@ namespace dxvk { }; struct D3D11ContextStateIA { - Com inputLayout = nullptr; - D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + Com inputLayout = nullptr; + D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; std::array vertexBuffers = { }; D3D11IndexBufferBinding indexBuffer = { }; From b40935a48daddb193fa4832c85bf343057eec15f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 16 Sep 2022 10:03:50 +0000 Subject: [PATCH 0843/1348] [d3d11] Store context state ID buffers as private refs --- src/d3d11/d3d11_context_state.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index 055d15101..df641fd2a 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -232,8 +232,8 @@ namespace dxvk { * argument and draw count buffer. */ struct D3D11ContextStateID { - Com argBuffer = nullptr; - Com cntBuffer = nullptr; + Com argBuffer = nullptr; + Com cntBuffer = nullptr; void reset() { argBuffer = nullptr; From 9e4877be81ead5a232df75eaac2f5908d18ef93c Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 16 Sep 2022 10:05:15 +0000 Subject: [PATCH 0844/1348] [d3d11] Store SoTarget buffer as a private ref --- src/d3d11/d3d11_context_state.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index df641fd2a..af478aaae 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -275,8 +275,8 @@ namespace dxvk { * Stores stream output buffers with offset. */ struct D3D11ContextSoTarget { - Com buffer = nullptr; - UINT offset = 0; + Com buffer = nullptr; + UINT offset = 0; }; struct D3D11ContextStateSO { From a69c65265ab6ce6a798f1fa9bd524f32d2cf7b7d Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 16 Sep 2022 10:05:40 +0000 Subject: [PATCH 0845/1348] [d3d11] Store context predication query as private ref --- src/d3d11/d3d11_context_state.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h index af478aaae..fd48d8ee4 100644 --- a/src/d3d11/d3d11_context_state.h +++ b/src/d3d11/d3d11_context_state.h @@ -294,8 +294,8 @@ namespace dxvk { * Stores predication info. */ struct D3D11ContextStatePR { - Com predicateObject = nullptr; - BOOL predicateValue = false; + Com predicateObject = nullptr; + BOOL predicateValue = false; void reset() { predicateObject = nullptr; From 000a647c569f89279fba22e507d3ee746576bf40 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 16 Sep 2022 10:08:40 +0000 Subject: [PATCH 0846/1348] [d3d11] Store D3D11DeviceContextState as private ref Avoids a circular dependency --- src/d3d11/d3d11_context_imm.cpp | 4 ++-- src/d3d11/d3d11_context_imm.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index f5e436621..1558ce6fa 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -743,8 +743,8 @@ namespace dxvk { // Reset all state affected by the current context state ResetCommandListState(); - Com oldState = std::move(m_stateObject); - Com newState = static_cast(pState); + Com oldState = std::move(m_stateObject); + Com newState = static_cast(pState); if (oldState == nullptr) oldState = new D3D11DeviceContextState(m_parent); diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index b00a81118..49872be2d 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -101,7 +101,8 @@ namespace dxvk { D3D10Multithread m_multithread; D3D11VideoContext m_videoContext; - Com m_stateObject; + + Com m_stateObject; HRESULT MapBuffer( D3D11Buffer* pResource, From c1ab09a048f503cbdc2ce5ced3ea4461a040e8f6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 15 Sep 2022 13:41:03 +0200 Subject: [PATCH 0847/1348] [util] Move platform-specific sleep code to dedicated helper class --- src/util/meson.build | 1 + src/util/util_fps_limiter.cpp | 94 +------------------------ src/util/util_fps_limiter.h | 20 ------ src/util/util_sleep.cpp | 125 ++++++++++++++++++++++++++++++++++ src/util/util_sleep.h | 78 +++++++++++++++++++++ 5 files changed, 206 insertions(+), 112 deletions(-) create mode 100644 src/util/util_sleep.cpp create mode 100644 src/util/util_sleep.h diff --git a/src/util/meson.build b/src/util/meson.build index 50044a00b..55f4482a4 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -6,6 +6,7 @@ util_src = files([ 'util_luid.cpp', 'util_matrix.cpp', 'util_shared_res.cpp', + 'util_sleep.cpp', 'thread.cpp', diff --git a/src/util/util_fps_limiter.cpp b/src/util/util_fps_limiter.cpp index 1bddcd410..8bec7b523 100644 --- a/src/util/util_fps_limiter.cpp +++ b/src/util/util_fps_limiter.cpp @@ -3,6 +3,7 @@ #include "thread.h" #include "util_env.h" #include "util_fps_limiter.h" +#include "util_sleep.h" #include "util_string.h" #include "./log/log.h" @@ -63,7 +64,7 @@ namespace dxvk { // Don't call sleep if the amount of time to sleep is shorter // than the time the function calls are likely going to take TimerDuration sleepDuration = m_targetInterval - m_deviation - frameTime; - t1 = sleep(t1, sleepDuration); + t1 = Sleep::sleepFor(t1, sleepDuration); // Compensate for any sleep inaccuracies in the next frame, and // limit cumulative deviation in order to avoid stutter in case we @@ -77,100 +78,9 @@ namespace dxvk { } - FpsLimiter::TimePoint FpsLimiter::sleep(TimePoint t0, TimerDuration duration) { - if (duration <= TimerDuration::zero()) - return t0; - - // On wine, we can rely on NtDelayExecution waiting for more or - // less exactly the desired amount of time, and we want to avoid - // spamming QueryPerformanceCounter for performance reasons. - // On Windows, we busy-wait for the last couple of milliseconds - // since sleeping is highly inaccurate and inconsistent. - TimerDuration sleepThreshold = m_sleepThreshold; - - if (m_sleepGranularity != TimerDuration::zero()) - sleepThreshold += duration / 6; - - TimerDuration remaining = duration; - TimePoint t1 = t0; - - while (remaining > sleepThreshold) { - TimerDuration sleepDuration = remaining - sleepThreshold; - - performSleep(sleepDuration); - - t1 = dxvk::high_resolution_clock::now(); - remaining -= std::chrono::duration_cast(t1 - t0); - t0 = t1; - } - - // Busy-wait until we have slept long enough - while (remaining > TimerDuration::zero()) { - t1 = dxvk::high_resolution_clock::now(); - remaining -= std::chrono::duration_cast(t1 - t0); - t0 = t1; - } - - return t1; - } - - void FpsLimiter::initialize() { - updateSleepGranularity(); - m_sleepThreshold = 4 * m_sleepGranularity; m_lastFrame = dxvk::high_resolution_clock::now(); m_initialized = true; } - - void FpsLimiter::updateSleepGranularity() { -#ifdef _WIN32 - HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll"); - - if (ntdll) { - NtDelayExecution = reinterpret_cast( - ::GetProcAddress(ntdll, "NtDelayExecution")); - auto NtQueryTimerResolution = reinterpret_cast( - ::GetProcAddress(ntdll, "NtQueryTimerResolution")); - auto NtSetTimerResolution = reinterpret_cast( - ::GetProcAddress(ntdll, "NtSetTimerResolution")); - - ULONG min, max, cur; - - // Wine's implementation of these functions is a stub as of 6.10, which is fine - // since it uses select() in NtDelayExecution. This is only relevant for Windows. - if (NtQueryTimerResolution && !NtQueryTimerResolution(&min, &max, &cur)) { - m_sleepGranularity = TimerDuration(cur); - - if (NtSetTimerResolution && !NtSetTimerResolution(max, TRUE, &cur)) { - Logger::info(str::format("Setting timer interval to ", (double(max) / 10.0), " us")); - m_sleepGranularity = TimerDuration(max); - } - } - } else { - // Assume 1ms sleep granularity by default - m_sleepGranularity = TimerDuration(1ms); - } -#else - // Assume 0.5ms sleep granularity by default - m_sleepGranularity = TimerDuration(500us); -#endif - } - - - void FpsLimiter::performSleep(TimerDuration sleepDuration) { -#ifdef _WIN32 - if (NtDelayExecution) { - LARGE_INTEGER ticks; - ticks.QuadPart = -sleepDuration.count(); - - NtDelayExecution(FALSE, &ticks); - } else { - std::this_thread::sleep_for(sleepDuration); - } -#else - std::this_thread::sleep_for(sleepDuration); -#endif - } - } diff --git a/src/util/util_fps_limiter.h b/src/util/util_fps_limiter.h index 0d2d63258..e75cbc706 100644 --- a/src/util/util_fps_limiter.h +++ b/src/util/util_fps_limiter.h @@ -49,18 +49,7 @@ namespace dxvk { private: using TimePoint = dxvk::high_resolution_clock::time_point; - -#ifdef _WIN32 - // On Windows, we use NtDelayExecution which has units of 100ns. - using TimerDuration = std::chrono::duration>; - using NtQueryTimerResolutionProc = UINT (WINAPI *) (ULONG*, ULONG*, ULONG*); - using NtSetTimerResolutionProc = UINT (WINAPI *) (ULONG, BOOL, ULONG*); - using NtDelayExecutionProc = UINT (WINAPI *) (BOOL, LARGE_INTEGER*); - NtDelayExecutionProc NtDelayExecution = nullptr; -#else - // On other platforms, we use the std library, which calls through to nanosleep -- which is ns. using TimerDuration = std::chrono::nanoseconds; -#endif dxvk::mutex m_mutex; @@ -71,17 +60,8 @@ namespace dxvk { bool m_initialized = false; bool m_envOverride = false; - TimerDuration m_sleepGranularity = TimerDuration::zero(); - TimerDuration m_sleepThreshold = TimerDuration::zero(); - - TimePoint sleep(TimePoint t0, TimerDuration duration); - void initialize(); - void updateSleepGranularity(); - - void performSleep(TimerDuration sleepDuration); - }; } diff --git a/src/util/util_sleep.cpp b/src/util/util_sleep.cpp new file mode 100644 index 000000000..b50b65e65 --- /dev/null +++ b/src/util/util_sleep.cpp @@ -0,0 +1,125 @@ +#include "util_sleep.h" +#include "util_string.h" + +#include "./log/log.h" + +using namespace std::chrono_literals; + +namespace dxvk { + + Sleep Sleep::s_instance; + + + Sleep::Sleep() { + + } + + + Sleep::~Sleep() { + + } + + + void Sleep::initialize() { + std::lock_guard lock(m_mutex); + + if (m_initialized.load()) + return; + + initializePlatformSpecifics(); + m_sleepThreshold = 4 * m_sleepGranularity; + + m_initialized.store(true, std::memory_order_release); + } + + + void Sleep::initializePlatformSpecifics() { +#ifdef _WIN32 + HMODULE ntdll = ::GetModuleHandleW(L"ntdll.dll"); + + if (ntdll) { + NtDelayExecution = reinterpret_cast( + ::GetProcAddress(ntdll, "NtDelayExecution")); + auto NtQueryTimerResolution = reinterpret_cast( + ::GetProcAddress(ntdll, "NtQueryTimerResolution")); + auto NtSetTimerResolution = reinterpret_cast( + ::GetProcAddress(ntdll, "NtSetTimerResolution")); + + ULONG min, max, cur; + + // Wine's implementation of these functions is a stub as of 6.10, which is fine + // since it uses select() in NtDelayExecution. This is only relevant for Windows. + if (NtQueryTimerResolution && !NtQueryTimerResolution(&min, &max, &cur)) { + m_sleepGranularity = TimerDuration(cur); + + if (NtSetTimerResolution && !NtSetTimerResolution(max, TRUE, &cur)) { + Logger::info(str::format("Setting timer interval to ", (double(max) / 10.0), " us")); + m_sleepGranularity = TimerDuration(max); + } + } + } else { + // Assume 1ms sleep granularity by default + m_sleepGranularity = TimerDuration(1ms); + } +#else + // Assume 0.5ms sleep granularity by default + m_sleepGranularity = TimerDuration(500us); +#endif + } + + + Sleep::TimePoint Sleep::sleep(TimePoint t0, TimerDuration duration) { + if (duration <= TimerDuration::zero()) + return t0; + + // If necessary, initialize function pointers and some values + if (!m_initialized.load(std::memory_order_acquire)) + initialize(); + + // Busy-wait for the last couple of milliseconds since sleeping + // on Windows is highly inaccurate and inconsistent. + TimerDuration sleepThreshold = m_sleepThreshold; + + if (m_sleepGranularity != TimerDuration::zero()) + sleepThreshold += duration / 6; + + TimerDuration remaining = duration; + TimePoint t1 = t0; + + while (remaining > sleepThreshold) { + TimerDuration sleepDuration = remaining - sleepThreshold; + + systemSleep(sleepDuration); + + t1 = dxvk::high_resolution_clock::now(); + remaining -= std::chrono::duration_cast(t1 - t0); + t0 = t1; + } + + // Busy-wait until we have slept long enough + while (remaining > TimerDuration::zero()) { + t1 = dxvk::high_resolution_clock::now(); + remaining -= std::chrono::duration_cast(t1 - t0); + t0 = t1; + } + + return t1; + } + + + void Sleep::systemSleep(TimerDuration duration) { +#ifdef _WIN32 + if (NtDelayExecution) { + LARGE_INTEGER ticks; + ticks.QuadPart = -duration.count(); + + NtDelayExecution(FALSE, &ticks); + } else { + std::this_thread::sleep_for(duration); + } +#else + std::this_thread::sleep_for(duration); +#endif + } + +} diff --git a/src/util/util_sleep.h b/src/util/util_sleep.h new file mode 100644 index 000000000..dc7fe0fca --- /dev/null +++ b/src/util/util_sleep.h @@ -0,0 +1,78 @@ +#pragma once + +#include "thread.h" +#include "util_time.h" + +namespace dxvk { + + /** + * \brief Utility class for accurate sleeping + */ + class Sleep { + + public: + + using TimePoint = dxvk::high_resolution_clock::time_point; + + ~Sleep(); + + /** + * \brief Sleeps for a given period of time + * + * \param [in] t0 Current time + * \param [in] duration Sleep duration + * \returns Time after sleep has finished + */ + template + static TimePoint sleepFor(TimePoint t0, std::chrono::duration duration) { + return s_instance.sleep(t0, std::chrono::duration_cast(duration)); + } + + /** + * \brief Sleeps until a given time point + * + * Convenience function that sleeps for the + * time difference between t1 and t0. + * \param [in] t0 Current time + * \param [in] t1 Target time + * \returns Time after sleep has finished + */ + static TimePoint sleepUntil(TimePoint t0, TimePoint t1) { + return sleepFor(t0, t1 - t0); + } + + private: + + static Sleep s_instance; + + std::mutex m_mutex; + std::atomic m_initialized = { false }; + +#ifdef _WIN32 + // On Windows, we use NtDelayExecution which has units of 100ns. + using TimerDuration = std::chrono::duration>; + using NtQueryTimerResolutionProc = UINT (WINAPI *) (ULONG*, ULONG*, ULONG*); + using NtSetTimerResolutionProc = UINT (WINAPI *) (ULONG, BOOL, ULONG*); + using NtDelayExecutionProc = UINT (WINAPI *) (BOOL, LARGE_INTEGER*); + NtDelayExecutionProc NtDelayExecution = nullptr; +#else + // On other platforms, we use the std library, which calls through to nanosleep -- which is ns. + using TimerDuration = std::chrono::nanoseconds; +#endif + + TimerDuration m_sleepGranularity = TimerDuration::zero(); + TimerDuration m_sleepThreshold = TimerDuration::zero(); + + Sleep(); + + void initialize(); + + void initializePlatformSpecifics(); + + TimePoint sleep(TimePoint t0, TimerDuration duration); + + void systemSleep(TimerDuration duration); + + }; + +} From e019edc8c3f8a422d7e9f3c63c39fda059997771 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 15 Sep 2022 14:55:59 +0200 Subject: [PATCH 0848/1348] [util] Add helper to get time point from raw counter value --- src/util/util_time.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/util/util_time.h b/src/util/util_time.h index 625b2b508..bcc311b6b 100644 --- a/src/util/util_time.h +++ b/src/util/util_time.h @@ -19,9 +19,12 @@ namespace dxvk { using time_point = std::chrono::time_point; static inline time_point now() noexcept { + return get_time_from_counter(get_counter()); + } + + static inline time_point get_time_from_counter(int64_t counter) { // Keep the frequency static, this doesn't change at all. static const int64_t freq = get_frequency(); - const int64_t counter = get_counter(); const int64_t whole = (counter / freq) * period::den; const int64_t part = (counter % freq) * period::den / freq; @@ -45,12 +48,16 @@ namespace dxvk { }; #else struct high_resolution_clock : public std::chrono::high_resolution_clock { + static inline time_point get_time_from_counter(int64_t counter) { + return time_point() + duration(counter); + } + static inline int64_t get_frequency() { return period::den; } static inline int64_t get_counter() { - return dxvk::high_resolution_clock::now().time_since_epoch().count(); + return now().time_since_epoch().count(); } }; #endif From 3543673c5c6cb3ecdccfdce4fe92e2d971622cbc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 15 Sep 2022 14:56:17 +0200 Subject: [PATCH 0849/1348] [util] Add helper to compute display refresh related stuff --- src/util/util_misc.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/util/util_misc.h b/src/util/util_misc.h index 6fb41f155..105f0507e 100644 --- a/src/util/util_misc.h +++ b/src/util/util_misc.h @@ -12,4 +12,32 @@ namespace dxvk { rgba[2] = (float)((color & 0x000000ff)) / 255.0f; } + /** + * \brief Computes refresh period for a given display refresh rate + * + * \param [in] numerator Numerator of refresh rate + * \param [in] denominator Denominator of refresh rate + * \returns Refresh period, in nanoseconds + */ + inline auto computeRefreshPeriod(uint64_t numerator, uint64_t denominator) { + using unit = std::chrono::nanoseconds; + unit::rep ns = unit::rep(unit::period::den * denominator) + / unit::rep(unit::period::num * numerator); + return unit(ns); + } + + /** + * \brief Computes refresh count within a given time period + * + * \param [in] t0 Start time + * \param [in] t1 End time + * \param [in] refreshPeriod Refresh period + * \returns Number of refreshes between t1 and t0 + */ + template + uint64_t computeRefreshCount(TimePoint t0, TimePoint t1, Duration refreshPeriod) { + auto duration = std::chrono::duration_cast(t1 - t0); + return duration.count() / refreshPeriod.count(); + } + } \ No newline at end of file From c56a9b5a3f1617a938d7c31043ee65c144864f55 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 15 Sep 2022 14:57:03 +0200 Subject: [PATCH 0850/1348] [dxgi] Implement WaitForVBlank using new sleep helper Not very accurate, but probably good enough if the display refresh rate is known. --- src/dxgi/dxgi_interfaces.h | 3 +++ src/dxgi/dxgi_output.cpp | 40 ++++++++++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index f7a939503..fc94dd858 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -2,6 +2,8 @@ #include "../dxvk/dxvk_include.h" +#include "../util/util_time.h" + #include "dxgi_format.h" #include "dxgi_include.h" @@ -24,6 +26,7 @@ struct DXGI_VK_MONITOR_DATA { dxvk::DxgiSwapChain* pSwapChain; DXGI_FRAME_STATISTICS FrameStats; DXGI_GAMMA_CONTROL GammaCurve; + DXGI_MODE_DESC1 LastMode; }; diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index 570282cfc..6f2cc98c6 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -14,6 +14,10 @@ #include "../dxvk/dxvk_format.h" +#include "../util/util_misc.h" +#include "../util/util_sleep.h" +#include "../util/util_time.h" + namespace dxvk { DxgiOutput::DxgiOutput( @@ -23,12 +27,16 @@ namespace dxvk { : m_monitorInfo(factory->GetMonitorInfo()), m_adapter(adapter), m_monitor(monitor) { + // Query current display mode + wsi::WsiMode activeWsiMode = { }; + wsi::getCurrentDisplayMode(m_monitor, &activeWsiMode); + // Init monitor info if necessary - DXGI_VK_MONITOR_DATA monitorData; - monitorData.pSwapChain = nullptr; - monitorData.FrameStats = DXGI_FRAME_STATISTICS(); + DXGI_VK_MONITOR_DATA monitorData = { }; + monitorData.FrameStats.SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter(); monitorData.GammaCurve.Scale = { 1.0f, 1.0f, 1.0f }; monitorData.GammaCurve.Offset = { 0.0f, 0.0f, 0.0f }; + monitorData.LastMode = ConvertDisplayMode(activeWsiMode); for (uint32_t i = 0; i < DXGI_VK_GAMMA_CP_COUNT; i++) { const float value = GammaControlPointLocation(i); @@ -443,7 +451,31 @@ namespace dxvk { static bool s_errorShown = false; if (!std::exchange(s_errorShown, true)) - Logger::warn("DxgiOutput::WaitForVBlank: Stub"); + Logger::warn("DxgiOutput::WaitForVBlank: Inaccurate"); + + // Get monitor data to compute the sleep duration + DXGI_VK_MONITOR_DATA* monitorInfo = nullptr; + HRESULT hr = m_monitorInfo->AcquireMonitorData(m_monitor, &monitorInfo); + + if (FAILED(hr)) + return hr; + + // Estimate number of vblanks since last mode + // change, then wait for one more refresh period + auto refreshPeriod = computeRefreshPeriod( + monitorInfo->LastMode.RefreshRate.Numerator, + monitorInfo->LastMode.RefreshRate.Denominator); + + auto t0 = dxvk::high_resolution_clock::get_time_from_counter(monitorInfo->FrameStats.SyncQPCTime.QuadPart); + auto t1 = dxvk::high_resolution_clock::now(); + + uint64_t vblankCount = computeRefreshCount(t0, t1, refreshPeriod); + auto t2 = t0 + (vblankCount + 1) * refreshPeriod; + + m_monitorInfo->ReleaseMonitorData(); + + // Sleep until the given time point + Sleep::sleepUntil(t1, t2); return S_OK; } From 57af9e8760bd45c2c4f14212a929be71d46c1ca5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 15 Sep 2022 14:58:31 +0200 Subject: [PATCH 0851/1348] [dxgi] Estimate vblank count for frame statistics --- src/dxgi/dxgi_output.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index 6f2cc98c6..23ef7369c 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -370,9 +370,26 @@ namespace dxvk { static bool s_errorShown = false; if (!std::exchange(s_errorShown, true)) - Logger::warn("DxgiOutput::GetFrameStatistics: Stub"); + Logger::warn("DxgiOutput::GetFrameStatistics: Frame statistics may be inaccurate"); + + // Estimate vblank count based on last known display mode. Querying + // the display mode on every call would be prohibitively expensive. + auto refreshPeriod = computeRefreshPeriod( + monitorInfo->LastMode.RefreshRate.Numerator, + monitorInfo->LastMode.RefreshRate.Denominator); + + // We don't really have a way to query time since boot + auto t1Counter = dxvk::high_resolution_clock::get_counter(); + + auto t0 = dxvk::high_resolution_clock::get_time_from_counter(monitorInfo->FrameStats.SyncQPCTime.QuadPart); + auto t1 = dxvk::high_resolution_clock::get_time_from_counter(t1Counter); + + pStats->PresentCount = monitorInfo->FrameStats.PresentCount; + pStats->PresentRefreshCount = monitorInfo->FrameStats.PresentRefreshCount; + pStats->SyncRefreshCount = monitorInfo->FrameStats.SyncRefreshCount + computeRefreshCount(t0, t1, refreshPeriod); + pStats->SyncQPCTime.QuadPart = t1Counter; + pStats->SyncGPUTime.QuadPart = 0; - *pStats = monitorInfo->FrameStats; m_monitorInfo->ReleaseMonitorData(); return S_OK; } From faaa6bf1df372084bad372ef2230c3b38fd830a7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 15 Sep 2022 15:30:07 +0200 Subject: [PATCH 0852/1348] [dxgi] Promote output stored in swap chain to IDXGIOutput1 --- src/dxgi/dxgi_swapchain.cpp | 93 +++++++++++++++++++++---------------- src/dxgi/dxgi_swapchain.h | 10 ++-- 2 files changed, 58 insertions(+), 45 deletions(-) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 678f3f69e..22172b39b 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -94,12 +94,19 @@ namespace dxvk { if (!wsi::isWindow(m_window)) return DXGI_ERROR_INVALID_CALL; - if (m_target != nullptr) { - *ppOutput = m_target.ref(); - return S_OK; + Com output; + + if (m_target == nullptr) { + HRESULT hr = GetOutputFromMonitor(wsi::getWindowMonitor(m_window), &output); + + if (FAILED(hr)) + return hr; + } else { + output = m_target; } - return GetOutputFromMonitor(wsi::getWindowMonitor(m_window), ppOutput); + *ppOutput = output.ref(); + return S_OK; } @@ -322,26 +329,35 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiSwapChain::ResizeTarget(const DXGI_MODE_DESC* pNewTargetParameters) { std::lock_guard lock(m_lockWindow); - if (pNewTargetParameters == nullptr) + if (!pNewTargetParameters) return DXGI_ERROR_INVALID_CALL; if (!wsi::isWindow(m_window)) return DXGI_ERROR_INVALID_CALL; + // Promote display mode + DXGI_MODE_DESC1 newDisplayMode = { }; + newDisplayMode.Width = pNewTargetParameters->Width; + newDisplayMode.Height = pNewTargetParameters->Height; + newDisplayMode.RefreshRate = pNewTargetParameters->RefreshRate; + newDisplayMode.Format = pNewTargetParameters->Format; + newDisplayMode.ScanlineOrdering = pNewTargetParameters->ScanlineOrdering; + newDisplayMode.Scaling = pNewTargetParameters->Scaling; + // Update the swap chain description - if (pNewTargetParameters->RefreshRate.Numerator != 0) - m_descFs.RefreshRate = pNewTargetParameters->RefreshRate; + if (newDisplayMode.RefreshRate.Numerator != 0) + m_descFs.RefreshRate = newDisplayMode.RefreshRate; - m_descFs.ScanlineOrdering = pNewTargetParameters->ScanlineOrdering; - m_descFs.Scaling = pNewTargetParameters->Scaling; + m_descFs.ScanlineOrdering = newDisplayMode.ScanlineOrdering; + m_descFs.Scaling = newDisplayMode.Scaling; if (m_descFs.Windowed) { wsi::resizeWindow( m_window, &m_windowState, - pNewTargetParameters->Width, - pNewTargetParameters->Height); + newDisplayMode.Width, + newDisplayMode.Height); } else { - Com output; + Com output; if (FAILED(GetOutputFromMonitor(m_monitor, &output))) { Logger::err("DXGI: ResizeTarget: Failed to query containing output"); @@ -350,7 +366,7 @@ namespace dxvk { // If the swap chain allows it, change the display mode if (m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH) { - ChangeDisplayMode(output.ptr(), pNewTargetParameters); + ChangeDisplayMode(output.ptr(), &newDisplayMode); NotifyModeChange(m_monitor, FALSE); } @@ -369,8 +385,13 @@ namespace dxvk { if (!Fullscreen && pTarget) return DXGI_ERROR_INVALID_CALL; + Com target; + + if (pTarget) + pTarget->QueryInterface(IID_PPV_ARGS(&target)); + if (m_descFs.Windowed && Fullscreen) - return this->EnterFullscreenMode(pTarget); + return this->EnterFullscreenMode(target.ptr()); else if (!m_descFs.Windowed && !Fullscreen) return this->LeaveFullscreenMode(); @@ -528,14 +549,14 @@ namespace dxvk { } - HRESULT DxgiSwapChain::EnterFullscreenMode(IDXGIOutput* pTarget) { - Com output = pTarget; + HRESULT DxgiSwapChain::EnterFullscreenMode(IDXGIOutput1* pTarget) { + Com output = pTarget; if (!wsi::isWindow(m_window)) return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; if (output == nullptr) { - if (FAILED(GetContainingOutput(&output))) { + if (FAILED(GetOutputFromMonitor(wsi::getWindowMonitor(m_window), &output))) { Logger::err("DXGI: EnterFullscreenMode: Cannot query containing output"); return E_FAIL; } @@ -544,7 +565,7 @@ namespace dxvk { const bool modeSwitch = m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; if (modeSwitch) { - DXGI_MODE_DESC displayMode; + DXGI_MODE_DESC1 displayMode = { }; displayMode.Width = m_desc.Width; displayMode.Height = m_desc.Height; displayMode.RefreshRate = m_descFs.RefreshRate; @@ -627,8 +648,8 @@ namespace dxvk { HRESULT DxgiSwapChain::ChangeDisplayMode( - IDXGIOutput* pOutput, - const DXGI_MODE_DESC* pDisplayMode) { + IDXGIOutput1* pOutput, + const DXGI_MODE_DESC1* pDisplayMode) { if (!pOutput) return DXGI_ERROR_INVALID_CALL; @@ -636,13 +657,13 @@ namespace dxvk { DXGI_OUTPUT_DESC outputDesc; pOutput->GetDesc(&outputDesc); - DXGI_MODE_DESC preferredMode = *pDisplayMode; - DXGI_MODE_DESC selectedMode; + DXGI_MODE_DESC1 preferredMode = *pDisplayMode; + DXGI_MODE_DESC1 selectedMode; if (preferredMode.Format == DXGI_FORMAT_UNKNOWN) preferredMode.Format = m_desc.Format; - HRESULT hr = pOutput->FindClosestMatchingMode( + HRESULT hr = pOutput->FindClosestMatchingMode1( &preferredMode, &selectedMode, nullptr); if (FAILED(hr)) { @@ -654,16 +675,7 @@ namespace dxvk { return hr; } - DXGI_MODE_DESC1 selectedMode1; - selectedMode1.Width = selectedMode.Width; - selectedMode1.Height = selectedMode.Height; - selectedMode1.RefreshRate = selectedMode.RefreshRate; - selectedMode1.Format = selectedMode.Format; - selectedMode1.ScanlineOrdering = selectedMode.ScanlineOrdering; - selectedMode1.Scaling = selectedMode.Scaling; - selectedMode1.Stereo = false; - - if (!wsi::setWindowMode(outputDesc.Monitor, m_window, ConvertDisplayMode(selectedMode1))) + if (!wsi::setWindowMode(outputDesc.Monitor, m_window, ConvertDisplayMode(selectedMode))) return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; return S_OK; @@ -696,19 +708,20 @@ namespace dxvk { HRESULT DxgiSwapChain::GetOutputFromMonitor( HMONITOR Monitor, - IDXGIOutput** ppOutput) { + IDXGIOutput1** ppOutput) { if (!ppOutput) return DXGI_ERROR_INVALID_CALL; - - for (uint32_t i = 0; SUCCEEDED(m_adapter->EnumOutputs(i, ppOutput)); i++) { + + Com output; + + for (uint32_t i = 0; SUCCEEDED(m_adapter->EnumOutputs(i, &output)); i++) { DXGI_OUTPUT_DESC outputDesc; - (*ppOutput)->GetDesc(&outputDesc); + output->GetDesc(&outputDesc); if (outputDesc.Monitor == Monitor) - return S_OK; + return output->QueryInterface(IID_PPV_ARGS(ppOutput)); - (*ppOutput)->Release(); - (*ppOutput) = nullptr; + output = nullptr; } return DXGI_ERROR_NOT_FOUND; diff --git a/src/dxgi/dxgi_swapchain.h b/src/dxgi/dxgi_swapchain.h index 31e49b941..b1c38c4e5 100644 --- a/src/dxgi/dxgi_swapchain.h +++ b/src/dxgi/dxgi_swapchain.h @@ -177,7 +177,7 @@ namespace dxvk { Com m_factory; Com m_adapter; - Com m_target; + Com m_target; Com m_monitorInfo; HWND m_window; @@ -191,13 +191,13 @@ namespace dxvk { wsi::DxvkWindowState m_windowState; HRESULT EnterFullscreenMode( - IDXGIOutput *pTarget); + IDXGIOutput1 *pTarget); HRESULT LeaveFullscreenMode(); HRESULT ChangeDisplayMode( - IDXGIOutput* pOutput, - const DXGI_MODE_DESC* pDisplayMode); + IDXGIOutput1* pOutput, + const DXGI_MODE_DESC1* pDisplayMode); HRESULT RestoreDisplayMode( HMONITOR hMonitor); @@ -208,7 +208,7 @@ namespace dxvk { HRESULT GetOutputFromMonitor( HMONITOR Monitor, - IDXGIOutput** ppOutput); + IDXGIOutput1** ppOutput); HRESULT AcquireMonitorData( HMONITOR hMonitor, From fe3fc82d8e2705119f30e8eb4328bf30b542d26c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 15 Sep 2022 15:47:09 +0200 Subject: [PATCH 0853/1348] [dxgi] Handle mode changes for frame statistics --- src/dxgi/dxgi_swapchain.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 22172b39b..df4575b08 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -2,6 +2,8 @@ #include "dxgi_output.h" #include "dxgi_swapchain.h" +#include "../util/util_misc.h" + namespace dxvk { DxgiSwapChain::DxgiSwapChain( @@ -678,6 +680,24 @@ namespace dxvk { if (!wsi::setWindowMode(outputDesc.Monitor, m_window, ConvertDisplayMode(selectedMode))) return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; + DXGI_VK_MONITOR_DATA* monitorData = nullptr; + + if (SUCCEEDED(AcquireMonitorData(outputDesc.Monitor, &monitorData))) { + auto refreshPeriod = computeRefreshPeriod( + monitorData->LastMode.RefreshRate.Numerator, + monitorData->LastMode.RefreshRate.Denominator); + + auto t1Counter = dxvk::high_resolution_clock::get_counter(); + + auto t0 = dxvk::high_resolution_clock::get_time_from_counter(monitorData->FrameStats.SyncQPCTime.QuadPart); + auto t1 = dxvk::high_resolution_clock::get_time_from_counter(t1Counter); + + monitorData->FrameStats.SyncRefreshCount += computeRefreshCount(t0, t1, refreshPeriod); + monitorData->FrameStats.SyncQPCTime.QuadPart = t1Counter; + monitorData->LastMode = selectedMode; + ReleaseMonitorData(); + } + return S_OK; } From 67bd2b5e76539a272581386aba4c3b177af1b546 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 15 Sep 2022 16:05:45 +0200 Subject: [PATCH 0854/1348] [dxgi] Report swap chain frame statistics --- src/dxgi/dxgi_swapchain.cpp | 69 ++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index df4575b08..9d7bb47f2 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -18,7 +18,7 @@ namespace dxvk { m_descFs (*pFullscreenDesc), m_presentCount(0u), m_presenter (pPresenter), - m_monitor (nullptr) { + m_monitor (wsi::getWindowMonitor(m_window)) { if (FAILED(m_presenter->GetAdapter(__uuidof(IDXGIAdapter), reinterpret_cast(&m_adapter)))) throw DxvkError("DXGI: Failed to get adapter for present device"); @@ -32,7 +32,8 @@ namespace dxvk { DxgiSwapChain::~DxgiSwapChain() { - RestoreDisplayMode(m_monitor); + if (!m_descFs.Windowed) + RestoreDisplayMode(m_monitor); // Decouple swap chain from monitor if necessary DXGI_VK_MONITOR_DATA* monitorInfo = nullptr; @@ -174,14 +175,36 @@ namespace dxvk { static bool s_errorShown = false; if (!std::exchange(s_errorShown, true)) - Logger::warn("DxgiSwapChain::GetFrameStatistics: Semi-stub"); + Logger::warn("DxgiSwapChain::GetFrameStatistics: Frame statistics may be inaccurate"); + + // If possible, use the monitor's frame statistics + DXGI_VK_MONITOR_DATA* monitorData = nullptr; + + if (SUCCEEDED(AcquireMonitorData(m_monitor, &monitorData))) { + auto refreshPeriod = computeRefreshPeriod( + monitorData->LastMode.RefreshRate.Numerator, + monitorData->LastMode.RefreshRate.Denominator); + + auto t1Counter = dxvk::high_resolution_clock::get_counter(); + + auto t0 = dxvk::high_resolution_clock::get_time_from_counter(monitorData->FrameStats.SyncQPCTime.QuadPart); + auto t1 = dxvk::high_resolution_clock::get_time_from_counter(t1Counter); + + pStats->PresentCount = monitorData->FrameStats.PresentCount; + pStats->PresentRefreshCount = monitorData->FrameStats.PresentRefreshCount; + pStats->SyncRefreshCount = monitorData->FrameStats.SyncRefreshCount + computeRefreshCount(t0, t1, refreshPeriod); + pStats->SyncQPCTime.QuadPart = t1Counter; + pStats->SyncGPUTime.QuadPart = 0; + + ReleaseMonitorData(); + } else { + pStats->PresentCount = m_presentCount; + pStats->PresentRefreshCount = 0; + pStats->SyncRefreshCount = 0; + pStats->SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter(); + pStats->SyncGPUTime.QuadPart = 0; + } - // TODO deal with the refresh counts at some point - pStats->PresentCount = m_presentCount; - pStats->PresentRefreshCount = 0; - pStats->SyncRefreshCount = 0; - pStats->SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter(); - pStats->SyncGPUTime.QuadPart = 0; return S_OK; } @@ -268,13 +291,33 @@ namespace dxvk { try { HRESULT hr = m_presenter->Present(SyncInterval, PresentFlags, nullptr); - if (hr == S_OK && !(PresentFlags & DXGI_PRESENT_TEST)) - m_presentCount++; - return hr; + + if (hr != S_OK || (PresentFlags & DXGI_PRESENT_TEST)) + return hr; } catch (const DxvkError& err) { Logger::err(err.message()); return DXGI_ERROR_DRIVER_INTERNAL_ERROR; } + + // Update frame statistics + DXGI_VK_MONITOR_DATA* monitorData; + + if (SUCCEEDED(AcquireMonitorData(m_monitor, &monitorData))) { + auto refreshPeriod = computeRefreshPeriod( + monitorData->LastMode.RefreshRate.Numerator, + monitorData->LastMode.RefreshRate.Denominator); + + auto t0 = dxvk::high_resolution_clock::get_time_from_counter(monitorData->FrameStats.SyncQPCTime.QuadPart); + auto t1 = dxvk::high_resolution_clock::now(); + + monitorData->FrameStats.PresentCount += 1; + monitorData->FrameStats.PresentRefreshCount = monitorData->FrameStats.SyncRefreshCount + computeRefreshCount(t0, t1, refreshPeriod); + ReleaseMonitorData(); + } else { + m_presentCount += 1; + } + + return S_OK; } @@ -633,8 +676,8 @@ namespace dxvk { HMONITOR monitor = m_monitor; m_descFs.Windowed = TRUE; - m_monitor = nullptr; m_target = nullptr; + m_monitor = wsi::getWindowMonitor(m_window); if (!wsi::isWindow(m_window)) return S_OK; From 3a63c7cb31bc43c825c816012277e7d714cb225c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 16 Sep 2022 17:24:04 +0200 Subject: [PATCH 0855/1348] [dxvk] Hide some more format compatibility validation errors --- src/dxvk/dxvk_instance.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index 4808fa45c..7f73e6e47 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -258,10 +258,13 @@ namespace dxvk { case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: logLevel = LogLevel::Error; break; } - static const std::array ignoredIds = { + static const std::array ignoredIds = { // Ignore image format features for depth-compare instructions. // These errors are expected in D3D9 and some D3D11 apps. + 0x23259a0d, 0x4b9d1597, + 0x534c50ad, + 0x9750b479, // Ignore vkCmdBindPipeline errors related to dynamic rendering. // Validation layers are buggy here and will complain about any // command buffer with more than one render pass. From b56ec10deb2b6b9f03e2c5339143bf3c19938bd0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 16 Sep 2022 15:31:17 +0200 Subject: [PATCH 0856/1348] [d3d9] Add helpers for precise matrix-vector products --- src/d3d9/d3d9_fixed_function.cpp | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index c54bdc422..6a9f5c7c2 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -764,6 +764,9 @@ namespace dxvk { void alphaTestPS(); + uint32_t emitMatrixTimesVector(uint32_t rowCount, uint32_t colCount, uint32_t matrix, uint32_t vector); + uint32_t emitVectorTimesMatrix(uint32_t rowCount, uint32_t colCount, uint32_t vector, uint32_t matrix); + bool isVS() { return m_programType == DxsoProgramType::VertexShader; } bool isPS() { return !isVS(); } @@ -2390,6 +2393,38 @@ namespace dxvk { } + uint32_t D3D9FFShaderCompiler::emitMatrixTimesVector(uint32_t rowCount, uint32_t colCount, uint32_t matrix, uint32_t vector) { + uint32_t f32Type = m_module.defFloatType(32); + uint32_t vecType = m_module.defVectorType(f32Type, rowCount); + uint32_t accum = 0; + + for (uint32_t i = 0; i < colCount; i++) { + std::array indices = { i, i, i, i }; + + uint32_t a = m_module.opVectorShuffle(vecType, vector, vector, rowCount, indices.data()); + uint32_t b = m_module.opCompositeExtract(vecType, matrix, 1, &i); + + accum = accum + ? m_module.opFFma(vecType, a, b, accum) + : m_module.opFMul(vecType, a, b); + + m_module.decorate(accum, spv::DecorationNoContraction); + } + + return accum; + } + + + uint32_t D3D9FFShaderCompiler::emitVectorTimesMatrix(uint32_t rowCount, uint32_t colCount, uint32_t vector, uint32_t matrix) { + uint32_t f32Type = m_module.defFloatType(32); + uint32_t vecType = m_module.defVectorType(f32Type, colCount); + uint32_t matType = m_module.defMatrixType(vecType, rowCount); + + matrix = m_module.opTranspose(matType, matrix); + return emitMatrixTimesVector(colCount, rowCount, matrix, vector); + } + + D3D9FFShader::D3D9FFShader( D3D9DeviceEx* pDevice, const D3D9FFShaderKeyVS& Key) { From 4fb6c200d7accabeac3b097e904e226a2929f6e5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 16 Sep 2022 15:49:27 +0200 Subject: [PATCH 0857/1348] [d3d9] Use precise matrix-vector operations to compute vertex position --- src/d3d9/d3d9_fixed_function.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 6a9f5c7c2..8efc9db39 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -976,8 +976,8 @@ namespace dxvk { if (!m_vsKey.Data.Contents.HasPositionT) { if (m_vsKey.Data.Contents.VertexBlendMode == D3D9FF_VertexBlendMode_Normal) { uint32_t blendWeightRemaining = m_module.constf32(1); - uint32_t vtxSum = m_module.constvec4f32(0, 0, 0, 0); - uint32_t nrmSum = m_module.constvec3f32(0, 0, 0); + uint32_t vtxSum = 0; + uint32_t nrmSum = 0; for (uint32_t i = 0; i <= m_vsKey.Data.Contents.VertexBlendCount; i++) { std::array arrayIndices; @@ -1004,7 +1004,7 @@ namespace dxvk { } nrmMtx = m_module.opCompositeConstruct(m_mat3Type, mtxIndices.size(), mtxIndices.data()); - uint32_t vtxResult = m_module.opVectorTimesMatrix(m_vec4Type, vtx, worldview); + uint32_t vtxResult = emitVectorTimesMatrix(4, 4, vtx, worldview); uint32_t nrmResult = m_module.opVectorTimesMatrix(m_vec3Type, normal, nrmMtx); uint32_t weight; @@ -1015,18 +1015,26 @@ namespace dxvk { else weight = blendWeightRemaining; - vtxResult = m_module.opVectorTimesScalar(m_vec4Type, vtxResult, weight); - nrmResult = m_module.opVectorTimesScalar(m_vec3Type, nrmResult, weight); + std::array weightIds = { weight, weight, weight, weight }; + uint32_t weightVec4 = m_module.opCompositeConstruct(m_vec4Type, 4, weightIds.data()); + uint32_t weightVec3 = m_module.opCompositeConstruct(m_vec3Type, 3, weightIds.data()); - vtxSum = m_module.opFAdd(m_vec4Type, vtxSum, vtxResult); - nrmSum = m_module.opFAdd(m_vec3Type, nrmSum, nrmResult); + vtxSum = vtxSum + ? m_module.opFFma(m_vec4Type, vtxResult, weightVec4, vtxSum) + : m_module.opFMul(m_vec4Type, vtxResult, weightVec4); + + nrmSum = nrmSum + ? m_module.opFFma(m_vec3Type, nrmResult, weightVec3, nrmSum) + : m_module.opFMul(m_vec3Type, nrmResult, weightVec3); + + m_module.decorate(vtxSum, spv::DecorationNoContraction); } vtx = vtxSum; normal = nrmSum; } else { - vtx = m_module.opVectorTimesMatrix(m_vec4Type, vtx, m_vs.constants.worldview); + vtx = emitVectorTimesMatrix(4, 4, vtx, m_vs.constants.worldview); uint32_t nrmMtx = m_vs.constants.normal; @@ -1054,7 +1062,7 @@ namespace dxvk { normal = m_module.opSelect(m_vec3Type, isZeroNormal3, m_module.constvec3f32(0.0f, 0.0f, 0.0f), normal); } - gl_Position = m_module.opVectorTimesMatrix(m_vec4Type, vtx, m_vs.constants.proj); + gl_Position = emitVectorTimesMatrix(4, 4, vtx, m_vs.constants.proj); } else { gl_Position = m_module.opFMul(m_vec4Type, gl_Position, m_vs.constants.invExtent); gl_Position = m_module.opFAdd(m_vec4Type, gl_Position, m_vs.constants.invOffset); @@ -2304,7 +2312,7 @@ namespace dxvk { void D3D9FFShaderCompiler::emitVsClipping(uint32_t vtx) { - uint32_t worldPos = m_module.opMatrixTimesVector(m_vec4Type, m_vs.constants.inverseView, vtx); + uint32_t worldPos = emitMatrixTimesVector(4, 4, m_vs.constants.inverseView, vtx); uint32_t clipPlaneCountId = m_module.constu32(caps::MaxClipPlanes); From 07094ac4f999651d9355aac4bf4c2ecdb2faaed7 Mon Sep 17 00:00:00 2001 From: xpander69 Date: Fri, 16 Sep 2022 23:12:29 +0300 Subject: [PATCH 0858/1348] [util] Remove fps cap from Warhammer Online This is a bit embarrassing. Added this config few days ago to counter the animation breakages, but now Return of Reckoning devs patched the executable on their side to cap the framerate by default. So the workaround is not needed anymore. --- src/util/config/config.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index f6e325d51..464362344 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -439,7 +439,6 @@ namespace dxvk { /* Warhammer: Online */ { R"(\\WAR(-64)?\.exe$)", {{ { "d3d9.customVendorId", "1002" }, - { "d3d9.maxFrameRate", "100" }, }} }, /* Dragon Nest */ { R"(\\DragonNest_x64\.exe$)", {{ From d93568f1a9fe5346955d58e8d5e9c0ea68b0a96a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 16 Sep 2022 17:07:53 +0200 Subject: [PATCH 0859/1348] [dxbc] Don't emit built-in position as a block variable This is no longer needed for interface matching. --- src/dxbc/dxbc_compiler.cpp | 136 ++++++++----------------------------- src/dxbc/dxbc_compiler.h | 18 ++--- 2 files changed, 36 insertions(+), 118 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 1a921de2a..b0e59edea 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -5,10 +5,6 @@ namespace dxvk { constexpr uint32_t Icb_BindingSlotId = 14; constexpr uint32_t Icb_MaxBakedDwords = 16; - constexpr uint32_t PerVertex_Position = 0; - constexpr uint32_t PerVertex_CullDist = 1; - constexpr uint32_t PerVertex_ClipDist = 2; - DxbcCompiler::DxbcCompiler( const std::string& fileName, const DxbcModuleInfo& moduleInfo, @@ -1279,7 +1275,6 @@ namespace dxvk { = primitiveVertexCount(m_gs.inputPrimitive); emitDclInputArray(vertexCount); - emitDclInputPerVertex(vertexCount, "gs_vertex_in"); } @@ -2275,7 +2270,7 @@ namespace dxvk { bool doCut = ins.op != DxbcOpcode::Emit && ins.op != DxbcOpcode::EmitStream; if (doEmit) { - if (m_perVertexOut) + if (m_gs.needsOutputSetup) emitOutputSetup(); emitClipCullStore(DxbcSystemValue::ClipDistance, m_clipDistances); emitClipCullStore(DxbcSystemValue::CullDistance, m_cullDistances); @@ -6171,25 +6166,24 @@ namespace dxvk { uint32_t vertexId) { switch (sv) { case DxbcSystemValue::Position: { - const std::array indices = { - m_module.consti32(vertexId), - m_module.consti32(PerVertex_Position), - }; - + uint32_t arrayIndex = m_module.consti32(vertexId); + + if (!m_positionIn) { + m_positionIn = emitNewBuiltinVariable({ + { DxbcScalarType::Float32, 4, primitiveVertexCount(m_gs.inputPrimitive) }, + spv::StorageClassInput }, + spv::BuiltInPosition, + "in_position"); + } + DxbcRegisterPointer ptrIn; ptrIn.type.ctype = DxbcScalarType::Float32; ptrIn.type.ccount = 4; - ptrIn.id = m_module.opAccessChain( - m_module.defPointerType( - getVectorTypeId(ptrIn.type), - spv::StorageClassInput), - m_perVertexIn, - indices.size(), - indices.data()); + m_module.defPointerType(getVectorTypeId(ptrIn.type), spv::StorageClassInput), + m_positionIn, 1, &arrayIndex); - return emitRegisterExtract( - emitValueLoad(ptrIn), mask); + return emitRegisterExtract(emitValueLoad(ptrIn), mask); } break; default: @@ -6344,17 +6338,18 @@ namespace dxvk { const DxbcRegisterValue& value) { switch (sv) { case DxbcSystemValue::Position: { - const uint32_t memberId = m_module.consti32(PerVertex_Position); - + if (!m_positionOut) { + m_positionOut = emitNewBuiltinVariable({ + { DxbcScalarType::Float32, 4, 0 }, + spv::StorageClassOutput }, + spv::BuiltInPosition, + "out_position"); + } + DxbcRegisterPointer ptr; ptr.type.ctype = DxbcScalarType::Float32; ptr.type.ccount = 4; - - ptr.id = m_module.opAccessChain( - m_module.defPointerType( - getVectorTypeId(ptr.type), - spv::StorageClassOutput), - m_perVertexOut, 1, &memberId); + ptr.id = m_positionOut; emitValueStore(ptr, value, mask); } break; @@ -6701,16 +6696,6 @@ namespace dxvk { m_module.enableCapability(spv::CapabilityCullDistance); m_module.enableCapability(spv::CapabilityDrawParameters); - // Declare the per-vertex output block. This is where - // the vertex shader will write the vertex position. - const uint32_t perVertexStruct = this->getPerVertexBlockId(); - const uint32_t perVertexPointer = m_module.defPointerType( - perVertexStruct, spv::StorageClassOutput); - - m_perVertexOut = m_module.newVar( - perVertexPointer, spv::StorageClassOutput); - m_module.setDebugName(m_perVertexOut, "vs_vertex_out"); - // Standard input array emitDclInputArray(0); @@ -6763,11 +6748,6 @@ namespace dxvk { m_ds.builtinTessLevelOuter = emitBuiltinTessLevelOuter(spv::StorageClassInput); m_ds.builtinTessLevelInner = emitBuiltinTessLevelInner(spv::StorageClassInput); - // Declare the per-vertex output block - const uint32_t perVertexStruct = this->getPerVertexBlockId(); - const uint32_t perVertexPointer = m_module.defPointerType( - perVertexStruct, spv::StorageClassOutput); - // Cull/clip distances as outputs m_clipDistances = emitDclClipCullDistanceArray( m_analysis->clipCullOut.numClipPlanes, @@ -6779,10 +6759,6 @@ namespace dxvk { spv::BuiltInCullDistance, spv::StorageClassOutput); - m_perVertexOut = m_module.newVar( - perVertexPointer, spv::StorageClassOutput); - m_module.setDebugName(m_perVertexOut, "ds_vertex_out"); - // Main function of the domain shader m_ds.functionId = m_module.allocateId(); m_module.setDebugName(m_ds.functionId, "ds_main"); @@ -6802,25 +6778,16 @@ namespace dxvk { m_module.enableCapability(spv::CapabilityCullDistance); // Enable capabilities for xfb mode if necessary - if (m_moduleInfo.xfb != nullptr) { + if (m_moduleInfo.xfb) { m_module.enableCapability(spv::CapabilityGeometryStreams); m_module.enableCapability(spv::CapabilityTransformFeedback); m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeXfb); } - - // Declare the per-vertex output block. Outputs are not - // declared as arrays, instead they will be flushed when - // calling EmitVertex. - if (!m_moduleInfo.xfb || m_moduleInfo.xfb->rasterizedStream >= 0) { - const uint32_t perVertexStruct = this->getPerVertexBlockId(); - const uint32_t perVertexPointer = m_module.defPointerType( - perVertexStruct, spv::StorageClassOutput); - - m_perVertexOut = m_module.newVar( - perVertexPointer, spv::StorageClassOutput); - m_module.setDebugName(m_perVertexOut, "gs_vertex_out"); - } + + // We only need outputs if rasterization is enabled + m_gs.needsOutputSetup = !m_moduleInfo.xfb + || m_moduleInfo.xfb->rasterizedStream >= 0; // Cull/clip distances as outputs m_clipDistances = emitDclClipCullDistanceArray( @@ -6834,7 +6801,7 @@ namespace dxvk { spv::StorageClassOutput); // Emit Xfb variables if necessary - if (m_moduleInfo.xfb != nullptr) + if (m_moduleInfo.xfb) emitXfbOutputDeclarations(); // Main function of the vertex shader @@ -7132,25 +7099,6 @@ namespace dxvk { } - void DxbcCompiler::emitDclInputPerVertex( - uint32_t vertexCount, - const char* varName) { - uint32_t typeId = getPerVertexBlockId(); - - if (vertexCount != 0) { - typeId = m_module.defArrayType(typeId, - m_module.constu32(vertexCount)); - } - - const uint32_t ptrTypeId = m_module.defPointerType( - typeId, spv::StorageClassInput); - - m_perVertexIn = m_module.newVar( - ptrTypeId, spv::StorageClassInput); - m_module.setDebugName(m_perVertexIn, varName); - } - - uint32_t DxbcCompiler::emitDclClipCullDistanceArray( uint32_t length, spv::BuiltIn builtIn, @@ -7894,32 +7842,6 @@ namespace dxvk { } - uint32_t DxbcCompiler::getPerVertexBlockId() { - uint32_t t_f32 = m_module.defFloatType(32); - uint32_t t_f32_v4 = m_module.defVectorType(t_f32, 4); -// uint32_t t_f32_a4 = m_module.defArrayType(t_f32, m_module.constu32(4)); - - std::array members; - members[PerVertex_Position] = t_f32_v4; -// members[PerVertex_CullDist] = t_f32_a4; -// members[PerVertex_ClipDist] = t_f32_a4; - - uint32_t typeId = m_module.defStructTypeUnique( - members.size(), members.data()); - - m_module.memberDecorateBuiltIn(typeId, PerVertex_Position, spv::BuiltInPosition); -// m_module.memberDecorateBuiltIn(typeId, PerVertex_CullDist, spv::BuiltInCullDistance); -// m_module.memberDecorateBuiltIn(typeId, PerVertex_ClipDist, spv::BuiltInClipDistance); - m_module.decorateBlock(typeId); - - m_module.setDebugName(typeId, "s_per_vertex"); - m_module.setDebugMemberName(typeId, PerVertex_Position, "position"); -// m_module.setDebugMemberName(typeId, PerVertex_CullDist, "cull_dist"); -// m_module.setDebugMemberName(typeId, PerVertex_ClipDist, "clip_dist"); - return typeId; - } - - uint32_t DxbcCompiler::getFunctionId( uint32_t functionNr) { auto entry = m_subroutines.find(functionNr); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 73e29e750..961219247 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -162,6 +162,8 @@ namespace dxvk { uint32_t builtinViewportId = 0; uint32_t builtinInvocationId = 0; uint32_t invocationCount = 0; + + bool needsOutputSetup = false; }; @@ -474,11 +476,11 @@ namespace dxvk { //////////////////////////////////////////////////// // Per-vertex input and output blocks. Depending on // the shader stage, these may be declared as arrays. - uint32_t m_perVertexIn = 0; - uint32_t m_perVertexOut = 0; - - uint32_t m_clipDistances = 0; - uint32_t m_cullDistances = 0; + uint32_t m_positionIn = 0; + uint32_t m_positionOut = 0; + + uint32_t m_clipDistances = 0; + uint32_t m_cullDistances = 0; uint32_t m_primitiveIdIn = 0; uint32_t m_primitiveIdOut = 0; @@ -1146,10 +1148,6 @@ namespace dxvk { void emitDclInputArray( uint32_t vertexCount); - void emitDclInputPerVertex( - uint32_t vertexCount, - const char* varName); - uint32_t emitDclClipCullDistanceArray( uint32_t length, spv::BuiltIn builtIn, @@ -1246,8 +1244,6 @@ namespace dxvk { uint32_t getSparseResultTypeId( uint32_t baseType); - uint32_t getPerVertexBlockId(); - uint32_t getFunctionId( uint32_t functionNr); From 5b6b9923abb078cfd00cfaaf8a5387a36d83868a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 16 Sep 2022 17:10:01 +0200 Subject: [PATCH 0860/1348] [dxbc] Write point size in vertex shaders Silences some validation errors when point rendering is enabled. --- src/dxbc/dxbc_compiler.cpp | 14 ++++++++++++++ src/dxbc/dxbc_compiler.h | 8 ++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index b0e59edea..5d31f9431 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -6634,6 +6634,19 @@ namespace dxvk { } + void DxbcCompiler::emitPointSizeStore() { + if (!m_pointSizeOut) { + m_pointSizeOut = emitNewBuiltinVariable(DxbcRegisterInfo { + { DxbcScalarType::Float32, 1, 0 }, + spv::StorageClassOutput }, + spv::BuiltInPointSize, + "point_size"); + } + + m_module.opStore(m_pointSizeOut, m_module.constf32(1.0f)); + } + + void DxbcCompiler::emitInit() { // Set up common capabilities for all shaders m_module.enableCapability(spv::CapabilityShader); @@ -6873,6 +6886,7 @@ namespace dxvk { this->emitOutputSetup(); this->emitClipCullStore(DxbcSystemValue::ClipDistance, m_clipDistances); this->emitClipCullStore(DxbcSystemValue::CullDistance, m_cullDistances); + this->emitPointSizeStore(); this->emitFunctionEnd(); } diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 961219247..03ddf7ad6 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -484,7 +484,9 @@ namespace dxvk { uint32_t m_primitiveIdIn = 0; uint32_t m_primitiveIdOut = 0; - + + uint32_t m_pointSizeOut = 0; + ////////////////////////////////////////////////// // Immediate constant buffer. If defined, this is // an array of four-component uint32 vectors. @@ -1077,7 +1079,9 @@ namespace dxvk { void emitClipCullLoad( DxbcSystemValue sv, uint32_t srcArray); - + + void emitPointSizeStore(); + ////////////////////////////////////// // Common function definition methods void emitInit(); From 9fa587e13c469bde8761175f4fa1ae6dfdcf6d17 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 17 Sep 2022 05:01:36 +0200 Subject: [PATCH 0861/1348] [dxgi] Always use swap chain-local present count for frame statistics Doesn't appear to match Windows behaviour, but there may be scenarios when we can't query the current monitor. Statistics still need to be consistent in this case. See #2933. --- src/dxgi/dxgi_swapchain.cpp | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 9d7bb47f2..3ebf48346 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -177,7 +177,16 @@ namespace dxvk { if (!std::exchange(s_errorShown, true)) Logger::warn("DxgiSwapChain::GetFrameStatistics: Frame statistics may be inaccurate"); - // If possible, use the monitor's frame statistics + // Populate frame statistics with local present count and current time + auto t1Counter = dxvk::high_resolution_clock::get_counter(); + + pStats->PresentCount = m_presentCount; + pStats->PresentRefreshCount = 0; + pStats->SyncRefreshCount = 0; + pStats->SyncQPCTime.QuadPart = t1Counter; + pStats->SyncGPUTime.QuadPart = 0; + + // If possible, use the monitor's frame statistics for vblank stats DXGI_VK_MONITOR_DATA* monitorData = nullptr; if (SUCCEEDED(AcquireMonitorData(m_monitor, &monitorData))) { @@ -185,24 +194,13 @@ namespace dxvk { monitorData->LastMode.RefreshRate.Numerator, monitorData->LastMode.RefreshRate.Denominator); - auto t1Counter = dxvk::high_resolution_clock::get_counter(); - auto t0 = dxvk::high_resolution_clock::get_time_from_counter(monitorData->FrameStats.SyncQPCTime.QuadPart); auto t1 = dxvk::high_resolution_clock::get_time_from_counter(t1Counter); - pStats->PresentCount = monitorData->FrameStats.PresentCount; pStats->PresentRefreshCount = monitorData->FrameStats.PresentRefreshCount; pStats->SyncRefreshCount = monitorData->FrameStats.SyncRefreshCount + computeRefreshCount(t0, t1, refreshPeriod); - pStats->SyncQPCTime.QuadPart = t1Counter; - pStats->SyncGPUTime.QuadPart = 0; ReleaseMonitorData(); - } else { - pStats->PresentCount = m_presentCount; - pStats->PresentRefreshCount = 0; - pStats->SyncRefreshCount = 0; - pStats->SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter(); - pStats->SyncGPUTime.QuadPart = 0; } return S_OK; @@ -300,7 +298,7 @@ namespace dxvk { } // Update frame statistics - DXGI_VK_MONITOR_DATA* monitorData; + DXGI_VK_MONITOR_DATA* monitorData = nullptr; if (SUCCEEDED(AcquireMonitorData(m_monitor, &monitorData))) { auto refreshPeriod = computeRefreshPeriod( @@ -313,10 +311,9 @@ namespace dxvk { monitorData->FrameStats.PresentCount += 1; monitorData->FrameStats.PresentRefreshCount = monitorData->FrameStats.SyncRefreshCount + computeRefreshCount(t0, t1, refreshPeriod); ReleaseMonitorData(); - } else { - m_presentCount += 1; } + m_presentCount += 1; return S_OK; } From 2a7706ba5395e197c80d59420043c06d511b8047 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 18 Sep 2022 02:23:24 +0200 Subject: [PATCH 0862/1348] [dxbc] Do not enable SPV_KHR_shader_float_controls This is core in Vulkan 1.2 and SPIR-V 1.5. --- src/dxbc/dxbc_compiler.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 5d31f9431..cfb5708f5 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -7427,8 +7427,6 @@ namespace dxvk { const uint32_t width32 = 32; const uint32_t width64 = 64; - m_module.enableExtension("SPV_KHR_float_controls"); - if (flags.test(DxbcFloatControlFlag::DenormFlushToZero32)) { m_module.enableCapability(spv::CapabilityDenormFlushToZero); m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeDenormFlushToZero, 1, &width32); From 0bb0c1e6467d333dcaffb6a177ec21836cd3f275 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 19 Sep 2022 15:43:45 +0200 Subject: [PATCH 0863/1348] [util] Enable ignoreGraphicsBarriers for FFXV Massively improves performance when VXAO is enabled. --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 464362344..e0a55a608 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -242,6 +242,11 @@ namespace dxvk { { R"(\\ffxiv_dx11\.exe$)", {{ { "d3d11.cachedDynamicResources", "vi" }, }} }, + /* Final Fantasy XV: VXAO does thousands of * + * draw calls with the same UAV bound */ + { R"(\\ffxv_s\.exe$)", {{ + { "d3d11.ignoreGraphicsBarriers", "True" }, + }} }, /* God of War - relies on NVAPI/AMDAGS for * * barrier stuff, needs nvapi for DLSS */ { R"(\\GoW\.exe$)", {{ From 9532126f7ced31109bf36b704b1ede5f2b5d08c8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 18 Sep 2022 02:44:34 +0200 Subject: [PATCH 0864/1348] [dxvk] Enable VK_EXT_fragment_shader_interlock --- src/dxvk/dxvk_adapter.cpp | 16 +++++++++++++++- src/dxvk/dxvk_device_info.h | 1 + src/dxvk/dxvk_extensions.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 7e6c45250..2fe5d87af 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -335,13 +335,14 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.extAttachmentFeedbackLoopLayout, &devExtensions.extConservativeRasterization, &devExtensions.extCustomBorderColor, &devExtensions.extDepthClipEnable, + &devExtensions.extFragmentShaderInterlock, &devExtensions.extFullScreenExclusive, &devExtensions.extGraphicsPipelineLibrary, &devExtensions.extMemoryBudget, @@ -482,6 +483,11 @@ namespace dxvk { enabledFeatures.extDepthClipEnable.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extDepthClipEnable); } + if (devExtensions.extFragmentShaderInterlock) { + enabledFeatures.extFragmentShaderInterlock.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT; + enabledFeatures.extFragmentShaderInterlock.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extFragmentShaderInterlock); + } + if (devExtensions.extFullScreenExclusive) enabledFeatures.extFullScreenExclusive = VK_TRUE; @@ -805,6 +811,11 @@ namespace dxvk { m_deviceFeatures.extDepthClipEnable.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extDepthClipEnable); } + if (m_deviceExtensions.supports(VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME)) { + m_deviceFeatures.extFragmentShaderInterlock.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT; + m_deviceFeatures.extFragmentShaderInterlock.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extFragmentShaderInterlock); + } + if (m_deviceExtensions.supports(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)) m_deviceFeatures.extFullScreenExclusive = VK_TRUE; @@ -965,6 +976,9 @@ namespace dxvk { "\n customBorderColorWithoutFormat : ", features.extCustomBorderColor.customBorderColorWithoutFormat ? "1" : "0", "\n", VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, "\n depthClipEnable : ", features.extDepthClipEnable.depthClipEnable ? "1" : "0", + "\n", VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME, + "\n fragmentShaderSampleInterlock : ", features.extFragmentShaderInterlock.fragmentShaderSampleInterlock ? "1" : "0", + "\n fragmentShaderPixelInterlock : ", features.extFragmentShaderInterlock.fragmentShaderPixelInterlock ? "1" : "0", "\n", VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, "\n extension supported : ", features.extFullScreenExclusive ? "1" : "0", "\n", VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index b5f8f587e..d8e23a084 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -43,6 +43,7 @@ namespace dxvk { VkBool32 extConservativeRasterization; VkPhysicalDeviceCustomBorderColorFeaturesEXT extCustomBorderColor; VkPhysicalDeviceDepthClipEnableFeaturesEXT extDepthClipEnable; + VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT extFragmentShaderInterlock; VkBool32 extFullScreenExclusive; VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT extGraphicsPipelineLibrary; VkBool32 extMemoryBudget; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index c9d9030e8..7eb30e6b8 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -283,6 +283,7 @@ namespace dxvk { DxvkExt extCustomBorderColor = { VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extDepthClipEnable = { VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extFullScreenExclusive = { VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extFragmentShaderInterlock = { VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extGraphicsPipelineLibrary = { VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extMemoryBudget = { VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, DxvkExtMode::Passive }; DxvkExt extMemoryPriority = { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, DxvkExtMode::Optional }; From 8ca5edeacd4fd1ef55c8d2783d2c7c0015762460 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 17 Sep 2022 22:35:15 +0200 Subject: [PATCH 0865/1348] [dxbc] Decode rasterizer ordered flag for UAVs --- src/dxbc/dxbc_decoder.h | 2 +- src/dxbc/dxbc_enums.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index 5f64cf225..326e1aaf7 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -329,7 +329,7 @@ namespace dxvk { } DxbcUavFlags uavFlags() const { - return DxbcUavFlags(bit::extract(m_bits, 16, 16)); + return DxbcUavFlags(bit::extract(m_bits, 16, 17)); } DxbcConstantBufferAccessType accessType() const { diff --git a/src/dxbc/dxbc_enums.h b/src/dxbc/dxbc_enums.h index 287271e41..f6d29a5b8 100644 --- a/src/dxbc/dxbc_enums.h +++ b/src/dxbc/dxbc_enums.h @@ -609,6 +609,7 @@ namespace dxvk { */ enum class DxbcUavFlag : uint32_t { GloballyCoherent = 0, + RasterizerOrdered = 1, }; using DxbcUavFlags = Flags; From 35a84053b576bd87b7e0d60764fc6e25688fc7b5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 17 Sep 2022 22:38:28 +0200 Subject: [PATCH 0866/1348] [dxbc] Implement rasterizer ordered views --- src/dxbc/dxbc_compiler.cpp | 31 ++++++++++++++++++++++++++++++- src/dxbc/dxbc_compiler.h | 1 + src/dxbc/dxbc_options.cpp | 1 + src/dxbc/dxbc_options.h | 3 +++ src/spirv/spirv_module.cpp | 10 ++++++++++ src/spirv/spirv_module.h | 6 +++++- 6 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index cfb5708f5..ed5e7533c 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -6950,11 +6950,31 @@ namespace dxvk { this->emitInputSetup(); this->emitClipCullLoad(DxbcSystemValue::ClipDistance, m_clipDistances); this->emitClipCullLoad(DxbcSystemValue::CullDistance, m_cullDistances); - + + if (m_hasRasterizerOrderedUav) { + // For simplicity, just lock the entire fragment shader + // if there are any rasterizer ordered views. + m_module.enableExtension("SPV_EXT_fragment_shader_interlock"); + + if (m_module.hasCapability(spv::CapabilitySampleRateShading) + && m_moduleInfo.options.enableSampleShadingInterlock) { + m_module.enableCapability(spv::CapabilityFragmentShaderSampleInterlockEXT); + m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeSampleInterlockOrderedEXT); + } else { + m_module.enableCapability(spv::CapabilityFragmentShaderPixelInterlockEXT); + m_module.setExecutionMode(m_entryPointId, spv::ExecutionModePixelInterlockOrderedEXT); + } + + m_module.opBeginInvocationInterlock(); + } + m_module.opFunctionCall( m_module.defVoidType(), m_ps.functionId, 0, nullptr); + if (m_hasRasterizerOrderedUav) + m_module.opEndInvocationInterlock(); + this->emitOutputSetup(); if (m_moduleInfo.options.useDepthClipWorkaround) @@ -7768,6 +7788,15 @@ namespace dxvk { uint32_t DxbcCompiler::getUavCoherence(uint32_t registerId, DxbcUavFlags flags) { + // For any ROV with write access, we must ensure that + // availability operations happen within the locked scope. + if (flags.test(DxbcUavFlag::RasterizerOrdered) + && (m_analysis->uavInfos[registerId].accessFlags & VK_ACCESS_SHADER_WRITE_BIT)) { + m_hasGloballyCoherentUav = true; + m_hasRasterizerOrderedUav = true; + return spv::ScopeQueueFamily; + } + // Ignore any resources that can't both be read and written in // the current shader, explicit availability/visibility operands // are not useful in that case. diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 03ddf7ad6..4720066cb 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -454,6 +454,7 @@ namespace dxvk { std::array m_uavs; bool m_hasGloballyCoherentUav = false; + bool m_hasRasterizerOrderedUav = false; /////////////////////////////////////////////// // Control flow information. Stores labels for diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 51c565bd4..9b0a5cfff 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -39,6 +39,7 @@ namespace dxvk { zeroInitWorkgroupMemory = options.zeroInitWorkgroupMemory; forceVolatileTgsmAccess = options.forceVolatileTgsmAccess; disableMsaa = options.disableMsaa; + enableSampleShadingInterlock = device->features().extFragmentShaderInterlock.fragmentShaderSampleInterlock; // Figure out float control flags to match D3D11 rules if (options.floatControls) { diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index 0949a6e10..6551b3c07 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -46,6 +46,9 @@ namespace dxvk { /// Replace ld_ms with ld bool disableMsaa = false; + // Enable per-sample interlock if supported + bool enableSampleShadingInterlock = false; + /// Float control flags DxbcFloatControlFlags floatControl; diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index b90e1edce..09240f290 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -3693,6 +3693,16 @@ namespace dxvk { } + void SpirvModule::opBeginInvocationInterlock() { + m_code.putIns(spv::OpBeginInvocationInterlockEXT, 1); + } + + + void SpirvModule::opEndInvocationInterlock() { + m_code.putIns(spv::OpEndInvocationInterlockEXT, 1); + } + + uint32_t SpirvModule::defType( spv::Op op, uint32_t argCount, diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index 2113101bb..a878e2e11 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -1259,7 +1259,11 @@ namespace dxvk { void opEndPrimitive( uint32_t streamId); - + + void opBeginInvocationInterlock(); + + void opEndInvocationInterlock(); + private: uint32_t m_version; From a14ce8d1b0e392b2c3e71e32b5dee90641933075 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 18 Sep 2022 02:52:03 +0200 Subject: [PATCH 0867/1348] [d3d11] Enable ROV support if corresponding Vulkan features are supported --- src/d3d11/d3d11_device.cpp | 4 ++++ src/d3d11/d3d11_features.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 417eadcfe..ce2c06dec 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1940,6 +1940,10 @@ namespace dxvk { enabled.core.features.shaderResourceMinLod = supported.core.features.shaderResourceMinLod; enabled.vk12.samplerFilterMinmax = supported.vk12.samplerFilterMinmax; + // Required for Feature Level 12_1 + enabled.extFragmentShaderInterlock.fragmentShaderSampleInterlock = supported.extFragmentShaderInterlock.fragmentShaderSampleInterlock; + enabled.extFragmentShaderInterlock.fragmentShaderPixelInterlock = supported.extFragmentShaderInterlock.fragmentShaderPixelInterlock; + // Optional in any feature level enabled.core.features.depthBounds = supported.core.features.depthBounds; enabled.core.features.shaderFloat64 = supported.core.features.shaderFloat64; diff --git a/src/d3d11/d3d11_features.cpp b/src/d3d11/d3d11_features.cpp index 3b764cae6..f206e517c 100644 --- a/src/d3d11/d3d11_features.cpp +++ b/src/d3d11/d3d11_features.cpp @@ -81,7 +81,7 @@ namespace dxvk { m_d3d11Options2.MapOnDefaultTextures = TRUE; if (FeatureLevel >= D3D_FEATURE_LEVEL_11_1) { - m_d3d11Options2.ROVsSupported = FALSE; + m_d3d11Options2.ROVsSupported = m_features.extFragmentShaderInterlock.fragmentShaderPixelInterlock; m_d3d11Options2.PSSpecifiedStencilRefSupported = m_features.extShaderStencilExport; } From c4c1d413dbf357cfbc542959613614c62612affc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 19 Sep 2022 16:09:48 +0200 Subject: [PATCH 0868/1348] [meta] Update default config file --- dxvk.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dxvk.conf b/dxvk.conf index 366d25a0e..abe6df4df 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -129,7 +129,7 @@ # # Supported values: 9_1, 9_2, 9_3, 10_0, 10_1, 11_0, 11_1, 12_0, 12_1 -# d3d11.maxFeatureLevel = 12_0 +# d3d11.maxFeatureLevel = 12_1 # Overrides the maximum allowed tessellation factor. This can be used to From 5962be44c6d62782eb1761fb63e78f3ce920865d Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sun, 18 Sep 2022 22:34:12 +0200 Subject: [PATCH 0869/1348] [dxso] Define color inputs as centroids on SM3 too --- src/dxso/dxso_compiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 6da68189c..f6ee9924d 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -629,7 +629,7 @@ namespace dxvk { const bool pixel = m_programInfo.type() == DxsoProgramTypes::PixelShader; const bool vertex = !pixel; - if (pixel && input && semantic.usage == DxsoUsage::Color && m_programInfo.majorVersion() < 3) + if (pixel && input && semantic.usage == DxsoUsage::Color) centroid = true; uint32_t slot = 0; From c759fb45aa362efa175eb4304869328444d6e830 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sat, 17 Sep 2022 17:30:27 +0200 Subject: [PATCH 0870/1348] [util] Disable DF support for pretty mirrors in GTA IV --- src/util/config/config.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index e0a55a608..85a4d87b9 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -410,10 +410,14 @@ namespace dxvk { }} }, /* GTA IV (NVAPI) */ /* Also thinks we're always on Intel * - * and will report/use bad amounts of VRAM. */ + * and will report/use bad amounts of VRAM. + * Disabling support for DF texture formats + * makes the game use a better looking render + * path for mirrors */ { R"(\\GTAIV\.exe$)", {{ { "d3d9.customVendorId", "1002" }, { "dxgi.emulateUMA", "True" }, + { "d3d9.supportDFFormats", "False" }, }} }, /* Battlefield 2 (bad z-pass) */ { R"(\\BF2\.exe$)", {{ From 5c22e2fbda34a622919e4808bb268cedf6ea5bd8 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 19 Sep 2022 16:08:48 +0200 Subject: [PATCH 0871/1348] [util] Enable GTA IV config for Episodes from Liberty City --- src/util/config/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 85a4d87b9..ffe2d89d1 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -414,7 +414,7 @@ namespace dxvk { * Disabling support for DF texture formats * makes the game use a better looking render * path for mirrors */ - { R"(\\GTAIV\.exe$)", {{ + { R"(\\(GTAIV|EFLC)\.exe$)", {{ { "d3d9.customVendorId", "1002" }, { "dxgi.emulateUMA", "True" }, { "d3d9.supportDFFormats", "False" }, From 82ebc29e18c215bf360e7ac6c94f1f9cf42ede7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pyrzowski?= Date: Wed, 21 Sep 2022 12:47:16 +0200 Subject: [PATCH 0872/1348] [dxso] Fix for illegal OpCompositeConstruct while translating Crs opcode During the translation of the Crs opcode to SPIR-V there is an assumption that the result type is a composite type. This is not always true. If the result is a scalar type the translation adds an OpCompositeConstruct with a scalar result type. This is a spec violation. This change checks if the result type is a composite type and does not add the OpCompositeConstruct in case of scalar types. --- src/dxso/dxso_compiler.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index f6ee9924d..0c8a4c6fe 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -2024,7 +2024,10 @@ namespace dxvk { indices[index++] = m_module.opCompositeExtract(m_module.defFloatType(32), crossValue.id, 1, &i); } - result.id = m_module.opCompositeConstruct(getVectorTypeId(result.type), result.type.ccount, indices.data()); + if (result.type.ccount == 1) + result.id = indices[0]; + else + result.id = m_module.opCompositeConstruct(typeId, result.type.ccount, indices.data()); break; } From 1e1ef8f1bd3970f75f70ef6e4113dcdb30ba0633 Mon Sep 17 00:00:00 2001 From: Krzysztof Dobrowolski Date: Thu, 22 Sep 2022 10:41:40 +0200 Subject: [PATCH 0873/1348] [d3d9] Fix for missing mapping of VertexElements declarations to FVF bits When Vertex declaration is created by CreateVertexDeclaration and SetFVF is not called then GetFVF returns 0. This code change implements mapping of D3D declarations to FVF mask and sets it if FVF was not set previously. --- src/d3d9/d3d9_vertex_declaration.cpp | 136 ++++++++++++++++++++++++++- src/d3d9/d3d9_vertex_declaration.h | 15 +++ 2 files changed, 150 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_vertex_declaration.cpp b/src/d3d9/d3d9_vertex_declaration.cpp index 9eb65d79c..270c4a88f 100644 --- a/src/d3d9/d3d9_vertex_declaration.cpp +++ b/src/d3d9/d3d9_vertex_declaration.cpp @@ -23,6 +23,7 @@ namespace dxvk { , m_elements ( DeclCount ) , m_fvf ( 0 ) { std::copy(pVertexElements, pVertexElements + DeclCount, m_elements.begin()); + m_fvf = this->MapD3D9VertexElementsToFvf(); this->Classify(); } @@ -194,7 +195,7 @@ namespace dxvk { for (uint32_t i = 0; i < elemCount; i++) { elements[i].Stream = 0; - elements[i].Offset = (i == 0) + elements[i].Offset = (i == 0) ? 0 : (elements[i - 1].Offset + GetDecltypeSize(D3DDECLTYPE(elements[i - 1].Type))); @@ -205,6 +206,139 @@ namespace dxvk { std::copy(elements.begin(), elements.begin() + elemCount, m_elements.data()); } + DWORD D3D9VertexDecl::MapD3DDeclToFvf( + const D3DVERTEXELEMENT9& element, + DWORD fvf, + DWORD& texCountPostUpdate) { + + // Mapping between a Direct3D Declaration and FVF Codes (Direct3D 9) + // This table maps members of a D3DVERTEXELEMENT9 declaration to a FVF code. + // + // Data type Usage Usage index FVF + // ---------------------------------------------------------------------------------------- + // D3DDECLTYPE_FLOAT3 D3DDECLUSAGE_POSITION 0 D3DFVF_XYZ + // D3DDECLTYPE_FLOAT4 D3DDECLUSAGE_POSITIONT 0 D3DFVF_XYZRHW + // D3DDECLTYPE_FLOATn D3DDECLUSAGE_BLENDWEIGHT 0 D3DFVF_XYZBn + // D3DDECLTYPE_UBYTE4 D3DDECLUSAGE_BLENDINDICES 0 D3DFVF_XYZB(nWeights + 1) + // D3DDECLTYPE_FLOAT3 D3DDECLUSAGE_NORMAL 0 D3DFVF_NORMAL + // D3DDECLTYPE_FLOAT1 D3DDECLUSAGE_PSIZE 0 D3DFVF_PSIZE + // D3DDECLTYPE_D3DCOLOR D3DDECLUSAGE_COLOR 0 D3DFVF_DIFFUSE + // D3DDECLTYPE_D3DCOLOR D3DDECLUSAGE_COLOR 1 D3DFVF_SPECULAR + // D3DDECLTYPE_FLOATm D3DDECLUSAGE_TEXCOORD n D3DFVF_TEXCOORDSIZEm(n) + // D3DDECLTYPE_FLOAT3 D3DDECLUSAGE_POSITION 1 N / A + // D3DDECLTYPE_FLOAT3 D3DDECLUSAGE_NORMAL 1 N / A + + if (element.Usage == D3DDECLUSAGE_POSITION && element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0) + return D3DFVF_XYZ; + else if (element.Usage == D3DDECLUSAGE_POSITIONT && element.Type == D3DDECLTYPE_FLOAT4 && element.UsageIndex == 0) + return D3DFVF_XYZRHW; + else if (element.Usage == D3DDECLUSAGE_BLENDWEIGHT && element.UsageIndex == 0) { + DWORD fvfRet = MapD3DDeclTypeFloatToFvfXYZBn(element.Type); + if (likely(fvfRet != 0)) + return fvfRet; + else { + Logger::warn("D3D9VertexDecl::MapD3DDeclToFvf: Unsupported set of D3DDECLUSAGE_BLENDWEIGHT / D3DDECLTYPE_* / UsageIndex"); + return 0; + } + } + else if (element.Usage == D3DDECLUSAGE_BLENDINDICES && element.Type == D3DDECLTYPE_UBYTE4 && element.UsageIndex == 0) + return D3DFVF_XYZB1; + else if (element.Usage == D3DDECLUSAGE_NORMAL && element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0) + return D3DFVF_NORMAL; + else if (element.Usage == D3DDECLUSAGE_PSIZE && element.Type == D3DDECLTYPE_FLOAT1 && element.UsageIndex == 0) + return D3DFVF_PSIZE; + else if (element.Usage == D3DDECLUSAGE_COLOR && element.Type == D3DDECLTYPE_D3DCOLOR) { + switch (element.UsageIndex) + { + case 0: + return D3DFVF_DIFFUSE; + case 1: + return D3DFVF_SPECULAR; + default:; + Logger::warn("D3D9VertexDecl::MapD3DDeclToFvf: Unsupported set of D3DDECLUSAGE_COLOR / D3DDECLTYPE_D3DCOLOR / UsageIndex"); + return 0; + } + } + else if (element.Usage == D3DDECLUSAGE_TEXCOORD && element.UsageIndex < 8) { + DWORD retFvf = 0; + if (likely(MapD3DDeclUsageTexCoordToFvfTexCoordSize(element, fvf, retFvf, texCountPostUpdate))) + return retFvf; + else { + Logger::warn("D3D9VertexDecl::MapD3DDeclToFvf: Unsupported set of D3DDECLUSAGE_TEXCOORD / D3DDECLTYPE_* / UsageIndex"); + return 0; + } + } + + Logger::warn("D3D9VertexDecl::MapD3DDeclToFvf: Unsupported set of D3DDECLUSAGE_* / D3DDECLTYPE_* / UsageIndex"); + return 0; + } + + + DWORD D3D9VertexDecl::MapD3DDeclTypeFloatToFvfXYZBn(BYTE type) { + + switch (type) + { + default:; + return 0; + case D3DDECLTYPE_FLOAT1: + return D3DFVF_XYZB1; + case D3DDECLTYPE_FLOAT2: + return D3DFVF_XYZB2; + case D3DDECLTYPE_FLOAT3: + return D3DFVF_XYZB3; + case D3DDECLTYPE_FLOAT4: + return D3DFVF_XYZB4; + } + } + + + bool D3D9VertexDecl::MapD3DDeclUsageTexCoordToFvfTexCoordSize( + const D3DVERTEXELEMENT9& element, + DWORD fvf, + DWORD& outFvf, + DWORD& texCountPostUpdate) { + + // Check if bits of format for current UsageIndex are free in the fvf + // It is necessary to skip multiple initializations of the bitfield because + // returned value is bitwise or-ed to final fvf DWORD. + // The D3DFVF_TEXCOORDSIZE1 is used below because it covers all formats bits. + if ((D3DFVF_TEXCOORDSIZE1(element.UsageIndex) & fvf) != 0) + return false; + + // Update max texture's index in fvf + DWORD currentTexCount = element.UsageIndex + 1; + bool retStatus = true; + + if (texCountPostUpdate < currentTexCount) + texCountPostUpdate = currentTexCount; + + if (element.Type == D3DDECLTYPE_FLOAT1) + outFvf = D3DFVF_TEXCOORDSIZE1(element.UsageIndex); + else if (element.Type == D3DDECLTYPE_FLOAT2) + outFvf = D3DFVF_TEXCOORDSIZE2(element.UsageIndex); + else if (element.Type == D3DDECLTYPE_FLOAT3) + outFvf = D3DFVF_TEXCOORDSIZE3(element.UsageIndex); + else if (element.Type == D3DDECLTYPE_FLOAT4) + outFvf = D3DFVF_TEXCOORDSIZE4(element.UsageIndex); + else + retStatus = false; + + return retStatus; + } + + + DWORD D3D9VertexDecl::MapD3D9VertexElementsToFvf() { + DWORD fvf = 0; + DWORD texCountPostUpdate = 0; + + for (const auto& element : m_elements) + fvf |= MapD3DDeclToFvf(element, fvf, texCountPostUpdate); + + fvf |= (texCountPostUpdate << 8); + + return fvf; + } + void D3D9VertexDecl::Classify() { for (const auto& element : m_elements) { diff --git a/src/d3d9/d3d9_vertex_declaration.h b/src/d3d9/d3d9_vertex_declaration.h index 240aa6ed1..4652f1f8e 100644 --- a/src/d3d9/d3d9_vertex_declaration.h +++ b/src/d3d9/d3d9_vertex_declaration.h @@ -68,6 +68,21 @@ namespace dxvk { private: + DWORD MapD3DDeclToFvf( + const D3DVERTEXELEMENT9& element, + DWORD fvf, + DWORD& texCountPostUpdate); + + DWORD MapD3D9VertexElementsToFvf(); + + DWORD MapD3DDeclTypeFloatToFvfXYZBn(BYTE type); + + bool MapD3DDeclUsageTexCoordToFvfTexCoordSize( + const D3DVERTEXELEMENT9& element, + DWORD fvf, + DWORD& outFvf, + DWORD& texCountPostUpdate); + void Classify(); D3D9VertexDeclFlags m_flags; From 1451032b8334f4dd0aac789d8f417ca64bd37557 Mon Sep 17 00:00:00 2001 From: Joshie Date: Thu, 22 Sep 2022 10:46:51 +0100 Subject: [PATCH 0874/1348] [d3d9] Minor cleanups in vertex declaration code (#2950) --- src/d3d9/d3d9_vertex_declaration.cpp | 39 ++++++++++------------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/src/d3d9/d3d9_vertex_declaration.cpp b/src/d3d9/d3d9_vertex_declaration.cpp index 270c4a88f..f2acd733e 100644 --- a/src/d3d9/d3d9_vertex_declaration.cpp +++ b/src/d3d9/d3d9_vertex_declaration.cpp @@ -20,10 +20,8 @@ namespace dxvk { const D3DVERTEXELEMENT9* pVertexElements, uint32_t DeclCount) : D3D9VertexDeclBase( pDevice ) - , m_elements ( DeclCount ) - , m_fvf ( 0 ) { - std::copy(pVertexElements, pVertexElements + DeclCount, m_elements.begin()); - m_fvf = this->MapD3D9VertexElementsToFvf(); + , m_elements ( pVertexElements, pVertexElements + DeclCount ) + , m_fvf ( this->MapD3D9VertexElementsToFvf() ) { this->Classify(); } @@ -248,15 +246,12 @@ namespace dxvk { else if (element.Usage == D3DDECLUSAGE_PSIZE && element.Type == D3DDECLTYPE_FLOAT1 && element.UsageIndex == 0) return D3DFVF_PSIZE; else if (element.Usage == D3DDECLUSAGE_COLOR && element.Type == D3DDECLTYPE_D3DCOLOR) { - switch (element.UsageIndex) - { - case 0: - return D3DFVF_DIFFUSE; - case 1: - return D3DFVF_SPECULAR; - default:; - Logger::warn("D3D9VertexDecl::MapD3DDeclToFvf: Unsupported set of D3DDECLUSAGE_COLOR / D3DDECLTYPE_D3DCOLOR / UsageIndex"); - return 0; + switch (element.UsageIndex) { + case 0: return D3DFVF_DIFFUSE; + case 1: return D3DFVF_SPECULAR; + default: + Logger::warn("D3D9VertexDecl::MapD3DDeclToFvf: Unsupported set of D3DDECLUSAGE_COLOR / D3DDECLTYPE_D3DCOLOR / UsageIndex"); + return 0; } } else if (element.Usage == D3DDECLUSAGE_TEXCOORD && element.UsageIndex < 8) { @@ -276,18 +271,12 @@ namespace dxvk { DWORD D3D9VertexDecl::MapD3DDeclTypeFloatToFvfXYZBn(BYTE type) { - switch (type) - { - default:; - return 0; - case D3DDECLTYPE_FLOAT1: - return D3DFVF_XYZB1; - case D3DDECLTYPE_FLOAT2: - return D3DFVF_XYZB2; - case D3DDECLTYPE_FLOAT3: - return D3DFVF_XYZB3; - case D3DDECLTYPE_FLOAT4: - return D3DFVF_XYZB4; + switch (type) { + case D3DDECLTYPE_FLOAT1: return D3DFVF_XYZB1; + case D3DDECLTYPE_FLOAT2: return D3DFVF_XYZB2; + case D3DDECLTYPE_FLOAT3: return D3DFVF_XYZB3; + case D3DDECLTYPE_FLOAT4: return D3DFVF_XYZB4; + default: return 0; } } From ae2465079e8e4c0cee964bc370b87bb94527a782 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 21 Sep 2022 19:48:55 +0000 Subject: [PATCH 0875/1348] [d3d9] Add ID3D9VkInteropInterface Allows getting the VkInstance handle from a IDirect3D9 interface, as well as VkPhysicalDevices from adapter ordinals. --- src/d3d9/d3d9_interface.cpp | 8 +++++- src/d3d9/d3d9_interface.h | 3 +++ src/d3d9/d3d9_interfaces.h | 37 ++++++++++++++++++++++++++++ src/d3d9/d3d9_interop.cpp | 49 +++++++++++++++++++++++++++++++++++++ src/d3d9/d3d9_interop.h | 39 +++++++++++++++++++++++++++++ src/d3d9/meson.build | 3 ++- 6 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 src/d3d9/d3d9_interfaces.h create mode 100644 src/d3d9/d3d9_interop.cpp create mode 100644 src/d3d9/d3d9_interop.h diff --git a/src/d3d9/d3d9_interface.cpp b/src/d3d9/d3d9_interface.cpp index b729466fd..e78a7e32a 100644 --- a/src/d3d9/d3d9_interface.cpp +++ b/src/d3d9/d3d9_interface.cpp @@ -11,7 +11,8 @@ namespace dxvk { D3D9InterfaceEx::D3D9InterfaceEx(bool bExtended) : m_instance ( new DxvkInstance() ) , m_extended ( bExtended ) - , m_d3d9Options ( nullptr, m_instance->config() ) { + , m_d3d9Options ( nullptr, m_instance->config() ) + , m_d3d9Interop ( this ) { // D3D9 doesn't enumerate adapters like physical adapters... // only as connected displays. @@ -76,6 +77,11 @@ namespace dxvk { return S_OK; } + if (riid == __uuidof(ID3D9VkInteropInterface)) { + *ppvObject = ref(&m_d3d9Interop); + return S_OK; + } + Logger::warn("D3D9InterfaceEx::QueryInterface: Unknown interface query"); Logger::warn(str::format(riid)); return E_NOINTERFACE; diff --git a/src/d3d9/d3d9_interface.h b/src/d3d9/d3d9_interface.h index 85cc5a036..3fc9a43d3 100644 --- a/src/d3d9/d3d9_interface.h +++ b/src/d3d9/d3d9_interface.h @@ -1,6 +1,7 @@ #pragma once #include "d3d9_adapter.h" +#include "d3d9_interop.h" #include "../dxvk/dxvk_instance.h" @@ -143,6 +144,8 @@ namespace dxvk { std::vector m_adapters; + D3D9VkInteropInterface m_d3d9Interop; + }; } \ No newline at end of file diff --git a/src/d3d9/d3d9_interfaces.h b/src/d3d9/d3d9_interfaces.h new file mode 100644 index 000000000..9b4b77a2e --- /dev/null +++ b/src/d3d9/d3d9_interfaces.h @@ -0,0 +1,37 @@ +#pragma once + +#include "d3d9_include.h" +#include "../vulkan/vulkan_loader.h" + +/** + * \brief D3D9 interface for Vulkan interop + * + * Provides access to the instance and physical device + * handles for the given D3D9 interface and adapter ordinals. + */ +MIDL_INTERFACE("3461a81b-ce41-485b-b6b5-fcf08ba6a6bd") +ID3D9VkInteropInterface : public IUnknown { + /** + * \brief Queries Vulkan handles used by DXVK + * + * \param [out] pInstance The Vulkan instance + */ + virtual void STDMETHODCALLTYPE GetInstanceHandle( + VkInstance* pInstance) = 0; + + /** + * \brief Queries Vulkan handles used by DXVK + * + * \param [in] Adapter Adapter ordinal + * \param [out] pInstance The Vulkan instance + */ + virtual void STDMETHODCALLTYPE GetPhysicalDeviceHandle( + UINT Adapter, + VkPhysicalDevice* pPhysicalDevice) = 0; +}; + +#ifdef _MSC_VER +struct __declspec(uuid("3461a81b-ce41-485b-b6b5-fcf08ba6a6bd")) ID3D9VkInteropInterface; +#else +__CRT_UUID_DECL(ID3D9VkInteropInterface, 0x3461a81b,0xce41,0x485b,0xb6,0xb5,0xfc,0xf0,0x8b,0xa6,0xa6,0xbd); +#endif diff --git a/src/d3d9/d3d9_interop.cpp b/src/d3d9/d3d9_interop.cpp new file mode 100644 index 000000000..efa0c7b15 --- /dev/null +++ b/src/d3d9/d3d9_interop.cpp @@ -0,0 +1,49 @@ +#include "d3d9_interop.h" +#include "d3d9_interface.h" + +namespace dxvk { + + //////////////////////////////// + // Interface Interop + /////////////////////////////// + + D3D9VkInteropInterface::D3D9VkInteropInterface( + D3D9InterfaceEx* pInterface) + : m_interface(pInterface) { + + } + + D3D9VkInteropInterface::~D3D9VkInteropInterface() { + + } + + ULONG STDMETHODCALLTYPE D3D9VkInteropInterface::AddRef() { + return m_interface->AddRef(); + } + + ULONG STDMETHODCALLTYPE D3D9VkInteropInterface::Release() { + return m_interface->Release(); + } + + HRESULT STDMETHODCALLTYPE D3D9VkInteropInterface::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_interface->QueryInterface(riid, ppvObject); + } + + void STDMETHODCALLTYPE D3D9VkInteropInterface::GetInstanceHandle( + VkInstance* pInstance) { + if (pInstance != nullptr) + *pInstance = m_interface->GetInstance()->handle(); + } + + void STDMETHODCALLTYPE D3D9VkInteropInterface::GetPhysicalDeviceHandle( + UINT Adapter, + VkPhysicalDevice* pPhysicalDevice) { + if (pPhysicalDevice != nullptr) { + D3D9Adapter* adapter = m_interface->GetAdapter(Adapter); + *pPhysicalDevice = adapter ? adapter->GetDXVKAdapter()->handle() : nullptr; + } + } + +} diff --git a/src/d3d9/d3d9_interop.h b/src/d3d9/d3d9_interop.h new file mode 100644 index 000000000..2f7f9b344 --- /dev/null +++ b/src/d3d9/d3d9_interop.h @@ -0,0 +1,39 @@ +#pragma once + +#include "d3d9_interfaces.h" + +namespace dxvk { + + class D3D9InterfaceEx; + + class D3D9VkInteropInterface final : public ID3D9VkInteropInterface { + + public: + + D3D9VkInteropInterface( + D3D9InterfaceEx* pInterface); + + ~D3D9VkInteropInterface(); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + void STDMETHODCALLTYPE GetInstanceHandle( + VkInstance* pInstance); + + void STDMETHODCALLTYPE GetPhysicalDeviceHandle( + UINT Adapter, + VkPhysicalDevice* pPhysicalDevice); + + private: + + D3D9InterfaceEx* m_interface; + + }; + +} diff --git a/src/d3d9/meson.build b/src/d3d9/meson.build index 1af266270..bb5f3f387 100644 --- a/src/d3d9/meson.build +++ b/src/d3d9/meson.build @@ -42,7 +42,8 @@ d3d9_src = [ 'd3d9_hud.cpp', 'd3d9_annotation.cpp', 'd3d9_mem.cpp', - 'd3d9_window.cpp' + 'd3d9_window.cpp', + 'd3d9_interop.cpp' ] d3d9_dll = shared_library('d3d9'+dll_ext, d3d9_src, glsl_generator.process(d3d9_shaders), d3d9_res, From ac131126193379080c133e9689eed87d7aa1e48f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 21 Sep 2022 20:28:09 +0000 Subject: [PATCH 0876/1348] [d3d9] Add ID3D9VkInteropTexture Provides access to the backing resource of a D3D9 texture. --- src/d3d9/d3d9_common_texture.cpp | 3 +- src/d3d9/d3d9_common_texture.h | 6 +++ src/d3d9/d3d9_interfaces.h | 46 ++++++++++++++++++++++ src/d3d9/d3d9_interop.cpp | 67 ++++++++++++++++++++++++++++++++ src/d3d9/d3d9_interop.h | 33 ++++++++++++++++ src/d3d9/d3d9_surface.cpp | 2 +- src/d3d9/d3d9_texture.cpp | 15 +++++++ src/d3d9/d3d9_texture.h | 2 +- src/d3d9/d3d9_volume.cpp | 2 +- 9 files changed, 172 insertions(+), 4 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 5b5c07115..b50bec821 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -12,10 +12,11 @@ namespace dxvk { D3D9CommonTexture::D3D9CommonTexture( D3D9DeviceEx* pDevice, + IUnknown* pInterface, const D3D9_COMMON_TEXTURE_DESC* pDesc, D3DRESOURCETYPE ResourceType, HANDLE* pSharedHandle) - : m_device(pDevice), m_desc(*pDesc), m_type(ResourceType) { + : m_device(pDevice), m_desc(*pDesc), m_type(ResourceType), m_d3d9Interop(pInterface, this) { if (m_desc.Format == D3D9Format::Unknown) m_desc.Format = (m_desc.Usage & D3DUSAGE_DEPTHSTENCIL) ? D3D9Format::D32 diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index 58c0827ba..f0cf03f26 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -4,6 +4,7 @@ #include "d3d9_util.h" #include "d3d9_caps.h" #include "d3d9_mem.h" +#include "d3d9_interop.h" #include "../dxvk/dxvk_device.h" @@ -72,6 +73,7 @@ namespace dxvk { D3D9CommonTexture( D3D9DeviceEx* pDevice, + IUnknown* pInterface, const D3D9_COMMON_TEXTURE_DESC* pDesc, D3DRESOURCETYPE ResourceType, HANDLE* pSharedHandle); @@ -474,6 +476,8 @@ namespace dxvk { */ void CreateBufferSubresource(UINT Subresource, bool Initialize); + ID3D9VkInteropTexture* GetVkInterop() { return &m_d3d9Interop; } + private: D3D9DeviceEx* m_device; @@ -523,6 +527,8 @@ namespace dxvk { std::array m_dirtyBoxes; + D3D9VkInteropTexture m_d3d9Interop; + Rc CreatePrimaryImage(D3DRESOURCETYPE ResourceType, bool TryOffscreenRT, HANDLE* pSharedHandle) const; Rc CreateResolveImage() const; diff --git a/src/d3d9/d3d9_interfaces.h b/src/d3d9/d3d9_interfaces.h index 9b4b77a2e..065e95cbd 100644 --- a/src/d3d9/d3d9_interfaces.h +++ b/src/d3d9/d3d9_interfaces.h @@ -30,8 +30,54 @@ ID3D9VkInteropInterface : public IUnknown { VkPhysicalDevice* pPhysicalDevice) = 0; }; +/** + * \brief D3D9 texture interface for Vulkan interop + * + * Provides access to the backing resource of a + * D3D9 texture. + */ +MIDL_INTERFACE("d56344f5-8d35-46fd-806d-94c351b472c1") +ID3D9VkInteropTexture : public IUnknown { + /** + * \brief Retrieves Vulkan image info + * + * Retrieves both the image handle as well as the image's + * properties. Any of the given pointers may be \c nullptr. + * + * If \c pInfo is not \c nullptr, the following rules apply: + * - \c pInfo->sType \e must be \c VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO + * - \c pInfo->pNext \e must be \c nullptr or point to a supported + * extension-specific structure (currently none) + * - \c pInfo->queueFamilyIndexCount must be the length of the + * \c pInfo->pQueueFamilyIndices array, in \c uint32_t units. + * - \c pInfo->pQueueFamilyIndices must point to a pre-allocated + * array of \c uint32_t of size \c pInfo->pQueueFamilyIndices. + * + * \note As of now, the sharing mode will always be + * \c VK_SHARING_MODE_EXCLUSIVE and no queue + * family indices will be written to the array. + * + * After the call, the structure pointed to by \c pInfo can + * be used to create an image with identical properties. + * + * If \c pLayout is not \c nullptr, it will receive the + * layout that the image will be in after flushing any + * outstanding commands on the device. + * \param [out] pHandle The image handle + * \param [out] pLayout Image layout + * \param [out] pInfo Image properties + * \returns \c S_OK on success, or \c D3DERR_INVALIDCALL + */ + virtual HRESULT STDMETHODCALLTYPE GetVulkanImageInfo( + VkImage* pHandle, + VkImageLayout* pLayout, + VkImageCreateInfo* pInfo) = 0; +}; + #ifdef _MSC_VER struct __declspec(uuid("3461a81b-ce41-485b-b6b5-fcf08ba6a6bd")) ID3D9VkInteropInterface; +struct __declspec(uuid("d56344f5-8d35-46fd-806d-94c351b472c1")) ID3D9VkInteropTexture; #else __CRT_UUID_DECL(ID3D9VkInteropInterface, 0x3461a81b,0xce41,0x485b,0xb6,0xb5,0xfc,0xf0,0x8b,0xa6,0xa6,0xbd); +__CRT_UUID_DECL(ID3D9VkInteropTexture, 0xd56344f5,0x8d35,0x46fd,0x80,0x6d,0x94,0xc3,0x51,0xb4,0x72,0xc1); #endif diff --git a/src/d3d9/d3d9_interop.cpp b/src/d3d9/d3d9_interop.cpp index efa0c7b15..64ac0b367 100644 --- a/src/d3d9/d3d9_interop.cpp +++ b/src/d3d9/d3d9_interop.cpp @@ -1,5 +1,6 @@ #include "d3d9_interop.h" #include "d3d9_interface.h" +#include "d3d9_common_texture.h" namespace dxvk { @@ -46,4 +47,70 @@ namespace dxvk { } } + //////////////////////////////// + // Texture Interop + /////////////////////////////// + + D3D9VkInteropTexture::D3D9VkInteropTexture( + IUnknown* pInterface, + D3D9CommonTexture* pTexture) + : m_interface(pInterface) + , m_texture (pTexture) { + + } + + D3D9VkInteropTexture::~D3D9VkInteropTexture() { + + } + + ULONG STDMETHODCALLTYPE D3D9VkInteropTexture::AddRef() { + return m_interface->AddRef(); + } + + ULONG STDMETHODCALLTYPE D3D9VkInteropTexture::Release() { + return m_interface->Release(); + } + + HRESULT STDMETHODCALLTYPE D3D9VkInteropTexture::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_interface->QueryInterface(riid, ppvObject); + } + + HRESULT STDMETHODCALLTYPE D3D9VkInteropTexture::GetVulkanImageInfo( + VkImage* pHandle, + VkImageLayout* pLayout, + VkImageCreateInfo* pInfo) { + const Rc image = m_texture->GetImage(); + const DxvkImageCreateInfo& info = image->info(); + + if (pHandle != nullptr) + *pHandle = image->handle(); + + if (pLayout != nullptr) + *pLayout = info.layout; + + if (pInfo != nullptr) { + // We currently don't support any extended structures + if (pInfo->sType != VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO + || pInfo->pNext != nullptr) + return D3DERR_INVALIDCALL; + + pInfo->flags = 0; + pInfo->imageType = info.type; + pInfo->format = info.format; + pInfo->extent = info.extent; + pInfo->mipLevels = info.mipLevels; + pInfo->arrayLayers = info.numLayers; + pInfo->samples = info.sampleCount; + pInfo->tiling = info.tiling; + pInfo->usage = info.usage; + pInfo->sharingMode = VK_SHARING_MODE_EXCLUSIVE; + pInfo->queueFamilyIndexCount = 0; + pInfo->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + } + + return S_OK; + } + } diff --git a/src/d3d9/d3d9_interop.h b/src/d3d9/d3d9_interop.h index 2f7f9b344..30596696f 100644 --- a/src/d3d9/d3d9_interop.h +++ b/src/d3d9/d3d9_interop.h @@ -5,6 +5,7 @@ namespace dxvk { class D3D9InterfaceEx; + class D3D9CommonTexture; class D3D9VkInteropInterface final : public ID3D9VkInteropInterface { @@ -36,4 +37,36 @@ namespace dxvk { }; + class D3D9VkInteropTexture final : public ID3D9VkInteropTexture { + + public: + + D3D9VkInteropTexture( + IUnknown* pInterface, + D3D9CommonTexture* pTexture); + + ~D3D9VkInteropTexture(); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + HRESULT STDMETHODCALLTYPE GetVulkanImageInfo( + VkImage* pHandle, + VkImageLayout* pLayout, + VkImageCreateInfo* pInfo); + + D3D9CommonTexture* GetCommonTexture() { return m_texture; } + + private: + + IUnknown* m_interface; + D3D9CommonTexture* m_texture; + + }; + } diff --git a/src/d3d9/d3d9_surface.cpp b/src/d3d9/d3d9_surface.cpp index 1ff2b4e33..91f917853 100644 --- a/src/d3d9/d3d9_surface.cpp +++ b/src/d3d9/d3d9_surface.cpp @@ -15,7 +15,7 @@ namespace dxvk { HANDLE* pSharedHandle) : D3D9SurfaceBase( pDevice, - new D3D9CommonTexture( pDevice, pDesc, D3DRTYPE_SURFACE, pSharedHandle), + new D3D9CommonTexture( pDevice, this, pDesc, D3DRTYPE_SURFACE, pSharedHandle), 0, 0, nullptr, pContainer) { } diff --git a/src/d3d9/d3d9_texture.cpp b/src/d3d9/d3d9_texture.cpp index 2f1d3ce6e..e1e3547c3 100644 --- a/src/d3d9/d3d9_texture.cpp +++ b/src/d3d9/d3d9_texture.cpp @@ -27,6 +27,11 @@ namespace dxvk { return S_OK; } + if (riid == __uuidof(ID3D9VkInteropTexture)) { + *ppvObject = ref(m_texture.GetVkInterop()); + return S_OK; + } + Logger::warn("D3D9Texture2D::QueryInterface: Unknown interface query"); Logger::warn(str::format(riid)); return E_NOINTERFACE; @@ -118,6 +123,11 @@ namespace dxvk { return S_OK; } + if (riid == __uuidof(ID3D9VkInteropTexture)) { + *ppvObject = ref(m_texture.GetVkInterop()); + return S_OK; + } + Logger::warn("D3D9Texture3D::QueryInterface: Unknown interface query"); Logger::warn(str::format(riid)); return E_NOINTERFACE; @@ -203,6 +213,11 @@ namespace dxvk { return S_OK; } + if (riid == __uuidof(ID3D9VkInteropTexture)) { + *ppvObject = ref(m_texture.GetVkInterop()); + return S_OK; + } + Logger::warn("D3D9TextureCube::QueryInterface: Unknown interface query"); Logger::warn(str::format(riid)); return E_NOINTERFACE; diff --git a/src/d3d9/d3d9_texture.h b/src/d3d9/d3d9_texture.h index 317f72ee5..fe9ff638a 100644 --- a/src/d3d9/d3d9_texture.h +++ b/src/d3d9/d3d9_texture.h @@ -26,7 +26,7 @@ namespace dxvk { D3DRESOURCETYPE ResourceType, HANDLE* pSharedHandle) : D3D9Resource ( pDevice ) - , m_texture ( pDevice, pDesc, ResourceType, pSharedHandle ) + , m_texture ( pDevice, this, pDesc, ResourceType, pSharedHandle ) , m_lod ( 0 ) { const uint32_t arraySlices = m_texture.Desc()->ArraySize; const uint32_t mipLevels = m_texture.Desc()->MipLevels; diff --git a/src/d3d9/d3d9_volume.cpp b/src/d3d9/d3d9_volume.cpp index 52886d80b..dff931f25 100644 --- a/src/d3d9/d3d9_volume.cpp +++ b/src/d3d9/d3d9_volume.cpp @@ -10,7 +10,7 @@ namespace dxvk { const D3D9_COMMON_TEXTURE_DESC* pDesc) : D3D9VolumeBase( pDevice, - new D3D9CommonTexture( pDevice, pDesc, D3DRTYPE_VOLUMETEXTURE, nullptr ), + new D3D9CommonTexture( pDevice, this, pDesc, D3DRTYPE_VOLUMETEXTURE, nullptr ), 0, 0, nullptr, nullptr) { } From e976218e1786ad88622dc2e53ed3bfe2000ddc77 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 21 Sep 2022 20:33:45 +0000 Subject: [PATCH 0877/1348] [d3d9] Make GetDXVKDevice return a const Rc reference Avoids some useless reffing. --- src/d3d9/d3d9_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 1e3750e69..7b4a7c52e 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -670,7 +670,7 @@ namespace dxvk { HWND GetWindow(); - Rc GetDXVKDevice() { + const Rc& GetDXVKDevice() { return m_dxvkDevice; } From d221bb7a9c4c412b7406ce868ccd0084d9ab2682 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 21 Sep 2022 21:02:36 +0000 Subject: [PATCH 0878/1348] [d3d9] Add ID3D9VkInteropDevice Provides access to the device and instance handles as well as the queue that is used for rendering. --- src/d3d9/d3d9_device.cpp | 8 ++- src/d3d9/d3d9_device.h | 4 ++ src/d3d9/d3d9_interfaces.h | 124 ++++++++++++++++++++++++++++++++++++ src/d3d9/d3d9_interop.cpp | 126 +++++++++++++++++++++++++++++++++++++ src/d3d9/d3d9_interop.h | 56 +++++++++++++++++ 5 files changed, 317 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index cbe5404f2..facd03d18 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -54,7 +54,8 @@ namespace dxvk { , m_multithread ( BehaviorFlags & D3DCREATE_MULTITHREADED ) , m_isSWVP ( (BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) ? true : false ) , m_csThread ( dxvkDevice, dxvkDevice->createContext(DxvkContextType::Primary) ) - , m_csChunk ( AllocCsChunk() ) { + , m_csChunk ( AllocCsChunk() ) + , m_d3d9Interop ( this ) { // If we can SWVP, then we use an extended constant set // as SWVP has many more slots available than HWVP. bool canSWVP = CanSWVP(); @@ -191,6 +192,11 @@ namespace dxvk { return S_OK; } + if (riid == __uuidof(ID3D9VkInteropDevice)) { + *ppvObject = ref(&m_d3d9Interop); + return S_OK; + } + // We want to ignore this if the extended device is queried and we weren't made extended. if (riid == __uuidof(IDirect3DDevice9Ex)) return E_NOINTERFACE; diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 7b4a7c52e..bc04b35eb 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -27,6 +27,7 @@ #include "d3d9_swvp_emu.h" #include "d3d9_spec_constants.h" +#include "d3d9_interop.h" #include #include @@ -118,6 +119,7 @@ namespace dxvk { friend class D3D9SwapChainEx; friend class D3D9ConstantBuffer; friend class D3D9UserDefinedAnnotation; + friend D3D9VkInteropDevice; public: D3D9DeviceEx( @@ -1317,6 +1319,8 @@ namespace dxvk { #ifdef D3D9_ALLOW_UNMAPPING lru_list m_mappedTextures; #endif + + D3D9VkInteropDevice m_d3d9Interop; }; } diff --git a/src/d3d9/d3d9_interfaces.h b/src/d3d9/d3d9_interfaces.h index 065e95cbd..48fbed9c6 100644 --- a/src/d3d9/d3d9_interfaces.h +++ b/src/d3d9/d3d9_interfaces.h @@ -74,10 +74,134 @@ ID3D9VkInteropTexture : public IUnknown { VkImageCreateInfo* pInfo) = 0; }; +/** + * \brief D3D9 device interface for Vulkan interop + * + * Provides access to the device and instance handles + * as well as the queue that is used for rendering. + */ +MIDL_INTERFACE("2eaa4b89-0107-4bdb-87f7-0f541c493ce0") +ID3D9VkInteropDevice : public IUnknown { + /** + * \brief Queries Vulkan handles used by DXVK + * + * \param [out] pInstance The Vulkan instance + * \param [out] pPhysDev The physical device + * \param [out] pDevide The device handle + */ + virtual void STDMETHODCALLTYPE GetVulkanHandles( + VkInstance* pInstance, + VkPhysicalDevice* pPhysDev, + VkDevice* pDevice) = 0; + + /** + * \brief Queries the rendering queue used by DXVK + * + * \param [out] pQueue The Vulkan queue handle + * \param [out] pQueueIndex Queue index + * \param [out] pQueueFamilyIndex Queue family index + */ + virtual void STDMETHODCALLTYPE GetSubmissionQueue( + VkQueue* pQueue, + uint32_t* pQueueIndex, + uint32_t* pQueueFamilyIndex) = 0; + + /** + * \brief Transitions a Texture to a given layout + * + * Executes an explicit image layout transition on the + * D3D device. Note that the image subresources \e must + * be transitioned back to its original layout before + * using it again from D3D9. + * Synchronization is left up to the caller. + * This function merely emits a call to transition the + * texture on the DXVK internal command stream. + * \param [in] pTexture The image to transform + * \param [in] pSubresources Subresources to transform + * \param [in] OldLayout Current image layout + * \param [in] NewLayout Desired image layout + */ + virtual void STDMETHODCALLTYPE TransitionTextureLayout( + ID3D9VkInteropTexture* pTexture, + const VkImageSubresourceRange* pSubresources, + VkImageLayout OldLayout, + VkImageLayout NewLayout) = 0; + + /** + * \brief Flushes outstanding D3D rendering commands + * + * Must be called before submitting Vulkan commands + * to the rendering queue if those commands use the + * backing resource of a D3D9 object. + */ + virtual void STDMETHODCALLTYPE FlushRenderingCommands() = 0; + + /** + * \brief Locks submission queue + * + * Should be called immediately before submitting + * Vulkan commands to the rendering queue in order + * to prevent DXVK from using the queue. + * + * While the submission queue is locked, no D3D9 + * methods must be called from the locking thread, + * or otherwise a deadlock might occur. + */ + virtual void STDMETHODCALLTYPE LockSubmissionQueue() = 0; + + /** + * \brief Releases submission queue + * + * Should be called immediately after submitting + * Vulkan commands to the rendering queue in order + * to allow DXVK to submit new commands. + */ + virtual void STDMETHODCALLTYPE ReleaseSubmissionQueue() = 0; + + /** + * \brief Locks the device + * + * Can be called to ensure no D3D9 device methods + * can be executed until UnlockDevice has been called. + * + * This will do nothing if the D3DCREATE_MULTITHREADED + * is not set. + */ + virtual void STDMETHODCALLTYPE LockDevice() = 0; + + /** + * \brief Unlocks the device + * + * Must only be called after a call to LockDevice. + */ + virtual void STDMETHODCALLTYPE UnlockDevice() = 0; + + /** + * \brief Wait for a resource to finish being used + * + * Waits for the GPU resource associated with the + * resource to finish being used by the GPU. + * + * Valid D3DLOCK flags: + * - D3DLOCK_READONLY: Only waits for writes + * - D3DLOCK_DONOTWAIT: Does not wait for the resource (may flush) + * + * \param [in] pResource Resource to be waited upon + * \param [in] MapFlags D3DLOCK flags + * \returns true if the resource is ready to use, + * false if the resource is till in use + */ + virtual bool STDMETHODCALLTYPE WaitForResource( + IDirect3DResource9* pResource, + DWORD MapFlags) = 0; +}; + #ifdef _MSC_VER struct __declspec(uuid("3461a81b-ce41-485b-b6b5-fcf08ba6a6bd")) ID3D9VkInteropInterface; struct __declspec(uuid("d56344f5-8d35-46fd-806d-94c351b472c1")) ID3D9VkInteropTexture; +struct __declspec(uuid("2eaa4b89-0107-4bdb-87f7-0f541c493ce0")) ID3D9VkInteropDevice; #else __CRT_UUID_DECL(ID3D9VkInteropInterface, 0x3461a81b,0xce41,0x485b,0xb6,0xb5,0xfc,0xf0,0x8b,0xa6,0xa6,0xbd); __CRT_UUID_DECL(ID3D9VkInteropTexture, 0xd56344f5,0x8d35,0x46fd,0x80,0x6d,0x94,0xc3,0x51,0xb4,0x72,0xc1); +__CRT_UUID_DECL(ID3D9VkInteropDevice, 0x2eaa4b89,0x0107,0x4bdb,0x87,0xf7,0x0f,0x54,0x1c,0x49,0x3c,0xe0); #endif diff --git a/src/d3d9/d3d9_interop.cpp b/src/d3d9/d3d9_interop.cpp index 64ac0b367..6f072f620 100644 --- a/src/d3d9/d3d9_interop.cpp +++ b/src/d3d9/d3d9_interop.cpp @@ -1,6 +1,9 @@ #include "d3d9_interop.h" #include "d3d9_interface.h" #include "d3d9_common_texture.h" +#include "d3d9_device.h" +#include "d3d9_texture.h" +#include "d3d9_buffer.h" namespace dxvk { @@ -113,4 +116,127 @@ namespace dxvk { return S_OK; } + //////////////////////////////// + // Device Interop + /////////////////////////////// + + D3D9VkInteropDevice::D3D9VkInteropDevice( + D3D9DeviceEx* pInterface) + : m_device(pInterface) { + + } + + D3D9VkInteropDevice::~D3D9VkInteropDevice() { + + } + + ULONG STDMETHODCALLTYPE D3D9VkInteropDevice::AddRef() { + return m_device->AddRef(); + } + + ULONG STDMETHODCALLTYPE D3D9VkInteropDevice::Release() { + return m_device->Release(); + } + + HRESULT STDMETHODCALLTYPE D3D9VkInteropDevice::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_device->QueryInterface(riid, ppvObject); + } + + void STDMETHODCALLTYPE D3D9VkInteropDevice::GetVulkanHandles( + VkInstance* pInstance, + VkPhysicalDevice* pPhysDev, + VkDevice* pDevice) { + auto device = m_device->GetDXVKDevice(); + auto adapter = device->adapter(); + auto instance = device->instance(); + + if (pDevice != nullptr) + *pDevice = device->handle(); + + if (pPhysDev != nullptr) + *pPhysDev = adapter->handle(); + + if (pInstance != nullptr) + *pInstance = instance->handle(); + } + + void STDMETHODCALLTYPE D3D9VkInteropDevice::GetSubmissionQueue( + VkQueue* pQueue, + uint32_t* pQueueIndex, + uint32_t* pQueueFamilyIndex) { + auto device = m_device->GetDXVKDevice(); + DxvkDeviceQueue queue = device->queues().graphics; + + if (pQueue != nullptr) + *pQueue = queue.queueHandle; + + if (pQueueIndex != nullptr) + *pQueueIndex = queue.queueIndex; + + if (pQueueFamilyIndex != nullptr) + *pQueueFamilyIndex = queue.queueFamily; + } + + void STDMETHODCALLTYPE D3D9VkInteropDevice::TransitionTextureLayout( + ID3D9VkInteropTexture* pTexture, + const VkImageSubresourceRange* pSubresources, + VkImageLayout OldLayout, + VkImageLayout NewLayout) { + auto texture = static_cast(pTexture)->GetCommonTexture(); + + m_device->EmitCs([ + cImage = texture->GetImage(), + cSubresources = *pSubresources, + cOldLayout = OldLayout, + cNewLayout = NewLayout + ] (DxvkContext* ctx) { + ctx->transformImage( + cImage, cSubresources, + cOldLayout, cNewLayout); + }); + } + + void STDMETHODCALLTYPE D3D9VkInteropDevice::FlushRenderingCommands() { + m_device->Flush(); + m_device->SynchronizeCsThread(DxvkCsThread::SynchronizeAll); + } + + void STDMETHODCALLTYPE D3D9VkInteropDevice::LockSubmissionQueue() { + m_device->GetDXVKDevice()->lockSubmission(); + } + + void STDMETHODCALLTYPE D3D9VkInteropDevice::ReleaseSubmissionQueue() { + m_device->GetDXVKDevice()->unlockSubmission(); + } + + void STDMETHODCALLTYPE D3D9VkInteropDevice::LockDevice() { + m_lock = m_device->LockDevice(); + } + + void STDMETHODCALLTYPE D3D9VkInteropDevice::UnlockDevice() { + m_lock = D3D9DeviceLock(); + } + + static Rc GetDxvkResource(IDirect3DResource9 *pResource) { + switch (pResource->GetType()) { + case D3DRTYPE_SURFACE: return static_cast (pResource)->GetCommonTexture()->GetImage(); + // Does not inherit from IDirect3DResource9... lol. + //case D3DRTYPE_VOLUME: return static_cast (pResource)->GetCommonTexture()->GetImage(); + case D3DRTYPE_TEXTURE: return static_cast (pResource)->GetCommonTexture()->GetImage(); + case D3DRTYPE_VOLUMETEXTURE: return static_cast (pResource)->GetCommonTexture()->GetImage(); + case D3DRTYPE_CUBETEXTURE: return static_cast (pResource)->GetCommonTexture()->GetImage(); + case D3DRTYPE_VERTEXBUFFER: return static_cast(pResource)->GetCommonBuffer()->GetBuffer(); + case D3DRTYPE_INDEXBUFFER: return static_cast (pResource)->GetCommonBuffer()->GetBuffer(); + default: return nullptr; + } + } + + bool STDMETHODCALLTYPE D3D9VkInteropDevice::WaitForResource( + IDirect3DResource9* pResource, + DWORD MapFlags) { + return m_device->WaitForResource(GetDxvkResource(pResource), DxvkCsThread::SynchronizeAll, MapFlags); + } + } diff --git a/src/d3d9/d3d9_interop.h b/src/d3d9/d3d9_interop.h index 30596696f..742f69a9b 100644 --- a/src/d3d9/d3d9_interop.h +++ b/src/d3d9/d3d9_interop.h @@ -1,11 +1,13 @@ #pragma once #include "d3d9_interfaces.h" +#include "d3d9_multithread.h" namespace dxvk { class D3D9InterfaceEx; class D3D9CommonTexture; + class D3D9DeviceEx; class D3D9VkInteropInterface final : public ID3D9VkInteropInterface { @@ -69,4 +71,58 @@ namespace dxvk { }; + class D3D9VkInteropDevice final : public ID3D9VkInteropDevice { + + public: + + D3D9VkInteropDevice( + D3D9DeviceEx* pInterface); + + ~D3D9VkInteropDevice(); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + void STDMETHODCALLTYPE GetVulkanHandles( + VkInstance* pInstance, + VkPhysicalDevice* pPhysDev, + VkDevice* pDevice); + + void STDMETHODCALLTYPE GetSubmissionQueue( + VkQueue* pQueue, + uint32_t* pQueueIndex, + uint32_t* pQueueFamilyIndex); + + void STDMETHODCALLTYPE TransitionTextureLayout( + ID3D9VkInteropTexture* pTexture, + const VkImageSubresourceRange* pSubresources, + VkImageLayout OldLayout, + VkImageLayout NewLayout); + + void STDMETHODCALLTYPE FlushRenderingCommands(); + + void STDMETHODCALLTYPE LockSubmissionQueue(); + + void STDMETHODCALLTYPE ReleaseSubmissionQueue(); + + void STDMETHODCALLTYPE LockDevice(); + + void STDMETHODCALLTYPE UnlockDevice(); + + bool STDMETHODCALLTYPE WaitForResource( + IDirect3DResource9* pResource, + DWORD MapFlags); + + private: + + D3D9DeviceEx* m_device; + D3D9DeviceLock m_lock; + + }; + } From f2950953e0d03e62070c234db6edc7974211365f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 11 Aug 2021 12:24:50 +0100 Subject: [PATCH 0879/1348] [d3d9] Avoid depth degenerate viewports --- src/d3d9/d3d9_device.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index facd03d18..1ab628fb7 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5624,12 +5624,16 @@ namespace dxvk { // Originally we did this only for powers of two // resolutions but since NEAREST filtering fixed to // truncate, we need to do this all the time now. - float cf = 0.5f - (1.0f / 128.0f); + constexpr float cf = 0.5f - (1.0f / 128.0f); + + // How much to bias MinZ by to avoid a depth + // degenerate viewport. + constexpr float zBias = 0.001f; viewport = VkViewport{ float(vp.X) + cf, float(vp.Height + vp.Y) + cf, float(vp.Width), -float(vp.Height), - vp.MinZ, vp.MaxZ, + vp.MinZ, std::max(vp.MaxZ, vp.MinZ + zBias), }; // Scissor rectangles. Vulkan does not provide an easy way From 15588004b4570bc3804070a4db48da2a0b1be2a3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 22 Sep 2022 02:32:20 +0200 Subject: [PATCH 0880/1348] [dxvk] Bump memory chunk size to 256 MiB. --- src/dxvk/dxvk_memory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index c51f2ea7d..aca642969 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -483,8 +483,8 @@ namespace dxvk { VkMemoryType type = m_memProps.memoryTypes[memTypeId]; VkMemoryHeap heap = m_memProps.memoryHeaps[type.heapIndex]; - // Default to a chunk size of 128 MiB - VkDeviceSize chunkSize = 128 << 20; + // Default to a chunk size of 256 MiB + VkDeviceSize chunkSize = 256 << 20; if (hints.test(DxvkMemoryFlag::Small)) chunkSize = 16 << 20; From f1f8d45fcdcf0018941fbd1f43460cd0a793786c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 22 Sep 2022 16:37:41 +0200 Subject: [PATCH 0881/1348] [dxvk] Rework allocation logic for large resources This may reduce internal fragmentation with very large resources. We previously changed behaviour to not do this in order to reduce memory pressure in the average case, however by trying to suballocate from existing chunks and falling back to a dedicated allocation on failure, rather than allocating a new chunk, we can mostly avoid that situation. --- src/dxvk/dxvk_memory.cpp | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index aca642969..af4760b5e 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -326,19 +326,25 @@ namespace dxvk { DxvkMemory memory; - if (size >= chunkSize || info.dedicated.buffer || info.dedicated.image) { - if (this->shouldFreeEmptyChunks(type->heap, size)) - this->freeEmptyChunks(type->heap); + // Require dedicated allocations for resources that use the Vulkan dedicated + // allocation bits, or are too large to fit into a single full-sized chunk + bool needsDedicatedAlocation = size >= chunkSize || info.dedicated.buffer || info.dedicated.image; - DxvkDeviceMemory devMem = this->tryAllocDeviceMemory(type, size, info, hints); + // Prefer a dedicated allocation for very large resources in order to + // reduce fragmentation if a large number of those resources are in use + bool wantsDedicatedAllocation = 3 * size >= chunkSize; - if (devMem.memHandle != VK_NULL_HANDLE) - memory = DxvkMemory(this, nullptr, type, devMem.memHandle, 0, size, devMem.memPointer); - } else { + // Try to reuse existing memory as much as possible in case the heap is nearly full + bool heapBudgedExceeded = 5 * type->heap->stats.memoryUsed + size > 4 * type->heap->properties.size; + + if (!needsDedicatedAlocation && (!wantsDedicatedAllocation || heapBudgedExceeded)) { + // Attempt to suballocate from existing chunks first for (uint32_t i = 0; i < type->chunks.size() && !memory; i++) memory = type->chunks[i]->alloc(info.flags, size, align, hints); - if (!memory) { + // If no existing chunk can accomodate the allocation, and if a dedicated + // allocation is not preferred, create a new chunk and suballocate from it + if (!memory && !wantsDedicatedAllocation) { DxvkDeviceMemory devMem; if (this->shouldFreeEmptyChunks(type->heap, chunkSize)) @@ -356,6 +362,18 @@ namespace dxvk { } } + // If a dedicated allocation is required or preferred and we haven't managed + // to suballocate any memory before, try to create a dedicated allocation + if (!memory && (needsDedicatedAlocation || wantsDedicatedAllocation)) { + if (this->shouldFreeEmptyChunks(type->heap, size)) + this->freeEmptyChunks(type->heap); + + DxvkDeviceMemory devMem = this->tryAllocDeviceMemory(type, size, info, hints); + + if (devMem.memHandle != VK_NULL_HANDLE) + memory = DxvkMemory(this, nullptr, type, devMem.memHandle, 0, size, devMem.memPointer); + } + if (memory) type->heap->stats.memoryUsed += memory.m_length; From 7552cfe62ad86dda0f48295d6e440096d8c88344 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Mon, 26 Sep 2022 14:14:37 +0200 Subject: [PATCH 0882/1348] [dxso] Always lower projection --- src/dxso/dxso_compiler.cpp | 133 +++++++++++-------------------------- src/dxso/dxso_compiler.h | 1 - 2 files changed, 40 insertions(+), 94 deletions(-) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 0c8a4c6fe..cb1ce67dd 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -2648,10 +2648,30 @@ void DxsoCompiler::emitControlFlowGenericLoop( DxsoRegMask vec3Mask(true, true, true, false); DxsoRegMask srcMask (true, true, true, true); - auto GetProjectionValue = [&]() { + auto DoProjection = [&](DxsoRegisterValue coord, bool switchProjRes) { + uint32_t bool_t = m_module.defBoolType(); + uint32_t texcoord_t = getVectorTypeId(coord.type); + uint32_t w = 3; - return m_module.opCompositeExtract( - m_module.defFloatType(32), texcoordVar.id, 1, &w); + + uint32_t projScalar = m_module.opCompositeExtract( + m_module.defFloatType(32), coord.id, 1, &w); + + projScalar = m_module.opFDiv(m_module.defFloatType(32), m_module.constf32(1.0), projScalar); + uint32_t projResult = m_module.opVectorTimesScalar(texcoord_t, coord.id, projScalar); + + if (switchProjRes) { + uint32_t shouldProj = m_spec.get(m_module, m_specUbo, SpecProjectionType, samplerIdx, 1); + shouldProj = m_module.opINotEqual(bool_t, shouldProj, m_module.constu32(0)); + + uint32_t bvec4_t = m_module.defVectorType(bool_t, 4); + std::array indices = { shouldProj, shouldProj, shouldProj, shouldProj }; + shouldProj = m_module.opCompositeConstruct(bvec4_t, indices.size(), indices.data()); + + return m_module.opSelect(texcoord_t, shouldProj, projResult, coord.id); + } else { + return projResult; + } }; if (opcode == DxsoOpcode::TexM3x2Tex || opcode == DxsoOpcode::TexM3x3Tex || opcode == DxsoOpcode::TexM3x3Spec || opcode == DxsoOpcode::TexM3x3VSpec) { @@ -2711,23 +2731,9 @@ void DxsoCompiler::emitControlFlowGenericLoop( texcoordVar = m; samplerIdx = ctx.dst.id.num; - uint32_t texcoord_t = getVectorTypeId(texcoordVar.type); - // The projection (/.w) happens before this... // Of course it does... - uint32_t bool_t = m_module.defBoolType(); - - uint32_t shouldProj = m_spec.get(m_module, m_specUbo, SpecProjectionType, samplerIdx, 1); - shouldProj = m_module.opINotEqual(bool_t, shouldProj, m_module.constu32(0)); - - uint32_t bvec4_t = m_module.defVectorType(bool_t, 4); - std::array indices = { shouldProj, shouldProj, shouldProj, shouldProj }; - shouldProj = m_module.opCompositeConstruct(bvec4_t, indices.size(), indices.data()); - - uint32_t projScalar = m_module.opFDiv(m_module.defFloatType(32), m_module.constf32(1.0), GetProjectionValue()); - uint32_t projResult = m_module.opVectorTimesScalar(texcoord_t, texcoordVar.id, projScalar); - - texcoordVar.id = m_module.opSelect(texcoord_t, shouldProj, projResult, texcoordVar.id); + texcoordVar.id = DoProjection(texcoordVar, true); // u' = tc(m).x + [bm00(m) * t(n).x + bm10(m) * t(n).y] // v' = tc(m).y + [bm01(m) * t(n).x + bm11(m) * t(n).y] @@ -2811,7 +2817,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( DxsoSampler sampler = m_samplers.at(samplerIdx); - auto SampleImage = [this, opcode, dst, ctx, samplerIdx, GetProjectionValue](DxsoRegisterValue texcoordVar, DxsoSamplerInfo& sampler, bool depth, DxsoSamplerType samplerType, uint32_t isNull) { + auto SampleImage = [this, opcode, dst, ctx, samplerIdx, DoProjection](DxsoRegisterValue texcoordVar, DxsoSamplerInfo& sampler, bool depth, DxsoSamplerType samplerType, uint32_t isNull) { DxsoRegisterValue result; result.type.ctype = dst.type.ctype; result.type.ccount = depth ? 1 : 4; @@ -2838,12 +2844,10 @@ void DxsoCompiler::emitControlFlowGenericLoop( imageOperands.sGradY = emitRegisterLoad(ctx.src[3], gradMask).id; } - uint32_t projDivider = 0; - if (opcode == DxsoOpcode::Tex && m_programInfo.majorVersion() >= 2) { if (ctx.instruction.specificData.texld == DxsoTexLdMode::Project) { - projDivider = GetProjectionValue(); + texcoordVar.id = DoProjection(texcoordVar, false); } else if (ctx.instruction.specificData.texld == DxsoTexLdMode::Bias) { uint32_t w = 3; @@ -2853,15 +2857,9 @@ void DxsoCompiler::emitControlFlowGenericLoop( } } - bool switchProjResult = m_programInfo.majorVersion() < 2 && samplerType != SamplerTypeTextureCube; - - if (switchProjResult) - projDivider = GetProjectionValue(); - - // We already handled this... - if (opcode == DxsoOpcode::TexBem) { - switchProjResult = false; - projDivider = 0; + // We already handled this for TexBem(L) + if (m_programInfo.majorVersion() < 2 && samplerType != SamplerTypeTextureCube && opcode != DxsoOpcode::TexBem && opcode != DxsoOpcode::TexBemL) { + texcoordVar.id = DoProjection(texcoordVar, true); } uint32_t reference = 0; @@ -2872,13 +2870,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( m_module.defFloatType(32), texcoordVar.id, 1, &component); } - if (projDivider != 0) { - for (uint32_t i = sampler.dimensions; i < 4; i++) { - texcoordVar.id = m_module.opCompositeInsert(getVectorTypeId(texcoordVar.type), - projDivider, texcoordVar.id, 1, &i); - } - } - uint32_t fetch4 = 0; if (m_programInfo.type() == DxsoProgramType::PixelShader && samplerType != SamplerTypeTexture3D) { fetch4 = m_spec.get(m_module, m_specUbo, SpecFetch4, samplerIdx, 1); @@ -2892,7 +2883,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( } result.id = this->emitSample( - projDivider != 0, typeId, sampler, texcoordVar, @@ -2900,33 +2890,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( fetch4, imageOperands); - if (switchProjResult) { - uint32_t bool_t = m_module.defBoolType(); - - uint32_t nonProjResult = this->emitSample( - 0, - typeId, - sampler, - texcoordVar, - reference, - fetch4, - imageOperands); - - uint32_t shouldProj = m_spec.get(m_module, m_specUbo, SpecProjectionType, samplerIdx, 1); - shouldProj = m_module.opINotEqual(m_module.defBoolType(), shouldProj, m_module.constu32(0)); - - // Depth -> .x - // Colour -> .xyzw - // Need to replicate the bool for the opSelect. - if (!depth) { - uint32_t bvec4_t = m_module.defVectorType(bool_t, 4); - std::array indices = { shouldProj, shouldProj, shouldProj, shouldProj }; - shouldProj = m_module.opCompositeConstruct(bvec4_t, indices.size(), indices.data()); - } - - result.id = m_module.opSelect(typeId, shouldProj, result.id, nonProjResult); - } - // If we are sampling depth we've already specc'ed this! // This path is always size 4 because it only hits on color. if (isNull != 0) { @@ -3118,7 +3081,6 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t DxsoCompiler::emitSample( - bool projected, uint32_t resultType, DxsoSamplerInfo& samplerInfo, DxsoRegisterValue coordinates, @@ -3134,37 +3096,22 @@ void DxsoCompiler::emitControlFlowGenericLoop( uint32_t val; - // No Fetch 4 - if (projected) { - if (depthCompare) { - if (explicitLod) - val = m_module.opImageSampleProjDrefExplicitLod(resultType, sampledImage, coordinates.id, reference, operands); - else - val = m_module.opImageSampleProjDrefImplicitLod(resultType, sampledImage, coordinates.id, reference, operands); - } - else { - if (explicitLod) - val = m_module.opImageSampleProjExplicitLod(resultType, sampledImage, coordinates.id, operands); - else - val = m_module.opImageSampleProjImplicitLod(resultType, sampledImage, coordinates.id, operands); - } + + if (depthCompare) { + if (explicitLod) + val = m_module.opImageSampleDrefExplicitLod(resultType, sampledImage, coordinates.id, reference, operands); + else + val = m_module.opImageSampleDrefImplicitLod(resultType, sampledImage, coordinates.id, reference, operands); } else { - if (depthCompare) { - if (explicitLod) - val = m_module.opImageSampleDrefExplicitLod(resultType, sampledImage, coordinates.id, reference, operands); - else - val = m_module.opImageSampleDrefImplicitLod(resultType, sampledImage, coordinates.id, reference, operands); - } - else { - if (explicitLod) - val = m_module.opImageSampleExplicitLod(resultType, sampledImage, coordinates.id, operands); - else - val = m_module.opImageSampleImplicitLod(resultType, sampledImage, coordinates.id, operands); - } + if (explicitLod) + val = m_module.opImageSampleExplicitLod(resultType, sampledImage, coordinates.id, operands); + else + val = m_module.opImageSampleImplicitLod(resultType, sampledImage, coordinates.id, operands); } + if (fetch4 && !depthCompare) { SpirvImageOperands fetch4Operands = operands; fetch4Operands.flags &= ~spv::ImageOperandsLodMask; diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h index 9f97fdda6..58b06a03e 100644 --- a/src/dxso/dxso_compiler.h +++ b/src/dxso/dxso_compiler.h @@ -664,7 +664,6 @@ namespace dxvk { void emitTextureDepth(const DxsoInstructionContext& ctx); uint32_t emitSample( - bool projected, uint32_t resultType, DxsoSamplerInfo& samplerInfo, DxsoRegisterValue coordinates, From 6188ffa23a87ca9f96572a01abf82668329ef838 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Mon, 26 Sep 2022 10:41:21 +0200 Subject: [PATCH 0883/1348] [d3d9] Add a config option for D24 -> D32 --- dxvk.conf | 9 +++++++++ src/d3d9/d3d9_format.cpp | 4 ++-- src/d3d9/d3d9_options.cpp | 1 + src/d3d9/d3d9_options.h | 3 +++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index abe6df4df..5c2746520 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -451,6 +451,15 @@ # d3d9.supportDFFormats = True +# Use D32f for D24 +# +# Useful for reproducing AMD issues on other hw. +# +# Supported values: +# - True/False + +# d3d9.useD32forD24 = False + # Support X4R4G4B4 # # Support the X4R4G4B4 format. diff --git a/src/d3d9/d3d9_format.cpp b/src/d3d9/d3d9_format.cpp index 089d9b1c0..13d19fde4 100644 --- a/src/d3d9/d3d9_format.cpp +++ b/src/d3d9/d3d9_format.cpp @@ -434,7 +434,8 @@ namespace dxvk { // AMD do not support 24-bit depth buffers on Vulkan, // so we have to fall back to a 32-bit depth format. - m_d24s8Support = CheckImageFormatSupport(adapter, VK_FORMAT_D24_UNORM_S8_UINT, + m_d24s8Support = !options.useD32forD24 && + CheckImageFormatSupport(adapter, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT); @@ -444,7 +445,6 @@ namespace dxvk { VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT); - // VK_EXT_4444_formats if (!m_d24s8Support) Logger::info("D3D9: VK_FORMAT_D24_UNORM_S8_UINT -> VK_FORMAT_D32_SFLOAT_S8_UINT"); diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index 0b1ce723e..0eabb3391 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -55,6 +55,7 @@ namespace dxvk { this->supportDFFormats = config.getOption ("d3d9.supportDFFormats", true); this->supportX4R4G4B4 = config.getOption ("d3d9.supportX4R4G4B4", true); this->supportD32 = config.getOption ("d3d9.supportD32", true); + this->useD32forD24 = config.getOption ("d3d9.useD32forD24", false); this->disableA8RT = config.getOption ("d3d9.disableA8RT", false); this->invariantPosition = config.getOption ("d3d9.invariantPosition", true); this->memoryTrackTest = config.getOption ("d3d9.memoryTrackTest", false); diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index 99fef6b14..cb0b5d4d3 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -91,6 +91,9 @@ namespace dxvk { /// Support D32 bool supportD32; + /// Use D32f for D24 + bool useD32forD24; + /// Disable D3DFMT_A8 for render targets. /// Specifically to work around a game /// bug in The Sims 2 that happens on native too! From 5684e29718d211b0a715d13b7c9a6df8019f2732 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Mon, 26 Sep 2022 11:18:59 +0200 Subject: [PATCH 0884/1348] [d3d9] Track if a texture is upgraded to D32f --- src/d3d9/d3d9_common_texture.cpp | 2 ++ src/d3d9/d3d9_common_texture.h | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index b50bec821..32a5d5e5a 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -40,6 +40,8 @@ namespace dxvk { m_mapMode = DetermineMapMode(); m_shadow = DetermineShadowState(); + m_upgradedToD32f = ConvertFormatUnfixed(m_desc.Format).FormatColor != VK_FORMAT_D32_SFLOAT_S8_UINT && + m_mapping.FormatColor == VK_FORMAT_D32_SFLOAT_S8_UINT; m_supportsFetch4 = DetermineFetch4Compatibility(); const bool createImage = m_desc.Pool != D3DPOOL_SYSTEMMEM && m_desc.Pool != D3DPOOL_SCRATCH && m_desc.Format != D3D9Format::NULL_FORMAT; diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index f0cf03f26..b727c8725 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -203,6 +203,14 @@ namespace dxvk { return m_shadow; } + /** + * \brief Dref Clamp + * \returns Whether the texture emulates an UNORM format with D32f + */ + bool IsUpgradedToD32f() const { + return m_upgradedToD32f; + } + /** * \brief FETCH4 compatibility * \returns Whether the format of the texture supports the FETCH4 hack @@ -499,6 +507,7 @@ namespace dxvk { D3D9_VK_FORMAT_MAPPING m_mapping; bool m_shadow; //< Depth Compare-ness + bool m_upgradedToD32f; // Dref Clamp bool m_supportsFetch4; int64_t m_size = 0; From 6fe96d7d8247c78070588bb5bec92b37bec6b129 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Mon, 26 Sep 2022 11:19:52 +0200 Subject: [PATCH 0885/1348] [dxso] Support clamping Dref. --- src/d3d9/d3d9_spec_constants.h | 4 +++- src/dxso/dxso_compiler.cpp | 11 ++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/d3d9/d3d9_spec_constants.h b/src/d3d9/d3d9_spec_constants.h index 78a850301..cfe84473a 100644 --- a/src/d3d9/d3d9_spec_constants.h +++ b/src/d3d9/d3d9_spec_constants.h @@ -27,6 +27,7 @@ namespace dxvk { SpecVertexShaderBools, // 16 bools | Bits: 16 SpecPixelShaderBools, // 16 bools | Bits: 16 + SpecDrefClamp, // 1 bit for 16 PS samplers | Bits: 16 SpecFetch4, // 1 bit for 16 PS samplers | Bits: 16 SpecConstantCount, @@ -62,7 +63,8 @@ namespace dxvk { { 3, 0, 16 }, // VertexShaderBools { 3, 16, 16 }, // PixelShaderBools - { 4, 0, 16 }, // Fetch4 + { 4, 0, 16 }, // DrefClamp + { 4, 16, 16 }, // Fetch4 }}; template diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index cb1ce67dd..8b9b16dd3 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -2862,19 +2862,24 @@ void DxsoCompiler::emitControlFlowGenericLoop( texcoordVar.id = DoProjection(texcoordVar, true); } - uint32_t reference = 0; + uint32_t bool_t = m_module.defBoolType(); + uint32_t reference = 0; if (depth) { + uint32_t fType = m_module.defFloatType(32); uint32_t component = sampler.dimensions; reference = m_module.opCompositeExtract( - m_module.defFloatType(32), texcoordVar.id, 1, &component); + fType, texcoordVar.id, 1, &component); + uint32_t clampDref = m_spec.get(m_module, m_specUbo, SpecDrefClamp, samplerIdx, 1); + clampDref = m_module.opINotEqual(bool_t, clampDref, m_module.constu32(0)); + uint32_t clampedDref = m_module.opFClamp(fType, reference, m_module.constf32(0.0f), m_module.constf32(1.0f)); + reference = m_module.opSelect(fType, clampDref, clampedDref, reference); } uint32_t fetch4 = 0; if (m_programInfo.type() == DxsoProgramType::PixelShader && samplerType != SamplerTypeTexture3D) { fetch4 = m_spec.get(m_module, m_specUbo, SpecFetch4, samplerIdx, 1); - uint32_t bool_t = m_module.defBoolType(); fetch4 = m_module.opINotEqual(bool_t, fetch4, m_module.constu32(0)); uint32_t bvec4_t = m_module.defVectorType(bool_t, 4); From a9bdea72e9603de85411e3b41f8a49c9cbd11182 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Mon, 26 Sep 2022 11:21:12 +0200 Subject: [PATCH 0886/1348] [d3d9] Clamp Dref to [0.0, 1.0] if the texture is emulated UNORM --- src/d3d9/d3d9_device.cpp | 11 ++++++++--- src/d3d9/d3d9_device.h | 3 ++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 1ab628fb7..3e5cd6ee6 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3791,6 +3791,9 @@ namespace dxvk { m_dirtySamplerStates |= 1u << StateSampler; } + m_drefClamp &= ~(1u << StateSampler); + m_drefClamp |= uint32_t(newTexture->IsUpgradedToD32f()) << StateSampler; + const bool oldCube = m_cubeTextures & (1u << StateSampler); const bool newCube = newTexture->GetType() == D3DRTYPE_CUBETEXTURE; if (oldCube != newCube) { @@ -6249,7 +6252,8 @@ namespace dxvk { const uint32_t nullTextureMask = usedSamplerMask & ~usedTextureMask; const uint32_t depthTextureMask = m_depthTextures & usedTextureMask; - UpdateCommonSamplerSpec(nullTextureMask, depthTextureMask); + const uint32_t drefClampMask = m_drefClamp & depthTextureMask; + UpdateCommonSamplerSpec(nullTextureMask, depthTextureMask, drefClampMask); if (m_flags.test(D3D9DeviceFlag::DirtySharedPixelShaderData)) { m_flags.clr(D3D9DeviceFlag::DirtySharedPixelShaderData); @@ -7249,7 +7253,7 @@ namespace dxvk { UpdatePixelShaderSamplerSpec(0u, 0u, 0u); UpdateVertexBoolSpec(0u); UpdatePixelBoolSpec(0u); - UpdateCommonSamplerSpec(0u, 0u); + UpdateCommonSamplerSpec(0u, 0u, 0u); return D3D_OK; } @@ -7443,9 +7447,10 @@ namespace dxvk { } - void D3D9DeviceEx::UpdateCommonSamplerSpec(uint32_t nullMask, uint32_t depthMask) { + void D3D9DeviceEx::UpdateCommonSamplerSpec(uint32_t nullMask, uint32_t depthMask, uint32_t drefMask) { bool dirty = m_specInfo.set(depthMask); dirty |= m_specInfo.set(nullMask); + dirty |= m_specInfo.set(drefMask); if (dirty) m_flags.set(D3D9DeviceFlag::DirtySpecializationEntries); diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index bc04b35eb..63e9fd476 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1145,7 +1145,7 @@ namespace dxvk { void UpdateVertexBoolSpec(uint32_t value); void UpdatePixelBoolSpec(uint32_t value); void UpdatePixelShaderSamplerSpec(uint32_t types, uint32_t projections, uint32_t fetch4); - void UpdateCommonSamplerSpec(uint32_t boundMask, uint32_t depthMask); + void UpdateCommonSamplerSpec(uint32_t boundMask, uint32_t depthMask, uint32_t drefMask); void UpdatePointModeSpec(uint32_t mode); void UpdateFogModeSpec(bool fogEnabled, D3DFOGMODE vertexFogMode, D3DFOGMODE pixelFogMode); @@ -1237,6 +1237,7 @@ namespace dxvk { uint32_t m_instancedData = 0; uint32_t m_depthTextures = 0; + uint32_t m_drefClamp = 0; uint32_t m_cubeTextures = 0; uint32_t m_textureTypes = 0; uint32_t m_projectionBitfield = 0; From 50857537d6dc7ce27b9e511aaa6be877beb247d0 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Mon, 26 Sep 2022 20:27:06 +0200 Subject: [PATCH 0887/1348] [d3d9] Use D32 not D32_S8 when upgrading formats without stencil aspect. --- src/d3d9/d3d9_common_texture.cpp | 4 ++-- src/d3d9/d3d9_format.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 32a5d5e5a..67fba7b09 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -40,8 +40,8 @@ namespace dxvk { m_mapMode = DetermineMapMode(); m_shadow = DetermineShadowState(); - m_upgradedToD32f = ConvertFormatUnfixed(m_desc.Format).FormatColor != VK_FORMAT_D32_SFLOAT_S8_UINT && - m_mapping.FormatColor == VK_FORMAT_D32_SFLOAT_S8_UINT; + m_upgradedToD32f = ConvertFormatUnfixed(m_desc.Format).FormatColor != m_mapping.FormatColor && + (m_mapping.FormatColor == VK_FORMAT_D32_SFLOAT_S8_UINT || m_mapping.FormatColor == VK_FORMAT_D32_SFLOAT); m_supportsFetch4 = DetermineFetch4Compatibility(); const bool createImage = m_desc.Pool != D3DPOOL_SYSTEMMEM && m_desc.Pool != D3DPOOL_SCRATCH && m_desc.Format != D3D9Format::NULL_FORMAT; diff --git a/src/d3d9/d3d9_format.cpp b/src/d3d9/d3d9_format.cpp index 13d19fde4..90ebfd93e 100644 --- a/src/d3d9/d3d9_format.cpp +++ b/src/d3d9/d3d9_format.cpp @@ -473,7 +473,7 @@ namespace dxvk { return D3D9_VK_FORMAT_MAPPING(); if (!m_d24s8Support && mapping.FormatColor == VK_FORMAT_D24_UNORM_S8_UINT) - mapping.FormatColor = VK_FORMAT_D32_SFLOAT_S8_UINT; + mapping.FormatColor = mapping.Aspect & VK_IMAGE_ASPECT_STENCIL_BIT ? VK_FORMAT_D32_SFLOAT_S8_UINT : VK_FORMAT_D32_SFLOAT; if (!m_d16s8Support && mapping.FormatColor == VK_FORMAT_D16_UNORM_S8_UINT) mapping.FormatColor = m_d24s8Support ? VK_FORMAT_D24_UNORM_S8_UINT : VK_FORMAT_D32_SFLOAT_S8_UINT; From 49854dbfba28f30ce98e2e9cc17574d4a4c3e4c6 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 27 Sep 2022 18:52:12 -0230 Subject: [PATCH 0888/1348] [d3d9] Saturate viewport depth range Viewport depth range in D3D9 is clamped at 0-1, same as OpenGL. Drivers like RADV, etc support VK_EXT_depth_range_unrestricted, which makes the regular UB of this actually work -- which isn't what we want. We also don't enable VK_EXT_depth_range_unrestricted, so we shouldn't be setting depth ranges outside of the 0-1 bounds anyway. Closes: #2960 --- src/d3d9/d3d9_device.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 3e5cd6ee6..536c6331a 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5636,7 +5636,8 @@ namespace dxvk { viewport = VkViewport{ float(vp.X) + cf, float(vp.Height + vp.Y) + cf, float(vp.Width), -float(vp.Height), - vp.MinZ, std::max(vp.MaxZ, vp.MinZ + zBias), + std::clamp(vp.MinZ, 0.0f, 1.0f), + std::clamp(std::max(vp.MaxZ, vp.MinZ + zBias), 0.0f, 1.0f), }; // Scissor rectangles. Vulkan does not provide an easy way From b2ad25755a7085ea9eac5f120ba4aa7a587e2ed5 Mon Sep 17 00:00:00 2001 From: Adam Jereczek Date: Wed, 28 Sep 2022 16:40:41 +0200 Subject: [PATCH 0889/1348] [d3d9] Fix for missing restriction check in ProcessVertices Co-authored-by: aroztkow --- src/d3d9/d3d9_device.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 536c6331a..3aa396482 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2620,9 +2620,18 @@ namespace dxvk { DWORD Flags) { D3D9DeviceLock lock = LockDevice(); - if (unlikely(pDestBuffer == nullptr || pVertexDecl == nullptr)) + if (unlikely(pDestBuffer == nullptr)) return D3DERR_INVALIDCALL; + // When vertex shader 3.0 or above is set as the current vertex shader, + // the output vertex declaration must be present. + if (UseProgrammableVS()) { + const auto& programInfo = GetCommonShader(m_state.vertexShader)->GetInfo(); + + if (unlikely(programInfo.majorVersion() >= 3) && (pVertexDecl == nullptr)) + return D3DERR_INVALIDCALL; + } + if (!SupportsSWVP()) { static bool s_errorShown = false; From f8bd19f210d32a27c51cdda7720f7d68f7787499 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Fri, 30 Sep 2022 21:03:34 +0200 Subject: [PATCH 0890/1348] [util] Cap Sonic Adventure 2 to 60 fps --- src/util/config/config.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index ffe2d89d1..36b503df9 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -329,6 +329,7 @@ namespace dxvk { /* Sonic Adventure 2 */ { R"(\\Sonic Adventure 2\\(launcher|sonic2app)\.exe$)", {{ { "d3d9.floatEmulation", "Strict" }, + { "d3d9.maxFrameRate", "60" }, }} }, /* The Sims 2, Body Shop, From ab622760a0f55c336a4fb3170cce84c10277af3e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 4 Oct 2022 20:59:21 +0200 Subject: [PATCH 0891/1348] [dxbc] Emit new block only after emitting switch instruction Otherwise emitting the OpSwitch will reset the block ID, which is not desireable. Fixes #2975. --- src/dxbc/dxbc_compiler.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index ed5e7533c..0514e0afe 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -4009,7 +4009,6 @@ namespace dxvk { // Close the current 'case' block m_module.opBranch(block.b_switch.labelBreak); - m_module.opLabel (block.b_switch.labelBreak); // Insert the 'switch' statement. For that, we need to // gather all the literal-label pairs for the construct. @@ -4036,6 +4035,9 @@ namespace dxvk { while (caseLabel != nullptr) delete std::exchange(caseLabel, caseLabel->next); + + // Begin new block after switch blocks + m_module.opLabel(block.b_switch.labelBreak); } From fa45e5838e9eae333c751095450eadaa5d52e7ad Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 5 Oct 2022 19:01:05 +0100 Subject: [PATCH 0892/1348] [util] Fix tzcnt on ARM64 + Clang This needed brackets around this conditional. --- src/util/util_bit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index d6832871b..9490d7353 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -104,7 +104,7 @@ namespace dxvk::bit { return _tzcnt_u64(n); #elif defined(DXVK_ARCH_X86_64) && defined(__BMI__) return __tzcnt_u64(n); - #elif defined(DXVK_ARCH_X86_64) && defined(__GNUC__) || defined(__clang__) + #elif defined(DXVK_ARCH_X86_64) && (defined(__GNUC__) || defined(__clang__)) uint64_t res; uint64_t tmp; asm ( From 038ed23a5dec9cdbd57a1da728989d480342f5c5 Mon Sep 17 00:00:00 2001 From: Vinjul1704 Date: Mon, 3 Oct 2022 14:51:20 +0200 Subject: [PATCH 0893/1348] [util] Force SM1 for the Escape from Tarkov launcher --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 36b503df9..a420fe929 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -538,6 +538,11 @@ namespace dxvk { { R"(\\spv3\.exe$)", {{ { "d3d9.shaderModel", "1" }, }} }, + /* Escape from Tarkov launcher + Same issue as Warhammer: RoR above */ + { R"(\\BsgLauncher\.exe$)", {{ + { "d3d9.shaderModel", "1" }, + }} }, /* Star Wars The Force Unleashed 2 * * Black particles because it tries to bind * * a 2D texture for a shader that * From bd7d2aac71eca32f346ceea88e4b34bd7151d907 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 7 Oct 2022 13:25:26 +0200 Subject: [PATCH 0894/1348] [dxgi] Get rid of NotifyModeChange method Was only used for the FPS limiter. --- src/d3d11/d3d11_swapchain.cpp | 13 ------------- src/d3d11/d3d11_swapchain.h | 6 ------ src/dxgi/dxgi_interfaces.h | 4 ---- src/dxgi/dxgi_swapchain.cpp | 29 +---------------------------- src/dxgi/dxgi_swapchain.h | 4 ---- 5 files changed, 1 insertion(+), 55 deletions(-) diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index cc128411b..4a7dad00d 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -255,19 +255,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11SwapChain::NotifyModeChange( - BOOL Windowed, - const DXGI_MODE_DESC* pDisplayMode) { - if (Windowed || !pDisplayMode) { - // Display modes aren't meaningful in windowed mode - m_displayRefreshRate = 0.0; - } else { - DXGI_RATIONAL rate = pDisplayMode->RefreshRate; - m_displayRefreshRate = double(rate.Numerator) / double(rate.Denominator); - } - } - - HRESULT D3D11SwapChain::PresentImage(UINT SyncInterval) { Com deviceContext = nullptr; m_parent->GetImmediateContext(&deviceContext); diff --git a/src/d3d11/d3d11_swapchain.h b/src/d3d11/d3d11_swapchain.h index 8a006a153..29f9b9a70 100644 --- a/src/d3d11/d3d11_swapchain.h +++ b/src/d3d11/d3d11_swapchain.h @@ -69,10 +69,6 @@ namespace dxvk { UINT PresentFlags, const DXGI_PRESENT_PARAMETERS* pPresentParameters); - void STDMETHODCALLTYPE NotifyModeChange( - BOOL Windowed, - const DXGI_MODE_DESC* pDisplayMode); - private: enum BindingIds : uint32_t { @@ -114,8 +110,6 @@ namespace dxvk { bool m_dirty = true; bool m_vsync = true; - double m_displayRefreshRate = 0.0; - HRESULT PresentImage(UINT SyncInterval); void SubmitPresent( diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index fc94dd858..10196f253 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -78,10 +78,6 @@ IDXGIVkSwapChain : public IUnknown { UINT SyncInterval, UINT PresentFlags, const DXGI_PRESENT_PARAMETERS* pPresentParameters) = 0; - - virtual void STDMETHODCALLTYPE NotifyModeChange( - BOOL Windowed, - const DXGI_MODE_DESC* pDisplayMode) = 0; }; diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 3ebf48346..f48a282c1 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -407,10 +407,8 @@ namespace dxvk { } // If the swap chain allows it, change the display mode - if (m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH) { + if (m_desc.Flags & DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH) ChangeDisplayMode(output.ptr(), &newDisplayMode); - NotifyModeChange(m_monitor, FALSE); - } wsi::updateFullscreenWindow(m_monitor, m_window, false); } @@ -649,7 +647,6 @@ namespace dxvk { ReleaseMonitorData(); } - NotifyModeChange(m_monitor, FALSE); return S_OK; } @@ -670,8 +667,6 @@ namespace dxvk { } // Restore internal state - HMONITOR monitor = m_monitor; - m_descFs.Windowed = TRUE; m_target = nullptr; m_monitor = wsi::getWindowMonitor(m_window); @@ -684,7 +679,6 @@ namespace dxvk { return DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; } - NotifyModeChange(monitor, TRUE); return S_OK; } @@ -802,25 +796,4 @@ namespace dxvk { m_monitorInfo->ReleaseMonitorData(); } - - void DxgiSwapChain::NotifyModeChange( - HMONITOR hMonitor, - BOOL Windowed) { - wsi::WsiMode mode = { }; - - if (wsi::getCurrentDisplayMode(hMonitor, &mode)) { - DXGI_MODE_DESC displayMode = { }; - displayMode.Width = mode.width; - displayMode.Height = mode.height; - displayMode.RefreshRate = { mode.refreshRate.numerator, mode.refreshRate.denominator }; - displayMode.Format = m_desc.Format; - displayMode.ScanlineOrdering = m_descFs.ScanlineOrdering; - displayMode.Scaling = m_descFs.Scaling; - m_presenter->NotifyModeChange(Windowed, &displayMode); - } else { - Logger::warn("Failed to query current display mode"); - m_presenter->NotifyModeChange(Windowed, nullptr); - } - } - } diff --git a/src/dxgi/dxgi_swapchain.h b/src/dxgi/dxgi_swapchain.h index b1c38c4e5..6aaa6892c 100644 --- a/src/dxgi/dxgi_swapchain.h +++ b/src/dxgi/dxgi_swapchain.h @@ -216,10 +216,6 @@ namespace dxvk { void ReleaseMonitorData(); - void NotifyModeChange( - HMONITOR hMonitor, - BOOL Windowed); - }; } From 2b964f0c67406280af59937aee51342998a38800 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Fri, 7 Oct 2022 17:09:19 +0200 Subject: [PATCH 0895/1348] [d3d9] Make MapD3DDeclToFvf more readable All branches return, so we might as well give it a bit more room to breath. --- src/d3d9/d3d9_vertex_declaration.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/d3d9/d3d9_vertex_declaration.cpp b/src/d3d9/d3d9_vertex_declaration.cpp index f2acd733e..8cbe56c78 100644 --- a/src/d3d9/d3d9_vertex_declaration.cpp +++ b/src/d3d9/d3d9_vertex_declaration.cpp @@ -228,9 +228,11 @@ namespace dxvk { if (element.Usage == D3DDECLUSAGE_POSITION && element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0) return D3DFVF_XYZ; - else if (element.Usage == D3DDECLUSAGE_POSITIONT && element.Type == D3DDECLTYPE_FLOAT4 && element.UsageIndex == 0) + + if (element.Usage == D3DDECLUSAGE_POSITIONT && element.Type == D3DDECLTYPE_FLOAT4 && element.UsageIndex == 0) return D3DFVF_XYZRHW; - else if (element.Usage == D3DDECLUSAGE_BLENDWEIGHT && element.UsageIndex == 0) { + + if (element.Usage == D3DDECLUSAGE_BLENDWEIGHT && element.UsageIndex == 0) { DWORD fvfRet = MapD3DDeclTypeFloatToFvfXYZBn(element.Type); if (likely(fvfRet != 0)) return fvfRet; @@ -239,13 +241,17 @@ namespace dxvk { return 0; } } - else if (element.Usage == D3DDECLUSAGE_BLENDINDICES && element.Type == D3DDECLTYPE_UBYTE4 && element.UsageIndex == 0) + + if (element.Usage == D3DDECLUSAGE_BLENDINDICES && element.Type == D3DDECLTYPE_UBYTE4 && element.UsageIndex == 0) return D3DFVF_XYZB1; - else if (element.Usage == D3DDECLUSAGE_NORMAL && element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0) + + if (element.Usage == D3DDECLUSAGE_NORMAL && element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0) return D3DFVF_NORMAL; - else if (element.Usage == D3DDECLUSAGE_PSIZE && element.Type == D3DDECLTYPE_FLOAT1 && element.UsageIndex == 0) + + if (element.Usage == D3DDECLUSAGE_PSIZE && element.Type == D3DDECLTYPE_FLOAT1 && element.UsageIndex == 0) return D3DFVF_PSIZE; - else if (element.Usage == D3DDECLUSAGE_COLOR && element.Type == D3DDECLTYPE_D3DCOLOR) { + + if (element.Usage == D3DDECLUSAGE_COLOR && element.Type == D3DDECLTYPE_D3DCOLOR) { switch (element.UsageIndex) { case 0: return D3DFVF_DIFFUSE; case 1: return D3DFVF_SPECULAR; @@ -254,7 +260,8 @@ namespace dxvk { return 0; } } - else if (element.Usage == D3DDECLUSAGE_TEXCOORD && element.UsageIndex < 8) { + + if (element.Usage == D3DDECLUSAGE_TEXCOORD && element.UsageIndex < 8) { DWORD retFvf = 0; if (likely(MapD3DDeclUsageTexCoordToFvfTexCoordSize(element, fvf, retFvf, texCountPostUpdate))) return retFvf; From 709010557320b6ce4683d4c9a08474c7110f270d Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sat, 8 Oct 2022 17:30:53 +0200 Subject: [PATCH 0896/1348] [d3d9] Remove declaration fvf mapping log spam --- src/d3d9/d3d9_vertex_declaration.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/d3d9/d3d9_vertex_declaration.cpp b/src/d3d9/d3d9_vertex_declaration.cpp index 8cbe56c78..05b3c5baa 100644 --- a/src/d3d9/d3d9_vertex_declaration.cpp +++ b/src/d3d9/d3d9_vertex_declaration.cpp @@ -237,7 +237,6 @@ namespace dxvk { if (likely(fvfRet != 0)) return fvfRet; else { - Logger::warn("D3D9VertexDecl::MapD3DDeclToFvf: Unsupported set of D3DDECLUSAGE_BLENDWEIGHT / D3DDECLTYPE_* / UsageIndex"); return 0; } } @@ -256,7 +255,6 @@ namespace dxvk { case 0: return D3DFVF_DIFFUSE; case 1: return D3DFVF_SPECULAR; default: - Logger::warn("D3D9VertexDecl::MapD3DDeclToFvf: Unsupported set of D3DDECLUSAGE_COLOR / D3DDECLTYPE_D3DCOLOR / UsageIndex"); return 0; } } @@ -266,12 +264,10 @@ namespace dxvk { if (likely(MapD3DDeclUsageTexCoordToFvfTexCoordSize(element, fvf, retFvf, texCountPostUpdate))) return retFvf; else { - Logger::warn("D3D9VertexDecl::MapD3DDeclToFvf: Unsupported set of D3DDECLUSAGE_TEXCOORD / D3DDECLTYPE_* / UsageIndex"); return 0; } } - Logger::warn("D3D9VertexDecl::MapD3DDeclToFvf: Unsupported set of D3DDECLUSAGE_* / D3DDECLTYPE_* / UsageIndex"); return 0; } From 4bcabe8d460b39baa824ddd215bddfb5aedcb0fa Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Fri, 7 Oct 2022 20:58:40 +0200 Subject: [PATCH 0897/1348] [d3d9] Return 0 if any vertex decl element can't be represented as fvf --- src/d3d9/d3d9_vertex_declaration.cpp | 71 +++++++++++++++++----------- src/d3d9/d3d9_vertex_declaration.h | 3 +- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/src/d3d9/d3d9_vertex_declaration.cpp b/src/d3d9/d3d9_vertex_declaration.cpp index 05b3c5baa..49b4dacaa 100644 --- a/src/d3d9/d3d9_vertex_declaration.cpp +++ b/src/d3d9/d3d9_vertex_declaration.cpp @@ -204,9 +204,10 @@ namespace dxvk { std::copy(elements.begin(), elements.begin() + elemCount, m_elements.data()); } - DWORD D3D9VertexDecl::MapD3DDeclToFvf( + bool D3D9VertexDecl::MapD3DDeclToFvf( const D3DVERTEXELEMENT9& element, DWORD fvf, + DWORD& outFvf, DWORD& texCountPostUpdate) { // Mapping between a Direct3D Declaration and FVF Codes (Direct3D 9) @@ -226,49 +227,60 @@ namespace dxvk { // D3DDECLTYPE_FLOAT3 D3DDECLUSAGE_POSITION 1 N / A // D3DDECLTYPE_FLOAT3 D3DDECLUSAGE_NORMAL 1 N / A - if (element.Usage == D3DDECLUSAGE_POSITION && element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0) - return D3DFVF_XYZ; - if (element.Usage == D3DDECLUSAGE_POSITIONT && element.Type == D3DDECLTYPE_FLOAT4 && element.UsageIndex == 0) - return D3DFVF_XYZRHW; + if (element.Usage == D3DDECLUSAGE_POSITION && element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0) { + outFvf = D3DFVF_XYZ; + return true; + } + + if (element.Usage == D3DDECLUSAGE_POSITIONT && element.Type == D3DDECLTYPE_FLOAT4 && element.UsageIndex == 0) { + outFvf = D3DFVF_XYZRHW; + return true; + } if (element.Usage == D3DDECLUSAGE_BLENDWEIGHT && element.UsageIndex == 0) { DWORD fvfRet = MapD3DDeclTypeFloatToFvfXYZBn(element.Type); - if (likely(fvfRet != 0)) - return fvfRet; - else { - return 0; + if (likely(fvfRet != 0)) { + outFvf = fvfRet; + return true; + } else { + return false; } } - if (element.Usage == D3DDECLUSAGE_BLENDINDICES && element.Type == D3DDECLTYPE_UBYTE4 && element.UsageIndex == 0) - return D3DFVF_XYZB1; + if (element.Usage == D3DDECLUSAGE_BLENDINDICES && element.Type == D3DDECLTYPE_UBYTE4 && element.UsageIndex == 0) { + outFvf = D3DFVF_XYZB1; + return true; + } - if (element.Usage == D3DDECLUSAGE_NORMAL && element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0) - return D3DFVF_NORMAL; + if (element.Usage == D3DDECLUSAGE_NORMAL && element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0) { + outFvf = D3DFVF_NORMAL; + return true; + } - if (element.Usage == D3DDECLUSAGE_PSIZE && element.Type == D3DDECLTYPE_FLOAT1 && element.UsageIndex == 0) - return D3DFVF_PSIZE; + if (element.Usage == D3DDECLUSAGE_PSIZE && element.Type == D3DDECLTYPE_FLOAT1 && element.UsageIndex == 0) { + outFvf = D3DFVF_PSIZE; + return true; + } if (element.Usage == D3DDECLUSAGE_COLOR && element.Type == D3DDECLTYPE_D3DCOLOR) { switch (element.UsageIndex) { - case 0: return D3DFVF_DIFFUSE; - case 1: return D3DFVF_SPECULAR; + case 0: + outFvf = D3DFVF_DIFFUSE; + return true; + case 1: + outFvf = D3DFVF_SPECULAR; + return true; default: - return 0; + return false; } } if (element.Usage == D3DDECLUSAGE_TEXCOORD && element.UsageIndex < 8) { - DWORD retFvf = 0; - if (likely(MapD3DDeclUsageTexCoordToFvfTexCoordSize(element, fvf, retFvf, texCountPostUpdate))) - return retFvf; - else { - return 0; - } + return MapD3DDeclUsageTexCoordToFvfTexCoordSize(element, fvf, outFvf, texCountPostUpdate); } - return 0; + return false; } @@ -323,8 +335,13 @@ namespace dxvk { DWORD fvf = 0; DWORD texCountPostUpdate = 0; - for (const auto& element : m_elements) - fvf |= MapD3DDeclToFvf(element, fvf, texCountPostUpdate); + for (const auto& element : m_elements) { + DWORD elementFvf = 0; + if (!MapD3DDeclToFvf(element, fvf, elementFvf, texCountPostUpdate)) { + return 0; + } + fvf |= elementFvf; + } fvf |= (texCountPostUpdate << 8); diff --git a/src/d3d9/d3d9_vertex_declaration.h b/src/d3d9/d3d9_vertex_declaration.h index 4652f1f8e..82b182756 100644 --- a/src/d3d9/d3d9_vertex_declaration.h +++ b/src/d3d9/d3d9_vertex_declaration.h @@ -68,9 +68,10 @@ namespace dxvk { private: - DWORD MapD3DDeclToFvf( + bool MapD3DDeclToFvf( const D3DVERTEXELEMENT9& element, DWORD fvf, + DWORD& outFvf, DWORD& texCountPostUpdate); DWORD MapD3D9VertexElementsToFvf(); From c54eac7d6132b81296da23479cf0d2e4a1ac855e Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Fri, 14 Oct 2022 09:24:43 +0200 Subject: [PATCH 0898/1348] [build] Update github actions Use github-checkout v3, github-upload-artifact-action v3 and joshua-ashton-gcc-problem-matcher v2. Fixes Node.js 12 deprecation warning. --- .github/workflows/artifacts.yml | 6 +++--- .github/workflows/test-build-windows.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/artifacts.yml b/.github/workflows/artifacts.yml index b843d1aaf..5a43b8904 100644 --- a/.github/workflows/artifacts.yml +++ b/.github/workflows/artifacts.yml @@ -9,13 +9,13 @@ jobs: steps: - name: Checkout code id: checkout-code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive fetch-depth: 0 - name: Setup problem matcher - uses: Joshua-Ashton/gcc-problem-matcher@v1 + uses: Joshua-Ashton/gcc-problem-matcher@v2 - name: Build release id: build-release @@ -28,7 +28,7 @@ jobs: - name: Upload artifacts id: upload-artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: dxvk-${{ env.VERSION_NAME }} path: build/dxvk-${{ env.VERSION_NAME }} diff --git a/.github/workflows/test-build-windows.yml b/.github/workflows/test-build-windows.yml index 67c3bfd6b..e4844bbba 100644 --- a/.github/workflows/test-build-windows.yml +++ b/.github/workflows/test-build-windows.yml @@ -9,7 +9,7 @@ jobs: steps: - name: Checkout code id: checkout-code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive From 3b90f5a77fed8c76bca14c60747f2426577df1c1 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 15 Oct 2022 17:21:24 +0100 Subject: [PATCH 0899/1348] [util] Enable apitrace mode for Hammer World Editor --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index a420fe929..f25e7c6b5 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -630,6 +630,10 @@ namespace dxvk { { R"(\\SinEpisodes\.exe$)", {{ { "d3d9.memoryTrackTest", "True" }, }} }, + /* Hammer World Editor */ + { R"(\\(hammer(plusplus)?|mallet|wc)\.exe$)", {{ + { "d3d9.apitraceMode", "True" }, + }} }, }}; From f1578b8ed3788a067957568f054804b3b11a6e58 Mon Sep 17 00:00:00 2001 From: Christophe <62888873+christophe-lunarg@users.noreply.github.com> Date: Sat, 15 Oct 2022 18:24:44 +0200 Subject: [PATCH 0900/1348] [meta] Factorize history and contributors sections using schema 0.8.1 --- VP_DXVK_requirements.json | 216 +++++++------------------------------- 1 file changed, 39 insertions(+), 177 deletions(-) diff --git a/VP_DXVK_requirements.json b/VP_DXVK_requirements.json index 6dee56330..751203d43 100644 --- a/VP_DXVK_requirements.json +++ b/VP_DXVK_requirements.json @@ -1,5 +1,5 @@ { - "$schema": "https://schema.khronos.org/vulkan/profiles-0.8.0-224.json#", + "$schema": "https://schema.khronos.org/vulkan/profiles-0.8.1-224.json#", "capabilities": { "vulkan10requirements": { "features": { @@ -267,31 +267,6 @@ "api-version": "1.3.204", "label": "DXVK D3D9 Baseline profile", "description": "DXVK for D3D9 minimum requirements", - "contributors": { - "Philip Rebohle": { - "company": "Valve" - }, - "Joshua Ashton": { - "company": "Valve" - }, - "Pierre-Loup A. Griffais": { - "company": "Valve" - }, - "Georg Lehmann": { - "company": "DXVK" - }, - "Christophe Riccio": { - "company": "LunarG" - } - }, - "history": [ - { - "revision": 1, - "date": "2022-08-22", - "author": "Christophe Riccio", - "comment": "Initial revision" - } - ], "capabilities": [ "vulkan10requirements", "vulkan11requirements", @@ -305,31 +280,6 @@ "api-version": "1.3.224", "label": "DXVK D3D9 Optimal profile", "description": "DXVK for D3D9 including optional capabilities", - "contributors": { - "Philip Rebohle": { - "company": "Valve" - }, - "Joshua Ashton": { - "company": "Valve" - }, - "Pierre-Loup A. Griffais": { - "company": "Valve" - }, - "Georg Lehmann": { - "company": "DXVK" - }, - "Christophe Riccio": { - "company": "LunarG" - } - }, - "history": [ - { - "revision": 1, - "date": "2022-08-22", - "author": "Christophe Riccio", - "comment": "Initial revision" - } - ], "capabilities": [ "vulkan10requirements", "vulkan11requirements", @@ -344,31 +294,6 @@ "api-version": "1.3.204", "label": "DXVK D3D10 Level 10.1 Baseline profile", "description": "DXVK for D3D10 Feature Level 10.1 minimum requirements", - "contributors": { - "Philip Rebohle": { - "company": "Valve" - }, - "Joshua Ashton": { - "company": "Valve" - }, - "Pierre-Loup A. Griffais": { - "company": "Valve" - }, - "Georg Lehmann": { - "company": "DXVK" - }, - "Christophe Riccio": { - "company": "LunarG" - } - }, - "history": [ - { - "revision": 1, - "date": "2022-08-22", - "author": "Christophe Riccio", - "comment": "Initial revision" - } - ], "capabilities": [ "vulkan10requirements", "vulkan11requirements", @@ -382,31 +307,6 @@ "api-version": "1.3.204", "label": "DXVK D3D11 Level 11.0 Baseline profile", "description": "DXVK for D3D11 Feature Level 11.0 minimum requirements", - "contributors": { - "Philip Rebohle": { - "company": "Valve" - }, - "Joshua Ashton": { - "company": "Valve" - }, - "Pierre-Loup A. Griffais": { - "company": "Valve" - }, - "Georg Lehmann": { - "company": "DXVK" - }, - "Christophe Riccio": { - "company": "LunarG" - } - }, - "history": [ - { - "revision": 1, - "date": "2022-08-22", - "author": "Christophe Riccio", - "comment": "Initial revision" - } - ], "capabilities": [ "vulkan10requirements", "vulkan11requirements", @@ -421,31 +321,6 @@ "api-version": "1.3.204", "label": "DXVK D3D11 Level 11.1 Baseline profile", "description": "DXVK for D3D11 Feature Level 11.1 minimum requirements", - "contributors": { - "Philip Rebohle": { - "company": "Valve" - }, - "Joshua Ashton": { - "company": "Valve" - }, - "Pierre-Loup A. Griffais": { - "company": "Valve" - }, - "Georg Lehmann": { - "company": "DXVK" - }, - "Christophe Riccio": { - "company": "LunarG" - } - }, - "history": [ - { - "revision": 1, - "date": "2022-08-22", - "author": "Christophe Riccio", - "comment": "Initial revision" - } - ], "capabilities": [ "vulkan10requirements", "vulkan11requirements", @@ -461,31 +336,6 @@ "api-version": "1.3.204", "label": "DXVK D3D11 Level 11.1 Optimal profile", "description": "DXVK for D3D11 Feature Level 11.1 including optional capabilities", - "contributors": { - "Philip Rebohle": { - "company": "Valve" - }, - "Joshua Ashton": { - "company": "Valve" - }, - "Pierre-Loup A. Griffais": { - "company": "Valve" - }, - "Georg Lehmann": { - "company": "DXVK" - }, - "Christophe Riccio": { - "company": "LunarG" - } - }, - "history": [ - { - "revision": 1, - "date": "2022-08-22", - "author": "Christophe Riccio", - "comment": "Initial revision" - } - ], "capabilities": [ "vulkan10requirements", "vulkan11requirements", @@ -503,31 +353,6 @@ "api-version": "1.3.204", "label": "DXVK D3D11 Level 12.0 Optimal profile", "description": "DXVK for D3D11 Feature Level 12.0 including optional capabilities", - "contributors": { - "Philip Rebohle": { - "company": "Valve" - }, - "Joshua Ashton": { - "company": "Valve" - }, - "Pierre-Loup A. Griffais": { - "company": "Valve" - }, - "Georg Lehmann": { - "company": "DXVK" - }, - "Christophe Riccio": { - "company": "LunarG" - } - }, - "history": [ - { - "revision": 1, - "date": "2022-08-30", - "author": "Philip Rebohle", - "comment": "Initial revision" - } - ], "capabilities": [ "vulkan10requirements", "vulkan11requirements", @@ -541,5 +366,42 @@ "d3d11_level12_0" ] } - } + }, + "contributors": { + "Philip Rebohle": { + "company": "Valve" + }, + "Joshua Ashton": { + "company": "Valve" + }, + "Pierre-Loup A. Griffais": { + "company": "Valve" + }, + "Georg Lehmann": { + "company": "DXVK" + }, + "Christophe Riccio": { + "company": "LunarG" + } + }, + "history": [ + { + "revision": 3, + "date": "2022-10-13", + "author": "Christophe Riccio", + "comment": "Factorize history and contributors sections using schema 0.8.1" + }, + { + "revision": 2, + "date": "2022-08-30", + "author": "Philip Rebohle", + "comment": "Add VP_DXVK_d3d11_level_12_0_optimal profile" + }, + { + "revision": 1, + "date": "2022-08-22", + "author": "Christophe Riccio", + "comment": "Initial revision" + } + ] } From 25798f6fe15c55b19e050ab484c122fc29d4a30d Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 5 Oct 2022 21:04:59 +0100 Subject: [PATCH 0901/1348] [build] Set name_prefix to `libdxvk_` for native builds Less rude and nicer than just d3d9.so. Matches old DXVK native behaviour too. --- meson.build | 2 ++ src/d3d10/meson.build | 2 +- src/d3d11/meson.build | 2 +- src/d3d9/meson.build | 2 +- src/dxgi/meson.build | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index ba5f88bb5..0ae1a4c92 100644 --- a/meson.build +++ b/meson.build @@ -97,6 +97,7 @@ if platform == 'windows' endif dxvk_wsi = 'win32' + dxvk_name_prefix = '' compiler_args += ['-DDXVK_WSI_WIN32'] else lib_sdl2 = cpp.find_library('SDL2') @@ -111,6 +112,7 @@ else ] dxvk_wsi = 'sdl2' + dxvk_name_prefix = 'libdxvk_' compiler_args += ['-DDXVK_WSI_SDL2'] endif diff --git a/src/d3d10/meson.build b/src/d3d10/meson.build index 20324939d..1ef0167f4 100644 --- a/src/d3d10/meson.build +++ b/src/d3d10/meson.build @@ -5,7 +5,7 @@ d3d10_core_src = [ ] d3d10_core_dll = shared_library('d3d10core'+dll_ext, d3d10_core_src, d3d10_core_res, - name_prefix : '', + name_prefix : dxvk_name_prefix, dependencies : [ d3d11_dep ], include_directories : dxvk_include_path, install : true, diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 7727387d6..26d655ade 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -69,7 +69,7 @@ d3d11_shaders = files([ d3d11_dll = shared_library('d3d11'+dll_ext, dxgi_common_src + d3d11_src + d3d10_src, glsl_generator.process(d3d11_shaders), d3d11_res, - name_prefix : '', + name_prefix : dxvk_name_prefix, dependencies : [ dxgi_dep, dxbc_dep, dxvk_dep ], include_directories : dxvk_include_path, install : true, diff --git a/src/d3d9/meson.build b/src/d3d9/meson.build index bb5f3f387..9bb8eb1db 100644 --- a/src/d3d9/meson.build +++ b/src/d3d9/meson.build @@ -47,7 +47,7 @@ d3d9_src = [ ] d3d9_dll = shared_library('d3d9'+dll_ext, d3d9_src, glsl_generator.process(d3d9_shaders), d3d9_res, - name_prefix : '', + name_prefix : dxvk_name_prefix, dependencies : [ dxso_dep, dxvk_dep ], include_directories : dxvk_include_path, install : true, diff --git a/src/dxgi/meson.build b/src/dxgi/meson.build index daa790f47..d25701f4a 100644 --- a/src/dxgi/meson.build +++ b/src/dxgi/meson.build @@ -13,7 +13,7 @@ dxgi_src = [ ] dxgi_dll = shared_library('dxgi'+dll_ext, dxgi_src, dxgi_res, - name_prefix : '', + name_prefix : dxvk_name_prefix, dependencies : [ dxvk_dep ], include_directories : dxvk_include_path, install : true, From 1d3decf1008782428c4d34eadbf54d1077862da2 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 6 Oct 2022 01:22:17 +0100 Subject: [PATCH 0902/1348] [build] Add version scripts for native builds FEX would like clean symbols for experimenting with making thunks down the line. We also just shouldn't be exporting a bunch of random crap -- sadly -fvisibility=hidden doesn't help with a bunch of stuff :( For reference, RADV also does this. --- src/d3d11/d3d11.sym | 10 ++++++++++ src/d3d11/meson.build | 10 ++++++++++ src/d3d9/d3d9.sym | 24 ++++++++++++++++++++++++ src/d3d9/meson.build | 10 ++++++++++ src/dxgi/dxgi.sym | 11 +++++++++++ src/dxgi/meson.build | 10 ++++++++++ 6 files changed, 75 insertions(+) create mode 100644 src/d3d11/d3d11.sym create mode 100644 src/d3d9/d3d9.sym create mode 100644 src/dxgi/dxgi.sym diff --git a/src/d3d11/d3d11.sym b/src/d3d11/d3d11.sym new file mode 100644 index 000000000..91c8598ed --- /dev/null +++ b/src/d3d11/d3d11.sym @@ -0,0 +1,10 @@ +{ + global: + D3D11CoreCreateDevice; + D3D11CreateDevice; + D3D11CreateDeviceAndSwapChain; + D3D11On12CreateDevice; + + local: + *; +}; diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 26d655ade..f231fcf49 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -67,6 +67,14 @@ d3d11_shaders = files([ 'shaders/d3d11_video_blit_vert.vert', ]) +d3d11_ld_args = [] +d3d11_link_depends = [] + +if platform != 'windows' + d3d11_ld_args += [ '-Wl,--version-script', join_paths(meson.current_source_dir(), 'd3d11.sym') ] + d3d11_link_depends += files('d3d11.sym') +endif + d3d11_dll = shared_library('d3d11'+dll_ext, dxgi_common_src + d3d11_src + d3d10_src, glsl_generator.process(d3d11_shaders), d3d11_res, name_prefix : dxvk_name_prefix, @@ -74,6 +82,8 @@ d3d11_dll = shared_library('d3d11'+dll_ext, dxgi_common_src + d3d11_src + d3d10_ include_directories : dxvk_include_path, install : true, vs_module_defs : 'd3d11'+def_spec_ext, + link_args : d3d11_ld_args, + link_depends : [ d3d11_link_depends ], ) d3d11_dep = declare_dependency( diff --git a/src/d3d9/d3d9.sym b/src/d3d9/d3d9.sym new file mode 100644 index 000000000..fd2e67c5f --- /dev/null +++ b/src/d3d9/d3d9.sym @@ -0,0 +1,24 @@ +{ + global: + Direct3DCreate9; + Direct3DCreate9Ex; + D3DPERF_BeginEvent; + D3DPERF_EndEvent; + D3DPERF_SetMarker; + D3DPERF_SetRegion; + D3DPERF_QueryRepeatFrame; + D3DPERF_SetOptions; + D3DPERF_GetStatus; + DebugSetMute; + DebugSetLevel; + PSGPError; + PSGPSampleTexture; + Direct3DShaderValidatorCreate9; + Direct3D9EnableMaximizedWindowedModeShim; + DXVK_RegisterAnnotation; + DXVK_UnRegisterAnnotation; + Direct3D9ForceHybridEnumeration; + + local: + *; +}; diff --git a/src/d3d9/meson.build b/src/d3d9/meson.build index 9bb8eb1db..3d121e2cc 100644 --- a/src/d3d9/meson.build +++ b/src/d3d9/meson.build @@ -46,12 +46,22 @@ d3d9_src = [ 'd3d9_interop.cpp' ] +d3d9_ld_args = [] +d3d9_link_depends = [] + +if platform != 'windows' + d3d9_ld_args += [ '-Wl,--version-script', join_paths(meson.current_source_dir(), 'd3d9.sym') ] + d3d9_link_depends += files('d3d9.sym') +endif + d3d9_dll = shared_library('d3d9'+dll_ext, d3d9_src, glsl_generator.process(d3d9_shaders), d3d9_res, name_prefix : dxvk_name_prefix, dependencies : [ dxso_dep, dxvk_dep ], include_directories : dxvk_include_path, install : true, vs_module_defs : 'd3d9'+def_spec_ext, + link_args : d3d9_ld_args, + link_depends : [ d3d9_link_depends ], ) d3d9_dep = declare_dependency( diff --git a/src/dxgi/dxgi.sym b/src/dxgi/dxgi.sym new file mode 100644 index 000000000..d527d64f0 --- /dev/null +++ b/src/dxgi/dxgi.sym @@ -0,0 +1,11 @@ +{ + global: + CreateDXGIFactory2; + CreateDXGIFactory1; + CreateDXGIFactory; + DXGIDeclareAdapterRemovalSupport; + DXGIGetDebugInterface1; + + local: + *; +}; diff --git a/src/dxgi/meson.build b/src/dxgi/meson.build index d25701f4a..f0c1b2e9c 100644 --- a/src/dxgi/meson.build +++ b/src/dxgi/meson.build @@ -12,12 +12,22 @@ dxgi_src = [ 'dxgi_swapchain.cpp', ] +dxgi_ld_args = [] +dxgi_link_depends = [] + +if platform != 'windows' + dxgi_ld_args += [ '-Wl,--version-script', join_paths(meson.current_source_dir(), 'dxgi.sym') ] + dxgi_link_depends += files('dxgi.sym') +endif + dxgi_dll = shared_library('dxgi'+dll_ext, dxgi_src, dxgi_res, name_prefix : dxvk_name_prefix, dependencies : [ dxvk_dep ], include_directories : dxvk_include_path, install : true, vs_module_defs : 'dxgi'+def_spec_ext, + link_args : dxgi_ld_args, + link_depends : [ dxgi_link_depends ], ) dxgi_dep = declare_dependency( From 1157b235ccc2e93be1166978e8610908ec7d9c8d Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 6 Oct 2022 01:25:38 +0100 Subject: [PATCH 0903/1348] [build] Specify static libgcc/stdc++ on native We don't have any interfaces that rely on the c++ abi. Makes our builds more portable. Means that our builds in Sniper can be used on games that are still forcing the old C++03 string abi. --- meson.build | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/meson.build b/meson.build index 0ae1a4c92..8fb1265c1 100644 --- a/meson.build +++ b/meson.build @@ -114,6 +114,11 @@ else dxvk_wsi = 'sdl2' dxvk_name_prefix = 'libdxvk_' compiler_args += ['-DDXVK_WSI_SDL2'] + + link_args += [ + '-static-libgcc', + '-static-libstdc++', + ] endif dxvk_include_path = include_directories(dxvk_include_dirs) From 2484dac34ae9aedbc6668f726167c86f7e27526b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 22:10:36 +0000 Subject: [PATCH 0904/1348] [meta] Add package-native.sh --- package-native.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100755 package-native.sh diff --git a/package-native.sh b/package-native.sh new file mode 100755 index 000000000..ba5f44e4b --- /dev/null +++ b/package-native.sh @@ -0,0 +1,86 @@ +#!/usr/bin/env bash + +set -e + +shopt -s extglob + +if [ -z "$1" ] || [ -z "$2" ]; then + echo "Usage: $0 version destdir [--no-package] [--dev-build]" + exit 1 +fi + +DXVK_VERSION="$1" +DXVK_SRC_DIR=`dirname $(readlink -f $0)` +DXVK_BUILD_DIR=$(realpath "$2")"/dxvk-native-$DXVK_VERSION" +DXVK_ARCHIVE_PATH=$(realpath "$2")"/dxvk-native-$DXVK_VERSION.tar.gz" + +if [ -e "$DXVK_BUILD_DIR" ]; then + echo "Build directory $DXVK_BUILD_DIR already exists" + exit 1 +fi + +shift 2 + +opt_nopackage=0 +opt_devbuild=0 +opt_buildid=false + +CC=${CC:="gcc"} +CXX=${CXX:="g++"} + +while [ $# -gt 0 ]; do + case "$1" in + "--no-package") + opt_nopackage=1 + ;; + "--dev-build") + opt_nopackage=1 + opt_devbuild=1 + ;; + "--build-id") + opt_buildid=true + ;; + *) + echo "Unrecognized option: $1" >&2 + exit 1 + esac + shift +done + +function build_arch { + cd "$DXVK_SRC_DIR" + + opt_strip= + if [ $opt_devbuild -eq 0 ]; then + opt_strip=--strip + fi + + CC="$CC -m$1" CXX="$CXX -m$1" meson \ + --buildtype "release" \ + --prefix "$DXVK_BUILD_DIR/usr" \ + --bindir "$2" \ + --libdir "$2" \ + -Dbuild_id=$opt_buildid \ + "$DXVK_BUILD_DIR/build" + + cd "$DXVK_BUILD_DIR/build" + ninja install + + if [ $opt_devbuild -eq 0 ]; then + rm -r "$DXVK_BUILD_DIR/build" + fi +} + +function package { + cd "$DXVK_BUILD_DIR" + tar -czf "$DXVK_ARCHIVE_PATH" "usr" + cd ".." + rm -R "dxvk-native-$DXVK_VERSION" +} + +build_arch 64 lib +build_arch 32 lib32 + +if [ $opt_nopackage -eq 0 ]; then + package +fi From eea77b845f04402638e835362aa79da8b2a57013 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 10 Sep 2022 22:11:25 +0000 Subject: [PATCH 0905/1348] [meta] Add CI for native builds in Steam Runtime Sniper --- .github/workflows/artifacts.yml | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/.github/workflows/artifacts.yml b/.github/workflows/artifacts.yml index 5a43b8904..9fe6485ad 100644 --- a/.github/workflows/artifacts.yml +++ b/.github/workflows/artifacts.yml @@ -3,7 +3,7 @@ name: Artifacts (Package) on: [push, pull_request, workflow_dispatch] jobs: - build-artifacts: + artifacts-mingw-w64: runs-on: ubuntu-20.04 steps: @@ -33,3 +33,34 @@ jobs: name: dxvk-${{ env.VERSION_NAME }} path: build/dxvk-${{ env.VERSION_NAME }} if-no-files-found: error + + artifacts-steamrt-sniper: + runs-on: ubuntu-20.04 + container: registry.gitlab.steamos.cloud/steamrt/sniper/sdk:beta + + steps: + - name: Checkout code + id: checkout-code + uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + + - name: Setup problem matcher + uses: Joshua-Ashton/gcc-problem-matcher@v2 + + - name: Build release + id: build-release + shell: bash + run: | + export VERSION_NAME="${GITHUB_REF##*/}-${GITHUB_SHA##*/}" + ./package-native.sh ${VERSION_NAME} build --no-package + echo "VERSION_NAME=${VERSION_NAME}" >> $GITHUB_ENV + + - name: Upload artifacts + id: upload-artifacts + uses: actions/upload-artifact@v3 + with: + name: dxvk-${{ env.VERSION_NAME }} + path: build/dxvk-native-${{ env.VERSION_NAME }} + if-no-files-found: error From d83e184afdd3e1cd6a5427373b0a7dbe2f233b49 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 15 Oct 2022 18:17:29 +0100 Subject: [PATCH 0906/1348] [d3d10] Enable native builds This started working at some point... may as well! --- src/d3d10/d3d10core.sym | 9 +++++++++ src/d3d10/meson.build | 10 ++++++++++ src/meson.build | 10 +++------- 3 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 src/d3d10/d3d10core.sym diff --git a/src/d3d10/d3d10core.sym b/src/d3d10/d3d10core.sym new file mode 100644 index 000000000..ba6ccb596 --- /dev/null +++ b/src/d3d10/d3d10core.sym @@ -0,0 +1,9 @@ +{ + global: + D3D10CoreCreateDevice; + D3D10CoreGetVersion; + D3D10CoreRegisterLayers; + + local: + *; +}; diff --git a/src/d3d10/meson.build b/src/d3d10/meson.build index 1ef0167f4..fca2f82b5 100644 --- a/src/d3d10/meson.build +++ b/src/d3d10/meson.build @@ -4,12 +4,22 @@ d3d10_core_src = [ 'd3d10_core.cpp', ] +d3d10_core_ld_args = [] +d3d10_core_link_depends = [] + +if platform != 'windows' + d3d10_core_ld_args += [ '-Wl,--version-script', join_paths(meson.current_source_dir(), 'd3d10core.sym') ] + d3d10_core_link_depends += files('d3d10core.sym') +endif + d3d10_core_dll = shared_library('d3d10core'+dll_ext, d3d10_core_src, d3d10_core_res, name_prefix : dxvk_name_prefix, dependencies : [ d3d11_dep ], include_directories : dxvk_include_path, install : true, vs_module_defs : 'd3d10core'+def_spec_ext, + link_args : d3d10_core_ld_args, + link_depends : [ d3d10_core_link_depends ], ) d3d10_core_dep = declare_dependency( diff --git a/src/meson.build b/src/meson.build index f4de1099c..f641ac046 100644 --- a/src/meson.build +++ b/src/meson.build @@ -20,14 +20,10 @@ if get_option('enable_d3d11') endif if get_option('enable_d3d10') - if platform == 'windows' - if not get_option('enable_d3d11') - error('D3D11 is required for D3D10.') - endif - subdir('d3d10') - else - warning('Building D3D10 is not supported on non-Windows platforms') + if not get_option('enable_d3d11') + error('D3D11 is required for D3D10.') endif + subdir('d3d10') endif if get_option('enable_d3d9') From be9687f3967de0ac3fc3edb7e862aa68b991f0db Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 15 Oct 2022 18:18:52 +0100 Subject: [PATCH 0907/1348] [meta] Fix --dev-build on package-native.sh Re-add the suffix to the build dir. --- package-native.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-native.sh b/package-native.sh index ba5f44e4b..a690d48ae 100755 --- a/package-native.sh +++ b/package-native.sh @@ -61,13 +61,13 @@ function build_arch { --bindir "$2" \ --libdir "$2" \ -Dbuild_id=$opt_buildid \ - "$DXVK_BUILD_DIR/build" + "$DXVK_BUILD_DIR/build.$1" - cd "$DXVK_BUILD_DIR/build" + cd "$DXVK_BUILD_DIR/build.$1" ninja install if [ $opt_devbuild -eq 0 ]; then - rm -r "$DXVK_BUILD_DIR/build" + rm -r "$DXVK_BUILD_DIR/build.$1" fi } From fc3d04c1c97b3a45d157c83e1fe34f169de7a00e Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 15 Oct 2022 18:25:19 +0100 Subject: [PATCH 0908/1348] [meta] Fix opt_strip in package-native.sh --- package-native.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/package-native.sh b/package-native.sh index a690d48ae..0ee4920e0 100755 --- a/package-native.sh +++ b/package-native.sh @@ -55,12 +55,13 @@ function build_arch { opt_strip=--strip fi - CC="$CC -m$1" CXX="$CXX -m$1" meson \ - --buildtype "release" \ - --prefix "$DXVK_BUILD_DIR/usr" \ - --bindir "$2" \ - --libdir "$2" \ - -Dbuild_id=$opt_buildid \ + CC="$CC -m$1" CXX="$CXX -m$1" meson \ + --buildtype "release" \ + --prefix "$DXVK_BUILD_DIR/usr" \ + $opt_strip \ + --bindir "$2" \ + --libdir "$2" \ + -Dbuild_id=$opt_buildid \ "$DXVK_BUILD_DIR/build.$1" cd "$DXVK_BUILD_DIR/build.$1" From 580dd5cf4a6df987ce4e4a9c7498fde1988203ee Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 7 Oct 2022 16:01:36 +0200 Subject: [PATCH 0909/1348] [dxgi] Add swap chain factory interface definition --- src/dxgi/dxgi_interfaces.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index 10196f253..ba16d19de 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -81,6 +81,18 @@ IDXGIVkSwapChain : public IUnknown { }; +/** + * \brief Private DXGI presenter factory + */ +MIDL_INTERFACE("e7d6c3ca-23a0-4e08-9f2f-ea5231df6633") +IDXGIVkSwapChainFactory : public IUnknown { + virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( + HWND hWnd, + const DXGI_SWAP_CHAIN_DESC1* pDesc, + IDXGIVkSwapChain** ppSwapChain) = 0; +}; + + /** * \brief Private DXGI adapter interface * @@ -363,6 +375,7 @@ struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09323")) IDXGIVkInteropDe struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09324")) IDXGIVkInteropDevice1; struct __declspec(uuid("5546cf8c-77e7-4341-b05d-8d4d5000e77d")) IDXGIVkInteropSurface; struct __declspec(uuid("104001a6-7f36-4957-b932-86ade9567d91")) IDXGIVkSwapChain; +struct __declspec(uuid("e7d6c3ca-23a0-4e08-9f2f-ea5231df6633")) IDXGIVkSwapChainFactory; struct __declspec(uuid("53cb4ff0-c25a-4164-a891-0e83db0a7aac")) IWineDXGISwapChainFactory; #else __CRT_UUID_DECL(IDXGIDXVKAdapter, 0x907bf281,0xea3c,0x43b4,0xa8,0xe4,0x9f,0x23,0x11,0x07,0xb4,0xff); @@ -373,5 +386,6 @@ __CRT_UUID_DECL(IDXGIVkInteropDevice, 0xe2ef5fa5,0xdc21,0x4af7,0x90,0xc4,0x __CRT_UUID_DECL(IDXGIVkInteropDevice1, 0xe2ef5fa5,0xdc21,0x4af7,0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x24); __CRT_UUID_DECL(IDXGIVkInteropSurface, 0x5546cf8c,0x77e7,0x4341,0xb0,0x5d,0x8d,0x4d,0x50,0x00,0xe7,0x7d); __CRT_UUID_DECL(IDXGIVkSwapChain, 0x104001a6,0x7f36,0x4957,0xb9,0x32,0x86,0xad,0xe9,0x56,0x7d,0x91); +__CRT_UUID_DECL(IDXGIVkSwapChainFactory, 0xe7d6c3ca,0x23a0,0x4e08,0x9f,0x2f,0xea,0x52,0x31,0xdf,0x66,0x33); __CRT_UUID_DECL(IWineDXGISwapChainFactory, 0x53cb4ff0,0xc25a,0x4164,0xa8,0x91,0x0e,0x83,0xdb,0x0a,0x7a,0xac); #endif From aca67f64daee50712cd87bb8809f739273b7e780 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 7 Oct 2022 16:15:08 +0200 Subject: [PATCH 0910/1348] [d3d11] Implement IDXGIVkSwapChainFactory for D3D11 --- src/d3d11/d3d11_device.cpp | 52 ++++++++++++++++++++++++++++++++++++++ src/d3d11/d3d11_device.h | 33 ++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index ce2c06dec..f95081d18 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2972,6 +2972,52 @@ namespace dxvk { + DXGIVkSwapChainFactory::DXGIVkSwapChainFactory( + D3D11DXGIDevice* pContainer, + D3D11Device* pDevice) + : m_container(pContainer), m_device(pDevice) { + + } + + + ULONG STDMETHODCALLTYPE DXGIVkSwapChainFactory::AddRef() { + return m_device->AddRef(); + } + + + ULONG STDMETHODCALLTYPE DXGIVkSwapChainFactory::Release() { + return m_device->Release(); + } + + + HRESULT STDMETHODCALLTYPE DXGIVkSwapChainFactory::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_device->QueryInterface(riid, ppvObject); + } + + + HRESULT STDMETHODCALLTYPE DXGIVkSwapChainFactory::CreateSwapChain( + HWND hWnd, + const DXGI_SWAP_CHAIN_DESC1* pDesc, + IDXGIVkSwapChain** ppSwapChain) { + InitReturnPtr(ppSwapChain); + + try { + Com presenter = new D3D11SwapChain( + m_container, m_device, hWnd, pDesc); + + *ppSwapChain = presenter.ref(); + return S_OK; + } catch (const DxvkError& e) { + Logger::err(e.message()); + return E_FAIL; + } + } + + + + WineDXGISwapChainFactory::WineDXGISwapChainFactory( D3D11DXGIDevice* pContainer, D3D11Device* pDevice) @@ -3097,6 +3143,7 @@ namespace dxvk { m_d3d11Interop (this, &m_d3d11Device), m_d3d11Video (this, &m_d3d11Device), m_metaDevice (this), + m_dxvkFactory (this, &m_d3d11Device), m_wineFactory (this, &m_d3d11Device) { } @@ -3157,6 +3204,11 @@ namespace dxvk { return S_OK; } + if (riid == __uuidof(IDXGIVkSwapChainFactory)) { + *ppvObject = ref(&m_dxvkFactory); + return S_OK; + } + if (riid == __uuidof(IWineDXGISwapChainFactory)) { *ppvObject = ref(&m_wineFactory); return S_OK; diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 3db1c2ee3..3c1db4295 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -690,6 +690,38 @@ namespace dxvk { }; + /** + * \brief DXVK swap chain factory + */ + class DXGIVkSwapChainFactory : public IDXGIVkSwapChainFactory { + + public: + + DXGIVkSwapChainFactory( + D3D11DXGIDevice* pContainer, + D3D11Device* pDevice); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + HRESULT STDMETHODCALLTYPE CreateSwapChain( + HWND hWnd, + const DXGI_SWAP_CHAIN_DESC1* pDesc, + IDXGIVkSwapChain** ppSwapChain); + + private: + + D3D11DXGIDevice* m_container; + D3D11Device* m_device; + + }; + + /** * \brief DXGI swap chain factory */ @@ -851,6 +883,7 @@ namespace dxvk { D3D11VideoDevice m_d3d11Video; DXGIDXVKDevice m_metaDevice; + DXGIVkSwapChainFactory m_dxvkFactory; WineDXGISwapChainFactory m_wineFactory; uint32_t m_frameLatency = DefaultFrameLatency; From d7ac21b6c7f1602c1006ee29efe01c4d3f50a5a5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 7 Oct 2022 16:28:11 +0200 Subject: [PATCH 0911/1348] [dxgi] Use new DXVK swap chain factory if available --- src/dxgi/dxgi_factory.cpp | 64 +++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp index f159999dd..bbd411892 100644 --- a/src/dxgi/dxgi_factory.cpp +++ b/src/dxgi/dxgi_factory.cpp @@ -126,27 +126,59 @@ namespace dxvk { if (!ppSwapChain || !pDesc || !hWnd || !pDevice) return DXGI_ERROR_INVALID_CALL; - Com wineDevice; - - if (SUCCEEDED(pDevice->QueryInterface( - __uuidof(IWineDXGISwapChainFactory), - reinterpret_cast(&wineDevice)))) { - IDXGISwapChain4* frontendSwapChain; + // Make sure the back buffer size is not zero + DXGI_SWAP_CHAIN_DESC1 desc = *pDesc; - HRESULT hr = wineDevice->CreateSwapChainForHwnd( - this, hWnd, pDesc, pFullscreenDesc, + wsi::getWindowSize(hWnd, + desc.Width ? nullptr : &desc.Width, + desc.Height ? nullptr : &desc.Height); + + // If necessary, set up a default set of + // fullscreen parameters for the swap chain + DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsDesc; + + if (pFullscreenDesc) { + fsDesc = *pFullscreenDesc; + } else { + fsDesc.RefreshRate = { 0, 0 }; + fsDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + fsDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + fsDesc.Windowed = TRUE; + } + + // Probe various modes to create the swap chain object + Com frontendSwapChain; + + Com dxvkFactory; + Com wineFactory; + + if (SUCCEEDED(pDevice->QueryInterface(IID_PPV_ARGS(&dxvkFactory)))) { + Com presenter; + + HRESULT hr = dxvkFactory->CreateSwapChain(hWnd, &desc, &presenter); + + if (FAILED(hr)) { + Logger::err(str::format("DXGI: CreateSwapChainForHwnd: Failed to create swap chain, hr ", hr)); + return hr; + } + + frontendSwapChain = new DxgiSwapChain(this, presenter.ptr(), hWnd, &desc, &fsDesc); + } else if (SUCCEEDED(pDevice->QueryInterface(IID_PPV_ARGS(&wineFactory)))) { + HRESULT hr = wineFactory->CreateSwapChainForHwnd(this, hWnd, &desc, &fsDesc, pRestrictToOutput, reinterpret_cast(&frontendSwapChain)); - // No ref as that's handled by the object we're wrapping - // which was ref'ed on creation. - if (SUCCEEDED(hr)) - *ppSwapChain = new DxgiSwapChainDispatcher(frontendSwapChain); - - return hr; + if (FAILED(hr)) { + Logger::err(str::format("DXGI: CreateSwapChainForHwnd: Failed to create swap chain, hr ", hr)); + return hr; + } + } else { + Logger::err("DXGI: CreateSwapChainForHwnd: Unsupported device type"); + return DXGI_ERROR_UNSUPPORTED; } - Logger::err("DXGI: CreateSwapChainForHwnd: Unsupported device type"); - return DXGI_ERROR_UNSUPPORTED; + // Wrap object in swap chain dispatcher + *ppSwapChain = new DxgiSwapChainDispatcher(frontendSwapChain.ref()); + return S_OK; } From 69d7af42a41867d300a36613fa12d05ce538e886 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 7 Oct 2022 17:38:40 +0200 Subject: [PATCH 0912/1348] [dxgi] Change swap chain interface to better map to D3D12 needs --- src/d3d11/d3d11_swapchain.cpp | 33 ++++++++++++- src/d3d11/d3d11_swapchain.h | 13 +++++- src/dxgi/dxgi_interfaces.h | 30 ++++++++++-- src/dxgi/dxgi_swapchain.cpp | 87 +++++++++++++++-------------------- 4 files changed, 106 insertions(+), 57 deletions(-) diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 4a7dad00d..988013d03 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -131,8 +131,9 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11SwapChain::ChangeProperties( - const DXGI_SWAP_CHAIN_DESC1* pDesc) { - + const DXGI_SWAP_CHAIN_DESC1* pDesc, + const UINT* pNodeMasks, + IUnknown* const* ppPresentQueues) { m_dirty |= m_desc.Format != pDesc->Format || m_desc.Width != pDesc->Width || m_desc.Height != pDesc->Height @@ -255,6 +256,34 @@ namespace dxvk { } + UINT STDMETHODCALLTYPE D3D11SwapChain::CheckColorSpaceSupport( + DXGI_COLOR_SPACE_TYPE ColorSpace) { + UINT supportFlags = 0; + + if (ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709) + supportFlags |= DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT; + + return supportFlags; + } + + + HRESULT STDMETHODCALLTYPE D3D11SwapChain::SetColorSpace( + DXGI_COLOR_SPACE_TYPE ColorSpace) { + // Ignore, will only ever be sRGB + return S_OK; + } + + + HRESULT STDMETHODCALLTYPE D3D11SwapChain::SetHDRMetaData( + const DXGI_VK_HDR_METADATA* pMetaData) { + // For some reason this call always seems to succeed on Windows + if (pMetaData->Type == DXGI_HDR_METADATA_TYPE_HDR10) + Logger::warn("D3D11: HDR10 metadata not supported"); + + return S_OK; + } + + HRESULT D3D11SwapChain::PresentImage(UINT SyncInterval) { Com deviceContext = nullptr; m_parent->GetImmediateContext(&deviceContext); diff --git a/src/d3d11/d3d11_swapchain.h b/src/d3d11/d3d11_swapchain.h index 29f9b9a70..a7f535f2d 100644 --- a/src/d3d11/d3d11_swapchain.h +++ b/src/d3d11/d3d11_swapchain.h @@ -52,7 +52,9 @@ namespace dxvk { HANDLE STDMETHODCALLTYPE GetFrameLatencyEvent(); HRESULT STDMETHODCALLTYPE ChangeProperties( - const DXGI_SWAP_CHAIN_DESC1* pDesc); + const DXGI_SWAP_CHAIN_DESC1* pDesc, + const UINT* pNodeMasks, + IUnknown* const* ppPresentQueues); HRESULT STDMETHODCALLTYPE SetPresentRegion( const RECT* pRegion); @@ -69,6 +71,15 @@ namespace dxvk { UINT PresentFlags, const DXGI_PRESENT_PARAMETERS* pPresentParameters); + UINT STDMETHODCALLTYPE CheckColorSpaceSupport( + DXGI_COLOR_SPACE_TYPE ColorSpace); + + HRESULT STDMETHODCALLTYPE SetColorSpace( + DXGI_COLOR_SPACE_TYPE ColorSpace); + + HRESULT STDMETHODCALLTYPE SetHDRMetaData( + const DXGI_VK_HDR_METADATA* pMetaData); + private: enum BindingIds : uint32_t { diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index ba16d19de..f555e3cbd 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -30,6 +30,17 @@ struct DXGI_VK_MONITOR_DATA { }; +/** + * \brief HDR metadata struct + */ +struct DXGI_VK_HDR_METADATA { + DXGI_HDR_METADATA_TYPE Type; + union { + DXGI_HDR_METADATA_HDR10 HDR10; + }; +}; + + /** * \brief Private DXGI presenter * @@ -37,7 +48,7 @@ struct DXGI_VK_MONITOR_DATA { * chain implementation to remain API-agnostic, * so that common code can stay in one class. */ -MIDL_INTERFACE("104001a6-7f36-4957-b932-86ade9567d91") +MIDL_INTERFACE("e4a9059e-b569-46ab-8de7-501bd2bc7f7a") IDXGIVkSwapChain : public IUnknown { virtual HRESULT STDMETHODCALLTYPE GetDesc( DXGI_SWAP_CHAIN_DESC1* pDesc) = 0; @@ -62,7 +73,9 @@ IDXGIVkSwapChain : public IUnknown { virtual HANDLE STDMETHODCALLTYPE GetFrameLatencyEvent() = 0; virtual HRESULT STDMETHODCALLTYPE ChangeProperties( - const DXGI_SWAP_CHAIN_DESC1* pDesc) = 0; + const DXGI_SWAP_CHAIN_DESC1* pDesc, + const UINT* pNodeMasks, + IUnknown* const* ppPresentQueues) = 0; virtual HRESULT STDMETHODCALLTYPE SetPresentRegion( const RECT* pRegion) = 0; @@ -78,6 +91,15 @@ IDXGIVkSwapChain : public IUnknown { UINT SyncInterval, UINT PresentFlags, const DXGI_PRESENT_PARAMETERS* pPresentParameters) = 0; + + virtual UINT STDMETHODCALLTYPE CheckColorSpaceSupport( + DXGI_COLOR_SPACE_TYPE ColorSpace) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetColorSpace( + DXGI_COLOR_SPACE_TYPE ColorSpace) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetHDRMetaData( + const DXGI_VK_HDR_METADATA* pMetaData) = 0; }; @@ -374,7 +396,7 @@ struct __declspec(uuid("3a6d8f2c-b0e8-4ab4-b4dc-4fd24891bfa5")) IDXGIVkInteropAd struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09323")) IDXGIVkInteropDevice; struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09324")) IDXGIVkInteropDevice1; struct __declspec(uuid("5546cf8c-77e7-4341-b05d-8d4d5000e77d")) IDXGIVkInteropSurface; -struct __declspec(uuid("104001a6-7f36-4957-b932-86ade9567d91")) IDXGIVkSwapChain; +struct __declspec(uuid("e4a9059e-b569-46ab-8de7-501bd2bc7f7a")) IDXGIVkSwapChain; struct __declspec(uuid("e7d6c3ca-23a0-4e08-9f2f-ea5231df6633")) IDXGIVkSwapChainFactory; struct __declspec(uuid("53cb4ff0-c25a-4164-a891-0e83db0a7aac")) IWineDXGISwapChainFactory; #else @@ -385,7 +407,7 @@ __CRT_UUID_DECL(IDXGIVkInteropAdapter, 0x3a6d8f2c,0xb0e8,0x4ab4,0xb4,0xdc,0x __CRT_UUID_DECL(IDXGIVkInteropDevice, 0xe2ef5fa5,0xdc21,0x4af7,0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x23); __CRT_UUID_DECL(IDXGIVkInteropDevice1, 0xe2ef5fa5,0xdc21,0x4af7,0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x24); __CRT_UUID_DECL(IDXGIVkInteropSurface, 0x5546cf8c,0x77e7,0x4341,0xb0,0x5d,0x8d,0x4d,0x50,0x00,0xe7,0x7d); -__CRT_UUID_DECL(IDXGIVkSwapChain, 0x104001a6,0x7f36,0x4957,0xb9,0x32,0x86,0xad,0xe9,0x56,0x7d,0x91); +__CRT_UUID_DECL(IDXGIVkSwapChain, 0xe4a9059e,0xb569,0x46ab,0x8d,0xe7,0x50,0x1b,0xd2,0xbc,0x7f,0x7a); __CRT_UUID_DECL(IDXGIVkSwapChainFactory, 0xe7d6c3ca,0x23a0,0x4e08,0x9f,0x2f,0xea,0x52,0x31,0xdf,0x66,0x33); __CRT_UUID_DECL(IWineDXGISwapChainFactory, 0x53cb4ff0,0xc25a,0x4164,0xa8,0x91,0x0e,0x83,0xdb,0x0a,0x7a,0xac); #endif diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index f48a282c1..8fe029a1a 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -319,11 +319,24 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiSwapChain::ResizeBuffers( - UINT BufferCount, - UINT Width, - UINT Height, - DXGI_FORMAT NewFormat, - UINT SwapChainFlags) { + UINT BufferCount, + UINT Width, + UINT Height, + DXGI_FORMAT NewFormat, + UINT SwapChainFlags) { + return ResizeBuffers1(BufferCount, Width, Height, + NewFormat, SwapChainFlags, nullptr, nullptr); + } + + + HRESULT STDMETHODCALLTYPE DxgiSwapChain::ResizeBuffers1( + UINT BufferCount, + UINT Width, + UINT Height, + DXGI_FORMAT Format, + UINT SwapChainFlags, + const UINT* pCreationNodeMask, + IUnknown* const* ppPresentQueue) { if (!wsi::isWindow(m_window)) return DXGI_ERROR_INVALID_CALL; @@ -343,28 +356,10 @@ namespace dxvk { if (BufferCount != 0) m_desc.BufferCount = BufferCount; - if (NewFormat != DXGI_FORMAT_UNKNOWN) - m_desc.Format = NewFormat; + if (Format != DXGI_FORMAT_UNKNOWN) + m_desc.Format = Format; - return m_presenter->ChangeProperties(&m_desc); - } - - - HRESULT STDMETHODCALLTYPE DxgiSwapChain::ResizeBuffers1( - UINT BufferCount, - UINT Width, - UINT Height, - DXGI_FORMAT Format, - UINT SwapChainFlags, - const UINT* pCreationNodeMask, - IUnknown* const* ppPresentQueue) { - static bool s_errorShown = false; - - if (!std::exchange(s_errorShown, true)) - Logger::warn("DxgiSwapChain::ResizeBuffers1: Stub"); - - return ResizeBuffers(BufferCount, - Width, Height, Format, SwapChainFlags); + return m_presenter->ChangeProperties(&m_desc, pCreationNodeMask, ppPresentQueue); } @@ -515,11 +510,9 @@ namespace dxvk { || Height == 0 || Height > m_desc.Height) return E_INVALIDARG; - RECT region; - region.left = 0; - region.top = 0; - region.right = Width; - region.bottom = Height; + std::lock_guard lock(m_lockBuffer); + + RECT region = { 0, 0, LONG(Width), LONG(Height) }; return m_presenter->SetPresentRegion(®ion); } @@ -529,29 +522,19 @@ namespace dxvk { UINT* pColorSpaceSupport) { if (!pColorSpaceSupport) return E_INVALIDARG; - - UINT supportFlags = 0; - if (ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709) - supportFlags |= DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT; - - *pColorSpaceSupport = supportFlags; - return S_OK; + return m_presenter->CheckColorSpaceSupport(ColorSpace); } HRESULT STDMETHODCALLTYPE DxgiSwapChain::SetColorSpace1(DXGI_COLOR_SPACE_TYPE ColorSpace) { - UINT support = 0; - - HRESULT hr = CheckColorSpaceSupport(ColorSpace, &support); - - if (FAILED(hr)) - return hr; + UINT support = m_presenter->CheckColorSpaceSupport(ColorSpace); if (!support) return E_INVALIDARG; - return S_OK; + std::lock_guard lock(m_lockBuffer); + return m_presenter->SetColorSpace(ColorSpace); } @@ -562,22 +545,26 @@ namespace dxvk { if (Size && !pMetaData) return E_INVALIDARG; + DXGI_VK_HDR_METADATA metadata = { Type }; + switch (Type) { case DXGI_HDR_METADATA_TYPE_NONE: - return S_OK; + break; case DXGI_HDR_METADATA_TYPE_HDR10: if (Size != sizeof(DXGI_HDR_METADATA_HDR10)) return E_INVALIDARG; - // For some reason this always seems to succeed on Windows - Logger::warn("DXGI: HDR not supported"); - return S_OK; + metadata.HDR10 = *static_cast(pMetaData); + break; default: - Logger::err(str::format("DXGI: Invalid HDR metadata type: ", Type)); + Logger::err(str::format("DXGI: Unsupported HDR metadata type: ", Type)); return E_INVALIDARG; } + + std::lock_guard lock(m_lockBuffer); + return m_presenter->SetHDRMetaData(&metadata); } From 53a0c3726c311ea01846f83afa670972f502b619 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 18 Oct 2022 00:07:41 +0200 Subject: [PATCH 0913/1348] [dxvk] Don't crash immediately on pipeline library compile error Things will blow up down the line but there's no good reason to crash immediately. Also ignore returned pipeline on error so we'll always return null. --- src/dxvk/dxvk_shader.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 9bacd838f..baf2ca2a1 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -1130,9 +1130,9 @@ namespace dxvk { VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline); if (vr && !(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT)) - throw DxvkError(str::format("DxvkShaderPipelineLibrary: Failed to create vertex shader pipeline: ", vr)); + Logger::err(str::format("DxvkShaderPipelineLibrary: Failed to create vertex shader pipeline: ", vr)); - return pipeline; + return vr ? VK_NULL_HANDLE : pipeline; } @@ -1201,9 +1201,9 @@ namespace dxvk { VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline); if (vr && !(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT)) - throw DxvkError(str::format("DxvkShaderPipelineLibrary: Failed to create fragment shader pipeline: ", vr)); + Logger::err(str::format("DxvkShaderPipelineLibrary: Failed to create fragment shader pipeline: ", vr)); - return pipeline; + return vr ? VK_NULL_HANDLE : pipeline; } @@ -1223,9 +1223,9 @@ namespace dxvk { VkResult vr = vk->vkCreateComputePipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline); if (vr && !(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT)) - throw DxvkError(str::format("DxvkShaderPipelineLibrary: Failed to create compute shader pipeline: ", vr)); + Logger::err(str::format("DxvkShaderPipelineLibrary: Failed to create compute shader pipeline: ", vr)); - return pipeline; + return vr ? VK_NULL_HANDLE : pipeline; } From e311f252875384dbd8946de165306f999a524748 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Thu, 20 Oct 2022 09:12:29 -0500 Subject: [PATCH 0914/1348] [dxgi] Store device pointer in DxgiSwapChainDispatcher --- src/dxgi/dxgi_factory.cpp | 2 +- src/dxgi/dxgi_swapchain_dispatcher.h | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp index bbd411892..0f6afee2d 100644 --- a/src/dxgi/dxgi_factory.cpp +++ b/src/dxgi/dxgi_factory.cpp @@ -177,7 +177,7 @@ namespace dxvk { } // Wrap object in swap chain dispatcher - *ppSwapChain = new DxgiSwapChainDispatcher(frontendSwapChain.ref()); + *ppSwapChain = new DxgiSwapChainDispatcher(frontendSwapChain.ref(), pDevice); return S_OK; } diff --git a/src/dxgi/dxgi_swapchain_dispatcher.h b/src/dxgi/dxgi_swapchain_dispatcher.h index c8a503b38..d7d8b584d 100644 --- a/src/dxgi/dxgi_swapchain_dispatcher.h +++ b/src/dxgi/dxgi_swapchain_dispatcher.h @@ -8,8 +8,9 @@ namespace dxvk { public: - DxgiSwapChainDispatcher(IDXGISwapChain4* dispatch) - : m_dispatch(dispatch) { + DxgiSwapChainDispatcher(IDXGISwapChain4* dispatch, IUnknown* device) + : m_device(device), + m_dispatch(dispatch) { } virtual ~DxgiSwapChainDispatcher() { @@ -296,6 +297,10 @@ namespace dxvk { private: + // m_device is not used or reference counted, provided for compatibility with mod engines + // which expect to find device pointer in the memory after swapchain interface. + IUnknown* m_device; + IDXGISwapChain4* m_dispatch; }; From 26536280417bac217d696c03b94ebdc516b1e110 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Fri, 21 Oct 2022 13:42:15 +0200 Subject: [PATCH 0915/1348] [build] Always use glslang with --quiet We depend on a new enough glslang anyway. --- meson.build | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/meson.build b/meson.build index 8fb1265c1..322fe19e8 100644 --- a/meson.build +++ b/meson.build @@ -133,10 +133,13 @@ dll_ext = '' def_spec_ext = '.def' glsl_compiler = find_program('glslangValidator') -glsl_args = [ '--target-env', 'vulkan1.2', '--vn', '@BASENAME@', '@INPUT@', '-o', '@OUTPUT@' ] -if run_command(glsl_compiler, [ '--quiet', '--version' ], check : false).returncode() == 0 - glsl_args += [ '--quiet' ] -endif +glsl_args = [ + '--quiet', + '--target-env', 'vulkan1.2', + '--vn', '@BASENAME@', + '@INPUT@', + '-o', '@OUTPUT@', +] glsl_generator = generator(glsl_compiler, output : [ '@BASENAME@.h' ], arguments : glsl_args, From ae764333f486ec40dd70079bdb05dd43fd4d03c8 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Fri, 21 Oct 2022 13:47:36 +0200 Subject: [PATCH 0916/1348] [build] Use glslang with --depfile to rebuild on header changes --- meson.build | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 322fe19e8..4c4a32210 100644 --- a/meson.build +++ b/meson.build @@ -137,11 +137,14 @@ glsl_args = [ '--quiet', '--target-env', 'vulkan1.2', '--vn', '@BASENAME@', + '--depfile', '@DEPFILE@', '@INPUT@', '-o', '@OUTPUT@', ] -glsl_generator = generator(glsl_compiler, +glsl_generator = generator( + glsl_compiler, output : [ '@BASENAME@.h' ], + depfile : '@BASENAME@.h.d', arguments : glsl_args, ) From a6ede3e0c2613a1ee11af6ed67c502b9dad9117c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 17 Oct 2022 18:55:07 +0200 Subject: [PATCH 0917/1348] [meta] Update Vulkan headers to 1.3.231 --- include/vulkan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vulkan b/include/vulkan index 715673702..98f440ce6 160000 --- a/include/vulkan +++ b/include/vulkan @@ -1 +1 @@ -Subproject commit 715673702f5b18ffb8e5832e67cf731468d32ac6 +Subproject commit 98f440ce6868c94f5ec6e198cc1adda4760e8849 From 859de7e82864132b7d8cab55660edda17716222b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 18 Oct 2022 19:37:41 +0200 Subject: [PATCH 0918/1348] [dxvk] Always enable depth clip feature if supported --- src/d3d11/d3d11_device.cpp | 2 -- src/d3d9/d3d9_device.cpp | 2 -- src/dxvk/dxvk_adapter.cpp | 4 ++++ 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index f95081d18..6d3580a54 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1908,8 +1908,6 @@ namespace dxvk { enabled.extCustomBorderColor.customBorderColors = supported.extCustomBorderColor.customBorderColorWithoutFormat; enabled.extCustomBorderColor.customBorderColorWithoutFormat = supported.extCustomBorderColor.customBorderColorWithoutFormat; - enabled.extDepthClipEnable.depthClipEnable = supported.extDepthClipEnable.depthClipEnable; - enabled.extTransformFeedback.transformFeedback = VK_TRUE; enabled.extTransformFeedback.geometryStreams = VK_TRUE; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 3aa396482..d2cca4fdb 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -3951,8 +3951,6 @@ namespace dxvk { // Ensure we support real BC formats and unofficial vendor ones. enabled.core.features.textureCompressionBC = VK_TRUE; - enabled.extDepthClipEnable.depthClipEnable = supported.extDepthClipEnable.depthClipEnable; - // SM2 level hardware enabled.core.features.occlusionQueryPrecise = VK_TRUE; diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 2fe5d87af..74d5aa2df 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -429,6 +429,10 @@ namespace dxvk { enabledFeatures.vk13.synchronization2 = VK_TRUE; enabledFeatures.vk13.dynamicRendering = VK_TRUE; + // We expose depth clip rather than depth clamp to client APIs + enabledFeatures.extDepthClipEnable.depthClipEnable = + m_deviceFeatures.extDepthClipEnable.depthClipEnable; + // Used for both pNext shader module info, and fast-linking pipelines provided // that graphicsPipelineLibraryIndependentInterpolationDecoration is supported enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = From 8e7ea899d2a2a13b3dc033f235d63a7eae1cc34c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 17 Oct 2022 19:10:04 +0200 Subject: [PATCH 0919/1348] [dxvk] Enable VK_EXT_extended_dynamic_state_3 if available --- src/dxvk/dxvk_adapter.cpp | 20 +++++++++++++++++++- src/dxvk/dxvk_device_info.h | 2 ++ src/dxvk/dxvk_extensions.h | 1 + src/vulkan/vulkan_loader.h | 18 ++++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 74d5aa2df..243d781df 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -335,13 +335,14 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.extAttachmentFeedbackLoopLayout, &devExtensions.extConservativeRasterization, &devExtensions.extCustomBorderColor, &devExtensions.extDepthClipEnable, + &devExtensions.extExtendedDynamicState3, &devExtensions.extFragmentShaderInterlock, &devExtensions.extFullScreenExclusive, &devExtensions.extGraphicsPipelineLibrary, @@ -487,6 +488,11 @@ namespace dxvk { enabledFeatures.extDepthClipEnable.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extDepthClipEnable); } + if (devExtensions.extExtendedDynamicState3) { + enabledFeatures.extExtendedDynamicState3.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT; + enabledFeatures.extExtendedDynamicState3.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extExtendedDynamicState3); + } + if (devExtensions.extFragmentShaderInterlock) { enabledFeatures.extFragmentShaderInterlock.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT; enabledFeatures.extFragmentShaderInterlock.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extFragmentShaderInterlock); @@ -737,6 +743,11 @@ namespace dxvk { m_deviceInfo.extCustomBorderColor.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extCustomBorderColor); } + if (m_deviceExtensions.supports(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME)) { + m_deviceInfo.extExtendedDynamicState3.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_PROPERTIES_EXT; + m_deviceInfo.extExtendedDynamicState3.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extExtendedDynamicState3); + } + if (m_deviceExtensions.supports(VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME)) { m_deviceInfo.extGraphicsPipelineLibrary.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT; m_deviceInfo.extGraphicsPipelineLibrary.pNext = std::exchange(m_deviceInfo.core.pNext, &m_deviceInfo.extGraphicsPipelineLibrary); @@ -815,6 +826,11 @@ namespace dxvk { m_deviceFeatures.extDepthClipEnable.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extDepthClipEnable); } + if (m_deviceExtensions.supports(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME)) { + m_deviceFeatures.extExtendedDynamicState3.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT; + m_deviceFeatures.extExtendedDynamicState3.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extExtendedDynamicState3); + } + if (m_deviceExtensions.supports(VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME)) { m_deviceFeatures.extFragmentShaderInterlock.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT; m_deviceFeatures.extFragmentShaderInterlock.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extFragmentShaderInterlock); @@ -980,6 +996,8 @@ namespace dxvk { "\n customBorderColorWithoutFormat : ", features.extCustomBorderColor.customBorderColorWithoutFormat ? "1" : "0", "\n", VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, "\n depthClipEnable : ", features.extDepthClipEnable.depthClipEnable ? "1" : "0", + "\n", VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME, + "\n extendedDynamicState3DepthClipEnable : ", features.extExtendedDynamicState3.extendedDynamicState3DepthClipEnable ? "1" : "0", "\n", VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME, "\n fragmentShaderSampleInterlock : ", features.extFragmentShaderInterlock.fragmentShaderSampleInterlock ? "1" : "0", "\n fragmentShaderPixelInterlock : ", features.extFragmentShaderInterlock.fragmentShaderPixelInterlock ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index d8e23a084..21b1b68cc 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -19,6 +19,7 @@ namespace dxvk { VkPhysicalDeviceVulkan13Properties vk13; VkPhysicalDeviceConservativeRasterizationPropertiesEXT extConservativeRasterization; VkPhysicalDeviceCustomBorderColorPropertiesEXT extCustomBorderColor; + VkPhysicalDeviceExtendedDynamicState3PropertiesEXT extExtendedDynamicState3; VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT extGraphicsPipelineLibrary; VkPhysicalDeviceRobustness2PropertiesEXT extRobustness2; VkPhysicalDeviceTransformFeedbackPropertiesEXT extTransformFeedback; @@ -43,6 +44,7 @@ namespace dxvk { VkBool32 extConservativeRasterization; VkPhysicalDeviceCustomBorderColorFeaturesEXT extCustomBorderColor; VkPhysicalDeviceDepthClipEnableFeaturesEXT extDepthClipEnable; + VkPhysicalDeviceExtendedDynamicState3FeaturesEXT extExtendedDynamicState3; VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT extFragmentShaderInterlock; VkBool32 extFullScreenExclusive; VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT extGraphicsPipelineLibrary; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 7eb30e6b8..1684f6caa 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -282,6 +282,7 @@ namespace dxvk { DxvkExt extConservativeRasterization = { VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extCustomBorderColor = { VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extDepthClipEnable = { VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extExtendedDynamicState3 = { VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extFullScreenExclusive = { VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extFragmentShaderInterlock = { VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extGraphicsPipelineLibrary = { VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 8701ca588..1f0ae7eed 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -358,6 +358,24 @@ namespace dxvk::vk { VULKAN_FN(vkSetDebugUtilsObjectTagEXT); #endif + #ifdef VK_EXT_extended_dynamic_state3 + VULKAN_FN(vkCmdSetTessellationDomainOriginEXT); + VULKAN_FN(vkCmdSetDepthClampEnableEXT); + VULKAN_FN(vkCmdSetPolygonModeEXT); + VULKAN_FN(vkCmdSetRasterizationSamplesEXT); + VULKAN_FN(vkCmdSetSampleMaskEXT); + VULKAN_FN(vkCmdSetAlphaToCoverageEnableEXT); + VULKAN_FN(vkCmdSetAlphaToOneEnableEXT); + VULKAN_FN(vkCmdSetLogicOpEnableEXT); + VULKAN_FN(vkCmdSetColorBlendEnableEXT); + VULKAN_FN(vkCmdSetColorBlendEquationEXT); + VULKAN_FN(vkCmdSetColorWriteMaskEXT); + VULKAN_FN(vkCmdSetRasterizationStreamEXT); + VULKAN_FN(vkCmdSetConservativeRasterizationModeEXT); + VULKAN_FN(vkCmdSetExtraPrimitiveOverestimationSizeEXT); + VULKAN_FN(vkCmdSetDepthClipEnableEXT); + #endif + #ifdef VK_EXT_full_screen_exclusive VULKAN_FN(vkAcquireFullScreenExclusiveModeEXT); VULKAN_FN(vkReleaseFullScreenExclusiveModeEXT); From fea86ef116891afe7c75da6040bcfe9a2a141276 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 18 Oct 2022 11:51:46 +0200 Subject: [PATCH 0920/1348] [dxvk] Use dynamic depth clip enable for linked pipelines if supported This way we won't have to compile any vertex shader pipelines twice. --- src/dxvk/dxvk_adapter.cpp | 5 +++++ src/dxvk/dxvk_cmdlist.h | 6 ++++++ src/dxvk/dxvk_context.cpp | 5 +++++ src/dxvk/dxvk_graphics.cpp | 4 +++- src/dxvk/dxvk_shader.cpp | 29 ++++++++++++++++++----------- 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 243d781df..e7ef26226 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -434,6 +434,11 @@ namespace dxvk { enabledFeatures.extDepthClipEnable.depthClipEnable = m_deviceFeatures.extDepthClipEnable.depthClipEnable; + // Used to make pipeline library stuff less clunky + enabledFeatures.extExtendedDynamicState3.extendedDynamicState3DepthClipEnable = + m_deviceFeatures.extExtendedDynamicState3.extendedDynamicState3DepthClipEnable && + m_deviceFeatures.extDepthClipEnable.depthClipEnable; + // Used for both pNext shader module info, and fast-linking pipelines provided // that graphicsPipelineLibraryIndependentInterpolationDecoration is supported enabledFeatures.extGraphicsPipelineLibrary.graphicsPipelineLibrary = diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 45f67c6d4..17c725352 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -811,6 +811,12 @@ namespace dxvk { } + void cmdSetDepthClipState( + VkBool32 depthClipEnable) { + m_vkd->vkCmdSetDepthClipEnableEXT(m_cmd.execBuffer, depthClipEnable); + } + + void cmdSetDepthBias( float depthBiasConstantFactor, float depthBiasClamp, diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index b4215ddbb..14cb8b598 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -5609,6 +5609,11 @@ namespace dxvk { m_cmd->cmdSetDepthBiasState( m_state.gp.state.rs.depthBiasEnable()); + + if (m_device->features().extExtendedDynamicState3.extendedDynamicState3DepthClipEnable) { + m_cmd->cmdSetDepthClipState( + m_state.gp.state.rs.depthClipEnable()); + } } if (unlikely(m_flags.all(DxvkContextFlag::GpDirtyBlendConstants, diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 8b0a65502..0e461f713 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -1124,7 +1124,9 @@ namespace dxvk { DxvkGraphicsPipelineBaseInstanceKey key; key.viLibrary = m_manager->createVertexInputLibrary(viState); key.foLibrary = m_manager->createFragmentOutputLibrary(foState); - key.args.depthClipEnable = state.rs.depthClipEnable(); + + if (!m_device->features().extExtendedDynamicState3.extendedDynamicState3DepthClipEnable) + key.args.depthClipEnable = state.rs.depthClipEnable(); auto entry = m_basePipelines.find(key); if (entry != m_basePipelines.end()) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index baf2ca2a1..0e3195cae 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -1077,17 +1077,21 @@ namespace dxvk { // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. - std::array dynamicStates = {{ - VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, - VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, - VK_DYNAMIC_STATE_DEPTH_BIAS, - VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE, - VK_DYNAMIC_STATE_CULL_MODE, - VK_DYNAMIC_STATE_FRONT_FACE, - }}; + uint32_t dynamicStateCount = 0; + std::array dynamicStates; + + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_CULL_MODE; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_FRONT_FACE; + + if (m_device->features().extExtendedDynamicState3.extendedDynamicState3DepthClipEnable) + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT; VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; - dyInfo.dynamicStateCount = dynamicStates.size(); + dyInfo.dynamicStateCount = dynamicStateCount; dyInfo.pDynamicStates = dynamicStates.data(); // All viewport state is dynamic, so we do not need to initialize this. @@ -1104,8 +1108,11 @@ namespace dxvk { rsInfo.lineWidth = 1.0f; if (m_device->features().extDepthClipEnable.depthClipEnable) { - rsDepthClipInfo.pNext = std::exchange(rsInfo.pNext, &rsDepthClipInfo); - rsDepthClipInfo.depthClipEnable = args.depthClipEnable; + // Only use the fixed depth clip state if we can't make it dynamic + if (!m_device->features().extExtendedDynamicState3.extendedDynamicState3DepthClipEnable) { + rsDepthClipInfo.pNext = std::exchange(rsInfo.pNext, &rsDepthClipInfo); + rsDepthClipInfo.depthClipEnable = args.depthClipEnable; + } } else { rsInfo.depthClampEnable = !args.depthClipEnable; } From b055c2daea4c8642cb44a35bc137ca36846795fc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 24 Oct 2022 17:58:57 +0200 Subject: [PATCH 0921/1348] [d3d11] Avoid querying environment variables on shader creation --- src/d3d11/d3d11_options.cpp | 3 +++ src/d3d11/d3d11_options.h | 3 +++ src/d3d11/d3d11_shader.cpp | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index 6a3f371cc..1d2997122 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -67,6 +67,9 @@ namespace dxvk { } } } + + // Shader dump path is only available via an environment variable + this->shaderDumpPath = env::getEnvVar("DXVK_SHADER_DUMP_PATH"); } } \ No newline at end of file diff --git a/src/d3d11/d3d11_options.h b/src/d3d11/d3d11_options.h index 594580200..e9431538c 100644 --- a/src/d3d11/d3d11_options.h +++ b/src/d3d11/d3d11_options.h @@ -116,6 +116,9 @@ namespace dxvk { /// useful for debugging purposes or when applications have /// race conditions. bool enableContextLock; + + /// Shader dump path + std::string shaderDumpPath; }; } \ No newline at end of file diff --git a/src/d3d11/d3d11_shader.cpp b/src/d3d11/d3d11_shader.cpp index c153c8397..3d6a0642d 100644 --- a/src/d3d11/d3d11_shader.cpp +++ b/src/d3d11/d3d11_shader.cpp @@ -24,7 +24,7 @@ namespace dxvk { // If requested by the user, dump both the raw DXBC // shader and the compiled SPIR-V module to a file. - const std::string dumpPath = env::getEnvVar("DXVK_SHADER_DUMP_PATH"); + const std::string& dumpPath = pDevice->GetOptions()->shaderDumpPath; if (dumpPath.size() != 0) { reader.store(std::ofstream(str::topath(str::format(dumpPath, "/", name, ".dxbc").c_str()).c_str(), From 494e01b353b0593ecd9e698158e62c68805a1a1e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 24 Oct 2022 18:01:48 +0200 Subject: [PATCH 0922/1348] [d3d9] Avoid querying environment variables on shader creation --- src/d3d9/d3d9_fixed_function.cpp | 8 ++++---- src/d3d9/d3d9_fixed_function.h | 2 +- src/d3d9/d3d9_options.cpp | 2 ++ src/d3d9/d3d9_options.h | 3 +++ src/d3d9/d3d9_shader.cpp | 2 +- src/d3d9/d3d9_swvp_emu.cpp | 2 +- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 8efc9db39..c24cf064e 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -2449,7 +2449,7 @@ namespace dxvk { m_shader = compiler.compile(); m_isgn = compiler.isgn(); - Dump(Key, name); + Dump(pDevice, Key, name); m_shader->setShaderKey(shaderKey); pDevice->GetDXVKDevice()->registerShader(m_shader); @@ -2472,15 +2472,15 @@ namespace dxvk { m_shader = compiler.compile(); m_isgn = compiler.isgn(); - Dump(Key, name); + Dump(pDevice, Key, name); m_shader->setShaderKey(shaderKey); pDevice->GetDXVKDevice()->registerShader(m_shader); } template - void D3D9FFShader::Dump(const T& Key, const std::string& Name) { - const std::string dumpPath = env::getEnvVar("DXVK_SHADER_DUMP_PATH"); + void D3D9FFShader::Dump(D3D9DeviceEx* pDevice, const T& Key, const std::string& Name) { + const std::string& dumpPath = pDevice->GetOptions()->shaderDumpPath; if (dumpPath.size() != 0) { std::ofstream dumpStream( diff --git a/src/d3d9/d3d9_fixed_function.h b/src/d3d9/d3d9_fixed_function.h index 4fe8d82c0..a75458713 100644 --- a/src/d3d9/d3d9_fixed_function.h +++ b/src/d3d9/d3d9_fixed_function.h @@ -217,7 +217,7 @@ namespace dxvk { const D3D9FFShaderKeyFS& Key); template - void Dump(const T& Key, const std::string& Name); + void Dump(D3D9DeviceEx* pDevice, const T& Key, const std::string& Name); Rc GetShader() const { return m_shader; diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index 0eabb3391..33938c4f7 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -86,6 +86,8 @@ namespace dxvk { && adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV, 0, 0); d3d9FloatEmulation = hasMulz ? D3D9FloatEmulation::Strict : D3D9FloatEmulation::Enabled; } + + this->shaderDumpPath = env::getEnvVar("DXVK_SHADER_DUMP_PATH"); } } \ No newline at end of file diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index cb0b5d4d3..43fcbb954 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -152,6 +152,9 @@ namespace dxvk { /// How much virtual memory will be used for textures (in MB). int32_t textureMemory; + + /// Shader dump path + std::string shaderDumpPath; }; } diff --git a/src/d3d9/d3d9_shader.cpp b/src/d3d9/d3d9_shader.cpp index 650a382e6..a62ceee10 100644 --- a/src/d3d9/d3d9_shader.cpp +++ b/src/d3d9/d3d9_shader.cpp @@ -23,7 +23,7 @@ namespace dxvk { // If requested by the user, dump both the raw DXBC // shader and the compiled SPIR-V module to a file. - const std::string dumpPath = env::getEnvVar("DXVK_SHADER_DUMP_PATH"); + const std::string& dumpPath = pDevice->GetOptions()->shaderDumpPath; if (dumpPath.size() != 0) { DxsoReader reader( diff --git a/src/d3d9/d3d9_swvp_emu.cpp b/src/d3d9/d3d9_swvp_emu.cpp index 140534956..39bf3da1d 100644 --- a/src/d3d9/d3d9_swvp_emu.cpp +++ b/src/d3d9/d3d9_swvp_emu.cpp @@ -322,7 +322,7 @@ namespace dxvk { shader->setShaderKey(key); pDevice->GetDXVKDevice()->registerShader(shader); - const std::string dumpPath = env::getEnvVar("DXVK_SHADER_DUMP_PATH"); + const std::string& dumpPath = pDevice->GetOptions()->shaderDumpPath; if (dumpPath.size() != 0) { std::ofstream dumpStream( From d771f7cf8fc8f246fdabf731142d6aa4bb475941 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 24 Oct 2022 20:17:35 +0200 Subject: [PATCH 0923/1348] [d3d9] Remove dead fields --- src/d3d9/d3d9_common_buffer.h | 1 - src/d3d9/d3d9_common_texture.h | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/d3d9/d3d9_common_buffer.h b/src/d3d9/d3d9_common_buffer.h index d2f7f7458..cf6726924 100644 --- a/src/d3d9/d3d9_common_buffer.h +++ b/src/d3d9/d3d9_common_buffer.h @@ -229,7 +229,6 @@ namespace dxvk { const D3D9_BUFFER_DESC m_desc; DWORD m_mapFlags; bool m_needsReadback = false; - bool m_uploadUsingStaging = false; D3D9_COMMON_BUFFER_MAP_MODE m_mapMode; Rc m_buffer; diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index b727c8725..fea9263c5 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -512,8 +512,6 @@ namespace dxvk { int64_t m_size = 0; - bool m_systemmemModified = false; - bool m_hazardous = false; D3D9ColorView m_sampleView; @@ -526,8 +524,6 @@ namespace dxvk { D3D9SubresourceBitset m_needsUpload = { }; - D3D9SubresourceBitset m_uploadUsingStaging = { }; - DWORD m_exposedMipLevels = 0; bool m_needsMipGen = false; From 9c22a585434ace22072e9014aa99098af4894caa Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 24 Oct 2022 20:40:58 +0200 Subject: [PATCH 0924/1348] [d3d9] Disable locking non-dynamic default textures --- src/d3d9/d3d9_device.cpp | 9 +++++++++ src/d3d9/d3d9_format.h | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index d2cca4fdb..c10ab0766 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4239,6 +4239,15 @@ namespace dxvk { auto& desc = *(pResource->Desc()); + // MSDN: + // Textures placed in the D3DPOOL_DEFAULT pool cannot be locked + // unless they are dynamic textures or they are private, FOURCC, driver formats. + // Also note that - unlike textures - swap chain back buffers, render targets [..] can be locked + if (unlikely(desc.Pool == D3DPOOL_DEFAULT + && !(desc.Usage & (D3DUSAGE_DYNAMIC | D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) + && !IsFourCCFormat(desc.Format))) + return D3DERR_INVALIDCALL; + auto& formatMapping = pResource->GetFormatMapping(); const DxvkFormatInfo* formatInfo = formatMapping.IsValid() diff --git a/src/d3d9/d3d9_format.h b/src/d3d9/d3d9_format.h index 1bdb4fb02..23acd1f51 100644 --- a/src/d3d9/d3d9_format.h +++ b/src/d3d9/d3d9_format.h @@ -219,4 +219,9 @@ namespace dxvk { bool m_d32supportFinal; }; + inline bool IsFourCCFormat(D3D9Format format) { + // BINARYBUFFER is the largest non-fourcc format + return format > D3D9Format::BINARYBUFFER; + } + } From 6335f065c3ead7047f6a68832917e24df9d44a81 Mon Sep 17 00:00:00 2001 From: iczero Date: Mon, 24 Oct 2022 05:59:17 -0400 Subject: [PATCH 0925/1348] Ensure setup_dxvk.sh works with spaces in basedir --- setup_dxvk.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup_dxvk.sh b/setup_dxvk.sh index e6fd67401..2e1e0b414 100755 --- a/setup_dxvk.sh +++ b/setup_dxvk.sh @@ -5,7 +5,7 @@ dxvk_lib32=${dxvk_lib32:-"x32"} dxvk_lib64=${dxvk_lib64:-"x64"} # figure out where we are -basedir=$(dirname "$(readlink -f $0)") +basedir="$(dirname "$(readlink -f "$0")")" # figure out which action to perform action="$1" From f84f992d44900d0e118df63cfd36885bec248423 Mon Sep 17 00:00:00 2001 From: Winter Snowfall Date: Sun, 23 Oct 2022 17:16:48 +0300 Subject: [PATCH 0926/1348] [util] Also enable workaround for the "mod load exe" of ToEE --- src/util/config/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index f25e7c6b5..fad24021e 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -402,7 +402,7 @@ namespace dxvk { { "d3d9.forceAspectRatio", "16:9" }, }} }, /* D&D - The Temple Of Elemental Evil */ - { R"(\\ToEE\.exe$)", {{ + { R"(\\ToEE(a)?\.exe$)", {{ { "d3d9.allowDiscard", "False" }, }} }, /* ZUSI 3 - Aerosoft Edition */ From cd21cd7fa3b0df3e0819e21ca700b7627a838d69 Mon Sep 17 00:00:00 2001 From: Konstantin Kharlamov Date: Sat, 8 Oct 2022 17:44:26 +0300 Subject: [PATCH 0927/1348] setup_dxvk.sh: install with reflinks if supported Some filesystems, such as XFS and BTRFS, may perform a lightweight copy with CoW. This is most useful for rarely changing content, and the usecase of installing DXVK is one of such usecases, as library files are usually not modified (might be removed, but it's not modification). So make use of it whenever supported. --- setup_dxvk.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup_dxvk.sh b/setup_dxvk.sh index 2e1e0b414..0f1998f30 100755 --- a/setup_dxvk.sh +++ b/setup_dxvk.sh @@ -25,7 +25,7 @@ esac shift with_dxgi=true -file_cmd="cp -v" +file_cmd="cp -v --reflink=auto" while (($# > 0)); do case "$1" in From bc31ebe1518ef7d68bbd87417334abd828085c01 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Sat, 29 Oct 2022 10:33:53 +0200 Subject: [PATCH 0928/1348] [d3d9] Fix OptimizeLayout with feedback loop usage. We kind of need dcc on GFX8/9. --- src/d3d9/d3d9_common_texture.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 67fba7b09..22646aea1 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -485,8 +485,10 @@ namespace dxvk { // Filter out unnecessary flags. Transfer operations // are handled by the backend in a transparent manner. + // Feedback loops are handled by hazard tracking. Usage &= ~(VK_IMAGE_USAGE_TRANSFER_DST_BIT - | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); + | VK_IMAGE_USAGE_TRANSFER_SRC_BIT + | VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT); // Ignore sampled bit in case the image was created with // an image flag that only allows attachment usage From 0fc5c84e7bc414ffbbf971b91a48fa11fac1cc98 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sun, 30 Oct 2022 21:04:02 +0100 Subject: [PATCH 0929/1348] [d3d9] Don't advertise support for MS INTZ format --- src/d3d9/d3d9_adapter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_adapter.cpp b/src/d3d9/d3d9_adapter.cpp index d304ff2c9..b85f7406b 100644 --- a/src/d3d9/d3d9_adapter.cpp +++ b/src/d3d9/d3d9_adapter.cpp @@ -186,7 +186,8 @@ namespace dxvk { if (MultiSampleType != D3DMULTISAMPLE_NONE && (SurfaceFormat == D3D9Format::D32_LOCKABLE || SurfaceFormat == D3D9Format::D32F_LOCKABLE - || SurfaceFormat == D3D9Format::D16_LOCKABLE)) + || SurfaceFormat == D3D9Format::D16_LOCKABLE + || SurfaceFormat == D3D9Format::INTZ)) return D3DERR_NOTAVAILABLE; uint32_t sampleCount = std::max(MultiSampleType, 1u); From 0462454d2bccc1ed1c9e384f31561f274a41e599 Mon Sep 17 00:00:00 2001 From: Adam Jereczek Date: Mon, 31 Oct 2022 19:16:15 +0100 Subject: [PATCH 0930/1348] Fix for saving vertex shader constants with a StateBlock Co-authored-by: aroztkow --- src/d3d9/d3d9_stateblock.cpp | 11 +++-------- src/util/util_bit.h | 11 +++++++++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/d3d9/d3d9_stateblock.cpp b/src/d3d9/d3d9_stateblock.cpp index 9ad2a590d..6deca2246 100644 --- a/src/d3d9/d3d9_stateblock.cpp +++ b/src/d3d9/d3d9_stateblock.cpp @@ -470,14 +470,9 @@ namespace dxvk { m_captures.flags.set(D3D9CapturedStateFlag::VertexShader); m_captures.flags.set(D3D9CapturedStateFlag::VsConstants); - for (uint32_t i = 0; i < m_parent->GetVertexConstantLayout().floatCount / 32; i++) - m_captures.vsConsts.fConsts.dword(i) = std::numeric_limits::max(); - - for (uint32_t i = 0; i < m_parent->GetVertexConstantLayout().intCount / 32; i++) - m_captures.vsConsts.iConsts.dword(i) = std::numeric_limits::max(); - - for (uint32_t i = 0; i < m_parent->GetVertexConstantLayout().bitmaskCount; i++) - m_captures.vsConsts.bConsts.dword(i) = std::numeric_limits::max(); + m_captures.vsConsts.fConsts.setN(m_parent->GetVertexConstantLayout().floatCount); + m_captures.vsConsts.iConsts.setN(m_parent->GetVertexConstantLayout().intCount); + m_captures.vsConsts.bConsts.setN(m_parent->GetVertexConstantLayout().boolCount); } diff --git a/src/util/util_bit.h b/src/util/util_bit.h index 9490d7353..aabc2649b 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -320,6 +320,17 @@ namespace dxvk::bit { return get(idx); } + constexpr void setN(uint32_t bits) { + uint32_t fullDwords = bits / 32; + uint32_t offset = bits % 32; + + for (size_t i = 0; i < fullDwords; i++) + m_dwords[i] = std::numeric_limits::max(); + + if (offset > 0) + m_dwords[fullDwords] = (1u << offset) - 1; + } + private: uint32_t m_dwords[Dwords]; From 0b9f785bc585b94ca25002af208859bdb05ffbe5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 1 Nov 2022 12:45:54 +0100 Subject: [PATCH 0931/1348] [dxvk] Remove broken memory budget logic for UMA systems All heaps on an UMA systems are by definition device-local, so this just leads to unnecessary issues. --- src/dxvk/dxvk_memory.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index af4760b5e..52f58aefc 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -187,12 +187,6 @@ namespace dxvk { m_memHeaps[i].properties = m_memProps.memoryHeaps[i]; m_memHeaps[i].stats = DxvkMemoryStats { 0, 0 }; m_memHeaps[i].budget = 0; - - /* Target 80% of a heap on systems where we want - * to avoid oversubscribing memory heaps */ - if ((m_memProps.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) - && (m_device->isUnifiedMemoryArchitecture())) - m_memHeaps[i].budget = (8 * m_memProps.memoryHeaps[i].size) / 10; } for (uint32_t i = 0; i < m_memProps.memoryTypeCount; i++) { From 892f676605e23455df2231b2315edf8c7fbe9648 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Wed, 2 Nov 2022 13:32:28 +0100 Subject: [PATCH 0932/1348] [util] Disable direct buffer mapping for Dragon Age Origins --- src/util/config/config.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index fad24021e..ec4529fd0 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -634,6 +634,13 @@ namespace dxvk { { R"(\\(hammer(plusplus)?|mallet|wc)\.exe$)", {{ { "d3d9.apitraceMode", "True" }, }} }, + /* Dragon Age Origins * + * Keeps unmapping the same 3 1MB buffers * + * thousands of times when you alt-tab out * + * Causing it to crash OOM */ + { R"(\\DAOrigins\.exe$)" , {{ + { "d3d9.allowDirectBufferMapping", "False" }, + }} }, }}; From e1eec9b3593d83103c98b4fc2a104e51d0a95168 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sat, 5 Nov 2022 00:14:24 +0100 Subject: [PATCH 0933/1348] [util] Set Fallout 3 to Nvidia vendor id --- src/util/config/config.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index ec4529fd0..ae474541d 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -641,6 +641,10 @@ namespace dxvk { { R"(\\DAOrigins\.exe$)" , {{ { "d3d9.allowDirectBufferMapping", "False" }, }} }, + /* Fallout 3 - Doesn't like Intel Id */ + { R"(\\Fallout3\.exe$)", {{ + { "d3d9.customVendorId", "10de" }, + }} } }}; From 40a4908a2a72409d0176c2ea519d4132f8291833 Mon Sep 17 00:00:00 2001 From: Vlad Date: Fri, 4 Nov 2022 17:31:06 +0300 Subject: [PATCH 0934/1348] Support for MW:R H1-Mod --- src/util/config/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index ae474541d..11b57a7aa 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -128,7 +128,7 @@ namespace dxvk { { "dxgi.customVendorId", "10de" }, }} }, /* Modern Warfare Remastered */ - { R"(\\h1_[ms]p64_ship\.exe$)", {{ + { R"(\\h1(_[ms]p64_ship|-mod)\.exe$)", {{ { "dxgi.customVendorId", "10de" }, }} }, /* Crysis 3 - slower if it notices AMD card * From 4fb7acc64e29b7e82436817ac04d8f02a09ea255 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sat, 5 Nov 2022 17:57:57 +0100 Subject: [PATCH 0935/1348] [d3d9] Implement converter for W11V11U10 --- src/d3d9/d3d9_format.cpp | 10 +++++ src/d3d9/d3d9_format.h | 2 + src/d3d9/d3d9_format_helpers.cpp | 6 +++ src/d3d9/meson.build | 1 + src/d3d9/shaders/d3d9_convert_w11v11u10.comp | 43 ++++++++++++++++++++ 5 files changed, 62 insertions(+) create mode 100644 src/d3d9/shaders/d3d9_convert_w11v11u10.comp diff --git a/src/d3d9/d3d9_format.cpp b/src/d3d9/d3d9_format.cpp index 90ebfd93e..4fe96bb45 100644 --- a/src/d3d9/d3d9_format.cpp +++ b/src/d3d9/d3d9_format.cpp @@ -168,6 +168,16 @@ namespace dxvk { // Convert -> float (this is a mixed snorm and unorm type) VK_FORMAT_R16G16B16A16_SFLOAT } }; + case D3D9Format::W11V11U10: return { + VK_FORMAT_B10G11R11_UFLOAT_PACK32, + VK_FORMAT_UNDEFINED, + VK_IMAGE_ASPECT_COLOR_BIT, + { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, + VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }, + { D3D9ConversionFormat_W11V11U10, 1u, + // can't use B10G11R11 bc this is a snorm type + VK_FORMAT_R16G16B16A16_SNORM } }; + case D3D9Format::UYVY: return { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_UNDEFINED, diff --git a/src/d3d9/d3d9_format.h b/src/d3d9/d3d9_format.h index 23acd1f51..b09b9d469 100644 --- a/src/d3d9/d3d9_format.h +++ b/src/d3d9/d3d9_format.h @@ -40,6 +40,7 @@ namespace dxvk { X8L8V8U8 = 62, Q8W8V8U8 = 63, V16U16 = 64, + W11V11U10 = 65, A2W10V10U10 = 67, UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'), R8G8_B8G8 = MAKEFOURCC('R', 'G', 'B', 'G'), @@ -134,6 +135,7 @@ namespace dxvk { D3D9ConversionFormat_L6V5U5, D3D9ConversionFormat_X8L8V8U8, D3D9ConversionFormat_A2W10V10U10, + D3D9ConversionFormat_W11V11U10, D3D9ConversionFormat_NV12, D3D9ConversionFormat_YV12, D3D9ConversionFormat_Count diff --git a/src/d3d9/d3d9_format_helpers.cpp b/src/d3d9/d3d9_format_helpers.cpp index 7d37bb598..f12592dac 100644 --- a/src/d3d9/d3d9_format_helpers.cpp +++ b/src/d3d9/d3d9_format_helpers.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -57,6 +58,10 @@ namespace dxvk { ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcSlice, VK_FORMAT_R32_UINT, 0, { 1u, 1u }); break; + case D3D9ConversionFormat_W11V11U10: + ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcSlice, VK_FORMAT_R32_UINT, 0, { 1u, 1u }); + break; + default: Logger::warn("Unimplemented format conversion"); } @@ -113,6 +118,7 @@ namespace dxvk { m_shaders[D3D9ConversionFormat_L6V5U5] = InitShader(d3d9_convert_l6v5u5); m_shaders[D3D9ConversionFormat_X8L8V8U8] = InitShader(d3d9_convert_x8l8v8u8); m_shaders[D3D9ConversionFormat_A2W10V10U10] = InitShader(d3d9_convert_a2w10v10u10); + m_shaders[D3D9ConversionFormat_W11V11U10] = InitShader(d3d9_convert_w11v11u10); m_shaders[D3D9ConversionFormat_NV12] = InitShader(d3d9_convert_nv12); m_shaders[D3D9ConversionFormat_YV12] = InitShader(d3d9_convert_yv12); } diff --git a/src/d3d9/meson.build b/src/d3d9/meson.build index 3d121e2cc..9e27c6e83 100644 --- a/src/d3d9/meson.build +++ b/src/d3d9/meson.build @@ -5,6 +5,7 @@ d3d9_shaders = files([ 'shaders/d3d9_convert_l6v5u5.comp', 'shaders/d3d9_convert_x8l8v8u8.comp', 'shaders/d3d9_convert_a2w10v10u10.comp', + 'shaders/d3d9_convert_w11v11u10.comp', 'shaders/d3d9_convert_nv12.comp', 'shaders/d3d9_convert_yv12.comp' ]) diff --git a/src/d3d9/shaders/d3d9_convert_w11v11u10.comp b/src/d3d9/shaders/d3d9_convert_w11v11u10.comp new file mode 100644 index 000000000..4c822546b --- /dev/null +++ b/src/d3d9/shaders/d3d9_convert_w11v11u10.comp @@ -0,0 +1,43 @@ +#version 450 +#extension GL_GOOGLE_include_directive : enable + +#include "d3d9_convert_common.h" + +layout( + local_size_x = 8, + local_size_y = 8, + local_size_z = 1) in; + +layout(binding = 0) +writeonly uniform image2D dst; + +layout(binding = 1) uniform usamplerBuffer src; + +layout(push_constant) +uniform u_info_t { + uvec2 extent; +} u_info; + +void main() { + ivec3 thread_id = ivec3(gl_GlobalInvocationID); + + if (all(lessThan(thread_id.xy, u_info.extent))) { + uint offset = thread_id.x + + thread_id.y * u_info.extent.x; + + uint value = texelFetch(src, int(offset)).r; + + // Sign-extend magic! + int u10 = bitfieldExtract(int (value), 0, 10); + int v11 = bitfieldExtract(int (value), 10, 11); + int w11 = bitfieldExtract(int (value), 21, 11); + + vec4 color = vec4( + snormalize(u10, 10), + snormalize(v11, 10), + snormalize(w11, 10), + 1.0); + + imageStore(dst, thread_id.xy, color); + } +} From 145c1ce127fdcae160f3a64a979fe39402f3e328 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sun, 6 Nov 2022 10:08:53 +0100 Subject: [PATCH 0936/1348] [util] Limit fps to 60 for some WayForward games --- src/util/config/config.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 11b57a7aa..86a8b5076 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -299,6 +299,16 @@ namespace dxvk { { R"(\\MgsGroundZeroes\.exe$)", {{ { "dxgi.maxDeviceMemory", "4095" }, }} }, + /* Shantae and the Pirate's Curse * + * Game speeds up above 60 fps */ + { R"(\\ShantaeCurse\.exe$)", {{ + { "dxgi.maxFrameRate", "60" }, + }} }, + /* Mighty Switch Force! Collection * + * Games speed up above 60 fps */ + { R"(\\MSFC\.exe$)", {{ + { "dxgi.maxFrameRate", "60" }, + }} }, /**********************************************/ /* D3D9 GAMES */ From d8933ca175aac5598cc6abf3ea5384553c5f01b4 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Thu, 18 Aug 2022 19:20:06 +0200 Subject: [PATCH 0937/1348] [d3d9] Only do one allocation for all texture subresources --- src/d3d9/d3d9_common_texture.cpp | 61 +++++----- src/d3d9/d3d9_common_texture.h | 67 ++++------- src/d3d9/d3d9_device.cpp | 185 +++++++++++++++---------------- src/d3d9/d3d9_initializer.cpp | 60 +++++----- src/d3d9/d3d9_swapchain.cpp | 19 ++-- 5 files changed, 181 insertions(+), 211 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index 22646aea1..dab0cf54e 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -78,10 +78,16 @@ namespace dxvk { } } + for (uint32_t i = 0; i < CountSubresources(); i++) { + m_memoryOffset[i] = m_totalSize; + m_totalSize += GetMipSize(i); + } + + // Initialization is handled by D3D9Initializer if (m_mapMode == D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE) - AllocData(); + m_data = m_device->GetAllocator()->Alloc(m_totalSize); else if (m_mapMode != D3D9_COMMON_TEXTURE_MAP_MODE_NONE && m_desc.Pool != D3DPOOL_DEFAULT) - CreateBuffers(); + CreateBuffer(false); m_exposedMipLevels = m_desc.MipLevels; @@ -174,22 +180,24 @@ namespace dxvk { return D3D_OK; } - void* D3D9CommonTexture::GetData(UINT Subresource) { - if (unlikely(m_mappedSlices[Subresource].mapPtr != nullptr || m_mapMode != D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE)) - return m_mappedSlices[Subresource].mapPtr; - D3D9Memory& memory = m_data[Subresource]; - memory.Map(); - return memory.Ptr(); + void* D3D9CommonTexture::GetData(UINT Subresource) { + if (unlikely(m_buffer != nullptr)) + return m_buffer->mapPtr(m_memoryOffset[Subresource]); + + m_data.Map(); + uint8_t* ptr = reinterpret_cast(m_data.Ptr()); + ptr += m_memoryOffset[Subresource]; + return ptr; } - void D3D9CommonTexture::CreateBufferSubresource(UINT Subresource, bool Initialize) { - if (likely(m_buffers[Subresource] != nullptr)) { + + void D3D9CommonTexture::CreateBuffer(bool Initialize) { + if (likely(m_buffer != nullptr)) return; - } DxvkBufferCreateInfo info; - info.size = GetMipSize(Subresource); + info.size = m_totalSize; info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; @@ -209,18 +217,17 @@ namespace dxvk { | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; - m_buffers[Subresource] = m_device->GetDXVKDevice()->createBuffer(info, memType); - m_mappedSlices[Subresource] = m_buffers[Subresource]->getSliceHandle(); + m_buffer = m_device->GetDXVKDevice()->createBuffer(info, memType); if (Initialize) { - if (m_data[Subresource]) { - m_data[Subresource].Map(); - memcpy(m_mappedSlices[Subresource].mapPtr, m_data[Subresource].Ptr(), info.size); + if (m_data) { + m_data.Map(); + std::memcpy(m_buffer->mapPtr(0), m_data.Ptr(), m_totalSize); } else { - memset(m_mappedSlices[Subresource].mapPtr, 0, info.size); + std::memset(m_buffer->mapPtr(0), 0, m_totalSize); } } - m_data[Subresource] = {}; + m_data = {}; } @@ -233,7 +240,7 @@ namespace dxvk { const VkExtent3D mipExtent = util::computeMipLevelExtent( GetExtent(), MipLevel); - + const VkExtent3D blockCount = util::computeBlockCount( mipExtent, formatInfo->blockSize); @@ -661,16 +668,14 @@ namespace dxvk { m_sampleView.Srgb = CreateView(AllLayers, Lod, VK_IMAGE_USAGE_SAMPLED_BIT, true); } - void D3D9CommonTexture::AllocData() { - // D3D9Initializer will handle clearing the data - const uint32_t count = CountSubresources(); - for (uint32_t i = 0; i < count; i++) { - m_data[i] = m_device->GetAllocator()->Alloc(GetMipSize(i)); - } + + const Rc& D3D9CommonTexture::GetBuffer() { + return m_buffer; } - const Rc& D3D9CommonTexture::GetBuffer(UINT Subresource) { - return m_buffers[Subresource]; + + DxvkBufferSlice D3D9CommonTexture::GetBufferSlice(UINT Subresource) { + return DxvkBufferSlice(GetBuffer(), m_memoryOffset[Subresource], GetMipSize(Subresource)); } } diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index fea9263c5..fcd9f2a00 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -155,19 +155,9 @@ namespace dxvk { */ void* GetData(UINT Subresource); - const Rc& GetBuffer(UINT Subresource); + const Rc& GetBuffer(); - - DxvkBufferSliceHandle GetMappedSlice(UINT Subresource) { - return m_mappedSlices[Subresource]; - } - - - DxvkBufferSliceHandle DiscardMapSlice(UINT Subresource) { - DxvkBufferSliceHandle handle = m_buffers[Subresource]->allocSlice(); - m_mappedSlices[Subresource] = handle; - return handle; - } + DxvkBufferSlice GetBufferSlice(UINT Subresource); /** * \brief Computes subresource from the subresource index @@ -235,24 +225,17 @@ namespace dxvk { return Face * m_desc.MipLevels + MipLevel; } - void UnmapData(UINT Subresource) { - m_data[Subresource].Unmap(); - } - void UnmapData() { - const uint32_t subresources = CountSubresources(); - for (uint32_t i = 0; i < subresources; i++) { - m_data[i].Unmap(); - } + m_data.Unmap(); } /** * \brief Destroys a buffer * Destroys mapping and staging buffers for a given subresource */ - void DestroyBufferSubresource(UINT Subresource) { - m_buffers[Subresource] = nullptr; - SetNeedsReadback(Subresource, true); + void DestroyBuffer() { + m_buffer = nullptr; + MarkAllNeedReadback(); } bool IsDynamic() const { @@ -476,13 +459,17 @@ namespace dxvk { */ VkDeviceSize GetMipSize(UINT Subresource) const; + uint32_t GetTotalSize() const { + return m_totalSize; + } + /** * \brief Creates a buffer - * Creates mapping and staging buffers for a given subresource - * allocates new buffers if necessary + * Creates the mapping buffer if necessary + * \param [in] Initialize Whether to copy over existing data (or clear if there is no data) * \returns Whether an allocation happened */ - void CreateBufferSubresource(UINT Subresource, bool Initialize); + void CreateBuffer(bool Initialize); ID3D9VkInteropTexture* GetVkInterop() { return &m_d3d9Interop; } @@ -495,15 +482,17 @@ namespace dxvk { Rc m_image; Rc m_resolveImage; - D3D9SubresourceArray< - Rc> m_buffers; - D3D9SubresourceArray< - DxvkBufferSliceHandle> m_mappedSlices = { }; - D3D9SubresourceArray< - D3D9Memory> m_data = { }; + Rc m_buffer; + D3D9Memory m_data = { }; + D3D9SubresourceArray< uint64_t> m_seqs = { }; + D3D9SubresourceArray< + uint32_t> m_memoryOffset = { }; + + uint32_t m_totalSize = 0; + D3D9_VK_FORMAT_MAPPING m_mapping; bool m_shadow; //< Depth Compare-ness @@ -561,20 +550,6 @@ namespace dxvk { D3DRESOURCETYPE Dimension, UINT Layer); - /** - * \brief Creates buffers - * Creates mapping and staging buffers for all subresources - * allocates new buffers if necessary - */ - void CreateBuffers() { - // D3D9Initializer will handle clearing the buffers - const uint32_t count = CountSubresources(); - for (uint32_t i = 0; i < count; i++) - CreateBufferSubresource(i, false); - } - - void AllocData(); - static constexpr UINT AllLayers = UINT32_MAX; }; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index c10ab0766..a89cc4631 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -911,11 +911,14 @@ namespace dxvk { VkExtent3D dstTexExtent = dstTexInfo->GetExtentMip(dst->GetMipLevel()); VkExtent3D srcTexExtent = srcTexInfo->GetExtentMip(src->GetMipLevel()); - dstTexInfo->CreateBufferSubresource(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height); - Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource()); + const bool clearDst = dstTexInfo->Desc()->MipLevels > 1 + || dstTexExtent.width > srcTexExtent.width + || dstTexExtent.height > srcTexExtent.height; - Rc srcImage = srcTexInfo->GetImage(); - const DxvkFormatInfo* srcFormatInfo = lookupFormatInfo(srcImage->info().format); + dstTexInfo->CreateBuffer(clearDst); + DxvkBufferSlice dstBufferSlice = dstTexInfo->GetBufferSlice(dst->GetSubresource()); + Rc srcImage = srcTexInfo->GetImage(); + const DxvkFormatInfo* srcFormatInfo = lookupFormatInfo(srcImage->info().format); const VkImageSubresource srcSubresource = srcTexInfo->GetSubresourceFromIndex(srcFormatInfo->aspectMask, src->GetSubresource()); VkImageSubresourceLayers srcSubresourceLayers = { @@ -924,12 +927,12 @@ namespace dxvk { srcSubresource.arrayLayer, 1 }; EmitCs([ - cBuffer = dstBuffer, + cBufferSlice = std::move(dstBufferSlice), cImage = srcImage, cSubresources = srcSubresourceLayers, cLevelExtent = srcTexExtent ] (DxvkContext* ctx) { - ctx->copyImageToBuffer(cBuffer, 0, 4, 0, + ctx->copyImageToBuffer(cBufferSlice.buffer(), cBufferSlice.offset(), 4, 0, cImage, cSubresources, VkOffset3D { 0, 0, 0 }, cLevelExtent); }); @@ -4298,107 +4301,94 @@ namespace dxvk { bool needsReadback = pResource->NeedsReadback(Subresource) || renderable; pResource->SetNeedsReadback(Subresource, false); + if (unlikely(pResource->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED || needsReadback)) { // Create mapping buffer if it doesn't exist yet. (POOL_DEFAULT) - pResource->CreateBufferSubresource(Subresource, !needsReadback); + pResource->CreateBuffer(!needsReadback); } - void* mapPtr; + // Don't use MapTexture here to keep the mapped list small while the resource is still locked. + void* mapPtr = pResource->GetData(Subresource); - if ((Flags & D3DLOCK_DISCARD) && needsReadback) { - // We do not have to preserve the contents of the - // buffer if the entire image gets discarded. - const Rc mappedBuffer = pResource->GetBuffer(Subresource); - DxvkBufferSliceHandle physSlice = pResource->DiscardMapSlice(Subresource); - mapPtr = physSlice.mapPtr; + if (needsReadback) { + DxvkBufferSlice mappedBufferSlice = pResource->GetBufferSlice(Subresource); + const Rc mappedBuffer = pResource->GetBuffer(); - EmitCs([ - cImageBuffer = std::move(mappedBuffer), - cBufferSlice = physSlice - ] (DxvkContext* ctx) { - ctx->invalidateBuffer(cImageBuffer, cBufferSlice); - }); - } else { - // Don't use MapTexture here to keep the mapped list small while the resource is still locked. - mapPtr = pResource->GetData(Subresource); + if (unlikely(needsReadback) && pResource->GetImage() != nullptr) { + Rc resourceImage = pResource->GetImage(); - if (needsReadback) { - const Rc mappedBuffer = pResource->GetBuffer(Subresource); - if (unlikely(needsReadback) && pResource->GetImage() != nullptr) { - Rc resourceImage = pResource->GetImage(); + Rc mappedImage = resourceImage->info().sampleCount != 1 + ? pResource->GetResolveImage() + : std::move(resourceImage); - Rc mappedImage = resourceImage->info().sampleCount != 1 - ? pResource->GetResolveImage() - : std::move(resourceImage); - - // When using any map mode which requires the image contents - // to be preserved, and if the GPU has write access to the - // image, copy the current image contents into the buffer. - auto subresourceLayers = vk::makeSubresourceLayers(subresource); - - // We need to resolve this, some games - // lock MSAA render targets even though - // that's entirely illegal and they explicitly - // tell us that they do NOT want to lock them... - if (resourceImage != nullptr) { - EmitCs([ - cMainImage = resourceImage, - cResolveImage = mappedImage, - cSubresource = subresourceLayers - ] (DxvkContext* ctx) { - VkImageResolve region; - region.srcSubresource = cSubresource; - region.srcOffset = VkOffset3D { 0, 0, 0 }; - region.dstSubresource = cSubresource; - region.dstOffset = VkOffset3D { 0, 0, 0 }; - region.extent = cMainImage->mipLevelExtent(cSubresource.mipLevel); - - if (cSubresource.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { - ctx->resolveImage( - cResolveImage, cMainImage, region, - cMainImage->info().format); - } - else { - ctx->resolveDepthStencilImage( - cResolveImage, cMainImage, region, - VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, - VK_RESOLVE_MODE_SAMPLE_ZERO_BIT); - } - }); - } - - VkFormat packedFormat = GetPackedDepthStencilFormat(desc.Format); + // When using any map mode which requires the image contents + // to be preserved, and if the GPU has write access to the + // image, copy the current image contents into the buffer. + auto subresourceLayers = vk::makeSubresourceLayers(subresource); + // We need to resolve this, some games + // lock MSAA render targets even though + // that's entirely illegal and they explicitly + // tell us that they do NOT want to lock them... + if (resourceImage != nullptr) { EmitCs([ - cImageBuffer = mappedBuffer, - cImage = std::move(mappedImage), - cSubresources = subresourceLayers, - cLevelExtent = levelExtent, - cPackedFormat = packedFormat + cMainImage = resourceImage, + cResolveImage = mappedImage, + cSubresource = subresourceLayers ] (DxvkContext* ctx) { - if (cSubresources.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { - ctx->copyImageToBuffer(cImageBuffer, 0, 4, 0, - cImage, cSubresources, VkOffset3D { 0, 0, 0 }, - cLevelExtent); - } else { - // Copying DS to a packed buffer is only supported for D24S8 and D32S8 - // right now so the 4 byte row alignment is guaranteed by the format size - ctx->copyDepthStencilImageToPackedBuffer( - cImageBuffer, 0, - VkOffset2D { 0, 0 }, - VkExtent2D { cLevelExtent.width, cLevelExtent.height }, - cImage, cSubresources, - VkOffset2D { 0, 0 }, - VkExtent2D { cLevelExtent.width, cLevelExtent.height }, - cPackedFormat); + VkImageResolve region; + region.srcSubresource = cSubresource; + region.srcOffset = VkOffset3D { 0, 0, 0 }; + region.dstSubresource = cSubresource; + region.dstOffset = VkOffset3D { 0, 0, 0 }; + region.extent = cMainImage->mipLevelExtent(cSubresource.mipLevel); + + if (cSubresource.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + ctx->resolveImage( + cResolveImage, cMainImage, region, + cMainImage->info().format); + } + else { + ctx->resolveDepthStencilImage( + cResolveImage, cMainImage, region, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT); } }); - TrackTextureMappingBufferSequenceNumber(pResource, Subresource); } - if (!WaitForResource(mappedBuffer, pResource->GetMappingBufferSequenceNumber(Subresource), Flags)) - return D3DERR_WASSTILLDRAWING; + VkFormat packedFormat = GetPackedDepthStencilFormat(desc.Format); + + EmitCs([ + cImageBufferSlice = std::move(mappedBufferSlice), + cImage = std::move(mappedImage), + cSubresources = subresourceLayers, + cLevelExtent = levelExtent, + cPackedFormat = packedFormat + ] (DxvkContext* ctx) { + if (cSubresources.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + ctx->copyImageToBuffer(cImageBufferSlice.buffer(), + cImageBufferSlice.offset(), 4, 0, cImage, + cSubresources, VkOffset3D { 0, 0, 0 }, + cLevelExtent); + } else { + // Copying DS to a packed buffer is only supported for D24S8 and D32S8 + // right now so the 4 byte row alignment is guaranteed by the format size + ctx->copyDepthStencilImageToPackedBuffer( + cImageBufferSlice.buffer(), cImageBufferSlice.offset(), + VkOffset2D { 0, 0 }, + VkExtent2D { cLevelExtent.width, cLevelExtent.height }, + cImage, cSubresources, + VkOffset2D { 0, 0 }, + VkExtent2D { cLevelExtent.width, cLevelExtent.height }, + cPackedFormat); + } + }); + TrackTextureMappingBufferSequenceNumber(pResource, Subresource); } + + if (!WaitForResource(mappedBuffer, pResource->GetMappingBufferSequenceNumber(Subresource), Flags)) + return D3DERR_WASSTILLDRAWING; } const bool atiHack = desc.Format == D3D9Format::ATI1 || desc.Format == D3D9Format::ATI2; @@ -4496,11 +4486,10 @@ namespace dxvk { bool shouldToss = pResource->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_BACKED; shouldToss &= !pResource->IsDynamic(); shouldToss &= !pResource->IsManaged(); + shouldToss &= !pResource->IsAnySubresourceLocked(); - if (shouldToss) { - pResource->DestroyBufferSubresource(Subresource); - pResource->SetNeedsReadback(Subresource, true); - } + if (shouldToss) + pResource->DestroyBuffer(); UnmapTextures(); return D3D_OK; @@ -4561,8 +4550,10 @@ namespace dxvk { auto convertFormat = pDestTexture->GetFormatMapping().ConversionFormatInfo; if (unlikely(pSrcTexture->NeedsReadback(SrcSubresource))) { - pSrcTexture->CreateBufferSubresource(SrcSubresource, true); - const Rc& buffer = pSrcTexture->GetBuffer(SrcSubresource); + // The src texutre has to be in POOL_SYSTEMEM, so it cannot use AUTOMIPGEN. + // That means that NeedsReadback is only true if the texture has been used with GetRTData or GetFrontbufferData before. + // Those functions create a buffer, so the buffer always exists here. + const Rc& buffer = pSrcTexture->GetBuffer(); WaitForResource(buffer, pSrcTexture->GetMappingBufferSequenceNumber(SrcSubresource), 0); pSrcTexture->SetNeedsReadback(SrcSubresource, false); } diff --git a/src/d3d9/d3d9_initializer.cpp b/src/d3d9/d3d9_initializer.cpp index d9a2eceac..a44674f92 100644 --- a/src/d3d9/d3d9_initializer.cpp +++ b/src/d3d9/d3d9_initializer.cpp @@ -113,41 +113,35 @@ namespace dxvk { // If the buffer is mapped, we can write data directly // to the mapped memory region instead of doing it on // the GPU. Same goes for zero-initialization. - const D3D9_COMMON_TEXTURE_DESC* desc = pTexture->Desc(); - for (uint32_t a = 0; a < desc->ArraySize; a++) { - for (uint32_t m = 0; m < desc->MipLevels; m++) { - uint32_t subresource = pTexture->CalcSubresource(a, m); - void* mapPtr = pTexture->GetData(subresource); - uint32_t length = pTexture->GetMipSize(subresource); + void* mapPtr = pTexture->GetData(0); + if (pInitialData) { + // Initial data is only supported for textures with 1 subresource + VkExtent3D mipExtent = pTexture->GetExtentMip(0); + const DxvkFormatInfo* formatInfo = lookupFormatInfo(pTexture->GetFormatMapping().FormatColor); + VkExtent3D blockCount = util::computeBlockCount(mipExtent, formatInfo->blockSize); + uint32_t pitch = blockCount.width * formatInfo->elementSize; + uint32_t alignedPitch = align(pitch, 4); - if (pInitialData != nullptr) { - VkExtent3D mipExtent = pTexture->GetExtentMip(m); - const DxvkFormatInfo* formatInfo = lookupFormatInfo(pTexture->GetFormatMapping().FormatColor); - VkExtent3D blockCount = util::computeBlockCount(mipExtent, formatInfo->blockSize); - uint32_t pitch = blockCount.width * formatInfo->elementSize; - uint32_t alignedPitch = align(pitch, 4); - - util::packImageData( - mapPtr, - pInitialData, - pitch, - pitch * blockCount.height, - alignedPitch, - alignedPitch * blockCount.height, - D3D9CommonTexture::GetImageTypeFromResourceType(pTexture->GetType()), - mipExtent, - pTexture->Desc()->ArraySize, - formatInfo, - VK_IMAGE_ASPECT_COLOR_BIT); - } else { - std::memset( - mapPtr, 0, - length); - } - } + util::packImageData( + mapPtr, + pInitialData, + pitch, + pitch * blockCount.height, + alignedPitch, + alignedPitch * blockCount.height, + D3D9CommonTexture::GetImageTypeFromResourceType(pTexture->GetType()), + mipExtent, + pTexture->Desc()->ArraySize, + formatInfo, + VK_IMAGE_ASPECT_COLOR_BIT); + } else { + // All subresources are allocated in one chunk of memory. + // So we can just get the pointer for subresource 0 and memset all of them at once. + std::memset( + mapPtr, 0, + pTexture->GetTotalSize()); } - if (pTexture->GetMapMode() == D3D9_COMMON_TEXTURE_MAP_MODE_UNMAPPABLE) - pTexture->UnmapData(); + pTexture->UnmapData(); } diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 8e078cf40..59b64073b 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -180,9 +180,13 @@ namespace dxvk { VkExtent3D dstTexExtent = dstTexInfo->GetExtentMip(dst->GetMipLevel()); VkExtent3D srcTexExtent = srcTexInfo->GetExtentMip(0); - dstTexInfo->CreateBufferSubresource(dst->GetSubresource(), dstTexExtent.width > srcTexExtent.width || dstTexExtent.height > srcTexExtent.height); - Rc dstBuffer = dstTexInfo->GetBuffer(dst->GetSubresource()); - Rc srcImage = srcTexInfo->GetImage(); + const bool clearDst = dstTexInfo->Desc()->MipLevels > 1 + || dstTexExtent.width > srcTexExtent.width + || dstTexExtent.height > srcTexExtent.height; + + dstTexInfo->CreateBuffer(clearDst); + DxvkBufferSlice dstBufferSlice = dstTexInfo->GetBufferSlice(dst->GetSubresource()); + Rc srcImage = srcTexInfo->GetImage(); if (srcImage->info().sampleCount != VK_SAMPLE_COUNT_1_BIT) { DxvkImageCreateInfo resolveInfo; @@ -316,13 +320,14 @@ namespace dxvk { VkExtent3D srcExtent = srcImage->mipLevelExtent(srcSubresource.mipLevel); m_parent->EmitCs([ - cBuffer = dstBuffer, - cImage = srcImage, + cBufferSlice = std::move(dstBufferSlice), + cImage = std::move(srcImage), cSubresources = srcSubresourceLayers, cLevelExtent = srcExtent ] (DxvkContext* ctx) { - ctx->copyImageToBuffer(cBuffer, 0, 4, 0, - cImage, cSubresources, VkOffset3D { 0, 0, 0 }, + ctx->copyImageToBuffer(cBufferSlice.buffer(), + cBufferSlice.offset(), 4, 0, cImage, + cSubresources, VkOffset3D { 0, 0, 0 }, cLevelExtent); }); From bd87e19de1c702bb51af8fe96818773836e8b183 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 27 Oct 2022 18:59:25 +0200 Subject: [PATCH 0938/1348] [dxgi] Introduce IDXGIVkSurfaceFactory --- src/dxgi/dxgi_interfaces.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index f555e3cbd..989fb064b 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -41,6 +41,18 @@ struct DXGI_VK_HDR_METADATA { }; +/** + * \brief Private DXGI surface factory + */ +MIDL_INTERFACE("1e7895a1-1bc3-4f9c-a670-290a4bc9581a") +IDXGIVkSurfaceFactory : public IUnknown { + virtual VkResult STDMETHODCALLTYPE CreateSurface( + VkInstance Instance, + VkPhysicalDevice Adapter, + VkSurfaceKHR* pSurface) = 0; +}; + + /** * \brief Private DXGI presenter * @@ -396,6 +408,7 @@ struct __declspec(uuid("3a6d8f2c-b0e8-4ab4-b4dc-4fd24891bfa5")) IDXGIVkInteropAd struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09323")) IDXGIVkInteropDevice; struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09324")) IDXGIVkInteropDevice1; struct __declspec(uuid("5546cf8c-77e7-4341-b05d-8d4d5000e77d")) IDXGIVkInteropSurface; +struct __declspec(uuid("1e7895a1-1bc3-4f9c-a670-290a4bc9581a")) IDXGIVkSurfaceFactory; struct __declspec(uuid("e4a9059e-b569-46ab-8de7-501bd2bc7f7a")) IDXGIVkSwapChain; struct __declspec(uuid("e7d6c3ca-23a0-4e08-9f2f-ea5231df6633")) IDXGIVkSwapChainFactory; struct __declspec(uuid("53cb4ff0-c25a-4164-a891-0e83db0a7aac")) IWineDXGISwapChainFactory; @@ -407,6 +420,7 @@ __CRT_UUID_DECL(IDXGIVkInteropAdapter, 0x3a6d8f2c,0xb0e8,0x4ab4,0xb4,0xdc,0x __CRT_UUID_DECL(IDXGIVkInteropDevice, 0xe2ef5fa5,0xdc21,0x4af7,0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x23); __CRT_UUID_DECL(IDXGIVkInteropDevice1, 0xe2ef5fa5,0xdc21,0x4af7,0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x24); __CRT_UUID_DECL(IDXGIVkInteropSurface, 0x5546cf8c,0x77e7,0x4341,0xb0,0x5d,0x8d,0x4d,0x50,0x00,0xe7,0x7d); +__CRT_UUID_DECL(IDXGIVkSurfaceFactory, 0x1e7895a1,0x1bc3,0x4f9c,0xa6,0x70,0x29,0x0a,0x4b,0xc9,0x58,0x1a); __CRT_UUID_DECL(IDXGIVkSwapChain, 0xe4a9059e,0xb569,0x46ab,0x8d,0xe7,0x50,0x1b,0xd2,0xbc,0x7f,0x7a); __CRT_UUID_DECL(IDXGIVkSwapChainFactory, 0xe7d6c3ca,0x23a0,0x4e08,0x9f,0x2f,0xea,0x52,0x31,0xdf,0x66,0x33); __CRT_UUID_DECL(IWineDXGISwapChainFactory, 0x53cb4ff0,0xc25a,0x4164,0xa8,0x91,0x0e,0x83,0xdb,0x0a,0x7a,0xac); From 1754b73adefdec70f11fe268cade19465304eef6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 27 Oct 2022 19:36:12 +0200 Subject: [PATCH 0939/1348] [wsi] Change interface for surface creation This temporarily breaks Win32 swap chains, but we're fine with that since this will take some refactoring. --- src/vulkan/vulkan_presenter.cpp | 3 ++- src/wsi/sdl2/wsi_window_sdl2.cpp | 9 +++++---- src/wsi/win32/wsi_window_win32.cpp | 12 +++++++++--- src/wsi/wsi_window.h | 6 ++++-- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index 0938f3ca3..40a5f13de 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -410,7 +410,8 @@ namespace dxvk::vk { VkResult Presenter::createSurface() { - VkResult status = wsi::createSurface(m_window, m_vki, &m_surface); + /* TODO fix */ + VkResult status = wsi::createSurface(m_window, nullptr, m_vki->instance(), &m_surface); if (status != VK_SUCCESS) return status; diff --git a/src/wsi/sdl2/wsi_window_sdl2.cpp b/src/wsi/sdl2/wsi_window_sdl2.cpp index a3b3247bd..1280b6c10 100644 --- a/src/wsi/sdl2/wsi_window_sdl2.cpp +++ b/src/wsi/sdl2/wsi_window_sdl2.cpp @@ -143,12 +143,13 @@ namespace dxvk::wsi { VkResult createSurface( - HWND hWindow, - const Rc& vki, - VkSurfaceKHR* pSurface) { + HWND hWindow, + PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, + VkInstance instance, + VkSurfaceKHR* pSurface) { SDL_Window* window = fromHwnd(hWindow); - return SDL_Vulkan_CreateSurface(window, vki->instance(), pSurface) + return SDL_Vulkan_CreateSurface(window, instance, pSurface) ? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY; } diff --git a/src/wsi/win32/wsi_window_win32.cpp b/src/wsi/win32/wsi_window_win32.cpp index 94a228e35..597d7478f 100644 --- a/src/wsi/win32/wsi_window_win32.cpp +++ b/src/wsi/win32/wsi_window_win32.cpp @@ -276,17 +276,23 @@ namespace dxvk::wsi { VkResult createSurface( HWND hWindow, - const Rc& vki, + PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, + VkInstance instance, VkSurfaceKHR* pSurface) { HINSTANCE hInstance = reinterpret_cast( GetWindowLongPtr(hWindow, GWLP_HINSTANCE)); + auto pfnVkCreateWin32SurfaceKHR = reinterpret_cast( + pfnVkGetInstanceProcAddr(instance, "vkCreateWin32SurfaceKHR")); + + if (!pfnVkCreateWin32SurfaceKHR) + return VK_ERROR_FEATURE_NOT_PRESENT; + VkWin32SurfaceCreateInfoKHR info = { VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR }; info.hinstance = hInstance; info.hwnd = hWindow; - return vki->vkCreateWin32SurfaceKHR( - vki->instance(), &info, nullptr, pSurface); + return (*pfnVkCreateWin32SurfaceKHR)(instance, &info, nullptr, pSurface); } } diff --git a/src/wsi/wsi_window.h b/src/wsi/wsi_window.h index af4b23e51..e0587a0fd 100644 --- a/src/wsi/wsi_window.h +++ b/src/wsi/wsi_window.h @@ -115,12 +115,14 @@ namespace dxvk::wsi { * \brief Create a surface for a window * * \param [in] hWindow The window - * \param [in] vki The instance + * \param [in] pfnVkGetInstanceProcAddr \c vkGetInstanceProcAddr pointer + * \param [in] instance Vulkan instance * \param [out] pSurface The surface */ VkResult createSurface( HWND hWindow, - const Rc& vki, + PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, + VkInstance instance, VkSurfaceKHR* pSurface); } From 3a9e975a7130960942cc3bd1eab4e0b3ff62897d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 27 Oct 2022 19:36:56 +0200 Subject: [PATCH 0940/1348] [dxgi] Implement DxgiSurfaceFactory --- src/d3d11/meson.build | 1 + src/dxgi/dxgi_surface.cpp | 45 +++++++++++++++++++++++++++++++++++++++ src/dxgi/dxgi_surface.h | 43 +++++++++++++++++++++++++++++++++++++ src/dxgi/meson.build | 1 + 4 files changed, 90 insertions(+) create mode 100644 src/dxgi/dxgi_surface.cpp create mode 100644 src/dxgi/dxgi_surface.h diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index f231fcf49..6067f7697 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -3,6 +3,7 @@ d3d11_res = wrc_generator.process('version.rc') dxgi_common_src = [ '../dxgi/dxgi_format.cpp', '../dxgi/dxgi_monitor.cpp', + '../dxgi/dxgi_surface.cpp', '../dxgi/dxgi_swapchain.cpp', ] diff --git a/src/dxgi/dxgi_surface.cpp b/src/dxgi/dxgi_surface.cpp new file mode 100644 index 000000000..d18abd648 --- /dev/null +++ b/src/dxgi/dxgi_surface.cpp @@ -0,0 +1,45 @@ +#include "dxgi_surface.h" + +#include "../wsi/wsi_window.h" + +namespace dxvk { + + DxgiSurfaceFactory::DxgiSurfaceFactory(PFN_vkGetInstanceProcAddr vulkanLoaderProc, HWND hWnd) + : m_vkGetInstanceProcAddr(vulkanLoaderProc), m_window(hWnd) { + + } + + + DxgiSurfaceFactory::~DxgiSurfaceFactory() { + + } + + + HRESULT STDMETHODCALLTYPE DxgiSurfaceFactory::QueryInterface( + REFIID riid, + void** ppvObject) { + if (ppvObject == nullptr) + return E_POINTER; + + *ppvObject = nullptr; + + if (riid == __uuidof(IUnknown) + || riid == __uuidof(IDXGIVkSurfaceFactory)) { + *ppvObject = ref(this); + return S_OK; + } + + Logger::warn("DxgiSurfaceFactory::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + return E_NOINTERFACE; + } + + + VkResult STDMETHODCALLTYPE DxgiSurfaceFactory::CreateSurface( + VkInstance Instance, + VkPhysicalDevice Adapter, + VkSurfaceKHR* pSurface) { + return wsi::createSurface(m_window, m_vkGetInstanceProcAddr, Instance, pSurface); + } + +} \ No newline at end of file diff --git a/src/dxgi/dxgi_surface.h b/src/dxgi/dxgi_surface.h new file mode 100644 index 000000000..25a845fdd --- /dev/null +++ b/src/dxgi/dxgi_surface.h @@ -0,0 +1,43 @@ +#pragma once + +#include "../util/com/com_object.h" + +#include "../vulkan/vulkan_loader.h" + +#include "dxgi_interfaces.h" + +namespace dxvk { + + /** + * \brief Surface factory + * + * Provides a way to transparently create a + * Vulkan surface for a given platform window. + */ + class DxgiSurfaceFactory : public ComObject { + + public: + + DxgiSurfaceFactory( + PFN_vkGetInstanceProcAddr vulkanLoaderProc, + HWND hWnd); + + ~DxgiSurfaceFactory(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + VkResult STDMETHODCALLTYPE CreateSurface( + VkInstance Instance, + VkPhysicalDevice Adapter, + VkSurfaceKHR* pSurface); + + private: + + PFN_vkGetInstanceProcAddr m_vkGetInstanceProcAddr; + HWND m_window; + + }; + +} \ No newline at end of file diff --git a/src/dxgi/meson.build b/src/dxgi/meson.build index f0c1b2e9c..a6e83b54e 100644 --- a/src/dxgi/meson.build +++ b/src/dxgi/meson.build @@ -9,6 +9,7 @@ dxgi_src = [ 'dxgi_monitor.cpp', 'dxgi_options.cpp', 'dxgi_output.cpp', + 'dxgi_surface.cpp', 'dxgi_swapchain.cpp', ] From 49cf0ecf54a0be4aa0cfef519594a1b24d3ea94c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 27 Oct 2022 19:46:45 +0200 Subject: [PATCH 0941/1348] [vulkan] Don't handle SURFACE_LOST in Vulkan presenter --- src/vulkan/vulkan_presenter.cpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index 40a5f13de..c667a815d 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -103,19 +103,8 @@ namespace dxvk::vk { VkResult status; if ((status = m_vki->vkGetPhysicalDeviceSurfaceCapabilitiesKHR( - m_device.adapter, m_surface, &caps)) != VK_SUCCESS) { - if (status == VK_ERROR_SURFACE_LOST_KHR) { - // Recreate the surface and try again. - if (m_surface) - destroySurface(); - if ((status = createSurface()) != VK_SUCCESS) - return status; - status = m_vki->vkGetPhysicalDeviceSurfaceCapabilitiesKHR( - m_device.adapter, m_surface, &caps); - } - if (status != VK_SUCCESS) - return status; - } + m_device.adapter, m_surface, &caps)) != VK_SUCCESS) + return status; if ((status = getSupportedFormats(formats, desc)) != VK_SUCCESS) return status; From 03dca539cbe38426e27498a34cc7d437628788c4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 28 Oct 2022 15:52:43 +0200 Subject: [PATCH 0942/1348] [vulkan,d3d9,d3d11] Move surface creation to swap chain implementation --- src/d3d11/d3d11_device.cpp | 14 ++++++- src/d3d11/d3d11_swapchain.cpp | 51 ++++++++++++++++--------- src/d3d11/d3d11_swapchain.h | 6 ++- src/d3d9/d3d9_swapchain.cpp | 38 ++++++++++++++++--- src/d3d9/d3d9_swapchain.h | 2 + src/vulkan/vulkan_loader.h | 2 + src/vulkan/vulkan_presenter.cpp | 66 ++++++++++++++------------------- src/vulkan/vulkan_presenter.h | 18 +++++++-- 8 files changed, 129 insertions(+), 68 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 6d3580a54..6599a7e40 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2,6 +2,7 @@ #include #include "../dxgi/dxgi_monitor.h" +#include "../dxgi/dxgi_surface.h" #include "../dxgi/dxgi_swapchain.h" #include "../dxvk/dxvk_adapter.h" @@ -3002,8 +3003,12 @@ namespace dxvk { InitReturnPtr(ppSwapChain); try { + auto vki = m_device->GetDXVKDevice()->adapter()->vki(); + + Com surfaceFactory = new DxgiSurfaceFactory(vki->getLoaderProc(), hWnd); + Com presenter = new D3D11SwapChain( - m_container, m_device, hWnd, pDesc); + m_container, m_device, surfaceFactory.ptr(), pDesc); *ppSwapChain = presenter.ref(); return S_OK; @@ -3074,9 +3079,14 @@ namespace dxvk { } try { + auto vki = m_device->GetDXVKDevice()->adapter()->vki(); + + // Create surface factory for the window + Com surfaceFactory = new DxgiSurfaceFactory(vki->getLoaderProc(), hWnd); + // Create presenter for the device Com presenter = new D3D11SwapChain( - m_container, m_device, hWnd, &desc); + m_container, m_device, surfaceFactory.ptr(), &desc); // Create the actual swap chain *ppSwapChain = ref(new DxgiSwapChain( diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 988013d03..a43c6bad2 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -16,23 +16,23 @@ namespace dxvk { D3D11SwapChain::D3D11SwapChain( D3D11DXGIDevice* pContainer, D3D11Device* pDevice, - HWND hWnd, + IDXGIVkSurfaceFactory* pSurfaceFactory, const DXGI_SWAP_CHAIN_DESC1* pDesc) : m_dxgiDevice(pContainer), - m_parent (pDevice), - m_window (hWnd), - m_desc (*pDesc), - m_device (pDevice->GetDXVKDevice()), - m_context (m_device->createContext(DxvkContextType::Supplementary)), + m_parent(pDevice), + m_surfaceFactory(pSurfaceFactory), + m_desc(*pDesc), + m_device(pDevice->GetDXVKDevice()), + m_context(m_device->createContext(DxvkContextType::Supplementary)), m_frameLatencyCap(pDevice->GetOptions()->maxFrameLatency) { CreateFrameLatencyEvent(); - - if (!pDevice->GetOptions()->deferSurfaceCreation) - CreatePresenter(); - + CreatePresenter(); CreateBackBuffer(); CreateBlitter(); CreateHud(); + + if (!pDevice->GetOptions()->deferSurfaceCreation) + RecreateSwapChain(false); } @@ -223,9 +223,6 @@ namespace dxvk { m_vsync = vsync; } - if (m_presenter == nullptr) - CreatePresenter(); - HRESULT hr = S_OK; if (!m_presenter->hasSwapChain()) { @@ -395,8 +392,21 @@ namespace dxvk { presenterDesc.numPresentModes = PickPresentModes(Vsync, presenterDesc.presentModes); presenterDesc.fullScreenExclusive = PickFullscreenMode(); - if (m_presenter->recreateSwapChain(presenterDesc) != VK_SUCCESS) - throw DxvkError("D3D11SwapChain: Failed to recreate swap chain"); + VkResult vr = m_presenter->recreateSwapChain(presenterDesc); + + if (vr == VK_ERROR_SURFACE_LOST_KHR) { + vr = m_presenter->recreateSurface([this] (VkSurfaceKHR* surface) { + return CreateSurface(surface); + }); + + if (vr) + throw DxvkError(str::format("D3D11SwapChain: Failed to recreate surface: ", vr)); + + vr = m_presenter->recreateSwapChain(presenterDesc); + } + + if (vr) + throw DxvkError(str::format("D3D11SwapChain: Failed to recreate swap chain: ", vr)); CreateRenderTargetViews(); } @@ -426,15 +436,22 @@ namespace dxvk { presenterDesc.numPresentModes = PickPresentModes(false, presenterDesc.presentModes); presenterDesc.fullScreenExclusive = PickFullscreenMode(); - m_presenter = new vk::Presenter(m_window, + m_presenter = new vk::Presenter( m_device->adapter()->vki(), m_device->vkd(), presenterDevice, presenterDesc); m_presenter->setFrameRateLimit(m_parent->GetOptions()->maxFrameRate); + } - CreateRenderTargetViews(); + + VkResult D3D11SwapChain::CreateSurface(VkSurfaceKHR* pSurface) { + Rc adapter = m_device->adapter(); + + return m_surfaceFactory->CreateSurface( + adapter->vki()->instance(), + adapter->handle(), pSurface); } diff --git a/src/d3d11/d3d11_swapchain.h b/src/d3d11/d3d11_swapchain.h index a7f535f2d..fdf67da2b 100644 --- a/src/d3d11/d3d11_swapchain.h +++ b/src/d3d11/d3d11_swapchain.h @@ -20,7 +20,7 @@ namespace dxvk { D3D11SwapChain( D3D11DXGIDevice* pContainer, D3D11Device* pDevice, - HWND hWnd, + IDXGIVkSurfaceFactory* pSurfaceFactory, const DXGI_SWAP_CHAIN_DESC1* pDesc); ~D3D11SwapChain(); @@ -90,7 +90,7 @@ namespace dxvk { Com m_dxgiDevice; D3D11Device* m_parent; - HWND m_window; + Com m_surfaceFactory; DXGI_SWAP_CHAIN_DESC1 m_desc; @@ -137,6 +137,8 @@ namespace dxvk { void CreatePresenter(); + VkResult CreateSurface(VkSurfaceKHR* pSurface); + void CreateRenderTargetViews(); void CreateBackBuffer(); diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 59b64073b..807740e74 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -35,9 +35,14 @@ namespace dxvk { m_window = m_presentParams.hDeviceWindow; UpdatePresentRegion(nullptr, nullptr); - if (m_window && !pDevice->GetOptions()->deferSurfaceCreation) + + if (m_window) { CreatePresenter(); + if (!pDevice->GetOptions()->deferSurfaceCreation) + RecreateSwapChain(false); + } + CreateBackBuffers(m_presentParams.BackBufferCount); CreateBlitter(); CreateHud(); @@ -116,7 +121,7 @@ namespace dxvk { bool recreate = false; recreate |= m_presenter == nullptr; - recreate |= window != m_window; + recreate |= window != m_window; recreate |= m_dialog != m_lastDialog; m_window = window; @@ -757,8 +762,21 @@ namespace dxvk { presenterDesc.numPresentModes = PickPresentModes(Vsync, presenterDesc.presentModes); presenterDesc.fullScreenExclusive = PickFullscreenMode(); - if (m_presenter->recreateSwapChain(presenterDesc) != VK_SUCCESS) - throw DxvkError("D3D9SwapChainEx: Failed to recreate swap chain"); + VkResult vr = m_presenter->recreateSwapChain(presenterDesc); + + if (vr == VK_ERROR_SURFACE_LOST_KHR) { + vr = m_presenter->recreateSurface([this] (VkSurfaceKHR* surface) { + return CreateSurface(surface); + }); + + if (vr) + throw DxvkError(str::format("D3D9SwapChainEx: Failed to recreate surface: ", vr)); + + vr = m_presenter->recreateSwapChain(presenterDesc); + } + + if (vr) + throw DxvkError(str::format("D3D9SwapChainEx: Failed to recreate swap chain: ", vr)); CreateRenderTargetViews(); } @@ -785,15 +803,23 @@ namespace dxvk { presenterDesc.numPresentModes = PickPresentModes(false, presenterDesc.presentModes); presenterDesc.fullScreenExclusive = PickFullscreenMode(); - m_presenter = new vk::Presenter(m_window, + m_presenter = new vk::Presenter( m_device->adapter()->vki(), m_device->vkd(), presenterDevice, presenterDesc); m_presenter->setFrameRateLimit(m_parent->GetOptions()->maxFrameRate); + } - CreateRenderTargetViews(); + + VkResult D3D9SwapChainEx::CreateSurface(VkSurfaceKHR* pSurface) { + auto vki = m_device->adapter()->vki(); + + return wsi::createSurface(m_window, + vki->getLoaderProc(), + vki->instance(), + pSurface); } diff --git a/src/d3d9/d3d9_swapchain.h b/src/d3d9/d3d9_swapchain.h index 9eae6a963..2e44a272f 100644 --- a/src/d3d9/d3d9_swapchain.h +++ b/src/d3d9/d3d9_swapchain.h @@ -137,6 +137,8 @@ namespace dxvk { void CreatePresenter(); + VkResult CreateSurface(VkSurfaceKHR* pSurface); + void CreateRenderTargetViews(); void DestroyBackBuffers(); diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 1f0ae7eed..653cf3975 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -23,6 +23,7 @@ namespace dxvk::vk { ~LibraryLoader(); PFN_vkVoidFunction sym(VkInstance instance, const char* name) const; PFN_vkVoidFunction sym(const char* name) const; + PFN_vkGetInstanceProcAddr getLoaderProc() const { return m_getInstanceProcAddr; } bool valid() const; protected: const HMODULE m_library; @@ -39,6 +40,7 @@ namespace dxvk::vk { struct InstanceLoader : public RcObject { InstanceLoader(const Rc& library, bool owned, VkInstance instance); PFN_vkVoidFunction sym(const char* name) const; + PFN_vkGetInstanceProcAddr getLoaderProc() const { return m_library->getLoaderProc(); } VkInstance instance() const { return m_instance; } protected: Rc m_library; diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index c667a815d..860fdbf4d 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -7,17 +7,12 @@ namespace dxvk::vk { Presenter::Presenter( - HWND window, const Rc& vki, const Rc& vkd, PresenterDevice device, const PresenterDesc& desc) - : m_vki(vki), m_vkd(vkd), m_device(device), m_window(window) { - if (createSurface() != VK_SUCCESS) - throw DxvkError("Failed to create surface"); + : m_vki(vki), m_vkd(vkd), m_device(device) { - if (recreateSwapChain(desc) != VK_SUCCESS) - throw DxvkError("Failed to create swap chain"); } @@ -46,7 +41,7 @@ namespace dxvk::vk { m_swapchain, std::numeric_limits::max(), sync.acquire, VK_NULL_HANDLE, &m_imageIndex); } - + if (m_acquireStatus != VK_SUCCESS && m_acquireStatus != VK_SUBOPTIMAL_KHR) return m_acquireStatus; @@ -88,11 +83,26 @@ namespace dxvk::vk { return status; } - + + VkResult Presenter::recreateSurface( + const std::function& fn) { + if (m_swapchain) + destroySwapchain(); + + if (m_surface) + destroySurface(); + + return fn(&m_surface); + } + + VkResult Presenter::recreateSwapChain(const PresenterDesc& desc) { if (m_swapchain) destroySwapchain(); + if (!m_surface) + return VK_ERROR_SURFACE_LOST_KHR; + // Query surface capabilities. Some properties might // have changed, including the size limits and supported // present modes, so we'll just query everything again. @@ -103,13 +113,13 @@ namespace dxvk::vk { VkResult status; if ((status = m_vki->vkGetPhysicalDeviceSurfaceCapabilitiesKHR( - m_device.adapter, m_surface, &caps)) != VK_SUCCESS) + m_device.adapter, m_surface, &caps))) return status; - if ((status = getSupportedFormats(formats, desc)) != VK_SUCCESS) + if ((status = getSupportedFormats(formats, desc))) return status; - if ((status = getSupportedPresentModes(modes, desc)) != VK_SUCCESS) + if ((status = getSupportedPresentModes(modes, desc))) return status; // Select actual swap chain properties and create swap chain @@ -155,13 +165,13 @@ namespace dxvk::vk { "\n Exclusive FS: ", desc.fullScreenExclusive)); if ((status = m_vkd->vkCreateSwapchainKHR(m_vkd->device(), - &swapInfo, nullptr, &m_swapchain)) != VK_SUCCESS) + &swapInfo, nullptr, &m_swapchain))) return status; // Acquire images and create views std::vector images; - if ((status = getSwapImages(images)) != VK_SUCCESS) + if ((status = getSwapImages(images))) return status; // Update actual image count @@ -183,7 +193,7 @@ namespace dxvk::vk { 0, 1, 0, 1 }; if ((status = m_vkd->vkCreateImageView(m_vkd->device(), - &viewInfo, nullptr, &m_images[i].view)) != VK_SUCCESS) + &viewInfo, nullptr, &m_images[i].view))) return status; } @@ -194,11 +204,11 @@ namespace dxvk::vk { VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(), - &semInfo, nullptr, &m_semaphores[i].acquire)) != VK_SUCCESS) + &semInfo, nullptr, &m_semaphores[i].acquire))) return status; if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(), - &semInfo, nullptr, &m_semaphores[i].present)) != VK_SUCCESS) + &semInfo, nullptr, &m_semaphores[i].present))) return status; } @@ -398,28 +408,6 @@ namespace dxvk::vk { } - VkResult Presenter::createSurface() { - /* TODO fix */ - VkResult status = wsi::createSurface(m_window, nullptr, m_vki->instance(), &m_surface); - - if (status != VK_SUCCESS) - return status; - - VkBool32 supportStatus = VK_FALSE; - - if ((status = m_vki->vkGetPhysicalDeviceSurfaceSupportKHR(m_device.adapter, - m_device.queueFamily, m_surface, &supportStatus)) != VK_SUCCESS) - return status; - - if (!supportStatus) { - m_vki->vkDestroySurfaceKHR(m_vki->instance(), m_surface, nullptr); - return VK_ERROR_OUT_OF_HOST_MEMORY; // just abuse this - } - - return VK_SUCCESS; - } - - void Presenter::destroySwapchain() { for (const auto& img : m_images) m_vkd->vkDestroyImageView(m_vkd->device(), img.view, nullptr); @@ -440,6 +428,8 @@ namespace dxvk::vk { void Presenter::destroySurface() { m_vki->vkDestroySurfaceKHR(m_vki->instance(), m_surface, nullptr); + + m_surface = VK_NULL_HANDLE; } } diff --git a/src/vulkan/vulkan_presenter.h b/src/vulkan/vulkan_presenter.h index 8df19ea93..858ada308 100644 --- a/src/vulkan/vulkan_presenter.h +++ b/src/vulkan/vulkan_presenter.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include "../util/log/log.h" @@ -93,7 +94,6 @@ namespace dxvk::vk { public: Presenter( - HWND window, const Rc& vki, const Rc& vkd, PresenterDevice device, @@ -141,7 +141,16 @@ namespace dxvk::vk { * \returns Status of the operation */ VkResult presentImage(); - + + /** + * \brief Changes and takes ownership of surface + * + * The presenter will destroy the surface as necessary. + * \param [in] fn Surface create function + */ + VkResult recreateSurface( + const std::function& fn); + /** * \brief Changes presenter properties * @@ -149,6 +158,7 @@ namespace dxvk::vk { * no swap chain resources must be in use by the * GPU at the time this is called. * \param [in] desc Swap chain description + * \param [in] surface New Vulkan surface */ VkResult recreateSwapChain( const PresenterDesc& desc); @@ -181,7 +191,6 @@ namespace dxvk::vk { PresenterDevice m_device; PresenterInfo m_info; - HWND m_window = nullptr; VkSurfaceKHR m_surface = VK_NULL_HANDLE; VkSwapchainKHR m_swapchain = VK_NULL_HANDLE; @@ -195,6 +204,9 @@ namespace dxvk::vk { FpsLimiter m_fpsLimiter; + VkResult recreateSwapChainInternal( + const PresenterDesc& desc); + VkResult getSupportedFormats( std::vector& formats, const PresenterDesc& desc); From 76e6b2764b1cc9f4203114074bf2a5edbe326227 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 28 Oct 2022 17:22:27 +0200 Subject: [PATCH 0943/1348] [dxgi] Change CreateSwapChain to take a surface factory --- src/d3d11/d3d11_device.cpp | 6 ++---- src/d3d11/d3d11_device.h | 2 +- src/dxgi/dxgi_factory.cpp | 7 +++++-- src/dxgi/dxgi_interfaces.h | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 6599a7e40..001574625 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -2997,7 +2997,7 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DXGIVkSwapChainFactory::CreateSwapChain( - HWND hWnd, + IDXGIVkSurfaceFactory* pSurfaceFactory, const DXGI_SWAP_CHAIN_DESC1* pDesc, IDXGIVkSwapChain** ppSwapChain) { InitReturnPtr(ppSwapChain); @@ -3005,10 +3005,8 @@ namespace dxvk { try { auto vki = m_device->GetDXVKDevice()->adapter()->vki(); - Com surfaceFactory = new DxgiSurfaceFactory(vki->getLoaderProc(), hWnd); - Com presenter = new D3D11SwapChain( - m_container, m_device, surfaceFactory.ptr(), pDesc); + m_container, m_device, pSurfaceFactory, pDesc); *ppSwapChain = presenter.ref(); return S_OK; diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 3c1db4295..e23de4b21 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -710,7 +710,7 @@ namespace dxvk { void** ppvObject); HRESULT STDMETHODCALLTYPE CreateSwapChain( - HWND hWnd, + IDXGIVkSurfaceFactory* pSurfaceFactory, const DXGI_SWAP_CHAIN_DESC1* pDesc, IDXGIVkSwapChain** ppSwapChain); diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp index 0f6afee2d..10cf2861d 100644 --- a/src/dxgi/dxgi_factory.cpp +++ b/src/dxgi/dxgi_factory.cpp @@ -1,4 +1,5 @@ #include "dxgi_factory.h" +#include "dxgi_surface.h" #include "dxgi_swapchain.h" #include "dxgi_swapchain_dispatcher.h" @@ -153,9 +154,11 @@ namespace dxvk { Com wineFactory; if (SUCCEEDED(pDevice->QueryInterface(IID_PPV_ARGS(&dxvkFactory)))) { - Com presenter; + Com surfaceFactory = new DxgiSurfaceFactory( + m_instance->vki()->getLoaderProc(), hWnd); - HRESULT hr = dxvkFactory->CreateSwapChain(hWnd, &desc, &presenter); + Com presenter; + HRESULT hr = dxvkFactory->CreateSwapChain(surfaceFactory.ptr(), &desc, &presenter); if (FAILED(hr)) { Logger::err(str::format("DXGI: CreateSwapChainForHwnd: Failed to create swap chain, hr ", hr)); diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index 989fb064b..66d517a88 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -121,7 +121,7 @@ IDXGIVkSwapChain : public IUnknown { MIDL_INTERFACE("e7d6c3ca-23a0-4e08-9f2f-ea5231df6633") IDXGIVkSwapChainFactory : public IUnknown { virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( - HWND hWnd, + IDXGIVkSurfaceFactory* pSurfaceFactory, const DXGI_SWAP_CHAIN_DESC1* pDesc, IDXGIVkSwapChain** ppSwapChain) = 0; }; From ecc230238913d2599db276573d7590ed4a898524 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 7 Nov 2022 22:25:05 +0100 Subject: [PATCH 0944/1348] [d3d9] Fix query reset counter underflow --- src/d3d9/d3d9_query.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_query.cpp b/src/d3d9/d3d9_query.cpp index 7ce47cf97..a48732528 100644 --- a/src/d3d9/d3d9_query.cpp +++ b/src/d3d9/d3d9_query.cpp @@ -101,8 +101,10 @@ namespace dxvk { if (dwIssueFlags == D3DISSUE_BEGIN) { if (QueryBeginnable(m_queryType)) { - if (m_state == D3D9_VK_QUERY_BEGUN && QueryEndable(m_queryType)) + if (m_state == D3D9_VK_QUERY_BEGUN && QueryEndable(m_queryType)) { + m_resetCtr.fetch_add(1, std::memory_order_acquire); m_parent->End(this); + } m_parent->Begin(this); From e30b783505247753723c95eab5239c802b19b047 Mon Sep 17 00:00:00 2001 From: Christopher Egert Date: Tue, 8 Nov 2022 23:47:01 +0100 Subject: [PATCH 0945/1348] d3d9: Use a different rvalue for depth bias on NV --- src/d3d9/d3d9_device.cpp | 3 ++- src/d3d9/d3d9_util.h | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index a89cc4631..93da5ce3d 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -1382,7 +1382,8 @@ namespace dxvk { m_flags.set(D3D9DeviceFlag::DirtyFramebuffer); if (ds != nullptr) { - float rValue = GetDepthBufferRValue(ds->GetCommonTexture()->GetFormatMapping().FormatColor); + const int32_t vendorId = m_dxvkDevice->adapter()->deviceProperties().vendorID; + float rValue = GetDepthBufferRValue(ds->GetCommonTexture()->GetFormatMapping().FormatColor, vendorId); if (m_depthBiasScale != rValue) { m_depthBiasScale = rValue; m_flags.set(D3D9DeviceFlag::DirtyDepthBias); diff --git a/src/d3d9/d3d9_util.h b/src/d3d9/d3d9_util.h index 4358233f8..5da8e95db 100644 --- a/src/d3d9/d3d9_util.h +++ b/src/d3d9/d3d9_util.h @@ -176,14 +176,14 @@ namespace dxvk { void ConvertRect(RECT rect, VkOffset2D& offset, VkExtent2D& extent); - inline float GetDepthBufferRValue(VkFormat Format) { + inline float GetDepthBufferRValue(VkFormat Format, int32_t vendorId) { switch (Format) { case VK_FORMAT_D16_UNORM_S8_UINT: case VK_FORMAT_D16_UNORM: - return float(1 << 16); + return vendorId == 0x10de ? float(1 << 15) : float(1 << 16); case VK_FORMAT_D24_UNORM_S8_UINT: - return float(1 << 24); + return vendorId == 0x10de ? float(1 << 23) : float(1 << 24); default: case VK_FORMAT_D32_SFLOAT_S8_UINT: From bc08cac22044ae9f4dccf5722e8290c5adb62df3 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Wed, 9 Nov 2022 17:21:11 +0100 Subject: [PATCH 0946/1348] [util] Enable apitraceMode for Sonic & All-Stars Racing Transformed --- src/util/config/config.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 86a8b5076..f3028b337 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -654,7 +654,13 @@ namespace dxvk { /* Fallout 3 - Doesn't like Intel Id */ { R"(\\Fallout3\.exe$)", {{ { "d3d9.customVendorId", "10de" }, - }} } + }} }, + /* Sonic & All-Stars Racing Transformed * + * Helps performance when Resizable BAR * + * is enabled */ + { R"(\\ASN_App_PcDx9_Final\.exe$)", {{ + { "d3d9.apitraceMode", "True" }, + }} }, }}; From 82685ca4fc27a6e3025d02fc257bc0bb92a1f4e5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 10 Nov 2022 13:26:31 +0100 Subject: [PATCH 0947/1348] [meta] Explicitly use meson setup command Fixes some deprecation warnings with Meson 0.64. --- README.md | 2 +- package-native.sh | 14 +++++++------- package-release.sh | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9a5793361..153a10041 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ ninja install ``` # 64-bit build. For 32-bit builds, replace # build-win64.txt with build-win32.txt -meson --cross-file build-win64.txt --buildtype release --prefix /your/dxvk/directory build.w64 +meson setup --cross-file build-win64.txt --buildtype release --prefix /your/dxvk/directory build.w64 cd build.w64 ninja install ``` diff --git a/package-native.sh b/package-native.sh index 0ee4920e0..cdb88b5ed 100755 --- a/package-native.sh +++ b/package-native.sh @@ -55,13 +55,13 @@ function build_arch { opt_strip=--strip fi - CC="$CC -m$1" CXX="$CXX -m$1" meson \ - --buildtype "release" \ - --prefix "$DXVK_BUILD_DIR/usr" \ - $opt_strip \ - --bindir "$2" \ - --libdir "$2" \ - -Dbuild_id=$opt_buildid \ + CC="$CC -m$1" CXX="$CXX -m$1" meson setup \ + --buildtype "release" \ + --prefix "$DXVK_BUILD_DIR/usr" \ + $opt_strip \ + --bindir "$2" \ + --libdir "$2" \ + -Dbuild_id=$opt_buildid \ "$DXVK_BUILD_DIR/build.$1" cd "$DXVK_BUILD_DIR/build.$1" diff --git a/package-release.sh b/package-release.sh index 6401b2020..cedec2d84 100755 --- a/package-release.sh +++ b/package-release.sh @@ -57,13 +57,13 @@ function build_arch { opt_strip=--strip fi - meson --cross-file "$DXVK_SRC_DIR/$crossfile$1.txt" \ - --buildtype "release" \ - --prefix "$DXVK_BUILD_DIR" \ - $opt_strip \ - --bindir "x$1" \ - --libdir "x$1" \ - -Dbuild_id=$opt_buildid \ + meson setup --cross-file "$DXVK_SRC_DIR/$crossfile$1.txt" \ + --buildtype "release" \ + --prefix "$DXVK_BUILD_DIR" \ + $opt_strip \ + --bindir "x$1" \ + --libdir "x$1" \ + -Dbuild_id=$opt_buildid \ "$DXVK_BUILD_DIR/build.$1" cd "$DXVK_BUILD_DIR/build.$1" From 8a2e4ef48196a4a7ff12bdd6a13abba17b3cfc4e Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Wed, 9 Nov 2022 23:04:41 +0100 Subject: [PATCH 0948/1348] [d3d9] Allow locking DEFAULT pool based on texture type --- src/d3d9/d3d9_common_texture.h | 1 + src/d3d9/d3d9_device.cpp | 33 ++++++++++++++++++++++++++------- src/d3d9/d3d9_format.h | 13 +++++++++++++ src/d3d9/d3d9_swapchain.cpp | 2 ++ 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index fcd9f2a00..cc27bcd2c 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -47,6 +47,7 @@ namespace dxvk { bool Discard; bool IsBackBuffer; bool IsAttachmentOnly; + bool IsLockable; }; struct D3D9ColorView { diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 93da5ce3d..f35dcc72c 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -482,6 +482,12 @@ namespace dxvk { desc.MultisampleQuality = 0; desc.IsBackBuffer = FALSE; desc.IsAttachmentOnly = FALSE; + // Docs: + // Textures placed in the D3DPOOL_DEFAULT pool cannot be locked + // unless they are dynamic textures or they are private, FOURCC, driver formats. + desc.IsLockable = Pool != D3DPOOL_DEFAULT + || (Usage & D3DUSAGE_DYNAMIC) + || IsVendorFormat(EnumerateFormat(Format)); if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc))) return D3DERR_INVALIDCALL; @@ -543,6 +549,12 @@ namespace dxvk { desc.MultisampleQuality = 0; desc.IsBackBuffer = FALSE; desc.IsAttachmentOnly = FALSE; + // Docs: + // Textures placed in the D3DPOOL_DEFAULT pool cannot be locked + // unless they are dynamic textures or they are private, FOURCC, driver formats. + desc.IsLockable = Pool != D3DPOOL_DEFAULT + || (Usage & D3DUSAGE_DYNAMIC) + || IsVendorFormat(EnumerateFormat(Format)); if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc))) return D3DERR_INVALIDCALL; @@ -591,6 +603,12 @@ namespace dxvk { desc.MultisampleQuality = 0; desc.IsBackBuffer = FALSE; desc.IsAttachmentOnly = FALSE; + // Docs: + // Textures placed in the D3DPOOL_DEFAULT pool cannot be locked + // unless they are dynamic textures or they are private, FOURCC, driver formats. + desc.IsLockable = Pool != D3DPOOL_DEFAULT + || (Usage & D3DUSAGE_DYNAMIC) + || IsVendorFormat(EnumerateFormat(Format)); if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc))) return D3DERR_INVALIDCALL; @@ -3539,6 +3557,7 @@ namespace dxvk { desc.MultisampleQuality = MultisampleQuality; desc.IsBackBuffer = FALSE; desc.IsAttachmentOnly = TRUE; + desc.IsLockable = Lockable; if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc))) return D3DERR_INVALIDCALL; @@ -3583,6 +3602,8 @@ namespace dxvk { desc.MultisampleQuality = 0; desc.IsBackBuffer = FALSE; desc.IsAttachmentOnly = Pool == D3DPOOL_DEFAULT; + // Docs: Off-screen plain surfaces are always lockable, regardless of their pool types. + desc.IsLockable = TRUE; if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc))) return D3DERR_INVALIDCALL; @@ -3632,6 +3653,8 @@ namespace dxvk { desc.MultisampleQuality = MultisampleQuality; desc.IsBackBuffer = FALSE; desc.IsAttachmentOnly = TRUE; + // Docs don't say anything, so just assume it's lockable. + desc.IsLockable = TRUE; if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc))) return D3DERR_INVALIDCALL; @@ -4243,13 +4266,7 @@ namespace dxvk { auto& desc = *(pResource->Desc()); - // MSDN: - // Textures placed in the D3DPOOL_DEFAULT pool cannot be locked - // unless they are dynamic textures or they are private, FOURCC, driver formats. - // Also note that - unlike textures - swap chain back buffers, render targets [..] can be locked - if (unlikely(desc.Pool == D3DPOOL_DEFAULT - && !(desc.Usage & (D3DUSAGE_DYNAMIC | D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) - && !IsFourCCFormat(desc.Format))) + if (unlikely(!desc.IsLockable)) return D3DERR_INVALIDCALL; auto& formatMapping = pResource->GetFormatMapping(); @@ -7311,6 +7328,8 @@ namespace dxvk { desc.MultisampleQuality = pPresentationParameters->MultiSampleQuality; desc.IsBackBuffer = FALSE; desc.IsAttachmentOnly = TRUE; + // Docs: Also note that - unlike textures - swap chain back buffers, render targets [..] can be locked + desc.IsLockable = TRUE; if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc))) return D3DERR_NOTAVAILABLE; diff --git a/src/d3d9/d3d9_format.h b/src/d3d9/d3d9_format.h index b09b9d469..c38f6fe4c 100644 --- a/src/d3d9/d3d9_format.h +++ b/src/d3d9/d3d9_format.h @@ -226,4 +226,17 @@ namespace dxvk { return format > D3D9Format::BINARYBUFFER; } + inline bool IsVendorFormat(D3D9Format format) { + return IsFourCCFormat(format) + && format != D3D9Format::MULTI2_ARGB8 + && format != D3D9Format::UYVY + && format != D3D9Format::R8G8_B8G8 + && format != D3D9Format::G8R8_G8B8 + && format != D3D9Format::DXT1 + && format != D3D9Format::DXT2 + && format != D3D9Format::DXT3 + && format != D3D9Format::DXT4 + && format != D3D9Format::DXT5; + } + } diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index 807740e74..e01c80413 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -897,6 +897,8 @@ namespace dxvk { desc.Discard = FALSE; desc.IsBackBuffer = TRUE; desc.IsAttachmentOnly = FALSE; + // Docs: Also note that - unlike textures - swap chain back buffers, render targets [..] can be locked + desc.IsLockable = TRUE; for (uint32_t i = 0; i < m_backBuffers.size(); i++) m_backBuffers[i] = new D3D9Surface(m_parent, &desc, this, nullptr); From 8f8a93696d36adca8efeed4e16dc6b3deea27268 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 10 Nov 2022 13:55:39 +0100 Subject: [PATCH 0949/1348] [meta] Release 2.0 --- RELEASE | 2 +- meson.build | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASE b/RELEASE index 4dae2985b..cd5ac039d 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -1.10.1 +2.0 diff --git a/meson.build b/meson.build index 4c4a32210..e417ff67e 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('dxvk', ['c', 'cpp'], version : 'v1.10.1', meson_version : '>= 0.49', default_options : [ 'cpp_std=c++17', 'warning_level=2' ]) +project('dxvk', ['c', 'cpp'], version : 'v2.0', meson_version : '>= 0.49', default_options : [ 'cpp_std=c++17', 'warning_level=2' ]) cpu_family = target_machine.cpu_family() platform = target_machine.system() From 785bc9738fec4059af47d9e34e0c60498bbe4f61 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Tue, 15 Nov 2022 15:49:45 +0100 Subject: [PATCH 0950/1348] [util] Disable DC Single Use Mode for Cardfight!! Vanguard Dear Days --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index f3028b337..8d9fa3a5e 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -309,6 +309,11 @@ namespace dxvk { { R"(\\MSFC\.exe$)", {{ { "dxgi.maxFrameRate", "60" }, }} }, + /* Cardfight!! Vanguard Dear Days: * + * Submits command lists multiple times */ + { R"(\\VG2\.exe$)", {{ + { "d3d11.dcSingleUseMode", "False" }, + }} }, /**********************************************/ /* D3D9 GAMES */ From ad3c316d0c96a02d19f76d6bbcb90cdcdd1a9425 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Wed, 16 Nov 2022 08:10:38 +0100 Subject: [PATCH 0951/1348] [util] Set Black Mesa customVendorId to Nvidia --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 8d9fa3a5e..961c74972 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -666,6 +666,11 @@ namespace dxvk { { R"(\\ASN_App_PcDx9_Final\.exe$)", {{ { "d3d9.apitraceMode", "True" }, }} }, + /* Black Mesa * + * Artifacts & broken flashlight on Intel */ + { R"(\\bms\.exe$)", {{ + { "d3d9.customVendorId", "10de" }, + }} }, }}; From 69b1aa251d4470a663ca211e6954ef3fa2a5fb35 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 16 Nov 2022 16:29:17 +0000 Subject: [PATCH 0952/1348] [wsi] Add getMonitorEdid function What an unbelievable pain this is to do on Windows... No-op on SDL2 right now, as there is nothing for that. --- src/wsi/sdl2/wsi_monitor_sdl2.cpp | 5 + src/wsi/win32/wsi_monitor_win32.cpp | 153 ++++++++++++++++++++++++++++ src/wsi/wsi_monitor.h | 17 +++- 3 files changed, 174 insertions(+), 1 deletion(-) diff --git a/src/wsi/sdl2/wsi_monitor_sdl2.cpp b/src/wsi/sdl2/wsi_monitor_sdl2.cpp index 1ab82301c..bb2fd3f86 100644 --- a/src/wsi/sdl2/wsi_monitor_sdl2.cpp +++ b/src/wsi/sdl2/wsi_monitor_sdl2.cpp @@ -144,4 +144,9 @@ namespace dxvk::wsi { return true; } + std::vector getMonitorEdid(HMONITOR hMonitor) { + Logger::err("getMonitorEdid not implemented on this platform."); + return {}; + } + } \ No newline at end of file diff --git a/src/wsi/win32/wsi_monitor_win32.cpp b/src/wsi/win32/wsi_monitor_win32.cpp index be466db58..3d7913e87 100644 --- a/src/wsi/win32/wsi_monitor_win32.cpp +++ b/src/wsi/win32/wsi_monitor_win32.cpp @@ -1,9 +1,14 @@ #include "../wsi_monitor.h" #include "../../util/log/log.h" +#include "../../util/util_string.h" #include +#include +#include +#include + namespace dxvk::wsi { HMONITOR getDefaultMonitor() { @@ -131,4 +136,152 @@ namespace dxvk::wsi { return retrieveDisplayMode(hMonitor, ENUM_REGISTRY_SETTINGS, pMode); } + static std::wstring getMonitorDevicePath(HMONITOR hMonitor) { + // Get the device name of the monitor. + MONITORINFOEXW monInfo; + monInfo.cbSize = sizeof(monInfo); + if (!::GetMonitorInfoW(hMonitor, &monInfo)) { + Logger::err("getMonitorDevicePath: Failed to get monitor info."); + return {}; + } + + // Try and find the monitor device path that matches + // the name of our HMONITOR from the monitor info. + LONG result = ERROR_SUCCESS; + std::vector paths; + std::vector modes; + do { + uint32_t pathCount = 0, modeCount = 0; + if ((result = ::GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount)) != ERROR_SUCCESS) { + Logger::err(str::format("getMonitorDevicePath: GetDisplayConfigBufferSizes failed. ret: ", result, " LastError: ", GetLastError())); + return {}; + } + paths.resize(pathCount); + modes.resize(modeCount); + result = ::QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, paths.data(), &modeCount, modes.data(), nullptr); + } while (result == ERROR_INSUFFICIENT_BUFFER); + + if (result != ERROR_SUCCESS) { + Logger::err(str::format("getMonitorDevicePath: QueryDisplayConfig failed. ret: ", result, " LastError: ", GetLastError())); + return {}; + } + + // Link a source name -> target name + for (const auto& path : paths) { + DISPLAYCONFIG_SOURCE_DEVICE_NAME sourceName; + sourceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + sourceName.header.size = sizeof(sourceName); + sourceName.header.adapterId = path.sourceInfo.adapterId; + sourceName.header.id = path.sourceInfo.id; + if ((result = ::DisplayConfigGetDeviceInfo(&sourceName.header)) != ERROR_SUCCESS) { + Logger::err(str::format("getMonitorDevicePath: DisplayConfigGetDeviceInfo with DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME failed. ret: ", result, " LastError: ", GetLastError())); + continue; + } + + DISPLAYCONFIG_TARGET_DEVICE_NAME targetName; + targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; + targetName.header.size = sizeof(targetName); + targetName.header.adapterId = path.targetInfo.adapterId; + targetName.header.id = path.targetInfo.id; + if ((result = ::DisplayConfigGetDeviceInfo(&targetName.header)) != ERROR_SUCCESS) { + Logger::err(str::format("getMonitorDevicePath: DisplayConfigGetDeviceInfo with DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME failed. ret: ", result, " LastError: ", GetLastError())); + continue; + } + + // Does the source match the GDI device we are looking for? + // If so, return the target back. + if (!wcscmp(sourceName.viewGdiDeviceName, monInfo.szDevice)) + return targetName.monitorDevicePath; + } + + Logger::err("getMonitorDevicePath: Failed to find a link from source -> target."); + return {}; + } + + static WsiEdidData readMonitorEdidFromKey(HKEY deviceRegKey) { + DWORD edidSize = 0; + if (::RegQueryValueExW(deviceRegKey, L"EDID", nullptr, nullptr, nullptr, &edidSize) != ERROR_SUCCESS) { + Logger::err("readMonitorEdidFromKey: Failed to get EDID reg key size"); + return {}; + } + + WsiEdidData edidData(edidSize); + if (::RegQueryValueExW(deviceRegKey, L"EDID", nullptr, nullptr, edidData.data(), &edidSize) != ERROR_SUCCESS) { + Logger::err("readMonitorEdidFromKey: Failed to get EDID reg key data"); + return {}; + } + + return edidData; + } + + struct DxvkDeviceInterfaceDetail { + // SP_DEVICE_INTERFACE_DETAIL_DATA_W contains an array called + // "ANYSIZE_ARRAY" which is just 1 wchar_t in size. + // Incredible, safe, and smart API design. + // Allocate some chars after so it can fill these in. + SP_DEVICE_INTERFACE_DETAIL_DATA_W base; + wchar_t extraChars[MAX_DEVICE_ID_LEN]; + }; + + WsiEdidData getMonitorEdid(HMONITOR hMonitor) { + static constexpr GUID GUID_DEVINTERFACE_MONITOR = { 0xe6f07b5f, 0xee97, 0x4a90, 0xb0, 0x76, 0x33, 0xf5, 0x7b, 0xf4, 0xea, 0xa7 }; + static auto pfnSetupDiGetClassDevsW = reinterpret_cast (::GetProcAddress(::GetModuleHandleW(L"setupapi.dll"), "SetupDiGetClassDevsW")); + static auto pfnSetupDiEnumDeviceInterfaces = reinterpret_cast (::GetProcAddress(::GetModuleHandleW(L"setupapi.dll"), "SetupDiEnumDeviceInterfaces")); + static auto pfnSetupDiGetDeviceInterfaceDetailW = reinterpret_cast(::GetProcAddress(::GetModuleHandleW(L"setupapi.dll"), "SetupDiGetDeviceInterfaceDetailW")); + static auto pfnSetupDiOpenDevRegKey = reinterpret_cast (::GetProcAddress(::GetModuleHandleW(L"setupapi.dll"), "SetupDiOpenDevRegKey")); + static auto pfnSetupDiGetDeviceInstanceIdW = reinterpret_cast (::GetProcAddress(::GetModuleHandleW(L"setupapi.dll"), "SetupDiGetDeviceInstanceIdW")); + if (!pfnSetupDiGetClassDevsW || !pfnSetupDiEnumDeviceInterfaces || !pfnSetupDiGetDeviceInterfaceDetailW || !pfnSetupDiOpenDevRegKey || !pfnSetupDiGetDeviceInstanceIdW) { + Logger::err("getMonitorEdid: Failed to load functions from setupapi."); + return {}; + } + + std::wstring monitorDevicePath = getMonitorDevicePath(hMonitor); + if (monitorDevicePath.empty()) { + Logger::err("getMonitorEdid: Failed to get monitor device path."); + return {}; + } + + const HDEVINFO devInfo = pfnSetupDiGetClassDevsW(&GUID_DEVINTERFACE_MONITOR, nullptr, nullptr, DIGCF_DEVICEINTERFACE); + + SP_DEVICE_INTERFACE_DATA interfaceData; + memset(&interfaceData, 0, sizeof(interfaceData)); + interfaceData.cbSize = sizeof(interfaceData); + + for (DWORD monitorIdx = 0; pfnSetupDiEnumDeviceInterfaces(devInfo, nullptr, &GUID_DEVINTERFACE_MONITOR, monitorIdx, &interfaceData); monitorIdx++) { + DxvkDeviceInterfaceDetail detailData; + // Josh: I'm taking no chances here. I don't trust this API at all. + memset(&detailData, 0, sizeof(detailData)); + detailData.base.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); + + SP_DEVINFO_DATA devInfoData; + memset(&devInfoData, 0, sizeof(devInfoData)); + devInfoData.cbSize = sizeof(devInfoData); + + if (!pfnSetupDiGetDeviceInterfaceDetailW(devInfo, &interfaceData, &detailData.base, sizeof(detailData), nullptr, &devInfoData)) + continue; + + // Check that this monitor matches the same one we are looking for. + // Note: For some reason the casing mismatches here, because this + // is a well-designed API. + // If it isn't what we are looking for, move along. + if (_wcsicmp(monitorDevicePath.c_str(), detailData.base.DevicePath) != 0) + continue; + + HKEY deviceRegKey = pfnSetupDiOpenDevRegKey(devInfo, &devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); + if (deviceRegKey == INVALID_HANDLE_VALUE) { + Logger::err("getMonitorEdid: Failed to open monitor device registry key."); + return {}; + } + + auto edidData = readMonitorEdidFromKey(deviceRegKey); + + ::RegCloseKey(deviceRegKey); + + return edidData; + } + + Logger::err("getMonitorEdid: Failed to find device interface for monitor using setupapi."); + return {}; + } + } \ No newline at end of file diff --git a/src/wsi/wsi_monitor.h b/src/wsi/wsi_monitor.h index c7e33578e..84c00b087 100644 --- a/src/wsi/wsi_monitor.h +++ b/src/wsi/wsi_monitor.h @@ -3,6 +3,7 @@ #include #include +#include #include namespace dxvk::wsi { @@ -123,5 +124,19 @@ namespace dxvk::wsi { if (pHeight) *pHeight = rect.bottom - rect.top; } - + + using WsiEdidData = std::vector; + + /** + * \brief Get the EDID of a monitor + * + * Helper function to grab the EDID of a monitor. + * This is needed to get the HDR static metadata + colorimetry + * info of a display for exposing HDR. + * + * \param [in] hMonitor The monitor + * \returns \c EDID if successful, an empty vector if failure. + */ + WsiEdidData getMonitorEdid(HMONITOR hMonitor); + } From 287412f74602225ff292d440fb71f4420174f3ae Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 16 Nov 2022 15:49:34 +0000 Subject: [PATCH 0953/1348] [util] Cast _tzcnt_u64 to uint32_t MSVC has _tzcnt_u64 return a uint64_t, which obviously, it can never return a number that big. --- src/util/util_bit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index aabc2649b..e5ee5ac2c 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -101,7 +101,7 @@ namespace dxvk::bit { inline uint32_t tzcnt(uint64_t n) { #if defined(DXVK_ARCH_X86_64) && defined(_MSC_VER) && !defined(__clang__) - return _tzcnt_u64(n); + return (uint32_t)_tzcnt_u64(n); #elif defined(DXVK_ARCH_X86_64) && defined(__BMI__) return __tzcnt_u64(n); #elif defined(DXVK_ARCH_X86_64) && (defined(__GNUC__) || defined(__clang__)) From e037d240179f1d5255cacceb8c681550253029fb Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Wed, 16 Nov 2022 15:50:04 +0000 Subject: [PATCH 0954/1348] [util] Default initialize BitMask to 0 Found via an MSVC warning, may not fix anything, but good to do anyway. --- src/util/util_bit.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index e5ee5ac2c..5f09c31ef 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -385,7 +385,8 @@ namespace dxvk::bit { }; - BitMask() { } + BitMask() + : m_mask(0) { } BitMask(uint32_t n) : m_mask(n) { } From a130146f153e1999343220d0a383092f8824d41d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 18 Nov 2022 22:29:04 +0100 Subject: [PATCH 0955/1348] [dxvk] Remove dead enableRtOutputNanFixup option Dead code since 2.0, not sure why this was still in here. --- src/d3d11/d3d11_options.cpp | 1 - src/d3d11/d3d11_options.h | 4 ---- src/dxbc/dxbc_options.cpp | 4 ---- src/dxbc/dxbc_options.h | 3 --- 4 files changed, 12 deletions(-) diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index 1d2997122..f4eee5b23 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -14,7 +14,6 @@ namespace dxvk { D3D11Options::D3D11Options(const Config& config, const Rc& device) { this->dcSingleUseMode = config.getOption("d3d11.dcSingleUseMode", true); - this->enableRtOutputNanFixup = config.getOption("d3d11.enableRtOutputNanFixup", false); this->zeroInitWorkgroupMemory = config.getOption("d3d11.zeroInitWorkgroupMemory", false); this->forceVolatileTgsmAccess = config.getOption("d3d11.forceVolatileTgsmAccess", false); this->relaxedBarriers = config.getOption("d3d11.relaxedBarriers", false); diff --git a/src/d3d11/d3d11_options.h b/src/d3d11/d3d11_options.h index e9431538c..1b636db18 100644 --- a/src/d3d11/d3d11_options.h +++ b/src/d3d11/d3d11_options.h @@ -20,10 +20,6 @@ namespace dxvk { /// than once. bool dcSingleUseMode; - /// Enables workaround to replace NaN render target - /// outputs with zero - bool enableRtOutputNanFixup; - /// Zero-initialize workgroup memory /// /// Workargound for games that don't initialize diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 9b0a5cfff..0d8486793 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -35,7 +35,6 @@ namespace dxvk { } invariantPosition = options.invariantPosition; - enableRtOutputNanFixup = options.enableRtOutputNanFixup; zeroInitWorkgroupMemory = options.zeroInitWorkgroupMemory; forceVolatileTgsmAccess = options.forceVolatileTgsmAccess; disableMsaa = options.disableMsaa; @@ -55,9 +54,6 @@ namespace dxvk { floatControl.set(DxbcFloatControlFlag::DenormPreserve64); } } - - if (!devInfo.vk12.shaderSignedZeroInfNanPreserveFloat32) - enableRtOutputNanFixup = true; } } \ No newline at end of file diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index 6551b3c07..b29cf5d44 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -31,9 +31,6 @@ namespace dxvk { /// atomic operations for append/consume buffers. bool useSubgroupOpsForAtomicCounters = false; - /// Enables NaN fixup for render target outputs - bool enableRtOutputNanFixup = false; - /// Clear thread-group shared memory to zero bool zeroInitWorkgroupMemory = false; From 3393c5f4ffd509c7c812ca54853a829910f23f90 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sun, 13 Nov 2022 20:23:30 +0100 Subject: [PATCH 0956/1348] [d3d9] Only upload mip 0 of managed automipgen textures --- src/d3d9/d3d9_common_texture.cpp | 15 ++++++--------- src/d3d9/d3d9_common_texture.h | 12 ++++++++++-- src/d3d9/d3d9_texture.cpp | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.cpp b/src/d3d9/d3d9_common_texture.cpp index dab0cf54e..8cb723d2f 100644 --- a/src/d3d9/d3d9_common_texture.cpp +++ b/src/d3d9/d3d9_common_texture.cpp @@ -22,15 +22,17 @@ namespace dxvk { ? D3D9Format::D32 : D3D9Format::X8R8G8B8; + m_exposedMipLevels = m_desc.MipLevels; + + if (m_desc.Usage & D3DUSAGE_AUTOGENMIPMAP) + m_exposedMipLevels = 1; + for (uint32_t i = 0; i < m_dirtyBoxes.size(); i++) { AddDirtyBox(nullptr, i); } if (m_desc.Pool != D3DPOOL_DEFAULT) { - const uint32_t subresources = CountSubresources(); - for (uint32_t i = 0; i < subresources; i++) { - SetNeedsUpload(i, true); - } + SetAllNeedUpload(); if (pSharedHandle) { throw DxvkError("D3D9: Incompatible pool type for texture sharing."); } @@ -88,11 +90,6 @@ namespace dxvk { m_data = m_device->GetAllocator()->Alloc(m_totalSize); else if (m_mapMode != D3D9_COMMON_TEXTURE_MAP_MODE_NONE && m_desc.Pool != D3DPOOL_DEFAULT) CreateBuffer(false); - - m_exposedMipLevels = m_desc.MipLevels; - - if (m_desc.Usage & D3DUSAGE_AUTOGENMIPMAP) - m_exposedMipLevels = 1; } diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index cc27bcd2c..764159b6f 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -370,7 +370,15 @@ namespace dxvk { D3D9SubresourceBitset& GetUploadBitmask() { return m_needsUpload; } void SetAllNeedUpload() { - m_needsUpload.setAll(); + if (likely(!IsAutomaticMip())) { + m_needsUpload.setAll(); + } else { + for (uint32_t a = 0; a < m_desc.ArraySize; a++) { + for (uint32_t m = 0; m < ExposedMipLevels(); m++) { + SetNeedsUpload(CalcSubresource(a, m), true); + } + } + } } void SetNeedsUpload(UINT Subresource, bool upload) { m_needsUpload.set(Subresource, upload); } bool NeedsUpload(UINT Subresource) const { return m_needsUpload.get(Subresource); } @@ -380,7 +388,7 @@ namespace dxvk { void SetNeedsMipGen(bool value) { m_needsMipGen = value; } bool NeedsMipGen() const { return m_needsMipGen; } - DWORD ExposedMipLevels() { return m_exposedMipLevels; } + DWORD ExposedMipLevels() const { return m_exposedMipLevels; } void SetMipFilter(D3DTEXTUREFILTERTYPE filter) { m_mipFilter = filter; } D3DTEXTUREFILTERTYPE GetMipFilter() const { return m_mipFilter; } diff --git a/src/d3d9/d3d9_texture.cpp b/src/d3d9/d3d9_texture.cpp index e1e3547c3..1332fb32e 100644 --- a/src/d3d9/d3d9_texture.cpp +++ b/src/d3d9/d3d9_texture.cpp @@ -279,7 +279,7 @@ namespace dxvk { // and purely rely on AddDirtyRect to notify D3D9 that contents have changed. // We have no way of knowing which mip levels were actually changed. if (m_texture.IsManaged()) { - for (uint32_t m = 0; m < m_texture.Desc()->MipLevels; m++) { + for (uint32_t m = 0; m < m_texture.ExposedMipLevels(); m++) { m_texture.SetNeedsUpload(m_texture.CalcSubresource(Face, m), true); } } From dd7ec24269900d2bc017c3cebcd38ef24e3d391f Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 21 Nov 2022 01:29:47 +0100 Subject: [PATCH 0957/1348] [dxbc] Move shex check to constructor Otherwise we dereference a null pointer when accessing the DxbcProgramInfo. --- src/dxbc/dxbc_module.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/dxbc/dxbc_module.cpp b/src/dxbc/dxbc_module.cpp index d406bf292..53293e4a9 100644 --- a/src/dxbc/dxbc_module.cpp +++ b/src/dxbc/dxbc_module.cpp @@ -32,6 +32,9 @@ namespace dxvk { if ((tag == "PCSG") || (tag == "PSG1")) m_psgnChunk = new DxbcIsgn(chunkReader, tag); } + + if (m_shexChunk == nullptr) + throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk"); } @@ -43,8 +46,6 @@ namespace dxvk { Rc DxbcModule::compile( const DxbcModuleInfo& moduleInfo, const std::string& fileName) const { - if (m_shexChunk == nullptr) - throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk"); DxbcAnalysisInfo analysisInfo; @@ -70,9 +71,6 @@ namespace dxvk { Rc DxbcModule::compilePassthroughShader( const DxbcModuleInfo& moduleInfo, const std::string& fileName) const { - if (m_shexChunk == nullptr) - throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk"); - DxbcAnalysisInfo analysisInfo; DxbcCompiler compiler( From 2c53459f4c013159d91dfc53c58dc980c59ff5b9 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Fri, 18 Nov 2022 22:33:04 +0100 Subject: [PATCH 0958/1348] [util] disable floatControls for Bad Company 2 --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 961c74972..4bf6520ba 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -314,6 +314,11 @@ namespace dxvk { { R"(\\VG2\.exe$)", {{ { "d3d11.dcSingleUseMode", "False" }, }} }, + /* Battlefield: Bad Company 2 * + * Gets rid of black flickering */ + { R"(\\BFBC2Game\.exe$)", {{ + { "d3d11.floatControls", "False" }, + }} }, /**********************************************/ /* D3D9 GAMES */ From d0a10cc9f8ed0ee4c39be8b85f0565fa8d9d9cea Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 21 Nov 2022 15:41:12 +0100 Subject: [PATCH 0959/1348] [d3d9] Handle DS texture uploads --- src/d3d9/d3d9_device.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index f35dcc72c..6acdedd9a 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -4611,18 +4611,33 @@ namespace dxvk { slice.mapPtr, srcData, extentBlockCount, formatInfo->elementSize, pitch, pitch * srcTexLevelExtentBlockCount.height); + + VkFormat packedFormat = GetPackedDepthStencilFormat(pDestTexture->Desc()->Format); + EmitCs([ cSrcSlice = slice.slice, cDstImage = image, cDstLayers = dstLayers, cDstLevelExtent = alignedExtent, - cOffset = alignedDestOffset + cOffset = alignedDestOffset, + cPackedFormat = packedFormat ] (DxvkContext* ctx) { - ctx->copyBufferToImage( - cDstImage, cDstLayers, - cOffset, cDstLevelExtent, - cSrcSlice.buffer(), cSrcSlice.offset(), - 1, 1); + if (cDstLayers.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + ctx->copyBufferToImage( + cDstImage, cDstLayers, + cOffset, cDstLevelExtent, + cSrcSlice.buffer(), cSrcSlice.offset(), + 1, 1); + } else { + ctx->copyPackedBufferToDepthStencilImage( + cDstImage, cDstLayers, + VkOffset2D { cOffset.x, cOffset.y }, + VkExtent2D { cDstLevelExtent.width, cDstLevelExtent.height }, + cSrcSlice.buffer(), cSrcSlice.offset(), + VkOffset2D { 0, 0 }, + VkExtent2D { cDstLevelExtent.width, cDstLevelExtent.height }, + cPackedFormat); + } }); TrackTextureMappingBufferSequenceNumber(pSrcTexture, SrcSubresource); From 1a3b576d35327af6a510741322c1bec532e9a6db Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sun, 20 Nov 2022 22:17:51 +0100 Subject: [PATCH 0960/1348] [util] Implement bit vector --- src/util/util_bit.h | 111 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/src/util/util_bit.h b/src/util/util_bit.h index 5f09c31ef..f4bb7a44c 100644 --- a/src/util/util_bit.h +++ b/src/util/util_bit.h @@ -32,6 +32,7 @@ #include #include #include +#include namespace dxvk::bit { @@ -337,6 +338,116 @@ namespace dxvk::bit { }; + class bitvector { + public: + + bool get(uint32_t idx) const { + uint32_t dword = idx / 32; + uint32_t bit = idx % 32; + + return m_dwords[dword] & (1u << bit); + } + + void ensureSize(uint32_t bitCount) { + uint32_t dword = bitCount / 32; + if (unlikely(dword >= m_dwords.size())) { + m_dwords.resize(dword + 1); + } + m_bitCount = std::max(m_bitCount, bitCount); + } + + void set(uint32_t idx, bool value) { + ensureSize(idx + 1); + + uint32_t dword = 0; + uint32_t bit = idx; + + if (value) + m_dwords[dword] |= 1u << bit; + else + m_dwords[dword] &= ~(1u << bit); + } + + bool exchange(uint32_t idx, bool value) { + ensureSize(idx + 1); + + bool oldValue = get(idx); + set(idx, value); + return oldValue; + } + + void flip(uint32_t idx) { + ensureSize(idx + 1); + + uint32_t dword = idx / 32; + uint32_t bit = idx % 32; + + m_dwords[dword] ^= 1u << bit; + } + + void setAll() { + if (m_bitCount % 32 == 0) { + for (size_t i = 0; i < m_dwords.size(); i++) + m_dwords[i] = std::numeric_limits::max(); + } + else { + for (size_t i = 0; i < m_dwords.size() - 1; i++) + m_dwords[i] = std::numeric_limits::max(); + + m_dwords[m_dwords.size() - 1] = (1u << (m_bitCount % 32)) - 1; + } + } + + void clearAll() { + for (size_t i = 0; i < m_dwords.size(); i++) + m_dwords[i] = 0; + } + + bool any() const { + for (size_t i = 0; i < m_dwords.size(); i++) { + if (m_dwords[i] != 0) + return true; + } + + return false; + } + + uint32_t& dword(uint32_t idx) { + return m_dwords[idx]; + } + + size_t bitCount() const { + return m_bitCount; + } + + size_t dwordCount() const { + return m_dwords.size(); + } + + bool operator [] (uint32_t idx) const { + return get(idx); + } + + void setN(uint32_t bits) { + ensureSize(bits); + + uint32_t fullDwords = bits / 32; + uint32_t offset = bits % 32; + + for (size_t i = 0; i < fullDwords; i++) + m_dwords[i] = std::numeric_limits::max(); + + if (offset > 0) + m_dwords[fullDwords] = (1u << offset) - 1; + } + + private: + + std::vector m_dwords; + uint32_t m_bitCount = 0; + + }; + class BitMask { public: From 4796eb0b0dfe1a932a6267c08e8c85831c476dd0 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 21 Nov 2022 00:37:39 +0100 Subject: [PATCH 0961/1348] [d3d9] Implement capturing lights in state blocks --- src/d3d9/d3d9_device.cpp | 7 +++++- src/d3d9/d3d9_stateblock.cpp | 42 ++++++++++++++++++++++++++++++++++++ src/d3d9/d3d9_stateblock.h | 25 ++++++++++++++++++++- 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 6acdedd9a..2a4750c2e 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -1728,7 +1728,7 @@ namespace dxvk { return D3DERR_INVALIDCALL; if (unlikely(ShouldRecord())) { - Logger::warn("D3D9DeviceEx::SetLight: State block not implemented."); + m_recorder->SetLight(Index, pLight); return D3D_OK; } @@ -1762,6 +1762,11 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D9DeviceEx::LightEnable(DWORD Index, BOOL Enable) { D3D9DeviceLock lock = LockDevice(); + if (unlikely(ShouldRecord())) { + m_recorder->LightEnable(Index, Enable); + return D3D_OK; + } + if (unlikely(Index >= m_state.lights.size())) m_state.lights.resize(Index + 1); diff --git a/src/d3d9/d3d9_stateblock.cpp b/src/d3d9/d3d9_stateblock.cpp index 6deca2246..aec477127 100644 --- a/src/d3d9/d3d9_stateblock.cpp +++ b/src/d3d9/d3d9_stateblock.cpp @@ -157,6 +157,46 @@ namespace dxvk { } + HRESULT D3D9StateBlock::SetLight(DWORD Index, const D3DLIGHT9* pLight) { + if (Index >= m_state.lights.size()) + m_state.lights.resize(Index + 1); + + m_state.lights[Index] = *pLight; + + m_captures.flags.set(D3D9CapturedStateFlag::Lights); + return D3D_OK; + } + + + HRESULT D3D9StateBlock::LightEnable(DWORD Index, BOOL Enable) { + if (unlikely(Index >= m_state.lights.size())) + m_state.lights.resize(Index + 1); + + if (unlikely(!m_state.lights[Index])) + m_state.lights[Index] = DefaultLight; + + if (m_state.IsLightEnabled(Index) == !!Enable) + return D3D_OK; + + uint32_t searchIndex = UINT32_MAX; + uint32_t setIndex = Index; + + if (!Enable) + std::swap(searchIndex, setIndex); + + for (auto& idx : m_state.enabledLightIndices) { + if (idx == searchIndex) { + idx = setIndex; + break; + } + } + + m_captures.lightEnabledChanges.set(Index, true); + m_captures.flags.set(D3D9CapturedStateFlag::Lights); + return D3D_OK; + } + + HRESULT D3D9StateBlock::SetStateTransform(uint32_t idx, const D3DMATRIX* pMatrix) { m_state.transforms[idx] = ConvertMatrix(pMatrix); @@ -495,6 +535,8 @@ namespace dxvk { m_captures.flags.set(D3D9CapturedStateFlag::VertexDecl); m_captures.flags.set(D3D9CapturedStateFlag::StreamFreq); + m_captures.flags.set(D3D9CapturedStateFlag::Lights); + m_captures.lightEnabledChanges.setN(m_deviceState->lights.size()); for (uint32_t i = 0; i < caps::MaxStreams; i++) m_captures.streamFreq.set(i, true); diff --git a/src/d3d9/d3d9_stateblock.h b/src/d3d9/d3d9_stateblock.h index 43a712ad6..a098b54fa 100644 --- a/src/d3d9/d3d9_stateblock.h +++ b/src/d3d9/d3d9_stateblock.h @@ -25,7 +25,8 @@ namespace dxvk { StreamFreq, Transforms, TextureStages, - Material + Material, + Lights }; using D3D9CapturedStateFlags = Flags; @@ -61,6 +62,8 @@ namespace dxvk { bit::bitset iConsts; bit::bitset bConsts; } psConsts; + + bit::bitvector lightEnabledChanges; }; enum class D3D9StateBlockType :uint32_t { @@ -120,6 +123,10 @@ namespace dxvk { HRESULT SetMaterial(const D3DMATERIAL9* pMaterial); + HRESULT SetLight(DWORD Index, const D3DLIGHT9* pLight); + + HRESULT LightEnable(DWORD Index, BOOL Enable); + HRESULT SetStateTransform(uint32_t idx, const D3DMATRIX* pMatrix); HRESULT SetStateTextureStageState( @@ -297,6 +304,22 @@ namespace dxvk { dst->SetPixelBoolBitfield(i, m_captures.psConsts.bConsts.dword(i), src->psConsts.bConsts[i]); } } + + if (m_captures.flags.test(D3D9CapturedStateFlag::Lights)) { + for (uint32_t i = 0; i < m_state.lights.size(); i++) { + if (!m_state.lights[i].has_value()) + continue; + + dst->SetLight(i, &m_state.lights[i].value()); + } + for (uint32_t i = 0; i < m_captures.lightEnabledChanges.dwordCount(); i++) { + for (uint32_t consts : bit::BitMask(m_captures.lightEnabledChanges.dword(i))) { + uint32_t idx = i * 32 + consts; + + dst->LightEnable(idx, m_state.IsLightEnabled(idx)); + } + } + } } template From 3b9235fe23e8db2b5d190ad3759ed1efd99cf862 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 21 Nov 2022 17:16:36 +0100 Subject: [PATCH 0962/1348] [util] Set max frame latency to 1 for Sonic Frontiers Seems like the only reason this game passes QA is because there *was* no QA. Seriously broken when GPU-bound even on Windows. --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 4bf6520ba..f3aaed0fa 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -319,6 +319,11 @@ namespace dxvk { { R"(\\BFBC2Game\.exe$)", {{ { "d3d11.floatControls", "False" }, }} }, + /* Sonic Frontiers - flickering shadows and * + * vegetation when GPU-bound */ + { R"(\\SonicFrontiers\.exe$)", {{ + { "dxgi.maxFrameLatency", "1" }, + }} }, /**********************************************/ /* D3D9 GAMES */ From ac10c75ca044a0e85d4f6edf51673540f5e173fc Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 17 Nov 2022 16:45:42 +0000 Subject: [PATCH 0963/1348] [build] Add Josh's libdisplay-info fork for parsing EDIDs This will be used to parse static HDR metadata and chromaticity of the display. Upstream currently has no Windows or MSVC support so use my fork for now. --- .gitmodules | 4 ++++ meson.build | 3 +++ subprojects/libdisplay-info | 1 + 3 files changed, 8 insertions(+) create mode 160000 subprojects/libdisplay-info diff --git a/.gitmodules b/.gitmodules index 91895ae2e..66196752d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,7 @@ [submodule "include/spirv"] path = include/spirv url = https://github.com/KhronosGroup/SPIRV-Headers.git +[submodule "subprojects/libdisplay-info"] + path = subprojects/libdisplay-info + url = https://gitlab.freedesktop.org/JoshuaAshton/libdisplay-info + branch = windows diff --git a/meson.build b/meson.build index e417ff67e..12d37300a 100644 --- a/meson.build +++ b/meson.build @@ -39,6 +39,9 @@ dxvk_include_dirs = [ './include/spirv/include' ] +proj_displayinfo = subproject('libdisplay-info') +dep_displayinfo = proj_displayinfo.get_variable('di_dep') + if platform == 'windows' compiler_args += [ '-DNOMINMAX', diff --git a/subprojects/libdisplay-info b/subprojects/libdisplay-info new file mode 160000 index 000000000..3b2e9f6b7 --- /dev/null +++ b/subprojects/libdisplay-info @@ -0,0 +1 @@ +Subproject commit 3b2e9f6b76aa8d0c413c93202e93816517d781bd From fabe4a85e310827fedb8092129d1f53f2882c883 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 17 Nov 2022 17:07:50 +0000 Subject: [PATCH 0964/1348] [wsi] Add parseColorimetryInfo helper --- src/wsi/meson.build | 12 +++++--- src/wsi/wsi_edid.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++ src/wsi/wsi_edid.h | 38 +++++++++++++++++++++++ src/wsi/wsi_monitor.h | 4 +-- 4 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 src/wsi/wsi_edid.cpp create mode 100644 src/wsi/wsi_edid.h diff --git a/src/wsi/meson.build b/src/wsi/meson.build index a7442dfb4..17efa26b2 100644 --- a/src/wsi/meson.build +++ b/src/wsi/meson.build @@ -1,3 +1,7 @@ +wsi_common_src = [ + 'wsi_edid.cpp', +] + wsi_win32_src = [ 'win32/wsi_monitor_win32.cpp', 'win32/wsi_window_win32.cpp', @@ -9,11 +13,11 @@ wsi_sdl2_src = [ ] if dxvk_wsi == 'win32' - wsi_src = wsi_win32_src - wsi_deps = [] + wsi_src = wsi_common_src + wsi_win32_src + wsi_deps = [ dep_displayinfo ] elif dxvk_wsi == 'sdl2' - wsi_src = wsi_sdl2_src - wsi_deps = [ lib_sdl2 ] + wsi_src = wsi_common_src + wsi_sdl2_src + wsi_deps = [ dep_displayinfo, lib_sdl2 ] else error('Unknown wsi') endif diff --git a/src/wsi/wsi_edid.cpp b/src/wsi/wsi_edid.cpp new file mode 100644 index 000000000..01741b91c --- /dev/null +++ b/src/wsi/wsi_edid.cpp @@ -0,0 +1,72 @@ +extern "C" { +#include "libdisplay-info/info.h" +#include "libdisplay-info/edid.h" +#include "libdisplay-info/cta.h" +} + +#include "wsi_edid.h" + +#include "../util/util_string.h" +#include "../util/log/log.h" + +namespace dxvk::wsi { + + std::optional parseColorimetryInfo( + const WsiEdidData& edidData) { + WsiDisplayMetadata metadata = {}; + + di_info* info = di_info_parse_edid(edidData.data(), edidData.size()); + if (!info) { + Logger::err(str::format("wsi: parseColorimetryInfo: Failed to get parse edid. Reason: ", di_info_get_failure_msg(info))); + return std::nullopt; + } + + const di_edid* edid = di_info_get_edid(info); + + const di_edid_chromaticity_coords* chroma = di_edid_get_chromaticity_coords(edid); + const di_cta_hdr_static_metadata_block* hdr_static_metadata = nullptr; + const di_cta_colorimetry_block* colorimetry = nullptr; + + const di_edid_cta* cta = nullptr; + const di_edid_ext* const* exts = di_edid_get_extensions(edid); + for (; *exts != nullptr; exts++) { + if ((cta = di_edid_ext_get_cta(*exts))) + break; + } + + if (cta) { + const di_cta_data_block* const* blocks = di_edid_cta_get_data_blocks(cta); + for (; *blocks != nullptr; blocks++) { + if ((hdr_static_metadata = di_cta_data_block_get_hdr_static_metadata(*blocks))) + continue; + if ((colorimetry = di_cta_data_block_get_colorimetry(*blocks))) + continue; + } + } + + if (chroma) { + metadata.redPrimary[0] = chroma->red_x; + metadata.redPrimary[1] = chroma->red_y; + metadata.greenPrimary[0] = chroma->green_x; + metadata.greenPrimary[1] = chroma->green_y; + metadata.bluePrimary[0] = chroma->blue_x; + metadata.bluePrimary[1] = chroma->blue_y; + metadata.whitePoint[0] = chroma->white_x; + metadata.whitePoint[1] = chroma->white_y; + } + + if (hdr_static_metadata) { + metadata.maxFullFrameLuminance = hdr_static_metadata->desired_content_max_frame_avg_luminance; + metadata.minLuminance = hdr_static_metadata->desired_content_min_luminance; + metadata.maxLuminance = hdr_static_metadata->desired_content_max_luminance; + } + + metadata.supportsST2084 = + chroma && + colorimetry && colorimetry->bt2020_rgb && + hdr_static_metadata && hdr_static_metadata->eotfs && hdr_static_metadata->eotfs->pq; + + return metadata; + } + +} \ No newline at end of file diff --git a/src/wsi/wsi_edid.h b/src/wsi/wsi_edid.h new file mode 100644 index 000000000..04bf239d0 --- /dev/null +++ b/src/wsi/wsi_edid.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include + +namespace dxvk::wsi { + + /** + * \brief Edid blob + */ + using WsiEdidData = std::vector; + + /** + * \brief Display colorimetry info + */ + struct WsiDisplayMetadata { + bool supportsST2084; + + float redPrimary[2]; + float greenPrimary[2]; + float bluePrimary[2]; + float whitePoint[2]; + float minLuminance; + float maxLuminance; + float maxFullFrameLuminance; + }; + + /** + * \brief Parse colorimetry info from the EDID + * + * \param [in] edidData The edid blob + * \returns The display metadata + colorimetry info + */ + std::optional parseColorimetryInfo( + const WsiEdidData& edidData); + +} diff --git a/src/wsi/wsi_monitor.h b/src/wsi/wsi_monitor.h index 84c00b087..ef542fed4 100644 --- a/src/wsi/wsi_monitor.h +++ b/src/wsi/wsi_monitor.h @@ -6,6 +6,8 @@ #include #include +#include "wsi_edid.h" + namespace dxvk::wsi { /** @@ -125,8 +127,6 @@ namespace dxvk::wsi { *pHeight = rect.bottom - rect.top; } - using WsiEdidData = std::vector; - /** * \brief Get the EDID of a monitor * From aa71e7e323f80ff20e87ccb9d8a94b5fb1047179 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 17 Nov 2022 17:21:38 +0000 Subject: [PATCH 0965/1348] [dxgi] Cache display metadata + colorimetry in DXGI_VK_MONITOR_DATA --- src/dxgi/dxgi_interfaces.h | 3 ++ src/dxgi/dxgi_output.cpp | 67 ++++++++++++++++++++++++++++---------- src/dxgi/dxgi_output.h | 4 +++ 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index 66d517a88..f297e5c36 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -2,6 +2,8 @@ #include "../dxvk/dxvk_include.h" +#include "../wsi/wsi_edid.h" + #include "../util/util_time.h" #include "dxgi_format.h" @@ -27,6 +29,7 @@ struct DXGI_VK_MONITOR_DATA { DXGI_FRAME_STATISTICS FrameStats; DXGI_GAMMA_CONTROL GammaCurve; DXGI_MODE_DESC1 LastMode; + dxvk::wsi::WsiDisplayMetadata DisplayMetadata; }; diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index 23ef7369c..e319b30a1 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -27,23 +27,7 @@ namespace dxvk { : m_monitorInfo(factory->GetMonitorInfo()), m_adapter(adapter), m_monitor(monitor) { - // Query current display mode - wsi::WsiMode activeWsiMode = { }; - wsi::getCurrentDisplayMode(m_monitor, &activeWsiMode); - - // Init monitor info if necessary - DXGI_VK_MONITOR_DATA monitorData = { }; - monitorData.FrameStats.SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter(); - monitorData.GammaCurve.Scale = { 1.0f, 1.0f, 1.0f }; - monitorData.GammaCurve.Offset = { 0.0f, 0.0f, 0.0f }; - monitorData.LastMode = ConvertDisplayMode(activeWsiMode); - - for (uint32_t i = 0; i < DXGI_VK_GAMMA_CP_COUNT; i++) { - const float value = GammaControlPointLocation(i); - monitorData.GammaCurve.GammaCurve[i] = { value, value, value }; - } - - m_monitorInfo->InitMonitorData(monitor, &monitorData); + CacheMonitorData(); } @@ -637,4 +621,53 @@ namespace dxvk { } } + + void DxgiOutput::CacheMonitorData() { + // Try and find an existing monitor info. + DXGI_VK_MONITOR_DATA* pMonitorData; + if (SUCCEEDED(m_monitorInfo->AcquireMonitorData(m_monitor, &pMonitorData))) { + m_metadata = pMonitorData->DisplayMetadata; + return; + } + + // Init monitor info ourselves. + // + // If some other thread ends up beating us to it + // by another InitMonitorData, it doesn't really matter. + // + // The only thing we cache from this is the m_metadata which + // should be exactly the same. + // We don't store any pointers from the DXGI_VK_MONITOR_DATA + // sturcture, etc. + DXGI_VK_MONITOR_DATA monitorData = {}; + + // Query current display mode + wsi::WsiMode activeWsiMode = { }; + wsi::getCurrentDisplayMode(m_monitor, &activeWsiMode); + + // Get the display metadata + colorimetry + wsi::WsiEdidData edidData = wsi::getMonitorEdid(m_monitor); + std::optional metadata = std::nullopt; + if (!edidData.empty()) + metadata = wsi::parseColorimetryInfo(edidData); + + if (metadata) + m_metadata = metadata.value(); + else + Logger::err("DXGI: Failed to parse display metadata + colorimetry info, using blank."); + + monitorData.FrameStats.SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter(); + monitorData.GammaCurve.Scale = { 1.0f, 1.0f, 1.0f }; + monitorData.GammaCurve.Offset = { 0.0f, 0.0f, 0.0f }; + monitorData.LastMode = ConvertDisplayMode(activeWsiMode); + monitorData.DisplayMetadata = m_metadata; + + for (uint32_t i = 0; i < DXGI_VK_GAMMA_CP_COUNT; i++) { + const float value = GammaControlPointLocation(i); + monitorData.GammaCurve.GammaCurve[i] = { value, value, value }; + } + + m_monitorInfo->InitMonitorData(m_monitor, &monitorData); + } + } diff --git a/src/dxgi/dxgi_output.h b/src/dxgi/dxgi_output.h index 0dc30868d..b0f15fa72 100644 --- a/src/dxgi/dxgi_output.h +++ b/src/dxgi/dxgi_output.h @@ -133,10 +133,14 @@ namespace dxvk { Com m_adapter = nullptr; HMONITOR m_monitor = nullptr; + wsi::WsiDisplayMetadata m_metadata = {}; + static void FilterModesByDesc( std::vector& Modes, const DXGI_MODE_DESC1& TargetMode); + void CacheMonitorData(); + }; } From f0a0e1b964d47212df9fa6b7c24ae64056f6486c Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 17 Nov 2022 17:22:22 +0000 Subject: [PATCH 0966/1348] [dxgi] Report display metadata in IDXGIOutput6::GetDesc1 --- src/dxgi/dxgi_output.cpp | 46 +++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index e319b30a1..21db7137d 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -215,23 +215,35 @@ namespace dxvk { return E_FAIL; } - pDesc->AttachedToDesktop = 1; - pDesc->Rotation = DXGI_MODE_ROTATION_UNSPECIFIED; - pDesc->Monitor = m_monitor; - pDesc->BitsPerColor = 8; - pDesc->ColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; - - // We don't really have a way to get these - for (uint32_t i = 0; i < 2; i++) { - pDesc->RedPrimary[i] = 0.0f; - pDesc->GreenPrimary[i] = 0.0f; - pDesc->BluePrimary[i] = 0.0f; - pDesc->WhitePoint[i] = 0.0f; - } - - pDesc->MinLuminance = 0.0f; - pDesc->MaxLuminance = 0.0f; - pDesc->MaxFullFrameLuminance = 0.0f; + pDesc->AttachedToDesktop = 1; + pDesc->Rotation = DXGI_MODE_ROTATION_UNSPECIFIED; + pDesc->Monitor = m_monitor; + // TODO: When in HDR, flip this to 10 to appease apps that the + // transition has occured. + // If we support more than HDR10 in future, then we may want + // to visit that assumption. + pDesc->BitsPerColor = 8; + // This should only return DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 + // (HDR) if the user has the HDR setting enabled in Windows. + // Games can still punt into HDR mode by using CheckColorSpaceSupport + // and SetColorSpace1. + // + // TODO: When we have a swapchain using SetColorSpace1 to + // DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020, we should use our monitor + // info to flip this over to that. + // As on Windows this would automatically engage HDR mode. + pDesc->ColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; + pDesc->RedPrimary[0] = m_metadata.redPrimary[0]; + pDesc->RedPrimary[1] = m_metadata.redPrimary[1]; + pDesc->GreenPrimary[0] = m_metadata.greenPrimary[0]; + pDesc->GreenPrimary[1] = m_metadata.greenPrimary[1]; + pDesc->BluePrimary[0] = m_metadata.bluePrimary[0]; + pDesc->BluePrimary[1] = m_metadata.bluePrimary[1]; + pDesc->WhitePoint[0] = m_metadata.whitePoint[0]; + pDesc->WhitePoint[1] = m_metadata.whitePoint[1]; + pDesc->MinLuminance = m_metadata.minLuminance; + pDesc->MaxLuminance = m_metadata.maxLuminance; + pDesc->MaxFullFrameLuminance = m_metadata.maxFullFrameLuminance; return S_OK; } From c6611dffa7ba7aef5868b29bcac6ec1d79b7184b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 21 Nov 2022 19:35:21 +0100 Subject: [PATCH 0967/1348] Revert "[dxbc] Move shex check to constructor" Breaks stuff for unknown reasons. --- src/dxbc/dxbc_module.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/dxbc/dxbc_module.cpp b/src/dxbc/dxbc_module.cpp index 53293e4a9..d406bf292 100644 --- a/src/dxbc/dxbc_module.cpp +++ b/src/dxbc/dxbc_module.cpp @@ -32,9 +32,6 @@ namespace dxvk { if ((tag == "PCSG") || (tag == "PSG1")) m_psgnChunk = new DxbcIsgn(chunkReader, tag); } - - if (m_shexChunk == nullptr) - throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk"); } @@ -46,6 +43,8 @@ namespace dxvk { Rc DxbcModule::compile( const DxbcModuleInfo& moduleInfo, const std::string& fileName) const { + if (m_shexChunk == nullptr) + throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk"); DxbcAnalysisInfo analysisInfo; @@ -71,6 +70,9 @@ namespace dxvk { Rc DxbcModule::compilePassthroughShader( const DxbcModuleInfo& moduleInfo, const std::string& fileName) const { + if (m_shexChunk == nullptr) + throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk"); + DxbcAnalysisInfo analysisInfo; DxbcCompiler compiler( From ebd29007d4a2aff20f0dc89e4c96d8795e87cb56 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 21 Nov 2022 20:24:15 +0100 Subject: [PATCH 0968/1348] [dxgi] Actually unlock monitor info Fixes some deadlocks. --- src/dxgi/dxgi_output.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index 21db7137d..1b4db77b8 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -639,6 +639,7 @@ namespace dxvk { DXGI_VK_MONITOR_DATA* pMonitorData; if (SUCCEEDED(m_monitorInfo->AcquireMonitorData(m_monitor, &pMonitorData))) { m_metadata = pMonitorData->DisplayMetadata; + m_monitorInfo->ReleaseMonitorData(); return; } From d01c9cb6d45a2d02be633b627e07852e98cad570 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 25 Nov 2022 06:20:55 +0000 Subject: [PATCH 0969/1348] [wsi] Free edid info after parsing --- src/wsi/wsi_edid.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wsi/wsi_edid.cpp b/src/wsi/wsi_edid.cpp index 01741b91c..792f19aac 100644 --- a/src/wsi/wsi_edid.cpp +++ b/src/wsi/wsi_edid.cpp @@ -66,6 +66,8 @@ namespace dxvk::wsi { colorimetry && colorimetry->bt2020_rgb && hdr_static_metadata && hdr_static_metadata->eotfs && hdr_static_metadata->eotfs->pq; + di_info_destroy(info); + return metadata; } From 4f90d7bf5f9ad785660507e0cb459a14dab5ac75 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 21 Nov 2022 19:49:08 +0100 Subject: [PATCH 0970/1348] [dxbc,d3d11] Don't access shex chunk if it is not defined --- src/d3d11/d3d11_shader.cpp | 17 +++++++++++------ src/dxbc/dxbc_module.h | 5 ++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/d3d11/d3d11_shader.cpp b/src/d3d11/d3d11_shader.cpp index 3d6a0642d..3753c075e 100644 --- a/src/d3d11/d3d11_shader.cpp +++ b/src/d3d11/d3d11_shader.cpp @@ -20,8 +20,6 @@ namespace dxvk { reinterpret_cast(pShaderBytecode), BytecodeLength); - DxbcModule module(reader); - // If requested by the user, dump both the raw DXBC // shader and the compiled SPIR-V module to a file. const std::string& dumpPath = pDevice->GetOptions()->shaderDumpPath; @@ -30,14 +28,21 @@ namespace dxvk { reader.store(std::ofstream(str::topath(str::format(dumpPath, "/", name, ".dxbc").c_str()).c_str(), std::ios_base::binary | std::ios_base::trunc)); } - + + // Error out if the shader is invalid + DxbcModule module(reader); + auto programInfo = module.programInfo(); + + if (!programInfo) + throw DxvkError("Invalid shader binary."); + // Decide whether we need to create a pass-through // geometry shader for vertex shader stream output bool passthroughShader = pDxbcModuleInfo->xfb != nullptr - && (module.programInfo().type() == DxbcProgramType::VertexShader - || module.programInfo().type() == DxbcProgramType::DomainShader); + && (programInfo->type() == DxbcProgramType::VertexShader + || programInfo->type() == DxbcProgramType::DomainShader); - if (module.programInfo().shaderStage() != pShaderKey->type() && !passthroughShader) + if (programInfo->shaderStage() != pShaderKey->type() && !passthroughShader) throw DxvkError("Mismatching shader type."); m_shader = passthroughShader diff --git a/src/dxbc/dxbc_module.h b/src/dxbc/dxbc_module.h index d785d9599..7609e2322 100644 --- a/src/dxbc/dxbc_module.h +++ b/src/dxbc/dxbc_module.h @@ -35,7 +35,10 @@ namespace dxvk { * \brief Shader type * \returns Shader type */ - DxbcProgramInfo programInfo() const { + std::optional programInfo() const { + if (m_shexChunk == nullptr) + return std::nullopt; + return m_shexChunk->programInfo(); } From 64cb1ad208f80b11400eef779e99fec223754098 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 25 Nov 2022 14:26:19 +0100 Subject: [PATCH 0971/1348] [meta] Remove setup script --- README.md | 21 ++--- setup_dxvk.sh | 206 -------------------------------------------------- 2 files changed, 6 insertions(+), 221 deletions(-) delete mode 100755 setup_dxvk.sh diff --git a/README.md b/README.md index 153a10041..a07c68b3b 100644 --- a/README.md +++ b/README.md @@ -9,26 +9,17 @@ The most recent development builds can be found [here](https://github.com/doitsu Release builds can be found [here](https://github.com/doitsujin/dxvk/releases). ## How to use -In order to install a DXVK package obtained from the [release](https://github.com/doitsujin/dxvk/releases) page into a given wine prefix, run the following commands from within the DXVK directory: - +In order to install a DXVK package obtained from the [release](https://github.com/doitsujin/dxvk/releases) page into a given wine prefix, copy or symlink the DLLs into the following directories as follows, then open `winecfg` and manually add DLL overrides for `d3d11`, `d3d10core`, `dxgi`, and `d3d9`: ``` -export WINEPREFIX=/path/to/.wine-prefix -./setup_dxvk.sh install +WINEPREFIX=/path/to/wineprefix +cp x64/*.dll $WINEPREFIX/drive_c/system32 +cp x32/*.dll $WINEPREFIX/drive_c/syswow64 +winecfg ``` -This will **copy** the DLLs into the `system32` and `syswow64` directories of your wine prefix and set up the required DLL overrides. Pure 32-bit prefixes are also supported. - -The setup script optionally takes the following arguments: -- `--symlink`: Create symbolic links to the DLL files instead of copying them. This is especially useful for development. -- `--without-dxgi`: Do not install DXVK's DXGI implementation and use the one provided by wine instead. - Verify that your application uses DXVK instead of wined3d by checking for the presence of the log file `d3d9.log` or `d3d11.log` in the application's directory, or by enabling the HUD (see notes below). -In order to remove DXVK from a prefix, run the following command: -``` -export WINEPREFIX=/path/to/.wine-prefix -./setup_dxvk.sh uninstall -``` +In order to remove DXVK from a prefix, remove the DLLs and DLL overrides, and run `wineboot -u` to restore the original DLL files. ## Build instructions diff --git a/setup_dxvk.sh b/setup_dxvk.sh deleted file mode 100755 index 0f1998f30..000000000 --- a/setup_dxvk.sh +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env bash - -# default directories -dxvk_lib32=${dxvk_lib32:-"x32"} -dxvk_lib64=${dxvk_lib64:-"x64"} - -# figure out where we are -basedir="$(dirname "$(readlink -f "$0")")" - -# figure out which action to perform -action="$1" - -case "$action" in -install) - ;; -uninstall) - ;; -*) - echo "Unrecognized action: $action" - echo "Usage: $0 [install|uninstall] [--without-dxgi] [--symlink]" - exit 1 -esac - -# process arguments -shift - -with_dxgi=true -file_cmd="cp -v --reflink=auto" - -while (($# > 0)); do - case "$1" in - "--without-dxgi") - with_dxgi=false - ;; - "--symlink") - file_cmd="ln -s -v" - ;; - esac - shift -done - -# check wine prefix before invoking wine, so that we -# don't accidentally create one if the user screws up -if [ -n "$WINEPREFIX" ] && ! [ -f "$WINEPREFIX/system.reg" ]; then - echo "$WINEPREFIX:"' Not a valid wine prefix.' >&2 - exit 1 -fi - -# find wine executable -export WINEDEBUG=-all -# disable mscoree and mshtml to avoid downloading -# wine gecko and mono -export WINEDLLOVERRIDES="mscoree,mshtml=" - -wine="wine" -wine64="wine64" -wineboot="wineboot" - -# $PATH is the way for user to control where wine is located (including custom Wine versions). -# Pure 64-bit Wine (non Wow64) requries skipping 32-bit steps. -# In such case, wine64 and winebooot will be present, but wine binary will be missing, -# however it can be present in other PATHs, so it shouldn't be used, to avoid versions mixing. -wine_path=$(dirname "$(which $wineboot)") -wow64=true -if ! [ -f "$wine_path/$wine" ]; then - wine=$wine64 - wow64=false -fi - -# resolve 32-bit and 64-bit system32 path -winever=$($wine --version | grep wine) -if [ -z "$winever" ]; then - echo "$wine:"' Not a wine executable. Check your $wine.' >&2 - exit 1 -fi - -# ensure wine placeholder dlls are recreated -# if they are missing -$wineboot -u - -win64_sys_path=$($wine64 winepath -u 'C:\windows\system32' 2> /dev/null) -win64_sys_path="${win64_sys_path/$'\r'/}" -if $wow64; then - win32_sys_path=$($wine winepath -u 'C:\windows\system32' 2> /dev/null) - win32_sys_path="${win32_sys_path/$'\r'/}" -fi - -if [ -z "$win32_sys_path" ] && [ -z "$win64_sys_path" ]; then - echo 'Failed to resolve C:\windows\system32.' >&2 - exit 1 -fi - -# create native dll override -overrideDll() { - $wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v $1 /d native /f >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo -e "Failed to add override for $1" - exit 1 - fi -} - -# remove dll override -restoreDll() { - $wine reg delete 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v $1 /f > /dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "Failed to remove override for $1" - fi -} - -# copy or link dxvk dll, back up original file -installFile() { - dstfile="${1}/${3}.dll" - srcfile="${basedir}/${2}/${3}.dll" - - if [ -f "${srcfile}.so" ]; then - srcfile="${srcfile}.so" - fi - - if ! [ -f "${srcfile}" ]; then - echo "${srcfile}: File not found. Skipping." >&2 - return 1 - fi - - if [ -n "$1" ]; then - if [ -f "${dstfile}" ] || [ -h "${dstfile}" ]; then - if ! [ -f "${dstfile}.old" ]; then - mv -v "${dstfile}" "${dstfile}.old" - else - rm -v "${dstfile}" - fi - $file_cmd "${srcfile}" "${dstfile}" - else - echo "${dstfile}: File not found in wine prefix" >&2 - return 1 - fi - fi - return 0 -} - -# remove dxvk dll, restore original file -uninstallFile() { - dstfile="${1}/${3}.dll" - srcfile="${basedir}/${2}/${3}.dll" - - if [ -f "${srcfile}.so" ]; then - srcfile="${srcfile}.so" - fi - - if ! [ -f "${srcfile}" ]; then - echo "${srcfile}: File not found. Skipping." >&2 - return 1 - fi - - if ! [ -f "${dstfile}" ] && ! [ -h "${dstfile}" ]; then - echo "${dstfile}: File not found. Skipping." >&2 - return 1 - fi - - if [ -f "${dstfile}.old" ]; then - rm -v "${dstfile}" - mv -v "${dstfile}.old" "${dstfile}" - return 0 - else - return 1 - fi -} - -install() { - installFile "$win64_sys_path" "$dxvk_lib64" "$1" - inst64_ret="$?" - - inst32_ret=-1 - if $wow64; then - installFile "$win32_sys_path" "$dxvk_lib32" "$1" - inst32_ret="$?" - fi - - if (( ($inst32_ret == 0) || ($inst64_ret == 0) )); then - overrideDll "$1" - fi -} - -uninstall() { - uninstallFile "$win64_sys_path" "$dxvk_lib64" "$1" - uninst64_ret="$?" - - uninst32_ret=-1 - if $wow64; then - uninstallFile "$win32_sys_path" "$dxvk_lib32" "$1" - uninst32_ret="$?" - fi - - if (( ($uninst32_ret == 0) || ($uninst64_ret == 0) )); then - restoreDll "$1" - fi -} - -# skip dxgi during install if not explicitly -# enabled, but always try to uninstall it -if $with_dxgi || [ "$action" == "uninstall" ]; then - $action dxgi -fi - -$action d3d9 -$action d3d10core -$action d3d11 From 57176e77ea8a14620f908ef4dd5c14a5e0115581 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 25 Nov 2022 14:51:52 +0100 Subject: [PATCH 0972/1348] [meta] Don't try to package setup script in a release tarball --- package-release.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/package-release.sh b/package-release.sh index cedec2d84..f614b8a08 100755 --- a/package-release.sh +++ b/package-release.sh @@ -76,11 +76,6 @@ function build_arch { fi } -function build_script { - cp "$DXVK_SRC_DIR/setup_dxvk.sh" "$DXVK_BUILD_DIR/setup_dxvk.sh" - chmod +x "$DXVK_BUILD_DIR/setup_dxvk.sh" -} - function package { cd "$DXVK_BUILD_DIR/.." tar -czf "$DXVK_ARCHIVE_PATH" "dxvk-$DXVK_VERSION" @@ -89,7 +84,6 @@ function package { build_arch 64 build_arch 32 -build_script if [ $opt_nopackage -eq 0 ]; then package From 7644776f7a3bc6a097f20c1465708acf88ad215f Mon Sep 17 00:00:00 2001 From: wael <40663@proton.me> Date: Sat, 26 Nov 2022 09:41:08 +0300 Subject: [PATCH 0973/1348] README: fix wine dll path --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a07c68b3b..2897017b9 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ Release builds can be found [here](https://github.com/doitsujin/dxvk/releases). In order to install a DXVK package obtained from the [release](https://github.com/doitsujin/dxvk/releases) page into a given wine prefix, copy or symlink the DLLs into the following directories as follows, then open `winecfg` and manually add DLL overrides for `d3d11`, `d3d10core`, `dxgi`, and `d3d9`: ``` WINEPREFIX=/path/to/wineprefix -cp x64/*.dll $WINEPREFIX/drive_c/system32 -cp x32/*.dll $WINEPREFIX/drive_c/syswow64 +cp x64/*.dll $WINEPREFIX/drive_c/windows/system32 +cp x32/*.dll $WINEPREFIX/drive_c/windows/syswow64 winecfg ``` From 42332f7fb8cfceecaf92466c201435e9238acf86 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Mon, 28 Nov 2022 12:20:37 +0100 Subject: [PATCH 0974/1348] [dxgi] Fix IDXGISwapchain::CheckColorSpaceSuport --- src/dxgi/dxgi_swapchain.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 8fe029a1a..de3547cba 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -523,7 +523,9 @@ namespace dxvk { if (!pColorSpaceSupport) return E_INVALIDARG; - return m_presenter->CheckColorSpaceSupport(ColorSpace); + UINT support = m_presenter->CheckColorSpaceSupport(ColorSpace); + *pColorSpaceSupport = support; + return S_OK; } From 9f7066677731e9a7ef2fa16cf85e36fd32c3313a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 28 Nov 2022 13:45:37 +0100 Subject: [PATCH 0975/1348] [build] Allow standalone DXGI builds --- src/meson.build | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/meson.build b/src/meson.build index f641ac046..779d9d46f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,9 +5,6 @@ subdir('vulkan') subdir('dxvk') if get_option('enable_dxgi') - if not get_option('enable_d3d11') - error('D3D11 is required for DXGI.') - endif subdir('dxgi') endif @@ -16,6 +13,9 @@ if get_option('enable_d3d10') or get_option('enable_d3d11') endif if get_option('enable_d3d11') + if not get_option('enable_dxgi') + error('DXGI is required for D3D11.') + endif subdir('d3d11') endif @@ -32,6 +32,6 @@ if get_option('enable_d3d9') endif # Nothing selected -if not get_option('enable_d3d9') and not get_option('enable_d3d10') and not get_option('enable_d3d11') +if not get_option('enable_d3d9') and not get_option('enable_dxgi') warning('Nothing selected to be built.?') endif From 573be24269d57805dee36881950767241d815c51 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 1 Dec 2022 20:03:13 +0100 Subject: [PATCH 0976/1348] [wsi] Fix crash when parsing EDID fails If info is null then we shouldn't pass it around. Also improve formatting a bit. --- src/wsi/wsi_edid.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/wsi/wsi_edid.cpp b/src/wsi/wsi_edid.cpp index 792f19aac..6a716a037 100644 --- a/src/wsi/wsi_edid.cpp +++ b/src/wsi/wsi_edid.cpp @@ -16,8 +16,9 @@ namespace dxvk::wsi { WsiDisplayMetadata metadata = {}; di_info* info = di_info_parse_edid(edidData.data(), edidData.size()); + if (!info) { - Logger::err(str::format("wsi: parseColorimetryInfo: Failed to get parse edid. Reason: ", di_info_get_failure_msg(info))); + Logger::err(str::format("wsi: parseColorimetryInfo: Failed to get parse edid.")); return std::nullopt; } @@ -28,15 +29,14 @@ namespace dxvk::wsi { const di_cta_colorimetry_block* colorimetry = nullptr; const di_edid_cta* cta = nullptr; - const di_edid_ext* const* exts = di_edid_get_extensions(edid); - for (; *exts != nullptr; exts++) { + + for (auto exts = di_edid_get_extensions(edid); *exts != nullptr; exts++) { if ((cta = di_edid_ext_get_cta(*exts))) break; } if (cta) { - const di_cta_data_block* const* blocks = di_edid_cta_get_data_blocks(cta); - for (; *blocks != nullptr; blocks++) { + for (auto blocks = di_edid_cta_get_data_blocks(cta); *blocks != nullptr; blocks++) { if ((hdr_static_metadata = di_cta_data_block_get_hdr_static_metadata(*blocks))) continue; if ((colorimetry = di_cta_data_block_get_colorimetry(*blocks))) @@ -61,13 +61,10 @@ namespace dxvk::wsi { metadata.maxLuminance = hdr_static_metadata->desired_content_max_luminance; } - metadata.supportsST2084 = - chroma && - colorimetry && colorimetry->bt2020_rgb && + metadata.supportsST2084 = chroma && colorimetry && colorimetry->bt2020_rgb && hdr_static_metadata && hdr_static_metadata->eotfs && hdr_static_metadata->eotfs->pq; di_info_destroy(info); - return metadata; } From 522909b16553c03112e0ec42701766ccfc0d7747 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sat, 3 Dec 2022 16:00:47 +0100 Subject: [PATCH 0977/1348] [d3d9] Don't set NeedsReadback when dirtying mip maps It's impossible to lock non 0 mips anyway. --- src/d3d9/d3d9_device.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 2a4750c2e..b882fcc4d 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5460,7 +5460,6 @@ namespace dxvk { void D3D9DeviceEx::MarkTextureMipsDirty(D3D9CommonTexture* pResource) { pResource->SetNeedsMipGen(true); - pResource->MarkAllNeedReadback(); for (uint32_t i : bit::BitMask(m_activeTextures)) { // Guaranteed to not be nullptr... From 4a4d880130c7e3fa2cb2b264a38a09df9e9d42b7 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sun, 4 Dec 2022 22:35:45 +0100 Subject: [PATCH 0978/1348] [util] Set TRAHA Global to Intel vendor id --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index f3aaed0fa..b69cac47c 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -324,6 +324,11 @@ namespace dxvk { { R"(\\SonicFrontiers\.exe$)", {{ { "dxgi.maxFrameLatency", "1" }, }} }, + /* TRAHA Global * + * Shadow issues when it sees AMD/Nvidia */ + { R"(\\RapaNui-Win64-Shipping\.exe$)", {{ + { "dxgi.customVendorId", "8086" }, + }} }, /**********************************************/ /* D3D9 GAMES */ From b838b65516bfb17e8ebe745f2a970e98973375b3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 6 Dec 2022 22:15:13 +0100 Subject: [PATCH 0979/1348] [d3d9] Correctly mask alpha reference push constant We accidentally lost this during the rework, since the initial implementation scaled the alpha ref value on the CPU. Fixes #3123. --- src/d3d9/d3d9_device.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index b882fcc4d..b5be3db88 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5187,7 +5187,7 @@ namespace dxvk { auto& rs = m_state.renderStates; if constexpr (Item == D3D9RenderStateItem::AlphaRef) { - uint32_t alpha = rs[D3DRS_ALPHAREF]; + uint32_t alpha = rs[D3DRS_ALPHAREF] & 0xFF; UpdatePushConstant(&alpha); } else if constexpr (Item == D3D9RenderStateItem::FogColor) { From 858452a0bdb8def9c1f93b103026e71835a8df1f Mon Sep 17 00:00:00 2001 From: bno1 Date: Tue, 6 Dec 2022 23:02:04 +0200 Subject: [PATCH 0980/1348] [build] Fix submodule url for libdisplay-info --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 66196752d..25deda64b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,5 +9,5 @@ url = https://github.com/KhronosGroup/SPIRV-Headers.git [submodule "subprojects/libdisplay-info"] path = subprojects/libdisplay-info - url = https://gitlab.freedesktop.org/JoshuaAshton/libdisplay-info + url = https://gitlab.freedesktop.org/JoshuaAshton/libdisplay-info.git branch = windows From c0d843c5788448ed66d61246c6ad8453c41c87fd Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Thu, 8 Dec 2022 06:05:19 +0000 Subject: [PATCH 0981/1348] [wsi] Fix overwriting colorimetry info to NULL --- src/wsi/wsi_edid.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wsi/wsi_edid.cpp b/src/wsi/wsi_edid.cpp index 6a716a037..b9ed9fd94 100644 --- a/src/wsi/wsi_edid.cpp +++ b/src/wsi/wsi_edid.cpp @@ -37,9 +37,9 @@ namespace dxvk::wsi { if (cta) { for (auto blocks = di_edid_cta_get_data_blocks(cta); *blocks != nullptr; blocks++) { - if ((hdr_static_metadata = di_cta_data_block_get_hdr_static_metadata(*blocks))) + if (!hdr_static_metadata && (hdr_static_metadata = di_cta_data_block_get_hdr_static_metadata(*blocks))) continue; - if ((colorimetry = di_cta_data_block_get_colorimetry(*blocks))) + if (!colorimetry && (colorimetry = di_cta_data_block_get_colorimetry(*blocks))) continue; } } From 7b2024888ea326230f2628bce6429538dcdaa31d Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Mon, 28 Nov 2022 15:08:27 +0100 Subject: [PATCH 0982/1348] [util] disable unmapping for Final Fantasy XIV d3d9 --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index b69cac47c..d7e69778a 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -686,6 +686,11 @@ namespace dxvk { { R"(\\bms\.exe$)", {{ { "d3d9.customVendorId", "10de" }, }} }, + /* Final Fantasy XIV - Direct3D 9 mode * + * Can crash with unmapping */ + { R"(\\ffxiv\.exe$)", {{ + { "d3d9.textureMemory", "0" }, + }} }, }}; From c55c09368b8e7d878cbe602b6d380ba0d1e6e1b3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 11 Dec 2022 19:28:37 +0100 Subject: [PATCH 0983/1348] [d3d11] Only store low 8 bits of stencil reference Seems to match behaviour of the D3D11 runtime, in that OMGetDepthStencilState will not retain the high bits. Found by CME. Should fix #1784. --- src/d3d11/d3d11_context.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 3c649c050..37135a759 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2261,6 +2261,10 @@ namespace dxvk { ApplyDepthStencilState(); } + // The D3D11 runtime only appears to store the low 8 bits, + // and some games rely on this behaviour. Do the same here. + StencilRef &= 0xFF; + if (m_state.om.stencilRef != StencilRef) { m_state.om.stencilRef = StencilRef; ApplyStencilRef(); From 6d4161cd6e2bd1a762607c8205fae6a9007448db Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 16 Dec 2022 17:15:50 +0100 Subject: [PATCH 0984/1348] [meta] Fix issues with build scripts if there are spaces in the path --- package-native.sh | 3 ++- package-release.sh | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package-native.sh b/package-native.sh index cdb88b5ed..3ef659438 100755 --- a/package-native.sh +++ b/package-native.sh @@ -10,7 +10,8 @@ if [ -z "$1" ] || [ -z "$2" ]; then fi DXVK_VERSION="$1" -DXVK_SRC_DIR=`dirname $(readlink -f $0)` +DXVK_SRC_DIR=$(readlink -f "$0") +DXVK_SRC_DIR=$(dirname "$DXVK_SRC_DIR") DXVK_BUILD_DIR=$(realpath "$2")"/dxvk-native-$DXVK_VERSION" DXVK_ARCHIVE_PATH=$(realpath "$2")"/dxvk-native-$DXVK_VERSION.tar.gz" diff --git a/package-release.sh b/package-release.sh index f614b8a08..0db4fa755 100755 --- a/package-release.sh +++ b/package-release.sh @@ -10,7 +10,8 @@ if [ -z "$1" ] || [ -z "$2" ]; then fi DXVK_VERSION="$1" -DXVK_SRC_DIR=`dirname $(readlink -f $0)` +DXVK_SRC_DIR=$(readlink -f "$0") +DXVK_SRC_DIR=$(dirname "$DXVK_SRC_DIR") DXVK_BUILD_DIR=$(realpath "$2")"/dxvk-$DXVK_VERSION" DXVK_ARCHIVE_PATH=$(realpath "$2")"/dxvk-$DXVK_VERSION.tar.gz" From 18b0ef697cb4a13cee046d323daa775865c571eb Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Mon, 7 Nov 2022 22:25:05 +0100 Subject: [PATCH 0985/1348] [dxvk] Rework SetEventOnCompletion * Create the waiter thread on demand * Don't wake up the waiter thread every 10ms when no events are queued * Wait on caller thread when hEvent = null --- src/d3d11/d3d11_fence.cpp | 14 ++++----- src/dxvk/dxvk_fence.cpp | 63 ++++++++++++++++++++++++++++++--------- src/dxvk/dxvk_fence.h | 17 +++++++---- 3 files changed, 68 insertions(+), 26 deletions(-) diff --git a/src/d3d11/d3d11_fence.cpp b/src/d3d11/d3d11_fence.cpp index 3351f4ac8..8c37a5f3c 100644 --- a/src/d3d11/d3d11_fence.cpp +++ b/src/d3d11/d3d11_fence.cpp @@ -81,13 +81,13 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Fence::SetEventOnCompletion( UINT64 Value, HANDLE hEvent) { - // TODO in case of rewinds, the stored value may be higher. - // For shared fences, calling vkWaitSemaphores here could alleviate the issue. - - m_fence->enqueueWait(Value, [hEvent] { - SetEvent(hEvent); - }); - + if (hEvent) { + m_fence->enqueueWait(Value, [hEvent] { + SetEvent(hEvent); + }); + } else { + m_fence->wait(Value); + } return S_OK; } diff --git a/src/dxvk/dxvk_fence.cpp b/src/dxvk/dxvk_fence.cpp index f9c3dc536..8e2b7c6a6 100644 --- a/src/dxvk/dxvk_fence.cpp +++ b/src/dxvk/dxvk_fence.cpp @@ -56,28 +56,51 @@ namespace dxvk { Logger::warn(str::format("Importing semaphores of type ", info.sharedType, " not supported by device")); } } - - m_thread = dxvk::thread([this] { run(); }); } DxvkFence::~DxvkFence() { - m_stop.store(true); - m_thread.join(); - + if (m_thread.joinable()) { + { + std::unique_lock lock(m_mutex); + m_running = false; + m_condVar.notify_one(); + } + m_thread.join(); + } m_vkd->vkDestroySemaphore(m_vkd->device(), m_semaphore, nullptr); } void DxvkFence::enqueueWait(uint64_t value, DxvkFenceEvent&& event) { - std::unique_lock lock(m_mutex); - - if (value > m_lastValue.load()) + if (value > getValue()) { + std::unique_lock lock(m_mutex); m_queue.emplace(value, std::move(event)); - else + + if (!m_running) { + m_running = true; + m_thread = dxvk::thread([this] { run(); }); + } else { + m_condVar.notify_one(); + } + lock.unlock(); + } else { event(); + } + } + + void DxvkFence::wait(uint64_t value) { + VkSemaphoreWaitInfo waitInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO }; + waitInfo.semaphoreCount = 1; + waitInfo.pSemaphores = &m_semaphore; + waitInfo.pValues = &value; + VkResult vr = m_vkd->vkWaitSemaphores( + m_vkd->device(), &waitInfo, ~0ull); + + if (vr != VK_SUCCESS) { + Logger::err(str::format("Failed to wait for semaphore: ", vr)); + } } - void DxvkFence::run() { uint64_t value = 0ull; @@ -87,9 +110,11 @@ namespace dxvk { waitInfo.pSemaphores = &m_semaphore; waitInfo.pValues = &value; - while (!m_stop.load()) { + while (true) { std::unique_lock lock(m_mutex); + m_condVar.wait(lock, [&]() { return !m_queue.empty() || !m_running; }); + // Query actual semaphore value and start from there, so that // we can skip over large increments in the semaphore value VkResult vr = m_vkd->vkGetSemaphoreCounterValue(m_vkd->device(), m_semaphore, &value); @@ -99,8 +124,6 @@ namespace dxvk { return; } - m_lastValue.store(value); - // Signal all enqueued events whose value is not greater than // the current semaphore value while (!m_queue.empty() && m_queue.top().value <= value) { @@ -108,9 +131,12 @@ namespace dxvk { m_queue.pop(); } - if (m_stop) + if (!m_running) return; + if (m_queue.empty()) + continue; + lock.unlock(); // Wait for the semaphore to be singaled again and update state. @@ -130,6 +156,15 @@ namespace dxvk { } } + uint64_t DxvkFence::getValue() { + uint64_t value = 0; + VkResult vr = m_vkd->vkGetSemaphoreCounterValue(m_vkd->device(), m_semaphore, &value); + if (vr != VK_SUCCESS) { + Logger::err(str::format("Failed to query semaphore value: ", vr)); + } + return value; + } + HANDLE DxvkFence::sharedHandle() const { if (m_info.sharedType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM) return INVALID_HANDLE_VALUE; diff --git a/src/dxvk/dxvk_fence.h b/src/dxvk/dxvk_fence.h index 99e0880e7..86783dac4 100644 --- a/src/dxvk/dxvk_fence.h +++ b/src/dxvk/dxvk_fence.h @@ -70,9 +70,7 @@ namespace dxvk { * \brief Retrieves current semaphore value * \returns Current semaphore value */ - uint64_t getValue() { - return m_lastValue.load(); - } + uint64_t getValue(); /** * \brief Enqueues semaphore wait @@ -90,6 +88,15 @@ namespace dxvk { */ HANDLE sharedHandle() const; + /* + * \brief Waits for the given value + * + * Blocks the calling thread until + * the fence reaches the given value. + * \param [in] value Value to wait for + */ + void wait(uint64_t value); + private: struct QueueItem { @@ -113,10 +120,10 @@ namespace dxvk { VkSemaphore m_semaphore; std::priority_queue m_queue; - std::atomic m_lastValue = { 0ull }; - std::atomic m_stop = { false }; + bool m_running = false; dxvk::mutex m_mutex; + dxvk::condition_variable m_condVar; dxvk::thread m_thread; void run(); From fd661d587ee7675b62308a95ff3776354debc5fa Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 18 Dec 2022 17:05:18 +0000 Subject: [PATCH 0986/1348] [vulkan] Simplify args to Presenter GetSupported* methods --- src/vulkan/vulkan_presenter.cpp | 12 ++++++------ src/vulkan/vulkan_presenter.h | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index 860fdbf4d..0a10676ea 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -116,10 +116,10 @@ namespace dxvk::vk { m_device.adapter, m_surface, &caps))) return status; - if ((status = getSupportedFormats(formats, desc))) + if ((status = getSupportedFormats(formats, desc.fullScreenExclusive))) return status; - if ((status = getSupportedPresentModes(modes, desc))) + if ((status = getSupportedPresentModes(modes, desc.fullScreenExclusive))) return status; // Select actual swap chain properties and create swap chain @@ -225,11 +225,11 @@ namespace dxvk::vk { } - VkResult Presenter::getSupportedFormats(std::vector& formats, const PresenterDesc& desc) { + VkResult Presenter::getSupportedFormats(std::vector& formats, VkFullScreenExclusiveEXT fullScreenExclusive) const { uint32_t numFormats = 0; VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; - fullScreenInfo.fullScreenExclusive = desc.fullScreenExclusive; + fullScreenInfo.fullScreenExclusive = fullScreenExclusive; VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, &fullScreenInfo }; surfaceInfo.surface = m_surface; @@ -267,11 +267,11 @@ namespace dxvk::vk { } - VkResult Presenter::getSupportedPresentModes(std::vector& modes, const PresenterDesc& desc) { + VkResult Presenter::getSupportedPresentModes(std::vector& modes, VkFullScreenExclusiveEXT fullScreenExclusive) const { uint32_t numModes = 0; VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; - fullScreenInfo.fullScreenExclusive = desc.fullScreenExclusive; + fullScreenInfo.fullScreenExclusive = fullScreenExclusive; VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, &fullScreenInfo }; surfaceInfo.surface = m_surface; diff --git a/src/vulkan/vulkan_presenter.h b/src/vulkan/vulkan_presenter.h index 858ada308..170d81c38 100644 --- a/src/vulkan/vulkan_presenter.h +++ b/src/vulkan/vulkan_presenter.h @@ -209,11 +209,11 @@ namespace dxvk::vk { VkResult getSupportedFormats( std::vector& formats, - const PresenterDesc& desc); + VkFullScreenExclusiveEXT fullScreenExclusive) const; VkResult getSupportedPresentModes( std::vector& modes, - const PresenterDesc& desc); + VkFullScreenExclusiveEXT fullScreenExclusive) const; VkResult getSwapImages( std::vector& images); From 50054d4675e3e8f490a6fc86c4bc9ea28ec0b0c3 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 18 Dec 2022 22:59:20 +0000 Subject: [PATCH 0987/1348] [vulkan] Add supportsColorSpace method to Presenter --- src/vulkan/vulkan_presenter.cpp | 13 +++++++++++++ src/vulkan/vulkan_presenter.h | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index 0a10676ea..5bcebfaec 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -220,6 +220,19 @@ namespace dxvk::vk { } + bool Presenter::supportsColorSpace(VkColorSpaceKHR colorspace) { + std::vector surfaceFormats; + getSupportedFormats(surfaceFormats, VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT); + + for (const auto& surfaceFormat : surfaceFormats) { + if (surfaceFormat.colorSpace == colorspace) + return true; + } + + return false; + } + + void Presenter::setFrameRateLimit(double frameRate) { m_fpsLimiter.setTargetFrameRate(frameRate); } diff --git a/src/vulkan/vulkan_presenter.h b/src/vulkan/vulkan_presenter.h index 170d81c38..0de46d44c 100644 --- a/src/vulkan/vulkan_presenter.h +++ b/src/vulkan/vulkan_presenter.h @@ -183,6 +183,14 @@ namespace dxvk::vk { return m_swapchain; } + /** + * \brief Checks if a presenter supports the colorspace + * + * \param [in] colorspace The colorspace to test + * * \returns \c true if the presenter supports the colorspace + */ + bool supportsColorSpace(VkColorSpaceKHR colorspace); + private: Rc m_vki; From 33acf58ac78161526f77e3c3e04be17418c5cb79 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 18 Dec 2022 17:12:16 +0000 Subject: [PATCH 0988/1348] [d3d11] Implement CheckColorSpaceSupport and SetColorSpace --- src/d3d11/d3d11_swapchain.cpp | 36 ++++++++++++++++++++++++++--------- src/d3d11/d3d11_swapchain.h | 2 ++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index a43c6bad2..17669ec62 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -12,6 +12,17 @@ namespace dxvk { return uint16_t(65535.0f * x); } + static VkColorSpaceKHR ConvertColorSpace(DXGI_COLOR_SPACE_TYPE colorspace) { + switch (colorspace) { + case DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709: return VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + case DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020: return VK_COLOR_SPACE_HDR10_ST2084_EXT; + case DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709: return VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT; + default: + Logger::warn(str::format("DXGI: ConvertColorSpace: Unknown colorspace ", colorspace)); + return VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + } + } + D3D11SwapChain::D3D11SwapChain( D3D11DXGIDevice* pContainer, @@ -257,7 +268,8 @@ namespace dxvk { DXGI_COLOR_SPACE_TYPE ColorSpace) { UINT supportFlags = 0; - if (ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709) + const VkColorSpaceKHR vkColorSpace = ConvertColorSpace(ColorSpace); + if (m_presenter->supportsColorSpace(vkColorSpace)) supportFlags |= DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT; return supportFlags; @@ -266,7 +278,13 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11SwapChain::SetColorSpace( DXGI_COLOR_SPACE_TYPE ColorSpace) { - // Ignore, will only ever be sRGB + if (!(CheckColorSpaceSupport(ColorSpace) & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT)) + return E_INVALIDARG; + + const VkColorSpaceKHR vkColorSpace = ConvertColorSpace(ColorSpace); + m_dirty |= vkColorSpace != m_colorspace; + m_colorspace = vkColorSpace; + return S_OK; } @@ -633,23 +651,23 @@ namespace dxvk { case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_B8G8R8A8_UNORM: { - pDstFormats[n++] = { VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }; - pDstFormats[n++] = { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }; + pDstFormats[n++] = { VK_FORMAT_R8G8B8A8_UNORM, m_colorspace }; + pDstFormats[n++] = { VK_FORMAT_B8G8R8A8_UNORM, m_colorspace }; } break; case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: { - pDstFormats[n++] = { VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }; - pDstFormats[n++] = { VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }; + pDstFormats[n++] = { VK_FORMAT_R8G8B8A8_SRGB, m_colorspace }; + pDstFormats[n++] = { VK_FORMAT_B8G8R8A8_SRGB, m_colorspace }; } break; case DXGI_FORMAT_R10G10B10A2_UNORM: { - pDstFormats[n++] = { VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }; - pDstFormats[n++] = { VK_FORMAT_A2R10G10B10_UNORM_PACK32, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }; + pDstFormats[n++] = { VK_FORMAT_A2B10G10R10_UNORM_PACK32, m_colorspace }; + pDstFormats[n++] = { VK_FORMAT_A2R10G10B10_UNORM_PACK32, m_colorspace }; } break; case DXGI_FORMAT_R16G16B16A16_FLOAT: { - pDstFormats[n++] = { VK_FORMAT_R16G16B16A16_SFLOAT, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }; + pDstFormats[n++] = { VK_FORMAT_R16G16B16A16_SFLOAT, m_colorspace }; } break; } diff --git a/src/d3d11/d3d11_swapchain.h b/src/d3d11/d3d11_swapchain.h index fdf67da2b..13c52c2a9 100644 --- a/src/d3d11/d3d11_swapchain.h +++ b/src/d3d11/d3d11_swapchain.h @@ -121,6 +121,8 @@ namespace dxvk { bool m_dirty = true; bool m_vsync = true; + VkColorSpaceKHR m_colorspace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + HRESULT PresentImage(UINT SyncInterval); void SubmitPresent( From 4335eccae9f233fbf8180395845258a27cb2f180 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 18 Dec 2022 17:25:18 +0000 Subject: [PATCH 0989/1348] [dxvk] Enable VK_EXT_swapchain_colorspace --- VP_DXVK_requirements.json | 9 ++++++++- src/dxvk/dxvk_adapter.cpp | 13 ++++++++++++- src/dxvk/dxvk_device_info.h | 1 + src/dxvk/dxvk_extensions.h | 1 + 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/VP_DXVK_requirements.json b/VP_DXVK_requirements.json index 751203d43..133d6c1ca 100644 --- a/VP_DXVK_requirements.json +++ b/VP_DXVK_requirements.json @@ -185,7 +185,8 @@ "VK_EXT_memory_priority": 1, "VK_EXT_vertex_attribute_divisor": 1, "VK_EXT_custom_border_color": 1, - "VK_EXT_depth_clip_enable": 1 + "VK_EXT_depth_clip_enable": 1, + "VK_EXT_swapchain_colorspace": 1 }, "features": { "VkPhysicalDeviceFeatures": { @@ -385,6 +386,12 @@ } }, "history": [ + { + "revision": 4, + "date": "2022-12-18", + "author": "Joshua Ashton", + "comment": "Add VK_EXT_swapchain_colorspace to d3d11_baseline_optional" + }, { "revision": 3, "date": "2022-10-13", diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index e7ef26226..5bafb9f98 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -316,6 +316,8 @@ namespace dxvk { || !required.extShaderModuleIdentifier.shaderModuleIdentifier) && (m_deviceFeatures.extShaderStencilExport || !required.extShaderStencilExport) + && (m_deviceFeatures.extShaderStencilExport + || !required.extSwapchainColorSpace) && (m_deviceFeatures.extTransformFeedback.transformFeedback || !required.extTransformFeedback.transformFeedback) && (m_deviceFeatures.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor @@ -335,7 +337,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.extAttachmentFeedbackLoopLayout, @@ -352,6 +354,7 @@ namespace dxvk { &devExtensions.extRobustness2, &devExtensions.extShaderModuleIdentifier, &devExtensions.extShaderStencilExport, + &devExtensions.extSwapchainColorSpace, &devExtensions.extTransformFeedback, &devExtensions.extVertexAttributeDivisor, &devExtensions.khrExternalMemoryWin32, @@ -537,6 +540,9 @@ namespace dxvk { if (devExtensions.extShaderStencilExport) enabledFeatures.extShaderStencilExport = VK_TRUE; + if (devExtensions.extSwapchainColorSpace) + enabledFeatures.extSwapchainColorSpace = VK_TRUE; + if (devExtensions.extTransformFeedback) { enabledFeatures.extTransformFeedback.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; enabledFeatures.extTransformFeedback.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extTransformFeedback); @@ -875,6 +881,9 @@ namespace dxvk { if (m_deviceExtensions.supports(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME)) m_deviceFeatures.extShaderStencilExport = VK_TRUE; + if (m_deviceExtensions.supports(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME)) + m_deviceFeatures.extSwapchainColorSpace = VK_TRUE; + if (m_deviceExtensions.supports(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) { m_deviceFeatures.extTransformFeedback.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; m_deviceFeatures.extTransformFeedback.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extTransformFeedback); @@ -1024,6 +1033,8 @@ namespace dxvk { "\n shaderModuleIdentifier : ", features.extShaderModuleIdentifier.shaderModuleIdentifier ? "1" : "0", "\n", VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, "\n extension supported : ", features.extShaderStencilExport ? "1" : "0", + "\n", VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, + "\n extension supported : ", features.extSwapchainColorSpace ? "1" : "0", "\n", VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, "\n transformFeedback : ", features.extTransformFeedback.transformFeedback ? "1" : "0", "\n geometryStreams : ", features.extTransformFeedback.geometryStreams ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 21b1b68cc..7b3527969 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -54,6 +54,7 @@ namespace dxvk { VkPhysicalDeviceRobustness2FeaturesEXT extRobustness2; VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT extShaderModuleIdentifier; VkBool32 extShaderStencilExport; + VkBool32 extSwapchainColorSpace; VkPhysicalDeviceTransformFeedbackFeaturesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT extVertexAttributeDivisor; VkBool32 khrExternalMemoryWin32; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 1684f6caa..3d3d979b9 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -292,6 +292,7 @@ namespace dxvk { DxvkExt extRobustness2 = { VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, DxvkExtMode::Required }; DxvkExt extShaderModuleIdentifier = { VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extSwapchainColorSpace = { VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; From 731bf84eddabfd2a95a245b8bb91214610fd0f8f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 18 Dec 2022 17:29:33 +0000 Subject: [PATCH 0990/1348] [dxvk] Enable VK_EXT_hdr_metadata --- VP_DXVK_requirements.json | 5 +++-- src/dxvk/dxvk_adapter.cpp | 13 ++++++++++++- src/dxvk/dxvk_device_info.h | 1 + src/dxvk/dxvk_extensions.h | 1 + src/vulkan/vulkan_loader.h | 4 ++++ 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/VP_DXVK_requirements.json b/VP_DXVK_requirements.json index 133d6c1ca..d837465bf 100644 --- a/VP_DXVK_requirements.json +++ b/VP_DXVK_requirements.json @@ -186,7 +186,8 @@ "VK_EXT_vertex_attribute_divisor": 1, "VK_EXT_custom_border_color": 1, "VK_EXT_depth_clip_enable": 1, - "VK_EXT_swapchain_colorspace": 1 + "VK_EXT_swapchain_colorspace": 1, + "VK_EXT_hdr_metadata": 1 }, "features": { "VkPhysicalDeviceFeatures": { @@ -390,7 +391,7 @@ "revision": 4, "date": "2022-12-18", "author": "Joshua Ashton", - "comment": "Add VK_EXT_swapchain_colorspace to d3d11_baseline_optional" + "comment": "Add VK_EXT_swapchain_colorspace and VK_EXT_hdr_metadata to d3d11_baseline_optional" }, { "revision": 3, diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 5bafb9f98..290ea9841 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -318,6 +318,8 @@ namespace dxvk { || !required.extShaderStencilExport) && (m_deviceFeatures.extShaderStencilExport || !required.extSwapchainColorSpace) + && (m_deviceFeatures.extHdrMetadata + || !required.extHdrMetadata) && (m_deviceFeatures.extTransformFeedback.transformFeedback || !required.extTransformFeedback.transformFeedback) && (m_deviceFeatures.extVertexAttributeDivisor.vertexAttributeInstanceRateDivisor @@ -337,7 +339,7 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures) { DxvkDeviceExtensions devExtensions; - std::array devExtensionList = {{ + std::array devExtensionList = {{ &devExtensions.amdMemoryOverallocationBehaviour, &devExtensions.amdShaderFragmentMask, &devExtensions.extAttachmentFeedbackLoopLayout, @@ -348,6 +350,7 @@ namespace dxvk { &devExtensions.extFragmentShaderInterlock, &devExtensions.extFullScreenExclusive, &devExtensions.extGraphicsPipelineLibrary, + &devExtensions.extHdrMetadata, &devExtensions.extMemoryBudget, &devExtensions.extMemoryPriority, &devExtensions.extNonSeamlessCubeMap, @@ -543,6 +546,9 @@ namespace dxvk { if (devExtensions.extSwapchainColorSpace) enabledFeatures.extSwapchainColorSpace = VK_TRUE; + if (devExtensions.extHdrMetadata) + enabledFeatures.extHdrMetadata = VK_TRUE; + if (devExtensions.extTransformFeedback) { enabledFeatures.extTransformFeedback.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; enabledFeatures.extTransformFeedback.pNext = std::exchange(enabledFeatures.core.pNext, &enabledFeatures.extTransformFeedback); @@ -884,6 +890,9 @@ namespace dxvk { if (m_deviceExtensions.supports(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME)) m_deviceFeatures.extSwapchainColorSpace = VK_TRUE; + if (m_deviceExtensions.supports(VK_EXT_HDR_METADATA_EXTENSION_NAME)) + m_deviceFeatures.extHdrMetadata = VK_TRUE; + if (m_deviceExtensions.supports(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME)) { m_deviceFeatures.extTransformFeedback.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; m_deviceFeatures.extTransformFeedback.pNext = std::exchange(m_deviceFeatures.core.pNext, &m_deviceFeatures.extTransformFeedback); @@ -1035,6 +1044,8 @@ namespace dxvk { "\n extension supported : ", features.extShaderStencilExport ? "1" : "0", "\n", VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, "\n extension supported : ", features.extSwapchainColorSpace ? "1" : "0", + "\n", VK_EXT_HDR_METADATA_EXTENSION_NAME, + "\n extension supported : ", features.extHdrMetadata ? "1" : "0", "\n", VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, "\n transformFeedback : ", features.extTransformFeedback.transformFeedback ? "1" : "0", "\n geometryStreams : ", features.extTransformFeedback.geometryStreams ? "1" : "0", diff --git a/src/dxvk/dxvk_device_info.h b/src/dxvk/dxvk_device_info.h index 7b3527969..3c385cbd3 100644 --- a/src/dxvk/dxvk_device_info.h +++ b/src/dxvk/dxvk_device_info.h @@ -55,6 +55,7 @@ namespace dxvk { VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT extShaderModuleIdentifier; VkBool32 extShaderStencilExport; VkBool32 extSwapchainColorSpace; + VkBool32 extHdrMetadata; VkPhysicalDeviceTransformFeedbackFeaturesEXT extTransformFeedback; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT extVertexAttributeDivisor; VkBool32 khrExternalMemoryWin32; diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index 3d3d979b9..1b7e91ccf 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -293,6 +293,7 @@ namespace dxvk { DxvkExt extShaderModuleIdentifier = { VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extShaderStencilExport = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extSwapchainColorSpace = { VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, DxvkExtMode::Optional }; + DxvkExt extHdrMetadata = { VK_EXT_HDR_METADATA_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extTransformFeedback = { VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional }; DxvkExt khrExternalMemoryWin32 = { VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, DxvkExtMode::Optional }; diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 653cf3975..71b2dab24 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -384,6 +384,10 @@ namespace dxvk::vk { VULKAN_FN(vkGetDeviceGroupSurfacePresentModes2EXT); #endif + #ifdef VK_EXT_hdr_metadata + VULKAN_FN(vkSetHdrMetadataEXT); + #endif + #ifdef VK_EXT_shader_module_identifier VULKAN_FN(vkGetShaderModuleCreateInfoIdentifierEXT); VULKAN_FN(vkGetShaderModuleIdentifierEXT); From e5418a956a80266c1bf0728ddd59b6bd863f6106 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 18 Dec 2022 17:44:59 +0000 Subject: [PATCH 0991/1348] [vulkan] Add setHdrMetadata method to Presenter --- src/d3d11/d3d11_swapchain.cpp | 1 + src/vulkan/vulkan_presenter.cpp | 6 ++++++ src/vulkan/vulkan_presenter.h | 8 ++++++++ 3 files changed, 15 insertions(+) diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 17669ec62..7c52bb776 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -446,6 +446,7 @@ namespace dxvk { presenterDevice.queue = graphicsQueue.queueHandle; presenterDevice.adapter = m_device->adapter()->handle(); presenterDevice.features.fullScreenExclusive = m_device->features().extFullScreenExclusive; + presenterDevice.features.hdrMetadata = m_device->features().extHdrMetadata; vk::PresenterDesc presenterDesc; presenterDesc.imageExtent = { m_desc.Width, m_desc.Height }; diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index 5bcebfaec..694f2dbb0 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -238,6 +238,12 @@ namespace dxvk::vk { } + void Presenter::setHdrMetadata(const VkHdrMetadataEXT& hdrMetadata) { + if (m_device.features.hdrMetadata) + m_vkd->vkSetHdrMetadataEXT(m_vkd->device(), 1, &m_swapchain, &hdrMetadata); + } + + VkResult Presenter::getSupportedFormats(std::vector& formats, VkFullScreenExclusiveEXT fullScreenExclusive) const { uint32_t numFormats = 0; diff --git a/src/vulkan/vulkan_presenter.h b/src/vulkan/vulkan_presenter.h index 0de46d44c..641956f90 100644 --- a/src/vulkan/vulkan_presenter.h +++ b/src/vulkan/vulkan_presenter.h @@ -49,6 +49,7 @@ namespace dxvk::vk { */ struct PresenterFeatures { bool fullScreenExclusive : 1; + bool hdrMetadata : 1; }; /** @@ -191,6 +192,13 @@ namespace dxvk::vk { */ bool supportsColorSpace(VkColorSpaceKHR colorspace); + /** + * \brief Sets HDR metadata + * + * \param [in] hdrMetadata HDR Metadata + */ + void setHdrMetadata(const VkHdrMetadataEXT& hdrMetadata); + private: Rc m_vki; From c7be18cb267d30ee3cc1fab0f9ccacbec22b8801 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sun, 18 Dec 2022 17:45:22 +0000 Subject: [PATCH 0992/1348] [d3d11] Implement SetHDRMetadata --- src/d3d11/d3d11_swapchain.cpp | 41 +++++++++++++++++++++++++++++++++-- src/d3d11/d3d11_swapchain.h | 3 +++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 7c52bb776..98cbc4dfc 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -23,6 +23,35 @@ namespace dxvk { } } + static VkXYColorEXT ConvertXYColor(const UINT16 (&dxgiColor)[2]) { + return VkXYColorEXT{ float(dxgiColor[0]) / 50000.0f, float(dxgiColor[1]) / 50000.0f }; + } + + static float ConvertMaxLuminance(UINT dxgiLuminance) { + return float(dxgiLuminance); + } + + static float ConvertMinLuminance(UINT dxgiLuminance) { + return float(dxgiLuminance) / 0.0001f; + } + + static float ConvertLevel(UINT16 dxgiLevel) { + return float(dxgiLevel); + } + + static VkHdrMetadataEXT ConvertHDRMetadata(const DXGI_HDR_METADATA_HDR10& dxgiMetadata) { + VkHdrMetadataEXT vkMetadata = { VK_STRUCTURE_TYPE_HDR_METADATA_EXT }; + vkMetadata.displayPrimaryRed = ConvertXYColor(dxgiMetadata.RedPrimary); + vkMetadata.displayPrimaryGreen = ConvertXYColor(dxgiMetadata.GreenPrimary); + vkMetadata.displayPrimaryBlue = ConvertXYColor(dxgiMetadata.BluePrimary); + vkMetadata.whitePoint = ConvertXYColor(dxgiMetadata.WhitePoint); + vkMetadata.maxLuminance = ConvertMaxLuminance(dxgiMetadata.MaxMasteringLuminance); + vkMetadata.minLuminance = ConvertMinLuminance(dxgiMetadata.MinMasteringLuminance); + vkMetadata.maxContentLightLevel = ConvertLevel(dxgiMetadata.MaxContentLightLevel); + vkMetadata.maxFrameAverageLightLevel = ConvertLevel(dxgiMetadata.MaxFrameAverageLightLevel); + return vkMetadata; + } + D3D11SwapChain::D3D11SwapChain( D3D11DXGIDevice* pContainer, @@ -292,8 +321,10 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11SwapChain::SetHDRMetaData( const DXGI_VK_HDR_METADATA* pMetaData) { // For some reason this call always seems to succeed on Windows - if (pMetaData->Type == DXGI_HDR_METADATA_TYPE_HDR10) - Logger::warn("D3D11: HDR10 metadata not supported"); + if (pMetaData->Type == DXGI_HDR_METADATA_TYPE_HDR10) { + m_hdrMetadata = ConvertHDRMetadata(pMetaData->HDR10); + m_dirtyHdrMetadata = true; + } return S_OK; } @@ -335,6 +366,11 @@ namespace dxvk { status = m_presenter->acquireNextImage(sync, imageIndex); } + if (m_hdrMetadata && m_dirtyHdrMetadata) { + m_presenter->setHdrMetadata(*m_hdrMetadata); + m_dirtyHdrMetadata = false; + } + // Resolve back buffer if it is multisampled. We // only have to do it only for the first frame. m_context->beginRecording( @@ -402,6 +438,7 @@ namespace dxvk { m_device->waitForIdle(); m_presentStatus.result = VK_SUCCESS; + m_dirtyHdrMetadata = true; vk::PresenterDesc presenterDesc; presenterDesc.imageExtent = { m_desc.Width, m_desc.Height }; diff --git a/src/d3d11/d3d11_swapchain.h b/src/d3d11/d3d11_swapchain.h index 13c52c2a9..9da85d664 100644 --- a/src/d3d11/d3d11_swapchain.h +++ b/src/d3d11/d3d11_swapchain.h @@ -123,6 +123,9 @@ namespace dxvk { VkColorSpaceKHR m_colorspace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + std::optional m_hdrMetadata; + bool m_dirtyHdrMetadata = true; + HRESULT PresentImage(UINT SyncInterval); void SubmitPresent( From f4f4f3647f30c9f401bd4b04eb38869e400b70f1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 20 Dec 2022 02:12:44 +0100 Subject: [PATCH 0993/1348] [d3d11] Do not create storage image views with swizzle This happens when a game uses A8_UNORM UAVs. Vulkan doesn't allow this, and it's not meaningful for stores anyway, we'd need shader emulation. --- src/d3d11/d3d11_view_uav.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/d3d11/d3d11_view_uav.cpp b/src/d3d11/d3d11_view_uav.cpp index 562626acd..51a7ceddd 100644 --- a/src/d3d11/d3d11_view_uav.cpp +++ b/src/d3d11/d3d11_view_uav.cpp @@ -59,9 +59,11 @@ namespace dxvk { DxvkImageViewCreateInfo viewInfo; viewInfo.format = formatInfo.Format; viewInfo.aspect = formatInfo.Aspect; - viewInfo.swizzle = formatInfo.Swizzle; viewInfo.usage = VK_IMAGE_USAGE_STORAGE_BIT; - + + if (!util::isIdentityMapping(formatInfo.Swizzle)) + Logger::warn(str::format("UAV format ", pDesc->Format, " has non-identity swizzle, but UAV swizzles are not supported")); + switch (pDesc->ViewDimension) { case D3D11_UAV_DIMENSION_TEXTURE1D: viewInfo.type = VK_IMAGE_VIEW_TYPE_1D; From 12901b52f19ea1d3eece450a009f4602b5f2adc3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 20 Dec 2022 03:10:44 +0100 Subject: [PATCH 0994/1348] [dxvk] Split barriers with very large VkDependencyInfo structures Works around an AMD driver bug. Fixes #3138. --- src/dxvk/dxvk_barrier.cpp | 45 +++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_barrier.cpp b/src/dxvk/dxvk_barrier.cpp index 3d1755c85..c9a7db7f5 100644 --- a/src/dxvk/dxvk_barrier.cpp +++ b/src/dxvk/dxvk_barrier.cpp @@ -327,12 +327,49 @@ namespace dxvk { depInfo.pImageMemoryBarriers = m_imgBarriers.data(); } - if (depInfo.memoryBarrierCount + depInfo.bufferMemoryBarrierCount + depInfo.imageMemoryBarrierCount) { - commandList->cmdPipelineBarrier(m_cmdBuffer, &depInfo); - commandList->addStatCtr(DxvkStatCounter::CmdBarrierCount, 1); + uint32_t totalBarrierCount = depInfo.memoryBarrierCount + + depInfo.bufferMemoryBarrierCount + + depInfo.imageMemoryBarrierCount; - this->reset(); + if (!totalBarrierCount) + return; + + // AMDVLK (and -PRO) will just crash if they encounter a very large structure + // in one vkCmdPipelineBarrier2 call, so we need to split the barrier into parts. + constexpr uint32_t MaxBarriersPerCall = 512; + + if (unlikely(totalBarrierCount > MaxBarriersPerCall)) { + VkDependencyInfo splitDepInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + + for (uint32_t i = 0; i < depInfo.memoryBarrierCount; i += MaxBarriersPerCall) { + splitDepInfo.memoryBarrierCount = std::min(depInfo.memoryBarrierCount - i, MaxBarriersPerCall); + splitDepInfo.pMemoryBarriers = depInfo.pMemoryBarriers + i; + commandList->cmdPipelineBarrier(m_cmdBuffer, &splitDepInfo); + } + + splitDepInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + + for (uint32_t i = 0; i < depInfo.bufferMemoryBarrierCount; i += MaxBarriersPerCall) { + splitDepInfo.bufferMemoryBarrierCount = std::min(depInfo.bufferMemoryBarrierCount - i, MaxBarriersPerCall); + splitDepInfo.pBufferMemoryBarriers = depInfo.pBufferMemoryBarriers + i; + commandList->cmdPipelineBarrier(m_cmdBuffer, &splitDepInfo); + } + + splitDepInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO }; + + for (uint32_t i = 0; i < depInfo.imageMemoryBarrierCount; i += MaxBarriersPerCall) { + splitDepInfo.imageMemoryBarrierCount = std::min(depInfo.imageMemoryBarrierCount - i, MaxBarriersPerCall); + splitDepInfo.pImageMemoryBarriers = depInfo.pImageMemoryBarriers + i; + commandList->cmdPipelineBarrier(m_cmdBuffer, &splitDepInfo); + } + } else { + // Otherwise, issue the barrier as-is + commandList->cmdPipelineBarrier(m_cmdBuffer, &depInfo); } + + commandList->addStatCtr(DxvkStatCounter::CmdBarrierCount, 1); + + this->reset(); } From f94b42f23f34cc92c9115764f800292e6d7a2c50 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Fri, 30 Dec 2022 20:12:37 +0100 Subject: [PATCH 0995/1348] [d3d9] Dont use GenerateDrawInfo in DrawPrimitiveUp This is confusing because it looks like a race condition at first glance. --- src/d3d9/d3d9_device.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index b5be3db88..4a4d31cad 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2536,10 +2536,10 @@ namespace dxvk { PrepareDraw(PrimitiveType); - auto drawInfo = GenerateDrawInfo(PrimitiveType, PrimitiveCount, 0); + uint32_t vertexCount = GetVertexCount(PrimitiveType, PrimitiveCount); - const uint32_t dataSize = GetUPDataSize(drawInfo.vertexCount, VertexStreamZeroStride); - const uint32_t bufferSize = GetUPBufferSize(drawInfo.vertexCount, VertexStreamZeroStride); + const uint32_t dataSize = GetUPDataSize(vertexCount, VertexStreamZeroStride); + const uint32_t bufferSize = GetUPBufferSize(vertexCount, VertexStreamZeroStride); auto upSlice = AllocUPBuffer(bufferSize); FillUPVertexBuffer(upSlice.mapPtr, pVertexStreamZeroData, dataSize, bufferSize); @@ -2589,13 +2589,13 @@ namespace dxvk { PrepareDraw(PrimitiveType); - auto drawInfo = GenerateDrawInfo(PrimitiveType, PrimitiveCount, 0); + uint32_t vertexCount = GetVertexCount(PrimitiveType, PrimitiveCount); const uint32_t vertexDataSize = GetUPDataSize(MinVertexIndex + NumVertices, VertexStreamZeroStride); const uint32_t vertexBufferSize = GetUPBufferSize(MinVertexIndex + NumVertices, VertexStreamZeroStride); const uint32_t indexSize = IndexDataFormat == D3DFMT_INDEX16 ? 2 : 4; - const uint32_t indicesSize = drawInfo.vertexCount * indexSize; + const uint32_t indicesSize = vertexCount * indexSize; const uint32_t upSize = vertexBufferSize + indicesSize; From fd34dba070137350dbe1edd5495d283762fffc94 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 6 Jan 2023 10:08:33 +0000 Subject: [PATCH 0996/1348] [build] Bump libdisplay-info fork Should fix issues running under Windows with MinGW builds. --- subprojects/libdisplay-info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/libdisplay-info b/subprojects/libdisplay-info index 3b2e9f6b7..7d90e5b5d 160000 --- a/subprojects/libdisplay-info +++ b/subprojects/libdisplay-info @@ -1 +1 @@ -Subproject commit 3b2e9f6b76aa8d0c413c93202e93816517d781bd +Subproject commit 7d90e5b5d15f65d63f2ff4c2d47af76b3bc1c564 From 421ac4800707833c75a17f2f9859b48ffce3f3c1 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 6 Jan 2023 10:38:17 +0000 Subject: [PATCH 0997/1348] [build] Bump libdisplay-info fork subproject to fix MSVC builds --- subprojects/libdisplay-info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/libdisplay-info b/subprojects/libdisplay-info index 7d90e5b5d..a7ff74af2 160000 --- a/subprojects/libdisplay-info +++ b/subprojects/libdisplay-info @@ -1 +1 @@ -Subproject commit 7d90e5b5d15f65d63f2ff4c2d47af76b3bc1c564 +Subproject commit a7ff74af258f01788c9cf932e5161256fe3ae1a6 From 4d2e90ceba7285065b45339fb1e5836225877664 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 6 Jan 2023 10:45:00 +0000 Subject: [PATCH 0998/1348] =?UTF-8?q?[build]=20Bump=20libdisplay-info=20fo?= =?UTF-8?q?rk=20again=20=F0=9F=90=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bruh moment with MAX_PATH define between MinGW and Windows headers going on. Should have just PRed it from the start to avoid the churn :( --- subprojects/libdisplay-info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/libdisplay-info b/subprojects/libdisplay-info index a7ff74af2..d39344f46 160000 --- a/subprojects/libdisplay-info +++ b/subprojects/libdisplay-info @@ -1 +1 @@ -Subproject commit a7ff74af258f01788c9cf932e5161256fe3ae1a6 +Subproject commit d39344f466caae0495ebac4d49b03a886d83ba3a From dd660585c045f647a6af61f5312558328f29e7bb Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sun, 1 Jan 2023 17:51:30 +0100 Subject: [PATCH 0999/1348] [meta] Remove current year from copyright notice --- LICENSE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index a9d4337ea..253cadd62 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ - Copyright (c) 2017-2021 Philip Rebohle - Copyright (c) 2019-2021 Joshua Ashton + Copyright (c) 2017 Philip Rebohle + Copyright (c) 2019 Joshua Ashton zlib/libpng license From f453d6ee2ab22e73faefd5961559d0810616ba05 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 3 Jan 2023 13:49:59 +0000 Subject: [PATCH 1000/1348] [dxgi] Implement DXGIOutput::GetDesc1's ColorSpace Adds the ability to punt the global colorspace into HDR from SetColorSpace1. We have no way of checking the actual Windows colorspace as the only public method for this *is* DXGI which we are re-implementing. So we just pick our color space based on the DXVK_HDR env var and the punting from SetColorSpace1. We might expand on this in future, but this is good enough for an initial implementation. --- src/dxgi/dxgi_interfaces.h | 24 ++++++++++++++++++++++++ src/dxgi/dxgi_monitor.cpp | 20 +++++++++++++++++++- src/dxgi/dxgi_monitor.h | 8 ++++++++ src/dxgi/dxgi_output.cpp | 16 ++++++---------- src/dxgi/dxgi_swapchain.cpp | 8 +++++++- 5 files changed, 64 insertions(+), 12 deletions(-) diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index f297e5c36..e15acc085 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -200,6 +200,30 @@ IDXGIVkMonitorInfo : public IUnknown { */ virtual void STDMETHODCALLTYPE ReleaseMonitorData() = 0; + /** + * \brief Punt global colorspace + * + * This exists to satiate a requirement for + * IDXGISwapChain::SetColorSpace1 punting Windows into + * the global "HDR mode". + * + * This operation is atomic and does not require + * owning any monitor data. + * + * \param [in] ColorSpace The colorspace + */ + virtual void STDMETHODCALLTYPE PuntColorSpace(DXGI_COLOR_SPACE_TYPE ColorSpace) = 0; + + /** + * \brief Get current global colorspace + * + * This operation is atomic and does not require + * owning any monitor data. + * + * \returns Current global colorspace + */ + virtual DXGI_COLOR_SPACE_TYPE STDMETHODCALLTYPE CurrentColorSpace() const = 0; + }; diff --git a/src/dxgi/dxgi_monitor.cpp b/src/dxgi/dxgi_monitor.cpp index 09959a627..c0e25a7a3 100644 --- a/src/dxgi/dxgi_monitor.cpp +++ b/src/dxgi/dxgi_monitor.cpp @@ -3,7 +3,8 @@ namespace dxvk { DxgiMonitorInfo::DxgiMonitorInfo(IUnknown* pParent) - : m_parent(pParent) { + : m_parent(pParent) + , m_globalColorSpace(DefaultColorSpace()) { } @@ -69,6 +70,23 @@ namespace dxvk { } + void STDMETHODCALLTYPE DxgiMonitorInfo::PuntColorSpace(DXGI_COLOR_SPACE_TYPE ColorSpace) { + m_globalColorSpace = ColorSpace; + } + + + DXGI_COLOR_SPACE_TYPE STDMETHODCALLTYPE DxgiMonitorInfo::CurrentColorSpace() const { + return m_globalColorSpace; + } + + + DXGI_COLOR_SPACE_TYPE DxgiMonitorInfo::DefaultColorSpace() { + return env::getEnvVar("DXVK_HDR") == "1" + ? DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 + : DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; + } + + uint32_t GetMonitorFormatBpp(DXGI_FORMAT Format) { switch (Format) { case DXGI_FORMAT_R8G8B8A8_UNORM: diff --git a/src/dxgi/dxgi_monitor.h b/src/dxgi/dxgi_monitor.h index eee6d47e2..4ab6c1b36 100644 --- a/src/dxgi/dxgi_monitor.h +++ b/src/dxgi/dxgi_monitor.h @@ -37,6 +37,12 @@ namespace dxvk { void STDMETHODCALLTYPE ReleaseMonitorData(); + void STDMETHODCALLTYPE PuntColorSpace(DXGI_COLOR_SPACE_TYPE ColorSpace); + + DXGI_COLOR_SPACE_TYPE STDMETHODCALLTYPE CurrentColorSpace() const; + + static DXGI_COLOR_SPACE_TYPE DefaultColorSpace(); + private: IUnknown* m_parent; @@ -44,6 +50,8 @@ namespace dxvk { dxvk::mutex m_monitorMutex; std::unordered_map m_monitorData; + std::atomic m_globalColorSpace; + }; diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index 1b4db77b8..367d58ecb 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -218,21 +218,17 @@ namespace dxvk { pDesc->AttachedToDesktop = 1; pDesc->Rotation = DXGI_MODE_ROTATION_UNSPECIFIED; pDesc->Monitor = m_monitor; - // TODO: When in HDR, flip this to 10 to appease apps that the - // transition has occured. - // If we support more than HDR10 in future, then we may want - // to visit that assumption. pDesc->BitsPerColor = 8; // This should only return DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 // (HDR) if the user has the HDR setting enabled in Windows. // Games can still punt into HDR mode by using CheckColorSpaceSupport // and SetColorSpace1. - // - // TODO: When we have a swapchain using SetColorSpace1 to - // DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020, we should use our monitor - // info to flip this over to that. - // As on Windows this would automatically engage HDR mode. - pDesc->ColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; + // + // We have no way of checking the actual Windows colorspace as the + // only public method for this *is* DXGI which we are re-implementing. + // So we just pick our color space based on the DXVK_HDR env var + // and the punting from SetColorSpace1. + pDesc->ColorSpace = m_monitorInfo->CurrentColorSpace(); pDesc->RedPrimary[0] = m_metadata.redPrimary[0]; pDesc->RedPrimary[1] = m_metadata.redPrimary[1]; pDesc->GreenPrimary[0] = m_metadata.greenPrimary[0]; diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index de3547cba..684c73044 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -536,7 +536,13 @@ namespace dxvk { return E_INVALIDARG; std::lock_guard lock(m_lockBuffer); - return m_presenter->SetColorSpace(ColorSpace); + HRESULT hr = m_presenter->SetColorSpace(ColorSpace); + if (SUCCEEDED(hr)) { + // If this was a colorspace other than our current one, + // punt us into that one on the DXGI output. + m_monitorInfo->PuntColorSpace(ColorSpace); + } + return hr; } From f25475d05e5af895031f2ce2bca550c75644495b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 6 Jan 2023 10:34:08 +0000 Subject: [PATCH 1001/1348] [dxgi] Normalize display metadata to something rational Sometimes we can't get an EDID if things aren't plumbed fully, or some displays just have broken EDIDs. This accounts for both of those cases by using some dummy data if we are missing information. Fixes value reporting to match Windows on common displays such as LG OLEDs. --- src/dxgi/dxgi_output.cpp | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index 367d58ecb..1ad9b49e9 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -19,6 +19,61 @@ #include "../util/util_time.h" namespace dxvk { + + static void NormalizeDisplayMetadata(wsi::WsiDisplayMetadata& metadata) { + // Use some dummy info when we have no hdr static metadata for the + // display or we were unable to obtain an EDID. + // + // These dummy values are the same as what Windows DXGI will output + // for panels with broken EDIDs such as LG OLEDs displays which + // have an entirely zeroed out luminance section in the hdr static + // metadata block. + // + // (Spec has 0 as 'undefined', which isn't really useful for an app + // to tonemap against.) + if (metadata.minLuminance == 0.0f) + metadata.minLuminance = 0.01f; + + if (metadata.maxLuminance == 0.0f) + metadata.maxLuminance = 1499.0f; + + if (metadata.maxFullFrameLuminance == 0.0f) + metadata.maxFullFrameLuminance = 799.0f; + + // If we have no RedPrimary/GreenPrimary/BluePrimary/WhitePoint due to + // the lack of a monitor exposing the chroma block or the lack of an EDID, + // simply just fall back to Rec.709 or Rec.2020 values depending on the default + // ColorSpace we started in. + // (Don't change based on punting, as this should be static for a display.) + if (metadata.redPrimary[0] == 0.0f && metadata.redPrimary[1] == 0.0f + && metadata.greenPrimary[0] == 0.0f && metadata.greenPrimary[1] == 0.0f + && metadata.bluePrimary[0] == 0.0f && metadata.bluePrimary[1] == 0.0f + && metadata.whitePoint[0] == 0.0f && metadata.whitePoint[1] == 0.0f) { + if (DxgiMonitorInfo::DefaultColorSpace() == DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709) { + // sRGB ColorSpace -> Rec.709 Primaries + metadata.redPrimary[0] = 0.640f; + metadata.redPrimary[1] = 0.330f; + metadata.greenPrimary[0] = 0.300f; + metadata.greenPrimary[1] = 0.600f; + metadata.bluePrimary[0] = 0.150f; + metadata.bluePrimary[1] = 0.060f; + metadata.whitePoint[0] = 0.3127f; + metadata.whitePoint[1] = 0.3290f; + } else { + // HDR10 ColorSpace -> Rec.2020 Primaries + // (Notably much bigger than any display is actually going to expose.) + metadata.redPrimary[0] = 0.708f; + metadata.redPrimary[1] = 0.292f; + metadata.greenPrimary[0] = 0.170f; + metadata.greenPrimary[1] = 0.797f; + metadata.bluePrimary[0] = 0.131f; + metadata.bluePrimary[1] = 0.046f; + metadata.whitePoint[0] = 0.3127f; + metadata.whitePoint[1] = 0.3290f; + } + } + } + DxgiOutput::DxgiOutput( const Com& factory, @@ -665,6 +720,10 @@ namespace dxvk { else Logger::err("DXGI: Failed to parse display metadata + colorimetry info, using blank."); + // Normalize either the display metadata we got back, or our + // blank one to get something sane here. + NormalizeDisplayMetadata(m_metadata); + monitorData.FrameStats.SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter(); monitorData.GammaCurve.Scale = { 1.0f, 1.0f, 1.0f }; monitorData.GammaCurve.Offset = { 0.0f, 0.0f, 0.0f }; From 3375cdf1fac066904dab3ee3ba1248b0292fe339 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 6 Jan 2023 14:32:33 +0000 Subject: [PATCH 1002/1348] [dxgi] Initialize DxgiOptions before DxgiMonitorInfo Needed to we can access DxgiOptions inside of DxgiMonitorInfo for the dxgi.enableHDR property coming up in a future commit. --- src/dxgi/dxgi_factory.cpp | 2 +- src/dxgi/dxgi_factory.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp index 10cf2861d..c7f3c302d 100644 --- a/src/dxgi/dxgi_factory.cpp +++ b/src/dxgi/dxgi_factory.cpp @@ -7,8 +7,8 @@ namespace dxvk { DxgiFactory::DxgiFactory(UINT Flags) : m_instance (new DxvkInstance()), - m_monitorInfo (this), m_options (m_instance->config()), + m_monitorInfo (this), m_flags (Flags) { for (uint32_t i = 0; m_instance->enumAdapters(i) != nullptr; i++) m_instance->enumAdapters(i)->logAdapterInfo(); diff --git a/src/dxgi/dxgi_factory.h b/src/dxgi/dxgi_factory.h index f398c78d9..4d75c277f 100644 --- a/src/dxgi/dxgi_factory.h +++ b/src/dxgi/dxgi_factory.h @@ -146,8 +146,8 @@ namespace dxvk { private: Rc m_instance; - DxgiMonitorInfo m_monitorInfo; DxgiOptions m_options; + DxgiMonitorInfo m_monitorInfo; UINT m_flags; HWND m_associatedWindow = nullptr; From c10b53ed3e4804dbde903914400641329bef805e Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 6 Jan 2023 14:41:30 +0000 Subject: [PATCH 1003/1348] [dxgi] Add dxgi.enableHDR option --- dxvk.conf | 12 ++++++++++++ src/dxgi/dxgi_factory.cpp | 2 +- src/dxgi/dxgi_monitor.cpp | 7 ++++--- src/dxgi/dxgi_monitor.h | 6 ++++-- src/dxgi/dxgi_options.cpp | 2 ++ src/dxgi/dxgi_options.h | 3 +++ src/dxgi/dxgi_output.cpp | 6 +++--- 7 files changed, 29 insertions(+), 9 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index 5c2746520..b5635a6e2 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -1,3 +1,15 @@ +# Expose the HDR10 ColorSpace (DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020) +# to the application by default. +# This shows to the game that the global Windows 'HDR Mode' is enabled. +# Many (broken) games will need this to be set to consider exposing HDR output +# as determine it based on the DXGIOutput's current ColorSpace instead of +# using CheckColorSpaceSupport. +# This defaults to the value of the DXVK_HDR environment variable. +# +# Supported values: True, False + +# dxgi.enableHDR = True + # Create the VkSurface on the first call to IDXGISwapChain::Present, # rather than when creating the swap chain. Some games that start # rendering with a different graphics API may require this option, diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp index c7f3c302d..cd548db5e 100644 --- a/src/dxgi/dxgi_factory.cpp +++ b/src/dxgi/dxgi_factory.cpp @@ -8,7 +8,7 @@ namespace dxvk { DxgiFactory::DxgiFactory(UINT Flags) : m_instance (new DxvkInstance()), m_options (m_instance->config()), - m_monitorInfo (this), + m_monitorInfo (this, m_options), m_flags (Flags) { for (uint32_t i = 0; m_instance->enumAdapters(i) != nullptr; i++) m_instance->enumAdapters(i)->logAdapterInfo(); diff --git a/src/dxgi/dxgi_monitor.cpp b/src/dxgi/dxgi_monitor.cpp index c0e25a7a3..0cac3c45a 100644 --- a/src/dxgi/dxgi_monitor.cpp +++ b/src/dxgi/dxgi_monitor.cpp @@ -2,8 +2,9 @@ namespace dxvk { - DxgiMonitorInfo::DxgiMonitorInfo(IUnknown* pParent) + DxgiMonitorInfo::DxgiMonitorInfo(IUnknown* pParent, const DxgiOptions& options) : m_parent(pParent) + , m_options(options) , m_globalColorSpace(DefaultColorSpace()) { } @@ -80,8 +81,8 @@ namespace dxvk { } - DXGI_COLOR_SPACE_TYPE DxgiMonitorInfo::DefaultColorSpace() { - return env::getEnvVar("DXVK_HDR") == "1" + DXGI_COLOR_SPACE_TYPE DxgiMonitorInfo::DefaultColorSpace() const { + return m_options.enableHDR ? DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 : DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; } diff --git a/src/dxgi/dxgi_monitor.h b/src/dxgi/dxgi_monitor.h index 4ab6c1b36..3a31a23cb 100644 --- a/src/dxgi/dxgi_monitor.h +++ b/src/dxgi/dxgi_monitor.h @@ -4,6 +4,7 @@ #include #include "dxgi_interfaces.h" +#include "dxgi_options.h" #include "../wsi/wsi_monitor.h" @@ -15,7 +16,7 @@ namespace dxvk { public: - DxgiMonitorInfo(IUnknown* pParent); + DxgiMonitorInfo(IUnknown* pParent, const DxgiOptions& options); ~DxgiMonitorInfo(); @@ -41,11 +42,12 @@ namespace dxvk { DXGI_COLOR_SPACE_TYPE STDMETHODCALLTYPE CurrentColorSpace() const; - static DXGI_COLOR_SPACE_TYPE DefaultColorSpace(); + DXGI_COLOR_SPACE_TYPE DefaultColorSpace() const; private: IUnknown* m_parent; + const DxgiOptions& m_options; dxvk::mutex m_monitorMutex; std::unordered_map m_monitorData; diff --git a/src/dxgi/dxgi_options.cpp b/src/dxgi/dxgi_options.cpp index 469692d19..1d9c96140 100644 --- a/src/dxgi/dxgi_options.cpp +++ b/src/dxgi/dxgi_options.cpp @@ -45,6 +45,8 @@ namespace dxvk { this->nvapiHack = false; else this->nvapiHack = config.getOption("dxgi.nvapiHack", true); + + this->enableHDR = config.getOption("dxgi.enableHDR", env::getEnvVar("DXVK_HDR") == "1"); } } diff --git a/src/dxgi/dxgi_options.h b/src/dxgi/dxgi_options.h index 8eb19d084..02f5c323a 100644 --- a/src/dxgi/dxgi_options.h +++ b/src/dxgi/dxgi_options.h @@ -35,6 +35,9 @@ namespace dxvk { /// Enables nvapi workaround bool nvapiHack; + + /// Enable HDR + bool enableHDR; }; } diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index 1ad9b49e9..f1787bb7c 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -20,7 +20,7 @@ namespace dxvk { - static void NormalizeDisplayMetadata(wsi::WsiDisplayMetadata& metadata) { + static void NormalizeDisplayMetadata(const DxgiMonitorInfo *pMonitorInfo, wsi::WsiDisplayMetadata& metadata) { // Use some dummy info when we have no hdr static metadata for the // display or we were unable to obtain an EDID. // @@ -49,7 +49,7 @@ namespace dxvk { && metadata.greenPrimary[0] == 0.0f && metadata.greenPrimary[1] == 0.0f && metadata.bluePrimary[0] == 0.0f && metadata.bluePrimary[1] == 0.0f && metadata.whitePoint[0] == 0.0f && metadata.whitePoint[1] == 0.0f) { - if (DxgiMonitorInfo::DefaultColorSpace() == DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709) { + if (pMonitorInfo->DefaultColorSpace() == DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709) { // sRGB ColorSpace -> Rec.709 Primaries metadata.redPrimary[0] = 0.640f; metadata.redPrimary[1] = 0.330f; @@ -722,7 +722,7 @@ namespace dxvk { // Normalize either the display metadata we got back, or our // blank one to get something sane here. - NormalizeDisplayMetadata(m_metadata); + NormalizeDisplayMetadata(m_monitorInfo, m_metadata); monitorData.FrameStats.SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter(); monitorData.GammaCurve.Scale = { 1.0f, 1.0f, 1.0f }; From 5115d80d5179d0158fae270616ef764dacc464c9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 5 Jan 2023 11:58:23 +0100 Subject: [PATCH 1004/1348] [dxbc] Handle dead code in shader binaries We should not emit any code when not inside a function. Fixes #3154. --- src/dxbc/dxbc_compiler.cpp | 11 +++++++++++ src/dxbc/dxbc_compiler.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 0514e0afe..f5664f87c 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -72,6 +72,17 @@ namespace dxvk { m_lastOp = m_currOp; m_currOp = ins.op; + if (!m_insideFunction + && ins.opClass != DxbcInstClass::CustomData + && ins.opClass != DxbcInstClass::Declaration + && ins.opClass != DxbcInstClass::HullShaderPhase + && ins.opClass != DxbcInstClass::NoOperation + && ins.op != DxbcOpcode::Label) { + if (!std::exchange(m_hasDeadCode, true)) + Logger::warn("DxbcCompiler: Dead code detected"); + return; + } + switch (ins.opClass) { case DxbcInstClass::Declaration: return this->emitDcl(ins); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 4720066cb..dbeec88f4 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -531,6 +531,7 @@ namespace dxvk { ////////////////////// // Global state stuff bool m_precise = true; + bool m_hasDeadCode = false; DxbcOpcode m_lastOp = DxbcOpcode::Nop; DxbcOpcode m_currOp = DxbcOpcode::Nop; From 389634f9b9ae1a88415066d95594072c9182453e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 6 Jan 2023 21:55:35 +0100 Subject: [PATCH 1005/1348] [d3d11] Fix D3D11Texture2D reference counting --- src/d3d11/d3d11_texture.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 631fceb6d..26e6c2700 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -1176,27 +1176,24 @@ namespace dxvk { ULONG STDMETHODCALLTYPE D3D11Texture2D::AddRef() { - uint32_t refCount = m_refCount++; + uint32_t refCount = D3D11DeviceChild::AddRef(); - if (unlikely(!refCount)) { - if (m_swapChain) + if (unlikely(m_swapChain != nullptr)) { + if (refCount == 1) m_swapChain->AddRef(); - - AddRefPrivate(); } - return refCount + 1; + return refCount; } ULONG STDMETHODCALLTYPE D3D11Texture2D::Release() { - uint32_t refCount = --m_refCount; + IUnknown* swapChain = m_swapChain; + uint32_t refCount = D3D11DeviceChild::Release(); - if (unlikely(!refCount)) { - if (m_swapChain) - m_swapChain->Release(); - - ReleasePrivate(); + if (unlikely(swapChain != nullptr)) { + if (refCount == 0) + swapChain->Release(); } return refCount; From 4612113227d1aa7b2c7f8ef6f663fa999bdf3c4d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 6 Jan 2023 23:47:55 +0100 Subject: [PATCH 1006/1348] [meta] Update hopelessly outdated README entry --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2897017b9..ae06e41a5 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ git clone --recursive https://github.com/doitsujin/dxvk.git ### Requirements: -- [wine 3.10](https://www.winehq.org/) or newer +- [wine 7.1](https://www.winehq.org/) or newer - [Meson](https://mesonbuild.com/) build system (at least version 0.49) - [Mingw-w64](https://www.mingw-w64.org) compiler and headers (at least version 10.0) - [glslang](https://github.com/KhronosGroup/glslang) compiler From f269cde7495caace24a3ebe45561cd6c285f0390 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 6 Jan 2023 19:36:08 +0100 Subject: [PATCH 1007/1348] [dxvk] Enable device features for dynamic multisample state --- src/dxvk/dxvk_adapter.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 290ea9841..dc4c06bbd 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -441,9 +441,15 @@ namespace dxvk { m_deviceFeatures.extDepthClipEnable.depthClipEnable; // Used to make pipeline library stuff less clunky + enabledFeatures.extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable = + m_deviceFeatures.extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable; enabledFeatures.extExtendedDynamicState3.extendedDynamicState3DepthClipEnable = m_deviceFeatures.extExtendedDynamicState3.extendedDynamicState3DepthClipEnable && m_deviceFeatures.extDepthClipEnable.depthClipEnable; + enabledFeatures.extExtendedDynamicState3.extendedDynamicState3RasterizationSamples = + m_deviceFeatures.extExtendedDynamicState3.extendedDynamicState3RasterizationSamples; + enabledFeatures.extExtendedDynamicState3.extendedDynamicState3SampleMask = + m_deviceFeatures.extExtendedDynamicState3.extendedDynamicState3SampleMask; // Used for both pNext shader module info, and fast-linking pipelines provided // that graphicsPipelineLibraryIndependentInterpolationDecoration is supported @@ -1020,7 +1026,10 @@ namespace dxvk { "\n", VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, "\n depthClipEnable : ", features.extDepthClipEnable.depthClipEnable ? "1" : "0", "\n", VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME, - "\n extendedDynamicState3DepthClipEnable : ", features.extExtendedDynamicState3.extendedDynamicState3DepthClipEnable ? "1" : "0", + "\n extDynamicState3AlphaToCoverageEnable : ", features.extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable ? "1" : "0", + "\n extDynamicState3DepthClipEnable : ", features.extExtendedDynamicState3.extendedDynamicState3DepthClipEnable ? "1" : "0", + "\n extDynamicState3RasterizationSamples : ", features.extExtendedDynamicState3.extendedDynamicState3RasterizationSamples ? "1" : "0", + "\n extDynamicState3SampleMask : ", features.extExtendedDynamicState3.extendedDynamicState3SampleMask ? "1" : "0", "\n", VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME, "\n fragmentShaderSampleInterlock : ", features.extFragmentShaderInterlock.fragmentShaderSampleInterlock ? "1" : "0", "\n fragmentShaderPixelInterlock : ", features.extFragmentShaderInterlock.fragmentShaderPixelInterlock ? "1" : "0", From 196fefec4c5ef6d336f06dc4a6e9786ae989d12e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 6 Jan 2023 20:53:28 +0100 Subject: [PATCH 1008/1348] [dxvk] Enable dynamic multisample state if supported by the device Eliminates stutter in situations where sample rate shading is used with MSAA. --- src/dxvk/dxvk_cmdlist.h | 16 +++++++++- src/dxvk/dxvk_context.cpp | 44 ++++++++++++++++++++++++--- src/dxvk/dxvk_context_state.h | 2 ++ src/dxvk/dxvk_graphics.cpp | 56 +++++++++++++++++++++++++---------- src/dxvk/dxvk_graphics.h | 2 +- src/dxvk/dxvk_shader.cpp | 26 ++++++++++++---- 6 files changed, 120 insertions(+), 26 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 17c725352..9edd768a6 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -798,7 +798,13 @@ namespace dxvk { m_vkd->vkCmdUpdateBuffer(getCmdBuffer(cmdBuffer), dstBuffer, dstOffset, dataSize, pData); } - + + + void cmdSetAlphaToCoverageState( + VkBool32 alphaToCoverageEnable) { + m_vkd->vkCmdSetAlphaToCoverageEnableEXT(m_cmd.execBuffer, alphaToCoverageEnable); + } + void cmdSetBlendConstants(const float blendConstants[4]) { m_vkd->vkCmdSetBlendConstants(m_cmd.execBuffer, blendConstants); @@ -868,6 +874,14 @@ namespace dxvk { } + void cmdSetMultisampleState( + VkSampleCountFlagBits sampleCount, + VkSampleMask sampleMask) { + m_vkd->vkCmdSetRasterizationSamplesEXT(m_cmd.execBuffer, sampleCount); + m_vkd->vkCmdSetSampleMaskEXT(m_cmd.execBuffer, sampleCount, &sampleMask); + } + + void cmdSetRasterizerState( VkCullModeFlags cullMode, VkFrontFace frontFace) { diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 14cb8b598..e59b97bc6 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2465,8 +2465,11 @@ namespace dxvk { m_flags.set(DxvkContextFlag::GpDirtyRasterizerState); } - if (unlikely(!m_features.test(DxvkContextFeature::VariableMultisampleRate))) { - if (rs.sampleCount != m_state.gp.state.rs.sampleCount()) + if (unlikely(rs.sampleCount != m_state.gp.state.rs.sampleCount())) { + if (!m_state.gp.state.ms.sampleCount()) + m_flags.set(DxvkContextFlag::GpDirtyMultisampleState); + + if (!m_features.test(DxvkContextFeature::VariableMultisampleRate)) m_flags.set(DxvkContextFlag::GpDirtyFramebuffer); } @@ -2497,7 +2500,9 @@ namespace dxvk { ms.sampleMask, ms.enableAlphaToCoverage); - m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + m_flags.set( + DxvkContextFlag::GpDirtyPipelineState, + DxvkContextFlag::GpDirtyMultisampleState); } @@ -4382,6 +4387,7 @@ namespace dxvk { DxvkContextFlag::GpDirtyXfbBuffers, DxvkContextFlag::GpDirtyBlendConstants, DxvkContextFlag::GpDirtyStencilRef, + DxvkContextFlag::GpDirtyMultisampleState, DxvkContextFlag::GpDirtyRasterizerState, DxvkContextFlag::GpDirtyViewport, DxvkContextFlag::GpDirtyDepthBias, @@ -4810,6 +4816,7 @@ namespace dxvk { DxvkContextFlag::GpDirtyXfbBuffers, DxvkContextFlag::GpDirtyBlendConstants, DxvkContextFlag::GpDirtyStencilRef, + DxvkContextFlag::GpDirtyMultisampleState, DxvkContextFlag::GpDirtyRasterizerState, DxvkContextFlag::GpDirtyViewport, DxvkContextFlag::GpDirtyDepthBias, @@ -4873,6 +4880,7 @@ namespace dxvk { DxvkContextFlag::GpDynamicDepthBias, DxvkContextFlag::GpDynamicDepthBounds, DxvkContextFlag::GpDynamicStencilRef, + DxvkContextFlag::GpDynamicMultisampleState, DxvkContextFlag::GpDynamicRasterizerState, DxvkContextFlag::GpIndependentSets); @@ -4905,6 +4913,10 @@ namespace dxvk { if (m_device->features().core.features.depthBounds) m_flags.set(DxvkContextFlag::GpDynamicDepthBounds); + + if (m_device->features().extExtendedDynamicState3.extendedDynamicState3RasterizationSamples + && m_device->features().extExtendedDynamicState3.extendedDynamicState3SampleMask) + m_flags.set(DxvkContextFlag::GpDynamicMultisampleState); } else { m_flags.set(m_state.gp.state.useDynamicDepthBias() ? DxvkContextFlag::GpDynamicDepthBias @@ -4918,7 +4930,9 @@ namespace dxvk { ? DxvkContextFlag::GpDynamicStencilRef : DxvkContextFlag::GpDirtyStencilRef); - m_flags.set(DxvkContextFlag::GpDirtyDepthStencilState); + m_flags.set( + DxvkContextFlag::GpDirtyDepthStencilState, + DxvkContextFlag::GpDirtyMultisampleState); } // If necessary, dirty descriptor sets due to layout incompatibilities @@ -5616,6 +5630,27 @@ namespace dxvk { } } + if (unlikely(m_flags.all(DxvkContextFlag::GpDirtyMultisampleState, + DxvkContextFlag::GpDynamicMultisampleState))) { + m_flags.clr(DxvkContextFlag::GpDirtyMultisampleState); + + // Infer actual sample count from both the multisample state + // and rasterizer state, just like during pipeline creation + VkSampleCountFlagBits sampleCount = VkSampleCountFlagBits(m_state.gp.state.ms.sampleCount()); + + if (!sampleCount) { + sampleCount = m_state.gp.state.rs.sampleCount() + ? VkSampleCountFlagBits(m_state.gp.state.rs.sampleCount()) + : VK_SAMPLE_COUNT_1_BIT; + } + + VkSampleMask sampleMask = m_state.gp.state.ms.sampleMask() & ((1u << sampleCount) - 1u); + m_cmd->cmdSetMultisampleState(sampleCount, sampleMask); + + if (m_device->features().extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable) + m_cmd->cmdSetAlphaToCoverageState(m_state.gp.state.ms.enableAlphaToCoverage()); + } + if (unlikely(m_flags.all(DxvkContextFlag::GpDirtyBlendConstants, DxvkContextFlag::GpDynamicBlendConstants))) { m_flags.clr(DxvkContextFlag::GpDirtyBlendConstants); @@ -6210,6 +6245,7 @@ namespace dxvk { DxvkContextFlag::GpDirtyXfbBuffers, DxvkContextFlag::GpDirtyBlendConstants, DxvkContextFlag::GpDirtyStencilRef, + DxvkContextFlag::GpDirtyMultisampleState, DxvkContextFlag::GpDirtyRasterizerState, DxvkContextFlag::GpDirtyViewport, DxvkContextFlag::GpDirtyDepthBias, diff --git a/src/dxvk/dxvk_context_state.h b/src/dxvk/dxvk_context_state.h index 922d2fb72..5c2218e89 100644 --- a/src/dxvk/dxvk_context_state.h +++ b/src/dxvk/dxvk_context_state.h @@ -35,6 +35,7 @@ namespace dxvk { GpDirtyDepthBias, ///< Depth bias has changed GpDirtyDepthBounds, ///< Depth bounds have changed GpDirtyStencilRef, ///< Stencil reference has changed + GpDirtyMultisampleState, ///< Multisample state has changed GpDirtyRasterizerState, ///< Cull mode and front face have changed GpDirtyViewport, ///< Viewport state has changed GpDirtySpecConstants, ///< Graphics spec constants are out of date @@ -43,6 +44,7 @@ namespace dxvk { GpDynamicDepthBias, ///< Depth bias is dynamic GpDynamicDepthBounds, ///< Depth bounds are dynamic GpDynamicStencilRef, ///< Stencil reference is dynamic + GpDynamicMultisampleState, ///< Multisample state is dynamic GpDynamicRasterizerState, ///< Cull mode and front face are dynamic GpDynamicVertexStrides, ///< Vertex buffer strides are dynamic GpIndependentSets, ///< Graphics pipeline layout was created with independent sets diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 0e461f713..aada10e0f 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -288,12 +288,13 @@ namespace dxvk { // Set up multisample state based on shader info as well // as rasterization state and render target sample counts. - if (state.ms.sampleCount()) - msInfo.rasterizationSamples = VkSampleCountFlagBits(state.ms.sampleCount()); - else if (state.rs.sampleCount()) - msInfo.rasterizationSamples = VkSampleCountFlagBits(state.rs.sampleCount()); - else - msInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + msInfo.rasterizationSamples = VkSampleCountFlagBits(state.ms.sampleCount()); + + if (!msInfo.rasterizationSamples) { + msInfo.rasterizationSamples = state.rs.sampleCount() + ? VkSampleCountFlagBits(state.rs.sampleCount()) + : VK_SAMPLE_COUNT_1_BIT; + } if (fs && fs->flags().test(DxvkShaderFlag::HasSampleRateShading)) { msInfo.sampleShadingEnable = VK_TRUE; @@ -392,12 +393,26 @@ namespace dxvk { : m_device(device) { auto vk = m_device->vkd(); - VkDynamicState dynamicState = VK_DYNAMIC_STATE_BLEND_CONSTANTS; + uint32_t dynamicStateCount = 0; + std::array dynamicStates = { }; + + if (m_device->features().extExtendedDynamicState3.extendedDynamicState3RasterizationSamples + && m_device->features().extExtendedDynamicState3.extendedDynamicState3SampleMask) { + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT; + + if (device->features().extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable) + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT; + } + + if (state.cbUseDynamicBlendConstants) + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_BLEND_CONSTANTS; + VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; - if (state.cbUseDynamicBlendConstants) { - dyInfo.dynamicStateCount = 1; - dyInfo.pDynamicStates = &dynamicState; + if (dynamicStateCount) { + dyInfo.dynamicStateCount = dynamicStateCount; + dyInfo.pDynamicStates = dynamicStates.data(); } VkPipelineCreateFlags flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; @@ -1095,12 +1110,23 @@ namespace dxvk { if (state.rs.flatShading() && m_shaders.fs->info().flatShadingInputs) return false; - // Multisample state must match in this case, and the - // library assumes that MSAA is disabled in this case. + // If dynamic multisample state is not supported and sample shading + // is enabled, the library is compiled with a sample count of 1. if (m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading)) { - if (state.ms.sampleCount() != VK_SAMPLE_COUNT_1_BIT - || state.ms.sampleMask() == 0 - || state.ms.enableAlphaToCoverage()) + bool canUseDynamicMultisampleState = + m_device->features().extExtendedDynamicState3.extendedDynamicState3RasterizationSamples && + m_device->features().extExtendedDynamicState3.extendedDynamicState3SampleMask; + + bool canUseDynamicAlphaToCoverage = canUseDynamicMultisampleState && + m_device->features().extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable; + + if (!canUseDynamicMultisampleState + && (state.ms.sampleCount() != VK_SAMPLE_COUNT_1_BIT + || state.ms.sampleMask() == 0)) + return false; + + if (!canUseDynamicAlphaToCoverage + && (state.ms.enableAlphaToCoverage())) return false; } } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index cfc424cd7..0a56d1451 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -113,7 +113,7 @@ namespace dxvk { VkPipelineColorBlendStateCreateInfo cbInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; VkPipelineMultisampleStateCreateInfo msInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; - uint32_t msSampleMask = 0u; + VkSampleMask msSampleMask = 0u; VkBool32 cbUseDynamicBlendConstants = VK_FALSE; std::array cbAttachments = { }; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 0e3195cae..d9d166553 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -1151,7 +1151,7 @@ namespace dxvk { // Set up dynamic state. We do not know any pipeline state // at this time, so make as much state dynamic as we can. uint32_t dynamicStateCount = 0; - std::array dynamicStates; + std::array dynamicStates; dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE; dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE; @@ -1167,6 +1167,19 @@ namespace dxvk { dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS; } + bool hasSampleRateShading = m_shader && m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading); + bool hasDynamicMultisampleState = hasSampleRateShading + && m_device->features().extExtendedDynamicState3.extendedDynamicState3RasterizationSamples + && m_device->features().extExtendedDynamicState3.extendedDynamicState3SampleMask; + + if (hasDynamicMultisampleState) { + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT; + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT; + + if (m_device->features().extExtendedDynamicState3.extendedDynamicState3AlphaToCoverageEnable) + dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT; + } + VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; dyInfo.dynamicStateCount = dynamicStateCount; dyInfo.pDynamicStates = dynamicStates.data(); @@ -1174,14 +1187,17 @@ namespace dxvk { // Set up multisample state. If sample shading is enabled, assume that // we only have one sample enabled, with a non-zero sample mask and no // alpha-to-coverage. - uint32_t msSampleMask = 0x1; + VkSampleMask msSampleMask = 0x1; VkPipelineMultisampleStateCreateInfo msInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; - msInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - msInfo.pSampleMask = &msSampleMask; msInfo.sampleShadingEnable = VK_TRUE; msInfo.minSampleShading = 1.0f; + if (!hasDynamicMultisampleState) { + msInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + msInfo.pSampleMask = &msSampleMask; + } + // All depth-stencil state is dynamic, so no need to initialize this. // Depth bounds testing is disabled on devices which don't support it. VkPipelineDepthStencilStateCreateInfo dsInfo = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; @@ -1201,7 +1217,7 @@ namespace dxvk { info.layout = m_layout->getPipelineLayout(true); info.basePipelineIndex = -1; - if (m_shader && m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading)) + if (hasSampleRateShading) info.pMultisampleState = &msInfo; VkPipeline pipeline = VK_NULL_HANDLE; From 3491895960e0d480e686a5a3489f7614bb51cd90 Mon Sep 17 00:00:00 2001 From: Hunter Kvalevog <91440203+hkva@users.noreply.github.com> Date: Sat, 7 Jan 2023 07:45:35 -0600 Subject: [PATCH 1009/1348] [dxvk] Remove SDL dummy window SDL >= 2.0.9 permits passing a nullptr window to SDL_Vulkan_GetInstanceExtensions, so there's no point in going though the work of creating a window just to call this function. --- src/dxvk/platform/dxvk_sdl2_exts.cpp | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/dxvk/platform/dxvk_sdl2_exts.cpp b/src/dxvk/platform/dxvk_sdl2_exts.cpp index 65a3f4993..701a3992b 100644 --- a/src/dxvk/platform/dxvk_sdl2_exts.cpp +++ b/src/dxvk/platform/dxvk_sdl2_exts.cpp @@ -13,30 +13,18 @@ namespace dxvk { DxvkNameSet DxvkPlatformExts::getInstanceExtensions() { - SDL_Window* window = SDL_CreateWindow( - "Dummy Window", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - 1, 1, - SDL_WINDOW_HIDDEN | SDL_WINDOW_VULKAN); - - if (window == nullptr) - throw DxvkError(str::format("SDL2 WSI: Failed to create dummy window. ", SDL_GetError())); - uint32_t extensionCount = 0; - if (!SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, nullptr)) + if (!SDL_Vulkan_GetInstanceExtensions(nullptr, &extensionCount, nullptr)) throw DxvkError(str::format("SDL2 WSI: Failed to get instance extension count. ", SDL_GetError())); auto extensionNames = std::vector(extensionCount); - if (!SDL_Vulkan_GetInstanceExtensions(window, &extensionCount, extensionNames.data())) + if (!SDL_Vulkan_GetInstanceExtensions(nullptr, &extensionCount, extensionNames.data())) throw DxvkError(str::format("SDL2 WSI: Failed to get instance extensions. ", SDL_GetError())); DxvkNameSet names; for (const char* name : extensionNames) names.add(name); - SDL_DestroyWindow(window); - return names; } From c11a63f5e577a93f902151621abfdaf00b30739a Mon Sep 17 00:00:00 2001 From: Beyley Thomas Date: Fri, 2 Dec 2022 19:11:43 -0800 Subject: [PATCH 1010/1348] [wsi] Add GLFW backend --- include/native/wsi/native_glfw.h | 25 ++++ include/native/wsi/native_wsi.h | 2 + meson.build | 14 ++- meson_options.txt | 2 + src/dxvk/meson.build | 4 + src/dxvk/platform/dxvk_glfw_exts.cpp | 49 ++++++++ src/wsi/glfw/wsi_monitor_glfw.cpp | 163 +++++++++++++++++++++++++++ src/wsi/glfw/wsi_platform_glfw.h | 23 ++++ src/wsi/glfw/wsi_window_glfw.cpp | 144 +++++++++++++++++++++++ src/wsi/meson.build | 8 ++ src/wsi/wsi_platform.h | 2 + 11 files changed, 432 insertions(+), 4 deletions(-) create mode 100644 include/native/wsi/native_glfw.h create mode 100644 src/dxvk/platform/dxvk_glfw_exts.cpp create mode 100644 src/wsi/glfw/wsi_monitor_glfw.cpp create mode 100644 src/wsi/glfw/wsi_platform_glfw.h create mode 100644 src/wsi/glfw/wsi_window_glfw.cpp diff --git a/include/native/wsi/native_glfw.h b/include/native/wsi/native_glfw.h new file mode 100644 index 000000000..e4946e02c --- /dev/null +++ b/include/native/wsi/native_glfw.h @@ -0,0 +1,25 @@ +#include + +#include + +namespace dxvk::wsi { + + inline GLFWwindow* fromHwnd(HWND hWindow) { + return reinterpret_cast(hWindow); + } + + inline HWND toHwnd(GLFWwindow* pWindow) { + return reinterpret_cast(pWindow); + } + + // Offset so null HMONITORs go to -1 + inline int32_t fromHmonitor(HMONITOR hMonitor) { + return static_cast(reinterpret_cast(hMonitor)) - 1; + } + + // Offset so -1 display id goes to 0 == NULL + inline HMONITOR toHmonitor(int32_t displayId) { + return reinterpret_cast(static_cast(displayId + 1)); + } + +} \ No newline at end of file diff --git a/include/native/wsi/native_wsi.h b/include/native/wsi/native_wsi.h index 00a299060..cfb64f12d 100644 --- a/include/native/wsi/native_wsi.h +++ b/include/native/wsi/native_wsi.h @@ -4,6 +4,8 @@ #error You shouldnt be using this code path. #elif DXVK_WSI_SDL2 #include "wsi/native_sdl2.h" +#elif DXVK_WSI_GLFW +#include "wsi/native_glfw.h" #else #error Unknown wsi! #endif \ No newline at end of file diff --git a/meson.build b/meson.build index 12d37300a..39a28e052 100644 --- a/meson.build +++ b/meson.build @@ -103,8 +103,6 @@ if platform == 'windows' dxvk_name_prefix = '' compiler_args += ['-DDXVK_WSI_WIN32'] else - lib_sdl2 = cpp.find_library('SDL2') - wrc = find_program('touch') wrc_generator = generator(wrc, output : [ '@BASENAME@_ignored.h' ], arguments : [ '@OUTPUT@' ] ) @@ -114,9 +112,17 @@ else './include/native/directx' ] - dxvk_wsi = 'sdl2' + dxvk_wsi = get_option('dxvk_native_wsi') + + if dxvk_wsi == 'sdl2' + lib_sdl2 = cpp.find_library('SDL2') + compiler_args += ['-DDXVK_WSI_SDL2'] + elif dxvk_wsi == 'glfw' + lib_glfw = cpp.find_library('glfw') + compiler_args += ['-DDXVK_WSI_GLFW'] + endif + dxvk_name_prefix = 'libdxvk_' - compiler_args += ['-DDXVK_WSI_SDL2'] link_args += [ '-static-libgcc', diff --git a/meson_options.txt b/meson_options.txt index 36fd01365..5ac9ea7b4 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -3,3 +3,5 @@ option('enable_d3d9', type : 'boolean', value : true, description: 'Build D3D9' option('enable_d3d10', type : 'boolean', value : true, description: 'Build D3D10') option('enable_d3d11', type : 'boolean', value : true, description: 'Build D3D11') option('build_id', type : 'boolean', value : false) + +option('dxvk_native_wsi', type : 'string', value : 'sdl2', description: 'WSI system to use if building natively.') \ No newline at end of file diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 387bc4d45..678ab268b 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -127,6 +127,10 @@ elif dxvk_wsi == 'sdl2' dxvk_src += [ 'platform/dxvk_sdl2_exts.cpp' ] +elif dxvk_wsi == 'glfw' + dxvk_src += [ + 'platform/dxvk_glfw_exts.cpp' + ] endif dxvk_extra_deps = [ dependency('threads') ] diff --git a/src/dxvk/platform/dxvk_glfw_exts.cpp b/src/dxvk/platform/dxvk_glfw_exts.cpp new file mode 100644 index 000000000..f5cfee88d --- /dev/null +++ b/src/dxvk/platform/dxvk_glfw_exts.cpp @@ -0,0 +1,49 @@ +#include "../dxvk_platform_exts.h" + +#include "../../vulkan/vulkan_loader.h" +#include + +namespace dxvk { + + DxvkPlatformExts DxvkPlatformExts::s_instance; + + std::string_view DxvkPlatformExts::getName() { + return "GLFW WSI"; + } + + DxvkNameSet DxvkPlatformExts::getInstanceExtensions() { + if (!glfwVulkanSupported()) + throw DxvkError(str::format("GLFW WSI: Vulkan is not supported in any capacity!")); + + uint32_t extensionCount = 0; + const char** extensionArray = glfwGetRequiredInstanceExtensions(&extensionCount); + + if (extensionCount == 0) + throw DxvkError(str::format("GLFW WSI: Failed to get required instance extensions")); + + DxvkNameSet names; + for (uint32_t i = 0; i < extensionCount; ++i) { + names.add(extensionArray[i]); + } + + return names; + } + + + DxvkNameSet DxvkPlatformExts::getDeviceExtensions( + uint32_t adapterId) { + return DxvkNameSet(); + } + + + void DxvkPlatformExts::initInstanceExtensions() { + //Nothing needs to be done here on GLFW + } + + + void DxvkPlatformExts::initDeviceExtensions( + const DxvkInstance* instance) { + //Nothing needs to be done here on GLFW + } + +} \ No newline at end of file diff --git a/src/wsi/glfw/wsi_monitor_glfw.cpp b/src/wsi/glfw/wsi_monitor_glfw.cpp new file mode 100644 index 000000000..7715118be --- /dev/null +++ b/src/wsi/glfw/wsi_monitor_glfw.cpp @@ -0,0 +1,163 @@ +#include "../wsi_monitor.h" + +#include "wsi/native_wsi.h" +#include "wsi_platform_glfw.h" + +#include "../../util/util_string.h" +#include "../../util/log/log.h" + +#include +#include + +namespace dxvk::wsi { + + HMONITOR getDefaultMonitor() { + return enumMonitors(0); + } + + + HMONITOR enumMonitors(uint32_t index) { + return isDisplayValid(int32_t(index)) + ? toHmonitor(index) + : nullptr; + } + + bool getDisplayName( + HMONITOR hMonitor, + WCHAR (&Name)[32]) { + const int32_t displayId = fromHmonitor(hMonitor); + + if (!isDisplayValid(displayId)) + return false; + + std::wstringstream nameStream; + nameStream << LR"(\\.\DISPLAY)" << (displayId + 1); + + std::wstring name = nameStream.str(); + + std::memset(Name, 0, sizeof(Name)); + name.copy(Name, name.length(), 0); + + return true; + } + + + bool getDesktopCoordinates( + HMONITOR hMonitor, + RECT* pRect) { + const int32_t displayId = fromHmonitor(hMonitor); + + if (!isDisplayValid(displayId)) + return false; + + int32_t displayCount = 0; + GLFWmonitor** monitors = glfwGetMonitors(&displayCount); + GLFWmonitor* monitor = monitors[displayId]; + + int32_t x; + int32_t y; + int32_t w; + int32_t h; + glfwGetMonitorWorkarea(monitor, &x, &y, &w, &h); + + pRect->left = x; + pRect->top = y; + pRect->right = x + w; + pRect->bottom = y + h; + + return true; + } + + static inline uint32_t roundToNextPow2(uint32_t num) { + if (num-- == 0) + return 0; + + num |= num >> 1; + num |= num >> 2; + num |= num >> 4; + num |= num >> 8; + num |= num >> 16; + + return ++num; + } + + + static inline void convertMode(const GLFWvidmode& mode, WsiMode* pMode) { + pMode->width = uint32_t(mode.width); + pMode->height = uint32_t(mode.height); + pMode->refreshRate = WsiRational{uint32_t(mode.refreshRate) * 1000, 1000}; + // BPP should always be a power of two + // to match Windows behaviour of including padding. + pMode->bitsPerPixel = roundToNextPow2(mode.blueBits + mode.redBits + mode.greenBits); + pMode->interlaced = false; + } + + + bool getDisplayMode( + HMONITOR hMonitor, + uint32_t ModeNumber, + WsiMode* pMode) { + const int32_t displayId = fromHmonitor(hMonitor); + int32_t displayCount = 0; + GLFWmonitor** monitors = glfwGetMonitors(&displayCount); + GLFWmonitor* monitor = monitors[displayId]; + + if (!isDisplayValid(displayId)) + return false; + + int32_t count = 0; + const GLFWvidmode* modes = glfwGetVideoModes(monitor, &count); + + if(ModeNumber >= uint32_t(count)) + return false; + + convertMode(modes[ModeNumber], pMode); + + return true; + } + + + bool getCurrentDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode) { + const int32_t displayId = fromHmonitor(hMonitor); + + if (!isDisplayValid(displayId)) + return false; + + int32_t displayCount = 0; + GLFWmonitor** monitors = glfwGetMonitors(&displayCount); + GLFWmonitor* monitor = monitors[displayId]; + + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + + convertMode(*mode, pMode); + + return true; + } + + + bool getDesktopDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode) { + const int32_t displayId = fromHmonitor(hMonitor); + + if (!isDisplayValid(displayId)) + return false; + + int32_t displayCount = 0; + GLFWmonitor** monitors = glfwGetMonitors(&displayCount); + GLFWmonitor* monitor = monitors[displayId]; + + //TODO: actually implement this properly, currently we just grab the current one + convertMode(*glfwGetVideoMode(monitor), pMode); + + return true; + } + + std::vector getMonitorEdid(HMONITOR hMonitor) { + Logger::err("getMonitorEdid not implemented on this platform."); + return {}; + } + +} \ No newline at end of file diff --git a/src/wsi/glfw/wsi_platform_glfw.h b/src/wsi/glfw/wsi_platform_glfw.h new file mode 100644 index 000000000..25753494f --- /dev/null +++ b/src/wsi/glfw/wsi_platform_glfw.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../../vulkan/vulkan_loader.h" +#include + +#include "../wsi_monitor.h" + +namespace dxvk::wsi { + + /** + * \brief Impl-dependent state + */ + struct DxvkWindowState { + }; + + inline bool isDisplayValid(int32_t displayId) { + int32_t displayCount = 0; + glfwGetMonitors(&displayCount); + + return displayId < displayCount && displayId >= 0; + } + +} \ No newline at end of file diff --git a/src/wsi/glfw/wsi_window_glfw.cpp b/src/wsi/glfw/wsi_window_glfw.cpp new file mode 100644 index 000000000..700312507 --- /dev/null +++ b/src/wsi/glfw/wsi_window_glfw.cpp @@ -0,0 +1,144 @@ +#include "../wsi_window.h" + +#include "native/wsi/native_wsi.h" +#include "wsi_platform_glfw.h" + +#include "../../util/util_string.h" +#include "../../util/log/log.h" + +#include +#include "../../vulkan/vulkan_loader.h" +#include + +namespace dxvk::wsi { + + void getWindowSize( + HWND hWindow, + uint32_t* pWidth, + uint32_t* pHeight) { + GLFWwindow* window = fromHwnd(hWindow); + + int32_t w, h; + glfwGetWindowSize(window, &w, &h); + + if (pWidth) + *pWidth = uint32_t(w); + + if (pHeight) + *pHeight = uint32_t(h); + } + + + void resizeWindow( + HWND hWindow, + DxvkWindowState* pState, + uint32_t Width, + uint32_t Height) { + GLFWwindow* window = fromHwnd(hWindow); + + glfwSetWindowSize(window, int32_t(Width), int32_t(Height)); + } + + + bool setWindowMode( + HMONITOR hMonitor, + HWND hWindow, + const WsiMode& pMode) { + const int32_t displayId = fromHmonitor(hMonitor); + GLFWwindow* window = fromHwnd(hWindow); + + if (!isDisplayValid(displayId)) + return false; + + int32_t displayCount = 0; + GLFWmonitor** monitors = glfwGetMonitors(&displayCount); + GLFWmonitor* monitor = monitors[displayId]; + + GLFWvidmode wantedMode = {}; + wantedMode.width = pMode.width; + wantedMode.height = pMode.height; + wantedMode.refreshRate = pMode.refreshRate.numerator != 0 + ? pMode.refreshRate.numerator / pMode.refreshRate.denominator + : 0; + // TODO: Implement lookup format for bitsPerPixel here. + + glfwSetWindowMonitor(window, monitor, 0, 0, wantedMode.width, wantedMode.width, wantedMode.refreshRate); + + return true; + } + + bool enterFullscreenMode( + HMONITOR hMonitor, + HWND hWindow, + DxvkWindowState* pState, + bool ModeSwitch) { + const int32_t displayId = fromHmonitor(hMonitor); + GLFWwindow* window = fromHwnd(hWindow); + + if (!isDisplayValid(displayId)) + return false; + + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + auto videoMode = glfwGetVideoMode(monitor); + + // TODO: Set this on the correct monitor. + // Docs aren't clear on this... + glfwSetWindowMonitor(window, monitor, 0, 0, videoMode->width, videoMode->height, videoMode->refreshRate); + + return true; + } + + + bool leaveFullscreenMode( + HWND hWindow, + DxvkWindowState* pState, + bool restoreCoordinates) { + GLFWwindow* window = fromHwnd(hWindow); + + GLFWmonitor* monitor = glfwGetPrimaryMonitor(); + auto videoMode = glfwGetVideoMode(monitor); + glfwSetWindowMonitor(window, nullptr, 0, 0, videoMode->width, videoMode->height, videoMode->refreshRate); + + return true; + } + + + bool restoreDisplayMode() { + // Don't need to do anything with GLFW here. + return true; + } + + + HMONITOR getWindowMonitor(HWND hWindow) { + // TODO: implement this with glfwGetWindowMonitor + // (or maybe not? glfwGetWindowMonitor only seems to reference *fullscreen* windows) + // GLFWwindow* window = fromHwnd(hWindow); + const int32_t displayId = 0; + + return toHmonitor(displayId); + } + + + bool isWindow(HWND hWindow) { + GLFWwindow* window = fromHwnd(hWindow); + return window != nullptr; + } + + void updateFullscreenWindow( + HMONITOR hMonitor, + HWND hWindow, + bool forceTopmost) { + // Don't need to do anything with GLFW here. + } + + VkResult createSurface( + HWND hWindow, + PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, + VkInstance instance, + VkSurfaceKHR* pSurface) { + GLFWwindow* window = fromHwnd(hWindow); + + return glfwCreateWindowSurface(instance, window, nullptr, pSurface); + } + +} \ No newline at end of file diff --git a/src/wsi/meson.build b/src/wsi/meson.build index 17efa26b2..27603ceab 100644 --- a/src/wsi/meson.build +++ b/src/wsi/meson.build @@ -12,12 +12,20 @@ wsi_sdl2_src = [ 'sdl2/wsi_window_sdl2.cpp', ] +wsi_glfw_src = [ + 'glfw/wsi_monitor_glfw.cpp', + 'glfw/wsi_window_glfw.cpp', +] + if dxvk_wsi == 'win32' wsi_src = wsi_common_src + wsi_win32_src wsi_deps = [ dep_displayinfo ] elif dxvk_wsi == 'sdl2' wsi_src = wsi_common_src + wsi_sdl2_src wsi_deps = [ dep_displayinfo, lib_sdl2 ] +elif dxvk_wsi == 'glfw' + wsi_src = wsi_common_src + wsi_glfw_src + wsi_deps = [ dep_displayinfo, lib_glfw ] else error('Unknown wsi') endif diff --git a/src/wsi/wsi_platform.h b/src/wsi/wsi_platform.h index 2cbcd2292..38b5c5aa1 100644 --- a/src/wsi/wsi_platform.h +++ b/src/wsi/wsi_platform.h @@ -4,4 +4,6 @@ #include "win32/wsi_platform_win32.h" #elif defined(DXVK_WSI_SDL2) #include "sdl2/wsi_platform_sdl2.h" +#elif defined(DXVK_WSI_GLFW) +#include "glfw/wsi_platform_glfw.h" #endif From 3ed0a4fd439f366248253f8066632a7e68336ffc Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sat, 7 Jan 2023 23:49:38 +0100 Subject: [PATCH 1011/1348] [util] Set Secret World Legends launcher to SM 2 --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index d7e69778a..fc466b535 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -691,6 +691,11 @@ namespace dxvk { { R"(\\ffxiv\.exe$)", {{ { "d3d9.textureMemory", "0" }, }} }, + /* Secret World Legends launcher * + * Invisible UI */ + { R"(\\Secret World Legends\\ClientPatcher\.exe$)", {{ + { "d3d9.shaderModel", "2" }, + }} }, }}; From 5206d97710d2f694224abeef99a560277f7d055a Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 9 Jan 2023 11:36:30 +0000 Subject: [PATCH 1012/1348] [dxgi] Workaround UE4 DX11 + HDR crashes Unreal Engine 4 titles use AGS/NVAPI to try and enable HDR globally. They can key this off IDXGIOutput::GetDesc1's ColorSpace being HDR10. Many of these UE4 games statically link against AGS. This is a problem as when UE4 tries to enable HDR via AGS, it does not check if AGSContext, and the display info etc are nullptr unlike the rest of the code using AGS. So we need to special-case UE4 titles to disable reporting a HDR when they are in DX11 mode. The simplest way to do this is to key off the fact that all UE4 titles have an executable ending with "-Win64-Shipping". We check if d3d12.dll is present, to determine what path in UE4 we are on, as there are some games that ship both and support HDR. (eg. The Dark Pictures: House of Ashes, 1281590) Luckily for us, they only load d3d12.dll on the D3D12 render path so we can key off that to force disable HDR only in D3D11. --- src/dxgi/dxgi_options.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/dxgi/dxgi_options.cpp b/src/dxgi/dxgi_options.cpp index 1d9c96140..be8c6ef5c 100644 --- a/src/dxgi/dxgi_options.cpp +++ b/src/dxgi/dxgi_options.cpp @@ -26,6 +26,39 @@ namespace dxvk { return id; } + + static bool isHDRDisallowed() { +#ifdef _WIN32 + // Unreal Engine 4 titles use AGS/NVAPI to try and enable + // HDR globally. + // The game checks IDXGIOutput::GetDesc1's ColorSpace + // being HDR10 to see if it should enable HDR. + // Many of these UE4 games statically link against AGS. + // + // This is a problem as when UE4 tries to enable HDR via AGS, + // it does not check if AGSContext, and the display info etc + // are nullptr unlike the rest of the code using AGS. + // So we need to special-case UE4 titles to disable reporting a HDR + // when they are in DX11 mode. + // + // The simplest way to do this is to key off the fact that all + // UE4 titles have an executable ending with "-Win64-Shipping". + // + // We check if d3d12.dll is present, to determine what path in + // UE4 we are on, as there are some games that ship both and support HDR. + // (eg. The Dark Pictures: House of Ashes, 1281590) + // Luckily for us, they only load d3d12.dll on the D3D12 render path + // so we can key off that to force disable HDR only in D3D11. + std::string exeName = env::getExeName(); + bool isUE4 = exeName.find("-Win64-Shipping") != std::string::npos; + bool hasD3D12 = GetModuleHandleA("d3d12") != nullptr; + + if (isUE4 && !hasD3D12) + return true; +#endif + return false; + } + DxgiOptions::DxgiOptions(const Config& config) { // Fetch these as a string representing a hexadecimal number and parse it. @@ -47,6 +80,10 @@ namespace dxvk { this->nvapiHack = config.getOption("dxgi.nvapiHack", true); this->enableHDR = config.getOption("dxgi.enableHDR", env::getEnvVar("DXVK_HDR") == "1"); + if (this->enableHDR && isHDRDisallowed()) { + Logger::info("HDR was configured to be enabled, but has been force disabled as a UE4 DX11 game was detected."); + this->enableHDR = false; + } } } From 6a4fe06ac668918b7328dcc139b4bd71863fbc3e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 9 Jan 2023 15:51:07 +0100 Subject: [PATCH 1013/1348] [dxvk] Fix incorrect flags for null fs pipeline layout --- src/dxvk/dxvk_pipemanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 76ad41e9a..c8889ac6a 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -433,8 +433,8 @@ namespace dxvk { DxvkShaderPipelineLibrary* DxvkPipelineManager::createNullFsPipelineLibrary() { std::lock_guard lock(m_mutex); - auto layout = createPipelineLayout(DxvkBindingLayout( - VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT)); + DxvkBindingLayout bindings(VK_SHADER_STAGE_FRAGMENT_BIT); + auto layout = createPipelineLayout(bindings); auto iter = m_shaderLibraries.emplace( std::piecewise_construct, From 06fb93daf09ad6ccaa0ccd061b98ca9eccbfb090 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 9 Jan 2023 18:29:15 +0100 Subject: [PATCH 1014/1348] [dxvk] Only create state cache file on demand If no pipelines are ever written to it, we should not create the cache file in the first place. --- src/dxvk/dxvk_state_cache.cpp | 84 +++++++++++++++++++++++------------ src/dxvk/dxvk_state_cache.h | 7 ++- 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index fa3322821..b1d71b6ca 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -242,26 +242,7 @@ namespace dxvk { bool newFile = (useStateCache == "reset") || (!readCacheFile()); if (newFile) { - Logger::warn("DXVK: Creating new state cache file"); - - // Start with an empty file - std::ofstream file(getCacheFileName().c_str(), - std::ios_base::binary | - std::ios_base::trunc); - - if (!file && env::createDirectory(getCacheDir())) { - file = std::ofstream(getCacheFileName().c_str(), - std::ios_base::binary | - std::ios_base::trunc); - } - - // Write header with the current version number - DxvkStateCacheHeader header; - - auto data = reinterpret_cast(&header); - auto size = sizeof(header); - - file.write(data, size); + auto file = openCacheFileForWrite(true); // Write all valid entries to the cache file in // case we're recovering a corrupted cache file @@ -454,12 +435,13 @@ namespace dxvk { bool DxvkStateCache::readCacheFile() { - // Open state file and just fail if it doesn't exist - std::ifstream ifile(getCacheFileName().c_str(), std::ios_base::binary); + // Return success if the file was not found. + // This way we will only create it on demand. + std::ifstream ifile = openCacheFileForRead(); if (!ifile) { Logger::warn("DXVK: No state cache file found"); - return false; + return true; } // The header stores the state cache version, @@ -771,11 +753,8 @@ namespace dxvk { m_writerQueue.pop(); } - if (!file.is_open()) { - file.open(getCacheFileName().c_str(), - std::ios_base::binary | - std::ios_base::app); - } + if (!file.is_open()) + file = openCacheFileForWrite(false); writeCacheEntry(file, entry); } @@ -806,6 +785,55 @@ namespace dxvk { } + std::ifstream DxvkStateCache::openCacheFileForRead() const { + return std::ifstream(getCacheFileName().c_str(), std::ios_base::binary); + } + + + std::ofstream DxvkStateCache::openCacheFileForWrite(bool recreate) const { + std::ofstream file; + + if (!recreate) { + // Apparently there's no other way to check whether + // the file is empty after creating an ofstream + recreate = !openCacheFileForRead(); + } + + if (recreate) { + file = std::ofstream(getCacheFileName().c_str(), + std::ios_base::binary | + std::ios_base::trunc); + + if (!file && env::createDirectory(getCacheDir())) { + file = std::ofstream(getCacheFileName().c_str(), + std::ios_base::binary | + std::ios_base::trunc); + } + } else { + file = std::ofstream(getCacheFileName().c_str(), + std::ios_base::binary | + std::ios_base::app); + } + + if (!file) + return file; + + if (recreate) { + Logger::warn("DXVK: Creating new state cache file"); + + // Write header with the current version number + DxvkStateCacheHeader header; + + auto data = reinterpret_cast(&header); + auto size = sizeof(header); + + file.write(data, size); + } + + return file; + } + + std::string DxvkStateCache::getCacheDir() const { return env::getEnvVar("DXVK_STATE_CACHE_PATH"); } diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index 3df28a4f9..24ec1001c 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -160,7 +160,12 @@ namespace dxvk { void createWriter(); str::path_string getCacheFileName() const; - + + std::ifstream openCacheFileForRead() const; + + std::ofstream openCacheFileForWrite( + bool recreate) const; + std::string getCacheDir() const; }; From e426ec09a1f5d02aa7b1589c40c083235df9df41 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 8 Jan 2023 00:51:13 +0100 Subject: [PATCH 1015/1348] [d3d11,dxbc] Add d3d11.forceSampleRateShading option --- dxvk.conf | 9 +++++++++ src/d3d11/d3d11_options.cpp | 1 + src/d3d11/d3d11_options.h | 5 +++++ src/dxbc/dxbc_compiler.cpp | 8 ++++++++ src/dxbc/dxbc_options.cpp | 1 + src/dxbc/dxbc_options.h | 4 ++++ 6 files changed, 28 insertions(+) diff --git a/dxvk.conf b/dxvk.conf index b5635a6e2..473ca91bd 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -201,6 +201,15 @@ # d3d9.invariantPosition = True +# Forces per-sample rate shading when MSAA is enabled, rather than per-pixel +# shading. May improve visual clarity at a significant performance cost, but +# may also introduce visual issues in some games. +# +# Supported values: True, False + +# d3d11.forceSampleRateShading = False + + # Forces the sample count of all textures to 1, and performs # the needed fixups in resolve operations and shaders. # diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index f4eee5b23..bcac396b9 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -23,6 +23,7 @@ namespace dxvk { this->samplerLodBias = config.getOption("d3d11.samplerLodBias", 0.0f); this->invariantPosition = config.getOption("d3d11.invariantPosition", true); this->floatControls = config.getOption("d3d11.floatControls", true); + this->forceSampleRateShading = config.getOption("d3d11.forceSampleRateShading", false); this->disableMsaa = config.getOption("d3d11.disableMsaa", false); this->enableContextLock = config.getOption("d3d11.enableContextLock", false); this->deferSurfaceCreation = config.getOption("dxgi.deferSurfaceCreation", false); diff --git a/src/d3d11/d3d11_options.h b/src/d3d11/d3d11_options.h index 1b636db18..99bca0765 100644 --- a/src/d3d11/d3d11_options.h +++ b/src/d3d11/d3d11_options.h @@ -99,6 +99,11 @@ namespace dxvk { /// for a single window that may interfere with each other. bool deferSurfaceCreation; + /// Enables sample rate shading by interpolating fragment shader + /// inputs at the sample location rather than pixel center, + /// unless otherwise specified by the application. + bool forceSampleRateShading; + /// Forces the sample count of all textures to be 1, and /// performs the required shader and resolve fixups. bool disableMsaa; diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index f5664f87c..fb107da63 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -726,6 +726,14 @@ namespace dxvk { m_module.decorate(varId, spv::DecorationSample); } + if (m_moduleInfo.options.forceSampleRateShading) { + if (im == DxbcInterpolationMode::Linear + || im == DxbcInterpolationMode::LinearNoPerspective) { + m_module.enableCapability(spv::CapabilitySampleRateShading); + m_module.decorate(varId, spv::DecorationSample); + } + } + // Declare the input slot as defined m_inputMask |= 1u << regIdx; m_vArrayLength = std::max(m_vArrayLength, regIdx + 1); diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 0d8486793..e642a0dfd 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -38,6 +38,7 @@ namespace dxvk { zeroInitWorkgroupMemory = options.zeroInitWorkgroupMemory; forceVolatileTgsmAccess = options.forceVolatileTgsmAccess; disableMsaa = options.disableMsaa; + forceSampleRateShading = options.forceSampleRateShading; enableSampleShadingInterlock = device->features().extFragmentShaderInterlock.fragmentShaderSampleInterlock; // Figure out float control flags to match D3D11 rules diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index b29cf5d44..2612a024f 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -43,6 +43,10 @@ namespace dxvk { /// Replace ld_ms with ld bool disableMsaa = false; + /// Force sample rate shading by using sample + /// interpolation for fragment shader inputs + bool forceSampleRateShading = false; + // Enable per-sample interlock if supported bool enableSampleShadingInterlock = false; From 0342a25e61ca855ed958076607ffa415d3372618 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 8 Jan 2023 01:05:50 +0100 Subject: [PATCH 1016/1348] [d3d9,dxso] Add d3d9.forceSampleRateShading option --- dxvk.conf | 1 + src/d3d9/d3d9_fixed_function.cpp | 11 +++++++++-- src/d3d9/d3d9_fixed_function.h | 1 + src/d3d9/d3d9_options.cpp | 1 + src/d3d9/d3d9_options.h | 3 +++ src/dxso/dxso_compiler.cpp | 6 ++++++ src/dxso/dxso_options.cpp | 1 + src/dxso/dxso_options.h | 3 +++ 8 files changed, 25 insertions(+), 2 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index 473ca91bd..626c187a6 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -208,6 +208,7 @@ # Supported values: True, False # d3d11.forceSampleRateShading = False +# d3d9.forceSampleRateShading = False # Forces the sample count of all textures to 1, and performs diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index c24cf064e..f8225222e 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -14,6 +14,7 @@ namespace dxvk { D3D9FixedFunctionOptions::D3D9FixedFunctionOptions(const D3D9Options* options) { invariantPosition = options->invariantPosition; + forceSampleRateShading = options->forceSampleRateShading; } uint32_t DoFixedFunctionFog(D3D9ShaderSpecConstantManager& spec, SpirvModule& spvModule, const D3D9FogContext& fogCtx) { @@ -933,10 +934,16 @@ namespace dxvk { uint32_t ptr = m_module.newVar(ptrType, storageClass); - if (builtin == spv::BuiltInMax) + if (builtin == spv::BuiltInMax) { m_module.decorateLocation(ptr, slot); - else + + if (isPS() && input && m_options.forceSampleRateShading) { + m_module.enableCapability(spv::CapabilitySampleRateShading); + m_module.decorate(ptr, spv::DecorationSample); + } + } else { m_module.decorateBuiltIn(ptr, builtin); + } bool diffuseOrSpec = semantic == DxsoSemantic{ DxsoUsage::Color, 0 } || semantic == DxsoSemantic{ DxsoUsage::Color, 1 }; diff --git a/src/d3d9/d3d9_fixed_function.h b/src/d3d9/d3d9_fixed_function.h index a75458713..104f044cd 100644 --- a/src/d3d9/d3d9_fixed_function.h +++ b/src/d3d9/d3d9_fixed_function.h @@ -49,6 +49,7 @@ namespace dxvk { D3D9FixedFunctionOptions(const D3D9Options* options); bool invariantPosition; + bool forceSampleRateShading; }; // Returns new oFog if VS diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index 33938c4f7..0ecb38953 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -63,6 +63,7 @@ namespace dxvk { this->enableDialogMode = config.getOption ("d3d9.enableDialogMode", false); this->forceSamplerTypeSpecConstants = config.getOption ("d3d9.forceSamplerTypeSpecConstants", false); this->forceSwapchainMSAA = config.getOption ("d3d9.forceSwapchainMSAA", -1); + this->forceSampleRateShading = config.getOption ("d3d9.forceSampleRateShading", false); this->forceAspectRatio = config.getOption ("d3d9.forceAspectRatio", ""); this->allowDiscard = config.getOption ("d3d9.allowDiscard", true); this->enumerateByDisplays = config.getOption ("d3d9.enumerateByDisplays", true); diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index 43fcbb954..592c27d18 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -123,6 +123,9 @@ namespace dxvk { /// Forces an MSAA level on the swapchain int32_t forceSwapchainMSAA; + /// Forces sample rate shading + bool forceSampleRateShading; + /// Allow D3DLOCK_DISCARD bool allowDiscard; diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 8b9b16dd3..f453f8172 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -3192,6 +3192,12 @@ void DxsoCompiler::emitControlFlowGenericLoop( m_module.decorateLocation(inputPtr.id, slot); + if (m_programInfo.type() == DxsoProgramType::PixelShader + && m_moduleInfo.options.forceSampleRateShading) { + m_module.enableCapability(spv::CapabilitySampleRateShading); + m_module.decorate(inputPtr.id, spv::DecorationSample); + } + std::string name = str::format("in_", elem.semantic.usage, elem.semantic.usageIndex); m_module.setDebugName(inputPtr.id, name.c_str()); diff --git a/src/dxso/dxso_options.cpp b/src/dxso/dxso_options.cpp index 163c39b96..d9f7834ed 100644 --- a/src/dxso/dxso_options.cpp +++ b/src/dxso/dxso_options.cpp @@ -25,6 +25,7 @@ namespace dxvk { invariantPosition = options.invariantPosition; forceSamplerTypeSpecConstants = options.forceSamplerTypeSpecConstants; + forceSampleRateShading = options.forceSampleRateShading; vertexFloatConstantBufferAsSSBO = pDevice->GetVertexConstantLayout().floatSize() > devInfo.core.properties.limits.maxUniformBufferRange; diff --git a/src/dxso/dxso_options.h b/src/dxso/dxso_options.h index 437f97532..cd0ab8e11 100644 --- a/src/dxso/dxso_options.h +++ b/src/dxso/dxso_options.h @@ -36,6 +36,9 @@ namespace dxvk { /// Works around a game bug in Halo CE where it gives cube textures to 2d/volume samplers bool forceSamplerTypeSpecConstants; + /// Interpolate pixel shader inputs at the sample location rather than pixel center + bool forceSampleRateShading; + /// Should the SWVP float constant buffer be a SSBO (because of the size on NV) bool vertexFloatConstantBufferAsSSBO; From 8052347a227f048de1698794d0fdcd8cc6328eb9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 10 Jan 2023 02:25:18 +0100 Subject: [PATCH 1017/1348] [dxvk] Keep more empty system memory chunks alive --- src/dxvk/dxvk_memory.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 52f58aefc..e88dff88e 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -522,14 +522,23 @@ namespace dxvk { if (this->shouldFreeEmptyChunks(type->heap, 0)) return true; - // Even if we have enough memory to spare, only keep - // one chunk of each type around to save memory. + // Only keep a small number of chunks of each type around to save memory. + uint32_t numEmptyChunks = 0; + for (const auto& c : type->chunks) { if (c != chunk && c->isEmpty() && c->isCompatible(chunk)) - return true; + numEmptyChunks += 1; } - return false; + // Be a bit more lenient on system memory since data uploads may otherwise + // lead to a large number of allocations and deallocations at runtime. + uint32_t maxEmptyChunks = env::is32BitHostPlatform() ? 2 : 4; + + if ((type->memType.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) + || !(type->memType.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) + maxEmptyChunks = 1; + + return numEmptyChunks >= maxEmptyChunks; } From 8011a40843c5dbdc62c4d65bff27c5f6337fcf97 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 10 Jan 2023 20:35:51 +0100 Subject: [PATCH 1018/1348] Revert "[dxbc] Handle dead code in shader binaries" Apparently this regressed something, but the reporter who asked for this fix in the first place did not specify what, so let's just revert this and break the whole thing again until we get something to actually work with. This reverts commit 5115d80d5179d0158fae270616ef764dacc464c9. --- src/dxbc/dxbc_compiler.cpp | 11 ----------- src/dxbc/dxbc_compiler.h | 1 - 2 files changed, 12 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index fb107da63..ea14d6202 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -72,17 +72,6 @@ namespace dxvk { m_lastOp = m_currOp; m_currOp = ins.op; - if (!m_insideFunction - && ins.opClass != DxbcInstClass::CustomData - && ins.opClass != DxbcInstClass::Declaration - && ins.opClass != DxbcInstClass::HullShaderPhase - && ins.opClass != DxbcInstClass::NoOperation - && ins.op != DxbcOpcode::Label) { - if (!std::exchange(m_hasDeadCode, true)) - Logger::warn("DxbcCompiler: Dead code detected"); - return; - } - switch (ins.opClass) { case DxbcInstClass::Declaration: return this->emitDcl(ins); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index dbeec88f4..4720066cb 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -531,7 +531,6 @@ namespace dxvk { ////////////////////// // Global state stuff bool m_precise = true; - bool m_hasDeadCode = false; DxbcOpcode m_lastOp = DxbcOpcode::Nop; DxbcOpcode m_currOp = DxbcOpcode::Nop; From f76a7c285cfd3e3159fb35dd60576d1f85c43b22 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 9 Jan 2023 14:39:55 +0100 Subject: [PATCH 1019/1348] [dxvk] Rework DxvkShaderPipelineLibrary to work with multiple shaders --- src/dxvk/dxvk_graphics.cpp | 21 +++- src/dxvk/dxvk_shader.cpp | 210 +++++++++++++++++++++++++++---------- src/dxvk/dxvk_shader.h | 57 ++++++++-- 3 files changed, 221 insertions(+), 67 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index aada10e0f..424e5c36d 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -1094,10 +1094,15 @@ namespace dxvk { return false; if (m_shaders.fs != nullptr) { - // If the fragment shader has inputs not produced by the - // vertex shader, we need to patch the fragment shader - uint32_t vsIoMask = m_shaders.vs->info().outputMask; + // If the fragment shader has inputs not produced by the last + // pre-rasterization stage, we need to patch the fragment shader uint32_t fsIoMask = m_shaders.fs->info().inputMask; + uint32_t vsIoMask = m_shaders.vs->info().outputMask; + + if (m_shaders.gs != nullptr) + vsIoMask = m_shaders.gs->info().outputMask; + else if (m_shaders.tes != nullptr) + vsIoMask = m_shaders.tes->info().outputMask; if ((vsIoMask & fsIoMask) != fsIoMask) return false; @@ -1226,10 +1231,16 @@ namespace dxvk { DxvkShaderStageInfo stageInfo(m_device); if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) { - stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, m_vsLibrary->getModuleIdentifier(), &key.scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, m_vsLibrary->getModuleIdentifier(VK_SHADER_STAGE_VERTEX_BIT), &key.scState.scInfo); + if (m_shaders.tcs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_vsLibrary->getModuleIdentifier(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT), &key.scState.scInfo); + if (m_shaders.tes != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_vsLibrary->getModuleIdentifier(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT), &key.scState.scInfo); + if (m_shaders.gs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, m_vsLibrary->getModuleIdentifier(VK_SHADER_STAGE_GEOMETRY_BIT), &key.scState.scInfo); if (m_shaders.fs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, m_fsLibrary->getModuleIdentifier(), &key.scState.scInfo); + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, m_fsLibrary->getModuleIdentifier(VK_SHADER_STAGE_FRAGMENT_BIT), &key.scState.scInfo); } else { stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, key.shState.vsInfo), &key.scState.scInfo); diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index d9d166553..740276dab 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -893,9 +893,21 @@ namespace dxvk { const DxvkBindingLayoutObjects* layout) : m_device (device), m_stats (&manager->m_stats), - m_shader (shader), m_layout (layout) { - + if (shader) { + switch (shader->info().stage) { + case VK_SHADER_STAGE_VERTEX_BIT: + m_shaders.vs = shader; + break; + case VK_SHADER_STAGE_FRAGMENT_BIT: + m_shaders.fs = shader; + break; + case VK_SHADER_STAGE_COMPUTE_BIT: + m_shaders.cs = shader; + break; + default: ; + } + } } @@ -904,17 +916,19 @@ namespace dxvk { } - VkShaderModuleIdentifierEXT DxvkShaderPipelineLibrary::getModuleIdentifier() { + VkShaderModuleIdentifierEXT DxvkShaderPipelineLibrary::getModuleIdentifier( + VkShaderStageFlagBits stage) { std::lock_guard lock(m_identifierMutex); + auto identifier = getShaderIdentifier(stage); - if (!m_identifier.identifierSize) { + if (!identifier->identifierSize) { // Unfortunate, but we'll have to decode the // shader code here to retrieve the identifier - SpirvCodeBuffer spirvCode = this->getShaderCode(); - this->generateModuleIdentifierLocked(spirvCode); + SpirvCodeBuffer spirvCode = this->getShaderCode(stage); + this->generateModuleIdentifierLocked(identifier, spirvCode); } - return m_identifier; + return *identifier; } @@ -925,9 +939,7 @@ namespace dxvk { if (m_device->mustTrackPipelineLifetime()) m_useCount += 1; - VkShaderStageFlagBits stage = getShaderStage(); - - VkPipeline& pipeline = (stage == VK_SHADER_STAGE_VERTEX_BIT && !args.depthClipEnable) + VkPipeline& pipeline = (m_shaders.vs && !args.depthClipEnable) ? m_pipelineNoDepthClip : m_pipeline; @@ -988,22 +1000,20 @@ namespace dxvk { VkPipeline DxvkShaderPipelineLibrary::compileShaderPipelineLocked( const DxvkShaderPipelineLibraryCompileArgs& args) { - VkShaderStageFlagBits stage = getShaderStage(); - VkPipeline pipeline = VK_NULL_HANDLE; - - if (m_shader) - m_shader->notifyLibraryCompile(); + this->notifyLibraryCompile(); // If this is not the first time we're compiling the pipeline, // try to get a cache hit using the shader module identifier // so that we don't have to decompress our SPIR-V shader again. + VkPipeline pipeline = VK_NULL_HANDLE; + if (m_compiledOnce && canUsePipelineCacheControl()) { - pipeline = this->compileShaderPipeline(args, stage, + pipeline = this->compileShaderPipeline(args, VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT); } if (!pipeline) - pipeline = this->compileShaderPipeline(args, stage, 0); + pipeline = this->compileShaderPipeline(args, 0); // Well that didn't work if (!pipeline) @@ -1012,7 +1022,7 @@ namespace dxvk { // Increment stat counter the first time this // shader pipeline gets compiled successfully if (!m_compiledOnce) { - if (stage == VK_SHADER_STAGE_COMPUTE_BIT) + if (m_shaders.cs) m_stats->numComputePipelines += 1; else m_stats->numGraphicsLibraries += 1; @@ -1026,46 +1036,49 @@ namespace dxvk { VkPipeline DxvkShaderPipelineLibrary::compileShaderPipeline( const DxvkShaderPipelineLibraryCompileArgs& args, - VkShaderStageFlagBits stage, VkPipelineCreateFlags flags) { DxvkShaderStageInfo stageInfo(m_device); + VkShaderStageFlags stageMask = getShaderStages(); { std::lock_guard lock(m_identifierMutex); + VkShaderStageFlags stages = stageMask; - if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) { - // Fail if we have no idenfitier for whatever reason, caller - // should fall back to the slow path if this happens - if (!m_identifier.identifierSize) - return VK_NULL_HANDLE; + while (stages) { + auto stage = VkShaderStageFlagBits(stages & -stages); + auto identifier = getShaderIdentifier(stage); - stageInfo.addStage(stage, m_identifier, nullptr); - } else { - // Decompress code and generate identifier as needed - SpirvCodeBuffer spirvCode = this->getShaderCode(); + if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) { + // Fail if we have no idenfitier for whatever reason, caller + // should fall back to the slow path if this happens + if (!identifier->identifierSize) + return VK_NULL_HANDLE; - if (!m_identifier.identifierSize) - this->generateModuleIdentifierLocked(spirvCode); + stageInfo.addStage(stage, *identifier, nullptr); + } else { + // Decompress code and generate identifier as needed + SpirvCodeBuffer spirvCode = this->getShaderCode(stage); - stageInfo.addStage(stage, std::move(spirvCode), nullptr); + if (!identifier->identifierSize) + this->generateModuleIdentifierLocked(identifier, spirvCode); + + stageInfo.addStage(stage, std::move(spirvCode), nullptr); + } + + stages &= stages - 1; } } - switch (stage) { - case VK_SHADER_STAGE_VERTEX_BIT: - return compileVertexShaderPipeline(args, stageInfo, flags); - break; + if (stageMask & VK_SHADER_STAGE_VERTEX_BIT) + return compileVertexShaderPipeline(args, stageInfo, flags); - case VK_SHADER_STAGE_FRAGMENT_BIT: - return compileFragmentShaderPipeline(stageInfo, flags); - break; + if (stageMask & VK_SHADER_STAGE_FRAGMENT_BIT) + return compileFragmentShaderPipeline(stageInfo, flags); - case VK_SHADER_STAGE_COMPUTE_BIT: - return compileComputeShaderPipeline(stageInfo, flags); + if (stageMask & VK_SHADER_STAGE_COMPUTE_BIT) + return compileComputeShaderPipeline(stageInfo, flags); - default: - // Should be unreachable - return VK_NULL_HANDLE; - } + // Should be unreachable + return VK_NULL_HANDLE; } @@ -1167,7 +1180,7 @@ namespace dxvk { dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS; } - bool hasSampleRateShading = m_shader && m_shader->flags().test(DxvkShaderFlag::HasSampleRateShading); + bool hasSampleRateShading = m_shaders.fs && m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading); bool hasDynamicMultisampleState = hasSampleRateShading && m_device->features().extExtendedDynamicState3.extendedDynamicState3RasterizationSamples && m_device->features().extExtendedDynamicState3.extendedDynamicState3SampleMask; @@ -1252,20 +1265,23 @@ namespace dxvk { } - SpirvCodeBuffer DxvkShaderPipelineLibrary::getShaderCode() const { + SpirvCodeBuffer DxvkShaderPipelineLibrary::getShaderCode(VkShaderStageFlagBits stage) const { // As a special case, it is possible that we have to deal with // a null shader, but the pipeline library extension requires // us to always specify a fragment shader for fragment stages, // so we need to return a dummy shader in that case. - if (!m_shader) + DxvkShader* shader = getShader(stage); + + if (!shader) return SpirvCodeBuffer(dxvk_dummy_frag); - return m_shader->getCode(m_layout, DxvkShaderModuleCreateInfo()); + return shader->getCode(m_layout, DxvkShaderModuleCreateInfo()); } void DxvkShaderPipelineLibrary::generateModuleIdentifierLocked( - const SpirvCodeBuffer& spirvCode) { + VkShaderModuleIdentifierEXT* identifier, + const SpirvCodeBuffer& spirvCode) { auto vk = m_device->vkd(); if (!canUsePipelineCacheControl()) @@ -1276,17 +1292,101 @@ namespace dxvk { info.pCode = spirvCode.data(); vk->vkGetShaderModuleCreateInfoIdentifierEXT( - vk->device(), &info, &m_identifier); + vk->device(), &info, identifier); } - VkShaderStageFlagBits DxvkShaderPipelineLibrary::getShaderStage() const { - VkShaderStageFlagBits stage = VK_SHADER_STAGE_FRAGMENT_BIT; + VkShaderStageFlags DxvkShaderPipelineLibrary::getShaderStages() const { + if (m_shaders.vs) { + VkShaderStageFlags result = VK_SHADER_STAGE_VERTEX_BIT; - if (m_shader != nullptr) - stage = m_shader->info().stage; + if (m_shaders.tcs) + result |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; - return stage; + if (m_shaders.tes) + result |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + + if (m_shaders.gs) + result |= VK_SHADER_STAGE_GEOMETRY_BIT; + + return result; + } + + if (m_shaders.cs) + return VK_SHADER_STAGE_COMPUTE_BIT; + + // Must be a fragment shader even if fs is null + return VK_SHADER_STAGE_FRAGMENT_BIT; + } + + + DxvkShader* DxvkShaderPipelineLibrary::getShader( + VkShaderStageFlagBits stage) const { + switch (stage) { + case VK_SHADER_STAGE_VERTEX_BIT: + return m_shaders.vs; + + case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: + return m_shaders.tcs; + + case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: + return m_shaders.tes; + + case VK_SHADER_STAGE_GEOMETRY_BIT: + return m_shaders.gs; + + case VK_SHADER_STAGE_FRAGMENT_BIT: + return m_shaders.fs; + + case VK_SHADER_STAGE_COMPUTE_BIT: + return m_shaders.cs; + + default: + return nullptr; + } + } + + + VkShaderModuleIdentifierEXT* DxvkShaderPipelineLibrary::getShaderIdentifier( + VkShaderStageFlagBits stage) { + switch (stage) { + case VK_SHADER_STAGE_VERTEX_BIT: + return &m_identifiers.vs; + + case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: + return &m_identifiers.tcs; + + case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: + return &m_identifiers.tes; + + case VK_SHADER_STAGE_GEOMETRY_BIT: + return &m_identifiers.gs; + + case VK_SHADER_STAGE_FRAGMENT_BIT: + return &m_identifiers.fs; + + case VK_SHADER_STAGE_COMPUTE_BIT: + return &m_identifiers.cs; + + default: + return nullptr; + } + } + + + void DxvkShaderPipelineLibrary::notifyLibraryCompile() const { + if (m_shaders.vs) { + // Only notify the shader itself if we're actually + // building the shader's standalone pipeline library + if (!m_shaders.tcs && !m_shaders.tes && !m_shaders.gs) + m_shaders.vs->notifyLibraryCompile(); + } + + if (m_shaders.fs) + m_shaders.fs->notifyLibraryCompile(); + + if (m_shaders.cs) + m_shaders.cs->notifyLibraryCompile(); } diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 6e5a21057..9ab46fb4f 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -396,6 +396,38 @@ namespace dxvk { }; + /** + * \brief Shader set + * + * Stores a set of shader pointers + * for use in a pipeline library. + */ + struct DxvkShaderSet { + DxvkShader* vs = nullptr; + DxvkShader* tcs = nullptr; + DxvkShader* tes = nullptr; + DxvkShader* gs = nullptr; + DxvkShader* fs = nullptr; + DxvkShader* cs = nullptr; + }; + + + /** + * \brief Shader identifer set + * + * Stores a set of shader module identifiers + * for use in a pipeline library. + */ + struct DxvkShaderIdentifierSet { + VkShaderModuleIdentifierEXT vs = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT }; + VkShaderModuleIdentifierEXT tcs = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT }; + VkShaderModuleIdentifierEXT tes = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT }; + VkShaderModuleIdentifierEXT gs = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT }; + VkShaderModuleIdentifierEXT fs = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT }; + VkShaderModuleIdentifierEXT cs = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT }; + }; + + /** * \brief Shader pipeline library * @@ -423,9 +455,11 @@ namespace dxvk { * Can be used to compile an optimized pipeline using the same * shader code, but without having to wait for the pipeline * library for this shader shader to compile first. + * \param [in] stage Shader stage to query * \returns Shader module identifier */ - VkShaderModuleIdentifierEXT getModuleIdentifier(); + VkShaderModuleIdentifierEXT getModuleIdentifier( + VkShaderStageFlagBits stage); /** * \brief Acquires pipeline handle for the given set of arguments @@ -461,7 +495,7 @@ namespace dxvk { const DxvkDevice* m_device; DxvkPipelineStats* m_stats; - DxvkShader* m_shader; + DxvkShaderSet m_shaders; const DxvkBindingLayoutObjects* m_layout; dxvk::mutex m_mutex; @@ -471,7 +505,7 @@ namespace dxvk { bool m_compiledOnce = false; dxvk::mutex m_identifierMutex; - VkShaderModuleIdentifierEXT m_identifier = { VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT }; + DxvkShaderIdentifierSet m_identifiers; void destroyShaderPipelinesLocked(); @@ -480,7 +514,6 @@ namespace dxvk { VkPipeline compileShaderPipeline( const DxvkShaderPipelineLibraryCompileArgs& args, - VkShaderStageFlagBits stage, VkPipelineCreateFlags flags); VkPipeline compileVertexShaderPipeline( @@ -496,12 +529,22 @@ namespace dxvk { const DxvkShaderStageInfo& stageInfo, VkPipelineCreateFlags flags); - SpirvCodeBuffer getShaderCode() const; + SpirvCodeBuffer getShaderCode( + VkShaderStageFlagBits stage) const; void generateModuleIdentifierLocked( - const SpirvCodeBuffer& spirvCode); + VkShaderModuleIdentifierEXT* identifier, + const SpirvCodeBuffer& spirvCode); - VkShaderStageFlagBits getShaderStage() const; + VkShaderStageFlags getShaderStages() const; + + DxvkShader* getShader( + VkShaderStageFlagBits stage) const; + + VkShaderModuleIdentifierEXT* getShaderIdentifier( + VkShaderStageFlagBits stage); + + void notifyLibraryCompile() const; bool canUsePipelineCacheControl() const; From 5e42230b954353d5643f02791bfafe2256dee7c7 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 9 Jan 2023 14:54:55 +0100 Subject: [PATCH 1020/1348] [dxvk] Add patch vertex count to shader info struct --- src/dxvk/dxvk_graphics.cpp | 7 +++++++ src/dxvk/dxvk_shader.cpp | 7 +++++++ src/dxvk/dxvk_shader.h | 2 ++ 3 files changed, 16 insertions(+) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 424e5c36d..1a653c871 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -1093,6 +1093,13 @@ namespace dxvk { || state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT) return false; + if (m_shaders.tcs != nullptr) { + // If tessellation shaders are present, the input patch + // vertex count must match the shader's definition. + if (m_shaders.tcs->info().patchVertexCount != state.ia.patchVertexCount()) + return false; + } + if (m_shaders.fs != nullptr) { // If the fragment shader has inputs not produced by the last // pre-rasterization stage, we need to patch the fragment shader diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 740276dab..7a51eda86 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -1107,6 +1107,12 @@ namespace dxvk { dyInfo.dynamicStateCount = dynamicStateCount; dyInfo.pDynamicStates = dynamicStates.data(); + // If a tessellation control shader is present, grab the patch vertex count + VkPipelineTessellationStateCreateInfo tsInfo = { VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO }; + + if (m_shaders.tcs) + tsInfo.patchControlPoints = m_shaders.tcs->info().patchVertexCount; + // All viewport state is dynamic, so we do not need to initialize this. VkPipelineViewportStateCreateInfo vpInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; @@ -1140,6 +1146,7 @@ namespace dxvk { info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | flags; info.stageCount = stageInfo.getStageCount(); info.pStages = stageInfo.getStageInfos(); + info.pTessellationState = m_shaders.tcs ? &tsInfo : nullptr; info.pViewportState = &vpInfo; info.pRasterizationState = &rsInfo; info.pDynamicState = &dyInfo; diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 9ab46fb4f..b3f6123a3 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -58,6 +58,8 @@ namespace dxvk { const char* uniformData = nullptr; /// Rasterized stream, or -1 int32_t xfbRasterizedStream = 0; + /// Tess control patch vertex count + uint32_t patchVertexCount = 0; /// Transform feedback vertex strides uint32_t xfbStrides[MaxNumXfbBuffers] = { }; }; From b916dc04e53cbb38ba160ff7fd30e6c496f9756b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 9 Jan 2023 14:55:10 +0100 Subject: [PATCH 1021/1348] [dxbc] Fill in patch vertex count info --- src/dxbc/dxbc_compiler.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index ea14d6202..110f9b0d4 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -258,6 +258,9 @@ namespace dxvk { info.uniformSize = m_immConstData.size(); info.uniformData = m_immConstData.data(); + if (m_programInfo.type() == DxbcProgramType::HullShader) + info.patchVertexCount = m_hs.vertexCountIn; + if (m_programInfo.type() == DxbcProgramType::PixelShader && m_ps.pushConstantId) info.pushConstSize = sizeof(DxbcPushConstants); From f9ff96d727fc36b684d073db587fe0de11fbe891 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 9 Jan 2023 15:04:03 +0100 Subject: [PATCH 1022/1348] [dxvk] Implement checks for pre-raster pipeline library compatibility --- src/dxvk/dxvk_pipemanager.cpp | 2 +- src/dxvk/dxvk_shader.cpp | 37 +++++++++++++++++++++++------------ src/dxvk/dxvk_shader.h | 5 ++++- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index c8889ac6a..39551d094 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -466,7 +466,7 @@ namespace dxvk { bool DxvkPipelineManager::canPrecompileShader( const Rc& shader) const { - if (!shader->canUsePipelineLibrary()) + if (!shader->canUsePipelineLibrary(true)) return false; if (shader->info().stage == VK_SHADER_STAGE_COMPUTE_BIT) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 7a51eda86..5dec0a7d7 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -161,7 +161,7 @@ namespace dxvk { // Don't set pipeline library flag if the shader // doesn't actually support pipeline libraries - m_needsLibraryCompile = canUsePipelineLibrary(); + m_needsLibraryCompile = canUsePipelineLibrary(true); } @@ -209,19 +209,30 @@ namespace dxvk { } - bool DxvkShader::canUsePipelineLibrary() const { - // Pipeline libraries are unsupported for geometry and - // tessellation stages since we'd need to compile them - // all into one library - if (m_info.stage != VK_SHADER_STAGE_VERTEX_BIT - && m_info.stage != VK_SHADER_STAGE_FRAGMENT_BIT - && m_info.stage != VK_SHADER_STAGE_COMPUTE_BIT) - return false; + bool DxvkShader::canUsePipelineLibrary(bool standalone) const { + if (standalone) { + // Standalone pipeline libraries are unsupported for geometry + // and tessellation stages since we'd need to compile them + // all into one library + if (m_info.stage != VK_SHADER_STAGE_VERTEX_BIT + && m_info.stage != VK_SHADER_STAGE_FRAGMENT_BIT + && m_info.stage != VK_SHADER_STAGE_COMPUTE_BIT) + return false; - // Standalone vertex shaders must export vertex position - if (m_info.stage == VK_SHADER_STAGE_VERTEX_BIT - && !m_flags.test(DxvkShaderFlag::ExportsPosition)) - return false; + // Standalone vertex shaders must export vertex position + if (m_info.stage == VK_SHADER_STAGE_VERTEX_BIT + && !m_flags.test(DxvkShaderFlag::ExportsPosition)) + return false; + } else { + // Tessellation control shaders must define a valid vertex count + if (m_info.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT + && (m_info.patchVertexCount < 1 || m_info.patchVertexCount > 32)) + return false; + + // We don't support GPL with transform feedback right now + if (m_flags.test(DxvkShaderFlag::HasTransformFeedback)) + return false; + } // Spec constant selectors are only supported in graphics if (m_specConstantMask & (1u << MaxNumSpecConstants)) diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index b3f6123a3..245f96f64 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -178,9 +178,12 @@ namespace dxvk { * * This is true for any vertex, fragment, or compute shader that does not * require additional pipeline state to be compiled into something useful. + * \param [in] standalone Set to \c true to evaluate this in the context + * of a single-shader pipeline library, or \c false for a pre-raster + * shader library consisting of multiple shader stages. * \returns \c true if this shader can be used with pipeline libraries */ - bool canUsePipelineLibrary() const; + bool canUsePipelineLibrary(bool standalone) const; /** * \brief Dumps SPIR-V shader From 17529101d55bcfecd951611f2c24bd182b607a9d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 9 Jan 2023 15:56:58 +0100 Subject: [PATCH 1023/1348] [dxvk] Allow creating pipeline libraries with more than one shader --- src/dxvk/dxvk_pipemanager.cpp | 69 ++++++++++++++------ src/dxvk/dxvk_pipemanager.h | 11 ++-- src/dxvk/dxvk_shader.cpp | 116 ++++++++++++++++++++++++++++------ src/dxvk/dxvk_shader.h | 80 ++++++++++++++++++----- 4 files changed, 218 insertions(+), 58 deletions(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 39551d094..821bea8af 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -248,8 +248,11 @@ namespace dxvk { if (pair != m_computePipelines.end()) return &pair->second; + DxvkShaderPipelineLibraryKey key; + key.addShader(shaders.cs); + auto layout = createPipelineLayout(shaders.cs->getBindings()); - auto library = findPipelineLibraryLocked(shaders.cs); + auto library = findPipelineLibraryLocked(key); auto iter = m_computePipelines.emplace( std::piecewise_construct, @@ -290,9 +293,28 @@ namespace dxvk { DxvkShaderPipelineLibrary* vsLibrary = nullptr; DxvkShaderPipelineLibrary* fsLibrary = nullptr; - if (shaders.tcs == nullptr && shaders.tes == nullptr && shaders.gs == nullptr) { - vsLibrary = findPipelineLibraryLocked(shaders.vs); - fsLibrary = findPipelineLibraryLocked(shaders.fs); + if (m_device->canUseGraphicsPipelineLibrary()) { + DxvkShaderPipelineLibraryKey vsKey; + vsKey.addShader(shaders.vs); + + if (shaders.tcs != nullptr) + vsKey.addShader(shaders.tcs); + if (shaders.tes != nullptr) + vsKey.addShader(shaders.tes); + if (shaders.gs != nullptr) + vsKey.addShader(shaders.gs); + + if (vsKey.canUsePipelineLibrary()) + vsLibrary = findPipelineLibraryLocked(vsKey); + + if (vsLibrary) { + DxvkShaderPipelineLibraryKey fsKey; + + if (shaders.fs != nullptr) + fsKey.addShader(shaders.fs); + + fsLibrary = findPipelineLibraryLocked(fsKey); + } } auto iter = m_graphicsPipelines.emplace( @@ -339,7 +361,10 @@ namespace dxvk { void DxvkPipelineManager::registerShader( const Rc& shader) { if (canPrecompileShader(shader)) { - auto library = createPipelineLibrary(shader); + DxvkShaderPipelineLibraryKey key; + key.addShader(shader); + + auto library = createPipelineLibrary(key); m_workers.compilePipelineLibrary(library, DxvkPipelinePriority::Normal); } @@ -353,7 +378,10 @@ namespace dxvk { return; // Dispatch high-priority compile job - auto library = findPipelineLibrary(shader); + DxvkShaderPipelineLibraryKey key; + key.addShader(shader); + + auto library = findPipelineLibrary(key); if (library) m_workers.compilePipelineLibrary(library, DxvkPipelinePriority::High); @@ -416,46 +444,49 @@ namespace dxvk { DxvkShaderPipelineLibrary* DxvkPipelineManager::createPipelineLibrary( - const Rc& shader) { + const DxvkShaderPipelineLibraryKey& key) { std::lock_guard lock(m_mutex); - auto layout = createPipelineLayout(shader->getBindings()); + return createPipelineLibraryLocked(key); + } - DxvkShaderPipelineLibraryKey key; - key.shader = shader; + + DxvkShaderPipelineLibrary* DxvkPipelineManager::createPipelineLibraryLocked( + const DxvkShaderPipelineLibraryKey& key) { + auto bindings = key.getBindings(); + auto layout = createPipelineLayout(bindings); auto iter = m_shaderLibraries.emplace( std::piecewise_construct, std::tuple(key), - std::tuple(m_device, this, shader.ptr(), layout)); + std::tuple(m_device, this, key, layout)); return &iter.first->second; } DxvkShaderPipelineLibrary* DxvkPipelineManager::createNullFsPipelineLibrary() { std::lock_guard lock(m_mutex); + DxvkShaderPipelineLibraryKey key; + DxvkBindingLayout bindings(VK_SHADER_STAGE_FRAGMENT_BIT); auto layout = createPipelineLayout(bindings); auto iter = m_shaderLibraries.emplace( std::piecewise_construct, std::tuple(), - std::tuple(m_device, this, nullptr, layout)); + std::tuple(m_device, this, key, layout)); return &iter.first->second; } DxvkShaderPipelineLibrary* DxvkPipelineManager::findPipelineLibrary( - const Rc& shader) { + const DxvkShaderPipelineLibraryKey& key) { std::lock_guard lock(m_mutex); - return findPipelineLibraryLocked(shader); + return findPipelineLibraryLocked(key); } DxvkShaderPipelineLibrary* DxvkPipelineManager::findPipelineLibraryLocked( - const Rc& shader) { - DxvkShaderPipelineLibraryKey key; - key.shader = shader; - + const DxvkShaderPipelineLibraryKey& key) { auto pair = m_shaderLibraries.find(key); if (pair == m_shaderLibraries.end()) return nullptr; @@ -465,7 +496,7 @@ namespace dxvk { bool DxvkPipelineManager::canPrecompileShader( - const Rc& shader) const { + const Rc& shader) const { if (!shader->canUsePipelineLibrary(true)) return false; diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index b43e12cc8..4a1f79228 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -295,18 +295,21 @@ namespace dxvk { const DxvkBindingLayout& layout); DxvkShaderPipelineLibrary* createPipelineLibrary( - const Rc& shader); + const DxvkShaderPipelineLibraryKey& key); + + DxvkShaderPipelineLibrary* createPipelineLibraryLocked( + const DxvkShaderPipelineLibraryKey& key); DxvkShaderPipelineLibrary* createNullFsPipelineLibrary(); DxvkShaderPipelineLibrary* findPipelineLibrary( - const Rc& shader); + const DxvkShaderPipelineLibraryKey& key); DxvkShaderPipelineLibrary* findPipelineLibraryLocked( - const Rc& shader); + const DxvkShaderPipelineLibraryKey& key); bool canPrecompileShader( - const Rc& shader) const; + const Rc& shader) const; }; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 5dec0a7d7..9df41bb32 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -897,28 +897,108 @@ namespace dxvk { } - DxvkShaderPipelineLibrary::DxvkShaderPipelineLibrary( - const DxvkDevice* device, - DxvkPipelineManager* manager, - DxvkShader* shader, - const DxvkBindingLayoutObjects* layout) - : m_device (device), - m_stats (&manager->m_stats), - m_layout (layout) { - if (shader) { + DxvkShaderPipelineLibraryKey::DxvkShaderPipelineLibraryKey() { + + } + + + DxvkShaderPipelineLibraryKey::~DxvkShaderPipelineLibraryKey() { + + } + + + DxvkShaderSet DxvkShaderPipelineLibraryKey::getShaderSet() const { + DxvkShaderSet result; + + for (uint32_t i = 0; i < m_shaderCount; i++) { + auto shader = m_shaders[i].ptr(); + switch (shader->info().stage) { - case VK_SHADER_STAGE_VERTEX_BIT: - m_shaders.vs = shader; - break; - case VK_SHADER_STAGE_FRAGMENT_BIT: - m_shaders.fs = shader; - break; - case VK_SHADER_STAGE_COMPUTE_BIT: - m_shaders.cs = shader; - break; + case VK_SHADER_STAGE_VERTEX_BIT: result.vs = shader; break; + case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: result.tcs = shader; break; + case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: result.tes = shader; break; + case VK_SHADER_STAGE_GEOMETRY_BIT: result.gs = shader; break; + case VK_SHADER_STAGE_FRAGMENT_BIT: result.fs = shader; break; + case VK_SHADER_STAGE_COMPUTE_BIT: result.cs = shader; break; default: ; } } + + return result; + } + + + DxvkBindingLayout DxvkShaderPipelineLibraryKey::getBindings() const { + DxvkBindingLayout mergedLayout(m_shaderStages); + + for (uint32_t i = 0; i < m_shaderCount; i++) + mergedLayout.merge(m_shaders[i]->getBindings()); + + return mergedLayout; + } + + + void DxvkShaderPipelineLibraryKey::addShader( + const Rc& shader) { + m_shaderStages |= shader->info().stage; + m_shaders[m_shaderCount++] = shader; + } + + + bool DxvkShaderPipelineLibraryKey::canUsePipelineLibrary() const { + // Ensure that each individual shader can be used in a library + bool standalone = m_shaderCount <= 1; + + for (uint32_t i = 0; i < m_shaderCount; i++) { + if (!m_shaders[i]->canUsePipelineLibrary(standalone)) + return false; + } + + // Ensure that stage I/O is compatible between stages + for (uint32_t i = 0; i + 1 < m_shaderCount; i++) { + uint32_t currStageIoMask = m_shaders[i]->info().outputMask; + uint32_t nextStageIoMask = m_shaders[i + 1]->info().inputMask; + + if ((currStageIoMask & nextStageIoMask) != nextStageIoMask) + return false; + } + + return true; + } + + + bool DxvkShaderPipelineLibraryKey::eq( + const DxvkShaderPipelineLibraryKey& other) const { + bool eq = m_shaderStages == other.m_shaderStages; + + for (uint32_t i = 0; i < m_shaderCount && eq; i++) + eq = m_shaders[i] == other.m_shaders[i]; + + return eq; + } + + + size_t DxvkShaderPipelineLibraryKey::hash() const { + DxvkHashState hash; + hash.add(uint32_t(m_shaderStages)); + + for (uint32_t i = 0; i < m_shaderCount; i++) + hash.add(m_shaders[i]->getHash()); + + return hash; + } + + + DxvkShaderPipelineLibrary::DxvkShaderPipelineLibrary( + const DxvkDevice* device, + DxvkPipelineManager* manager, + const DxvkShaderPipelineLibraryKey& key, + const DxvkBindingLayoutObjects* layout) + : m_device (device), + m_stats (&manager->m_stats), + m_shaders (key.getShaderSet()), + m_layout (layout) { + } diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 245f96f64..ead2d345f 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -385,22 +385,6 @@ namespace dxvk { }; - /** - * \brief Shader pipeline library key - */ - struct DxvkShaderPipelineLibraryKey { - Rc shader; - - bool eq(const DxvkShaderPipelineLibraryKey& other) const { - return shader == other.shader; - } - - size_t hash() const { - return DxvkShader::getHash(shader); - } - }; - - /** * \brief Shader set * @@ -433,6 +417,68 @@ namespace dxvk { }; + /** + * \brief Shader pipeline library key + */ + class DxvkShaderPipelineLibraryKey { + + public: + + DxvkShaderPipelineLibraryKey(); + + ~DxvkShaderPipelineLibraryKey(); + + /** + * \brief Creates shader set from key + * \returns Shader set + */ + DxvkShaderSet getShaderSet() const; + + /** + * \brief Generates merged binding layout + * \returns Binding layout + */ + DxvkBindingLayout getBindings() const; + + /** + * \brief Adds a shader to the key + * + * Shaders must be added in stage order. + * \param [in] shader Shader to add + */ + void addShader( + const Rc& shader); + + /** + * \brief Checks wether a pipeline library can be created + * \returns \c true if all added shaders are compatible + */ + bool canUsePipelineLibrary() const; + + /** + * \brief Checks for equality + * + * \param [in] other Key to compare to + * \returns \c true if the keys are equal + */ + bool eq( + const DxvkShaderPipelineLibraryKey& other) const; + + /** + * \brief Computes key hash + * \returns Key hash + */ + size_t hash() const; + + private: + + uint32_t m_shaderCount = 0; + VkShaderStageFlags m_shaderStages = 0; + std::array, 4> m_shaders; + + }; + + /** * \brief Shader pipeline library * @@ -449,7 +495,7 @@ namespace dxvk { DxvkShaderPipelineLibrary( const DxvkDevice* device, DxvkPipelineManager* manager, - DxvkShader* shader, + const DxvkShaderPipelineLibraryKey& key, const DxvkBindingLayoutObjects* layout); ~DxvkShaderPipelineLibrary(); From 28ae85b7ab93e29608ce4d28c6b6b079a22bd102 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 9 Jan 2023 16:08:49 +0100 Subject: [PATCH 1024/1348] [dxvk] Enable creating full pre-rasterization pipeline libraries --- src/dxvk/dxvk_pipemanager.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 821bea8af..b3754ab54 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -304,9 +304,18 @@ namespace dxvk { if (shaders.gs != nullptr) vsKey.addShader(shaders.gs); - if (vsKey.canUsePipelineLibrary()) + if (vsKey.canUsePipelineLibrary()) { vsLibrary = findPipelineLibraryLocked(vsKey); + if (!vsLibrary) { + // If multiple shader stages are participating, create a + // pipeline library so that it can potentially be reused. + // Don't dispatch the pipeline library to a worker thread + // since it should be compiled on demand anyway. + vsLibrary = createPipelineLibraryLocked(vsKey); + } + } + if (vsLibrary) { DxvkShaderPipelineLibraryKey fsKey; From e5157a5360280fd195fe9489b2f4578e7ca6bb55 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 9 Jan 2023 21:26:15 +0100 Subject: [PATCH 1025/1348] [dxvk] Add pre-rasterization pipeline libraries to the state cache This allows compiling tessellation or geometry shader pipelines early while still using the pipeline library path. Also removes compute shaders. Since API-provided compute shaders are always compiled early, supporting them is no longer needed. --- src/dxvk/dxvk_compute.cpp | 15 +-- src/dxvk/dxvk_compute.h | 3 - src/dxvk/dxvk_pipemanager.cpp | 36 +++--- src/dxvk/dxvk_pipemanager.h | 13 ++- src/dxvk/dxvk_state_cache.cpp | 187 +++++++++++++++++++----------- src/dxvk/dxvk_state_cache.h | 26 ++--- src/dxvk/dxvk_state_cache_types.h | 14 ++- 7 files changed, 175 insertions(+), 119 deletions(-) diff --git a/src/dxvk/dxvk_compute.cpp b/src/dxvk/dxvk_compute.cpp index fdc7394d2..93ebfa5e1 100644 --- a/src/dxvk/dxvk_compute.cpp +++ b/src/dxvk/dxvk_compute.cpp @@ -60,10 +60,8 @@ namespace dxvk { std::lock_guard lock(m_mutex); instance = this->findInstance(state); - if (!instance) { + if (!instance) instance = this->createInstance(state); - this->writePipelineStateToCache(state); - } } return instance->handle; @@ -139,17 +137,6 @@ namespace dxvk { } - void DxvkComputePipeline::writePipelineStateToCache( - const DxvkComputePipelineStateInfo& state) const { - DxvkStateCacheKey key; - - if (m_shaders.cs != nullptr) - key.cs = m_shaders.cs->getShaderKey(); - - m_stateCache->addComputePipeline(key, state); - } - - void DxvkComputePipeline::logPipelineState( LogLevel level, const DxvkComputePipelineStateInfo& state) const { diff --git a/src/dxvk/dxvk_compute.h b/src/dxvk/dxvk_compute.h index 141a11335..cd758ae0d 100644 --- a/src/dxvk/dxvk_compute.h +++ b/src/dxvk/dxvk_compute.h @@ -149,9 +149,6 @@ namespace dxvk { void destroyPipeline( VkPipeline pipeline); - void writePipelineStateToCache( - const DxvkComputePipelineStateInfo& state) const; - void logPipelineState( LogLevel level, const DxvkComputePipelineStateInfo& state) const; diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index b3754ab54..07e75fd58 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -297,12 +297,9 @@ namespace dxvk { DxvkShaderPipelineLibraryKey vsKey; vsKey.addShader(shaders.vs); - if (shaders.tcs != nullptr) - vsKey.addShader(shaders.tcs); - if (shaders.tes != nullptr) - vsKey.addShader(shaders.tes); - if (shaders.gs != nullptr) - vsKey.addShader(shaders.gs); + if (shaders.tcs != nullptr) vsKey.addShader(shaders.tcs); + if (shaders.tes != nullptr) vsKey.addShader(shaders.tes); + if (shaders.gs != nullptr) vsKey.addShader(shaders.gs); if (vsKey.canUsePipelineLibrary()) { vsLibrary = findPipelineLibraryLocked(vsKey); @@ -313,6 +310,17 @@ namespace dxvk { // Don't dispatch the pipeline library to a worker thread // since it should be compiled on demand anyway. vsLibrary = createPipelineLibraryLocked(vsKey); + + // Register the pipeline library with the state cache + // so that subsequent runs can still compile it early + DxvkStateCacheKey shaderKeys; + shaderKeys.vs = shaders.vs->getShaderKey(); + + if (shaders.tcs != nullptr) shaderKeys.tcs = shaders.tcs->getShaderKey(); + if (shaders.tes != nullptr) shaderKeys.tes = shaders.tes->getShaderKey(); + if (shaders.gs != nullptr) shaderKeys.gs = shaders.gs->getShaderKey(); + + m_stateCache.addPipelineLibrary(shaderKeys); } } @@ -335,6 +343,13 @@ namespace dxvk { } + DxvkShaderPipelineLibrary* DxvkPipelineManager::createShaderPipelineLibrary( + const DxvkShaderPipelineLibraryKey& key) { + std::lock_guard lock(m_mutex); + return createPipelineLibraryLocked(key); + } + + DxvkGraphicsPipelineVertexInputLibrary* DxvkPipelineManager::createVertexInputLibrary( const DxvkGraphicsPipelineVertexInputState& state) { std::lock_guard lock(m_mutex); @@ -373,7 +388,7 @@ namespace dxvk { DxvkShaderPipelineLibraryKey key; key.addShader(shader); - auto library = createPipelineLibrary(key); + auto library = createShaderPipelineLibrary(key); m_workers.compilePipelineLibrary(library, DxvkPipelinePriority::Normal); } @@ -452,13 +467,6 @@ namespace dxvk { } - DxvkShaderPipelineLibrary* DxvkPipelineManager::createPipelineLibrary( - const DxvkShaderPipelineLibraryKey& key) { - std::lock_guard lock(m_mutex); - return createPipelineLibraryLocked(key); - } - - DxvkShaderPipelineLibrary* DxvkPipelineManager::createPipelineLibraryLocked( const DxvkShaderPipelineLibraryKey& key) { auto bindings = key.getBindings(); diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 4a1f79228..3ae32de16 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -185,6 +185,16 @@ namespace dxvk { DxvkGraphicsPipeline* createGraphicsPipeline( const DxvkGraphicsPipelineShaders& shaders); + /** + * \brief Creates a pipeline library with a given set of shaders + * + * If a pipeline library already exists, it will be returned. + * Otherwise, a new pipeline library will be created. + * \param [in] key Shader set + */ + DxvkShaderPipelineLibrary* createShaderPipelineLibrary( + const DxvkShaderPipelineLibraryKey& key); + /** * \brief Retrieves a vertex input pipeline library * @@ -294,9 +304,6 @@ namespace dxvk { DxvkBindingLayoutObjects* createPipelineLayout( const DxvkBindingLayout& layout); - DxvkShaderPipelineLibrary* createPipelineLibrary( - const DxvkShaderPipelineLibraryKey& key); - DxvkShaderPipelineLibrary* createPipelineLibraryLocked( const DxvkShaderPipelineLibraryKey& key); diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index b1d71b6ca..b0c1f131f 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -12,6 +12,16 @@ namespace dxvk { * \brief Packed entry header */ struct DxvkStateCacheEntryHeader { + uint32_t entryType : 1; + uint32_t stageMask : 5; + uint32_t entrySize : 26; + }; + + + /** + * \brief Version 8 entry header + */ + struct DxvkStateCacheEntryHeaderV8 { uint32_t stageMask : 8; uint32_t entrySize : 24; }; @@ -44,6 +54,28 @@ namespace dxvk { return read(data); } + bool read(DxvkStateCacheKey& shaders, uint32_t version, VkShaderStageFlags stageFlags) { + DxvkShaderKey dummyKey; + + std::array, 6> stages = {{ + { VK_SHADER_STAGE_VERTEX_BIT, &shaders.vs }, + { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, &shaders.tcs }, + { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, &shaders.tes }, + { VK_SHADER_STAGE_GEOMETRY_BIT, &shaders.gs }, + { VK_SHADER_STAGE_FRAGMENT_BIT, &shaders.fs }, + { VK_SHADER_STAGE_COMPUTE_BIT, &dummyKey }, + }}; + + for (uint32_t i = 0; i < stages.size(); i++) { + if (stageFlags & stages[i].first) { + if (!read(*stages[i].second, version)) + return false; + } + } + + return true; + } + bool read(DxvkBindingMaskV10& data, uint32_t version) { // v11 removes this field if (version >= 11) @@ -208,8 +240,7 @@ namespace dxvk { && this->tcs.eq(key.tcs) && this->tes.eq(key.tes) && this->gs.eq(key.gs) - && this->fs.eq(key.fs) - && this->cs.eq(key.cs); + && this->fs.eq(key.fs); } @@ -220,7 +251,6 @@ namespace dxvk { hash.add(this->tes.hash()); hash.add(this->gs.hash()); hash.add(this->fs.hash()); - hash.add(this->cs.hash()); return hash; } @@ -257,52 +287,52 @@ namespace dxvk { } - void DxvkStateCache::addGraphicsPipeline( - const DxvkStateCacheKey& shaders, - const DxvkGraphicsPipelineStateInfo& state) { + void DxvkStateCache::addPipelineLibrary( + const DxvkStateCacheKey& shaders) { if (!m_enable || shaders.vs.eq(g_nullShaderKey)) return; - + // Do not add an entry that is already in the cache auto entries = m_entryMap.equal_range(shaders); for (auto e = entries.first; e != entries.second; e++) { - const DxvkStateCacheEntry& entry = m_entries[e->second]; - - if (entry.gpState == state) + if (m_entries[e->second].type == DxvkStateCacheEntryType::PipelineLibrary) return; } // Queue a job to write this pipeline to the cache std::unique_lock lock(m_writerLock); - m_writerQueue.push({ shaders, state, - DxvkComputePipelineStateInfo(), g_nullHash }); + m_writerQueue.push({ + DxvkStateCacheEntryType::PipelineLibrary, shaders, + DxvkGraphicsPipelineStateInfo(), g_nullHash }); m_writerCond.notify_one(); createWriter(); } - void DxvkStateCache::addComputePipeline( + void DxvkStateCache::addGraphicsPipeline( const DxvkStateCacheKey& shaders, - const DxvkComputePipelineStateInfo& state) { - if (!m_enable || shaders.cs.eq(g_nullShaderKey)) + const DxvkGraphicsPipelineStateInfo& state) { + if (!m_enable || shaders.vs.eq(g_nullShaderKey)) return; // Do not add an entry that is already in the cache auto entries = m_entryMap.equal_range(shaders); for (auto e = entries.first; e != entries.second; e++) { - if (m_entries[e->second].cpState == state) + if (m_entries[e->second].type == DxvkStateCacheEntryType::MonolithicPipeline + && m_entries[e->second].gpState == state) return; } // Queue a job to write this pipeline to the cache std::unique_lock lock(m_writerLock); - m_writerQueue.push({ shaders, - DxvkGraphicsPipelineStateInfo(), state, g_nullHash }); + m_writerQueue.push({ + DxvkStateCacheEntryType::MonolithicPipeline, + shaders, state, g_nullHash }); m_writerCond.notify_one(); createWriter(); @@ -334,8 +364,7 @@ namespace dxvk { || !getShaderByKey(p->second.tcs, item.gp.tcs) || !getShaderByKey(p->second.tes, item.gp.tes) || !getShaderByKey(p->second.gs, item.gp.gs) - || !getShaderByKey(p->second.fs, item.gp.fs) - || !getShaderByKey(p->second.cs, item.cp.cs)) + || !getShaderByKey(p->second.fs, item.gp.fs)) continue; if (!workerLock) @@ -412,23 +441,35 @@ namespace dxvk { key.tes = getShaderKey(item.gp.tes); key.gs = getShaderKey(item.gp.gs); key.fs = getShaderKey(item.gp.fs); - key.cs = getShaderKey(item.cp.cs); - if (item.cp.cs == nullptr) { - auto pipeline = m_pipeManager->createGraphicsPipeline(item.gp); - auto entries = m_entryMap.equal_range(key); + DxvkGraphicsPipeline* pipeline = nullptr; + auto entries = m_entryMap.equal_range(key); - for (auto e = entries.first; e != entries.second; e++) { - const auto& entry = m_entries[e->second]; - m_pipeWorkers->compileGraphicsPipeline(pipeline, entry.gpState); - } - } else { - auto pipeline = m_pipeManager->createComputePipeline(item.cp); - auto entries = m_entryMap.equal_range(key); + for (auto e = entries.first; e != entries.second; e++) { + const auto& entry = m_entries[e->second]; - for (auto e = entries.first; e != entries.second; e++) { - const auto& entry = m_entries[e->second]; - m_pipeWorkers->compileComputePipeline(pipeline, entry.cpState); + switch (entry.type) { + case DxvkStateCacheEntryType::MonolithicPipeline: { + if (!pipeline) + pipeline = m_pipeManager->createGraphicsPipeline(item.gp); + + m_pipeWorkers->compileGraphicsPipeline(pipeline, entry.gpState); + } break; + + case DxvkStateCacheEntryType::PipelineLibrary: { + if (!m_device->canUseGraphicsPipelineLibrary() || item.gp.vs == nullptr) + break; + + DxvkShaderPipelineLibraryKey libraryKey; + libraryKey.addShader(item.gp.vs); + + if (item.gp.tcs != nullptr) libraryKey.addShader(item.gp.tcs); + if (item.gp.tes != nullptr) libraryKey.addShader(item.gp.tes); + if (item.gp.gs != nullptr) libraryKey.addShader(item.gp.gs); + + auto pipelineLibrary = m_pipeManager->createShaderPipelineLibrary(libraryKey); + m_pipeWorkers->compilePipelineLibrary(pipelineLibrary, DxvkPipelinePriority::Normal); + } break; } } } @@ -483,7 +524,6 @@ namespace dxvk { mapShaderToPipeline(entry.shaders.tes, entry.shaders); mapShaderToPipeline(entry.shaders.gs, entry.shaders); mapShaderToPipeline(entry.shaders.fs, entry.shaders); - mapShaderToPipeline(entry.shaders.cs, entry.shaders); } else if (ifile) { numInvalidEntries += 1; } @@ -531,11 +571,28 @@ namespace dxvk { DxvkStateCacheEntry& entry) const { // Read entry metadata and actual data DxvkStateCacheEntryHeader header; + DxvkStateCacheEntryHeaderV8 headerV8; DxvkStateCacheEntryData data; + VkShaderStageFlags stageMask; Sha1Hash hash; - - if (!stream.read(reinterpret_cast(&header), sizeof(header)) - || !stream.read(reinterpret_cast(&hash), sizeof(hash)) + + if (version >= 16) { + if (!stream.read(reinterpret_cast(&header), sizeof(header))) + return false; + + stageMask = VkShaderStageFlags(header.stageMask); + } else { + if (!stream.read(reinterpret_cast(&headerV8), sizeof(headerV8))) + return false; + + header.entryType = uint32_t(DxvkStateCacheEntryType::MonolithicPipeline); + header.stageMask = headerV8.stageMask & VK_SHADER_STAGE_ALL_GRAPHICS; + header.entrySize = headerV8.entrySize; + + stageMask = VkShaderStageFlags(headerV8.stageMask); + } + + if (!stream.read(reinterpret_cast(&hash), sizeof(hash)) || !data.readFromStream(stream, header.entrySize)) return false; @@ -543,16 +600,15 @@ namespace dxvk { if (hash != data.computeHash()) return false; - // Read shader hashes - VkShaderStageFlags stageMask = VkShaderStageFlags(header.stageMask); - auto keys = &entry.shaders.vs; + // Set up entry metadata + entry.type = DxvkStateCacheEntryType(header.entryType); - for (uint32_t i = 0; i < 6; i++) { - if (stageMask & VkShaderStageFlagBits(1 << i)) - data.read(keys[i], version); - else - keys[i] = g_nullShaderKey; - } + // Read shader hashes + auto entryType = DxvkStateCacheEntryType(header.entryType); + data.read(entry.shaders, version, stageMask); + + if (entryType == DxvkStateCacheEntryType::PipelineLibrary) + return true; DxvkBindingMaskV10 dummyBindingMask = { }; @@ -610,10 +666,6 @@ namespace dxvk { } // Read non-zero spec constants - auto& sc = (stageMask & VK_SHADER_STAGE_COMPUTE_BIT) - ? entry.cpState.sc - : entry.gpState.sc; - uint32_t specConstantMask = 0; if (!data.read(specConstantMask, version)) @@ -621,11 +673,15 @@ namespace dxvk { for (uint32_t i = 0; i < MaxNumSpecConstants; i++) { if (specConstantMask & (1 << i)) { - if (!data.read(sc.specConstants[i], version)) + if (!data.read(entry.gpState.sc.specConstants[i], version)) return false; } } + // Compute shaders are no longer supported + if (stageMask & VK_SHADER_STAGE_COMPUTE_BIT) + return false; + return true; } @@ -646,7 +702,7 @@ namespace dxvk { } } - if (!(stageMask & VK_SHADER_STAGE_COMPUTE_BIT)) { + if (entry.type != DxvkStateCacheEntryType::PipelineLibrary) { // Write out common pipeline state data.write(entry.gpState.ia); data.write(entry.gpState.il); @@ -671,28 +727,25 @@ namespace dxvk { for (uint32_t i = 0; i < entry.gpState.il.bindingCount(); i++) data.write(entry.gpState.ilBindings[i]); - } - // Write out all non-zero spec constants - auto& sc = (stageMask & VK_SHADER_STAGE_COMPUTE_BIT) - ? entry.cpState.sc - : entry.gpState.sc; + // Write out all non-zero spec constants + uint32_t specConstantMask = 0; - uint32_t specConstantMask = 0; + for (uint32_t i = 0; i < MaxNumSpecConstants; i++) + specConstantMask |= entry.gpState.sc.specConstants[i] ? (1 << i) : 0; - for (uint32_t i = 0; i < MaxNumSpecConstants; i++) - specConstantMask |= sc.specConstants[i] ? (1 << i) : 0; + data.write(specConstantMask); - data.write(specConstantMask); - - for (uint32_t i = 0; i < MaxNumSpecConstants; i++) { - if (specConstantMask & (1 << i)) - data.write(sc.specConstants[i]); + for (uint32_t i = 0; i < MaxNumSpecConstants; i++) { + if (specConstantMask & (1 << i)) + data.write(entry.gpState.sc.specConstants[i]); + } } // General layout: header -> hash -> data DxvkStateCacheEntryHeader header; - header.stageMask = uint8_t(stageMask); + header.entryType = uint32_t(entry.type); + header.stageMask = uint32_t(stageMask); header.entrySize = data.size(); Sha1Hash hash = data.computeHash(); diff --git a/src/dxvk/dxvk_state_cache.h b/src/dxvk/dxvk_state_cache.h index 24ec1001c..0e72138ad 100644 --- a/src/dxvk/dxvk_state_cache.h +++ b/src/dxvk/dxvk_state_cache.h @@ -37,30 +37,27 @@ namespace dxvk { ~DxvkStateCache(); /** - * Adds a graphics pipeline to the cache + * \brief Adds pipeline library to the cache + * + * If the pipeline is not already cached, this + * will write a new pipeline to the cache file. + * \param [in] shaders Shader keys + */ + void addPipelineLibrary( + const DxvkStateCacheKey& shaders); + + /** + * \brief Adds a graphics pipeline to the cache * * If the pipeline is not already cached, this * will write a new pipeline to the cache file. * \param [in] shaders Shader keys * \param [in] state Graphics pipeline state - * \param [in] format Render pass format */ void addGraphicsPipeline( const DxvkStateCacheKey& shaders, const DxvkGraphicsPipelineStateInfo& state); - /** - * Adds a compute pipeline to the cache - * - * If the pipeline is not already cached, this - * will write a new pipeline to the cache file. - * \param [in] shaders Shader keys - * \param [in] state Compute pipeline state - */ - void addComputePipeline( - const DxvkStateCacheKey& shaders, - const DxvkComputePipelineStateInfo& state); - /** * \brief Registers a newly compiled shader * @@ -83,7 +80,6 @@ namespace dxvk { struct WorkerItem { DxvkGraphicsPipelineShaders gp; - DxvkComputePipelineShaders cp; }; DxvkDevice* m_device; diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index c2f818683..86d99a55c 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -19,13 +19,21 @@ namespace dxvk { DxvkShaderKey tes; DxvkShaderKey gs; DxvkShaderKey fs; - DxvkShaderKey cs; bool eq(const DxvkStateCacheKey& key) const; size_t hash() const; }; + + /** + * \brief State entry type + */ + enum class DxvkStateCacheEntryType : uint32_t { + MonolithicPipeline = 0, + PipelineLibrary = 1, + }; + /** * \brief State entry @@ -36,9 +44,9 @@ namespace dxvk { * that is used as a check sum to verify integrity. */ struct DxvkStateCacheEntry { + DxvkStateCacheEntryType type; DxvkStateCacheKey shaders; DxvkGraphicsPipelineStateInfo gpState; - DxvkComputePipelineStateInfo cpState; Sha1Hash hash; }; @@ -52,7 +60,7 @@ namespace dxvk { */ struct DxvkStateCacheHeader { char magic[4] = { 'D', 'X', 'V', 'K' }; - uint32_t version = 15; + uint32_t version = 16; uint32_t entrySize = 0; /* no longer meaningful */ }; From a22d70e184b2ef930fee55f9b7e2be1d161d6ade Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 12 Jan 2023 16:47:15 +0100 Subject: [PATCH 1026/1348] [dxvk] Remove unused compileComputePipeline function --- src/dxvk/dxvk_pipemanager.cpp | 21 +-------------------- src/dxvk/dxvk_pipemanager.h | 12 ------------ 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 07e75fd58..cbcc162da 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -40,23 +40,6 @@ namespace dxvk { } - void DxvkPipelineWorkers::compileComputePipeline( - DxvkComputePipeline* pipeline, - const DxvkComputePipelineStateInfo& state) { - std::unique_lock lock(m_queueLock); - this->startWorkers(); - - m_pendingTasks += 1; - - PipelineEntry e = { }; - e.computePipeline = pipeline; - e.computeState = state; - - m_queuedPipelines.push(e); - m_queueCond.notify_one(); - } - - void DxvkPipelineWorkers::compileGraphicsPipeline( DxvkGraphicsPipeline* pipeline, const DxvkGraphicsPipelineStateInfo& state) { @@ -176,9 +159,7 @@ namespace dxvk { } if (p) { - if (p->computePipeline) { - p->computePipeline->compilePipeline(p->computeState); - } else if (p->graphicsPipeline) { + if (p->graphicsPipeline) { p->graphicsPipeline->compilePipeline(p->graphicsState); p->graphicsPipeline->releasePipeline(); } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 3ae32de16..49768d4be 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -70,16 +70,6 @@ namespace dxvk { DxvkShaderPipelineLibrary* library, DxvkPipelinePriority priority); - /** - * \brief Compiles an optimized compute pipeline - * - * \param [in] pipeline Compute pipeline - * \param [in] state Pipeline state - */ - void compileComputePipeline( - DxvkComputePipeline* pipeline, - const DxvkComputePipelineStateInfo& state); - /** * \brief Compiles an optimized graphics pipeline * @@ -107,9 +97,7 @@ namespace dxvk { private: struct PipelineEntry { - DxvkComputePipeline* computePipeline; DxvkGraphicsPipeline* graphicsPipeline; - DxvkComputePipelineStateInfo computeState; DxvkGraphicsPipelineStateInfo graphicsState; }; From 070a34011533302e06a41eb73af90d6133ae36d1 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 13 Jan 2023 11:40:01 +0100 Subject: [PATCH 1027/1348] [dxvk] Remove path to look up optimized pipeline in cache For some reason this sometimes takes several milliseconds, which leads to noticeable stutter. Linking a pipeline is more consistent. --- src/dxvk/dxvk_graphics.cpp | 84 ++++++++++++-------------------------- src/dxvk/dxvk_graphics.h | 6 +-- 2 files changed, 27 insertions(+), 63 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 1a653c871..ea34dd018 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -990,7 +990,7 @@ namespace dxvk { || instance->isCompiling.exchange(VK_TRUE, std::memory_order_acquire)) return; - VkPipeline pipeline = this->getOptimizedPipeline(state, 0); + VkPipeline pipeline = this->getOptimizedPipeline(state); instance->fastHandle.store(pipeline, std::memory_order_release); // Log pipeline state on error @@ -1044,22 +1044,10 @@ namespace dxvk { VkPipeline baseHandle = VK_NULL_HANDLE; VkPipeline fastHandle = VK_NULL_HANDLE; - if (doCreateBasePipeline) { - // Try to create an optimized pipeline from the cache - // first, since this is expected to be the fastest path. - if (m_device->canUsePipelineCacheControl()) { - fastHandle = this->getOptimizedPipeline(state, - VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT); - } - - // If that didn't succeed, link a pipeline using the - // pre-compiled fragment and vertex shader libraries. - if (!fastHandle) - baseHandle = this->getBasePipeline(state); - } else { - // Create optimized variant right away, no choice - fastHandle = this->getOptimizedPipeline(state, 0); - } + if (doCreateBasePipeline) + baseHandle = this->getBasePipeline(state); + else + fastHandle = this->getOptimizedPipeline(state); // Log pipeline state if requested, or on failure if (!fastHandle && !baseHandle) @@ -1206,8 +1194,7 @@ namespace dxvk { VkPipeline DxvkGraphicsPipeline::getOptimizedPipeline( - const DxvkGraphicsPipelineStateInfo& state, - VkPipelineCreateFlags flags) { + const DxvkGraphicsPipelineStateInfo& state) { DxvkGraphicsPipelineFastInstanceKey key(m_device, m_shaders, state, m_flags, m_specConstantMask); @@ -1220,7 +1207,7 @@ namespace dxvk { // Keep pipeline locked to prevent multiple threads from compiling // identical Vulkan pipelines. This should be rare, but has been // buggy on some drivers in the past, so just don't allow it. - VkPipeline handle = createOptimizedPipeline(key, flags); + VkPipeline handle = createOptimizedPipeline(key); if (handle) m_fastPipelines.insert({ key, handle }); @@ -1230,45 +1217,22 @@ namespace dxvk { VkPipeline DxvkGraphicsPipeline::createOptimizedPipeline( - const DxvkGraphicsPipelineFastInstanceKey& key, - VkPipelineCreateFlags flags) const { + const DxvkGraphicsPipelineFastInstanceKey& key) const { auto vk = m_device->vkd(); - // Build stage infos for all provided shaders DxvkShaderStageInfo stageInfo(m_device); + stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, key.shState.vsInfo), &key.scState.scInfo); - if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) { - stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, m_vsLibrary->getModuleIdentifier(VK_SHADER_STAGE_VERTEX_BIT), &key.scState.scInfo); - - if (m_shaders.tcs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_vsLibrary->getModuleIdentifier(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT), &key.scState.scInfo); - if (m_shaders.tes != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_vsLibrary->getModuleIdentifier(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT), &key.scState.scInfo); - if (m_shaders.gs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, m_vsLibrary->getModuleIdentifier(VK_SHADER_STAGE_GEOMETRY_BIT), &key.scState.scInfo); - if (m_shaders.fs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, m_fsLibrary->getModuleIdentifier(VK_SHADER_STAGE_FRAGMENT_BIT), &key.scState.scInfo); - } else { - stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, key.shState.vsInfo), &key.scState.scInfo); - - if (m_shaders.tcs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, key.shState.tcsInfo), &key.scState.scInfo); - if (m_shaders.tes != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, key.shState.tesInfo), &key.scState.scInfo); - if (m_shaders.gs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, key.shState.gsInfo), &key.scState.scInfo); - if (m_shaders.fs != nullptr) - stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, key.shState.fsInfo), &key.scState.scInfo); - } - - if (key.foState.feedbackLoop & VK_IMAGE_ASPECT_COLOR_BIT) - flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; - - if (key.foState.feedbackLoop & VK_IMAGE_ASPECT_DEPTH_BIT) - flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + if (m_shaders.tcs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, key.shState.tcsInfo), &key.scState.scInfo); + if (m_shaders.tes != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, key.shState.tesInfo), &key.scState.scInfo); + if (m_shaders.gs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, key.shState.gsInfo), &key.scState.scInfo); + if (m_shaders.fs != nullptr) + stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, key.shState.fsInfo), &key.scState.scInfo); VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &key.foState.rtInfo }; - info.flags = flags; info.stageCount = stageInfo.getStageCount(); info.pStages = stageInfo.getStageInfos(); info.pVertexInputState = &key.viState.viInfo; @@ -1286,18 +1250,20 @@ namespace dxvk { if (!key.prState.tsInfo.patchControlPoints) info.pTessellationState = nullptr; + if (key.foState.feedbackLoop & VK_IMAGE_ASPECT_COLOR_BIT) + info.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + + if (key.foState.feedbackLoop & VK_IMAGE_ASPECT_DEPTH_BIT) + info.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT; + VkPipeline pipeline = VK_NULL_HANDLE; VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), VK_NULL_HANDLE, 1, &info, nullptr, &pipeline); if (vr != VK_SUCCESS) { - // Ignore any error if we're trying to create a cached pipeline. If linking or - // compiling an optimized pipeline fail later, we'll still be printing errors. - if (!(flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT)) - Logger::err(str::format("DxvkGraphicsPipeline: Failed to compile pipeline: ", vr)); - + Logger::err(str::format("DxvkGraphicsPipeline: Failed to compile pipeline: ", vr)); return VK_NULL_HANDLE; } - + return pipeline; } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 0a56d1451..9a614c575 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -606,12 +606,10 @@ namespace dxvk { const DxvkGraphicsPipelineBaseInstanceKey& key) const; VkPipeline getOptimizedPipeline( - const DxvkGraphicsPipelineStateInfo& state, - VkPipelineCreateFlags flags); + const DxvkGraphicsPipelineStateInfo& state); VkPipeline createOptimizedPipeline( - const DxvkGraphicsPipelineFastInstanceKey& key, - VkPipelineCreateFlags flags) const; + const DxvkGraphicsPipelineFastInstanceKey& key) const; void destroyBasePipelines(); From cc9266edaa35c9c4dd15f16b381665630ce01889 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Wed, 11 Jan 2023 21:13:58 +0100 Subject: [PATCH 1028/1348] [util] Add config for Alien Rage Reporting a GTX 295 puts us into the highest behind the scenes graphics settings preset bucket and prevents the shadow issue with `FloatingPointRenderTargets` set to false in the lower preset bucket. NvapiHack needs to be disabled on Linux since the game pings it in the Windows system folder and want's the VendorId to match your GPU. Else the issue will still happen on Nvidia Linux --- src/util/config/config.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index fc466b535..c31c8e0f1 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -696,6 +696,13 @@ namespace dxvk { { R"(\\Secret World Legends\\ClientPatcher\.exe$)", {{ { "d3d9.shaderModel", "2" }, }} }, + /* Alien Rage * + * GTX 295 & disable Hack to fix shadows */ + { R"(\\(ShippingPC-AFEARGame|ARageMP)\.exe$)", {{ + { "d3d9.customVendorId", "10de" }, + { "d3d9.customDeviceId", "05E0" }, + { "dxgi.nvapiHack", "False" }, + }} }, }}; From c978e62ec8616031a028f2ffa2b5bf3a6b3662cc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 13 Jan 2023 14:20:27 +0100 Subject: [PATCH 1029/1348] [dxvk] Implement better priority system for background shader compiles Reduces the number of workers that perform background optimization, which may reduce the performance impact when encountering a large number of new pipelines at once. --- src/dxvk/dxvk_graphics.cpp | 2 +- src/dxvk/dxvk_pipemanager.cpp | 178 +++++++++++++++------------------- src/dxvk/dxvk_pipemanager.h | 39 +++++--- src/dxvk/dxvk_state_cache.cpp | 2 +- 4 files changed, 103 insertions(+), 118 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index ea34dd018..a6cba7859 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -938,7 +938,7 @@ namespace dxvk { // If necessary, compile an optimized pipeline variant if (!instance->fastHandle.load()) - m_workers->compileGraphicsPipeline(this, state); + m_workers->compileGraphicsPipeline(this, state, DxvkPipelinePriority::Low); // Only store pipelines in the state cache that cannot benefit // from pipeline libraries, or if that feature is disabled. diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index cbcc162da..b6443975e 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -21,40 +21,28 @@ namespace dxvk { void DxvkPipelineWorkers::compilePipelineLibrary( DxvkShaderPipelineLibrary* library, DxvkPipelinePriority priority) { - std::unique_lock lock(m_queueLock); + std::unique_lock lock(m_lock); this->startWorkers(); m_pendingTasks += 1; - PipelineLibraryEntry e = { }; - e.pipelineLibrary = library; - - if (priority == DxvkPipelinePriority::High) { - m_queuedLibrariesPrioritized.push(e); - m_queueCondPrioritized.notify_one(); - } else { - m_queuedLibraries.push(e); - } - - m_queueCond.notify_one(); + m_buckets[uint32_t(priority)].queue.emplace(library); + notifyWorkers(priority); } void DxvkPipelineWorkers::compileGraphicsPipeline( DxvkGraphicsPipeline* pipeline, - const DxvkGraphicsPipelineStateInfo& state) { - std::unique_lock lock(m_queueLock); + const DxvkGraphicsPipelineStateInfo& state, + DxvkPipelinePriority priority) { + std::unique_lock lock(m_lock); this->startWorkers(); pipeline->acquirePipeline(); m_pendingTasks += 1; - PipelineEntry e = { }; - e.graphicsPipeline = pipeline; - e.graphicsState = state; - - m_queuedPipelines.push(e); - m_queueCond.notify_one(); + m_buckets[uint32_t(priority)].queue.emplace(pipeline, state); + notifyWorkers(priority); } @@ -64,14 +52,15 @@ namespace dxvk { void DxvkPipelineWorkers::stopWorkers() { - { std::unique_lock lock(m_queueLock); + { std::unique_lock lock(m_lock); if (!m_workersRunning) return; m_workersRunning = false; - m_queueCond.notify_all(); - m_queueCondPrioritized.notify_all(); + + for (uint32_t i = 0; i < m_buckets.size(); i++) + m_buckets[i].cond.notify_all(); } for (auto& worker : m_workers) @@ -81,8 +70,23 @@ namespace dxvk { } + void DxvkPipelineWorkers::notifyWorkers(DxvkPipelinePriority priority) { + uint32_t index = uint32_t(priority); + + // If any workers are idle in a suitable set, notify the corresponding + // condition variable. If all workers are busy anyway, we know that the + // job is going to be picked up at some point anyway. + for (uint32_t i = index; i < m_buckets.size(); i++) { + if (m_buckets[i].idleWorkers) { + m_buckets[i].cond.notify_one(); + break; + } + } + } + + void DxvkPipelineWorkers::startWorkers() { - if (!m_workersRunning) { + if (!std::exchange(m_workersRunning, true)) { // Use all available cores by default uint32_t workerCount = dxvk::thread::hardware_concurrency(); @@ -98,102 +102,74 @@ namespace dxvk { // Number of workers that can process pipeline pipelines with normal // priority. Any other workers can only build high-priority pipelines. - uint32_t npWorkerCount = m_device->canUseGraphicsPipelineLibrary() - ? std::max(((workerCount - 1) * 5) / 7, 1u) - : workerCount; - uint32_t hpWorkerCount = workerCount - npWorkerCount; + uint32_t npWorkerCount = std::max(((workerCount - 1) * 5) / 7, 1u); + uint32_t lpWorkerCount = std::max(((workerCount - 1) * 2) / 7, 1u); - Logger::info(str::format("DXVK: Using ", npWorkerCount, " + ", hpWorkerCount, " compiler threads")); - m_workers.resize(npWorkerCount + hpWorkerCount); + m_workers.reserve(workerCount); - // Set worker flag so that they don't exit immediately - m_workersRunning = true; + for (size_t i = 0; i < workerCount; i++) { + DxvkPipelinePriority priority = DxvkPipelinePriority::Normal; - for (size_t i = 0; i < m_workers.size(); i++) { - m_workers[i] = i >= npWorkerCount - ? dxvk::thread([this] { runWorkerPrioritized(); }) - : dxvk::thread([this] { runWorker(); }); - m_workers[i].set_priority(ThreadPriority::Lowest); + if (m_device->canUseGraphicsPipelineLibrary()) { + if (i >= npWorkerCount) + priority = DxvkPipelinePriority::High; + else if (i < lpWorkerCount) + priority = DxvkPipelinePriority::Low; + } + + m_workers.emplace_back([this, priority] { + runWorker(priority); + }); } + + Logger::info(str::format("DXVK: Using ", workerCount, " compiler threads")); } } - void DxvkPipelineWorkers::runWorker() { - env::setThreadName("dxvk-shader"); + void DxvkPipelineWorkers::runWorker(DxvkPipelinePriority maxPriority) { + static const std::array suffixes = { 'h', 'n', 'l' }; + + const uint32_t maxPriorityIndex = uint32_t(maxPriority); + env::setThreadName(str::format("dxvk-shader-", suffixes.at(maxPriorityIndex))); while (true) { - std::optional p; - std::optional l; + PipelineEntry entry; - { std::unique_lock lock(m_queueLock); + { std::unique_lock lock(m_lock); + auto& bucket = m_buckets[maxPriorityIndex]; - m_queueCond.wait(lock, [this] { - return !m_workersRunning - || !m_queuedLibrariesPrioritized.empty() - || !m_queuedLibraries.empty() - || !m_queuedPipelines.empty(); + bucket.idleWorkers += 1; + bucket.cond.wait(lock, [this, maxPriorityIndex, &entry] { + // Attempt to fetch a work item from the + // highest-priority queue that is not empty + for (uint32_t i = 0; i <= maxPriorityIndex; i++) { + if (!m_buckets[i].queue.empty()) { + entry = m_buckets[i].queue.front(); + m_buckets[i].queue.pop(); + return true; + } + } + + return !m_workersRunning; }); - if (!m_workersRunning) { - // Skip pending work, exiting early is - // more important in this case. - break; - } else if (!m_queuedLibrariesPrioritized.empty()) { - l = m_queuedLibrariesPrioritized.front(); - m_queuedLibrariesPrioritized.pop(); - } else if (!m_queuedLibraries.empty()) { - l = m_queuedLibraries.front(); - m_queuedLibraries.pop(); - } else if (!m_queuedPipelines.empty()) { - p = m_queuedPipelines.front(); - m_queuedPipelines.pop(); - } - } - - if (l) { - if (l->pipelineLibrary) - l->pipelineLibrary->compilePipeline(); - - m_pendingTasks -= 1; - } - - if (p) { - if (p->graphicsPipeline) { - p->graphicsPipeline->compilePipeline(p->graphicsState); - p->graphicsPipeline->releasePipeline(); - } - - m_pendingTasks -= 1; - } - } - } - - - void DxvkPipelineWorkers::runWorkerPrioritized() { - env::setThreadName("dxvk-shader-p"); - - while (true) { - PipelineLibraryEntry l = { }; - - { std::unique_lock lock(m_queueLock); - - m_queueCondPrioritized.wait(lock, [this] { - return !m_workersRunning - || !m_queuedLibrariesPrioritized.empty(); - }); + bucket.idleWorkers -= 1; + // Skip pending work, exiting early is + // more important in this case. if (!m_workersRunning) break; - - l = m_queuedLibrariesPrioritized.front(); - m_queuedLibrariesPrioritized.pop(); } - if (l.pipelineLibrary) - l.pipelineLibrary->compilePipeline(); - - m_pendingTasks -= 1; + if (entry.pipelineLibrary) { + entry.pipelineLibrary->compilePipeline(); + m_pendingTasks -= 1; + } else if (entry.graphicsPipeline) { + entry.graphicsPipeline->compilePipeline(entry.graphicsState); + entry.graphicsPipeline->releasePipeline(); + m_pendingTasks -= 1; + } } } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 49768d4be..033e37ee6 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -38,8 +38,9 @@ namespace dxvk { * \brief Pipeline priority */ enum class DxvkPipelinePriority : uint32_t { - Normal = 0, - High = 1, + High = 0, + Normal = 1, + Low = 2, }; /** @@ -78,7 +79,8 @@ namespace dxvk { */ void compileGraphicsPipeline( DxvkGraphicsPipeline* pipeline, - const DxvkGraphicsPipelineStateInfo& state); + const DxvkGraphicsPipelineStateInfo& state, + DxvkPipelinePriority priority); /** * \brief Checks whether workers are busy @@ -97,34 +99,41 @@ namespace dxvk { private: struct PipelineEntry { + PipelineEntry() + : pipelineLibrary(nullptr), graphicsPipeline(nullptr) { } + + PipelineEntry(DxvkShaderPipelineLibrary* l) + : pipelineLibrary(l), graphicsPipeline(nullptr) { } + + PipelineEntry(DxvkGraphicsPipeline* p, const DxvkGraphicsPipelineStateInfo& s) + : pipelineLibrary(nullptr), graphicsPipeline(p), graphicsState(s) { } + + DxvkShaderPipelineLibrary* pipelineLibrary; DxvkGraphicsPipeline* graphicsPipeline; DxvkGraphicsPipelineStateInfo graphicsState; }; - struct PipelineLibraryEntry { - DxvkShaderPipelineLibrary* pipelineLibrary; + struct PipelineBucket { + dxvk::condition_variable cond; + std::queue queue; + uint32_t idleWorkers = 0; }; DxvkDevice* m_device; std::atomic m_pendingTasks = { 0ull }; - dxvk::mutex m_queueLock; - dxvk::condition_variable m_queueCond; - dxvk::condition_variable m_queueCondPrioritized; - - std::queue m_queuedLibrariesPrioritized; - std::queue m_queuedLibraries; - std::queue m_queuedPipelines; + dxvk::mutex m_lock; + std::array m_buckets; bool m_workersRunning = false; std::vector m_workers; + void notifyWorkers(DxvkPipelinePriority priority); + void startWorkers(); - void runWorker(); - - void runWorkerPrioritized(); + void runWorker(DxvkPipelinePriority maxPriority); }; diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index b0c1f131f..1bd31e67b 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -453,7 +453,7 @@ namespace dxvk { if (!pipeline) pipeline = m_pipeManager->createGraphicsPipeline(item.gp); - m_pipeWorkers->compileGraphicsPipeline(pipeline, entry.gpState); + m_pipeWorkers->compileGraphicsPipeline(pipeline, entry.gpState, DxvkPipelinePriority::Normal); } break; case DxvkStateCacheEntryType::PipelineLibrary: { From 3a84838ac40bd24da64f76ad76ed65f4ec8aadcd Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 13 Jan 2023 15:09:32 +0100 Subject: [PATCH 1030/1348] [hud] Display approximate progress when compiling shaders --- src/dxvk/dxvk_device.cpp | 4 ++- src/dxvk/dxvk_pipemanager.cpp | 13 +++------ src/dxvk/dxvk_pipemanager.h | 31 ++++++++++++++------- src/dxvk/dxvk_stats.h | 3 ++- src/dxvk/hud/dxvk_hud_item.cpp | 49 +++++++++++++++++++++++++++++----- src/dxvk/hud/dxvk_hud_item.h | 13 ++++++--- 6 files changed, 83 insertions(+), 30 deletions(-) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index e059f9012..54ef28210 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -188,12 +188,14 @@ namespace dxvk { DxvkStatCounters DxvkDevice::getStatCounters() { DxvkPipelineCount pipe = m_objects.pipelineManager().getPipelineCount(); + DxvkPipelineWorkerStats workers = m_objects.pipelineManager().getWorkerStats(); DxvkStatCounters result; result.setCtr(DxvkStatCounter::PipeCountGraphics, pipe.numGraphicsPipelines); result.setCtr(DxvkStatCounter::PipeCountLibrary, pipe.numGraphicsLibraries); result.setCtr(DxvkStatCounter::PipeCountCompute, pipe.numComputePipelines); - result.setCtr(DxvkStatCounter::PipeCompilerBusy, m_objects.pipelineManager().isCompilingShaders()); + result.setCtr(DxvkStatCounter::PipeTasksDone, workers.tasksCompleted); + result.setCtr(DxvkStatCounter::PipeTasksTotal, workers.tasksTotal); result.setCtr(DxvkStatCounter::GpuIdleTicks, m_submissionQueue.gpuIdleTicks()); std::lock_guard lock(m_statLock); diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index b6443975e..40c20cf81 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -24,7 +24,7 @@ namespace dxvk { std::unique_lock lock(m_lock); this->startWorkers(); - m_pendingTasks += 1; + m_tasksTotal += 1; m_buckets[uint32_t(priority)].queue.emplace(library); notifyWorkers(priority); @@ -39,18 +39,13 @@ namespace dxvk { this->startWorkers(); pipeline->acquirePipeline(); - m_pendingTasks += 1; + m_tasksTotal += 1; m_buckets[uint32_t(priority)].queue.emplace(pipeline, state); notifyWorkers(priority); } - bool DxvkPipelineWorkers::isBusy() const { - return m_pendingTasks.load() != 0ull; - } - - void DxvkPipelineWorkers::stopWorkers() { { std::unique_lock lock(m_lock); @@ -164,12 +159,12 @@ namespace dxvk { if (entry.pipelineLibrary) { entry.pipelineLibrary->compilePipeline(); - m_pendingTasks -= 1; } else if (entry.graphicsPipeline) { entry.graphicsPipeline->compilePipeline(entry.graphicsState); entry.graphicsPipeline->releasePipeline(); - m_pendingTasks -= 1; } + + m_tasksCompleted += 1; } } diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index 033e37ee6..36801aefb 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -34,6 +34,11 @@ namespace dxvk { std::atomic numComputePipelines = { 0u }; }; + struct DxvkPipelineWorkerStats { + uint64_t tasksCompleted; + uint64_t tasksTotal; + }; + /** * \brief Pipeline priority */ @@ -58,6 +63,19 @@ namespace dxvk { ~DxvkPipelineWorkers(); + /** + * \brief Queries worker statistics + * + * The returned result may be immediately out of date. + * \returns Worker statistics + */ + DxvkPipelineWorkerStats getStats() const { + DxvkPipelineWorkerStats result; + result.tasksCompleted = m_tasksCompleted.load(std::memory_order_acquire); + result.tasksTotal = m_tasksTotal.load(std::memory_order_relaxed); + return result; + } + /** * \brief Compiles a pipeline library * @@ -82,12 +100,6 @@ namespace dxvk { const DxvkGraphicsPipelineStateInfo& state, DxvkPipelinePriority priority); - /** - * \brief Checks whether workers are busy - * \returns \c true if there is unfinished work - */ - bool isBusy() const; - /** * \brief Stops all worker threads * @@ -121,7 +133,8 @@ namespace dxvk { DxvkDevice* m_device; - std::atomic m_pendingTasks = { 0ull }; + std::atomic m_tasksTotal = { 0ull }; + std::atomic m_tasksCompleted = { 0ull }; dxvk::mutex m_lock; std::array m_buckets; @@ -242,8 +255,8 @@ namespace dxvk { * \brief Checks whether async compiler is busy * \returns \c true if shaders are being compiled */ - bool isCompilingShaders() const { - return m_workers.isBusy(); + DxvkPipelineWorkerStats getWorkerStats() const { + return m_workers.getStats(); } /** diff --git a/src/dxvk/dxvk_stats.h b/src/dxvk/dxvk_stats.h index 211570f52..91c83701d 100644 --- a/src/dxvk/dxvk_stats.h +++ b/src/dxvk/dxvk_stats.h @@ -18,7 +18,8 @@ namespace dxvk { PipeCountGraphics, ///< Number of graphics pipelines PipeCountLibrary, ///< Number of graphics shader libraries PipeCountCompute, ///< Number of compute pipelines - PipeCompilerBusy, ///< Boolean indicating compiler activity + PipeTasksDone, ///< Boolean indicating compiler activity + PipeTasksTotal, ///< Boolean indicating compiler activity QueueSubmitCount, ///< Number of command buffer submissions QueuePresentCount, ///< Number of present calls / frames GpuSyncCount, ///< Number of GPU synchronizations diff --git a/src/dxvk/hud/dxvk_hud_item.cpp b/src/dxvk/hud/dxvk_hud_item.cpp index 4b7b0ea54..40707d644 100644 --- a/src/dxvk/hud/dxvk_hud_item.cpp +++ b/src/dxvk/hud/dxvk_hud_item.cpp @@ -755,15 +755,36 @@ namespace dxvk::hud { void HudCompilerActivityItem::update(dxvk::high_resolution_clock::time_point time) { DxvkStatCounters counters = m_device->getStatCounters(); - bool doShow = counters.getCtr(DxvkStatCounter::PipeCompilerBusy); - if (!doShow) { - auto elapsed = std::chrono::duration_cast(time - m_timeShown); - doShow = elapsed.count() <= MinShowDuration; - } + m_tasksDone = counters.getCtr(DxvkStatCounter::PipeTasksDone); + m_tasksTotal = counters.getCtr(DxvkStatCounter::PipeTasksTotal); - if (doShow && !m_show) + bool doShow = m_tasksDone < m_tasksTotal; + + if (!doShow) + m_timeDone = time; + + if (!m_show) { m_timeShown = time; + m_showPercentage = false; + } else { + auto durationShown = std::chrono::duration_cast(time - m_timeShown); + auto durationWorking = std::chrono::duration_cast(time - m_timeDone); + + if (!doShow) { + m_offset = m_tasksTotal; + + // Ensure the item stays up long enough to be legible + doShow = durationShown.count() <= MinShowDuration; + } + + if (!m_showPercentage) { + // Don't show percentage if it's just going to be stuck at 99% + // because the workers are not being fed tasks fast enough + m_showPercentage = durationWorking.count() >= (MinShowDuration / 5) + && (computePercentage() < 50); + } + } m_show = doShow; } @@ -773,13 +794,27 @@ namespace dxvk::hud { HudRenderer& renderer, HudPos position) { if (m_show) { + std::string string = "Compiling shaders..."; + + if (m_showPercentage) + string = str::format(string, " (", computePercentage(), "%)"); + renderer.drawText(16.0f, { position.x, renderer.surfaceSize().height / renderer.scale() - 20.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, - "Compiling shaders..."); + string); } return position; } + + uint32_t HudCompilerActivityItem::computePercentage() const { + if (m_offset == m_tasksTotal) + return 100; + + return (uint32_t(m_tasksDone - m_offset) * 100) + / (uint32_t(m_tasksTotal - m_offset)); + } + } diff --git a/src/dxvk/hud/dxvk_hud_item.h b/src/dxvk/hud/dxvk_hud_item.h index b91f4d710..18f75054b 100644 --- a/src/dxvk/hud/dxvk_hud_item.h +++ b/src/dxvk/hud/dxvk_hud_item.h @@ -482,10 +482,17 @@ namespace dxvk::hud { Rc m_device; - bool m_show = false; + bool m_show = false; + bool m_showPercentage = false; - dxvk::high_resolution_clock::time_point m_timeShown - = dxvk::high_resolution_clock::now(); + uint64_t m_tasksDone = 0ull; + uint64_t m_tasksTotal = 0ull; + uint64_t m_offset = 0ull; + + dxvk::high_resolution_clock::time_point m_timeShown = dxvk::high_resolution_clock::now(); + dxvk::high_resolution_clock::time_point m_timeDone = dxvk::high_resolution_clock::now(); + + uint32_t computePercentage() const; }; From 97a91c816fd17869e630f1b766a4681741af9600 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sat, 31 Dec 2022 01:47:43 +0100 Subject: [PATCH 1031/1348] [d3d9] Disable instancing for non-indexed draws --- src/d3d9/d3d9_device.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 4a4d31cad..7634848a7 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2467,15 +2467,16 @@ namespace dxvk { EmitCs([this, cPrimType = PrimitiveType, cPrimCount = PrimitiveCount, - cStartVertex = StartVertex, - cInstanceCount = GetInstanceCount() + cStartVertex = StartVertex ](DxvkContext* ctx) { - auto drawInfo = GenerateDrawInfo(cPrimType, cPrimCount, cInstanceCount); + uint32_t vertexCount = GetVertexCount(cPrimType, cPrimCount); ApplyPrimitiveType(ctx, cPrimType); + // Tests on Windows show that D3D9 does not do non-indexed instanced draws. + ctx->draw( - drawInfo.vertexCount, drawInfo.instanceCount, + vertexCount, 1, cStartVertex, 0); }); @@ -2547,17 +2548,16 @@ namespace dxvk { EmitCs([this, cBufferSlice = std::move(upSlice.slice), cPrimType = PrimitiveType, - cPrimCount = PrimitiveCount, - cInstanceCount = GetInstanceCount(), - cStride = VertexStreamZeroStride + cStride = VertexStreamZeroStride, + cVertexCount = vertexCount ](DxvkContext* ctx) mutable { - auto drawInfo = GenerateDrawInfo(cPrimType, cPrimCount, cInstanceCount); - ApplyPrimitiveType(ctx, cPrimType); + // Tests on Windows show that D3D9 does not do non-indexed instanced draws. + ctx->bindVertexBuffer(0, std::move(cBufferSlice), cStride); ctx->draw( - drawInfo.vertexCount, drawInfo.instanceCount, + cVertexCount, 1, 0, 0); ctx->bindVertexBuffer(0, DxvkBufferSlice(), 0); }); @@ -2699,8 +2699,7 @@ namespace dxvk { cVertexCount = VertexCount, cStartIndex = SrcStartIndex, cInstanceCount = GetInstanceCount(), - cBufferSlice = slice, - cIndexed = m_state.indices != nullptr + cBufferSlice = slice ](DxvkContext* ctx) mutable { Rc shader = m_swvpEmulator.GetShaderModule(this, cDecl); From 2922b780c14ed5f4fe32476aa2fd38d1de206bf0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 14 Jan 2023 01:02:03 +0100 Subject: [PATCH 1032/1348] [dxvk] Properly handle bufferImageGranularity for images Fixes validation errors about dedicated allocations being bigger than the image's memory requirement on Nvidia. --- src/dxvk/dxvk_buffer.cpp | 1 + src/dxvk/dxvk_image.cpp | 13 +---- src/dxvk/dxvk_memory.cpp | 107 ++++++++++++++++++++++----------------- src/dxvk/dxvk_memory.h | 16 +----- src/dxvk/dxvk_sparse.cpp | 1 + 5 files changed, 66 insertions(+), 72 deletions(-) diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 00dde9d70..48d88bbbf 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -88,6 +88,7 @@ namespace dxvk { // Query memory requirements and whether to use a dedicated allocation DxvkMemoryRequirements memoryRequirements = { }; + memoryRequirements.tiling = VK_IMAGE_TILING_LINEAR; memoryRequirements.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS }; memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &memoryRequirements.dedicated }; diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index 69b745477..5d84386ff 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -65,6 +65,7 @@ namespace dxvk { // Get memory requirements for the image and ask driver // whether we need to use a dedicated allocation. DxvkMemoryRequirements memoryRequirements = { }; + memoryRequirements.tiling = info.tiling; memoryRequirements.dedicated = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS }; memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, &memoryRequirements.dedicated }; @@ -96,17 +97,6 @@ namespace dxvk { memoryProperties.dedicated.image = m_image.image; } - // If there's a chance we won't create the image with a dedicated - // allocation, enforce strict alignment for tiled images to not - // violate the bufferImageGranularity requirement on some GPUs. - if (info.tiling != VK_IMAGE_TILING_LINEAR && !memoryRequirements.dedicated.requiresDedicatedAllocation) { - VkDeviceSize granularity = memAlloc.bufferImageGranularity(); - - auto& core = memoryRequirements.core.memoryRequirements; - core.size = align(core.size, granularity); - core.alignment = align(core.alignment, granularity); - } - // Use high memory priority for GPU-writable resources bool isGpuWritable = (m_info.access & ( VK_ACCESS_SHADER_WRITE_BIT | @@ -136,6 +126,7 @@ namespace dxvk { if (properties.metadataPageCount) { DxvkMemoryRequirements memoryRequirements = { }; + memoryRequirements.tiling = VK_IMAGE_TILING_OPTIMAL; memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 }; m_vkd->vkGetImageMemoryRequirements2(m_vkd->device(), diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index e88dff88e..96c100452 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -181,7 +181,6 @@ namespace dxvk { DxvkMemoryAllocator::DxvkMemoryAllocator(DxvkDevice* device) : m_device (device), - m_devProps (device->adapter()->deviceProperties()), m_memProps (device->adapter()->memoryProperties()) { for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { m_memHeaps[i].properties = m_memProps.memoryHeaps[i]; @@ -207,7 +206,7 @@ namespace dxvk { DxvkMemory DxvkMemoryAllocator::alloc( - const DxvkMemoryRequirements& req, + DxvkMemoryRequirements req, DxvkMemoryProperties info, DxvkMemoryFlags hints) { std::lock_guard lock(m_mutex); @@ -225,66 +224,80 @@ namespace dxvk { if (info.flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) hints = hints & DxvkMemoryFlag::Transient; - // Try to allocate from a memory type which supports the given flags exactly - DxvkMemory result = this->tryAlloc(req, info, hints); + // If requested, try with a dedicated allocation first. + if (info.dedicated.image || info.dedicated.buffer) { + DxvkMemory result = this->tryAlloc(req, info, hints); - if (!result && !req.dedicated.requiresDedicatedAllocation) { - // If that failed, try without a dedicated allocation - if (info.dedicated.image || info.dedicated.buffer) { - info.dedicated.image = VK_NULL_HANDLE; - info.dedicated.buffer = VK_NULL_HANDLE; - - result = this->tryAlloc(req, info, hints); - } + if (result) + return result; } - if (!result) { + // If possible, retry without a dedicated allocation + if (!req.dedicated.requiresDedicatedAllocation) { + info.dedicated.image = VK_NULL_HANDLE; + info.dedicated.buffer = VK_NULL_HANDLE; + + // If we're allocating tiled image memory, ensure + // that it will not overlap with buffer memory. + if (req.tiling == VK_IMAGE_TILING_OPTIMAL) { + VkDeviceSize granularity = m_device->properties().core.properties.limits.bufferImageGranularity; + req.core.memoryRequirements.size = align(req.core.memoryRequirements.size, granularity); + req.core.memoryRequirements.alignment = align(req.core.memoryRequirements.alignment, granularity); + } + + DxvkMemory result = this->tryAlloc(req, info, hints); + + if (result) + return result; + // Retry without the hint constraints hints.set(DxvkMemoryFlag::IgnoreConstraints); result = this->tryAlloc(req, info, hints); + + if (result) + return result; } - if (!result) { - // If that still didn't work, probe slower memory types as well - VkMemoryPropertyFlags optFlags = info.flags & ( - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | - VK_MEMORY_PROPERTY_HOST_CACHED_BIT); + // If that still didn't work, probe slower memory types as + // well, but re-enable restrictions to decrease fragmentation. + hints.clr(DxvkMemoryFlag::IgnoreConstraints); - while (!result && optFlags) { - VkMemoryPropertyFlags bit = optFlags & -optFlags; - optFlags &= ~bit; + const VkMemoryPropertyFlags optionalFlags = + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_CACHED_BIT; - info.flags &= ~bit; - result = this->tryAlloc(req, info, hints); - } + if (info.flags & optionalFlags) { + info.flags &= ~optionalFlags; + + DxvkMemory result = this->tryAlloc(req, info, hints); + + if (result) + return result; } - if (!result) { - DxvkAdapterMemoryInfo memHeapInfo = m_device->adapter()->getMemoryHeapInfo(); + // We weren't able to allocate memory for this resource form any type + DxvkAdapterMemoryInfo memHeapInfo = m_device->adapter()->getMemoryHeapInfo(); - Logger::err(str::format( - "DxvkMemoryAllocator: Memory allocation failed", - "\n Size: ", req.core.memoryRequirements.size, - "\n Alignment: ", req.core.memoryRequirements.alignment, - "\n Mem types: ", "0x", std::hex, req.core.memoryRequirements.memoryTypeBits)); + Logger::err(str::format( + "DxvkMemoryAllocator: Memory allocation failed", + "\n Size: ", req.core.memoryRequirements.size, + "\n Alignment: ", req.core.memoryRequirements.alignment, + "\n Mem types: ", "0x", std::hex, req.core.memoryRequirements.memoryTypeBits)); - for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { - Logger::err(str::format("Heap ", i, ": ", - (m_memHeaps[i].stats.memoryAllocated >> 20), " MB allocated, ", - (m_memHeaps[i].stats.memoryUsed >> 20), " MB used, ", - m_device->features().extMemoryBudget - ? str::format( - (memHeapInfo.heaps[i].memoryAllocated >> 20), " MB allocated (driver), ", - (memHeapInfo.heaps[i].memoryBudget >> 20), " MB budget (driver), ", - (m_memHeaps[i].properties.size >> 20), " MB total") - : str::format( - (m_memHeaps[i].properties.size >> 20), " MB total"))); - } - - throw DxvkError("DxvkMemoryAllocator: Memory allocation failed"); + for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { + Logger::err(str::format("Heap ", i, ": ", + (m_memHeaps[i].stats.memoryAllocated >> 20), " MB allocated, ", + (m_memHeaps[i].stats.memoryUsed >> 20), " MB used, ", + m_device->features().extMemoryBudget + ? str::format( + (memHeapInfo.heaps[i].memoryAllocated >> 20), " MB allocated (driver), ", + (memHeapInfo.heaps[i].memoryBudget >> 20), " MB budget (driver), ", + (m_memHeaps[i].properties.size >> 20), " MB total") + : str::format( + (m_memHeaps[i].properties.size >> 20), " MB total"))); } - - return result; + + throw DxvkError("DxvkMemoryAllocator: Memory allocation failed"); } diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index c5caaf88c..daeb84bce 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -277,6 +277,7 @@ namespace dxvk { * \brief Memory requirement info */ struct DxvkMemoryRequirements { + VkImageTiling tiling; VkMemoryDedicatedRequirements dedicated; VkMemoryRequirements2 core; }; @@ -309,18 +310,6 @@ namespace dxvk { DxvkMemoryAllocator(DxvkDevice* device); ~DxvkMemoryAllocator(); - /** - * \brief Buffer-image granularity - * - * The granularity between linear and non-linear - * resources in adjacent memory locations. See - * section 11.6 of the Vulkan spec for details. - * \returns Buffer-image granularity - */ - VkDeviceSize bufferImageGranularity() const { - return m_devProps.limits.bufferImageGranularity; - } - /** * \brief Memory type mask for sparse resources * \returns Sparse resource memory types @@ -338,7 +327,7 @@ namespace dxvk { * \returns Allocated memory slice */ DxvkMemory alloc( - const DxvkMemoryRequirements& req, + DxvkMemoryRequirements req, DxvkMemoryProperties info, DxvkMemoryFlags hints); @@ -357,7 +346,6 @@ namespace dxvk { private: DxvkDevice* m_device; - VkPhysicalDeviceProperties m_devProps; VkPhysicalDeviceMemoryProperties m_memProps; dxvk::mutex m_mutex; diff --git a/src/dxvk/dxvk_sparse.cpp b/src/dxvk/dxvk_sparse.cpp index 373906edf..ffdc7814f 100644 --- a/src/dxvk/dxvk_sparse.cpp +++ b/src/dxvk/dxvk_sparse.cpp @@ -120,6 +120,7 @@ namespace dxvk { Rc DxvkSparsePageAllocator::allocPage() { DxvkMemoryRequirements memoryRequirements = { }; + memoryRequirements.tiling = VK_IMAGE_TILING_LINEAR; memoryRequirements.core = { VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 }; // We don't know what kind of resource the memory6 From 1c2df54bdfe21843c164ac443f84586fe16c9776 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 14 Jan 2023 02:26:42 +0100 Subject: [PATCH 1033/1348] [dxvk] Improve logging in case of memory errors --- src/dxvk/dxvk_memory.cpp | 71 +++++++++++++++++++++++++++++----------- src/dxvk/dxvk_memory.h | 5 +++ 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 96c100452..1b7c643e4 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include "dxvk_device.h" #include "dxvk_memory.h" @@ -276,26 +278,8 @@ namespace dxvk { } // We weren't able to allocate memory for this resource form any type - DxvkAdapterMemoryInfo memHeapInfo = m_device->adapter()->getMemoryHeapInfo(); - - Logger::err(str::format( - "DxvkMemoryAllocator: Memory allocation failed", - "\n Size: ", req.core.memoryRequirements.size, - "\n Alignment: ", req.core.memoryRequirements.alignment, - "\n Mem types: ", "0x", std::hex, req.core.memoryRequirements.memoryTypeBits)); - - for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { - Logger::err(str::format("Heap ", i, ": ", - (m_memHeaps[i].stats.memoryAllocated >> 20), " MB allocated, ", - (m_memHeaps[i].stats.memoryUsed >> 20), " MB used, ", - m_device->features().extMemoryBudget - ? str::format( - (memHeapInfo.heaps[i].memoryAllocated >> 20), " MB allocated (driver), ", - (memHeapInfo.heaps[i].memoryBudget >> 20), " MB budget (driver), ", - (m_memHeaps[i].properties.size >> 20), " MB total") - : str::format( - (m_memHeaps[i].properties.size >> 20), " MB total"))); - } + this->logMemoryError(req.core.memoryRequirements); + this->logMemoryStats(); throw DxvkError("DxvkMemoryAllocator: Memory allocation failed"); } @@ -653,4 +637,51 @@ namespace dxvk { return typeMask; } + + void DxvkMemoryAllocator::logMemoryError(const VkMemoryRequirements& req) const { + std::stringstream sstr; + sstr << "DxvkMemoryAllocator: Memory allocation failed" << std::endl + << " Size: " << req.size << std::endl + << " Alignment: " << req.alignment << std::endl + << " Mem types: "; + + uint32_t memTypes = req.memoryTypeBits; + + while (memTypes) { + uint32_t index = bit::tzcnt(memTypes); + sstr << index; + + if ((memTypes &= memTypes - 1)) + sstr << ","; + else + sstr << std::endl; + } + + Logger::err(sstr.str()); + } + + + void DxvkMemoryAllocator::logMemoryStats() const { + DxvkAdapterMemoryInfo memHeapInfo = m_device->adapter()->getMemoryHeapInfo(); + + std::stringstream sstr; + sstr << "Heap Size (MiB) Allocated Used Reserved Budget" << std::endl; + + for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { + sstr << std::setw(2) << i << ": " + << std::setw(6) << (m_memHeaps[i].properties.size >> 20) << " " + << std::setw(6) << (m_memHeaps[i].stats.memoryAllocated >> 20) << " " + << std::setw(6) << (m_memHeaps[i].stats.memoryUsed >> 20) << " "; + + if (m_device->features().extMemoryBudget) { + sstr << std::setw(6) << (memHeapInfo.heaps[i].memoryAllocated >> 20) << " " + << std::setw(6) << (memHeapInfo.heaps[i].memoryBudget >> 20) << " " << std::endl; + } else { + sstr << " n/a n/a" << std::endl; + } + } + + Logger::err(sstr.str()); + } + } diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index daeb84bce..7748ebbaa 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -403,6 +403,11 @@ namespace dxvk { uint32_t determineSparseMemoryTypes( DxvkDevice* device) const; + void logMemoryError( + const VkMemoryRequirements& req) const; + + void logMemoryStats() const; + }; } From 92de3f3f5f5ce4f1589814f5ed8f27167fd0f39c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 14 Jan 2023 18:35:03 +0100 Subject: [PATCH 1034/1348] [d3d11] Add missing context locks --- src/d3d11/d3d11_context.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 37135a759..51c154894 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2632,6 +2632,8 @@ namespace dxvk { ID3D11Buffer* pBuffer, UINT64 BufferStartOffsetInBytes, UINT Flags) { + D3D10DeviceLock lock = LockContext(); + if (!pTiledResource || !pBuffer) return; @@ -2662,6 +2664,8 @@ namespace dxvk { const D3D11_TILED_RESOURCE_COORDINATE* pSourceRegionCoordinate, const D3D11_TILE_REGION_SIZE* pTileRegionSize, UINT Flags) { + D3D10DeviceLock lock = LockContext(); + if (!pDestTiledResource || !pSourceTiledResource) return E_INVALIDARG; @@ -2740,6 +2744,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11CommonContext::ResizeTilePool( ID3D11Buffer* pTilePool, UINT64 NewSizeInBytes) { + D3D10DeviceLock lock = LockContext(); + if (NewSizeInBytes % SparseMemoryPageSize) return E_INVALIDARG; @@ -2765,6 +2771,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11CommonContext::TiledResourceBarrier( ID3D11DeviceChild* pTiledResourceOrViewAccessBeforeBarrier, ID3D11DeviceChild* pTiledResourceOrViewAccessAfterBarrier) { + D3D10DeviceLock lock = LockContext(); + DxvkGlobalPipelineBarrier srcBarrier = GetTiledResourceDependency(pTiledResourceOrViewAccessBeforeBarrier); DxvkGlobalPipelineBarrier dstBarrier = GetTiledResourceDependency(pTiledResourceOrViewAccessAfterBarrier); @@ -2793,6 +2801,8 @@ namespace dxvk { const UINT* pRangeTileOffsets, const UINT* pRangeTileCounts, UINT Flags) { + D3D10DeviceLock lock = LockContext(); + if (!pTiledResource || !NumRegions || !NumRanges) return E_INVALIDARG; @@ -2946,6 +2956,8 @@ namespace dxvk { const D3D11_TILE_REGION_SIZE* pDestTileRegionSize, const void* pSourceTileData, UINT Flags) { + D3D10DeviceLock lock = LockContext(); + if (!pDestTiledResource || !pSourceTileData) return; From c347bd4d8bf98fcacd892f7471a7b283b46d65fe Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 12 Jan 2023 18:18:11 +0100 Subject: [PATCH 1035/1348] [dxvk] Allow creating buffer views with undefined format --- src/dxvk/dxvk_buffer.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 48d88bbbf..f2fbf5c5b 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -204,8 +204,9 @@ namespace dxvk { const DxvkBufferViewCreateInfo& info) : m_vkd(vkd), m_info(info), m_buffer(buffer), m_bufferSlice (getSliceHandle()), - m_bufferView (createBufferView(m_bufferSlice)) { - + m_bufferView (VK_NULL_HANDLE) { + if (m_info.format != VK_FORMAT_UNDEFINED) + m_bufferView = createBufferView(m_bufferSlice); } @@ -247,17 +248,21 @@ namespace dxvk { void DxvkBufferView::updateBufferView( const DxvkBufferSliceHandle& slice) { - if (m_views.empty()) - m_views.insert({ m_bufferSlice, m_bufferView }); - - m_bufferSlice = slice; - - auto entry = m_views.find(slice); - if (entry != m_views.end()) { - m_bufferView = entry->second; + if (m_info.format != VK_FORMAT_UNDEFINED) { + if (m_views.empty()) + m_views.insert({ m_bufferSlice, m_bufferView }); + + m_bufferSlice = slice; + + auto entry = m_views.find(slice); + if (entry != m_views.end()) { + m_bufferView = entry->second; + } else { + m_bufferView = createBufferView(m_bufferSlice); + m_views.insert({ m_bufferSlice, m_bufferView }); + } } else { - m_bufferView = createBufferView(m_bufferSlice); - m_views.insert({ m_bufferSlice, m_bufferView }); + m_bufferSlice = slice; } } From 82f500250f54f17da99c840dc647dab54a159b90 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 12 Jan 2023 18:26:17 +0100 Subject: [PATCH 1036/1348] [hud] Bind data buffers as views --- src/dxvk/hud/dxvk_hud_renderer.cpp | 15 +++++++++++++-- src/dxvk/hud/dxvk_hud_renderer.h | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/dxvk/hud/dxvk_hud_renderer.cpp b/src/dxvk/hud/dxvk_hud_renderer.cpp index b797d68e3..f7a7bcd13 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.cpp +++ b/src/dxvk/hud/dxvk_hud_renderer.cpp @@ -19,6 +19,7 @@ namespace dxvk::hud { m_dataView (createDataView()), m_dataOffset (0ull), m_fontBuffer (createFontBuffer()), + m_fontBufferView(createFontBufferView()), m_fontImage (createFontImage()), m_fontView (createFontView()), m_fontSampler (createFontSampler()) { @@ -107,7 +108,7 @@ namespace dxvk::hud { m_context->bindShader(Rc(m_textShaders.vert)); m_context->bindShader(Rc(m_textShaders.frag)); - m_context->bindResourceBuffer(VK_SHADER_STAGE_VERTEX_BIT, 0, DxvkBufferSlice(m_fontBuffer)); + m_context->bindResourceBufferView(VK_SHADER_STAGE_VERTEX_BIT, 0, Rc(m_fontBufferView)); m_context->bindResourceBufferView(VK_SHADER_STAGE_VERTEX_BIT, 1, Rc(m_dataView)); m_context->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 2, Rc(m_fontSampler)); m_context->bindResourceImageView(VK_SHADER_STAGE_FRAGMENT_BIT, 2, Rc(m_fontView)); @@ -129,7 +130,7 @@ namespace dxvk::hud { m_context->bindShader(Rc(m_graphShaders.vert)); m_context->bindShader(Rc(m_graphShaders.frag)); - m_context->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_dataBuffer)); + m_context->bindResourceBufferView(VK_SHADER_STAGE_FRAGMENT_BIT, 0, Rc(m_dataView)); static const DxvkInputAssemblyState iaState = { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, @@ -257,6 +258,16 @@ namespace dxvk::hud { } + Rc HudRenderer::createFontBufferView() { + DxvkBufferViewCreateInfo info; + info.format = VK_FORMAT_UNDEFINED; + info.rangeOffset = 0; + info.rangeLength = m_fontBuffer->info().size; + + return m_device->createBufferView(m_fontBuffer, info); + } + + Rc HudRenderer::createFontImage() { DxvkImageCreateInfo info; info.type = VK_IMAGE_TYPE_2D; diff --git a/src/dxvk/hud/dxvk_hud_renderer.h b/src/dxvk/hud/dxvk_hud_renderer.h index 3986fba81..dcea3197c 100644 --- a/src/dxvk/hud/dxvk_hud_renderer.h +++ b/src/dxvk/hud/dxvk_hud_renderer.h @@ -156,6 +156,7 @@ namespace dxvk::hud { VkDeviceSize m_dataOffset; Rc m_fontBuffer; + Rc m_fontBufferView; Rc m_fontImage; Rc m_fontView; Rc m_fontSampler; @@ -175,6 +176,7 @@ namespace dxvk::hud { Rc createDataView(); Rc createFontBuffer(); + Rc createFontBufferView(); Rc createFontImage(); Rc createFontView(); Rc createFontSampler(); From 6f194b0e7b52f0999f301b16041b8cb83231fb85 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 12 Jan 2023 18:07:52 +0100 Subject: [PATCH 1037/1348] [d3d11] Bind UAV counter buffers as views --- src/d3d11/d3d11_context.cpp | 27 +++++++++++++++------------ src/d3d11/d3d11_initializer.cpp | 11 +++++++---- src/d3d11/d3d11_view_uav.cpp | 14 +++++++++++--- src/d3d11/d3d11_view_uav.h | 10 ++++------ 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 51c154894..5a4734fc0 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -329,13 +329,14 @@ namespace dxvk { if (!buf || !uav) return; - auto counterSlice = uav->GetCounterSlice(); - if (!counterSlice.defined()) + auto counterView = uav->GetCounterView(); + + if (counterView == nullptr) return; EmitCs([ cDstSlice = buf->GetBufferSlice(DstAlignedByteOffset), - cSrcSlice = std::move(counterSlice) + cSrcSlice = counterView->slice() ] (DxvkContext* ctx) { ctx->copyBuffer( cDstSlice.buffer(), @@ -3702,25 +3703,27 @@ namespace dxvk { cUavSlotId = UavSlot, cCtrSlotId = CtrSlot, cBufferView = pUav->GetBufferView(), - cCounterSlice = pUav->GetCounterSlice(), + cCounterView = pUav->GetCounterView(), cCounterValue = Counter ] (DxvkContext* ctx) mutable { VkShaderStageFlags stages = ShaderStage == DxbcProgramType::ComputeShader ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_ALL_GRAPHICS; - if (cCounterSlice.defined() && cCounterValue != ~0u) { + if (cCounterView != nullptr && cCounterValue != ~0u) { + auto counterSlice = cCounterView->slice(); + ctx->updateBuffer( - cCounterSlice.buffer(), - cCounterSlice.offset(), + counterSlice.buffer(), + counterSlice.offset(), sizeof(uint32_t), &cCounterValue); } ctx->bindResourceBufferView(stages, cUavSlotId, Forwarder::move(cBufferView)); - ctx->bindResourceBuffer(stages, cCtrSlotId, - Forwarder::move(cCounterSlice)); + ctx->bindResourceBufferView(stages, cCtrSlotId, + Forwarder::move(cCounterView)); }); } else { EmitCs([ @@ -3734,7 +3737,7 @@ namespace dxvk { ctx->bindResourceImageView(stages, cUavSlotId, Forwarder::move(cImageView)); - ctx->bindResourceBuffer(stages, cCtrSlotId, DxvkBufferSlice()); + ctx->bindResourceBufferView(stages, cCtrSlotId, nullptr); }); } } else { @@ -3747,7 +3750,7 @@ namespace dxvk { : VK_SHADER_STAGE_ALL_GRAPHICS; ctx->bindResourceImageView(stages, cUavSlotId, nullptr); - ctx->bindResourceBuffer(stages, cCtrSlotId, DxvkBufferSlice()); + ctx->bindResourceBufferView(stages, cCtrSlotId, nullptr); }); } } @@ -4416,7 +4419,7 @@ namespace dxvk { for (uint32_t j = 0; j < cUsedBindings.stages[i].uavCount; j++) { ctx->bindResourceImageView(stages, uavSlotId, nullptr); - ctx->bindResourceBuffer(stages, ctrSlotId, DxvkBufferSlice()); + ctx->bindResourceBufferView(stages, ctrSlotId, nullptr); } } } diff --git a/src/d3d11/d3d11_initializer.cpp b/src/d3d11/d3d11_initializer.cpp index a5391adb2..44c16e561 100644 --- a/src/d3d11/d3d11_initializer.cpp +++ b/src/d3d11/d3d11_initializer.cpp @@ -54,18 +54,21 @@ namespace dxvk { void D3D11Initializer::InitUavCounter( D3D11UnorderedAccessView* pUav) { - auto counterBuffer = pUav->GetCounterSlice(); + auto counterView = pUav->GetCounterView(); - if (!counterBuffer.defined()) + if (counterView == nullptr) return; + auto counterSlice = counterView->slice(); + std::lock_guard lock(m_mutex); m_transferCommands += 1; const uint32_t zero = 0; m_context->updateBuffer( - counterBuffer.buffer(), - 0, sizeof(zero), &zero); + counterSlice.buffer(), + counterSlice.offset(), + sizeof(zero), &zero); FlushImplicit(); } diff --git a/src/d3d11/d3d11_view_uav.cpp b/src/d3d11/d3d11_view_uav.cpp index 51a7ceddd..f21fe053f 100644 --- a/src/d3d11/d3d11_view_uav.cpp +++ b/src/d3d11/d3d11_view_uav.cpp @@ -44,7 +44,7 @@ namespace dxvk { } if (pDesc->Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND | D3D11_BUFFER_UAV_FLAG_COUNTER)) - m_counterBuffer = CreateCounterBuffer(); + m_counterView = CreateCounterBufferView(); // Populate view info struct m_info.Buffer.Offset = viewInfo.rangeOffset; @@ -429,7 +429,7 @@ namespace dxvk { } - Rc D3D11UnorderedAccessView::CreateCounterBuffer() { + Rc D3D11UnorderedAccessView::CreateCounterBufferView() { Rc device = m_parent->GetDXVKDevice(); DxvkBufferCreateInfo info; @@ -443,7 +443,15 @@ namespace dxvk { | VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT; - return device->createBuffer(info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + Rc buffer = device->createBuffer(info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + DxvkBufferViewCreateInfo viewInfo; + viewInfo.format = VK_FORMAT_UNDEFINED; + viewInfo.rangeOffset = 0; + viewInfo.rangeLength = sizeof(uint32_t); + + return device->createBufferView(buffer, viewInfo); } } diff --git a/src/d3d11/d3d11_view_uav.h b/src/d3d11/d3d11_view_uav.h index 3076fe094..c86eba5fa 100644 --- a/src/d3d11/d3d11_view_uav.h +++ b/src/d3d11/d3d11_view_uav.h @@ -57,10 +57,8 @@ namespace dxvk { return m_imageView; } - DxvkBufferSlice GetCounterSlice() const { - return m_counterBuffer != nullptr - ? DxvkBufferSlice(m_counterBuffer) - : DxvkBufferSlice(); + Rc GetCounterView() const { + return m_counterView; } static HRESULT GetDescFromResource( @@ -85,9 +83,9 @@ namespace dxvk { D3D11_VK_VIEW_INFO m_info; Rc m_bufferView; Rc m_imageView; - Rc m_counterBuffer; + Rc m_counterView; - Rc CreateCounterBuffer(); + Rc CreateCounterBufferView(); }; From 4a30933359205a2bc72db600175ce783b61b0f5f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 12 Jan 2023 19:09:24 +0100 Subject: [PATCH 1038/1348] [dxvk] Add UBO set property to descriptor info Used to explicitly propagate storage buffer bindings to the respective UBO set. --- src/d3d11/d3d11_video.cpp | 2 +- src/d3d9/d3d9_fixed_function.cpp | 6 ++++++ src/d3d9/d3d9_swvp_emu.cpp | 1 + src/dxbc/dxbc_compiler.cpp | 1 + src/dxso/dxso_compiler.cpp | 4 ++++ src/dxvk/dxvk_pipelayout.cpp | 12 +++++++----- src/dxvk/dxvk_pipelayout.h | 1 + 7 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 0e0a4897a..e98210330 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -329,7 +329,7 @@ namespace dxvk { SpirvCodeBuffer fsCode(d3d11_video_blit_frag); const std::array fsBindings = {{ - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_UNIFORM_READ_BIT }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_UNIFORM_READ_BIT, VK_TRUE }, { VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, 0 }, { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index f8225222e..7b6b379bb 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -423,6 +423,7 @@ namespace dxvk { binding.resourceBinding = getSpecConstantBufferSlot(); binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; + binding.uboSet = VK_TRUE; bindings.push_back(binding); return specBlock; @@ -1577,6 +1578,7 @@ namespace dxvk { binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; + binding.uboSet = VK_TRUE; m_bindings.push_back(binding); } @@ -1616,6 +1618,7 @@ namespace dxvk { binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_SHADER_READ_BIT; + binding.uboSet = VK_TRUE; m_bindings.push_back(binding); } @@ -2227,6 +2230,7 @@ namespace dxvk { binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; + binding.uboSet = VK_TRUE; m_bindings.push_back(binding); // Load constants @@ -2314,6 +2318,7 @@ namespace dxvk { binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; + binding.uboSet = VK_TRUE; m_bindings.push_back(binding); } @@ -2353,6 +2358,7 @@ namespace dxvk { binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; + binding.uboSet = VK_TRUE; m_bindings.push_back(binding); // Declare output array for clip distances diff --git a/src/d3d9/d3d9_swvp_emu.cpp b/src/d3d9/d3d9_swvp_emu.cpp index 39bf3da1d..210edf01f 100644 --- a/src/d3d9/d3d9_swvp_emu.cpp +++ b/src/d3d9/d3d9_swvp_emu.cpp @@ -135,6 +135,7 @@ namespace dxvk { m_bufferBinding.resourceBinding = bufferSlot; m_bufferBinding.stage = VK_SHADER_STAGE_GEOMETRY_BIT; m_bufferBinding.access = VK_ACCESS_SHADER_WRITE_BIT; + m_bufferBinding.uboSet = VK_TRUE; // Load our builtins uint32_t primitiveIdPtr = m_module.newVar(m_module.defPointerType(uint_t, spv::StorageClassInput), spv::StorageClassInput); diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 110f9b0d4..01f715e04 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -862,6 +862,7 @@ namespace dxvk { binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; binding.resourceBinding = bindingId; + binding.uboSet = VK_TRUE; m_bindings.push_back(binding); } diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index f453f8172..00e734247 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -307,6 +307,7 @@ namespace dxvk { binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; + binding.uboSet = VK_TRUE; m_bindings.push_back(binding); } @@ -398,6 +399,7 @@ namespace dxvk { binding.access = asSsbo ? VK_ACCESS_SHADER_READ_BIT : VK_ACCESS_UNIFORM_READ_BIT; + binding.uboSet = VK_TRUE; m_bindings.push_back(binding); return constantBufferId; @@ -483,6 +485,7 @@ namespace dxvk { binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; + binding.uboSet = VK_TRUE; m_bindings.push_back(binding); } @@ -3457,6 +3460,7 @@ void DxsoCompiler::emitControlFlowGenericLoop( binding.resourceBinding = bindingId; binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; binding.access = VK_ACCESS_UNIFORM_READ_BIT; + binding.uboSet = VK_TRUE; m_bindings.push_back(binding); // Declare output array for clip distances diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index ef40431b9..88b9083b6 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -34,11 +34,12 @@ namespace dxvk { bool DxvkBindingInfo::eq(const DxvkBindingInfo& other) const { - return descriptorType == other.descriptorType - && resourceBinding == other.resourceBinding - && viewType == other.viewType - && stage == other.stage - && access == other.access; + return descriptorType == other.descriptorType + && resourceBinding == other.resourceBinding + && viewType == other.viewType + && stage == other.stage + && access == other.access + && uboSet == other.uboSet; } @@ -49,6 +50,7 @@ namespace dxvk { hash.add(uint32_t(viewType)); hash.add(uint32_t(stage)); hash.add(access); + hash.add(uint32_t(uboSet)); return hash; } diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 8c03d6dd6..66599ea0f 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -36,6 +36,7 @@ namespace dxvk { VkImageViewType viewType; ///< Image view type VkShaderStageFlagBits stage; ///< Shader stage VkAccessFlags access; ///< Access mask for the resource + VkBool32 uboSet; ///< Whether to include this in the UBO set /** * \brief Computes descriptor set index for the given binding From a8f9fdb21de7edeacfcd29863453be619fa24a06 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 13 Jan 2023 02:22:53 +0100 Subject: [PATCH 1039/1348] [dxvk] Rearrange descriptor sets This allows us not to unnecessarily dirty the FS UBO set when changing tetxure bindings, leading to a cleaner separation. --- src/dxvk/dxvk_context.cpp | 14 ++++++++------ src/dxvk/dxvk_pipelayout.cpp | 8 +++----- src/dxvk/dxvk_pipelayout.h | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index e59b97bc6..b0f03a6e6 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1792,14 +1792,16 @@ namespace dxvk { ~(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT); - if (usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) + // Fast early-out for plain uniform buffers, very common + if (likely(usage == VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) { + m_descriptorState.dirtyBuffers(buffer->getShaderStages()); + return; + } + + if (usage & (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) m_descriptorState.dirtyBuffers(buffer->getShaderStages()); - // Fast early-out for plain buffers, very common - if (likely(!(usage & ~(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)))) - return; - - if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) + if (usage & (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) m_descriptorState.dirtyViews(buffer->getShaderStages()); if (usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index 88b9083b6..c16992cf8 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -14,11 +14,9 @@ namespace dxvk { return DxvkDescriptorSets::CsAll; } else if (stage == VK_SHADER_STAGE_FRAGMENT_BIT) { // For fragment shaders, create a separate set for UBOs - if (descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER - || descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) - return DxvkDescriptorSets::FsBuffers; - - return DxvkDescriptorSets::FsViews; + return uboSet + ? DxvkDescriptorSets::FsBuffers + : DxvkDescriptorSets::FsViews; } else { // Put all vertex shader resources into the last set. // Vertex shader UBOs are usually updated every draw, diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 66599ea0f..1e9b6b1e8 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -552,7 +552,7 @@ namespace dxvk { if (m_dirtyBuffers & VK_SHADER_STAGE_FRAGMENT_BIT) result |= (1u << DxvkDescriptorSets::FsBuffers); if (m_dirtyViews & VK_SHADER_STAGE_FRAGMENT_BIT) - result |= (1u << DxvkDescriptorSets::FsViews) | (1u << DxvkDescriptorSets::FsBuffers); + result |= (1u << DxvkDescriptorSets::FsViews); if ((m_dirtyBuffers | m_dirtyViews) & (VK_SHADER_STAGE_ALL_GRAPHICS & ~VK_SHADER_STAGE_FRAGMENT_BIT)) result |= (1u << DxvkDescriptorSets::VsAll); return result; From d35bf455d9d54d6085cc0126b4d115530b98a181 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 13 Jan 2023 02:39:12 +0100 Subject: [PATCH 1040/1348] [dxvk] Rename bindResourceBuffer to bindUniformBuffer --- src/d3d11/d3d11_context.cpp | 14 +++++++------- src/d3d11/d3d11_video.cpp | 4 ++-- src/d3d9/d3d9_constant_buffer.cpp | 4 ++-- src/d3d9/d3d9_device.cpp | 4 ++-- src/dxvk/dxvk_context.h | 12 +++++++----- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 5a4734fc0..748b378e3 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3375,7 +3375,7 @@ namespace dxvk { ctx->bindShader( Forwarder::move(cShader)); - ctx->bindResourceBuffer(stage, slotId, + ctx->bindUniformBuffer(stage, slotId, Forwarder::move(cBuffer)); }); } else { @@ -3386,7 +3386,7 @@ namespace dxvk { D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); ctx->bindShader(nullptr); - ctx->bindResourceBuffer(stage, slotId, DxvkBufferSlice()); + ctx->bindUniformBuffer(stage, slotId, DxvkBufferSlice()); }); } } @@ -3598,7 +3598,7 @@ namespace dxvk { cBufferSlice = pBuffer->GetBufferSlice(16 * Offset, 16 * Length) ] (DxvkContext* ctx) mutable { VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceBuffer(stage, cSlotId, + ctx->bindUniformBuffer(stage, cSlotId, Forwarder::move(cBufferSlice)); }); } else { @@ -3606,7 +3606,7 @@ namespace dxvk { cSlotId = Slot ] (DxvkContext* ctx) { VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceBuffer(stage, cSlotId, DxvkBufferSlice()); + ctx->bindUniformBuffer(stage, cSlotId, DxvkBufferSlice()); }); } } @@ -3624,7 +3624,7 @@ namespace dxvk { cLength = 16 * Length ] (DxvkContext* ctx) { VkShaderStageFlagBits stage = GetShaderStage(ShaderStage); - ctx->bindResourceBufferRange(stage, cSlotId, cOffset, cLength); + ctx->bindUniformBufferRange(stage, cSlotId, cOffset, cLength); }); } @@ -4390,10 +4390,10 @@ namespace dxvk { // Unbind constant buffers, including the shader's ICB auto cbSlotId = computeConstantBufferBinding(programType, 0); - ctx->bindResourceBuffer(stage, cbSlotId + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, DxvkBufferSlice()); + ctx->bindUniformBuffer(stage, cbSlotId + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, DxvkBufferSlice()); for (uint32_t j = 0; j < cUsedBindings.stages[i].cbvCount; j++) - ctx->bindResourceBuffer(stage, cbSlotId + j, DxvkBufferSlice()); + ctx->bindUniformBuffer(stage, cbSlotId + j, DxvkBufferSlice()); // Unbind shader resource views auto srvSlotId = computeSrvBinding(programType, 0); diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index e98210330..e4d763598 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -1202,7 +1202,7 @@ namespace dxvk { ctx->bindRenderTargets(std::move(rt), 0u); ctx->bindShader(Rc(m_vs)); ctx->bindShader(Rc(m_fs)); - ctx->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo)); + ctx->bindUniformBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo)); DxvkInputAssemblyState iaState; iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; @@ -1318,7 +1318,7 @@ namespace dxvk { ctx->bindShader(nullptr); ctx->bindShader(nullptr); - ctx->bindResourceBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice()); + ctx->bindUniformBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice()); }); } diff --git a/src/d3d9/d3d9_constant_buffer.cpp b/src/d3d9/d3d9_constant_buffer.cpp index a88935b01..523f53914 100644 --- a/src/d3d9/d3d9_constant_buffer.cpp +++ b/src/d3d9/d3d9_constant_buffer.cpp @@ -65,7 +65,7 @@ namespace dxvk { cOffset = m_offset, cLength = size ] (DxvkContext* ctx) { - ctx->bindResourceBufferRange(cStages, cBinding, cOffset, cLength); + ctx->bindUniformBufferRange(cStages, cBinding, cOffset, cLength); }); void* mapPtr = reinterpret_cast(m_slice.mapPtr) + m_offset; @@ -118,7 +118,7 @@ namespace dxvk { cBinding = m_binding, cSlice = DxvkBufferSlice(m_buffer) ] (DxvkContext* ctx) mutable { - ctx->bindResourceBuffer(cStages, cBinding, std::move(cSlice)); + ctx->bindUniformBuffer(cStages, cBinding, std::move(cSlice)); }); } diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 7634848a7..93554d0ec 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2718,11 +2718,11 @@ namespace dxvk { ctx->bindShader(nullptr); ctx->bindShader(std::move(shader)); - ctx->bindResourceBuffer(VK_SHADER_STAGE_GEOMETRY_BIT, getSWVPBufferSlot(), std::move(cBufferSlice)); + ctx->bindUniformBuffer(VK_SHADER_STAGE_GEOMETRY_BIT, getSWVPBufferSlot(), std::move(cBufferSlice)); ctx->draw( drawInfo.vertexCount, drawInfo.instanceCount, cStartIndex, 0); - ctx->bindResourceBuffer(VK_SHADER_STAGE_GEOMETRY_BIT, getSWVPBufferSlot(), DxvkBufferSlice()); + ctx->bindUniformBuffer(VK_SHADER_STAGE_GEOMETRY_BIT, getSWVPBufferSlot(), DxvkBufferSlice()); ctx->bindShader(nullptr); }); diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index aa42ef79f..2da97d97d 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -169,14 +169,16 @@ namespace dxvk { } /** - * \brief Binds buffer as a shader resource + * \brief Binds buffer to the UBO set * - * Can be used for uniform and storage buffers. + * Can be used for uniform and storage buffers bound that + * are used within the UBO descriptor set. Storage buffers + * within the view set must be bound via a view. * \param [in] stages Shader stages that access the binding * \param [in] slot Resource binding slot * \param [in] buffer Buffer to bind */ - void bindResourceBuffer( + void bindUniformBuffer( VkShaderStageFlags stages, uint32_t slot, DxvkBufferSlice&& buffer) { @@ -191,12 +193,12 @@ namespace dxvk { } /** - * \brief Changes bound range of a resource buffer + * \brief Changes bound range of a uniform buffer * * Can be used to quickly bind a new sub-range of * a buffer rather than re-binding the entire buffer. */ - void bindResourceBufferRange( + void bindUniformBufferRange( VkShaderStageFlags stages, uint32_t slot, VkDeviceSize offset, From 459758c6ffa386fbba5cf995d680ce9ba57b7101 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 13 Jan 2023 03:44:21 +0100 Subject: [PATCH 1041/1348] [d3d9] Don't set storage buffer usage unless necessary This actually matters now to some degree. --- src/d3d9/d3d9_constant_buffer.cpp | 32 ++++++++++++++++++++++++++----- src/d3d9/d3d9_constant_buffer.h | 7 +++++++ src/d3d9/d3d9_device.cpp | 1 + 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/d3d9/d3d9_constant_buffer.cpp b/src/d3d9/d3d9_constant_buffer.cpp index 523f53914..5bbd9a1d9 100644 --- a/src/d3d9/d3d9_constant_buffer.cpp +++ b/src/d3d9/d3d9_constant_buffer.cpp @@ -13,7 +13,7 @@ namespace dxvk { DxsoProgramType ShaderStage, DxsoConstantBuffers BufferType, VkDeviceSize Size) - : D3D9ConstantBuffer(pDevice, GetShaderStage(ShaderStage), + : D3D9ConstantBuffer(pDevice, getBufferUsage(pDevice, ShaderStage, BufferType), GetShaderStage(ShaderStage), computeResourceSlotId(ShaderStage, DxsoBindingType::ConstantBuffer, BufferType), Size) { @@ -22,11 +22,13 @@ namespace dxvk { D3D9ConstantBuffer::D3D9ConstantBuffer( D3D9DeviceEx* pDevice, + VkBufferUsageFlags Usage, VkShaderStageFlags Stages, uint32_t ResourceSlot, VkDeviceSize Size) : m_device (pDevice) , m_binding (ResourceSlot) + , m_usage (Usage) , m_stages (Stages) , m_size (Size) , m_align (getAlignment(pDevice->GetDXVKDevice())) { @@ -98,12 +100,15 @@ namespace dxvk { // in the backend, so set both STORAGE and UNIFORM usage/access. DxvkBufferCreateInfo bufferInfo; bufferInfo.size = align(m_size, m_align); - bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT - | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - bufferInfo.access = VK_ACCESS_UNIFORM_READ_BIT - | VK_ACCESS_SHADER_READ_BIT; + bufferInfo.usage = m_usage; + bufferInfo.access = 0; bufferInfo.stages = util::pipelineStages(m_stages); + if (m_usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) + bufferInfo.access |= VK_ACCESS_UNIFORM_READ_BIT; + if (m_usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) + bufferInfo.access |= VK_ACCESS_SHADER_READ_BIT; + VkMemoryPropertyFlags memoryFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; @@ -130,4 +135,21 @@ namespace dxvk { device->properties().extRobustness2.robustUniformBufferAccessSizeAlignment); } + + VkBufferUsageFlags D3D9ConstantBuffer::getBufferUsage( + D3D9DeviceEx* pDevice, + DxsoProgramType ShaderStage, + DxsoConstantBuffers BufferType) { + VkBufferUsageFlags result = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + + // We won't always need this, but the only buffer that + // this applies to is so large that it will not matter. + if (pDevice->CanSWVP() + && ShaderStage == DxsoProgramType::VertexShader + && BufferType == DxsoConstantBuffers::VSConstantBuffer) + result |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + + return result; + } + } diff --git a/src/d3d9/d3d9_constant_buffer.h b/src/d3d9/d3d9_constant_buffer.h index 980a7b1bf..22abe2225 100644 --- a/src/d3d9/d3d9_constant_buffer.h +++ b/src/d3d9/d3d9_constant_buffer.h @@ -29,6 +29,7 @@ namespace dxvk { D3D9ConstantBuffer( D3D9DeviceEx* pDevice, + VkBufferUsageFlags Usage, VkShaderStageFlags Stages, uint32_t ResourceSlot, VkDeviceSize Size); @@ -66,6 +67,7 @@ namespace dxvk { D3D9DeviceEx* m_device = nullptr; uint32_t m_binding = 0u; + VkBufferUsageFlags m_usage = 0u; VkShaderStageFlags m_stages = 0u; VkDeviceSize m_size = 0ull; VkDeviceSize m_align = 0ull; @@ -78,6 +80,11 @@ namespace dxvk { VkDeviceSize getAlignment(const Rc& device) const; + static VkBufferUsageFlags getBufferUsage( + D3D9DeviceEx* pDevice, + DxsoProgramType ShaderStage, + DxsoConstantBuffers BufferType); + }; } \ No newline at end of file diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 93554d0ec..e8ef30126 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5021,6 +5021,7 @@ namespace dxvk { if (m_usingGraphicsPipelines) { m_specBuffer = D3D9ConstantBuffer(this, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, getSpecConstantBufferSlot(), sizeof(D3D9SpecializationInfo)); From af05265cb62e663e97f81e1ece1fed3f87ae3d53 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 15 Jan 2023 15:54:03 +0100 Subject: [PATCH 1042/1348] [dxvk] Set thread priority for background workers We accidentally lost this somehow. --- src/dxvk/dxvk_pipemanager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index 40c20cf81..84a07c1f9 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -112,9 +112,11 @@ namespace dxvk { priority = DxvkPipelinePriority::Low; } - m_workers.emplace_back([this, priority] { + auto& worker = m_workers.emplace_back([this, priority] { runWorker(priority); }); + + worker.set_priority(ThreadPriority::Lowest); } Logger::info(str::format("DXVK: Using ", workerCount, " compiler threads")); From 9010f11adf7718f28ba610479d788772c44d95ea Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 16 Jan 2023 02:31:36 +0000 Subject: [PATCH 1043/1348] [dxgi, d3d11] Remove support for legacy IWineDXGISwapChainFactory interface vkd3d-proton 2.8 released last year with support for the new swapchain interface. No need to keep support for this legacy interface hanging around when it complicates adding DxgiOptions support to the swapchain. --- src/d3d11/d3d11_device.cpp | 87 +------------------------------------- src/d3d11/d3d11_device.h | 36 ---------------- src/d3d11/meson.build | 3 -- src/dxgi/dxgi_factory.cpp | 9 ---- src/dxgi/dxgi_interfaces.h | 20 --------- 5 files changed, 1 insertion(+), 154 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 001574625..a69a0164c 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -3019,85 +3019,6 @@ namespace dxvk { - WineDXGISwapChainFactory::WineDXGISwapChainFactory( - D3D11DXGIDevice* pContainer, - D3D11Device* pDevice) - : m_container(pContainer), m_device(pDevice) { - - } - - - ULONG STDMETHODCALLTYPE WineDXGISwapChainFactory::AddRef() { - return m_device->AddRef(); - } - - - ULONG STDMETHODCALLTYPE WineDXGISwapChainFactory::Release() { - return m_device->Release(); - } - - - HRESULT STDMETHODCALLTYPE WineDXGISwapChainFactory::QueryInterface( - REFIID riid, - void** ppvObject) { - return m_device->QueryInterface(riid, ppvObject); - } - - - HRESULT STDMETHODCALLTYPE WineDXGISwapChainFactory::CreateSwapChainForHwnd( - IDXGIFactory* pFactory, - HWND hWnd, - const DXGI_SWAP_CHAIN_DESC1* pDesc, - const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, - IDXGIOutput* pRestrictToOutput, - IDXGISwapChain1** ppSwapChain) { - InitReturnPtr(ppSwapChain); - - if (!ppSwapChain || !pDesc || !hWnd) - return DXGI_ERROR_INVALID_CALL; - - // Make sure the back buffer size is not zero - DXGI_SWAP_CHAIN_DESC1 desc = *pDesc; - - wsi::getWindowSize(hWnd, - desc.Width ? nullptr : &desc.Width, - desc.Height ? nullptr : &desc.Height); - - // If necessary, set up a default set of - // fullscreen parameters for the swap chain - DXGI_SWAP_CHAIN_FULLSCREEN_DESC fsDesc; - - if (pFullscreenDesc) { - fsDesc = *pFullscreenDesc; - } else { - fsDesc.RefreshRate = { 0, 0 }; - fsDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - fsDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - fsDesc.Windowed = TRUE; - } - - try { - auto vki = m_device->GetDXVKDevice()->adapter()->vki(); - - // Create surface factory for the window - Com surfaceFactory = new DxgiSurfaceFactory(vki->getLoaderProc(), hWnd); - - // Create presenter for the device - Com presenter = new D3D11SwapChain( - m_container, m_device, surfaceFactory.ptr(), &desc); - - // Create the actual swap chain - *ppSwapChain = ref(new DxgiSwapChain( - pFactory, presenter.ptr(), hWnd, &desc, &fsDesc)); - return S_OK; - } catch (const DxvkError& e) { - Logger::err(e.message()); - return E_INVALIDARG; - } - } - - - DXGIDXVKDevice::DXGIDXVKDevice(D3D11DXGIDevice* pContainer) : m_container(pContainer), m_apiVersion(11) { @@ -3149,8 +3070,7 @@ namespace dxvk { m_d3d11Interop (this, &m_d3d11Device), m_d3d11Video (this, &m_d3d11Device), m_metaDevice (this), - m_dxvkFactory (this, &m_d3d11Device), - m_wineFactory (this, &m_d3d11Device) { + m_dxvkFactory (this, &m_d3d11Device) { } @@ -3215,11 +3135,6 @@ namespace dxvk { return S_OK; } - if (riid == __uuidof(IWineDXGISwapChainFactory)) { - *ppvObject = ref(&m_wineFactory); - return S_OK; - } - if (riid == __uuidof(ID3D11VideoDevice)) { *ppvObject = ref(&m_d3d11Video); return S_OK; diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index e23de4b21..58700cc39 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -722,41 +722,6 @@ namespace dxvk { }; - /** - * \brief DXGI swap chain factory - */ - class WineDXGISwapChainFactory : public IWineDXGISwapChainFactory { - - public: - - WineDXGISwapChainFactory( - D3D11DXGIDevice* pContainer, - D3D11Device* pDevice); - - ULONG STDMETHODCALLTYPE AddRef(); - - ULONG STDMETHODCALLTYPE Release(); - - HRESULT STDMETHODCALLTYPE QueryInterface( - REFIID riid, - void** ppvObject); - - HRESULT STDMETHODCALLTYPE CreateSwapChainForHwnd( - IDXGIFactory* pFactory, - HWND hWnd, - const DXGI_SWAP_CHAIN_DESC1* pDesc, - const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, - IDXGIOutput* pRestrictToOutput, - IDXGISwapChain1** ppSwapChain); - - private: - - D3D11DXGIDevice* m_container; - D3D11Device* m_device; - - }; - - /** * \brief D3D11 device metadata shenanigans */ @@ -884,7 +849,6 @@ namespace dxvk { DXGIDXVKDevice m_metaDevice; DXGIVkSwapChainFactory m_dxvkFactory; - WineDXGISwapChainFactory m_wineFactory; uint32_t m_frameLatency = DefaultFrameLatency; diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 6067f7697..ea51a9d5f 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -2,9 +2,6 @@ d3d11_res = wrc_generator.process('version.rc') dxgi_common_src = [ '../dxgi/dxgi_format.cpp', - '../dxgi/dxgi_monitor.cpp', - '../dxgi/dxgi_surface.cpp', - '../dxgi/dxgi_swapchain.cpp', ] d3d10_src = [ diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp index cd548db5e..d15686634 100644 --- a/src/dxgi/dxgi_factory.cpp +++ b/src/dxgi/dxgi_factory.cpp @@ -151,7 +151,6 @@ namespace dxvk { Com frontendSwapChain; Com dxvkFactory; - Com wineFactory; if (SUCCEEDED(pDevice->QueryInterface(IID_PPV_ARGS(&dxvkFactory)))) { Com surfaceFactory = new DxgiSurfaceFactory( @@ -166,14 +165,6 @@ namespace dxvk { } frontendSwapChain = new DxgiSwapChain(this, presenter.ptr(), hWnd, &desc, &fsDesc); - } else if (SUCCEEDED(pDevice->QueryInterface(IID_PPV_ARGS(&wineFactory)))) { - HRESULT hr = wineFactory->CreateSwapChainForHwnd(this, hWnd, &desc, &fsDesc, - pRestrictToOutput, reinterpret_cast(&frontendSwapChain)); - - if (FAILED(hr)) { - Logger::err(str::format("DXGI: CreateSwapChainForHwnd: Failed to create swap chain, hr ", hr)); - return hr; - } } else { Logger::err("DXGI: CreateSwapChainForHwnd: Unsupported device type"); return DXGI_ERROR_UNSUPPORTED; diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index e15acc085..b5e584f3f 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -409,24 +409,6 @@ IDXGIVkInteropAdapter : public IUnknown { }; -/** - * \brief IWineDXGISwapChainFactory device interface - * - * Allows a swap chain to be created from a device. - * See include/wine/winedxgi.idl for definition. - */ -MIDL_INTERFACE("53cb4ff0-c25a-4164-a891-0e83db0a7aac") -IWineDXGISwapChainFactory : public IUnknown { - virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForHwnd( - IDXGIFactory* pFactory, - HWND hWnd, - const DXGI_SWAP_CHAIN_DESC1* pDesc, - const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, - IDXGIOutput* pRestrictToOutput, - IDXGISwapChain1** ppSwapChain) = 0; -}; - - #ifdef _MSC_VER struct __declspec(uuid("907bf281-ea3c-43b4-a8e4-9f231107b4ff")) IDXGIDXVKAdapter; struct __declspec(uuid("92a5d77b-b6e1-420a-b260-fdd701272827")) IDXGIDXVKDevice; @@ -438,7 +420,6 @@ struct __declspec(uuid("5546cf8c-77e7-4341-b05d-8d4d5000e77d")) IDXGIVkInteropSu struct __declspec(uuid("1e7895a1-1bc3-4f9c-a670-290a4bc9581a")) IDXGIVkSurfaceFactory; struct __declspec(uuid("e4a9059e-b569-46ab-8de7-501bd2bc7f7a")) IDXGIVkSwapChain; struct __declspec(uuid("e7d6c3ca-23a0-4e08-9f2f-ea5231df6633")) IDXGIVkSwapChainFactory; -struct __declspec(uuid("53cb4ff0-c25a-4164-a891-0e83db0a7aac")) IWineDXGISwapChainFactory; #else __CRT_UUID_DECL(IDXGIDXVKAdapter, 0x907bf281,0xea3c,0x43b4,0xa8,0xe4,0x9f,0x23,0x11,0x07,0xb4,0xff); __CRT_UUID_DECL(IDXGIDXVKDevice, 0x92a5d77b,0xb6e1,0x420a,0xb2,0x60,0xfd,0xf7,0x01,0x27,0x28,0x27); @@ -450,5 +431,4 @@ __CRT_UUID_DECL(IDXGIVkInteropSurface, 0x5546cf8c,0x77e7,0x4341,0xb0,0x5d,0x __CRT_UUID_DECL(IDXGIVkSurfaceFactory, 0x1e7895a1,0x1bc3,0x4f9c,0xa6,0x70,0x29,0x0a,0x4b,0xc9,0x58,0x1a); __CRT_UUID_DECL(IDXGIVkSwapChain, 0xe4a9059e,0xb569,0x46ab,0x8d,0xe7,0x50,0x1b,0xd2,0xbc,0x7f,0x7a); __CRT_UUID_DECL(IDXGIVkSwapChainFactory, 0xe7d6c3ca,0x23a0,0x4e08,0x9f,0x2f,0xea,0x52,0x31,0xdf,0x66,0x33); -__CRT_UUID_DECL(IWineDXGISwapChainFactory, 0x53cb4ff0,0xc25a,0x4164,0xa8,0x91,0x0e,0x83,0xdb,0x0a,0x7a,0xac); #endif From bb75e214d616e40780434f54927ca5891e67413b Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 16 Jan 2023 02:38:09 +0000 Subject: [PATCH 1044/1348] [dxgi] Store top-level DxgiFactory in DxgiSwapChain Can do this now that we tossed the old stuff that depended on the swapchain factory being resident in D3D11. --- src/dxgi/dxgi_swapchain.cpp | 2 +- src/dxgi/dxgi_swapchain.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 684c73044..3f41df684 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -7,7 +7,7 @@ namespace dxvk { DxgiSwapChain::DxgiSwapChain( - IDXGIFactory* pFactory, + DxgiFactory* pFactory, IDXGIVkSwapChain* pPresenter, HWND hWnd, const DXGI_SWAP_CHAIN_DESC1* pDesc, diff --git a/src/dxgi/dxgi_swapchain.h b/src/dxgi/dxgi_swapchain.h index 6aaa6892c..c32c2c791 100644 --- a/src/dxgi/dxgi_swapchain.h +++ b/src/dxgi/dxgi_swapchain.h @@ -27,7 +27,7 @@ namespace dxvk { public: DxgiSwapChain( - IDXGIFactory* pFactory, + DxgiFactory* pFactory, IDXGIVkSwapChain* pPresenter, HWND hWnd, const DXGI_SWAP_CHAIN_DESC1* pDesc, @@ -175,7 +175,7 @@ namespace dxvk { dxvk::recursive_mutex m_lockWindow; dxvk::mutex m_lockBuffer; - Com m_factory; + Com m_factory; Com m_adapter; Com m_target; Com m_monitorInfo; From 28ee6867be00e5d32f96bb26a06209a6d1fb81a7 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 16 Jan 2023 02:42:55 +0000 Subject: [PATCH 1045/1348] [dxgi] Expose only sRGB when enableHDR is disabled Death Stranding: Director's Cut crashes if HDR was last enabled in-game and CheckColorSpaceSupport reports support for HDR but it is not globally enabled in DXGIOutput::GetDesc1's ColorSpace. It seems safer to just lock HDR behind an option to avoid any teething issues like this. It sucks, but it also makes sense in a way. --- src/dxgi/dxgi_swapchain.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 3f41df684..e7cd76516 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -523,6 +523,17 @@ namespace dxvk { if (!pColorSpaceSupport) return E_INVALIDARG; + // Don't expose any color spaces other than standard + // sRGB if the enableHDR option is not set. + // + // If we ever have a use for the non-SRGB non-HDR colorspaces + // some day, we may want to revisit this. + if (ColorSpace != DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 + && !m_factory->GetOptions()->enableHDR) { + *pColorSpaceSupport = 0; + return S_OK; + } + UINT support = m_presenter->CheckColorSpaceSupport(ColorSpace); *pColorSpaceSupport = support; return S_OK; From 132bc529c3b809b1290af5ad839685972cf34f01 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 16 Jan 2023 02:47:48 +0000 Subject: [PATCH 1046/1348] [dxgi] Only allow colorspace punting if we started in sRGB --- src/dxgi/dxgi_monitor.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/dxgi/dxgi_monitor.cpp b/src/dxgi/dxgi_monitor.cpp index 0cac3c45a..b0622b3be 100644 --- a/src/dxgi/dxgi_monitor.cpp +++ b/src/dxgi/dxgi_monitor.cpp @@ -72,6 +72,13 @@ namespace dxvk { void STDMETHODCALLTYPE DxgiMonitorInfo::PuntColorSpace(DXGI_COLOR_SPACE_TYPE ColorSpace) { + // Only allow punting if we started from sRGB. + // That way we can go from sRGB -> HDR10 or HDR10 -> sRGB if we started in sRGB. + // But if we started off by advertising HDR10 to the game, don't allow us to go back. + // This mirrors the behaviour of the global Windows HDR toggle more closely. + if (DefaultColorSpace() != DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709) + return; + m_globalColorSpace = ColorSpace; } From 1482715fd1f1c310cd183d61f9039ff11425eee4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 16 Jan 2023 16:15:19 +0100 Subject: [PATCH 1047/1348] [vulkan] Use fence for acquiring a swap chain image In practice, drivers will block here anyway. --- src/dxvk/dxvk_cmdlist.cpp | 7 ----- src/vulkan/vulkan_presenter.cpp | 50 +++++++++++++++++++++++++-------- src/vulkan/vulkan_presenter.h | 13 +++++++-- 3 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index a59b7707d..ecfd55207 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -269,13 +269,6 @@ namespace dxvk { m_commandSubmission.waitSemaphore(m_sdmaSemaphore, 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); } - // We promise to never do weird stuff to WSI images on - // the transfer queue, so blocking graphics is sufficient - if (isFirst && m_wsiSemaphores.acquire) { - m_commandSubmission.waitSemaphore(m_wsiSemaphores.acquire, - 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); - } - // Submit graphics commands if (cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer)) m_commandSubmission.executeCommandBuffer(cmd.initBuffer); diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index 694f2dbb0..d2210a400 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -12,13 +12,15 @@ namespace dxvk::vk { PresenterDevice device, const PresenterDesc& desc) : m_vki(vki), m_vkd(vkd), m_device(device) { - + if (createFence() != VK_SUCCESS) + throw DxvkError("Failed to create presenter fence."); } Presenter::~Presenter() { destroySwapchain(); destroySurface(); + destroyFence(); } @@ -39,12 +41,19 @@ namespace dxvk::vk { if (m_acquireStatus == VK_NOT_READY) { m_acquireStatus = m_vkd->vkAcquireNextImageKHR(m_vkd->device(), m_swapchain, std::numeric_limits::max(), - sync.acquire, VK_NULL_HANDLE, &m_imageIndex); + VK_NULL_HANDLE, m_acquireFence, &m_imageIndex); } if (m_acquireStatus != VK_SUCCESS && m_acquireStatus != VK_SUBOPTIMAL_KHR) return m_acquireStatus; - + + VkResult vr = waitForAcquireFence(); + + if (vr != VK_SUCCESS) { + Logger::err(str::format("Failed to wait for presenter fence: ", vr)); + return vr; + } + index = m_imageIndex; return m_acquireStatus; } @@ -74,7 +83,7 @@ namespace dxvk::vk { m_acquireStatus = m_vkd->vkAcquireNextImageKHR(m_vkd->device(), m_swapchain, std::numeric_limits::max(), - sync.acquire, VK_NULL_HANDLE, &m_imageIndex); + VK_NULL_HANDLE, m_acquireFence, &m_imageIndex); bool vsync = m_info.presentMode == VK_PRESENT_MODE_FIFO_KHR || m_info.presentMode == VK_PRESENT_MODE_FIFO_RELAXED_KHR; @@ -203,10 +212,6 @@ namespace dxvk::vk { for (uint32_t i = 0; i < m_semaphores.size(); i++) { VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; - if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(), - &semInfo, nullptr, &m_semaphores[i].acquire))) - return status; - if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(), &semInfo, nullptr, &m_semaphores[i].present))) return status; @@ -427,14 +432,19 @@ namespace dxvk::vk { } + VkResult Presenter::createFence() { + VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; + + return m_vkd->vkCreateFence(m_vkd->device(), &fenceInfo, nullptr, &m_acquireFence); + } + + void Presenter::destroySwapchain() { for (const auto& img : m_images) m_vkd->vkDestroyImageView(m_vkd->device(), img.view, nullptr); - for (const auto& sem : m_semaphores) { - m_vkd->vkDestroySemaphore(m_vkd->device(), sem.acquire, nullptr); + for (const auto& sem : m_semaphores) m_vkd->vkDestroySemaphore(m_vkd->device(), sem.present, nullptr); - } m_vkd->vkDestroySwapchainKHR(m_vkd->device(), m_swapchain, nullptr); @@ -451,4 +461,22 @@ namespace dxvk::vk { m_surface = VK_NULL_HANDLE; } + + void Presenter::destroyFence() { + m_vkd->vkWaitForFences(m_vkd->device(), 1, &m_acquireFence, + VK_TRUE, std::numeric_limits::max()); + m_vkd->vkDestroyFence(m_vkd->device(), m_acquireFence, nullptr); + } + + + VkResult Presenter::waitForAcquireFence() { + VkResult vr = m_vkd->vkWaitForFences(m_vkd->device(), 1, + &m_acquireFence, VK_TRUE, std::numeric_limits::max()); + + if (vr == VK_SUCCESS) + vr = m_vkd->vkResetFences(m_vkd->device(), 1, &m_acquireFence); + + return vr; + } + } diff --git a/src/vulkan/vulkan_presenter.h b/src/vulkan/vulkan_presenter.h index 641956f90..af1129dd0 100644 --- a/src/vulkan/vulkan_presenter.h +++ b/src/vulkan/vulkan_presenter.h @@ -79,7 +79,6 @@ namespace dxvk::vk { * image acquisition. */ struct PresenterSync { - VkSemaphore acquire; VkSemaphore present; }; @@ -207,8 +206,10 @@ namespace dxvk::vk { PresenterDevice m_device; PresenterInfo m_info; - VkSurfaceKHR m_surface = VK_NULL_HANDLE; - VkSwapchainKHR m_swapchain = VK_NULL_HANDLE; + VkFence m_acquireFence = VK_NULL_HANDLE; + + VkSurfaceKHR m_surface = VK_NULL_HANDLE; + VkSwapchainKHR m_swapchain = VK_NULL_HANDLE; std::vector m_images; std::vector m_semaphores; @@ -257,10 +258,16 @@ namespace dxvk::vk { VkResult createSurface(); + VkResult createFence(); + void destroySwapchain(); void destroySurface(); + void destroyFence(); + + VkResult waitForAcquireFence(); + }; } From 0e503ce795e5d22f7d432c3f834976bf03027374 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 16 Jan 2023 13:30:41 +0100 Subject: [PATCH 1048/1348] [vulkan] Log swap chain color space --- src/vulkan/vulkan_names.cpp | 15 +++++++++++++++ src/vulkan/vulkan_presenter.cpp | 1 + 2 files changed, 16 insertions(+) diff --git a/src/vulkan/vulkan_names.cpp b/src/vulkan/vulkan_names.cpp index 4d5f1a88e..be52650e7 100644 --- a/src/vulkan/vulkan_names.cpp +++ b/src/vulkan/vulkan_names.cpp @@ -307,6 +307,21 @@ std::ostream& operator << (std::ostream& os, VkPresentModeKHR e) { std::ostream& operator << (std::ostream& os, VkColorSpaceKHR e) { switch (e) { ENUM_NAME(VK_COLOR_SPACE_SRGB_NONLINEAR_KHR); + ENUM_NAME(VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT); + ENUM_NAME(VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT); + ENUM_NAME(VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT); + ENUM_NAME(VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT); + ENUM_NAME(VK_COLOR_SPACE_BT709_LINEAR_EXT); + ENUM_NAME(VK_COLOR_SPACE_BT709_NONLINEAR_EXT); + ENUM_NAME(VK_COLOR_SPACE_BT2020_LINEAR_EXT); + ENUM_NAME(VK_COLOR_SPACE_HDR10_ST2084_EXT); + ENUM_NAME(VK_COLOR_SPACE_DOLBYVISION_EXT); + ENUM_NAME(VK_COLOR_SPACE_HDR10_HLG_EXT); + ENUM_NAME(VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT); + ENUM_NAME(VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT); + ENUM_NAME(VK_COLOR_SPACE_PASS_THROUGH_EXT); + ENUM_NAME(VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT); + ENUM_NAME(VK_COLOR_SPACE_DISPLAY_NATIVE_AMD); ENUM_DEFAULT(e); } return os; diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index d2210a400..21ea00643 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -168,6 +168,7 @@ namespace dxvk::vk { Logger::info(str::format( "Presenter: Actual swap chain properties:" "\n Format: ", m_info.format.format, + "\n Color space: ", m_info.format.colorSpace, "\n Present mode: ", m_info.presentMode, "\n Buffer size: ", m_info.imageExtent.width, "x", m_info.imageExtent.height, "\n Image count: ", m_info.imageCount, From 599357721a9bbf8316ccaf12c40e972fb6047537 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 16 Jan 2023 13:31:02 +0100 Subject: [PATCH 1049/1348] [hud] Support HDR color spaces Blending is broken if we need to do encoding in the shader, but we cannot do much about that without changing the rendering process, so this will have to do for now. --- src/dxvk/hud/dxvk_hud.cpp | 7 ++- src/dxvk/hud/shaders/hud_frag_common.glsl | 68 +++++++++++++++++++++++ src/dxvk/hud/shaders/hud_graph_frag.frag | 20 ++----- src/dxvk/hud/shaders/hud_text_frag.frag | 15 ++--- 4 files changed, 83 insertions(+), 27 deletions(-) create mode 100644 src/dxvk/hud/shaders/hud_frag_common.glsl diff --git a/src/dxvk/hud/dxvk_hud.cpp b/src/dxvk/hud/dxvk_hud.cpp index 5a1af3c39..752e514b4 100644 --- a/src/dxvk/hud/dxvk_hud.cpp +++ b/src/dxvk/hud/dxvk_hud.cpp @@ -79,7 +79,10 @@ namespace dxvk::hud { const Rc& ctx, VkSurfaceFormatKHR surfaceFormat, VkExtent2D surfaceSize) { - bool isSrgb = lookupFormatInfo(surfaceFormat.format)->flags.test(DxvkFormatFlag::ColorSpaceSrgb); + VkColorSpaceKHR colorSpace = surfaceFormat.colorSpace; + + if (lookupFormatInfo(surfaceFormat.format)->flags.test(DxvkFormatFlag::ColorSpaceSrgb)) + colorSpace = VK_COLOR_SPACE_PASS_THROUGH_EXT; VkViewport viewport; viewport.x = 0.0f; @@ -97,7 +100,7 @@ namespace dxvk::hud { ctx->setRasterizerState(m_rsState); ctx->setBlendMode(0, m_blendMode); - ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, isSrgb); + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, colorSpace); m_renderer.beginFrame(ctx, surfaceSize, m_scale); } diff --git a/src/dxvk/hud/shaders/hud_frag_common.glsl b/src/dxvk/hud/shaders/hud_frag_common.glsl new file mode 100644 index 000000000..20b51c537 --- /dev/null +++ b/src/dxvk/hud/shaders/hud_frag_common.glsl @@ -0,0 +1,68 @@ +#define VK_COLOR_SPACE_SRGB_NONLINEAR_KHR (0) +#define VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT (1000104002) +#define VK_COLOR_SPACE_HDR10_ST2084_EXT (1000104008) +#define VK_COLOR_SPACE_PASS_THROUGH_EXT (1000104013) + +#define HUD_NITS (203.0f) + +const mat3 rec709_to_xyz = mat3( + 0.4123908, 0.2126390, 0.0193308, + 0.3575843, 0.7151687, 0.1191948, + 0.1804808, 0.0721923, 0.9505322); + +const mat3 xyz_to_rec2020 = mat3( + 1.7166512, -0.6666844, 0.0176399, + -0.3556708, 1.6164812, -0.0427706, + -0.2533663, 0.0157685, 0.9421031); + +const mat3 rec709_to_rec2020 = xyz_to_rec2020 * rec709_to_xyz; + +// Spec constants must always default to +// zero for DXVK to handle them properly +layout(constant_id = 0) const uint hud_color_space = 0; + +vec3 encodeSrgb(vec3 linear) { + bvec3 isLo = lessThanEqual(linear, vec3(0.0031308f)); + + vec3 loPart = linear * 12.92f; + vec3 hiPart = pow(linear, vec3(5.0f / 12.0f)) * 1.055f - 0.055f; + return mix(hiPart, loPart, isLo); +} + +vec3 encodePq(vec3 nits) { + const float c1 = 0.8359375f; + const float c2 = 18.8515625f; + const float c3 = 18.6875f; + const float m1 = 0.1593017578125f; + const float m2 = 78.84375f; + + vec3 y = clamp(nits / 10000.0f, vec3(0.0f), vec3(1.0f)); + vec3 y_m1 = pow(y, vec3(m1)); + + vec3 num = c1 + c2 * y_m1; + vec3 den = 1.0f + c3 * y_m1; + + return pow(num / den, vec3(m2)); +} + +vec3 encodeScRgb(vec3 nits) { + return nits / 80.0f; +} + +vec3 encodeOutput(vec3 linear) { + switch (hud_color_space) { + default: + return linear; + + case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR: + return encodeSrgb(linear); + + case VK_COLOR_SPACE_HDR10_ST2084_EXT: { + vec3 rec2020 = rec709_to_rec2020 * linear; + return encodePq(rec2020 * HUD_NITS); + } + + case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT: + return encodeScRgb(linear * HUD_NITS); + } +} diff --git a/src/dxvk/hud/shaders/hud_graph_frag.frag b/src/dxvk/hud/shaders/hud_graph_frag.frag index 224eb061c..6b1a22efb 100644 --- a/src/dxvk/hud/shaders/hud_graph_frag.frag +++ b/src/dxvk/hud/shaders/hud_graph_frag.frag @@ -1,6 +1,8 @@ #version 450 -layout(constant_id = 0) const bool srgbSwapchain = false; +#extension GL_GOOGLE_include_directive : require + +#include "hud_frag_common.glsl" layout(location = 0) in vec2 v_coord; layout(location = 0) out vec4 o_color; @@ -24,14 +26,6 @@ uniform push_data_t { vec2 scale; }; -vec3 linearToSrgb(vec3 color) { - bvec3 isLo = lessThanEqual(color, vec3(0.0031308f)); - - vec3 loPart = color * 12.92f; - vec3 hiPart = pow(color, vec3(5.0f / 12.0f)) * 1.055f - 0.055f; - return mix(hiPart, loPart, isLo); -} - void main() { float cx = v_coord.x * float(count); float fx = fract(cx); @@ -53,9 +47,7 @@ void main() { o_color = mix( unpackUnorm4x8(p0.color), unpackUnorm4x8(p1.color), fx); - - if (!srgbSwapchain) - o_color.rgb = linearToSrgb(o_color.rgb); - o_color *= alpha; -} \ No newline at end of file + + o_color.rgb = encodeOutput(o_color.rgb); +} diff --git a/src/dxvk/hud/shaders/hud_text_frag.frag b/src/dxvk/hud/shaders/hud_text_frag.frag index 86d3a9093..83e23dd47 100644 --- a/src/dxvk/hud/shaders/hud_text_frag.frag +++ b/src/dxvk/hud/shaders/hud_text_frag.frag @@ -1,6 +1,8 @@ #version 450 -layout(constant_id = 0) const bool srgbSwapchain = false; +#extension GL_GOOGLE_include_directive : require + +#include "hud_frag_common.glsl" layout(binding = 2) uniform sampler2D s_font; @@ -9,14 +11,6 @@ layout(location = 1) in vec4 v_color; layout(location = 0) out vec4 o_color; -vec3 linearToSrgb(vec3 color) { - bvec3 isLo = lessThanEqual(color, vec3(0.0031308f)); - - vec3 loPart = color * 12.92f; - vec3 hiPart = pow(color, vec3(5.0f / 12.0f)) * 1.055f - 0.055f; - return mix(hiPart, loPart, isLo); -} - float sampleAlpha(float alpha_bias, float dist_range) { float value = textureLod(s_font, v_texcoord, 0).r + alpha_bias - 0.5f; float dist = value * dot(vec2(dist_range, dist_range), 1.0f / fwidth(v_texcoord.xy)); @@ -34,6 +28,5 @@ void main() { o_color.a = r_alpha_shadow * v_color.a; o_color.rgb *= o_color.a; - if (!srgbSwapchain) - o_color.rgb = linearToSrgb(o_color.rgb); + o_color.rgb = encodeOutput(o_color.rgb); } From 421d7d90773292f3960c8bc0f64c9b78fcefa4ce Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 16 Jan 2023 23:16:09 +0100 Subject: [PATCH 1050/1348] Revert "[vulkan] Use fence for acquiring a swap chain image" Breaks things and we don't really need this right now anyway. --- src/dxvk/dxvk_cmdlist.cpp | 7 +++++ src/vulkan/vulkan_presenter.cpp | 50 ++++++++------------------------- src/vulkan/vulkan_presenter.h | 13 ++------- 3 files changed, 21 insertions(+), 49 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index ecfd55207..a59b7707d 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -269,6 +269,13 @@ namespace dxvk { m_commandSubmission.waitSemaphore(m_sdmaSemaphore, 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); } + // We promise to never do weird stuff to WSI images on + // the transfer queue, so blocking graphics is sufficient + if (isFirst && m_wsiSemaphores.acquire) { + m_commandSubmission.waitSemaphore(m_wsiSemaphores.acquire, + 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); + } + // Submit graphics commands if (cmd.usedFlags.test(DxvkCmdBuffer::InitBuffer)) m_commandSubmission.executeCommandBuffer(cmd.initBuffer); diff --git a/src/vulkan/vulkan_presenter.cpp b/src/vulkan/vulkan_presenter.cpp index 21ea00643..62499530d 100644 --- a/src/vulkan/vulkan_presenter.cpp +++ b/src/vulkan/vulkan_presenter.cpp @@ -12,15 +12,13 @@ namespace dxvk::vk { PresenterDevice device, const PresenterDesc& desc) : m_vki(vki), m_vkd(vkd), m_device(device) { - if (createFence() != VK_SUCCESS) - throw DxvkError("Failed to create presenter fence."); + } Presenter::~Presenter() { destroySwapchain(); destroySurface(); - destroyFence(); } @@ -41,19 +39,12 @@ namespace dxvk::vk { if (m_acquireStatus == VK_NOT_READY) { m_acquireStatus = m_vkd->vkAcquireNextImageKHR(m_vkd->device(), m_swapchain, std::numeric_limits::max(), - VK_NULL_HANDLE, m_acquireFence, &m_imageIndex); + sync.acquire, VK_NULL_HANDLE, &m_imageIndex); } if (m_acquireStatus != VK_SUCCESS && m_acquireStatus != VK_SUBOPTIMAL_KHR) return m_acquireStatus; - - VkResult vr = waitForAcquireFence(); - - if (vr != VK_SUCCESS) { - Logger::err(str::format("Failed to wait for presenter fence: ", vr)); - return vr; - } - + index = m_imageIndex; return m_acquireStatus; } @@ -83,7 +74,7 @@ namespace dxvk::vk { m_acquireStatus = m_vkd->vkAcquireNextImageKHR(m_vkd->device(), m_swapchain, std::numeric_limits::max(), - VK_NULL_HANDLE, m_acquireFence, &m_imageIndex); + sync.acquire, VK_NULL_HANDLE, &m_imageIndex); bool vsync = m_info.presentMode == VK_PRESENT_MODE_FIFO_KHR || m_info.presentMode == VK_PRESENT_MODE_FIFO_RELAXED_KHR; @@ -213,6 +204,10 @@ namespace dxvk::vk { for (uint32_t i = 0; i < m_semaphores.size(); i++) { VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; + if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(), + &semInfo, nullptr, &m_semaphores[i].acquire))) + return status; + if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(), &semInfo, nullptr, &m_semaphores[i].present))) return status; @@ -433,19 +428,14 @@ namespace dxvk::vk { } - VkResult Presenter::createFence() { - VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; - - return m_vkd->vkCreateFence(m_vkd->device(), &fenceInfo, nullptr, &m_acquireFence); - } - - void Presenter::destroySwapchain() { for (const auto& img : m_images) m_vkd->vkDestroyImageView(m_vkd->device(), img.view, nullptr); - for (const auto& sem : m_semaphores) + for (const auto& sem : m_semaphores) { + m_vkd->vkDestroySemaphore(m_vkd->device(), sem.acquire, nullptr); m_vkd->vkDestroySemaphore(m_vkd->device(), sem.present, nullptr); + } m_vkd->vkDestroySwapchainKHR(m_vkd->device(), m_swapchain, nullptr); @@ -462,22 +452,4 @@ namespace dxvk::vk { m_surface = VK_NULL_HANDLE; } - - void Presenter::destroyFence() { - m_vkd->vkWaitForFences(m_vkd->device(), 1, &m_acquireFence, - VK_TRUE, std::numeric_limits::max()); - m_vkd->vkDestroyFence(m_vkd->device(), m_acquireFence, nullptr); - } - - - VkResult Presenter::waitForAcquireFence() { - VkResult vr = m_vkd->vkWaitForFences(m_vkd->device(), 1, - &m_acquireFence, VK_TRUE, std::numeric_limits::max()); - - if (vr == VK_SUCCESS) - vr = m_vkd->vkResetFences(m_vkd->device(), 1, &m_acquireFence); - - return vr; - } - } diff --git a/src/vulkan/vulkan_presenter.h b/src/vulkan/vulkan_presenter.h index af1129dd0..641956f90 100644 --- a/src/vulkan/vulkan_presenter.h +++ b/src/vulkan/vulkan_presenter.h @@ -79,6 +79,7 @@ namespace dxvk::vk { * image acquisition. */ struct PresenterSync { + VkSemaphore acquire; VkSemaphore present; }; @@ -206,10 +207,8 @@ namespace dxvk::vk { PresenterDevice m_device; PresenterInfo m_info; - VkFence m_acquireFence = VK_NULL_HANDLE; - - VkSurfaceKHR m_surface = VK_NULL_HANDLE; - VkSwapchainKHR m_swapchain = VK_NULL_HANDLE; + VkSurfaceKHR m_surface = VK_NULL_HANDLE; + VkSwapchainKHR m_swapchain = VK_NULL_HANDLE; std::vector m_images; std::vector m_semaphores; @@ -258,16 +257,10 @@ namespace dxvk::vk { VkResult createSurface(); - VkResult createFence(); - void destroySwapchain(); void destroySurface(); - void destroyFence(); - - VkResult waitForAcquireFence(); - }; } From f7aa310fdddc09fd85319887c42391e75d8d6db3 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 17 Jan 2023 13:59:24 +0100 Subject: [PATCH 1051/1348] [dxvk] Disable pipeline lifetime tracking for RADV Seems like this is not needed on this driver, so let's just use the fast path by default. Makes the current implementation work with 32-bit games as well since caching does not work yet. --- src/dxvk/dxvk_device.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 54ef28210..d1356a4cf 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -68,9 +68,25 @@ namespace dxvk { bool DxvkDevice::mustTrackPipelineLifetime() const { - bool result = env::is32BitHostPlatform(); - applyTristate(result, m_options.trackPipelineLifetime); - return result && canUseGraphicsPipelineLibrary(); + switch (m_options.trackPipelineLifetime) { + case Tristate::True: + return canUseGraphicsPipelineLibrary(); + + case Tristate::False: + return false; + + default: + case Tristate::Auto: + if (!env::is32BitHostPlatform() || !canUseGraphicsPipelineLibrary()) + return false; + + // Disable lifetime tracking for drivers that do not have any + // significant issues with 32-bit address space to begin with + if (m_adapter->matchesDriver(VK_DRIVER_ID_MESA_RADV_KHR, 0, 0)) + return false; + + return true; + } } From 741cc493c60cc3c7342a390135f970c2675445db Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 14 Jan 2023 16:52:57 +0100 Subject: [PATCH 1052/1348] [dxvk] Increase maximum number of command buffers in flight --- src/dxvk/dxvk_limits.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_limits.h b/src/dxvk/dxvk_limits.h index d197acb78..07da2a1d2 100644 --- a/src/dxvk/dxvk_limits.h +++ b/src/dxvk/dxvk_limits.h @@ -12,7 +12,7 @@ namespace dxvk { MaxNumXfbStreams = 4, MaxNumViewports = 16, MaxNumResourceSlots = 1216, - MaxNumQueuedCommandBuffers = 18, + MaxNumQueuedCommandBuffers = 32, MaxNumQueryCountPerPool = 128, MaxNumSpecConstants = 12, MaxUniformBufferSize = 65536, From 0ac247c89cf739e28c85e10fb9069e5a7a3ead27 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 14 Jan 2023 16:51:41 +0100 Subject: [PATCH 1053/1348] [util] Add helper class for common flush heuristic --- src/util/meson.build | 1 + src/util/util_flush.cpp | 79 +++++++++++++++++++++++++++++++++++++++++ src/util/util_flush.h | 71 ++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 src/util/util_flush.cpp create mode 100644 src/util/util_flush.h diff --git a/src/util/meson.build b/src/util/meson.build index 55f4482a4..b064fee7b 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -2,6 +2,7 @@ util_src = files([ 'util_env.cpp', 'util_string.cpp', 'util_fps_limiter.cpp', + 'util_flush.cpp', 'util_gdi.cpp', 'util_luid.cpp', 'util_matrix.cpp', diff --git a/src/util/util_flush.cpp b/src/util/util_flush.cpp new file mode 100644 index 000000000..a4d91bd43 --- /dev/null +++ b/src/util/util_flush.cpp @@ -0,0 +1,79 @@ +#include "util_flush.h" + +namespace dxvk { + + bool GpuFlushTracker::considerFlush( + GpuFlushType flushType, + uint64_t chunkId, + uint32_t lastCompleteSubmissionId) { + constexpr uint32_t minPendingSubmissions = 2; + + constexpr uint32_t minChunkCount = 3u; + constexpr uint32_t maxChunkCount = 20u; + + // Do not flush if there is nothing to flush + uint32_t chunkCount = uint32_t(chunkId - m_lastFlushChunkId); + + if (!chunkCount) + return false; + + // Take any earlier missed flush with a stronger hint into account, so + // that we still flush those as soon as possible. Ignore synchronization + // commands since they will either perform a flush or not need it at all. + flushType = std::min(flushType, m_lastMissedType); + + if (flushType != GpuFlushType::ImplicitSynchronization) + m_lastMissedType = flushType; + + switch (flushType) { + case GpuFlushType::ExplicitFlush: { + // This shouldn't really be called for explicit flushes, + // but handle them anyway for the sake of completeness + return true; + } + + case GpuFlushType::ImplicitStrongHint: { + // Flush aggressively with a strong hint to reduce readback latency. + return chunkCount >= minChunkCount; + } + + case GpuFlushType::ImplicitWeakHint: { + // Aim for a higher number of chunks per submission with + // a weak hint in order to avoid submitting too often. + if (chunkCount < 2 * minChunkCount) + return false; + + // Actual heuristic is shared with synchronization commands + } [[fallthrough]]; + + case GpuFlushType::ImplicitSynchronization: { + // If the GPU is about to go idle, flush aggressively. This may be + // required if the application is spinning on a query or resource. + uint32_t pendingSubmissions = uint32_t(m_lastFlushSubmissionId - lastCompleteSubmissionId); + + if (pendingSubmissions < minPendingSubmissions) + return true; + + // Use the number of pending submissions to decide whether to flush. Other + // than ignoring the minimum chunk count condition, we should treat this + // the same as weak hints to avoid unnecessary synchronization. + uint32_t threshold = std::min(maxChunkCount, pendingSubmissions * minChunkCount); + return chunkCount >= threshold; + } + } + + // Should be unreachable + return false; + } + + + void GpuFlushTracker::notifyFlush( + uint64_t chunkId, + uint64_t submissionId) { + m_lastMissedType = GpuFlushType::ImplicitWeakHint; + + m_lastFlushChunkId = chunkId; + m_lastFlushSubmissionId = submissionId; + } + +} diff --git a/src/util/util_flush.h b/src/util/util_flush.h new file mode 100644 index 000000000..138aa992b --- /dev/null +++ b/src/util/util_flush.h @@ -0,0 +1,71 @@ +#pragma once + +#include +#include +#include + +namespace dxvk { + + /** + * \brief GPU context flush type + */ + enum class GpuFlushType : uint32_t { + /** Flush or Present called by application */ + ExplicitFlush = 0, + /** Function that requires GPU synchronization and + * may require a flush called by application */ + ImplicitSynchronization = 1, + /** GPU command that applications are likely to synchronize + * with soon has been recorded into the command list */ + ImplicitStrongHint = 2, + /** GPU commands have been recorded and a flush should be + * performed if the current command list is large enough. */ + ImplicitWeakHint = 3, + }; + + + /** + * \brief GPU flush tracker + * + * Helper class that implements a context flush + * heuristic for various scenarios. + */ + class GpuFlushTracker { + + public: + + /** + * \brief Checks whether a context flush should be performed + * + * Note that this modifies internal state, and depending on the + * flush type, this may influence the decision for future flushes. + * \param [in] flushType Flush type + * \param [in] chunkId GPU command sequence number + * \param [in] lastCompleteSubmissionId Last completed command submission ID + * \returns \c true if a flush should be performed + */ + bool considerFlush( + GpuFlushType flushType, + uint64_t chunkId, + uint32_t lastCompleteSubmissionId); + + /** + * \brief Notifies tracker about a context flush + * + * \param [in] chunkId GPU command sequence number + * \param [in] submissionId Command submission ID + */ + void notifyFlush( + uint64_t chunkId, + uint64_t submissionId); + + private: + + GpuFlushType m_lastMissedType = GpuFlushType::ImplicitWeakHint; + + uint64_t m_lastFlushChunkId = 0ull; + uint64_t m_lastFlushSubmissionId = 0ull; + + }; + +} From f952418958cd8e82fee3a9ff0475d9cc624afd6a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 14 Jan 2023 14:30:30 +0100 Subject: [PATCH 1054/1348] [d3d11] Determine pending commands based on sequence number We get this for free and this allows us to query how many CS chunks have been emitted since the last flush. --- src/d3d11/d3d11_context_imm.cpp | 14 +++++++------- src/d3d11/d3d11_context_imm.h | 6 +++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 1558ce6fa..b58f93e72 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -170,7 +170,7 @@ namespace dxvk { D3D10DeviceLock lock = LockContext(); - if (m_csIsBusy || !m_csChunk->empty()) { + if (GetPendingCsChunks()) { // Add commands to flush the threaded // context, then flush the command list EmitCs([] (DxvkContext* ctx) { @@ -181,7 +181,7 @@ namespace dxvk { // Reset flush timer used for implicit flushes m_lastFlush = dxvk::high_resolution_clock::now(); - m_csIsBusy = false; + m_flushSeqNum = m_csSeqNum; } } @@ -257,10 +257,6 @@ namespace dxvk { RestoreCommandListState(); else ResetContextState(); - - // Mark CS thread as busy so that subsequent - // flush operations get executed correctly. - m_csIsBusy = true; } @@ -833,7 +829,6 @@ namespace dxvk { void D3D11ImmediateContext::EmitCsChunk(DxvkCsChunkRef&& chunk) { m_csSeqNum = m_csThread.dispatchChunk(std::move(chunk)); - m_csIsBusy = true; } @@ -864,6 +859,11 @@ namespace dxvk { } + uint64_t D3D11ImmediateContext::GetPendingCsChunks() { + return GetCurrentSequenceNumber() - m_flushSeqNum; + } + + void D3D11ImmediateContext::FlushImplicit(BOOL StrongHint) { // Flush only if the GPU is about to go idle, in // order to keep the number of submissions low. diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 49872be2d..6958e5175 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -88,7 +88,6 @@ namespace dxvk { DxvkCsThread m_csThread; uint64_t m_csSeqNum = 0ull; - bool m_csIsBusy = false; Rc m_eventSignal; uint64_t m_eventCount = 0ull; @@ -96,6 +95,9 @@ namespace dxvk { VkDeviceSize m_maxImplicitDiscardSize = 0ull; + uint64_t m_flushSeqNum = 0ull; + + dxvk::high_resolution_clock::time_point m_lastFlush = dxvk::high_resolution_clock::now(); @@ -158,6 +160,8 @@ namespace dxvk { uint64_t GetCurrentSequenceNumber(); + uint64_t GetPendingCsChunks(); + void FlushImplicit(BOOL StrongHint); void SignalEvent(HANDLE hEvent); From 2a3d7ee7dc03b42bb110cc01f247af509556f1e9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 14 Jan 2023 14:31:26 +0100 Subject: [PATCH 1055/1348] [d3d11] Use new flush heuristic --- src/d3d11/d3d11_context.cpp | 16 ++--- src/d3d11/d3d11_context_imm.cpp | 116 ++++++++++++++++---------------- src/d3d11/d3d11_context_imm.h | 44 ++++++------ 3 files changed, 89 insertions(+), 87 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 748b378e3..f5ca5df0f 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -2194,9 +2194,6 @@ namespace dxvk { ID3D11DepthStencilView* pDepthStencilView) { D3D10DeviceLock lock = LockContext(); - if constexpr (!IsDeferred) - GetTypedContext()->FlushImplicit(true); - SetRenderTargetsAndUnorderedAccessViews( NumViews, ppRenderTargetViews, pDepthStencilView, NumViews, 0, nullptr, nullptr); @@ -2214,9 +2211,6 @@ namespace dxvk { const UINT* pUAVInitialCounts) { D3D10DeviceLock lock = LockContext(); - if constexpr (!IsDeferred) - GetTypedContext()->FlushImplicit(true); - SetRenderTargetsAndUnorderedAccessViews( NumRTVs, ppRenderTargetViews, pDepthStencilView, UAVStartSlot, NumUAVs, ppUnorderedAccessViews, pUAVInitialCounts); @@ -2671,7 +2665,7 @@ namespace dxvk { return E_INVALIDARG; if constexpr (!IsDeferred) - GetTypedContext()->FlushImplicit(false); + GetTypedContext()->ConsiderFlush(GpuFlushType::ImplicitWeakHint); DxvkSparseBindInfo bindInfo; bindInfo.dstResource = GetPagedResource(pDestTiledResource); @@ -2808,7 +2802,7 @@ namespace dxvk { return E_INVALIDARG; if constexpr (!IsDeferred) - GetTypedContext()->FlushImplicit(false); + GetTypedContext()->ConsiderFlush(GpuFlushType::ImplicitWeakHint); // Find sparse allocator if the tile pool is defined DxvkSparseBindInfo bindInfo; @@ -4921,8 +4915,12 @@ namespace dxvk { } } - if (needsUpdate) + if (needsUpdate) { BindFramebuffer(); + + if constexpr (!IsDeferred) + GetTypedContext()->ConsiderFlush(GpuFlushType::ImplicitWeakHint); + } } diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index b58f93e72..1ccfd3538 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -18,6 +18,7 @@ namespace dxvk { : D3D11CommonContext(pParent, Device, 0, DxvkCsChunkFlag::SingleUse), m_csThread(Device, Device->createContext(DxvkContextType::Primary)), m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize), + m_submissionFence(new sync::CallbackFence()), m_multithread(this, false, pParent->GetOptions()->enableContextLock), m_videoContext(this, Device) { EmitCs([ @@ -48,7 +49,7 @@ namespace dxvk { if (this_thread::isInModuleDetachment()) return; - Flush(); + ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr); SynchronizeCsThread(DxvkCsThread::SynchronizeAll); SynchronizeDevice(); } @@ -99,7 +100,8 @@ namespace dxvk { // Ignore the DONOTFLUSH flag here as some games will spin // on queries without ever flushing the context otherwise. - FlushImplicit(FALSE); + D3D10DeviceLock lock = LockContext(); + ConsiderFlush(GpuFlushType::ImplicitSynchronization); } return hr; @@ -148,47 +150,33 @@ namespace dxvk { query->NotifyEnd(); if (query->IsStalling()) - Flush(); + ExecuteFlush(GpuFlushType::ImplicitSynchronization, nullptr); else if (query->IsEvent()) - FlushImplicit(TRUE); + ConsiderFlush(GpuFlushType::ImplicitStrongHint); } } void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() { - Flush1(D3D11_CONTEXT_TYPE_ALL, nullptr); + D3D10DeviceLock lock = LockContext(); + + ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr); } void STDMETHODCALLTYPE D3D11ImmediateContext::Flush1( D3D11_CONTEXT_TYPE ContextType, HANDLE hEvent) { - m_parent->FlushInitContext(); - - if (hEvent) - SignalEvent(hEvent); - D3D10DeviceLock lock = LockContext(); - - if (GetPendingCsChunks()) { - // Add commands to flush the threaded - // context, then flush the command list - EmitCs([] (DxvkContext* ctx) { - ctx->flushCommandList(); - }); - - FlushCsChunk(); - - // Reset flush timer used for implicit flushes - m_lastFlush = dxvk::high_resolution_clock::now(); - m_flushSeqNum = m_csSeqNum; - } + + ExecuteFlush(GpuFlushType::ExplicitFlush, hEvent); } HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::Signal( ID3D11Fence* pFence, UINT64 Value) { + D3D10DeviceLock lock = LockContext(); auto fence = static_cast(pFence); if (!fence) @@ -201,7 +189,7 @@ namespace dxvk { ctx->signalFence(cFence, cValue); }); - Flush(); + ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr); return S_OK; } @@ -209,12 +197,13 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::Wait( ID3D11Fence* pFence, UINT64 Value) { + D3D10DeviceLock lock = LockContext(); auto fence = static_cast(pFence); if (!fence) return E_INVALIDARG; - Flush(); + ExecuteFlush(GpuFlushType::ExplicitFlush, nullptr); EmitCs([ cFence = fence->GetFence(), @@ -246,7 +235,7 @@ namespace dxvk { // As an optimization, flush everything if the // number of pending draw calls is high enough. - FlushImplicit(FALSE); + ConsiderFlush(GpuFlushType::ImplicitWeakHint); // Dispatch command list to the CS thread and // restore the immediate context's state @@ -257,6 +246,9 @@ namespace dxvk { RestoreCommandListState(); else ResetContextState(); + + // Flush after if the command list was sufficiently long + ConsiderFlush(GpuFlushType::ImplicitWeakHint); } @@ -386,7 +378,7 @@ namespace dxvk { } if (doInvalidatePreserve) { - FlushImplicit(TRUE); + ConsiderFlush(GpuFlushType::ImplicitWeakHint); auto prevSlice = pResource->GetMappedSlice(); auto physSlice = pResource->DiscardSlice(); @@ -533,7 +525,7 @@ namespace dxvk { } if (doFlags & DoInvalidate) { - FlushImplicit(TRUE); + ConsiderFlush(GpuFlushType::ImplicitWeakHint); DxvkBufferSliceHandle prevSlice = pResource->GetMappedSlice(Subresource); DxvkBufferSliceHandle physSlice = pResource->DiscardSlice(Subresource); @@ -809,14 +801,14 @@ namespace dxvk { // We don't have to wait, but misbehaving games may // still try to spin on `Map` until the resource is // idle, so we should flush pending commands - FlushImplicit(FALSE); + ConsiderFlush(GpuFlushType::ImplicitSynchronization); return false; } } else { if (isInUse) { // Make sure pending commands using the resource get // executed on the the GPU if we have to wait for it - Flush(); + ExecuteFlush(GpuFlushType::ImplicitSynchronization, nullptr); SynchronizeCsThread(SequenceNumber); m_device->waitForResource(Resource, access); @@ -838,7 +830,7 @@ namespace dxvk { uint64_t sequenceNumber = GetCurrentSequenceNumber(); pResource->TrackSequenceNumber(Subresource, sequenceNumber); - FlushImplicit(TRUE); + ConsiderFlush(GpuFlushType::ImplicitStrongHint); } @@ -847,7 +839,7 @@ namespace dxvk { uint64_t sequenceNumber = GetCurrentSequenceNumber(); pResource->TrackSequenceNumber(sequenceNumber); - FlushImplicit(TRUE); + ConsiderFlush(GpuFlushType::ImplicitStrongHint); } @@ -864,40 +856,50 @@ namespace dxvk { } - void D3D11ImmediateContext::FlushImplicit(BOOL StrongHint) { - // Flush only if the GPU is about to go idle, in - // order to keep the number of submissions low. - uint32_t pending = m_device->pendingSubmissions(); + void D3D11ImmediateContext::ConsiderFlush( + GpuFlushType FlushType) { + uint64_t chunkId = GetCurrentSequenceNumber(); + uint64_t submissionId = m_submissionFence->value(); - if (StrongHint || pending <= MaxPendingSubmits) { - auto now = dxvk::high_resolution_clock::now(); - - uint32_t delay = MinFlushIntervalUs - + IncFlushIntervalUs * pending; - - // Prevent flushing too often in short intervals. - if (now - m_lastFlush >= std::chrono::microseconds(delay)) - Flush(); - } + if (m_flushTracker.considerFlush(FlushType, chunkId, submissionId)) + ExecuteFlush(FlushType, nullptr); } - void D3D11ImmediateContext::SignalEvent(HANDLE hEvent) { - uint64_t value = ++m_eventCount; + void D3D11ImmediateContext::ExecuteFlush( + GpuFlushType FlushType, + HANDLE hEvent) { + // Flush init context so that new resources are fully initialized + // before the app can access them in any way. This has to happen + // unconditionally since we may otherwise deadlock on Map. + m_parent->FlushInitContext(); - if (m_eventSignal == nullptr) - m_eventSignal = new sync::CallbackFence(); + // Exit early if there's nothing to do + if (!GetPendingCsChunks() && !hEvent) + return; - m_eventSignal->setCallback(value, [hEvent] { - SetEvent(hEvent); - }); + // Signal the submission fence and flush the command list + uint64_t submissionId = ++m_submissionId; + + if (hEvent) { + m_submissionFence->setCallback(submissionId, [hEvent] { + SetEvent(hEvent); + }); + } EmitCs([ - cSignal = m_eventSignal, - cValue = value + cSubmissionFence = m_submissionFence, + cSubmissionId = submissionId ] (DxvkContext* ctx) { - ctx->signal(cSignal, cValue); + ctx->signal(cSubmissionFence, cSubmissionId); + ctx->flushCommandList(); }); + + FlushCsChunk(); + + // Notify flush tracker about the flush + m_flushSeqNum = m_csSeqNum; + m_flushTracker.notifyFlush(m_flushSeqNum, submissionId); } } diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index 6958e5175..c7b6b2f93 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -1,5 +1,6 @@ #pragma once +#include "../util/util_flush.h" #include "../util/util_time.h" #include "../util/sync/sync_signal.h" @@ -12,7 +13,7 @@ namespace dxvk { class D3D11Buffer; class D3D11CommonTexture; - + class D3D11ImmediateContext : public D3D11CommonContext { friend class D3D11CommonContext; friend class D3D11SwapChain; @@ -89,20 +90,18 @@ namespace dxvk { DxvkCsThread m_csThread; uint64_t m_csSeqNum = 0ull; - Rc m_eventSignal; - uint64_t m_eventCount = 0ull; uint32_t m_mappedImageCount = 0u; VkDeviceSize m_maxImplicitDiscardSize = 0ull; + Rc m_submissionFence; + uint64_t m_submissionId = 0ull; + uint64_t m_flushSeqNum = 0ull; + GpuFlushTracker m_flushTracker; - - dxvk::high_resolution_clock::time_point m_lastFlush - = dxvk::high_resolution_clock::now(); - - D3D10Multithread m_multithread; - D3D11VideoContext m_videoContext; + D3D10Multithread m_multithread; + D3D11VideoContext m_videoContext; Com m_stateObject; @@ -133,21 +132,21 @@ namespace dxvk { const D3D11_COMMON_TEXTURE_REGION* pRegion); void UpdateMappedBuffer( - D3D11Buffer* pDstBuffer, - UINT Offset, - UINT Length, - const void* pSrcData, - UINT CopyFlags); + D3D11Buffer* pDstBuffer, + UINT Offset, + UINT Length, + const void* pSrcData, + UINT CopyFlags); void SynchronizeDevice(); void EndFrame(); bool WaitForResource( - const Rc& Resource, - uint64_t SequenceNumber, - D3D11_MAP MapType, - UINT MapFlags); + const Rc& Resource, + uint64_t SequenceNumber, + D3D11_MAP MapType, + UINT MapFlags); void EmitCsChunk(DxvkCsChunkRef&& chunk); @@ -162,10 +161,13 @@ namespace dxvk { uint64_t GetPendingCsChunks(); - void FlushImplicit(BOOL StrongHint); + void ConsiderFlush( + GpuFlushType FlushType); + + void ExecuteFlush( + GpuFlushType FlushType, + HANDLE hEvent); - void SignalEvent(HANDLE hEvent); - }; } From 591e2df701c38ab786db8a8a6e427644d5dbf37a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 14 Jan 2023 19:28:51 +0100 Subject: [PATCH 1056/1348] [d3d11] Consider flushing after each CS chunk This way we will never end up with overly long command lists. --- src/d3d11/d3d11_context.cpp | 4 +++- src/d3d11/d3d11_context.h | 18 ++++++++++++++---- src/d3d11/d3d11_context_imm.cpp | 12 ++++-------- src/d3d11/d3d11_context_imm.h | 1 - 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index f5ca5df0f..e13342da9 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -4918,8 +4918,10 @@ namespace dxvk { if (needsUpdate) { BindFramebuffer(); - if constexpr (!IsDeferred) + if constexpr (!IsDeferred) { + // Doing this makes it less likely to flush during render passes GetTypedContext()->ConsiderFlush(GpuFlushType::ImplicitWeakHint); + } } } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index ec2db673a..618c07d69 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -10,6 +10,8 @@ #include "../d3d10/d3d10_multithread.h" +#include "../util/util_flush.h" + #include "d3d11_annotation.h" #include "d3d11_buffer.h" #include "d3d11_cmd.h" @@ -1064,27 +1066,35 @@ namespace dxvk { DxvkMultisampleState* pMsState, UINT SampleMask); - template + template void EmitCs(Cmd&& command) { m_cmdData = nullptr; if (unlikely(!m_csChunk->push(command))) { GetTypedContext()->EmitCsChunk(std::move(m_csChunk)); - m_csChunk = AllocCsChunk(); + + if constexpr (AllowFlush) + GetTypedContext()->ConsiderFlush(GpuFlushType::ImplicitWeakHint); + m_csChunk->push(command); } } - template + template M* EmitCsCmd(Cmd&& command, Args&&... args) { M* data = m_csChunk->pushCmd( command, std::forward(args)...); if (unlikely(!data)) { GetTypedContext()->EmitCsChunk(std::move(m_csChunk)); - m_csChunk = AllocCsChunk(); + + if constexpr (AllowFlush) + GetTypedContext()->ConsiderFlush(GpuFlushType::ImplicitWeakHint); + + // We must record this command after the potential + // flush since the caller may still access the data data = m_csChunk->pushCmd( command, std::forward(args)...); } diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 1ccfd3538..7386e848c 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -236,7 +236,7 @@ namespace dxvk { // As an optimization, flush everything if the // number of pending draw calls is high enough. ConsiderFlush(GpuFlushType::ImplicitWeakHint); - + // Dispatch command list to the CS thread and // restore the immediate context's state uint64_t csSeqNum = commandList->EmitToCsThread(&m_csThread); @@ -247,7 +247,7 @@ namespace dxvk { else ResetContextState(); - // Flush after if the command list was sufficiently long + // Flush again if the command list was sufficiently long ConsiderFlush(GpuFlushType::ImplicitWeakHint); } @@ -378,8 +378,6 @@ namespace dxvk { } if (doInvalidatePreserve) { - ConsiderFlush(GpuFlushType::ImplicitWeakHint); - auto prevSlice = pResource->GetMappedSlice(); auto physSlice = pResource->DiscardSlice(); @@ -525,8 +523,6 @@ namespace dxvk { } if (doFlags & DoInvalidate) { - ConsiderFlush(GpuFlushType::ImplicitWeakHint); - DxvkBufferSliceHandle prevSlice = pResource->GetMappedSlice(Subresource); DxvkBufferSliceHandle physSlice = pResource->DiscardSlice(Subresource); @@ -770,7 +766,7 @@ namespace dxvk { void D3D11ImmediateContext::EndFrame() { D3D10DeviceLock lock = LockContext(); - EmitCs([] (DxvkContext* ctx) { + EmitCs([] (DxvkContext* ctx) { ctx->endFrame(); }); } @@ -887,7 +883,7 @@ namespace dxvk { }); } - EmitCs([ + EmitCs([ cSubmissionFence = m_submissionFence, cSubmissionId = submissionId ] (DxvkContext* ctx) { diff --git a/src/d3d11/d3d11_context_imm.h b/src/d3d11/d3d11_context_imm.h index c7b6b2f93..8e60bf6c7 100644 --- a/src/d3d11/d3d11_context_imm.h +++ b/src/d3d11/d3d11_context_imm.h @@ -1,6 +1,5 @@ #pragma once -#include "../util/util_flush.h" #include "../util/util_time.h" #include "../util/sync/sync_signal.h" From cf5adb8b12b16c1e944743bb9db316b187bf5bbf Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 15 Jan 2023 01:02:03 +0100 Subject: [PATCH 1057/1348] [d3d11] Improve flushing around deferred context submissions --- src/d3d11/d3d11_cmdlist.cpp | 6 +++--- src/d3d11/d3d11_cmdlist.h | 12 ++++++++++-- src/d3d11/d3d11_context_imm.cpp | 27 +++++++++++++++++++-------- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/d3d11/d3d11_cmdlist.cpp b/src/d3d11/d3d11_cmdlist.cpp index aeb1cd5a2..c34757817 100644 --- a/src/d3d11/d3d11_cmdlist.cpp +++ b/src/d3d11/d3d11_cmdlist.cpp @@ -67,20 +67,20 @@ namespace dxvk { } - uint64_t D3D11CommandList::EmitToCsThread(DxvkCsThread* CsThread) { + void D3D11CommandList::EmitToCsThread( + const D3D11ChunkDispatchProc& DispatchProc) { uint64_t seq = 0; for (const auto& query : m_queries) query->DoDeferredEnd(); for (const auto& chunk : m_chunks) - seq = CsThread->dispatchChunk(DxvkCsChunkRef(chunk)); + seq = DispatchProc(DxvkCsChunkRef(chunk)); for (const auto& resource : m_resources) TrackResourceSequenceNumber(resource, seq); MarkSubmitted(); - return seq; } diff --git a/src/d3d11/d3d11_cmdlist.h b/src/d3d11/d3d11_cmdlist.h index 8be313ad6..95330b15a 100644 --- a/src/d3d11/d3d11_cmdlist.h +++ b/src/d3d11/d3d11_cmdlist.h @@ -1,9 +1,13 @@ #pragma once +#include + #include "d3d11_context.h" namespace dxvk { + using D3D11ChunkDispatchProc = std::function; + class D3D11CommandList : public D3D11DeviceChild { public: @@ -29,14 +33,18 @@ namespace dxvk { void EmitToCommandList( ID3D11CommandList* pCommandList); - uint64_t EmitToCsThread( - DxvkCsThread* CsThread); + void EmitToCsThread( + const D3D11ChunkDispatchProc& DispatchProc); void TrackResourceUsage( ID3D11Resource* pResource, D3D11_RESOURCE_DIMENSION ResourceType, UINT Subresource); + bool HasTrackedResources() const { + return !m_resources.empty(); + } + private: UINT const m_contextFlags; diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 7386e848c..e6cfd1d71 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -237,18 +237,29 @@ namespace dxvk { // number of pending draw calls is high enough. ConsiderFlush(GpuFlushType::ImplicitWeakHint); - // Dispatch command list to the CS thread and - // restore the immediate context's state - uint64_t csSeqNum = commandList->EmitToCsThread(&m_csThread); - m_csSeqNum = std::max(m_csSeqNum, csSeqNum); - + // Dispatch command list to the CS thread + commandList->EmitToCsThread([this] (DxvkCsChunkRef&& chunk) { + EmitCsChunk(std::move(chunk)); + + // Return the sequence number from before the flush since + // that is actually going to be needed for resource tracking + uint64_t csSeqNum = m_csSeqNum; + + // Consider a flush after every chunk in case the app + // submits a very large command list or the GPU is idle + ConsiderFlush(GpuFlushType::ImplicitWeakHint); + return csSeqNum; + }); + + // If any resource tracking took place, flush with a strong hint + if (commandList->HasTrackedResources()) + ConsiderFlush(GpuFlushType::ImplicitStrongHint); + + // Restore the immediate context's state if (RestoreContextState) RestoreCommandListState(); else ResetContextState(); - - // Flush again if the command list was sufficiently long - ConsiderFlush(GpuFlushType::ImplicitWeakHint); } From d7a4ddb5d06bb7ef0807540fdd6d245f330c6835 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 17 Jan 2023 12:33:19 +0100 Subject: [PATCH 1058/1348] [d3d11] Implement more accurate resource tracking on deferred contexts Allows us to track chunks that access any given tracked resource more accurately and flush as needed, e.g. if a staging buffer is written at the start of a long command list. --- src/d3d11/d3d11_cmdlist.cpp | 86 +++++++++++++++++++++------------ src/d3d11/d3d11_cmdlist.h | 30 ++++++------ src/d3d11/d3d11_context_def.cpp | 21 +++++--- src/d3d11/d3d11_context_def.h | 5 ++ src/d3d11/d3d11_context_imm.cpp | 8 +-- 5 files changed, 93 insertions(+), 57 deletions(-) diff --git a/src/d3d11/d3d11_cmdlist.cpp b/src/d3d11/d3d11_cmdlist.cpp index c34757817..e15f322ab 100644 --- a/src/d3d11/d3d11_cmdlist.cpp +++ b/src/d3d11/d3d11_cmdlist.cpp @@ -41,44 +41,64 @@ namespace dxvk { } - void D3D11CommandList::AddChunk(DxvkCsChunkRef&& Chunk) { - m_chunks.push_back(std::move(Chunk)); - } - - void D3D11CommandList::AddQuery(D3D11Query* pQuery) { m_queries.emplace_back(pQuery); } - void D3D11CommandList::EmitToCommandList(ID3D11CommandList* pCommandList) { - auto cmdList = static_cast(pCommandList); - - for (const auto& chunk : m_chunks) - cmdList->m_chunks.push_back(chunk); - - for (const auto& query : m_queries) - cmdList->m_queries.push_back(query); - - for (const auto& resource : m_resources) - cmdList->m_resources.push_back(resource); - - MarkSubmitted(); + uint64_t D3D11CommandList::AddChunk(DxvkCsChunkRef&& Chunk) { + m_chunks.push_back(std::move(Chunk)); + return m_chunks.size() - 1; } + uint64_t D3D11CommandList::AddCommandList( + D3D11CommandList* pCommandList) { + // This will be the chunk ID of the first chunk + // added, for the purpose of resource tracking. + uint64_t baseChunkId = m_chunks.size(); + + for (const auto& chunk : pCommandList->m_chunks) + m_chunks.push_back(chunk); + + for (const auto& query : pCommandList->m_queries) + m_queries.push_back(query); + + for (const auto& resource : pCommandList->m_resources) { + TrackedResource entry = resource; + entry.chunkId += baseChunkId; + + m_resources.push_back(std::move(entry)); + } + + pCommandList->MarkSubmitted(); + + // Return ID of the last chunk added. The command list + // added can never be empty, so do not handle zero. + return m_chunks.size() - 1; + } + + void D3D11CommandList::EmitToCsThread( const D3D11ChunkDispatchProc& DispatchProc) { - uint64_t seq = 0; - for (const auto& query : m_queries) query->DoDeferredEnd(); - for (const auto& chunk : m_chunks) - seq = DispatchProc(DxvkCsChunkRef(chunk)); - - for (const auto& resource : m_resources) - TrackResourceSequenceNumber(resource, seq); + for (size_t i = 0, j = 0; i < m_chunks.size(); i++) { + // If there are resources to track for the current chunk, + // use a strong flush hint to dispatch GPU work quickly. + GpuFlushType flushType = GpuFlushType::ImplicitWeakHint; + + if (j < m_resources.size() && m_resources[j].chunkId == i) + flushType = GpuFlushType::ImplicitStrongHint; + + // Dispatch the chunk and capture its sequence number + uint64_t seq = DispatchProc(DxvkCsChunkRef(m_chunks[i]), flushType); + + // Track resource sequence numbers for the added chunk + while (j < m_resources.size() && m_resources[j].chunkId == i) + TrackResourceSequenceNumber(m_resources[j++].ref, seq); + } MarkSubmitted(); } @@ -87,8 +107,13 @@ namespace dxvk { void D3D11CommandList::TrackResourceUsage( ID3D11Resource* pResource, D3D11_RESOURCE_DIMENSION ResourceType, - UINT Subresource) { - m_resources.emplace_back(pResource, Subresource, ResourceType); + UINT Subresource, + uint64_t ChunkId) { + TrackedResource entry; + entry.ref = D3D11ResourceRef(pResource, Subresource, ResourceType); + entry.chunkId = ChunkId; + + m_resources.push_back(std::move(entry)); } @@ -96,7 +121,6 @@ namespace dxvk { const D3D11ResourceRef& Resource, uint64_t Seq) { ID3D11Resource* iface = Resource.Get(); - UINT subresource = Resource.GetSubresource(); switch (Resource.GetType()) { case D3D11_RESOURCE_DIMENSION_UNKNOWN: @@ -109,17 +133,17 @@ namespace dxvk { case D3D11_RESOURCE_DIMENSION_TEXTURE1D: { auto impl = static_cast(iface)->GetCommonTexture(); - impl->TrackSequenceNumber(subresource, Seq); + impl->TrackSequenceNumber(Resource.GetSubresource(), Seq); } break; case D3D11_RESOURCE_DIMENSION_TEXTURE2D: { auto impl = static_cast(iface)->GetCommonTexture(); - impl->TrackSequenceNumber(subresource, Seq); + impl->TrackSequenceNumber(Resource.GetSubresource(), Seq); } break; case D3D11_RESOURCE_DIMENSION_TEXTURE3D: { auto impl = static_cast(iface)->GetCommonTexture(); - impl->TrackSequenceNumber(subresource, Seq); + impl->TrackSequenceNumber(Resource.GetSubresource(), Seq); } break; } } diff --git a/src/d3d11/d3d11_cmdlist.h b/src/d3d11/d3d11_cmdlist.h index 95330b15a..45253ecfa 100644 --- a/src/d3d11/d3d11_cmdlist.h +++ b/src/d3d11/d3d11_cmdlist.h @@ -6,7 +6,7 @@ namespace dxvk { - using D3D11ChunkDispatchProc = std::function; + using D3D11ChunkDispatchProc = std::function; class D3D11CommandList : public D3D11DeviceChild { @@ -24,34 +24,36 @@ namespace dxvk { UINT STDMETHODCALLTYPE GetContextFlags() final; - void AddChunk( - DxvkCsChunkRef&& Chunk); - void AddQuery( D3D11Query* pQuery); - void EmitToCommandList( - ID3D11CommandList* pCommandList); - + uint64_t AddChunk( + DxvkCsChunkRef&& Chunk); + + uint64_t AddCommandList( + D3D11CommandList* pCommandList); + void EmitToCsThread( const D3D11ChunkDispatchProc& DispatchProc); void TrackResourceUsage( ID3D11Resource* pResource, D3D11_RESOURCE_DIMENSION ResourceType, - UINT Subresource); - - bool HasTrackedResources() const { - return !m_resources.empty(); - } + UINT Subresource, + uint64_t ChunkId); private: - UINT const m_contextFlags; + struct TrackedResource { + D3D11ResourceRef ref; + uint64_t chunkId; + }; + + UINT m_contextFlags; std::vector m_chunks; std::vector> m_queries; - std::vector m_resources; + std::vector m_resources; std::atomic m_submitted = { false }; std::atomic m_warned = { false }; diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index b12f5b858..a3f740f4f 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -148,8 +148,9 @@ namespace dxvk { // Record any chunks from the given command list into the // current command list and deal with context state auto commandList = static_cast(pCommandList); - commandList->EmitToCommandList(m_commandList.ptr()); + m_chunkId = m_commandList->AddCommandList(commandList); + // Restore deferred context state if (RestoreContextState) RestoreCommandListState(); else @@ -166,7 +167,8 @@ namespace dxvk { FinalizeQueries(); // Clean up command list state so that the any state changed - // by this command list does not affect the calling context + // by this command list does not affect the calling context. + // This also ensures that the command list is never empty. ResetCommandListState(); // Make sure all commands are visible to the command list @@ -180,6 +182,7 @@ namespace dxvk { // Any use of ExecuteCommandList will reset command list state // before the command list is actually executed. m_commandList = CreateCommandList(); + m_chunkId = 0; if (RestoreDeferredContextState) RestoreCommandListState(); @@ -388,7 +391,12 @@ namespace dxvk { void D3D11DeferredContext::EmitCsChunk(DxvkCsChunkRef&& chunk) { - m_commandList->AddChunk(std::move(chunk)); + m_chunkId = m_commandList->AddChunk(std::move(chunk)); + } + + + uint64_t D3D11DeferredContext::GetCurrentChunkId() const { + return m_csChunk->empty() ? m_chunkId : m_chunkId + 1; } @@ -398,14 +406,15 @@ namespace dxvk { m_commandList->TrackResourceUsage( pResource->GetInterface(), pResource->GetDimension(), - Subresource); + Subresource, GetCurrentChunkId()); } void D3D11DeferredContext::TrackBufferSequenceNumber( D3D11Buffer* pResource) { - m_commandList->TrackResourceUsage( - pResource, D3D11_RESOURCE_DIMENSION_BUFFER, 0); + m_commandList->TrackResourceUsage(pResource, + D3D11_RESOURCE_DIMENSION_BUFFER, 0, + GetCurrentChunkId()); } diff --git a/src/d3d11/d3d11_context_def.h b/src/d3d11/d3d11_context_def.h index 869ae09ea..7f1c4eee9 100644 --- a/src/d3d11/d3d11_context_def.h +++ b/src/d3d11/d3d11_context_def.h @@ -96,6 +96,9 @@ namespace dxvk { // Begun and ended queries, will also be stored in command list std::vector> m_queriesBegun; + // Chunk ID within the current command list + uint64_t m_chunkId = 0ull; + HRESULT MapBuffer( ID3D11Resource* pResource, D3D11_MAPPED_SUBRESOURCE* pMappedResource); @@ -118,6 +121,8 @@ namespace dxvk { void EmitCsChunk(DxvkCsChunkRef&& chunk); + uint64_t GetCurrentChunkId() const; + void TrackTextureSequenceNumber( D3D11CommonTexture* pResource, UINT Subresource); diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index e6cfd1d71..e356c77bb 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -238,7 +238,7 @@ namespace dxvk { ConsiderFlush(GpuFlushType::ImplicitWeakHint); // Dispatch command list to the CS thread - commandList->EmitToCsThread([this] (DxvkCsChunkRef&& chunk) { + commandList->EmitToCsThread([this] (DxvkCsChunkRef&& chunk, GpuFlushType flushType) { EmitCsChunk(std::move(chunk)); // Return the sequence number from before the flush since @@ -247,14 +247,10 @@ namespace dxvk { // Consider a flush after every chunk in case the app // submits a very large command list or the GPU is idle - ConsiderFlush(GpuFlushType::ImplicitWeakHint); + ConsiderFlush(flushType); return csSeqNum; }); - // If any resource tracking took place, flush with a strong hint - if (commandList->HasTrackedResources()) - ConsiderFlush(GpuFlushType::ImplicitStrongHint); - // Restore the immediate context's state if (RestoreContextState) RestoreCommandListState(); From 906b931e61ba4acc9685f1cb1fd6ed1d5e13991c Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Tue, 17 Jan 2023 16:58:23 +0100 Subject: [PATCH 1059/1348] [util] Disable unmapping for BlazBlue Centralfiction --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index c31c8e0f1..c8bc14c0d 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -703,6 +703,11 @@ namespace dxvk { { "d3d9.customDeviceId", "05E0" }, { "dxgi.nvapiHack", "False" }, }} }, + /* BlazBlue Centralfiction * + * Temporary crash workaround */ + { R"(\\BBCF\.exe$)", {{ + { "d3d9.textureMemory", "0" }, + }} }, }}; From c6668ffbaae41719b20cb9160dcbc2198ba7b88b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 18 Jan 2023 15:54:32 +0100 Subject: [PATCH 1060/1348] [dxvk] Drop shader module workaround for compute pipelines. This was a bug in early Nvidia development drivers, but has been fixed since. --- src/dxvk/dxvk_shader.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index 9df41bb32..880737667 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -832,14 +832,13 @@ namespace dxvk { // For graphics pipelines, as long as graphics pipeline libraries are // enabled, we do not need to create a shader module object and can // instead chain the create info to the shader stage info struct. - // For compute pipelines, this doesn't work and we still need a module. auto& moduleInfo = m_moduleInfos[m_stageCount].moduleInfo; moduleInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; moduleInfo.codeSize = codeBuffer.size(); moduleInfo.pCode = codeBuffer.data(); VkShaderModule shaderModule = VK_NULL_HANDLE; - if (!m_device->features().extGraphicsPipelineLibrary.graphicsPipelineLibrary || stage == VK_SHADER_STAGE_COMPUTE_BIT) { + if (!m_device->features().extGraphicsPipelineLibrary.graphicsPipelineLibrary) { auto vk = m_device->vkd(); if (vk->vkCreateShaderModule(vk->device(), &moduleInfo, nullptr, &shaderModule)) From 4d0d455895fb0066dd7eba611f1dc50273f0e17f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 18 Jan 2023 17:18:10 +0100 Subject: [PATCH 1061/1348] [vulkan] Try loading winevulkan.dll before vulkan-1.dll Should bypass issues with third-party overlays trying to hook Vulkan. --- src/vulkan/vulkan_loader.cpp | 44 ++++++++++++++++++++++++++++-------- src/vulkan/vulkan_loader.h | 4 ++-- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/vulkan/vulkan_loader.cpp b/src/vulkan/vulkan_loader.cpp index b435b22ae..e5981e945 100644 --- a/src/vulkan/vulkan_loader.cpp +++ b/src/vulkan/vulkan_loader.cpp @@ -1,24 +1,48 @@ +#include + #include "vulkan_loader.h" +#include "../util/log/log.h" + +#include "../util/util_string.h" #include "../util/util_win32_compat.h" namespace dxvk::vk { - static HMODULE loadVulkanLibrary() { + static std::pair loadVulkanLibrary() { + static const std::array dllNames = {{ #ifdef _WIN32 - return LoadLibraryA("vulkan-1.dll"); + "winevulkan.dll", + "vulkan-1.dll", #else - HMODULE library = LoadLibraryA("libvulkan.so"); - if (!library) - library = LoadLibraryA("libvulkan.so.1"); - return library; + "libvulkan.so", + "libvulkan.so.1", #endif + }}; + + for (auto dllName : dllNames) { + HMODULE library = LoadLibraryA(dllName); + + if (!library) + continue; + + auto proc = GetProcAddress(library, "vkGetInstanceProcAddr"); + + if (!proc) { + FreeLibrary(library); + continue; + } + + Logger::info(str::format("Vulkan: Found vkGetInstanceProcAddr in ", dllName, " @ 0x", std::hex, reinterpret_cast(proc))); + return std::make_pair(library, reinterpret_cast(proc)); + } + + Logger::err("Vulkan: vkGetInstanceProcAddr not found"); + return { }; } - LibraryLoader::LibraryLoader() - : m_library(loadVulkanLibrary()) - , m_getInstanceProcAddr(reinterpret_cast( - GetProcAddress(m_library, "vkGetInstanceProcAddr"))) { + LibraryLoader::LibraryLoader() { + std::tie(m_library, m_getInstanceProcAddr) = loadVulkanLibrary(); } LibraryLoader::~LibraryLoader() { diff --git a/src/vulkan/vulkan_loader.h b/src/vulkan/vulkan_loader.h index 71b2dab24..89944e091 100644 --- a/src/vulkan/vulkan_loader.h +++ b/src/vulkan/vulkan_loader.h @@ -26,8 +26,8 @@ namespace dxvk::vk { PFN_vkGetInstanceProcAddr getLoaderProc() const { return m_getInstanceProcAddr; } bool valid() const; protected: - const HMODULE m_library; - const PFN_vkGetInstanceProcAddr m_getInstanceProcAddr; + HMODULE m_library = nullptr; + PFN_vkGetInstanceProcAddr m_getInstanceProcAddr = nullptr; }; From eacb8da9f7df76323084bcf2eb2c43971db5c0f6 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 20 Jan 2023 14:34:46 +0100 Subject: [PATCH 1062/1348] [dxvk] Tweak descriptor pool numbers Increases the descriptor pool size on 64-bit, but also makes significantly better use of descriptor pool memory in situations with very high draw counts and many UBO descriptor set updates. --- src/dxvk/dxvk_descriptor.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index 13cc93a63..fa1560bf9 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -288,18 +288,26 @@ namespace dxvk { return m_vkPools[--m_vkPoolCount]; } + // Deliberately pick a very high number of descriptor sets so that + // we will typically end up using all available pool memory before + // the descriptor set limit becomes the limiting factor. uint32_t maxSets = m_contextType == DxvkContextType::Primary - ? 8192 : 256; + ? (env::is32BitHostPlatform() ? 24576u : 49152u) + : (512u); + // Samplers and uniform buffers may be special on some implementations + // so we should allocate space for a reasonable number of both, but + // assume that all other descriptor types share pool memory. std::array pools = {{ - { VK_DESCRIPTOR_TYPE_SAMPLER, maxSets * 2 }, - { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, maxSets * 2 }, + { VK_DESCRIPTOR_TYPE_SAMPLER, maxSets * 1 }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, maxSets / 4 }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, maxSets / 2 }, { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, maxSets / 64 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, maxSets * 4 }, - { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, maxSets * 1 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, maxSets * 1 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, maxSets / 2 }, { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, maxSets / 64 }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, maxSets * 1 } }}; + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, maxSets * 2 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, maxSets / 2 }, + }}; VkDescriptorPoolCreateInfo info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; info.maxSets = maxSets; From 0af5ececa6ba250b529c9eb988791cf4c0a347e5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 20 Jan 2023 15:23:25 +0100 Subject: [PATCH 1063/1348] [dxvk] Also reset descriptor pool when only one pool is in use This way we can often avoid allocating additional descriptor pools. --- src/dxvk/dxvk_descriptor.cpp | 34 ++++++++++++++++------------------ src/dxvk/dxvk_descriptor.h | 9 +++++++++ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/dxvk/dxvk_descriptor.cpp b/src/dxvk/dxvk_descriptor.cpp index fa1560bf9..56ea85a4f 100644 --- a/src/dxvk/dxvk_descriptor.cpp +++ b/src/dxvk/dxvk_descriptor.cpp @@ -106,7 +106,7 @@ namespace dxvk { size_t poolCount = m_descriptorPools.size(); - if (poolCount > 1) { + if (poolCount > 1 || m_setsAllocated > m_manager->getMaxSetCount() / 2) { double factor = std::max(11.0 / 3.0 - double(poolCount) / 3.0, 1.0); isLowUsageFrame = double(m_setsUsed) * factor < double(m_setsAllocated); } @@ -244,7 +244,12 @@ namespace dxvk { DxvkDevice* device, DxvkContextType contextType) : m_device(device), m_contextType(contextType) { - + // Deliberately pick a very high number of descriptor sets so that + // we will typically end up using all available pool memory before + // the descriptor set limit becomes the limiting factor. + m_maxSets = m_contextType == DxvkContextType::Primary + ? (env::is32BitHostPlatform() ? 24576u : 49152u) + : (512u); } @@ -288,29 +293,22 @@ namespace dxvk { return m_vkPools[--m_vkPoolCount]; } - // Deliberately pick a very high number of descriptor sets so that - // we will typically end up using all available pool memory before - // the descriptor set limit becomes the limiting factor. - uint32_t maxSets = m_contextType == DxvkContextType::Primary - ? (env::is32BitHostPlatform() ? 24576u : 49152u) - : (512u); - // Samplers and uniform buffers may be special on some implementations // so we should allocate space for a reasonable number of both, but // assume that all other descriptor types share pool memory. std::array pools = {{ - { VK_DESCRIPTOR_TYPE_SAMPLER, maxSets * 1 }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, maxSets / 4 }, - { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, maxSets / 2 }, - { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, maxSets / 64 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, maxSets / 2 }, - { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, maxSets / 64 }, - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, maxSets * 2 }, - { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, maxSets / 2 }, + { VK_DESCRIPTOR_TYPE_SAMPLER, m_maxSets * 1 }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, m_maxSets / 4 }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, m_maxSets / 2 }, + { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_maxSets / 64 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, m_maxSets / 2 }, + { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, m_maxSets / 64 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, m_maxSets * 2 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_maxSets / 2 }, }}; VkDescriptorPoolCreateInfo info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; - info.maxSets = maxSets; + info.maxSets = m_maxSets; info.poolSizeCount = pools.size(); info.pPoolSizes = pools.data(); diff --git a/src/dxvk/dxvk_descriptor.h b/src/dxvk/dxvk_descriptor.h index 876aae04b..95d2c045f 100644 --- a/src/dxvk/dxvk_descriptor.h +++ b/src/dxvk/dxvk_descriptor.h @@ -191,6 +191,14 @@ namespace dxvk { ~DxvkDescriptorManager(); + /** + * \brief Queries maximum number of descriptor sets per pool + * \returns Maximum set count + */ + uint32_t getMaxSetCount() const { + return m_maxSets; + } + /** * \brief Retrieves or creates a descriptor type * \returns The descriptor pool @@ -229,6 +237,7 @@ namespace dxvk { DxvkDevice* m_device; DxvkContextType m_contextType; + uint32_t m_maxSets = 0; DxvkRecycler m_pools; dxvk::mutex m_mutex; From 3d24560af7646f499caea85c92e2f104f8534d0c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 21 Jan 2023 01:14:45 +0100 Subject: [PATCH 1064/1348] [dxvk] Fix reading out-of-bounds memory in state cache Fixes #3196, not to mention that this was god-awful code anyway. --- src/dxvk/dxvk_state_cache.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 1bd31e67b..534117eeb 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -571,7 +571,6 @@ namespace dxvk { DxvkStateCacheEntry& entry) const { // Read entry metadata and actual data DxvkStateCacheEntryHeader header; - DxvkStateCacheEntryHeaderV8 headerV8; DxvkStateCacheEntryData data; VkShaderStageFlags stageMask; Sha1Hash hash; @@ -582,6 +581,8 @@ namespace dxvk { stageMask = VkShaderStageFlags(header.stageMask); } else { + DxvkStateCacheEntryHeaderV8 headerV8; + if (!stream.read(reinterpret_cast(&headerV8), sizeof(headerV8))) return false; @@ -693,12 +694,18 @@ namespace dxvk { VkShaderStageFlags stageMask = 0; // Write shader hashes - auto keys = &entry.shaders.vs; + std::array, 5> stages = {{ + { VK_SHADER_STAGE_VERTEX_BIT, &entry.shaders.vs }, + { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, &entry.shaders.tcs }, + { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, &entry.shaders.tes }, + { VK_SHADER_STAGE_GEOMETRY_BIT, &entry.shaders.gs }, + { VK_SHADER_STAGE_FRAGMENT_BIT, &entry.shaders.fs }, + }}; - for (uint32_t i = 0; i < 6; i++) { - if (!keys[i].eq(g_nullShaderKey)) { - stageMask |= VkShaderStageFlagBits(1 << i); - data.write(keys[i]); + for (uint32_t i = 0; i < stages.size(); i++) { + if (!stages[i].second->eq(g_nullShaderKey)) { + stageMask |= stages[i].first; + data.write(*stages[i].second); } } From d020f4451a3f6fb98ec36590f767f44e85dd51dc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 21 Jan 2023 01:24:02 +0100 Subject: [PATCH 1065/1348] [dxvk] Invalidate all v16 cache files We were randomly writing bogus data in an irrecoverable way, so in order to not cause any problems for users, invalidate all caches created with this version. --- src/dxvk/dxvk_state_cache.cpp | 3 ++- src/dxvk/dxvk_state_cache_types.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dxvk/dxvk_state_cache.cpp b/src/dxvk/dxvk_state_cache.cpp index 534117eeb..5bf9a7e49 100644 --- a/src/dxvk/dxvk_state_cache.cpp +++ b/src/dxvk/dxvk_state_cache.cpp @@ -496,7 +496,8 @@ namespace dxvk { } // Discard caches of unsupported versions - if (curHeader.version < 8 || curHeader.version > newHeader.version) { + if (curHeader.version < 8 || curHeader.version == 16 + || curHeader.version > newHeader.version) { Logger::warn("DXVK: State cache version not supported"); return false; } diff --git a/src/dxvk/dxvk_state_cache_types.h b/src/dxvk/dxvk_state_cache_types.h index 86d99a55c..e58825932 100644 --- a/src/dxvk/dxvk_state_cache_types.h +++ b/src/dxvk/dxvk_state_cache_types.h @@ -60,7 +60,7 @@ namespace dxvk { */ struct DxvkStateCacheHeader { char magic[4] = { 'D', 'X', 'V', 'K' }; - uint32_t version = 16; + uint32_t version = 17; uint32_t entrySize = 0; /* no longer meaningful */ }; From 41ee092b97dc9e8ee4808385262404463b908b74 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 21 Jan 2023 12:54:10 +0100 Subject: [PATCH 1066/1348] [dxvk] Get rid of global timeline semaphore Timeline semaphores are broken on 32-bit Proton, so just use the existing command list binary semaphore to synchronize sparse binding operation. This will introduce some additional graphics queue submissions around sparse binding, but since that is basically unused it's not a concern. --- src/dxvk/dxvk_cmdlist.cpp | 57 +++++++++++++++++---------------------- src/dxvk/dxvk_cmdlist.h | 13 +++------ src/dxvk/dxvk_queue.cpp | 12 +-------- src/dxvk/dxvk_queue.h | 3 --- 4 files changed, 28 insertions(+), 57 deletions(-) diff --git a/src/dxvk/dxvk_cmdlist.cpp b/src/dxvk/dxvk_cmdlist.cpp index a59b7707d..42fd0a9c4 100644 --- a/src/dxvk/dxvk_cmdlist.cpp +++ b/src/dxvk/dxvk_cmdlist.cpp @@ -176,7 +176,9 @@ namespace dxvk { VkSemaphoreCreateInfo semaphoreInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; - if (m_vkd->vkCreateSemaphore(m_vkd->device(), &semaphoreInfo, nullptr, &m_sdmaSemaphore)) + if (m_vkd->vkCreateSemaphore(m_vkd->device(), &semaphoreInfo, nullptr, &m_bindSemaphore) + || m_vkd->vkCreateSemaphore(m_vkd->device(), &semaphoreInfo, nullptr, &m_postSemaphore) + || m_vkd->vkCreateSemaphore(m_vkd->device(), &semaphoreInfo, nullptr, &m_sdmaSemaphore)) throw DxvkError("DxvkCommandList: Failed to create semaphore"); VkFenceCreateInfo fenceInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; @@ -196,14 +198,15 @@ namespace dxvk { DxvkCommandList::~DxvkCommandList() { this->reset(); + m_vkd->vkDestroySemaphore(m_vkd->device(), m_bindSemaphore, nullptr); + m_vkd->vkDestroySemaphore(m_vkd->device(), m_postSemaphore, nullptr); m_vkd->vkDestroySemaphore(m_vkd->device(), m_sdmaSemaphore, nullptr); + m_vkd->vkDestroyFence(m_vkd->device(), m_fence, nullptr); } - VkResult DxvkCommandList::submit( - VkSemaphore semaphore, - uint64_t& semaphoreValue) { + VkResult DxvkCommandList::submit() { VkResult status = VK_SUCCESS; const auto& graphics = m_device->queues().graphics; @@ -222,44 +225,37 @@ namespace dxvk { ? &m_cmdSparseBinds[cmd.sparseCmd] : nullptr; - if (sparseBind) { - // Sparse bindig needs to serialize command execution, so wait - // for any prior submissions, then block any subsequent ones - sparseBind->waitSemaphore(semaphore, semaphoreValue); - sparseBind->signalSemaphore(semaphore, ++semaphoreValue); - - m_commandSubmission.waitSemaphore(semaphore, semaphoreValue, - VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); - } - if (isFirst) { // Wait for per-command list semaphores on first submission for (const auto& entry : m_waitSemaphores) { - if (sparseBind) { - sparseBind->waitSemaphore( - entry.fence->handle(), - entry.value); - } else { - m_commandSubmission.waitSemaphore( - entry.fence->handle(), - entry.value, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); - } + m_commandSubmission.waitSemaphore(entry.fence->handle(), + entry.value, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); } } - // Execute sparse bind if (sparseBind) { + // Sparse binding needs to serialize command execution, so wait + // for any prior submissions, then block any subsequent ones + m_commandSubmission.signalSemaphore(m_bindSemaphore, 0, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); + + if ((status = m_commandSubmission.submit(m_device, graphics.queueHandle))) + return status; + + sparseBind->waitSemaphore(m_bindSemaphore, 0); + sparseBind->signalSemaphore(m_postSemaphore, 0); + if ((status = sparseBind->submit(m_device, sparse.queueHandle))) return status; + + m_commandSubmission.waitSemaphore(m_postSemaphore, 0, VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT); } // Submit transfer commands as necessary if (cmd.usedFlags.test(DxvkCmdBuffer::SdmaBuffer)) m_commandSubmission.executeCommandBuffer(cmd.sdmaBuffer); - // If we had either a transfer command or a semaphore wait, - // submit to the transfer queue so that all subsequent commands - // get stalled appropriately. + // If we had either a transfer command or a semaphore wait, submit to the + // transfer queue so that all subsequent commands get stalled as necessary. if (m_device->hasDedicatedTransferQueue() && !m_commandSubmission.isEmpty()) { m_commandSubmission.signalSemaphore(m_sdmaSemaphore, 0, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); @@ -283,15 +279,10 @@ namespace dxvk { if (cmd.usedFlags.test(DxvkCmdBuffer::ExecBuffer)) m_commandSubmission.executeCommandBuffer(cmd.execBuffer); - // Signal global timeline semaphore at the end of every submission - m_commandSubmission.signalSemaphore(semaphore, - ++semaphoreValue, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); - if (isLast) { // Signal per-command list semaphores on the final submission for (const auto& entry : m_signalSemaphores) { - m_commandSubmission.signalSemaphore( - entry.fence->handle(), + m_commandSubmission.signalSemaphore(entry.fence->handle(), entry.value, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); } diff --git a/src/dxvk/dxvk_cmdlist.h b/src/dxvk/dxvk_cmdlist.h index 9edd768a6..988c9e4ad 100644 --- a/src/dxvk/dxvk_cmdlist.h +++ b/src/dxvk/dxvk_cmdlist.h @@ -198,18 +198,9 @@ namespace dxvk { /** * \brief Submits command list - * - * \param [in] semaphore Global timeline semaphore - * \param [in,out] semaphoreValue Semaphore value. On input, - * this is the last signaled value of the semaphore so that - * synchronization can take place as needed. On ouput, this - * will contain the new value the semaphore gets signaled - * to by this submission. * \returns Submission status */ - VkResult submit( - VkSemaphore semaphore, - uint64_t& semaphoreValue); + VkResult submit(); /** * \brief Stat counters @@ -1029,6 +1020,8 @@ namespace dxvk { Rc m_graphicsPool; Rc m_transferPool; + VkSemaphore m_bindSemaphore = VK_NULL_HANDLE; + VkSemaphore m_postSemaphore = VK_NULL_HANDLE; VkSemaphore m_sdmaSemaphore = VK_NULL_HANDLE; VkFence m_fence = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_queue.cpp b/src/dxvk/dxvk_queue.cpp index 520a901e3..1939817cf 100644 --- a/src/dxvk/dxvk_queue.cpp +++ b/src/dxvk/dxvk_queue.cpp @@ -7,15 +7,7 @@ namespace dxvk { : m_device(device), m_submitThread([this] () { submitCmdLists(); }), m_finishThread([this] () { finishCmdLists(); }) { - auto vk = m_device->vkd(); - VkSemaphoreTypeCreateInfo typeInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO }; - typeInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; - - VkSemaphoreCreateInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &typeInfo }; - - if (vk->vkCreateSemaphore(vk->device(), &info, nullptr, &m_semaphore)) - throw DxvkError("Failed to create global timeline semaphore"); } @@ -31,8 +23,6 @@ namespace dxvk { m_submitThread.join(); m_finishThread.join(); - - vk->vkDestroySemaphore(vk->device(), m_semaphore, nullptr); } @@ -116,7 +106,7 @@ namespace dxvk { std::lock_guard lock(m_mutexQueue); if (entry.submit.cmdList != nullptr) - status = entry.submit.cmdList->submit(m_semaphore, m_semaphoreValue); + status = entry.submit.cmdList->submit(); else if (entry.present.presenter != nullptr) status = entry.present.presenter->presentImage(); } else { diff --git a/src/dxvk/dxvk_queue.h b/src/dxvk/dxvk_queue.h index 8f589b558..ecde61a03 100644 --- a/src/dxvk/dxvk_queue.h +++ b/src/dxvk/dxvk_queue.h @@ -183,9 +183,6 @@ namespace dxvk { std::atomic m_pending = { 0u }; std::atomic m_gpuIdle = { 0ull }; - VkSemaphore m_semaphore = VK_NULL_HANDLE; - uint64_t m_semaphoreValue = 0ull; - dxvk::mutex m_mutex; dxvk::mutex m_mutexQueue; From 0ee69fef00fa958a433d25732be27aa18b892ac4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 22 Jan 2023 19:55:56 +0100 Subject: [PATCH 1067/1348] [dxgi] Define IDXGIVkInteropFactory interface --- src/dxgi/dxgi_interfaces.h | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index b5e584f3f..ba44a0faa 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -384,9 +384,9 @@ IDXGIVkInteropDevice1 : public IDXGIVkInteropDevice { uint32_t* pQueueFamilyIndex) = 0; virtual HRESULT STDMETHODCALLTYPE CreateTexture2DFromVkImage( - const D3D11_TEXTURE2D_DESC1 *pDesc, - VkImage vkImage, - ID3D11Texture2D **ppTexture2D) = 0; + const D3D11_TEXTURE2D_DESC1* pDesc, + VkImage vkImage, + ID3D11Texture2D** ppTexture2D) = 0; }; /** @@ -399,7 +399,7 @@ MIDL_INTERFACE("3a6d8f2c-b0e8-4ab4-b4dc-4fd24891bfa5") IDXGIVkInteropAdapter : public IUnknown { /** * \brief Queries Vulkan handles used by DXVK - * + * * \param [out] pInstance The Vulkan instance * \param [out] pPhysDev The physical device */ @@ -408,11 +408,28 @@ IDXGIVkInteropAdapter : public IUnknown { VkPhysicalDevice* pPhysDev) = 0; }; +/** + * \brief DXGI factory interface for Vulkan interop + */ +MIDL_INTERFACE("4c5e1b0d-b0c8-4131-bfd8-9b2476f7f408") +IDXGIVkInteropFactory : public IUnknown { + /** + * \brief Queries Vulkan instance used by DXVK + * + * \param [out] pInstance The Vulkan instance + * \param [out] ppfnVkGetInstanceProcAddr Vulkan entry point + */ + virtual void STDMETHODCALLTYPE GetVulkanInstance( + VkInstance* pInstance, + PFN_vkGetInstanceProcAddr* ppfnVkGetInstanceProcAddr) = 0; +}; + #ifdef _MSC_VER struct __declspec(uuid("907bf281-ea3c-43b4-a8e4-9f231107b4ff")) IDXGIDXVKAdapter; struct __declspec(uuid("92a5d77b-b6e1-420a-b260-fdd701272827")) IDXGIDXVKDevice; struct __declspec(uuid("c06a236f-5be3-448a-8943-89c611c0c2c1")) IDXGIVkMonitorInfo; +struct __declspec(uuid("4c5e1b0d-b0c8-4131-bfd8-9b2476f7f408")) IDXGIVkInteropFactory; struct __declspec(uuid("3a6d8f2c-b0e8-4ab4-b4dc-4fd24891bfa5")) IDXGIVkInteropAdapter; struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09323")) IDXGIVkInteropDevice; struct __declspec(uuid("e2ef5fa5-dc21-4af7-90c4-f67ef6a09324")) IDXGIVkInteropDevice1; @@ -424,6 +441,7 @@ struct __declspec(uuid("e7d6c3ca-23a0-4e08-9f2f-ea5231df6633")) IDXGIVkSwapChain __CRT_UUID_DECL(IDXGIDXVKAdapter, 0x907bf281,0xea3c,0x43b4,0xa8,0xe4,0x9f,0x23,0x11,0x07,0xb4,0xff); __CRT_UUID_DECL(IDXGIDXVKDevice, 0x92a5d77b,0xb6e1,0x420a,0xb2,0x60,0xfd,0xf7,0x01,0x27,0x28,0x27); __CRT_UUID_DECL(IDXGIVkMonitorInfo, 0xc06a236f,0x5be3,0x448a,0x89,0x43,0x89,0xc6,0x11,0xc0,0xc2,0xc1); +__CRT_UUID_DECL(IDXGIVkInteropFactory, 0x4c5e1b0d,0xb0c8,0x4131,0xbf,0xd8,0x9b,0x24,0x76,0xf7,0xf4,0x08); __CRT_UUID_DECL(IDXGIVkInteropAdapter, 0x3a6d8f2c,0xb0e8,0x4ab4,0xb4,0xdc,0x4f,0xd2,0x48,0x91,0xbf,0xa5); __CRT_UUID_DECL(IDXGIVkInteropDevice, 0xe2ef5fa5,0xdc21,0x4af7,0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x23); __CRT_UUID_DECL(IDXGIVkInteropDevice1, 0xe2ef5fa5,0xdc21,0x4af7,0x90,0xc4,0xf6,0x7e,0xf6,0xa0,0x93,0x24); From 3128f4ea8e90a2053d420c0c78235c8befb718f5 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 22 Jan 2023 20:04:39 +0100 Subject: [PATCH 1068/1348] [dxgi] Implement IDXGIVkInteropFactory for DXGI factory --- src/dxgi/dxgi_factory.cpp | 44 +++++++++++++++++++++++++++++++++++++++ src/dxgi/dxgi_factory.h | 30 +++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp index d15686634..635221868 100644 --- a/src/dxgi/dxgi_factory.cpp +++ b/src/dxgi/dxgi_factory.cpp @@ -5,8 +5,47 @@ namespace dxvk { + DxgiVkFactory::DxgiVkFactory(DxgiFactory* pFactory) + : m_factory(pFactory) { + + } + + + ULONG STDMETHODCALLTYPE DxgiVkFactory::AddRef() { + return m_factory->AddRef(); + } + + + ULONG STDMETHODCALLTYPE DxgiVkFactory::Release() { + return m_factory->Release(); + } + + + HRESULT STDMETHODCALLTYPE DxgiVkFactory::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_factory->QueryInterface(riid, ppvObject); + } + + + void STDMETHODCALLTYPE DxgiVkFactory::GetVulkanInstance( + VkInstance* pInstance, + PFN_vkGetInstanceProcAddr* ppfnVkGetInstanceProcAddr) { + auto instance = m_factory->GetDXVKInstance(); + + if (pInstance) + *pInstance = instance->handle(); + + if (ppfnVkGetInstanceProcAddr) + *ppfnVkGetInstanceProcAddr = instance->vki()->getLoaderProc(); + } + + + + DxgiFactory::DxgiFactory(UINT Flags) : m_instance (new DxvkInstance()), + m_interop (this), m_options (m_instance->config()), m_monitorInfo (this, m_options), m_flags (Flags) { @@ -40,6 +79,11 @@ namespace dxvk { return S_OK; } + if (riid == __uuidof(IDXGIVkInteropFactory)) { + *ppvObject = ref(&m_interop); + return S_OK; + } + if (riid == __uuidof(IDXGIVkMonitorInfo)) { *ppvObject = ref(&m_monitorInfo); return S_OK; diff --git a/src/dxgi/dxgi_factory.h b/src/dxgi/dxgi_factory.h index 4d75c277f..72af2f3c0 100644 --- a/src/dxgi/dxgi_factory.h +++ b/src/dxgi/dxgi_factory.h @@ -9,7 +9,34 @@ #include "../dxvk/dxvk_instance.h" namespace dxvk { - + + class DxgiFactory; + + class DxgiVkFactory : public IDXGIVkInteropFactory { + + public: + + DxgiVkFactory(DxgiFactory* pFactory); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + void STDMETHODCALLTYPE GetVulkanInstance( + VkInstance* pInstance, + PFN_vkGetInstanceProcAddr* ppfnVkGetInstanceProcAddr); + + private: + + DxgiFactory* m_factory; + + }; + + class DxgiFactory : public DxgiObject { public: @@ -146,6 +173,7 @@ namespace dxvk { private: Rc m_instance; + DxgiVkFactory m_interop; DxgiOptions m_options; DxgiMonitorInfo m_monitorInfo; UINT m_flags; From 255ab1a63c07ec47ac20eb4416e1287b195be349 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 23 Jan 2023 00:10:39 +0100 Subject: [PATCH 1069/1348] [hud] Display more useful driver info in HUD Vulkan versions are irrelevant anyway, not sure why we ever displayed that in the first place. --- src/dxvk/hud/dxvk_hud_item.cpp | 27 +++++++++++++++------------ src/dxvk/hud/dxvk_hud_item.h | 2 +- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/dxvk/hud/dxvk_hud_item.cpp b/src/dxvk/hud/dxvk_hud_item.cpp index 40707d644..cbabd658b 100644 --- a/src/dxvk/hud/dxvk_hud_item.cpp +++ b/src/dxvk/hud/dxvk_hud_item.cpp @@ -125,17 +125,20 @@ namespace dxvk::hud { HudDeviceInfoItem::HudDeviceInfoItem(const Rc& device) { - VkPhysicalDeviceProperties props = device->adapter()->deviceProperties(); + const auto& props = device->properties(); - m_deviceName = props.deviceName; - m_driverVer = str::format("Driver: ", - VK_VERSION_MAJOR(props.driverVersion), ".", - VK_VERSION_MINOR(props.driverVersion), ".", - VK_VERSION_PATCH(props.driverVersion)); - m_vulkanVer = str::format("Vulkan: ", - VK_VERSION_MAJOR(props.apiVersion), ".", - VK_VERSION_MINOR(props.apiVersion), ".", - VK_VERSION_PATCH(props.apiVersion)); + std::string driverInfo = props.vk12.driverInfo; + + if (driverInfo.empty()) { + driverInfo = str::format( + VK_VERSION_MAJOR(props.core.properties.driverVersion), ".", + VK_VERSION_MINOR(props.core.properties.driverVersion), ".", + VK_VERSION_PATCH(props.core.properties.driverVersion)); + } + + m_deviceName = props.core.properties.deviceName; + m_driverName = str::format("Driver: ", props.vk12.driverName); + m_driverVer = str::format("Version: ", driverInfo); } @@ -157,13 +160,13 @@ namespace dxvk::hud { renderer.drawText(16.0f, { position.x, position.y }, { 1.0f, 1.0f, 1.0f, 1.0f }, - m_driverVer); + m_driverName); position.y += 20.0f; renderer.drawText(16.0f, { position.x, position.y }, { 1.0f, 1.0f, 1.0f, 1.0f }, - m_vulkanVer); + m_driverVer); position.y += 8.0f; return position; diff --git a/src/dxvk/hud/dxvk_hud_item.h b/src/dxvk/hud/dxvk_hud_item.h index 18f75054b..6b0e93fd7 100644 --- a/src/dxvk/hud/dxvk_hud_item.h +++ b/src/dxvk/hud/dxvk_hud_item.h @@ -175,8 +175,8 @@ namespace dxvk::hud { private: std::string m_deviceName; + std::string m_driverName; std::string m_driverVer; - std::string m_vulkanVer; }; From d4143429c43d3492c896bb9a5a1b7e4a87804b7e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 23 Jan 2023 17:17:43 +0100 Subject: [PATCH 1070/1348] [util] Add Singleton helper --- src/util/util_singleton.h | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/util/util_singleton.h diff --git a/src/util/util_singleton.h b/src/util/util_singleton.h new file mode 100644 index 000000000..08cd1562d --- /dev/null +++ b/src/util/util_singleton.h @@ -0,0 +1,43 @@ +#pragma once + +#include "rc/util_rc_ptr.h" + +#include "thread.h" + +namespace dxvk { + +/** + * \brief Singleton helper + * + * Class that manages a dynamically created + */ +template +class Singleton { + +public: + + Rc acquire() { + std::lock_guard lock(m_mutex); + + if (!(m_useCount++)) + m_object = new T(); + + return m_object; + } + + void release() { + std::lock_guard lock(m_mutex); + + if (!(--m_useCount)) + m_object = nullptr; + } + +private: + + dxvk::mutex m_mutex; + size_t m_useCount = 0; + Rc m_object = nullptr;; + +}; + +} From 61d72eebc1c4db2e9f89ade175ce14c3fa94e08f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 23 Jan 2023 17:17:56 +0100 Subject: [PATCH 1071/1348] [dxgi,d3d9] Use global singleton for DXVK instances No reason to have multiple of these around, and instance creation is fairly expensive. --- src/d3d9/d3d9_interface.cpp | 11 ++++++++++- src/d3d9/d3d9_interface.h | 2 ++ src/dxgi/dxgi_factory.cpp | 8 ++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/d3d9/d3d9_interface.cpp b/src/d3d9/d3d9_interface.cpp index e78a7e32a..10113e57d 100644 --- a/src/d3d9/d3d9_interface.cpp +++ b/src/d3d9/d3d9_interface.cpp @@ -4,12 +4,16 @@ #include "d3d9_caps.h" #include "d3d9_device.h" +#include "../util/util_singleton.h" + #include namespace dxvk { + Singleton g_dxvkInstance; + D3D9InterfaceEx::D3D9InterfaceEx(bool bExtended) - : m_instance ( new DxvkInstance() ) + : m_instance ( g_dxvkInstance.acquire() ) , m_extended ( bExtended ) , m_d3d9Options ( nullptr, m_instance->config() ) , m_d3d9Interop ( this ) { @@ -64,6 +68,11 @@ namespace dxvk { } + D3D9InterfaceEx::~D3D9InterfaceEx() { + g_dxvkInstance.release(); + } + + HRESULT STDMETHODCALLTYPE D3D9InterfaceEx::QueryInterface(REFIID riid, void** ppvObject) { if (ppvObject == nullptr) return E_POINTER; diff --git a/src/d3d9/d3d9_interface.h b/src/d3d9/d3d9_interface.h index 3fc9a43d3..55c9be918 100644 --- a/src/d3d9/d3d9_interface.h +++ b/src/d3d9/d3d9_interface.h @@ -20,6 +20,8 @@ namespace dxvk { D3D9InterfaceEx(bool bExtended); + ~D3D9InterfaceEx(); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); HRESULT STDMETHODCALLTYPE RegisterSoftwareDevice(void* pInitializeFunction); diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp index 635221868..80d43ddce 100644 --- a/src/dxgi/dxgi_factory.cpp +++ b/src/dxgi/dxgi_factory.cpp @@ -3,8 +3,12 @@ #include "dxgi_swapchain.h" #include "dxgi_swapchain_dispatcher.h" +#include "../util/util_singleton.h" + namespace dxvk { + Singleton g_dxvkInstance; + DxgiVkFactory::DxgiVkFactory(DxgiFactory* pFactory) : m_factory(pFactory) { @@ -44,7 +48,7 @@ namespace dxvk { DxgiFactory::DxgiFactory(UINT Flags) - : m_instance (new DxvkInstance()), + : m_instance (g_dxvkInstance.acquire()), m_interop (this), m_options (m_instance->config()), m_monitorInfo (this, m_options), @@ -55,7 +59,7 @@ namespace dxvk { DxgiFactory::~DxgiFactory() { - + g_dxvkInstance.release(); } From 2abc102d2c195dbeb41193237de67b17692fc245 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 24 Jan 2023 14:54:09 +0100 Subject: [PATCH 1072/1348] [meta] Release 2.1 --- RELEASE | 2 +- meson.build | 2 +- src/dxvk/dxvk_instance.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASE b/RELEASE index cd5ac039d..879b416e6 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -2.0 +2.1 diff --git a/meson.build b/meson.build index 39a28e052..2a5769120 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('dxvk', ['c', 'cpp'], version : 'v2.0', meson_version : '>= 0.49', default_options : [ 'cpp_std=c++17', 'warning_level=2' ]) +project('dxvk', ['c', 'cpp'], version : 'v2.1', meson_version : '>= 0.49', default_options : [ 'cpp_std=c++17', 'warning_level=2' ]) cpu_family = target_machine.cpu_family() platform = target_machine.system() diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index 7f73e6e47..fc1accc73 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -162,7 +162,7 @@ namespace dxvk { VkApplicationInfo appInfo = { VK_STRUCTURE_TYPE_APPLICATION_INFO }; appInfo.pApplicationName = appName.c_str(); appInfo.pEngineName = "DXVK"; - appInfo.engineVersion = VK_MAKE_VERSION(2, 0, 0); + appInfo.engineVersion = VK_MAKE_VERSION(2, 1, 0); appInfo.apiVersion = VK_MAKE_VERSION(1, 3, 0); VkInstanceCreateInfo info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; From c6111eaf61e3c3c59b51e2adaec2cfac64765e27 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 27 Jan 2023 05:27:49 +0100 Subject: [PATCH 1073/1348] [dxvk] Fix small_vector size Kind of harmless since we're not using this much. --- src/util/util_small_vector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/util_small_vector.h b/src/util/util_small_vector.h index daf5bedb9..3302f1c58 100644 --- a/src/util/util_small_vector.h +++ b/src/util/util_small_vector.h @@ -106,7 +106,7 @@ namespace dxvk { union { storage* m_ptr; - storage m_data[sizeof(T) * N]; + storage m_data[N]; } u; size_t pick_capacity(size_t n) { From 41b1efd7ce0b0b80b0a99e814fe62153d9c47b8a Mon Sep 17 00:00:00 2001 From: Jens Peters Date: Fri, 27 Jan 2023 23:06:07 +0100 Subject: [PATCH 1074/1348] [dxgi] Fix potential division by zero in log statement Apparently 0/0 is legal and should be interpreted as 0/1. --- src/dxgi/dxgi_swapchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index e7cd76516..fef525bec 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -713,7 +713,7 @@ namespace dxvk { "DXGI: Failed to query closest mode:", "\n Format: ", preferredMode.Format, "\n Mode: ", preferredMode.Width, "x", preferredMode.Height, - "@", preferredMode.RefreshRate.Numerator / preferredMode.RefreshRate.Denominator)); + "@", preferredMode.RefreshRate.Numerator / std::max(preferredMode.RefreshRate.Denominator, 1u))); return hr; } From 2263dcad954742d7415defec956219fb111d38bf Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Fri, 27 Jan 2023 14:59:54 -0600 Subject: [PATCH 1075/1348] [d3d11] Improve video processor caps query stubs --- src/d3d11/d3d11_video.cpp | 40 ++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index e4d763598..9202ca6d3 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -48,23 +48,47 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11VideoProcessorEnumerator::CheckVideoProcessorFormat( DXGI_FORMAT Format, UINT* pFlags) { - Logger::err("D3D11VideoProcessorEnumerator::CheckVideoProcessorFormat: Stub"); - return E_NOTIMPL; + Logger::err(str::format("D3D11VideoProcessorEnumerator::CheckVideoProcessorFormat: stub, format ", Format)); + + if (!pFlags) + return E_INVALIDARG; + + *pFlags = D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_INPUT | D3D11_VIDEO_PROCESSOR_FORMAT_SUPPORT_OUTPUT; + return S_OK; } HRESULT STDMETHODCALLTYPE D3D11VideoProcessorEnumerator::GetVideoProcessorCaps( D3D11_VIDEO_PROCESSOR_CAPS* pCaps) { - Logger::err("D3D11VideoProcessorEnumerator::GetVideoProcessorCaps: Stub"); - return E_NOTIMPL; + Logger::err("D3D11VideoProcessorEnumerator::GetVideoProcessorCaps: semi-stub"); + + if (!pCaps) + return E_INVALIDARG; + + *pCaps = {}; + pCaps->RateConversionCapsCount = 1; + pCaps->MaxInputStreams = 52; + pCaps->MaxStreamStates = 52; + return S_OK; } HRESULT STDMETHODCALLTYPE D3D11VideoProcessorEnumerator::GetVideoProcessorRateConversionCaps( UINT TypeIndex, D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS* pCaps) { - Logger::err("D3D11VideoProcessorEnumerator::GetVideoProcessorRateConversionCaps: Stub"); - return E_NOTIMPL; + Logger::err("D3D11VideoProcessorEnumerator::GetVideoProcessorRateConversionCaps: semi-stub"); + if (!pCaps || TypeIndex) + return E_INVALIDARG; + + *pCaps = {}; + if (m_desc.InputFrameFormat == D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE) { + pCaps->ProcessorCaps = D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_FRAME_RATE_CONVERSION; + } else { + pCaps->ProcessorCaps = D3D11_VIDEO_PROCESSOR_PROCESSOR_CAPS_DEINTERLACE_BOB; + pCaps->PastFrames = 1; + pCaps->FutureFrames = 1; + } + return S_OK; } @@ -603,7 +627,9 @@ namespace dxvk { D3D11_VIDEO_PROCESSOR_OUTPUT_RATE Rate, BOOL Repeat, const DXGI_RATIONAL* CustomRate) { - Logger::err("D3D11VideoContext::VideoProcessorSetStreamOutputRate: Stub"); + Logger::err(str::format("D3D11VideoContext::VideoProcessorSetStreamOutputRate: Stub, Rate ", Rate)); + if (CustomRate) + Logger::err(str::format("CustomRate ", CustomRate->Numerator, "/", CustomRate->Denominator)); } From caf31033d711460e86781b16a4d9b0f41fa9e817 Mon Sep 17 00:00:00 2001 From: TacoDeBoss Date: Tue, 7 Feb 2023 05:14:48 -0600 Subject: [PATCH 1076/1348] [util] Far Cry 2: Set VendorId to Nvidia, enable apitraceMode (#3241) --- src/util/config/config.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index c8bc14c0d..2d39c7e52 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -43,6 +43,14 @@ namespace dxvk { { "d3d11.dcSingleUseMode", "False" }, { "d3d11.cachedDynamicResources", "vi" }, }} }, + /* Far Cry 2: Set vendor ID to Nvidia to avoid + * vegetation artifacts on Intel, and set + * apitrace mode to True to improve perf on all + * hardware. */ + { R"(\\(FarCry2|farcry2game)\.exe$)", {{ + { "d3d9.customVendorId", "10de" }, + { "d3d9.apitraceMode", "True" }, + }} }, /* Far Cry 3: Assumes clear(0.5) on an UNORM * * format to result in 128 on AMD and 127 on * * Nvidia. We assume that the Vulkan drivers * From 081181313e16999101966b823f29c1982d2ddab6 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Sat, 18 Feb 2023 10:54:14 +0100 Subject: [PATCH 1077/1348] [util] Limit Battle Fantasia Revisited Edition to 60fps (#3256) --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 2d39c7e52..68a3c7285 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -716,6 +716,11 @@ namespace dxvk { { R"(\\BBCF\.exe$)", {{ { "d3d9.textureMemory", "0" }, }} }, + /* Battle Fantasia Revised Edition * + * Speedup above 60fps */ + { R"(\\bf10\.exe$)", {{ + { "d3d9.maxFrameRate", "60" }, + }} }, }}; From 0d28be4ab8162b6ee2a37d959f5c791e1e69b166 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Sat, 18 Feb 2023 15:42:42 +0100 Subject: [PATCH 1078/1348] [d3d9] Fix capturing lights in state block --- src/d3d9/d3d9_state.h | 2 +- src/d3d9/d3d9_stateblock.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/d3d9/d3d9_state.h b/src/d3d9/d3d9_state.h index a3dd0a570..da19de1f3 100644 --- a/src/d3d9/d3d9_state.h +++ b/src/d3d9/d3d9_state.h @@ -227,7 +227,7 @@ namespace dxvk { std::vector> lights; std::array enabledLightIndices; - bool IsLightEnabled(DWORD Index) { + bool IsLightEnabled(DWORD Index) const { const auto& indices = enabledLightIndices; return std::find(indices.begin(), indices.end(), Index) != indices.end(); } diff --git a/src/d3d9/d3d9_stateblock.h b/src/d3d9/d3d9_stateblock.h index a098b54fa..05e7daf35 100644 --- a/src/d3d9/d3d9_stateblock.h +++ b/src/d3d9/d3d9_stateblock.h @@ -306,17 +306,17 @@ namespace dxvk { } if (m_captures.flags.test(D3D9CapturedStateFlag::Lights)) { - for (uint32_t i = 0; i < m_state.lights.size(); i++) { - if (!m_state.lights[i].has_value()) + for (uint32_t i = 0; i < src->lights.size(); i++) { + if (!src->lights[i].has_value()) continue; - dst->SetLight(i, &m_state.lights[i].value()); + dst->SetLight(i, &src->lights[i].value()); } for (uint32_t i = 0; i < m_captures.lightEnabledChanges.dwordCount(); i++) { for (uint32_t consts : bit::BitMask(m_captures.lightEnabledChanges.dword(i))) { uint32_t idx = i * 32 + consts; - dst->LightEnable(idx, m_state.IsLightEnabled(idx)); + dst->LightEnable(idx, src->IsLightEnabled(idx)); } } } From 2be0d6842ef343b68dee544a390133213f10ce9f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 1 Mar 2023 11:52:55 +0100 Subject: [PATCH 1079/1348] [dxvk] Add option to limit memory chunk size --- dxvk.conf | 11 +++++++++++ src/dxvk/dxvk_memory.cpp | 20 ++++++++++++++++---- src/dxvk/dxvk_memory.h | 5 +++++ src/dxvk/dxvk_options.cpp | 1 + src/dxvk/dxvk_options.h | 3 +++ 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/dxvk.conf b/dxvk.conf index 626c187a6..f5ec17eba 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -294,6 +294,17 @@ # dxvk.useRawSsbo = Auto +# Changes memory chunk size. +# +# Can be used to override the maximum memory chunk size. +# +# Supported values: +# - 0 to use the defaults +# - any positive integer to limit the chunk size, in MiB + +# dxvk.maxChunkSize = 0 + + # Controls graphics pipeline library behaviour # # Can be used to change VK_EXT_graphics_pipeline_library usage for diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 1b7c643e4..5091f09b7 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -183,7 +183,8 @@ namespace dxvk { DxvkMemoryAllocator::DxvkMemoryAllocator(DxvkDevice* device) : m_device (device), - m_memProps (device->adapter()->memoryProperties()) { + m_memProps (device->adapter()->memoryProperties()), + m_maxChunkSize (determineMaxChunkSize(device)) { for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { m_memHeaps[i].properties = m_memProps.memoryHeaps[i]; m_memHeaps[i].stats = DxvkMemoryStats { 0, 0 }; @@ -493,15 +494,15 @@ namespace dxvk { VkMemoryHeap heap = m_memProps.memoryHeaps[type.heapIndex]; // Default to a chunk size of 256 MiB - VkDeviceSize chunkSize = 256 << 20; + VkDeviceSize chunkSize = m_maxChunkSize; if (hints.test(DxvkMemoryFlag::Small)) - chunkSize = 16 << 20; + chunkSize = std::min(chunkSize, 16 << 20); // Try to waste a bit less system memory especially in // 32-bit applications due to address space constraints if (type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) - chunkSize = (env::is32BitHostPlatform() ? 16 : 64) << 20; + chunkSize = std::min((env::is32BitHostPlatform() ? 16 : 64) << 20, chunkSize); // Reduce the chunk size on small heaps so // we can at least fit in 15 allocations @@ -638,6 +639,17 @@ namespace dxvk { } + VkDeviceSize DxvkMemoryAllocator::determineMaxChunkSize( + DxvkDevice* device) const { + int32_t option = device->config().maxChunkSize; + + if (option <= 0) + option = 256; + + return VkDeviceSize(option) << 20; + } + + void DxvkMemoryAllocator::logMemoryError(const VkMemoryRequirements& req) const { std::stringstream sstr; sstr << "DxvkMemoryAllocator: Memory allocation failed" << std::endl diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index 7748ebbaa..1dfb535ad 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -352,6 +352,8 @@ namespace dxvk { std::array m_memHeaps; std::array m_memTypes; + VkDeviceSize m_maxChunkSize; + uint32_t m_sparseMemoryTypes = 0u; DxvkMemory tryAlloc( @@ -403,6 +405,9 @@ namespace dxvk { uint32_t determineSparseMemoryTypes( DxvkDevice* device) const; + VkDeviceSize determineMaxChunkSize( + DxvkDevice* device) const; + void logMemoryError( const VkMemoryRequirements& req) const; diff --git a/src/dxvk/dxvk_options.cpp b/src/dxvk/dxvk_options.cpp index 00f284aa6..373db3255 100644 --- a/src/dxvk/dxvk_options.cpp +++ b/src/dxvk/dxvk_options.cpp @@ -9,6 +9,7 @@ namespace dxvk { enableGraphicsPipelineLibrary = config.getOption("dxvk.enableGraphicsPipelineLibrary", Tristate::Auto); trackPipelineLifetime = config.getOption("dxvk.trackPipelineLifetime", Tristate::Auto); useRawSsbo = config.getOption("dxvk.useRawSsbo", Tristate::Auto); + maxChunkSize = config.getOption ("dxvk.maxChunkSize", 0); hud = config.getOption("dxvk.hud", ""); } diff --git a/src/dxvk/dxvk_options.h b/src/dxvk/dxvk_options.h index 015fea0cf..fe4e903d9 100644 --- a/src/dxvk/dxvk_options.h +++ b/src/dxvk/dxvk_options.h @@ -27,6 +27,9 @@ namespace dxvk { /// Shader-related options Tristate useRawSsbo; + /// Maximum memory chunk size in MiB + int32_t maxChunkSize; + /// HUD elements std::string hud; }; From f4b91817fe276332885271563cb48fa0389b2ab8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 1 Mar 2023 12:10:48 +0100 Subject: [PATCH 1080/1348] [dxvk] Create dummy sampler and buffer on demand We only need the dummy buffer for transform feedback, all other cases are handled by null descriptors. May save a memory allocation. --- src/dxvk/dxvk_unbound.cpp | 59 ++++++++++++++++++++++++++++++++------- src/dxvk/dxvk_unbound.h | 24 +++++++++------- 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/dxvk/dxvk_unbound.cpp b/src/dxvk/dxvk_unbound.cpp index a06eafe98..fd2af2f35 100644 --- a/src/dxvk/dxvk_unbound.cpp +++ b/src/dxvk/dxvk_unbound.cpp @@ -3,18 +3,57 @@ namespace dxvk { DxvkUnboundResources::DxvkUnboundResources(DxvkDevice* dev) - : m_sampler (createSampler(dev)), - m_buffer (createBuffer(dev)) { - + : m_device(dev) { + } DxvkUnboundResources::~DxvkUnboundResources() { } - - - Rc DxvkUnboundResources::createSampler(DxvkDevice* dev) { + + + VkBuffer DxvkUnboundResources::bufferHandle() { + VkBuffer buffer = m_bufferHandle.load(); + + if (likely(buffer != VK_NULL_HANDLE)) + return buffer; + + std::lock_guard lock(m_mutex); + buffer = m_bufferHandle.load(); + + if (buffer) + return buffer; + + m_buffer = createBuffer(); + buffer = m_buffer->getSliceHandle().handle; + + m_bufferHandle.store(buffer, std::memory_order_release); + return buffer; + } + + + VkSampler DxvkUnboundResources::samplerHandle() { + VkSampler sampler = m_samplerHandle.load(); + + if (likely(sampler != VK_NULL_HANDLE)) + return sampler; + + std::lock_guard lock(m_mutex); + sampler = m_samplerHandle.load(); + + if (sampler) + return sampler; + + m_sampler = createSampler(); + sampler = m_sampler->handle(); + + m_samplerHandle.store(sampler, std::memory_order_release); + return sampler; + } + + + Rc DxvkUnboundResources::createSampler() { DxvkSamplerCreateInfo info; info.minFilter = VK_FILTER_LINEAR; info.magFilter = VK_FILTER_LINEAR; @@ -34,11 +73,11 @@ namespace dxvk { info.usePixelCoord = VK_FALSE; info.nonSeamless = VK_FALSE; - return dev->createSampler(info); + return m_device->createSampler(info); } - Rc DxvkUnboundResources::createBuffer(DxvkDevice* dev) { + Rc DxvkUnboundResources::createBuffer() { DxvkBufferCreateInfo info; info.size = MaxUniformBufferSize; info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT @@ -50,12 +89,12 @@ namespace dxvk { | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT; info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT - | dev->getShaderPipelineStages(); + | m_device->getShaderPipelineStages(); info.access = VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; - Rc buffer = dev->createBuffer(info, + Rc buffer = m_device->createBuffer(info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); diff --git a/src/dxvk/dxvk_unbound.h b/src/dxvk/dxvk_unbound.h index 8668f38b6..52f17a0d4 100644 --- a/src/dxvk/dxvk_unbound.h +++ b/src/dxvk/dxvk_unbound.h @@ -1,5 +1,7 @@ #pragma once +#include + #include "dxvk_buffer.h" #include "dxvk_image.h" #include "dxvk_sampler.h" @@ -30,9 +32,7 @@ namespace dxvk { * and index buffers. * \returns Dummy buffer handle */ - VkBuffer bufferHandle() const { - return m_buffer->getSliceHandle().handle; - } + VkBuffer bufferHandle(); /** * \brief Dummy sampler descriptor @@ -42,18 +42,22 @@ namespace dxvk { * still require different behaviour. * \returns Dummy sampler descriptor */ - VkSampler samplerHandle() const { - return m_sampler->handle(); - } + VkSampler samplerHandle(); private: - Rc m_sampler; - Rc m_buffer; + DxvkDevice* m_device; + + std::atomic m_samplerHandle = { VK_NULL_HANDLE }; + std::atomic m_bufferHandle = { VK_NULL_HANDLE }; + + std::mutex m_mutex; + Rc m_sampler; + Rc m_buffer; - Rc createSampler(DxvkDevice* dev); + Rc createSampler(); - Rc createBuffer(DxvkDevice* dev); + Rc createBuffer(); }; From 2356d34f2ef2f8b85928278614dc7ec838278670 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 1 Mar 2023 12:37:06 +0100 Subject: [PATCH 1081/1348] [d3d11] Create video context resources on demand Saves another memory allocation that we will often not need. --- src/d3d11/d3d11_video.cpp | 129 +++++++++++++++++++++++--------------- src/d3d11/d3d11_video.h | 21 +++++-- 2 files changed, 93 insertions(+), 57 deletions(-) diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 9202ca6d3..471793948 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -348,56 +348,8 @@ namespace dxvk { D3D11VideoContext::D3D11VideoContext( D3D11ImmediateContext* pContext, const Rc& Device) - : m_ctx(pContext) { - SpirvCodeBuffer vsCode(d3d11_video_blit_vert); - SpirvCodeBuffer fsCode(d3d11_video_blit_frag); + : m_ctx(pContext), m_device(Device) { - const std::array fsBindings = {{ - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_UNIFORM_READ_BIT, VK_TRUE }, - { VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, 0 }, - { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, - { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, - }}; - - DxvkShaderCreateInfo vsInfo; - vsInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; - vsInfo.outputMask = 0x1; - m_vs = new DxvkShader(vsInfo, std::move(vsCode)); - - DxvkShaderCreateInfo fsInfo; - fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - fsInfo.bindingCount = fsBindings.size(); - fsInfo.bindings = fsBindings.data(); - fsInfo.inputMask = 0x1; - fsInfo.outputMask = 0x1; - m_fs = new DxvkShader(fsInfo, std::move(fsCode)); - - DxvkSamplerCreateInfo samplerInfo; - samplerInfo.magFilter = VK_FILTER_LINEAR; - samplerInfo.minFilter = VK_FILTER_LINEAR; - samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; - samplerInfo.mipmapLodBias = 0.0f; - samplerInfo.mipmapLodMin = 0.0f; - samplerInfo.mipmapLodMax = 0.0f; - samplerInfo.useAnisotropy = VK_FALSE; - samplerInfo.maxAnisotropy = 1.0f; - samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.compareToDepth = VK_FALSE; - samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; - samplerInfo.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; - samplerInfo.borderColor = VkClearColorValue(); - samplerInfo.usePixelCoord = VK_FALSE; - samplerInfo.nonSeamless = VK_FALSE; - m_sampler = Device->createSampler(samplerInfo); - - DxvkBufferCreateInfo bufferInfo; - bufferInfo.size = sizeof(UboData); - bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - bufferInfo.stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; - bufferInfo.access = VK_ACCESS_UNIFORM_READ_BIT; - m_ubo = Device->createBuffer(bufferInfo, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); } @@ -1226,9 +1178,6 @@ namespace dxvk { rt.color[0].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; ctx->bindRenderTargets(std::move(rt), 0u); - ctx->bindShader(Rc(m_vs)); - ctx->bindShader(Rc(m_fs)); - ctx->bindUniformBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo)); DxvkInputAssemblyState iaState; iaState.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; @@ -1245,6 +1194,8 @@ namespace dxvk { void D3D11VideoContext::BlitStream( const D3D11VideoProcessorStreamState* pStreamState, const D3D11_VIDEO_PROCESSOR_STREAM* pStream) { + CreateResources(); + if (pStream->PastFrames || pStream->FutureFrames) Logger::err("D3D11VideoContext: Ignoring non-zero PastFrames and FutureFrames"); @@ -1322,6 +1273,11 @@ namespace dxvk { ctx->invalidateBuffer(m_ubo, uboSlice); ctx->setViewports(1, &viewport, &scissor); + + ctx->bindShader(Rc(m_vs)); + ctx->bindShader(Rc(m_fs)); + + ctx->bindUniformBuffer(VK_SHADER_STAGE_FRAGMENT_BIT, 0, DxvkBufferSlice(m_ubo)); ctx->bindResourceSampler(VK_SHADER_STAGE_FRAGMENT_BIT, 1, Rc(m_sampler)); for (uint32_t i = 0; i < cViews.size(); i++) @@ -1337,6 +1293,75 @@ namespace dxvk { } + void D3D11VideoContext::CreateUniformBuffer() { + DxvkBufferCreateInfo bufferInfo; + bufferInfo.size = sizeof(UboData); + bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + bufferInfo.stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + bufferInfo.access = VK_ACCESS_UNIFORM_READ_BIT; + m_ubo = m_device->createBuffer(bufferInfo, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + } + + + void D3D11VideoContext::CreateSampler() { + DxvkSamplerCreateInfo samplerInfo; + samplerInfo.magFilter = VK_FILTER_LINEAR; + samplerInfo.minFilter = VK_FILTER_LINEAR; + samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + samplerInfo.mipmapLodBias = 0.0f; + samplerInfo.mipmapLodMin = 0.0f; + samplerInfo.mipmapLodMax = 0.0f; + samplerInfo.useAnisotropy = VK_FALSE; + samplerInfo.maxAnisotropy = 1.0f; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.compareToDepth = VK_FALSE; + samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; + samplerInfo.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE; + samplerInfo.borderColor = VkClearColorValue(); + samplerInfo.usePixelCoord = VK_FALSE; + samplerInfo.nonSeamless = VK_FALSE; + m_sampler = m_device->createSampler(samplerInfo); + } + + + void D3D11VideoContext::CreateShaders() { + SpirvCodeBuffer vsCode(d3d11_video_blit_vert); + SpirvCodeBuffer fsCode(d3d11_video_blit_frag); + + const std::array fsBindings = {{ + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_UNIFORM_READ_BIT, VK_TRUE }, + { VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_IMAGE_VIEW_TYPE_MAX_ENUM, VK_SHADER_STAGE_FRAGMENT_BIT, 0 }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 3, VK_IMAGE_VIEW_TYPE_2D, VK_SHADER_STAGE_FRAGMENT_BIT, VK_ACCESS_SHADER_READ_BIT }, + }}; + + DxvkShaderCreateInfo vsInfo; + vsInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; + vsInfo.outputMask = 0x1; + m_vs = new DxvkShader(vsInfo, std::move(vsCode)); + + DxvkShaderCreateInfo fsInfo; + fsInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + fsInfo.bindingCount = fsBindings.size(); + fsInfo.bindings = fsBindings.data(); + fsInfo.inputMask = 0x1; + fsInfo.outputMask = 0x1; + m_fs = new DxvkShader(fsInfo, std::move(fsCode)); + } + + + void D3D11VideoContext::CreateResources() { + if (std::exchange(m_resourcesCreated, true)) + return; + + CreateSampler(); + CreateUniformBuffer(); + CreateShaders(); + } + + void D3D11VideoContext::UnbindResources() { m_ctx->EmitCs([] (DxvkContext* ctx) { ctx->bindRenderTargets(DxvkRenderTargets(), 0u); diff --git a/src/d3d11/d3d11_video.h b/src/d3d11/d3d11_video.h index fd3b3387b..30288a586 100644 --- a/src/d3d11/d3d11_video.h +++ b/src/d3d11/d3d11_video.h @@ -588,15 +588,18 @@ namespace dxvk { VkBool32 isPlanar; }; - D3D11ImmediateContext* m_ctx; + D3D11ImmediateContext* m_ctx; - Rc m_sampler; - Rc m_vs; - Rc m_fs; - Rc m_ubo; + Rc m_device; + Rc m_vs; + Rc m_fs; + Rc m_sampler; + Rc m_ubo; VkExtent2D m_dstExtent = { 0u, 0u }; + bool m_resourcesCreated = false; + void ApplyColorMatrix(float pDst[3][4], const float pSrc[3][4]); void ApplyYCbCrMatrix(float pColorMatrix[3][4], bool UseBt709); @@ -608,6 +611,14 @@ namespace dxvk { const D3D11VideoProcessorStreamState* pStreamState, const D3D11_VIDEO_PROCESSOR_STREAM* pStream); + void CreateUniformBuffer(); + + void CreateSampler(); + + void CreateShaders(); + + void CreateResources(); + void UnbindResources(); }; From 81440340ac1d28c9e76517a03115f369ddcffd2e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 1 Mar 2023 13:03:43 +0100 Subject: [PATCH 1082/1348] [d3d9,dxvk,util] Actually use dxvk::mutex --- src/d3d9/d3d9_annotation.h | 5 ++++- src/dxvk/dxvk_unbound.h | 2 +- src/util/util_sleep.h | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/d3d9/d3d9_annotation.h b/src/d3d9/d3d9_annotation.h index 1fdb19fc2..8ae3eca30 100644 --- a/src/d3d9/d3d9_annotation.h +++ b/src/d3d9/d3d9_annotation.h @@ -2,8 +2,11 @@ #include "d3d9_device.h" #include "d3d9_include.h" + #include "../dxvk/dxvk_annotation.h" +#include "../util/thread.h" + #include #include #include @@ -43,7 +46,7 @@ namespace dxvk { std::atomic m_shouldAnnotate; - std::mutex m_mutex; + dxvk::mutex m_mutex; std::vector m_annotations; // Provide our own event depth as we diff --git a/src/dxvk/dxvk_unbound.h b/src/dxvk/dxvk_unbound.h index 52f17a0d4..9caa9fd8c 100644 --- a/src/dxvk/dxvk_unbound.h +++ b/src/dxvk/dxvk_unbound.h @@ -51,7 +51,7 @@ namespace dxvk { std::atomic m_samplerHandle = { VK_NULL_HANDLE }; std::atomic m_bufferHandle = { VK_NULL_HANDLE }; - std::mutex m_mutex; + dxvk::mutex m_mutex; Rc m_sampler; Rc m_buffer; diff --git a/src/util/util_sleep.h b/src/util/util_sleep.h index dc7fe0fca..44653a5ba 100644 --- a/src/util/util_sleep.h +++ b/src/util/util_sleep.h @@ -45,7 +45,7 @@ namespace dxvk { static Sleep s_instance; - std::mutex m_mutex; + dxvk::mutex m_mutex; std::atomic m_initialized = { false }; #ifdef _WIN32 From aa92cf48f557bb9876672d2513cdac5c78941ade Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 1 Mar 2023 13:01:48 +0100 Subject: [PATCH 1083/1348] [util] Add function to cache QueryInterface errors --- src/util/com/com_guid.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/util/com/com_guid.h | 13 +++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/util/com/com_guid.cpp b/src/util/com/com_guid.cpp index 329d18488..ed4eaba67 100644 --- a/src/util/com/com_guid.cpp +++ b/src/util/com/com_guid.cpp @@ -1,9 +1,47 @@ +#include +#include + #include "com_guid.h" #include "../../d3d11/d3d11_interfaces.h" #include "../../dxgi/dxgi_interfaces.h" +#include "../../dxvk/dxvk_hash.h" + +#include "../thread.h" + +namespace dxvk { + + struct GuidPair { + GuidPair() { }; + GuidPair(IID a_, IID b_) + : a(a_), b(b_) { } + + IID a, b; + + size_t hash() const { + return size_t(a.Data1) ^ size_t(b.Data1); + } + + bool eq(const GuidPair& other) const { + return a == other.a && b == other.b; + } + }; + + dxvk::mutex g_loggedQueryInterfaceErrorMutex; + std::unordered_set g_loggedQueryInterfaceErrors; + + bool logQueryInterfaceError(REFIID objectGuid, REFIID requestedGuid) { + if (Logger::logLevel() > LogLevel::Warn) + return false; + + std::lock_guard lock(g_loggedQueryInterfaceErrorMutex); + return g_loggedQueryInterfaceErrors.emplace(objectGuid, requestedGuid).second; + } + +} + std::ostream& operator << (std::ostream& os, REFIID guid) { os << std::hex << std::setfill('0') << std::setw(8) << guid.Data1 << '-'; diff --git a/src/util/com/com_guid.h b/src/util/com/com_guid.h index 9a69fc932..f090c2367 100644 --- a/src/util/com/com_guid.h +++ b/src/util/com/com_guid.h @@ -5,4 +5,17 @@ #include "com_include.h" +namespace dxvk { + + /** + * \brief Checks whether an unknown GUID should be logged + * + * \param [in] objectGuid GUID of the object that QueryInterface is called on + * \param [in] requestGuid Requested unsupported GUID + * \returns \c true if the error should be logged + */ + bool logQueryInterfaceError(REFIID objectGuid, REFIID requestedGuid); + +}; + std::ostream& operator << (std::ostream& os, REFIID guid); From cc78276897455845f7f64d7521b1f3f7e795b3cb Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 1 Mar 2023 13:13:16 +0100 Subject: [PATCH 1084/1348] [d3d11] Only log QueryInterface errors once --- src/d3d11/d3d11_blend.cpp | 7 +++++-- src/d3d11/d3d11_buffer.cpp | 7 +++++-- src/d3d11/d3d11_class_linkage.cpp | 7 +++++-- src/d3d11/d3d11_cmdlist.cpp | 7 +++++-- src/d3d11/d3d11_context.cpp | 7 +++++-- src/d3d11/d3d11_depth_stencil.cpp | 7 +++++-- src/d3d11/d3d11_device.cpp | 7 +++++-- src/d3d11/d3d11_fence.cpp | 7 +++++-- src/d3d11/d3d11_input_layout.cpp | 7 +++++-- src/d3d11/d3d11_query.cpp | 7 +++++-- src/d3d11/d3d11_rasterizer.cpp | 7 +++++-- src/d3d11/d3d11_sampler.cpp | 7 +++++-- src/d3d11/d3d11_shader.h | 6 ++++-- src/d3d11/d3d11_state_object.cpp | 7 +++++-- src/d3d11/d3d11_swapchain.cpp | 6 +++++- src/d3d11/d3d11_texture.cpp | 21 +++++++++++++++------ src/d3d11/d3d11_video.cpp | 28 ++++++++++++++++++++-------- src/d3d11/d3d11_view_dsv.cpp | 7 +++++-- src/d3d11/d3d11_view_rtv.cpp | 7 +++++-- src/d3d11/d3d11_view_srv.cpp | 7 +++++-- src/d3d11/d3d11_view_uav.cpp | 7 +++++-- 21 files changed, 129 insertions(+), 51 deletions(-) diff --git a/src/d3d11/d3d11_blend.cpp b/src/d3d11/d3d11_blend.cpp index 38752b691..441d35a7c 100644 --- a/src/d3d11/d3d11_blend.cpp +++ b/src/d3d11/d3d11_blend.cpp @@ -58,8 +58,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11BlendState::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11BlendState), riid)) { + Logger::warn("D3D11BlendState::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index 8296f6d6b..6695fd057 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -138,8 +138,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11Buffer), riid)) { + Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_class_linkage.cpp b/src/d3d11/d3d11_class_linkage.cpp index 8070b6603..d2bc7588f 100644 --- a/src/d3d11/d3d11_class_linkage.cpp +++ b/src/d3d11/d3d11_class_linkage.cpp @@ -28,8 +28,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11ClassLinkage::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11ClassLinkage), riid)) { + Logger::warn("D3D11ClassLinkage::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_cmdlist.cpp b/src/d3d11/d3d11_cmdlist.cpp index e15f322ab..31ed4376f 100644 --- a/src/d3d11/d3d11_cmdlist.cpp +++ b/src/d3d11/d3d11_cmdlist.cpp @@ -30,8 +30,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11CommandList::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11CommandList), riid)) { + Logger::warn("D3D11CommandList::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index e13342da9..d24401354 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -61,8 +61,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11DeviceContext::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11DeviceContext), riid)) { + Logger::warn("D3D11DeviceContext::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_depth_stencil.cpp b/src/d3d11/d3d11_depth_stencil.cpp index ded08d02c..65416c9dd 100644 --- a/src/d3d11/d3d11_depth_stencil.cpp +++ b/src/d3d11/d3d11_depth_stencil.cpp @@ -41,8 +41,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11DepthStencilState::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11DepthStencilState), riid)) { + Logger::warn("D3D11DepthStencilState::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index a69a0164c..1398fa70e 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -3153,8 +3153,11 @@ namespace dxvk { if (riid == GUID{0xd56e2a4c,0x5127,0x8437,{0x65,0x8a,0x98,0xc5,0xbb,0x78,0x94,0x98}}) return E_NOINTERFACE; - Logger::warn("D3D11DXGIDevice::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDXGIDXVKDevice), riid)) { + Logger::warn("D3D11DXGIDevice::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_fence.cpp b/src/d3d11/d3d11_fence.cpp index 8c37a5f3c..3eeb69467 100644 --- a/src/d3d11/d3d11_fence.cpp +++ b/src/d3d11/d3d11_fence.cpp @@ -48,8 +48,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11Fence: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11Fence), riid)) { + Logger::warn("D3D11Fence: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_input_layout.cpp b/src/d3d11/d3d11_input_layout.cpp index 257e38a79..3b42e0a42 100644 --- a/src/d3d11/d3d11_input_layout.cpp +++ b/src/d3d11/d3d11_input_layout.cpp @@ -46,8 +46,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11InputLayout::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11InputLayout), riid)) { + Logger::warn("D3D11InputLayout::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_query.cpp b/src/d3d11/d3d11_query.cpp index b7145739f..6629cd56f 100644 --- a/src/d3d11/d3d11_query.cpp +++ b/src/d3d11/d3d11_query.cpp @@ -120,8 +120,11 @@ namespace dxvk { } } - Logger::warn("D3D11Query: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11Query), riid)) { + Logger::warn("D3D11Query: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_rasterizer.cpp b/src/d3d11/d3d11_rasterizer.cpp index 169ce3b58..4a441f707 100644 --- a/src/d3d11/d3d11_rasterizer.cpp +++ b/src/d3d11/d3d11_rasterizer.cpp @@ -74,8 +74,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11RasterizerState::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11RasterizerState), riid)) { + Logger::warn("D3D11RasterizerState::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_sampler.cpp b/src/d3d11/d3d11_sampler.cpp index f0cd292f9..a80c91802 100644 --- a/src/d3d11/d3d11_sampler.cpp +++ b/src/d3d11/d3d11_sampler.cpp @@ -86,8 +86,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11SamplerState::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11SamplerState), riid)) { + Logger::warn("D3D11SamplerState::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_shader.h b/src/d3d11/d3d11_shader.h index fe499bc14..8d6e11254 100644 --- a/src/d3d11/d3d11_shader.h +++ b/src/d3d11/d3d11_shader.h @@ -134,8 +134,10 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11Shader::QueryInterface: Unknown interface query"); - return E_NOINTERFACE; + if (logQueryInterfaceError(__uuidof(D3D11Interface), riid)) { + Logger::warn("D3D11Shader::QueryInterface: Unknown interface query"); + return E_NOINTERFACE; + } } const D3D11CommonShader* GetCommonShader() const { diff --git a/src/d3d11/d3d11_state_object.cpp b/src/d3d11/d3d11_state_object.cpp index 33cc8a33f..3a8f2d849 100644 --- a/src/d3d11/d3d11_state_object.cpp +++ b/src/d3d11/d3d11_state_object.cpp @@ -29,8 +29,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11DeviceContextState::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3DDeviceContextState), riid)) { + Logger::warn("D3D11DeviceContextState::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index 98cbc4dfc..fbe78a5b2 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -103,7 +103,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11SwapChain::QueryInterface: Unknown interface query"); + if (logQueryInterfaceError(__uuidof(IDXGIVkSwapChain), riid)) { + Logger::warn("D3D11SwapChain::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 26e6c2700..15579edde 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -1086,8 +1086,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11Texture1D::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D10Texture1D), riid)) { + Logger::warn("D3D11Texture1D::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } @@ -1243,8 +1246,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11Texture2D::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D10Texture2D), riid)) { + Logger::warn("D3D11Texture2D::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } @@ -1350,8 +1356,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11Texture3D::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D10Texture3D), riid)) { + Logger::warn("D3D11Texture3D::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_video.cpp b/src/d3d11/d3d11_video.cpp index 471793948..3851a4981 100644 --- a/src/d3d11/d3d11_video.cpp +++ b/src/d3d11/d3d11_video.cpp @@ -32,8 +32,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11VideoProcessorEnumerator::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11VideoProcessorEnumerator), riid)) { + Logger::warn("D3D11VideoProcessorEnumerator::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } @@ -136,8 +139,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11VideoProcessor::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11VideoProcessor), riid)) { + Logger::warn("D3D11VideoProcessor::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } @@ -247,8 +253,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11VideoProcessorInputView::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11VideoProcessorInputView), riid)) { + Logger::warn("D3D11VideoProcessorInputView::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } @@ -326,8 +335,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11VideoProcessorOutputView::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11VideoProcessorOutputView), riid)) { + Logger::warn("D3D11VideoProcessorOutputView::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_view_dsv.cpp b/src/d3d11/d3d11_view_dsv.cpp index 62e79fedb..c9a861f9c 100644 --- a/src/d3d11/d3d11_view_dsv.cpp +++ b/src/d3d11/d3d11_view_dsv.cpp @@ -130,8 +130,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11DepthStencilView::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11DepthStencilView), riid)) { + Logger::warn("D3D11DepthStencilView::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_view_rtv.cpp b/src/d3d11/d3d11_view_rtv.cpp index 09153d0a0..eeb8787ca 100644 --- a/src/d3d11/d3d11_view_rtv.cpp +++ b/src/d3d11/d3d11_view_rtv.cpp @@ -141,8 +141,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11RenderTargetView::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11RenderTargetView), riid)) { + Logger::warn("D3D11RenderTargetView::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_view_srv.cpp b/src/d3d11/d3d11_view_srv.cpp index 73c179b09..4d1bd0481 100644 --- a/src/d3d11/d3d11_view_srv.cpp +++ b/src/d3d11/d3d11_view_srv.cpp @@ -209,8 +209,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11ShaderResourceView::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11ShaderResourceView), riid)) { + Logger::warn("D3D11ShaderResourceView::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d11/d3d11_view_uav.cpp b/src/d3d11/d3d11_view_uav.cpp index f21fe053f..94faf88d9 100644 --- a/src/d3d11/d3d11_view_uav.cpp +++ b/src/d3d11/d3d11_view_uav.cpp @@ -147,8 +147,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D11UnorderedAccessView::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(ID3D11UnorderedAccessView), riid)) { + Logger::warn("D3D11UnorderedAccessView::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } From 4c7896467955fed3091234f7016583f303f28d28 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 1 Mar 2023 13:16:37 +0100 Subject: [PATCH 1085/1348] [d3d9] Only log QueryInterface errors once --- src/d3d11/d3d11_shader.h | 4 +++- src/d3d9/d3d9_buffer.cpp | 14 ++++++++++---- src/d3d9/d3d9_device.cpp | 7 +++++-- src/d3d9/d3d9_interface.cpp | 7 +++++-- src/d3d9/d3d9_query.cpp | 7 +++++-- src/d3d9/d3d9_shader.h | 7 +++++-- src/d3d9/d3d9_stateblock.cpp | 7 +++++-- src/d3d9/d3d9_surface.cpp | 7 +++++-- src/d3d9/d3d9_swapchain.cpp | 7 +++++-- src/d3d9/d3d9_texture.cpp | 21 +++++++++++++++------ src/d3d9/d3d9_vertex_declaration.cpp | 7 +++++-- src/d3d9/d3d9_volume.cpp | 7 +++++-- 12 files changed, 73 insertions(+), 29 deletions(-) diff --git a/src/d3d11/d3d11_shader.h b/src/d3d11/d3d11_shader.h index 8d6e11254..44a3bcb98 100644 --- a/src/d3d11/d3d11_shader.h +++ b/src/d3d11/d3d11_shader.h @@ -136,8 +136,10 @@ namespace dxvk { if (logQueryInterfaceError(__uuidof(D3D11Interface), riid)) { Logger::warn("D3D11Shader::QueryInterface: Unknown interface query"); - return E_NOINTERFACE; + Logger::warn(str::format(riid)); } + + return E_NOINTERFACE; } const D3D11CommonShader* GetCommonShader() const { diff --git a/src/d3d9/d3d9_buffer.cpp b/src/d3d9/d3d9_buffer.cpp index c0b72c46e..999844ef1 100644 --- a/src/d3d9/d3d9_buffer.cpp +++ b/src/d3d9/d3d9_buffer.cpp @@ -29,8 +29,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9VertexBuffer::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DVertexBuffer9), riid)) { + Logger::warn("D3D9VertexBuffer::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } @@ -86,8 +89,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9IndexBuffer::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DIndexBuffer9), riid)) { + Logger::warn("D3D9IndexBuffer::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index e8ef30126..0cf65cf00 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -201,8 +201,11 @@ namespace dxvk { if (riid == __uuidof(IDirect3DDevice9Ex)) return E_NOINTERFACE; - Logger::warn("D3D9DeviceEx::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DDevice9), riid)) { + Logger::warn("D3D9DeviceEx::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d9/d3d9_interface.cpp b/src/d3d9/d3d9_interface.cpp index 10113e57d..e56c8b3d5 100644 --- a/src/d3d9/d3d9_interface.cpp +++ b/src/d3d9/d3d9_interface.cpp @@ -91,8 +91,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9InterfaceEx::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3D9), riid)) { + Logger::warn("D3D9InterfaceEx::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d9/d3d9_query.cpp b/src/d3d9/d3d9_query.cpp index a48732528..238c7e353 100644 --- a/src/d3d9/d3d9_query.cpp +++ b/src/d3d9/d3d9_query.cpp @@ -64,8 +64,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9Query::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DQuery9), riid)) { + Logger::warn("D3D9Query::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d9/d3d9_shader.h b/src/d3d9/d3d9_shader.h index 997d15259..564c881ac 100644 --- a/src/d3d9/d3d9_shader.h +++ b/src/d3d9/d3d9_shader.h @@ -109,8 +109,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9Shader::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(Base), riid)) { + Logger::warn("D3D9Shader::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d9/d3d9_stateblock.cpp b/src/d3d9/d3d9_stateblock.cpp index aec477127..9c0abba11 100644 --- a/src/d3d9/d3d9_stateblock.cpp +++ b/src/d3d9/d3d9_stateblock.cpp @@ -32,8 +32,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9StateBlock::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DStateBlock9), riid)) { + Logger::warn("D3D9StateBlock::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d9/d3d9_surface.cpp b/src/d3d9/d3d9_surface.cpp index 91f917853..ec6b7860f 100644 --- a/src/d3d9/d3d9_surface.cpp +++ b/src/d3d9/d3d9_surface.cpp @@ -74,8 +74,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9Surface::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DSurface9), riid)) { + Logger::warn("D3D9Surface::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d9/d3d9_swapchain.cpp b/src/d3d9/d3d9_swapchain.cpp index e01c80413..89c356fbe 100644 --- a/src/d3d9/d3d9_swapchain.cpp +++ b/src/d3d9/d3d9_swapchain.cpp @@ -84,8 +84,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9SwapChainEx::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DSwapChain9), riid)) { + Logger::warn("D3D9SwapChainEx::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d9/d3d9_texture.cpp b/src/d3d9/d3d9_texture.cpp index 1332fb32e..25a131493 100644 --- a/src/d3d9/d3d9_texture.cpp +++ b/src/d3d9/d3d9_texture.cpp @@ -32,8 +32,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9Texture2D::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DTexture9), riid)) { + Logger::warn("D3D9Texture2D::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } @@ -128,8 +131,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9Texture3D::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DVolumeTexture9), riid)) { + Logger::warn("D3D9Texture3D::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } @@ -218,8 +224,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9TextureCube::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DCubeTexture9), riid)) { + Logger::warn("D3D9TextureCube::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d9/d3d9_vertex_declaration.cpp b/src/d3d9/d3d9_vertex_declaration.cpp index 49b4dacaa..58c43be43 100644 --- a/src/d3d9/d3d9_vertex_declaration.cpp +++ b/src/d3d9/d3d9_vertex_declaration.cpp @@ -40,8 +40,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9VertexDecl::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DVertexDeclaration9), riid)) { + Logger::warn("D3D9VertexDecl::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/d3d9/d3d9_volume.cpp b/src/d3d9/d3d9_volume.cpp index dff931f25..18a80751b 100644 --- a/src/d3d9/d3d9_volume.cpp +++ b/src/d3d9/d3d9_volume.cpp @@ -65,8 +65,11 @@ namespace dxvk { return S_OK; } - Logger::warn("D3D9Volume::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDirect3DVolume9), riid)) { + Logger::warn("D3D9Volume::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } From 55e7cb1d5425ce8b64abf885ecb4c8f297dda035 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 1 Mar 2023 13:19:42 +0100 Subject: [PATCH 1086/1348] [dxgi] Only log QueryInterface errors once --- src/dxgi/dxgi_adapter.cpp | 7 +++++-- src/dxgi/dxgi_factory.cpp | 7 +++++-- src/dxgi/dxgi_output.cpp | 7 +++++-- src/dxgi/dxgi_surface.cpp | 7 +++++-- src/dxgi/dxgi_swapchain.cpp | 7 +++++-- src/dxgi/dxgi_swapchain_dispatcher.h | 7 +++++-- 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index a6395f4b7..71342b44c 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -103,8 +103,11 @@ namespace dxvk { return S_OK; } - Logger::warn("DxgiAdapter::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDXGIAdapter), riid)) { + Logger::warn("DxgiAdapter::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp index 80d43ddce..3e218ecb4 100644 --- a/src/dxgi/dxgi_factory.cpp +++ b/src/dxgi/dxgi_factory.cpp @@ -93,8 +93,11 @@ namespace dxvk { return S_OK; } - Logger::warn("DxgiFactory::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDXGIFactory), riid)) { + Logger::warn("DxgiFactory::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/dxgi/dxgi_output.cpp b/src/dxgi/dxgi_output.cpp index f1787bb7c..034521a48 100644 --- a/src/dxgi/dxgi_output.cpp +++ b/src/dxgi/dxgi_output.cpp @@ -110,8 +110,11 @@ namespace dxvk { return S_OK; } - Logger::warn("DxgiOutput::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDXGIOutput), riid)) { + Logger::warn("DxgiOutput::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/dxgi/dxgi_surface.cpp b/src/dxgi/dxgi_surface.cpp index d18abd648..b2cc03935 100644 --- a/src/dxgi/dxgi_surface.cpp +++ b/src/dxgi/dxgi_surface.cpp @@ -29,8 +29,11 @@ namespace dxvk { return S_OK; } - Logger::warn("DxgiSurfaceFactory::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDXGIVkSurfaceFactory), riid)) { + Logger::warn("DxgiSurfaceFactory::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index fef525bec..226ba28d6 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -65,8 +65,11 @@ namespace dxvk { return S_OK; } - Logger::warn("DxgiSwapChain::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDXGISwapChain), riid)) { + Logger::warn("DxgiSwapChain::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return E_NOINTERFACE; } diff --git a/src/dxgi/dxgi_swapchain_dispatcher.h b/src/dxgi/dxgi_swapchain_dispatcher.h index d7d8b584d..d5c00caef 100644 --- a/src/dxgi/dxgi_swapchain_dispatcher.h +++ b/src/dxgi/dxgi_swapchain_dispatcher.h @@ -61,8 +61,11 @@ namespace dxvk { return S_OK; } - Logger::warn("DxgiSwapChainDispatcher::QueryInterface: Unknown interface query"); - Logger::warn(str::format(riid)); + if (logQueryInterfaceError(__uuidof(IDXGISwapChain), riid)) { + Logger::warn("DxgiSwapChainDispatcher::QueryInterface: Unknown interface query"); + Logger::warn(str::format(riid)); + } + return m_dispatch->QueryInterface(riid, ppvObject); } From 5609c5e076470e0b5e81dd454ca7a9bcf9f46fff Mon Sep 17 00:00:00 2001 From: Guy1524 <35645466+Guy1524@users.noreply.github.com> Date: Wed, 1 Mar 2023 15:38:14 +0100 Subject: [PATCH 1087/1348] [util] Reduce maximum chunk size for WILD HEARTS. Co-authored-by: Blisto91 <47954800+Blisto91@users.noreply.github.com> --- src/util/config/config.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 68a3c7285..192983f97 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -721,6 +721,14 @@ namespace dxvk { { R"(\\bf10\.exe$)", {{ { "d3d9.maxFrameRate", "60" }, }} }, + /* WILD HEARTS™️ * + * D3D12 title using D3D11 device for * + * media texture creation, whereby a large * + * chunk size only slows down media * + * initialization */ + { R"(\\WILD HEARTS(_Trial)?\.exe$)", {{ + { "dxvk.maxChunkSize", "4" }, + }} }, }}; From 1c6fc7b5b8192f66003a9a3d2d75d81bc88846be Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Thu, 2 Mar 2023 02:06:02 +0100 Subject: [PATCH 1088/1348] [d3d9] Clamp stage and type in [G,S]etTextureStageState This is what happens on the Nvidia D3D9 driver. Dawn of Magic 2 calls SetTextureStageState with a stage > 7 and expects that to succeed. --- src/d3d9/d3d9_device.cpp | 21 ++++++++------------- src/d3d9/d3d9_stateblock.cpp | 3 +++ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 0cf65cf00..f606c8db1 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -2304,13 +2304,8 @@ namespace dxvk { if (unlikely(pValue == nullptr)) return D3DERR_INVALIDCALL; - *pValue = 0; - - if (unlikely(Stage >= caps::TextureStageCount)) - return D3DERR_INVALIDCALL; - - if (unlikely(dxvkType >= TextureStageStateCount)) - return D3DERR_INVALIDCALL; + Stage = std::min(Stage, DWORD(caps::TextureStageCount - 1)); + dxvkType = std::min(dxvkType, D3D9TextureStageStateTypes(DXVK_TSS_COUNT - 1)); *pValue = m_state.textureStages[Stage][dxvkType]; @@ -3876,14 +3871,14 @@ namespace dxvk { DWORD Stage, D3D9TextureStageStateTypes Type, DWORD Value) { + + // Clamp values instead of checking and returning INVALID_CALL + // Matches tests + Dawn of Magic 2 relies on it. + Stage = std::min(Stage, DWORD(caps::TextureStageCount - 1)); + Type = std::min(Type, D3D9TextureStageStateTypes(DXVK_TSS_COUNT - 1)); + D3D9DeviceLock lock = LockDevice(); - if (unlikely(Stage >= caps::TextureStageCount)) - return D3DERR_INVALIDCALL; - - if (unlikely(Type >= TextureStageStateCount)) - return D3DERR_INVALIDCALL; - if (unlikely(ShouldRecord())) return m_recorder->SetStateTextureStageState(Stage, Type, Value); diff --git a/src/d3d9/d3d9_stateblock.cpp b/src/d3d9/d3d9_stateblock.cpp index 9c0abba11..76ab1d645 100644 --- a/src/d3d9/d3d9_stateblock.cpp +++ b/src/d3d9/d3d9_stateblock.cpp @@ -213,6 +213,9 @@ namespace dxvk { DWORD Stage, D3D9TextureStageStateTypes Type, DWORD Value) { + Stage = std::min(Stage, DWORD(caps::TextureStageCount - 1)); + Type = std::min(Type, D3D9TextureStageStateTypes(DXVK_TSS_COUNT - 1)); + m_state.textureStages[Stage][Type] = Value; m_captures.flags.set(D3D9CapturedStateFlag::TextureStages); From 1acf88510928bec61e85d507791bc89ca67d734f Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 3 Mar 2023 00:13:55 +0000 Subject: [PATCH 1089/1348] [dxvk] Call SDL_Vulkan_LoadLibrary in getInstanceExtensions for SDL WSI Closes: #3275 --- src/dxvk/platform/dxvk_sdl2_exts.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dxvk/platform/dxvk_sdl2_exts.cpp b/src/dxvk/platform/dxvk_sdl2_exts.cpp index 701a3992b..13583aa77 100644 --- a/src/dxvk/platform/dxvk_sdl2_exts.cpp +++ b/src/dxvk/platform/dxvk_sdl2_exts.cpp @@ -13,6 +13,8 @@ namespace dxvk { DxvkNameSet DxvkPlatformExts::getInstanceExtensions() { + SDL_Vulkan_LoadLibrary(nullptr); + uint32_t extensionCount = 0; if (!SDL_Vulkan_GetInstanceExtensions(nullptr, &extensionCount, nullptr)) throw DxvkError(str::format("SDL2 WSI: Failed to get instance extension count. ", SDL_GetError())); From e430ff5cfda0e3b66300445047dbbfe9422d4787 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Mar 2023 17:13:03 +0100 Subject: [PATCH 1090/1348] [dxvk] Use small_vector to store query handles. --- src/dxvk/dxvk_gpu_query.cpp | 38 +++++++++++++++--------------------- src/dxvk/dxvk_gpu_query.h | 14 ++++++++----- src/util/util_small_vector.h | 11 +++++++++++ 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/dxvk/dxvk_gpu_query.cpp b/src/dxvk/dxvk_gpu_query.cpp index 426b58f6e..7ceb32d18 100644 --- a/src/dxvk/dxvk_gpu_query.cpp +++ b/src/dxvk/dxvk_gpu_query.cpp @@ -18,11 +18,8 @@ namespace dxvk { DxvkGpuQuery::~DxvkGpuQuery() { - if (m_handle.queryPool) - m_handle.allocator->freeQuery(m_handle); - - for (DxvkGpuQueryHandle handle : m_handles) - handle.allocator->freeQuery(handle); + for (size_t i = 0; i < m_handles.size(); i++) + m_handles[i].allocator->freeQuery(m_handles[i]); } @@ -34,15 +31,14 @@ namespace dxvk { DxvkGpuQueryStatus DxvkGpuQuery::getData(DxvkQueryData& queryData) const { queryData = DxvkQueryData(); - if (!m_ended) + // Callers must ensure that no begin call is pending when + // calling this. Given that, once the query is ended, we + // know that no other thread will access query state. + if (!m_ended.load(std::memory_order_acquire)) return DxvkGpuQueryStatus::Invalid; - - // Empty begin/end pair - if (!m_handle.queryPool) - return DxvkGpuQueryStatus::Available; - + // Get query data from all associated handles - DxvkGpuQueryStatus status = getDataForHandle(queryData, m_handle); + DxvkGpuQueryStatus status = DxvkGpuQueryStatus::Available; for (size_t i = 0; i < m_handles.size() && status == DxvkGpuQueryStatus::Available; i++) @@ -61,27 +57,25 @@ namespace dxvk { void DxvkGpuQuery::begin(const Rc& cmd) { - m_ended = false; + // Not useful to enforce a memory order here since + // only the false->true transition is defined. + m_ended.store(false, std::memory_order_relaxed); - cmd->trackGpuQuery(m_handle); - m_handle = DxvkGpuQueryHandle(); + for (size_t i = 0; i < m_handles.size(); i++) + cmd->trackGpuQuery(m_handles[i]); - for (const auto& handle : m_handles) - cmd->trackGpuQuery(handle); m_handles.clear(); } void DxvkGpuQuery::end() { - m_ended = true; + // Ensure that all prior writes are made available + m_ended.store(true, std::memory_order_release); } void DxvkGpuQuery::addQueryHandle(const DxvkGpuQueryHandle& handle) { - if (m_handle.queryPool) - m_handles.push_back(m_handle); - - m_handle = handle; + m_handles.push_back(handle); } diff --git a/src/dxvk/dxvk_gpu_query.h b/src/dxvk/dxvk_gpu_query.h index 0c45d1200..f23185634 100644 --- a/src/dxvk/dxvk_gpu_query.h +++ b/src/dxvk/dxvk_gpu_query.h @@ -1,8 +1,11 @@ #pragma once +#include #include #include +#include "../util/util_small_vector.h" + #include "dxvk_resource.h" namespace dxvk { @@ -149,7 +152,10 @@ namespace dxvk { * \returns Current query handle */ DxvkGpuQueryHandle handle() const { - return m_handle; + if (m_handles.empty()) + return DxvkGpuQueryHandle(); + + return m_handles.back(); } /** @@ -222,11 +228,9 @@ namespace dxvk { VkQueryType m_type; VkQueryControlFlags m_flags; uint32_t m_index; - bool m_ended; + std::atomic m_ended; - DxvkGpuQueryHandle m_handle; - - std::vector m_handles; + small_vector m_handles; DxvkGpuQueryStatus getDataForHandle( DxvkQueryData& queryData, diff --git a/src/util/util_small_vector.h b/src/util/util_small_vector.h index 3302f1c58..13ff1ac7e 100644 --- a/src/util/util_small_vector.h +++ b/src/util/util_small_vector.h @@ -90,6 +90,17 @@ namespace dxvk { ptr(--m_size)->~T(); } + void clear() { + for (size_t i = 0; i < m_size; i++) + ptr(i)->~T(); + + m_size = 0; + } + + bool empty() const { + return m_size == 0; + } + T& operator [] (size_t idx) { return *ptr(idx); } const T& operator [] (size_t idx) const { return *ptr(idx); } From 7f21a6c4913d16fb57786e40ede6bf5f53cd9f5f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 2 Mar 2023 21:12:24 +0100 Subject: [PATCH 1091/1348] [dxvk] Accumulate query data into query object And do so when adding additional query handles, in order to avoid allocating queries indefinitely if End is never called, which Halo:MCC supposedly does. Co-authored-by: Sam Edwards --- src/dxvk/dxvk_gpu_query.cpp | 96 +++++++++++++++++++++++++----------- src/dxvk/dxvk_gpu_query.h | 11 +++-- src/util/util_small_vector.h | 2 + 3 files changed, 77 insertions(+), 32 deletions(-) diff --git a/src/dxvk/dxvk_gpu_query.cpp b/src/dxvk/dxvk_gpu_query.cpp index 7ceb32d18..aaec6a0f3 100644 --- a/src/dxvk/dxvk_gpu_query.cpp +++ b/src/dxvk/dxvk_gpu_query.cpp @@ -28,7 +28,7 @@ namespace dxvk { } - DxvkGpuQueryStatus DxvkGpuQuery::getData(DxvkQueryData& queryData) const { + DxvkGpuQueryStatus DxvkGpuQuery::getData(DxvkQueryData& queryData) { queryData = DxvkQueryData(); // Callers must ensure that no begin call is pending when @@ -37,21 +37,21 @@ namespace dxvk { if (!m_ended.load(std::memory_order_acquire)) return DxvkGpuQueryStatus::Invalid; - // Get query data from all associated handles - DxvkGpuQueryStatus status = DxvkGpuQueryStatus::Available; - - for (size_t i = 0; i < m_handles.size() - && status == DxvkGpuQueryStatus::Available; i++) - status = getDataForHandle(queryData, m_handles[i]); + // Accumulate query data from all available queries + DxvkGpuQueryStatus status = this->accumulateQueryData(); // Treat non-precise occlusion queries as available // if we already know the result will be non-zero if ((status == DxvkGpuQueryStatus::Pending) && (m_type == VK_QUERY_TYPE_OCCLUSION) && !(m_flags & VK_QUERY_CONTROL_PRECISE_BIT) - && (queryData.occlusion.samplesPassed)) + && (m_queryData.occlusion.samplesPassed)) status = DxvkGpuQueryStatus::Available; - + + // Write back accumulated query data if the result is useful + if (status == DxvkGpuQueryStatus::Available) + queryData = m_queryData; + return status; } @@ -61,10 +61,15 @@ namespace dxvk { // only the false->true transition is defined. m_ended.store(false, std::memory_order_relaxed); + // Ideally we should have no queries left at this point, + // if we do, lifetime-track them with the command list. for (size_t i = 0; i < m_handles.size(); i++) cmd->trackGpuQuery(m_handles[i]); m_handles.clear(); + + // Reset accumulated query data + m_queryData = DxvkQueryData(); } @@ -75,14 +80,18 @@ namespace dxvk { void DxvkGpuQuery::addQueryHandle(const DxvkGpuQueryHandle& handle) { + // Already accumulate available queries here in case + // we already allocated a large number of queries + if (m_handles.size() >= m_handles.MinCapacity) + this->accumulateQueryData(); + m_handles.push_back(handle); } - DxvkGpuQueryStatus DxvkGpuQuery::getDataForHandle( - DxvkQueryData& queryData, - const DxvkGpuQueryHandle& handle) const { - DxvkQueryData tmpData; + DxvkGpuQueryStatus DxvkGpuQuery::accumulateQueryDataForHandle( + const DxvkGpuQueryHandle& handle) { + DxvkQueryData tmpData = { }; // Try to copy query data to temporary structure VkResult result = m_vkd->vkGetQueryPoolResults(m_vkd->device(), @@ -98,30 +107,30 @@ namespace dxvk { // Add numbers to the destination structure switch (m_type) { case VK_QUERY_TYPE_OCCLUSION: - queryData.occlusion.samplesPassed += tmpData.occlusion.samplesPassed; + m_queryData.occlusion.samplesPassed += tmpData.occlusion.samplesPassed; break; case VK_QUERY_TYPE_TIMESTAMP: - queryData.timestamp.time = tmpData.timestamp.time; + m_queryData.timestamp.time = tmpData.timestamp.time; break; case VK_QUERY_TYPE_PIPELINE_STATISTICS: - queryData.statistic.iaVertices += tmpData.statistic.iaVertices; - queryData.statistic.iaPrimitives += tmpData.statistic.iaPrimitives; - queryData.statistic.vsInvocations += tmpData.statistic.vsInvocations; - queryData.statistic.gsInvocations += tmpData.statistic.gsInvocations; - queryData.statistic.gsPrimitives += tmpData.statistic.gsPrimitives; - queryData.statistic.clipInvocations += tmpData.statistic.clipInvocations; - queryData.statistic.clipPrimitives += tmpData.statistic.clipPrimitives; - queryData.statistic.fsInvocations += tmpData.statistic.fsInvocations; - queryData.statistic.tcsPatches += tmpData.statistic.tcsPatches; - queryData.statistic.tesInvocations += tmpData.statistic.tesInvocations; - queryData.statistic.csInvocations += tmpData.statistic.csInvocations; + m_queryData.statistic.iaVertices += tmpData.statistic.iaVertices; + m_queryData.statistic.iaPrimitives += tmpData.statistic.iaPrimitives; + m_queryData.statistic.vsInvocations += tmpData.statistic.vsInvocations; + m_queryData.statistic.gsInvocations += tmpData.statistic.gsInvocations; + m_queryData.statistic.gsPrimitives += tmpData.statistic.gsPrimitives; + m_queryData.statistic.clipInvocations += tmpData.statistic.clipInvocations; + m_queryData.statistic.clipPrimitives += tmpData.statistic.clipPrimitives; + m_queryData.statistic.fsInvocations += tmpData.statistic.fsInvocations; + m_queryData.statistic.tcsPatches += tmpData.statistic.tcsPatches; + m_queryData.statistic.tesInvocations += tmpData.statistic.tesInvocations; + m_queryData.statistic.csInvocations += tmpData.statistic.csInvocations; break; case VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT: - queryData.xfbStream.primitivesWritten += tmpData.xfbStream.primitivesWritten; - queryData.xfbStream.primitivesNeeded += tmpData.xfbStream.primitivesNeeded; + m_queryData.xfbStream.primitivesWritten += tmpData.xfbStream.primitivesWritten; + m_queryData.xfbStream.primitivesNeeded += tmpData.xfbStream.primitivesNeeded; break; default: @@ -131,6 +140,37 @@ namespace dxvk { return DxvkGpuQueryStatus::Available; } + + + DxvkGpuQueryStatus DxvkGpuQuery::accumulateQueryData() { + DxvkGpuQueryStatus status = DxvkGpuQueryStatus::Available; + + // Process available queries and return them to the + // allocator if possible. This may help reduce the + // number of Vulkan queries in flight. + size_t queriesAvailable = 0; + + while (queriesAvailable < m_handles.size()) { + status = this->accumulateQueryDataForHandle(m_handles[queriesAvailable]); + + if (status != DxvkGpuQueryStatus::Available) + break; + + queriesAvailable += 1; + } + + if (queriesAvailable) { + for (size_t i = 0; i < queriesAvailable; i++) + m_handles[i].allocator->freeQuery(m_handles[i]); + + for (size_t i = queriesAvailable; i < m_handles.size(); i++) + m_handles[i - queriesAvailable] = m_handles[i]; + + m_handles.resize(m_handles.size() - queriesAvailable); + } + + return status; + } diff --git a/src/dxvk/dxvk_gpu_query.h b/src/dxvk/dxvk_gpu_query.h index f23185634..919d0e268 100644 --- a/src/dxvk/dxvk_gpu_query.h +++ b/src/dxvk/dxvk_gpu_query.h @@ -188,7 +188,7 @@ namespace dxvk { * \returns Current query status */ DxvkGpuQueryStatus getData( - DxvkQueryData& queryData) const; + DxvkQueryData& queryData); /** * \brief Begins query @@ -230,11 +230,14 @@ namespace dxvk { uint32_t m_index; std::atomic m_ended; + DxvkQueryData m_queryData = { }; + small_vector m_handles; - DxvkGpuQueryStatus getDataForHandle( - DxvkQueryData& queryData, - const DxvkGpuQueryHandle& handle) const; + DxvkGpuQueryStatus accumulateQueryDataForHandle( + const DxvkGpuQueryHandle& handle); + + DxvkGpuQueryStatus accumulateQueryData(); }; diff --git a/src/util/util_small_vector.h b/src/util/util_small_vector.h index 13ff1ac7e..48fe8bff7 100644 --- a/src/util/util_small_vector.h +++ b/src/util/util_small_vector.h @@ -9,6 +9,8 @@ namespace dxvk { using storage = std::aligned_storage_t; public: + constexpr static size_t MinCapacity = N; + small_vector() { } small_vector (const small_vector&) = delete; From 8ecd1b3b6b580b810eaea1ea18f566688031a6f6 Mon Sep 17 00:00:00 2001 From: Blisto91 <47954800+Blisto91@users.noreply.github.com> Date: Tue, 24 Jan 2023 22:03:08 +0100 Subject: [PATCH 1092/1348] [util] enableDialogMode for Codename Panzers Phase One/Two --- src/util/config/config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 192983f97..e3f5ab6fd 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -729,6 +729,11 @@ namespace dxvk { { R"(\\WILD HEARTS(_Trial)?\.exe$)", {{ { "dxvk.maxChunkSize", "4" }, }} }, + /* Codename Panzers Phase One/Two * + * Main menu won't render after intros */ + { R"(\\(PANZERS|PANZERS_Phase_2)\.exe$)", {{ + { "d3d9.enableDialogMode", "True" }, + }} }, }}; From 996acbe3f2eba97a6d3e725a8e7748aa0dd6764a Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Sat, 11 Feb 2023 21:39:05 +0000 Subject: [PATCH 1093/1348] [d3d9] Refactor state blocks to allocate dynamically. --- src/d3d9/d3d9_device.cpp | 22 +++---- src/d3d9/d3d9_device.h | 6 +- src/d3d9/d3d9_state.cpp | 28 ++++++--- src/d3d9/d3d9_state.h | 118 +++++++++++++++++++++++++---------- src/d3d9/d3d9_stateblock.cpp | 8 +-- src/d3d9/d3d9_stateblock.h | 14 ++--- 6 files changed, 127 insertions(+), 69 deletions(-) diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index f606c8db1..e8719d63c 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -5145,9 +5145,9 @@ namespace dxvk { if (CanSWVP()) return UploadSoftwareConstantSet(m_state.vsConsts, m_vsLayout); else - return UploadConstantSet(m_state.vsConsts, m_vsLayout, m_state.vertexShader); + return UploadConstantSet(m_state.vsConsts.get(), m_vsLayout, m_state.vertexShader); } else { - return UploadConstantSet (m_state.psConsts, m_psLayout, m_state.pixelShader); + return UploadConstantSet (m_state.psConsts.get(), m_psLayout, m_state.pixelShader); } } @@ -6255,7 +6255,7 @@ namespace dxvk { if (likely(!CanSWVP())) { UpdateVertexBoolSpec( - m_state.vsConsts.bConsts[0] & + m_state.vsConsts->bConsts[0] & m_consts[DxsoProgramType::VertexShader].meta.boolConstantMask); } else UpdateVertexBoolSpec(0); @@ -6283,7 +6283,7 @@ namespace dxvk { UpdatePixelShaderSamplerSpec(m_textureTypes, programInfo.minorVersion() >= 4 ? 0u : projected, fetch4); // For implicit samplers... UpdatePixelBoolSpec( - m_state.psConsts.bConsts[0] & + m_state.psConsts->bConsts[0] & m_consts[DxsoProgramType::PixelShader].meta.boolConstantMask); } else { @@ -6524,16 +6524,16 @@ namespace dxvk { void D3D9DeviceEx::SetVertexBoolBitfield(uint32_t idx, uint32_t mask, uint32_t bits) { - m_state.vsConsts.bConsts[idx] &= ~mask; - m_state.vsConsts.bConsts[idx] |= bits & mask; + m_state.vsConsts->bConsts[idx] &= ~mask; + m_state.vsConsts->bConsts[idx] |= bits & mask; m_consts[DxsoProgramTypes::VertexShader].dirty = true; } void D3D9DeviceEx::SetPixelBoolBitfield(uint32_t idx, uint32_t mask, uint32_t bits) { - m_state.psConsts.bConsts[idx] &= ~mask; - m_state.psConsts.bConsts[idx] |= bits & mask; + m_state.psConsts->bConsts[idx] &= ~mask; + m_state.psConsts->bConsts[idx] |= bits & mask; m_consts[DxsoProgramTypes::PixelShader].dirty = true; } @@ -7244,11 +7244,11 @@ namespace dxvk { for (uint32_t i = 0; i < caps::MaxStreams; i++) m_state.streamFreq[i] = 1; - for (uint32_t i = 0; i < m_state.textures.size(); i++) + for (uint32_t i = 0; i < m_state.textures->size(); i++) SetStateTexture(i, nullptr); EmitCs([ - cSize = m_state.textures.size() + cSize = m_state.textures->size() ](DxvkContext* ctx) { VkShaderStageFlags stage = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; @@ -7263,7 +7263,7 @@ namespace dxvk { m_depthTextures = 0; m_cubeTextures = 0; - auto& ss = m_state.samplerStates; + auto& ss = m_state.samplerStates.get(); for (uint32_t i = 0; i < ss.size(); i++) { auto& state = ss[i]; state[D3DSAMP_ADDRESSU] = D3DTADDRESS_WRAP; diff --git a/src/d3d9/d3d9_device.h b/src/d3d9/d3d9_device.h index 63e9fd476..bd379266d 100644 --- a/src/d3d9/d3d9_device.h +++ b/src/d3d9/d3d9_device.h @@ -1093,13 +1093,13 @@ namespace dxvk { return D3DERR_INVALIDCALL; if constexpr (ConstantType == D3D9ConstantType::Float) { - const float* source = set.fConsts[StartRegister].data; + const float* source = set->fConsts[StartRegister].data; const size_t size = Count * sizeof(Vector4); std::memcpy(pConstantData, source, size); } else if constexpr (ConstantType == D3D9ConstantType::Int) { - const int* source = set.iConsts[StartRegister].data; + const int* source = set->iConsts[StartRegister].data; const size_t size = Count * sizeof(Vector4i); std::memcpy(pConstantData, source, size); @@ -1112,7 +1112,7 @@ namespace dxvk { const uint32_t bit = (1u << bitIdx); - bool constValue = set.bConsts[arrayIdx] & bit; + bool constValue = set->bConsts[arrayIdx] & bit; pConstantData[i] = constValue ? TRUE : FALSE; } } diff --git a/src/d3d9/d3d9_state.cpp b/src/d3d9/d3d9_state.cpp index 2c32bef45..af749cf76 100644 --- a/src/d3d9/d3d9_state.cpp +++ b/src/d3d9/d3d9_state.cpp @@ -4,17 +4,25 @@ namespace dxvk { - D3D9CapturableState::D3D9CapturableState() { - for (uint32_t i = 0; i < streamFreq.size(); i++) - streamFreq[i] = 1; + template