What exactly does that error even come from? The message isn't exactly helpful and our use of std::optional is generally fairly basic, but I don't want to remove it for the sake of non-default build environments, especially without understanding what the problem is.
What info do you need? I'm happy to help!
I made a fully static LLVM/Clang toolchain which uses the 22.x branch from the LLVM project:
https://github.com/NTULINUX/llvm-mingw/releases/tag/Polly-03082026
You can easily reproduce this issue with that binary toolchain. Just be sure to update your $PATH.
If someone is interested in a patch for 2.7.1 for this issue, this is what AI suggested to me and solves this issue with the latest Clang/LLVM 22 llvm-mingw toolchain for me:
--- a/src/dxvk/dxvk_pipemanager.cpp 2026-03-01 15:59:36.414718665 +0100
+++ b/src/dxvk/dxvk_pipemanager.cpp 2026-03-01 16:13:00.338026808 +0100
@@ -23,7 +23,7 @@ namespace dxvk {
std::unique_lock lock(m_lock);
this->startWorkers();
- m_tasksTotal += 1;
+ m_tasksTotal.fetch_add(1, std::memory_order_relaxed);
m_buckets[uint32_t(priority)].queue.emplace(library);
notifyWorkers(priority);
@@ -38,7 +38,7 @@ namespace dxvk {
this->startWorkers();
pipeline->acquirePipeline();
- m_tasksTotal += 1;
+ m_tasksTotal.fetch_add(1, std::memory_order_relaxed);
m_buckets[uint32_t(priority)].queue.emplace(pipeline, state);
notifyWorkers(priority);
@@ -165,7 +165,7 @@ namespace dxvk {
entry.graphicsPipeline->releasePipeline();
}
- m_tasksCompleted += 1;
+ m_tasksCompleted.fetch_add(1, std::memory_order_relaxed);
}
}
@@ -193,9 +193,9 @@ namespace dxvk {
const DxvkComputePipelineShaders& shaders) {
if (shaders.cs == nullptr)
return nullptr;
-
+
std::lock_guard<dxvk::mutex> lock(m_mutex);
-
+
auto pair = m_computePipelines.find(shaders);
if (pair != m_computePipelines.end())
return &pair->second;
@@ -205,11 +205,9 @@ namespace dxvk {
auto library = findPipelineLibraryLocked(key);
- auto iter = m_computePipelines.emplace(
- std::piecewise_construct,
- std::tuple(shaders),
- std::tuple(m_device, this, shaders, library));
- return &iter.first->second;
+ auto result = m_computePipelines.try_emplace(
+ shaders, m_device, this, shaders, library);
+ return &result.first->second;
}
@@ -217,9 +215,9 @@ namespace dxvk {
const DxvkGraphicsPipelineShaders& shaders) {
if (shaders.vs == nullptr)
return nullptr;
-
+
std::lock_guard<dxvk::mutex> lock(m_mutex);
-
+
auto pair = m_graphicsPipelines.find(shaders);
if (pair != m_graphicsPipelines.end())
return &pair->second;
@@ -257,11 +255,9 @@ namespace dxvk {
}
}
- auto iter = m_graphicsPipelines.emplace(
- std::piecewise_construct,
- std::tuple(shaders),
- std::tuple(m_device, this, shaders, vsLibrary, fsLibrary));
- return &iter.first->second;
+ auto result = m_graphicsPipelines.try_emplace(
+ shaders, m_device, this, shaders, vsLibrary, fsLibrary);
+ return &result.first->second;
}
@@ -276,15 +272,8 @@ namespace dxvk {
const DxvkGraphicsPipelineVertexInputState& state) {
std::lock_guard<dxvk::mutex> 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));
- return &iter.first->second;
+ auto result = m_vertexInputLibraries.try_emplace(state, m_device, state);
+ return &result.first->second;
}
@@ -292,15 +281,8 @@ namespace dxvk {
const DxvkGraphicsPipelineFragmentOutputState& state) {
std::lock_guard<dxvk::mutex> 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));
- return &iter.first->second;
+ auto result = m_fragmentOutputLibraries.try_emplace(state, m_device, state);
+ return &result.first->second;
}
@@ -352,39 +334,22 @@ namespace dxvk {
const DxvkDescriptorSetLayout* DxvkPipelineManager::createDescriptorSetLayout(
const DxvkDescriptorSetLayoutKey& 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;
+ auto result = m_descriptorSetLayouts.try_emplace(key, m_device, key);
+ return &result.first->second;
}
const DxvkPipelineLayout* DxvkPipelineManager::createPipelineLayout(
const DxvkPipelineLayoutKey& key) {
- auto pair = m_pipelineLayouts.find(key);
- if (pair != m_pipelineLayouts.end())
- return &pair->second;
-
- auto iter = m_pipelineLayouts.emplace(
- std::piecewise_construct,
- std::tuple(key),
- std::tuple(m_device, key));
- return &iter.first->second;
+ auto result = m_pipelineLayouts.try_emplace(key, m_device, key);
+ return &result.first->second;
}
DxvkShaderPipelineLibrary* DxvkPipelineManager::createPipelineLibraryLocked(
const DxvkShaderPipelineLibraryKey& key) {
- auto iter = m_shaderLibraries.emplace(
- std::piecewise_construct,
- std::tuple(key),
- std::tuple(m_device, this, key));
- return &iter.first->second;
+ auto result = m_shaderLibraries.try_emplace(key, m_device, this, key);
+ return &result.first->second;
}
@@ -392,11 +357,8 @@ namespace dxvk {
std::lock_guard<dxvk::mutex> lock(m_mutex);
DxvkShaderPipelineLibraryKey key;
- auto iter = m_shaderLibraries.emplace(
- std::piecewise_construct,
- std::tuple(),
- std::tuple(m_device, this, key));
- return &iter.first->second;
+ auto result = m_shaderLibraries.try_emplace(key, m_device, this, key);
+ return &result.first->second;
}
I mean that patch is obviously complete garbage like everything generated by AI, but I guess the problem is that... tuple construction doesn't work for some stupid reason?
I really don't have time to investigate weird issues with non-default toolchains right now, but this doesn't really make an awful lot of sense.
I hope you find time eventually because there won't be anymore updates to Clang 21, and GCC takes a dump when you throw AVX instructions at it in a MinGW environment. Been a problem for over a decade and it hasn't gotten any better since. AVX is a good thing.
This is how someone fixed it here:
https://github.com/bitcoin-core/libmultiprocess/commit/22bec918c97d32660c4694c3a8b5af4cdbb88481
It's also possible the LLVM devs will fix the behavior eventually, I'm not sure if this is by design though.
OK, that explains what the issue is and boils it down to something I can eventually work with.
I don't think it is illegal to use empty tuples for piecewise_construct though, so this probably shouldn't be happening in the first place.
Been a problem for over a decade and it hasn't gotten any better since.
I'm painfully aware, but it's low priority because a) our default builds will need to support non-AVX CPUs anyway and b) AVX does next to nothing for DXVK in general. Out of all the "new" instruction sets I'd guess that BMI is the most interesting one.
SWEET! Also, good to know!
You're awesome!
Nothing extracted yet.
https://github.com/llvm/llvm-project/issues/167709#issuecomment-4021564275
This is supposedly fixed in the
release/22.xbranch however I am still getting this issue. I am not sure if this is strictly an LLVM/Clang bug still or an issue with DXVK so I am posting this here as well.Thanks!