예제 #1
0
        public void AsStorageBufferUsage()
        {
            var expected = MgBufferUsageFlagBits.STORAGE_BUFFER_BIT;
            var selector = new PerMaterialTextureStorageQuery(
                new MgPhysicalDeviceLimits
            {
                MaxPerStageDescriptorStorageBuffers = 1,
                MaxUniformBufferRange = 100,
                MaxStorageBufferRange = 1000,
            }
                );

            MgBufferUsageFlagBits actual = selector.GetAppropriateBufferUsage();

            Assert.AreEqual(expected, actual);
        }
예제 #2
0
        public void NewMaterials_7()
        {
            var selector = new PerMaterialTextureStorageQuery(
                new MgPhysicalDeviceLimits
            {
                MaxUniformBufferRange = 400,
                MaxStorageBufferRange = 300,
                MaxPerStageDescriptorStorageBuffers = 1,
                MaxPerStageDescriptorSampledImages  = 100,
            }
                );

            var actual = selector.GetElementRange(
                MgBufferUsageFlagBits.UNIFORM_BUFFER_BIT,
                5U,
                20U);
            // since it's storage is should be limited by the
            // number of texture slots / 5 => 20  << SAME
            // number of storage space / data size => 20U << SAME
            var expected = 20U;

            Assert.AreEqual(expected, actual);
        }
예제 #3
0
        private static int[] AllocateMaterials(MgtfMaterial[] materials, MgStorageBlockAllocationRequest dynamicRequest, MgPhysicalDeviceLimits limits)
        {
            // materials
            var query        = new PerMaterialTextureStorageQuery(limits);
            var noOfSamplers = query.GetMaxNoOfCombinedImageSamplers();

            const uint PBR_TEXTURES_PER_MATERIALS = 5U;
            var        blockSize = (uint)Marshal.SizeOf(typeof(MaterialUBO));

            const uint HI_RES  = 32U;
            const uint LOW_RES = 16U;

            // GONNA RESERVE 5 BINDINGS SLOTS
            // IN VK, a global binding range is used by all descriptors
            // IN OPENGL/WEBGL, buffer and textures have the own binding range
            // THEREFORE, Mg standard is not to overlap binding values between descriptors
            // OTHERWISE, separate sets implementation (TODO) could be used to handle separate ranges
            const uint NO_OF_RESERVED_BINDINGS = 5U;
            var        range = noOfSamplers - NO_OF_RESERVED_BINDINGS;

            if (noOfSamplers < LOW_RES)
            {
                throw new InvalidOperationException("not enough combined samplers for pbr");
            }

            // pick between hi res and low res
            bool isHighRes      = (noOfSamplers >= HI_RES);
            uint bindableImages = isHighRes ? 32U : 16U;

            var elementRange = query.GetElementRange(
                MgBufferUsageFlagBits.UNIFORM_BUFFER_BIT,
                PBR_TEXTURES_PER_MATERIALS,
                blockSize);

            if (isHighRes)
            {
                // floor(no_of_samplers - reserved_slots / textures_per_mat) = floor((32 - 5)/5) = 5
                if (elementRange < 5U)
                {
                    throw new InvalidOperationException("hi res not applicable");
                }
                elementRange = 5U;
            }
            else
            {
                // floor(no_of_samplers - reserved_slots / textures_per_mat) = floor((16 - 5)/5) = 2
                if (elementRange < 2U)
                {
                    throw new InvalidOperationException("low res not applicable");
                }
                elementRange = 2U;
            }

            var noOfAllocations = (materials.Length / elementRange);

            noOfAllocations += (materials.Length % elementRange == 0) ? 0 : 1;

            var info = new MgStorageBlockAllocationInfo
            {
                Usage = MgBufferUsageFlagBits.UNIFORM_BUFFER_BIT,
                MemoryPropertyFlags = MgMemoryPropertyFlagBits.HOST_VISIBLE_BIT,
                Size = elementRange * blockSize,
            };

            var materialIndices = new int[noOfAllocations];

            for (var i = 0; i < noOfAllocations; i += 1)
            {
                materialIndices[i] = dynamicRequest.Insert(info);
            }
            return(materialIndices);
        }