[cmake] enable clang-cl and WoA builds (#348)

Compilation and CMake fixes for both Windows on ARM and clang-cl, meaning Windows can now be built on both MSVC and clang on both amd64 and aarch64.

Compiling on clang is *dramatically* faster so this should be useful for CI.

Co-authored-by: crueter <crueter@eden-emu.dev>
Co-authored-by: crueter <crueter@crueter.xyz>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/348
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie 2025-09-09 20:47:49 +02:00 committed by crueter
parent 428f136a75
commit 9d2681ecc9
Signed by: crueter
GPG key ID: 425ACD2D4830EBC6
276 changed files with 973 additions and 1010 deletions

View file

@ -123,7 +123,7 @@ Id RegAlloc::Alloc(bool is_long) {
if (use[reg]) {
continue;
}
num_regs = std::max(num_regs, reg + 1);
num_regs = (std::max)(num_regs, reg + 1);
use[reg] = true;
Id ret{};
ret.is_valid.Assign(1);

View file

@ -39,7 +39,7 @@ void EmitIAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::strin
// which may be overwritten by the result of the addition
if (IR::Inst * overflow{inst.GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp)}) {
// https://stackoverflow.com/questions/55468823/how-to-detect-integer-overflow-in-c
constexpr u32 s32_max{static_cast<u32>(std::numeric_limits<s32>::max())};
constexpr u32 s32_max{static_cast<u32>((std::numeric_limits<s32>::max)())};
const auto sub_a{fmt::format("{}u-{}", s32_max, a)};
const auto positive_result{fmt::format("int({})>int({})", b, sub_a)};
const auto negative_result{fmt::format("int({})<int({})", b, sub_a)};

View file

@ -314,9 +314,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
break;
case Stage::Compute:
stage_name = "cs";
const u32 local_x{std::max(program.workgroup_size[0], 1u)};
const u32 local_y{std::max(program.workgroup_size[1], 1u)};
const u32 local_z{std::max(program.workgroup_size[2], 1u)};
const u32 local_x{(std::max)(program.workgroup_size[0], 1u)};
const u32 local_y{(std::max)(program.workgroup_size[1], 1u)};
const u32 local_z{(std::max)(program.workgroup_size[2], 1u)};
header += fmt::format("layout(local_size_x={},local_size_y={},local_size_z={}) in;",
local_x, local_y, local_z);
break;

View file

@ -155,7 +155,7 @@ Id VarAlloc::Alloc(GlslVarType type) {
if (use_tracker.var_use[var]) {
continue;
}
use_tracker.num_used = std::max(use_tracker.num_used, var + 1);
use_tracker.num_used = (std::max)(use_tracker.num_used, var + 1);
use_tracker.var_use[var] = true;
Id ret{};
ret.is_valid.Assign(1);

View file

@ -366,7 +366,7 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) {
return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.draw_index));
case IR::Attribute::FrontFace:
return ctx.OpSelect(ctx.F32[1], ctx.OpLoad(ctx.U1, ctx.front_face),
ctx.OpBitcast(ctx.F32[1], ctx.Const(std::numeric_limits<u32>::max())),
ctx.OpBitcast(ctx.F32[1], ctx.Const((std::numeric_limits<u32>::max)())),
ctx.f32_zero_value);
case IR::Attribute::PointSpriteS:
return ctx.OpLoad(ctx.F32[1],

View file

@ -42,7 +42,7 @@ Id EmitIAdd32(EmitContext& ctx, IR::Inst* inst, Id a, Id b) {
SetSignFlag(ctx, inst, result);
if (IR::Inst * overflow{inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp)}) {
// https://stackoverflow.com/questions/55468823/how-to-detect-integer-overflow-in-c
constexpr u32 s32_max{static_cast<u32>(std::numeric_limits<s32>::max())};
constexpr u32 s32_max{static_cast<u32>((std::numeric_limits<s32>::max)())};
const Id is_positive{ctx.OpSGreaterThanEqual(ctx.U1, a, ctx.u32_zero_value)};
const Id sub_a{ctx.OpISub(ctx.U32[1], ctx.Const(s32_max), a)};

View file

@ -1593,7 +1593,7 @@ void EmitContext::DefineOutputs(const IR::Program& program) {
throw NotImplementedException("Storing ClipDistance in fragment stage");
}
if (profile.max_user_clip_distances > 0) {
const u32 used{std::min(profile.max_user_clip_distances, 8u)};
const u32 used{(std::min)(profile.max_user_clip_distances, 8u)};
const std::array<Id, 8> zero{f32_zero_value, f32_zero_value, f32_zero_value,
f32_zero_value, f32_zero_value, f32_zero_value,
f32_zero_value, f32_zero_value};

View file

@ -73,7 +73,7 @@ constexpr auto ENCODINGS{SortedEncodings()};
constexpr int WidestLeftBits() {
int bits{64};
for (const InstEncoding& encoding : ENCODINGS) {
bits = std::min(bits, std::countr_zero(encoding.mask_value.mask));
bits = (std::min)(bits, std::countr_zero(encoding.mask_value.mask));
}
return 64 - bits;
}
@ -87,7 +87,7 @@ constexpr size_t ToFastLookupIndex(u64 value) {
constexpr size_t FastLookupSize() {
size_t max_width{};
for (const InstEncoding& encoding : ENCODINGS) {
max_width = std::max(max_width, ToFastLookupIndex(encoding.mask_value.mask));
max_width = (std::max)(max_width, ToFastLookupIndex(encoding.mask_value.mask));
}
return max_width + 1;
}

View file

@ -60,28 +60,28 @@ std::pair<f64, f64> ClampBounds(DestFormat format, bool is_signed) {
if (is_signed) {
switch (format) {
case DestFormat::I16:
return {static_cast<f64>(std::numeric_limits<s16>::max()),
static_cast<f64>(std::numeric_limits<s16>::min())};
return {static_cast<f64>((std::numeric_limits<s16>::max)()),
static_cast<f64>((std::numeric_limits<s16>::min)())};
case DestFormat::I32:
return {static_cast<f64>(std::numeric_limits<s32>::max()),
static_cast<f64>(std::numeric_limits<s32>::min())};
return {static_cast<f64>((std::numeric_limits<s32>::max)()),
static_cast<f64>((std::numeric_limits<s32>::min)())};
case DestFormat::I64:
return {static_cast<f64>(std::numeric_limits<s64>::max()),
static_cast<f64>(std::numeric_limits<s64>::min())};
return {static_cast<f64>((std::numeric_limits<s64>::max)()),
static_cast<f64>((std::numeric_limits<s64>::min)())};
default:
break;
}
} else {
switch (format) {
case DestFormat::I16:
return {static_cast<f64>(std::numeric_limits<u16>::max()),
static_cast<f64>(std::numeric_limits<u16>::min())};
return {static_cast<f64>((std::numeric_limits<u16>::max)()),
static_cast<f64>((std::numeric_limits<u16>::min)())};
case DestFormat::I32:
return {static_cast<f64>(std::numeric_limits<u32>::max()),
static_cast<f64>(std::numeric_limits<u32>::min())};
return {static_cast<f64>((std::numeric_limits<u32>::max)()),
static_cast<f64>((std::numeric_limits<u32>::min)())};
case DestFormat::I64:
return {static_cast<f64>(std::numeric_limits<u64>::max()),
static_cast<f64>(std::numeric_limits<u64>::min())};
return {static_cast<f64>((std::numeric_limits<u64>::max)()),
static_cast<f64>((std::numeric_limits<u64>::min)())};
default:
break;
}

View file

@ -114,9 +114,9 @@ void I2F(TranslatorVisitor& v, u64 insn, IR::U32U64 src) {
// Only negate if the input isn't the lowest value
IR::U1 is_least;
if (src_bitsize == 64) {
is_least = v.ir.IEqual(src, v.ir.Imm64(std::numeric_limits<s64>::min()));
is_least = v.ir.IEqual(src, v.ir.Imm64((std::numeric_limits<s64>::min)()));
} else if (src_bitsize == 32) {
is_least = v.ir.IEqual(src, v.ir.Imm32(std::numeric_limits<s32>::min()));
is_least = v.ir.IEqual(src, v.ir.Imm32((std::numeric_limits<s32>::min)()));
} else {
const IR::U32 least_value{v.ir.Imm32(-(1 << (src_bitsize - 1)))};
is_least = v.ir.IEqual(src, least_value);

View file

@ -336,7 +336,7 @@ IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b
}
result.stage = Stage::VertexB;
result.info = vertex_a.info;
result.local_memory_size = std::max(vertex_a.local_memory_size, vertex_b.local_memory_size);
result.local_memory_size = (std::max)(vertex_a.local_memory_size, vertex_b.local_memory_size);
result.info.loads.mask |= vertex_b.info.loads.mask;
result.info.stores.mask |= vertex_b.info.stores.mask;

View file

@ -509,7 +509,7 @@ void VisitUsages(Info& info, IR::Inst& inst) {
u32 element_size = GetElementSize(info.used_constant_buffer_types, inst.GetOpcode());
u32& size{info.constant_buffer_used_sizes[index.U32()]};
if (offset.IsImmediate()) {
size = Common::AlignUp(std::max(size, offset.U32() + element_size), 16u);
size = Common::AlignUp((std::max)(size, offset.U32() + element_size), 16u);
} else {
size = 0x10'000;
}

View file

@ -905,7 +905,7 @@ void FoldConstBuffer(Environment& env, IR::Block& block, IR::Inst& inst) {
}
void FoldDriverConstBuffer(Environment& env, IR::Block& block, IR::Inst& inst, u32 which_bank,
u32 offset_start = 0, u32 offset_end = std::numeric_limits<u16>::max()) {
u32 offset_start = 0, u32 offset_end = (std::numeric_limits<u16>::max)()) {
const IR::Value bank{inst.Arg(0)};
const IR::Value offset{inst.Arg(1)};
if (!bank.IsImmediate() || !offset.IsImmediate()) {

View file

@ -517,11 +517,11 @@ void PatchTexelFetch(IR::Block& block, IR::Inst& inst, TexturePixelFormat pixel_
case TexturePixelFormat::A8B8G8R8_SNORM:
case TexturePixelFormat::R8G8_SNORM:
case TexturePixelFormat::R8_SNORM:
return 1.f / std::numeric_limits<char>::max();
return 1.f / (std::numeric_limits<char>::max)();
case TexturePixelFormat::R16G16B16A16_SNORM:
case TexturePixelFormat::R16G16_SNORM:
case TexturePixelFormat::R16_SNORM:
return 1.f / std::numeric_limits<short>::max();
return 1.f / (std::numeric_limits<short>::max)();
default:
throw InvalidArgument("Invalid texture pixel format");
}