mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Fix Windows ARM64 build: disable x86 asm in StormLib's libtomcrypt
StormLib's bundled libtomcrypt uses x86 inline assembly (bswapl/movl) gated by __MINGW32__, which is defined on CLANGARM64 too. Pass -DLTC_NO_BSWAP to force portable C byte-swap fallback.
This commit is contained in:
parent
9b90ab0429
commit
7ca9caa212
6 changed files with 26 additions and 89 deletions
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
|
|
@ -195,10 +195,14 @@ jobs:
|
|||
shell: msys2 {0}
|
||||
run: |
|
||||
git clone --depth 1 https://github.com/ladislav-zezula/StormLib.git /tmp/StormLib
|
||||
# Disable x86 inline asm in bundled libtomcrypt (bswapl/movl) —
|
||||
# __MINGW32__ is defined on CLANGARM64 which incorrectly enables x86 asm
|
||||
cmake -S /tmp/StormLib -B /tmp/StormLib/build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" \
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DCMAKE_C_FLAGS="-DLTC_NO_BSWAP" \
|
||||
-DCMAKE_CXX_FLAGS="-DLTC_NO_BSWAP"
|
||||
cmake --build /tmp/StormLib/build --parallel $(nproc)
|
||||
cmake --install /tmp/StormLib/build
|
||||
|
||||
|
|
|
|||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
|
|
@ -256,10 +256,14 @@ jobs:
|
|||
shell: msys2 {0}
|
||||
run: |
|
||||
git clone --depth 1 https://github.com/ladislav-zezula/StormLib.git /tmp/StormLib
|
||||
# Disable x86 inline asm in bundled libtomcrypt (bswapl/movl) —
|
||||
# __MINGW32__ is defined on CLANGARM64 which incorrectly enables x86 asm
|
||||
cmake -S /tmp/StormLib -B /tmp/StormLib/build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX="$MINGW_PREFIX" \
|
||||
-DBUILD_SHARED_LIBS=OFF
|
||||
-DBUILD_SHARED_LIBS=OFF \
|
||||
-DCMAKE_C_FLAGS="-DLTC_NO_BSWAP" \
|
||||
-DCMAKE_CXX_FLAGS="-DLTC_NO_BSWAP"
|
||||
cmake --build /tmp/StormLib/build --parallel $(nproc)
|
||||
cmake --install /tmp/StormLib/build
|
||||
|
||||
|
|
|
|||
|
|
@ -478,7 +478,6 @@ private:
|
|||
// Helper to allocate descriptor sets
|
||||
VkDescriptorSet allocateMaterialSet();
|
||||
VkDescriptorSet allocateBoneSet();
|
||||
void preallocateBoneBuffers(M2Instance& instance);
|
||||
|
||||
// Helper to destroy model GPU resources
|
||||
void destroyModelGPU(M2ModelGPU& model);
|
||||
|
|
|
|||
|
|
@ -657,9 +657,9 @@ private:
|
|||
bool wireframeMode = false;
|
||||
bool frustumCulling = true;
|
||||
bool portalCulling = false; // Disabled by default - needs debugging
|
||||
bool distanceCulling = true; // Enabled with active-group exemption to prevent floor disappearing
|
||||
float maxGroupDistance = 800.0f;
|
||||
float maxGroupDistanceSq = 640000.0f; // maxGroupDistance^2
|
||||
bool distanceCulling = false; // Disabled - causes ground to disappear
|
||||
float maxGroupDistance = 500.0f;
|
||||
float maxGroupDistanceSq = 250000.0f; // maxGroupDistance^2
|
||||
uint32_t lastDrawCalls = 0;
|
||||
mutable uint32_t lastPortalCulledGroups = 0;
|
||||
mutable uint32_t lastDistanceCulledGroups = 0;
|
||||
|
|
|
|||
|
|
@ -767,38 +767,6 @@ VkDescriptorSet M2Renderer::allocateBoneSet() {
|
|||
return set;
|
||||
}
|
||||
|
||||
void M2Renderer::preallocateBoneBuffers(M2Instance& instance) {
|
||||
if (!vkCtx_) return;
|
||||
for (int fi = 0; fi < 2; fi++) {
|
||||
if (instance.boneBuffer[fi]) continue; // already allocated
|
||||
VkBufferCreateInfo bci{VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
|
||||
bci.size = 128 * sizeof(glm::mat4); // max 128 bones
|
||||
bci.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
VmaAllocationCreateInfo aci{};
|
||||
aci.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
|
||||
aci.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||
VmaAllocationInfo allocInfo{};
|
||||
vmaCreateBuffer(vkCtx_->getAllocator(), &bci, &aci,
|
||||
&instance.boneBuffer[fi], &instance.boneAlloc[fi], &allocInfo);
|
||||
instance.boneMapped[fi] = allocInfo.pMappedData;
|
||||
|
||||
instance.boneSet[fi] = allocateBoneSet();
|
||||
if (instance.boneSet[fi]) {
|
||||
VkDescriptorBufferInfo bufInfo{};
|
||||
bufInfo.buffer = instance.boneBuffer[fi];
|
||||
bufInfo.offset = 0;
|
||||
bufInfo.range = bci.size;
|
||||
VkWriteDescriptorSet write{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET};
|
||||
write.dstSet = instance.boneSet[fi];
|
||||
write.dstBinding = 0;
|
||||
write.descriptorCount = 1;
|
||||
write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
write.pBufferInfo = &bufInfo;
|
||||
vkUpdateDescriptorSets(vkCtx_->getDevice(), 1, &write, 0, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// M2 collision mesh: build spatial grid + classify triangles
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -1647,11 +1615,6 @@ uint32_t M2Renderer::createInstance(uint32_t modelId, const glm::vec3& position,
|
|||
instance.variationTimer = 3000.0f + static_cast<float>(rand() % 8000);
|
||||
}
|
||||
|
||||
// Pre-allocate bone SSBOs so first render frame doesn't hitch
|
||||
if (mdlRef.hasAnimation && !mdlRef.disableAnimation) {
|
||||
preallocateBoneBuffers(instance);
|
||||
}
|
||||
|
||||
instances.push_back(instance);
|
||||
size_t idx = instances.size() - 1;
|
||||
instanceIndexById[instance.id] = idx;
|
||||
|
|
@ -1685,8 +1648,6 @@ uint32_t M2Renderer::createInstanceWithMatrix(uint32_t modelId, const glm::mat4&
|
|||
}
|
||||
}
|
||||
|
||||
const auto& mdlRef = models[modelId];
|
||||
|
||||
M2Instance instance;
|
||||
instance.id = nextInstanceId++;
|
||||
instance.modelId = modelId;
|
||||
|
|
@ -1696,24 +1657,20 @@ uint32_t M2Renderer::createInstanceWithMatrix(uint32_t modelId, const glm::mat4&
|
|||
instance.modelMatrix = modelMatrix;
|
||||
instance.invModelMatrix = glm::inverse(modelMatrix);
|
||||
glm::vec3 localMin, localMax;
|
||||
getTightCollisionBounds(mdlRef, localMin, localMax);
|
||||
getTightCollisionBounds(models[modelId], localMin, localMax);
|
||||
transformAABB(instance.modelMatrix, localMin, localMax, instance.worldBoundsMin, instance.worldBoundsMax);
|
||||
// Initialize animation
|
||||
if (mdlRef.hasAnimation && !mdlRef.disableAnimation && !mdlRef.sequences.empty()) {
|
||||
const auto& mdl2 = models[modelId];
|
||||
if (mdl2.hasAnimation && !mdl2.disableAnimation && !mdl2.sequences.empty()) {
|
||||
instance.currentSequenceIndex = 0;
|
||||
instance.idleSequenceIndex = 0;
|
||||
instance.animDuration = static_cast<float>(mdlRef.sequences[0].duration);
|
||||
instance.animTime = static_cast<float>(rand() % std::max(1u, mdlRef.sequences[0].duration));
|
||||
instance.animDuration = static_cast<float>(mdl2.sequences[0].duration);
|
||||
instance.animTime = static_cast<float>(rand() % std::max(1u, mdl2.sequences[0].duration));
|
||||
instance.variationTimer = 3000.0f + static_cast<float>(rand() % 8000);
|
||||
} else {
|
||||
instance.animTime = static_cast<float>(rand()) / RAND_MAX * 10000.0f;
|
||||
}
|
||||
|
||||
// Pre-allocate bone SSBOs so first render frame doesn't hitch
|
||||
if (mdlRef.hasAnimation && !mdlRef.disableAnimation) {
|
||||
preallocateBoneBuffers(instance);
|
||||
}
|
||||
|
||||
instances.push_back(instance);
|
||||
size_t idx = instances.size() - 1;
|
||||
instanceIndexById[instance.id] = idx;
|
||||
|
|
@ -1854,11 +1811,7 @@ void M2Renderer::update(float deltaTime, const glm::vec3& cameraPos, const glm::
|
|||
|
||||
// Cache camera state for frustum-culling bone computation
|
||||
cachedCamPos_ = cameraPos;
|
||||
const size_t animInstCount = instances.size();
|
||||
const float maxRenderDistance = (animInstCount > 3000) ? 600.0f
|
||||
: (animInstCount > 2000) ? 800.0f
|
||||
: (animInstCount > 1000) ? 1400.0f
|
||||
: 2800.0f;
|
||||
const float maxRenderDistance = (instances.size() > 2000) ? 800.0f : 2800.0f;
|
||||
cachedMaxRenderDistSq_ = maxRenderDistance * maxRenderDistance;
|
||||
|
||||
// Build frustum for culling bones
|
||||
|
|
@ -2128,12 +2081,8 @@ void M2Renderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const
|
|||
|
||||
lastDrawCallCount = 0;
|
||||
|
||||
// Adaptive render distance: tiered for performance without excessive pop-in
|
||||
const size_t instCount = instances.size();
|
||||
const float maxRenderDistance = (instCount > 3000) ? 250.0f
|
||||
: (instCount > 2000) ? 400.0f
|
||||
: (instCount > 1000) ? 600.0f
|
||||
: 1000.0f;
|
||||
// Adaptive render distance: balanced for performance without excessive pop-in
|
||||
const float maxRenderDistance = (instances.size() > 2000) ? 350.0f : 1000.0f;
|
||||
const float maxRenderDistanceSq = maxRenderDistance * maxRenderDistance;
|
||||
const float fadeStartFraction = 0.75f;
|
||||
const glm::vec3 camPos = camera.getPosition();
|
||||
|
|
|
|||
|
|
@ -1319,9 +1319,6 @@ void WMORenderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const
|
|||
bool doFrustumCull = false; // Temporarily disabled: can over-cull world WMOs
|
||||
bool doDistanceCull = distanceCulling;
|
||||
|
||||
// Cache active group info for distance-cull exemption (player's current WMO group)
|
||||
const auto activeGroupCopy = activeGroup_;
|
||||
|
||||
auto cullInstance = [&](size_t instIdx) -> InstanceDrawList {
|
||||
if (instIdx >= instances.size()) return InstanceDrawList{};
|
||||
const auto& instance = instances[instIdx];
|
||||
|
|
@ -1332,9 +1329,6 @@ void WMORenderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const
|
|||
InstanceDrawList result;
|
||||
result.instanceIndex = instIdx;
|
||||
|
||||
// Check if this instance is the one the player is standing in
|
||||
bool isActiveInstance = activeGroupCopy.isValid() && activeGroupCopy.instanceIdx == instIdx;
|
||||
|
||||
// Portal-based visibility
|
||||
std::unordered_set<uint32_t> portalVisibleGroups;
|
||||
bool usePortalCulling = doPortalCull && !model.portals.empty() && !model.portalRefs.empty();
|
||||
|
|
@ -1355,24 +1349,11 @@ void WMORenderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const
|
|||
const auto& [gMin, gMax] = instance.worldGroupBounds[gi];
|
||||
|
||||
if (doDistanceCull) {
|
||||
// Never cull the group the player is standing in or its portal neighbors
|
||||
bool isExempt = false;
|
||||
if (isActiveInstance) {
|
||||
if (static_cast<int32_t>(gi) == activeGroupCopy.groupIdx) {
|
||||
isExempt = true;
|
||||
} else {
|
||||
for (uint32_t ng : activeGroupCopy.neighborGroups) {
|
||||
if (ng == static_cast<uint32_t>(gi)) { isExempt = true; break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isExempt) {
|
||||
glm::vec3 closestPoint = glm::clamp(camPos, gMin, gMax);
|
||||
float distSq = glm::dot(closestPoint - camPos, closestPoint - camPos);
|
||||
if (distSq > maxGroupDistanceSq) {
|
||||
result.distanceCulled++;
|
||||
continue;
|
||||
}
|
||||
glm::vec3 closestPoint = glm::clamp(camPos, gMin, gMax);
|
||||
float distSq = glm::dot(closestPoint - camPos, closestPoint - camPos);
|
||||
if (distSq > 250000.0f) {
|
||||
result.distanceCulled++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue