Merge remote-tracking branch 'origin/master' into sdl_platform

This commit is contained in:
2025-06-17 14:19:46 +03:00
6 changed files with 72 additions and 12 deletions

View File

@@ -209,8 +209,8 @@ public:
bool Get(const int32 index) const bool Get(const int32 index) const
{ {
ASSERT(index >= 0 && index < _count); ASSERT(index >= 0 && index < _count);
const ItemType offset = index / sizeof(ItemType); const ItemType offset = index / 64;
const ItemType bitMask = (ItemType)(int32)(1 << (index & ((int32)sizeof(ItemType) - 1))); const ItemType bitMask = 1ull << (index & 63ull);
const ItemType item = ((ItemType*)_allocation.Get())[offset]; const ItemType item = ((ItemType*)_allocation.Get())[offset];
return (item & bitMask) != 0; return (item & bitMask) != 0;
} }
@@ -223,13 +223,13 @@ public:
void Set(const int32 index, const bool value) void Set(const int32 index, const bool value)
{ {
ASSERT(index >= 0 && index < _count); ASSERT(index >= 0 && index < _count);
const ItemType offset = index / sizeof(ItemType); const ItemType offset = index / 64;
const ItemType bitMask = (ItemType)(int32)(1 << (index & ((int32)sizeof(ItemType) - 1))); const ItemType bitMask = 1ull << (index & 63ull);
ItemType& item = ((ItemType*)_allocation.Get())[offset]; ItemType& item = ((ItemType*)_allocation.Get())[offset];
if (value) if (value)
item |= bitMask; item |= bitMask; // Set the bit
else else
item &= ~bitMask; // Clear the bit item &= ~bitMask; // Unset the bit
} }
public: public:

View File

@@ -26,6 +26,8 @@
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS \ #define PRAGMA_ENABLE_DEPRECATION_WARNINGS \
_Pragma("clang diagnostic pop") _Pragma("clang diagnostic pop")
#define PRAGMA_DISABLE_OPTIMIZATION
#define PRAGMA_ENABLE_OPTIMIZATION
#pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wswitch"
#pragma clang diagnostic ignored "-Wmacro-redefined" #pragma clang diagnostic ignored "-Wmacro-redefined"
@@ -54,6 +56,8 @@
#define OFFSET_OF(X, Y) __builtin_offsetof(X, Y) #define OFFSET_OF(X, Y) __builtin_offsetof(X, Y)
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS #define PRAGMA_DISABLE_DEPRECATION_WARNINGS
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS #define PRAGMA_ENABLE_DEPRECATION_WARNINGS
#define PRAGMA_DISABLE_OPTIMIZATION
#define PRAGMA_ENABLE_OPTIMIZATION
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
@@ -86,6 +90,8 @@
__pragma(warning(disable: 4996)) __pragma(warning(disable: 4996))
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS \ #define PRAGMA_ENABLE_DEPRECATION_WARNINGS \
__pragma (warning(pop)) __pragma (warning(pop))
#define PRAGMA_DISABLE_OPTIMIZATION __pragma(optimize("", off))
#define PRAGMA_ENABLE_OPTIMIZATION __pragma(optimize("", on))
#pragma warning(disable: 4251) #pragma warning(disable: 4251)

View File

@@ -630,6 +630,23 @@ GPUTask* GPUTexture::UploadMipMapAsync(const BytesContainer& data, int32 mipInde
return task; return task;
} }
bool GPUTexture::UploadData(TextureData& data, bool copyData)
{
if (!IsAllocated())
return true;
if (data.Width != Width() || data.Height != Height() || data.Depth != Depth() || data.GetArraySize() != ArraySize() || data.Format != Format())
return true;
for (int32 arrayIndex = 0; arrayIndex < ArraySize(); arrayIndex++)
{
for (int32 mipLevel = 0; mipLevel < MipLevels(); mipLevel++)
{
TextureMipData* mip = data.GetData(arrayIndex, mipLevel);
UploadMipMapAsync(mip->Data, mipLevel, mip->RowPitch, mip->DepthPitch, copyData);
}
}
return false;
}
class TextureDownloadDataTask : public ThreadPoolTask class TextureDownloadDataTask : public ThreadPoolTask
{ {
private: private:

View File

@@ -499,7 +499,7 @@ public:
/// <summary> /// <summary>
/// Uploads mip map data to the GPU. Creates async GPU task. /// Uploads mip map data to the GPU. Creates async GPU task.
/// </summary> /// </summary>
/// <param name="data">Data to upload (it must be valid for the next a few frames due to GPU latency and async works executing)</param> /// <param name="data">Data to upload, it must match texture dimensions. It must be valid for the next couple of frames due to GPU async task latency or use data copy.</param>
/// <param name="mipIndex">Mip level index.</param> /// <param name="mipIndex">Mip level index.</param>
/// <param name="copyData">If true, the data will be copied to the async execution task instead of using the input pointer provided.</param> /// <param name="copyData">If true, the data will be copied to the async execution task instead of using the input pointer provided.</param>
/// <returns>Created async task or null if cannot.</returns> /// <returns>Created async task or null if cannot.</returns>
@@ -508,7 +508,7 @@ public:
/// <summary> /// <summary>
/// Uploads mip map data to the GPU. Creates async GPU task. /// Uploads mip map data to the GPU. Creates async GPU task.
/// </summary> /// </summary>
/// <param name="data">Data to upload (it must be valid for the next a few frames due to GPU latency and async works executing)</param> /// <param name="data">Data to upload, it must match texture dimensions. It must be valid for the next couple of frames due to GPU async task latency or use data copy.</param>
/// <param name="mipIndex">Mip level index.</param> /// <param name="mipIndex">Mip level index.</param>
/// <param name="rowPitch">The data row pitch.</param> /// <param name="rowPitch">The data row pitch.</param>
/// <param name="slicePitch">The data slice pitch.</param> /// <param name="slicePitch">The data slice pitch.</param>
@@ -516,6 +516,14 @@ public:
/// <returns>Created async task or null if cannot.</returns> /// <returns>Created async task or null if cannot.</returns>
GPUTask* UploadMipMapAsync(const BytesContainer& data, int32 mipIndex, int32 rowPitch, int32 slicePitch, bool copyData = false); GPUTask* UploadMipMapAsync(const BytesContainer& data, int32 mipIndex, int32 rowPitch, int32 slicePitch, bool copyData = false);
/// <summary>
/// Uploads texture data to the GPU. Actual data copy to the GPU memory is performed via async task.
/// </summary>
/// <param name="data">Data to upload, it must match texture dimensions. It must be valid for the next couple of frames due to GPU async task latency or use data copy.</param>
/// <param name="copyData">If true, the data will be copied to the async execution task instead of using the input pointer provided.</param>
/// <returns>True if cannot upload data, otherwise false.</returns>
API_FUNCTION() bool UploadData(TextureData& data, bool copyData = false);
/// <summary> /// <summary>
/// Downloads the texture data to be accessible from CPU. For frequent access, use staging textures, otherwise current thread will be stalled to wait for the GPU frame to copy data into staging buffer. /// Downloads the texture data to be accessible from CPU. For frequent access, use staging textures, otherwise current thread will be stalled to wait for the GPU frame to copy data into staging buffer.
/// </summary> /// </summary>

View File

@@ -78,6 +78,32 @@ TEST_CASE("Array")
TEST_CASE("BitArray") TEST_CASE("BitArray")
{ {
SECTION("Test Access")
{
BitArray<> a1;
CHECK(a1.Count() == 0);
for (int32 i = 0; i < 310; i++)
{
a1.Add(false);
}
CHECK(a1.Count() == 310);
a1.Resize(300);
CHECK(a1.Count() == 300);
CHECK(a1.Capacity() >= 300);
a1.SetAll(true);
a1.SetAll(false);
for (int32 i = 0; i < 300; i++)
{
a1.Set(i, true);
for (int32 j = 0; j < 300; j++)
{
bool expected = j == i;
CHECK(a1.Get(j) == expected);
}
a1.Set(i, false);
}
}
SECTION("Test Allocators") SECTION("Test Allocators")
{ {
BitArray<> a1; BitArray<> a1;
@@ -142,7 +168,7 @@ TEST_CASE("BitArray")
// Generate some random data for testing // Generate some random data for testing
BitArray<> testData; BitArray<> testData;
testData.Resize(32); testData.Resize(128);
RandomStream rand(101); RandomStream rand(101);
for (int32 i = 0; i < testData.Count(); i++) for (int32 i = 0; i < testData.Count(); i++)
testData.Set(i, rand.GetBool()); testData.Set(i, rand.GetBool());
@@ -151,8 +177,8 @@ TEST_CASE("BitArray")
{ {
const BitArray<> a1(testData); const BitArray<> a1(testData);
const BitArray<InlinedAllocation<8>> a2(testData); const BitArray<InlinedAllocation<8>> a2(testData);
const BitArray<InlinedAllocation<64>> a3(testData); const BitArray<InlinedAllocation<256>> a3(testData);
const BitArray<FixedAllocation<64>> a4(testData); const BitArray<FixedAllocation<256>> a4(testData);
CHECK(a1 == testData); CHECK(a1 == testData);
CHECK(a2 == testData); CHECK(a2 == testData);
CHECK(a3 == testData); CHECK(a3 == testData);

View File

@@ -17,6 +17,7 @@ namespace Flax.Build
private static Platform _buildPlatform; private static Platform _buildPlatform;
private static Platform[] _platforms; private static Platform[] _platforms;
private Dictionary<TargetArchitecture, Toolchain> _toolchains; private Dictionary<TargetArchitecture, Toolchain> _toolchains;
private uint _failedArchitectures = 0;
/// <summary> /// <summary>
/// Gets the current target platform that build tool runs on. /// Gets the current target platform that build tool runs on.
@@ -251,7 +252,8 @@ namespace Flax.Build
public Toolchain TryGetToolchain(TargetArchitecture targetArchitecture) public Toolchain TryGetToolchain(TargetArchitecture targetArchitecture)
{ {
Toolchain result = null; Toolchain result = null;
if (HasRequiredSDKsInstalled) uint failedMask = 1u << (int)targetArchitecture; // Skip retrying if it already failed once on this arch
if (HasRequiredSDKsInstalled && (_failedArchitectures & failedMask) != failedMask)
{ {
try try
{ {
@@ -259,6 +261,7 @@ namespace Flax.Build
} }
catch (Exception ex) catch (Exception ex)
{ {
_failedArchitectures |= failedMask;
Log.Exception(ex); Log.Exception(ex);
} }
} }