Example #1
0
            public Model(ITagContainer diContainer, zzio.scn.Model sceneModel, Behavior?sceneBehavior)
            {
                this.diContainer = diContainer;
                var textureLoader    = diContainer.GetTag <IAssetLoader <Texture> >();
                var textureBasePaths = new[]
                {
                    new FilePath("resources/textures/models"),
                    new FilePath("resources/textures/worlds")
                };
                var camera = diContainer.GetTag <Camera>();

                SceneModel             = sceneModel;
                SceneBehaviour         = sceneBehavior;
                locationRange          = diContainer.GetTag <LocationBuffer>().Add(Location);
                Location.LocalPosition = sceneModel.pos;
                Location.LocalRotation = sceneModel.rot.ToZZRotation();

                var clumpLoader = diContainer.GetTag <IAssetLoader <ClumpBuffers> >();

                clumpBuffers = clumpLoader.Load(new FilePath("resources/models/models").Combine(sceneModel.filename + ".dff"));
                materials    = clumpBuffers.SubMeshes.Select(subMesh =>
                {
                    var rwMaterial = subMesh.Material;
                    var material   = new ModelStandardMaterial(diContainer);
                    (material.MainTexture.Texture, material.Sampler.Sampler) = textureLoader.LoadTexture(textureBasePaths, rwMaterial);
                    material.LinkTransformsTo(camera);
                    material.World.BufferRange = locationRange;
                    material.Uniforms.Ref      = ModelStandardMaterialUniforms.Default;
                    material.Uniforms.Ref.vertexColorFactor = 0.0f;
                    material.Uniforms.Ref.tint = rwMaterial.color.ToFColor() * sceneModel.color;
                    return(material);
                }).ToArray();
            }
Example #2
0
        public DeviceBuffer ConfigureDeviceBuffers(GraphicsDevice device, ResourceFactory factory)
        {
            var alignment = device.UniformBufferMinOffsetAlignment;

            var uniformObjSizeInBytes = SizeOfUniformDataElement;
            var hostBuffStride        = 1u;

            if (alignment > SizeOfUniformDataElement)
            {
                hostBuffStride        = alignment / SizeOfUniformDataElement;
                uniformObjSizeInBytes = alignment;
            }

            var bufsize = (uint)(uniformObjSizeInBytes * UniformData.Length);

            BufferDescription = new BufferDescription(bufsize, BufferUsage);

            var uniformBuffer = factory.CreateBuffer(BufferDescription);

            var uniformBufferStaging = new T[UniformData.Length * hostBuffStride];

            for (var i = 0; i < UniformData.Length; ++i)
            {
                uniformBufferStaging[i * hostBuffStride] = UniformData[i];
            }

            device.UpdateBuffer(uniformBuffer, 0, uniformBufferStaging);

            DeviceBufferRange = new DeviceBufferRange(uniformBuffer, 0, uniformObjSizeInBytes);

            return(uniformBuffer);
        }
Example #3
0
        internal static void ValidateResourceSet(GraphicsDevice gd, ref ResourceSetDescription description)
        {
            ResourceLayoutElementDescription[] elements = description.Layout.Description.Elements;
            BindableResource[] resources = description.BoundResources;

            if (elements.Length != resources.Length)
            {
                throw new VeldridException(
                          $"The number of resources specified ({resources.Length}) must be equal to the number of resources in the {nameof(ResourceLayout)} ({elements.Length}).");
            }

            for (uint i = 0; i < elements.Length; i++)
            {
                ValidateResourceKind(elements[i].Kind, resources[i], i);
            }

            for (int i = 0; i < description.Layout.Description.Elements.Length; i++)
            {
                ResourceLayoutElementDescription element = description.Layout.Description.Elements[i];
                if (element.Kind == ResourceKind.UniformBuffer ||
                    element.Kind == ResourceKind.StructuredBufferReadOnly ||
                    element.Kind == ResourceKind.StructuredBufferReadWrite)
                {
                    DeviceBufferRange range = Util.GetBufferRange(description.BoundResources[i], 0);

                    if (!gd.Features.BufferRangeBinding && (range.Offset != 0 || range.SizeInBytes != range.Buffer.SizeInBytes))
                    {
                        throw new VeldridException($"The {nameof(DeviceBufferRange)} in slot {i} uses a non-zero offset or less-than-full size, " +
                                                   $"which requires {nameof(GraphicsDeviceFeatures)}.{nameof(GraphicsDeviceFeatures.BufferRangeBinding)}.");
                    }

                    uint alignment = element.Kind == ResourceKind.UniformBuffer
                       ? gd.UniformBufferMinOffsetAlignment
                       : gd.StructuredBufferMinOffsetAlignment;

                    if ((range.Offset % alignment) != 0)
                    {
                        throw new VeldridException($"The {nameof(DeviceBufferRange)} in slot {i} has an invalid offset: {range.Offset}. " +
                                                   $"The offset for this buffer must be a multiple of {alignment}.");
                    }
                }
            }
        }
Example #4
0
        public BeamStarRenderer(ITagContainer diContainer, DeviceBufferRange locationRange, BeamStar data)
        {
            this.data = data;
            var textureLoader = diContainer.GetTag <IAssetLoader <Texture> >();
            var camera        = diContainer.GetTag <Camera>();

            quadMeshBuffer = diContainer.GetTag <IQuadMeshBuffer <EffectVertex> >();
            material       = EffectMaterial.CreateFor(data.renderMode, diContainer);
            material.LinkTransformsTo(camera);
            material.World.BufferRange        = locationRange;
            material.Uniforms.Value           = EffectMaterialUniforms.Default;
            material.Uniforms.Ref.isBillboard = false;
            material.MainTexture.Texture      = textureLoader.LoadTexture(
                IEffectPartRenderer.TexturePath, data.texName);
            material.Sampler.Value = IEffectPartRenderer.SamplerDescription;
            AddDisposable(material);

            quadRange = quadMeshBuffer.Reserve(data.complexity.GetPlaneCount() * 2);

            Reset();
        }
Example #5
0
        public MovingPlanesRenderer(ITagContainer diContainer, DeviceBufferRange locationRange, MovingPlanes data)
        {
            this.data = data;
            var textureLoader = diContainer.GetTag <IAssetLoader <Texture> >();
            var camera        = diContainer.GetTag <Camera>();

            quadMeshBuffer = diContainer.GetTag <IQuadMeshBuffer <EffectVertex> >();
            material       = EffectMaterial.CreateFor(data.renderMode, diContainer);
            material.LinkTransformsTo(camera);
            material.World.BufferRange        = locationRange;
            material.Uniforms.Value           = EffectMaterialUniforms.Default;
            material.Uniforms.Ref.isBillboard = !data.circlesAround && !data.useDirection;
            material.MainTexture.Texture      = textureLoader.LoadTexture(
                IEffectPartRenderer.TexturePath, data.texName);
            material.Sampler.Value = IEffectPartRenderer.SamplerDescription;
            AddDisposable(material);

            quadRange = quadMeshBuffer.Reserve(data.disableSecondPlane ? 1 : 2);
            texCoords = EffectPartUtility.GetTileUV(data.tileW, data.tileH, data.tileId);

            Reset();
        }
Example #6
0
        public RandomPlanesRenderer(ITagContainer diContainer, DeviceBufferRange locationRange, RandomPlanes data)
        {
            this.data = data;
            var textureLoader = diContainer.GetTag <IAssetLoader <Texture> >();
            var camera        = diContainer.GetTag <Camera>();

            quadMeshBuffer = diContainer.GetTag <IQuadMeshBuffer <EffectVertex> >();
            material       = EffectMaterial.CreateFor(data.renderMode, diContainer);
            material.LinkTransformsTo(camera);
            material.World.BufferRange                 = locationRange;
            material.Uniforms.Value                    = EffectMaterialUniforms.Default;
            material.Uniforms.Ref.isBillboard          = !data.circlesAround;
            AddDisposable(material.MainTexture.Texture = textureLoader.LoadTexture(
                              IEffectPartRenderer.TexturePath, data.texName));
            material.Sampler.Value = SamplerAddressMode.Clamp.AsDescription(SamplerFilter.MinLinear_MagLinear_MipLinear);
            AddDisposable(material);

            planes        = new RandomPlane[(int)(data.planeLife * data.spawnRate / 1000)];
            quadRange     = quadMeshBuffer.Reserve(planes.Length);
            tileTexCoords = EffectPartUtility.GetTileUV(data.tileW, data.tileH, data.tileId, data.tileCount);

            Reset();
        }
Example #7
0
        public DebugSkeletonRenderer(ITagContainer diContainer, ClumpBuffers geometryBuffers, Skeleton skeleton)
        {
            Geometry = geometryBuffers;
            Skeleton = skeleton;
            var camera = diContainer.GetTag <Camera>();

            locationBuffer   = diContainer.GetTag <LocationBuffer>();
            worldBufferRange = locationBuffer.Add(skeleton.Location);

            void LinkTransformsFor(IStandardTransformMaterial m)
            {
                m.LinkTransformsTo(camera);
                m.World.BufferRange = worldBufferRange;
            }

            BoneMaterial = new DebugSkinnedMaterial(diContainer);
            LinkTransformsFor(BoneMaterial);
            BoneMaterial.Pose.Skeleton = skeleton;
            SkinMaterial = new DebugSkinAllMaterial(diContainer);
            LinkTransformsFor(SkinMaterial);
            SkinMaterial.Alpha.Ref  = 1.0f;
            SkinHighlightedMaterial = new DebugSkinSingleMaterial(diContainer);
            LinkTransformsFor(SkinHighlightedMaterial);
            SkinHighlightedMaterial.BoneIndex.Ref = -1;
            LinesMaterial = new DebugLinesMaterial(diContainer);
            LinkTransformsFor(LinesMaterial);
            device = diContainer.GetTag <GraphicsDevice>();

            var vertices     = Enumerable.Empty <ColoredVertex>();
            var skinVertices = Enumerable.Empty <SkinVertex>();
            var indices      = Enumerable.Empty <ushort>();

            foreach (var(bone, index) in skeleton.Bones.Indexed())
            {
                if (bone.Parent == null)
                {
                    continue;
                }
                var to       = bone.GlobalPosition;
                var from     = bone.Parent.GlobalPosition;
                var length   = (to - from).Length();
                var baseSize = length * RhombusBaseSize;

                var normal = MathEx.CmpZero(length)
                    ? Vector3.UnitY
                    : (to - from) / length;
                var tangent    = Vector3.Normalize(normal.SomeOrthogonal()) * baseSize;
                var bitangent  = Vector3.Normalize(Vector3.Cross(normal, tangent)) * baseSize;
                var baseCenter = from + normal * length * RhombusBaseOffset;

                vertices = vertices.Concat(new[]
                {
                    from,
                    baseCenter - tangent - bitangent,
                    baseCenter + tangent - bitangent,
                    baseCenter + tangent + bitangent,
                    baseCenter - tangent + bitangent,
                    to
                }.Select(p => new ColoredVertex(p, Colors[index % Colors.Length])));
                skinVertices = skinVertices.Concat(Enumerable.Repeat(new SkinVertex()
                {
                    bone0   = unchecked ((byte)Skeleton.Parents[index]),
                    weights = Vector4.UnitX
                }, RhombusVertexCount));
                indices = indices.Concat(RhombusIndices.Select(i => (ushort)(i + index * RhombusVertexCount)));
            }

            var vertexArray     = vertices.ToArray();
            var skinVertexArray = skinVertices.ToArray();
            var indexArray      = indices.ToArray();

            vertexBuffer = device.ResourceFactory.CreateBuffer(new BufferDescription(
                                                                   (uint)vertexArray.Length * ColoredVertex.Stride, BufferUsage.VertexBuffer));
            skinBuffer = device.ResourceFactory.CreateBuffer(new BufferDescription(
                                                                 (uint)skinVertexArray.Length * SkinVertex.Stride, BufferUsage.VertexBuffer));
            indexBuffer = device.ResourceFactory.CreateBuffer(new BufferDescription(
                                                                  (uint)indexArray.Length * sizeof(ushort), BufferUsage.IndexBuffer));
            device.UpdateBuffer(vertexBuffer, 0, vertexArray);
            device.UpdateBuffer(skinBuffer, 0, skinVertexArray);
            device.UpdateBuffer(indexBuffer, 0, indexArray);

            var lineVertices = new ColoredVertex[]
            {
                new ColoredVertex(Vector3.Zero, Colors[0]),
                new ColoredVertex(Vector3.UnitX * LineLength, Colors[0]),
                new ColoredVertex(Vector3.Zero, Colors[1]),
                new ColoredVertex(Vector3.UnitY * LineLength, Colors[1]),
                new ColoredVertex(Vector3.Zero, Colors[2]),
                new ColoredVertex(Vector3.UnitZ * LineLength, Colors[2])
            };

            lineBuffer = device.ResourceFactory.CreateBuffer(new BufferDescription(
                                                                 (uint)lineVertices.Length * ColoredVertex.Stride, BufferUsage.VertexBuffer));
            device.UpdateBuffer(lineBuffer, 0, lineVertices);

            var boneDepthsArr = new int[Skeleton.Bones.Count];

            for (int i = 0; i < Skeleton.Bones.Count; i++)
            {
                boneDepthsArr[i] = Skeleton.Parents[i] < 0 ? 0 : boneDepthsArr[Skeleton.Parents[i]] + 1;
            }
            boneDepths = boneDepthsArr;
        }
Example #8
0
        public void FillBuffer_WithOffsets(uint srcSetMultiple, uint srcBindingMultiple, uint dstSetMultiple, uint dstBindingMultiple, bool combinedLayout)
        {
            if (!GD.Features.ComputeShader)
            {
                return;
            }
            Debug.Assert((GD.StructuredBufferMinOffsetAlignment % sizeof(uint)) == 0);

            uint valueCount        = 512;
            uint dataSize          = valueCount * sizeof(uint);
            uint totalSrcAlignment = GD.StructuredBufferMinOffsetAlignment * (srcSetMultiple + srcBindingMultiple);
            uint totalDstAlignment = GD.StructuredBufferMinOffsetAlignment * (dstSetMultiple + dstBindingMultiple);

            DeviceBuffer copySrc = RF.CreateBuffer(
                new BufferDescription(totalSrcAlignment + dataSize, BufferUsage.StructuredBufferReadOnly, sizeof(uint)));
            DeviceBuffer copyDst = RF.CreateBuffer(
                new BufferDescription(totalDstAlignment + dataSize, BufferUsage.StructuredBufferReadWrite, sizeof(uint)));

            ResourceLayout[] layouts;
            ResourceSet[]    sets;

            DeviceBufferRange srcRange = new DeviceBufferRange(copySrc, srcSetMultiple * GD.StructuredBufferMinOffsetAlignment, dataSize);
            DeviceBufferRange dstRange = new DeviceBufferRange(copyDst, dstSetMultiple * GD.StructuredBufferMinOffsetAlignment, dataSize);

            if (combinedLayout)
            {
                layouts = new[]
                {
                    RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                new ResourceLayoutElementDescription(
                                                    "CopySrc",
                                                    ResourceKind.StructuredBufferReadOnly,
                                                    ShaderStages.Compute,
                                                    ResourceLayoutElementOptions.DynamicBinding),
                                                new ResourceLayoutElementDescription(
                                                    "CopyDst",
                                                    ResourceKind.StructuredBufferReadWrite,
                                                    ShaderStages.Compute,
                                                    ResourceLayoutElementOptions.DynamicBinding)))
                };
                sets = new[]
                {
                    RF.CreateResourceSet(new ResourceSetDescription(layouts[0], srcRange, dstRange))
                };
            }
            else
            {
                layouts = new[]
                {
                    RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                new ResourceLayoutElementDescription(
                                                    "CopySrc",
                                                    ResourceKind.StructuredBufferReadOnly,
                                                    ShaderStages.Compute,
                                                    ResourceLayoutElementOptions.DynamicBinding))),
                    RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                new ResourceLayoutElementDescription(
                                                    "CopyDst",
                                                    ResourceKind.StructuredBufferReadWrite,
                                                    ShaderStages.Compute,
                                                    ResourceLayoutElementOptions.DynamicBinding)))
                };
                sets = new[]
                {
                    RF.CreateResourceSet(new ResourceSetDescription(layouts[0], srcRange)),
                    RF.CreateResourceSet(new ResourceSetDescription(layouts[1], dstRange)),
                };
            }

            Pipeline pipeline = RF.CreateComputePipeline(new ComputePipelineDescription(
                                                             TestShaders.LoadCompute(RF, combinedLayout ? "FillBuffer" : "FillBuffer_SeparateLayout"),
                                                             layouts,
                                                             1, 1, 1));

            uint[] srcData = Enumerable.Range(0, (int)copySrc.SizeInBytes / sizeof(uint)).Select(i => (uint)i).ToArray();
            GD.UpdateBuffer(copySrc, 0, srcData);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.SetPipeline(pipeline);
            if (combinedLayout)
            {
                uint[] offsets = new[]
                {
                    srcBindingMultiple *GD.StructuredBufferMinOffsetAlignment,
                       dstBindingMultiple *GD.StructuredBufferMinOffsetAlignment
                };
                cl.SetComputeResourceSet(0, sets[0], offsets);
            }
            else
            {
                uint offset = srcBindingMultiple * GD.StructuredBufferMinOffsetAlignment;
                cl.SetComputeResourceSet(0, sets[0], 1, ref offset);
                offset = dstBindingMultiple * GD.StructuredBufferMinOffsetAlignment;
                cl.SetComputeResourceSet(1, sets[1], 1, ref offset);
            }
            cl.Dispatch(512, 1, 1);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            DeviceBuffer readback = GetReadback(copyDst);

            MappedResourceView <uint> readView = GD.Map <uint>(readback, MapMode.Read);
            for (uint i = 0; i < valueCount; i++)
            {
                uint srcIndex = totalSrcAlignment / sizeof(uint) + i;
                uint expected = srcData[(int)srcIndex];

                uint dstIndex = totalDstAlignment / sizeof(uint) + i;
                uint actual   = readView[dstIndex];

                Assert.Equal(expected, actual);
            }
            GD.Unmap(readback);
        }
Example #9
0
        public VkResourceSet(VkGraphicsDevice gd, ref ResourceSetDescription description)
            : base(ref description)
        {
            _gd      = gd;
            RefCount = new ResourceRefCount(DisposeCore);
            VkResourceLayout vkLayout = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(description.Layout);

            VkDescriptorSetLayout dsl = vkLayout.DescriptorSetLayout;

            _descriptorCounts          = vkLayout.DescriptorResourceCounts;
            _descriptorAllocationToken = _gd.DescriptorPoolManager.Allocate(_descriptorCounts, dsl);

            BindableResource[] boundResources        = description.BoundResources;
            uint descriptorWriteCount                = (uint)boundResources.Length;
            VkWriteDescriptorSet *  descriptorWrites = stackalloc VkWriteDescriptorSet[(int)descriptorWriteCount];
            VkDescriptorBufferInfo *bufferInfos      = stackalloc VkDescriptorBufferInfo[(int)descriptorWriteCount];
            VkDescriptorImageInfo * imageInfos       = stackalloc VkDescriptorImageInfo[(int)descriptorWriteCount];

            for (int i = 0; i < descriptorWriteCount; i++)
            {
                VkDescriptorType type = vkLayout.DescriptorTypes[i];

                descriptorWrites[i].sType           = VkStructureType.WriteDescriptorSet;
                descriptorWrites[i].descriptorCount = 1;
                descriptorWrites[i].descriptorType  = type;
                descriptorWrites[i].dstBinding      = (uint)i;
                descriptorWrites[i].dstSet          = _descriptorAllocationToken.Set;

                if (type == VkDescriptorType.UniformBuffer || type == VkDescriptorType.UniformBufferDynamic ||
                    type == VkDescriptorType.StorageBuffer || type == VkDescriptorType.StorageBufferDynamic)
                {
                    DeviceBufferRange range          = Util.GetBufferRange(boundResources[i], 0);
                    VkBuffer          rangedVkBuffer = Util.AssertSubtype <DeviceBuffer, VkBuffer>(range.Buffer);
                    bufferInfos[i].buffer           = rangedVkBuffer.DeviceBuffer;
                    bufferInfos[i].offset           = range.Offset;
                    bufferInfos[i].range            = range.SizeInBytes;
                    descriptorWrites[i].pBufferInfo = &bufferInfos[i];
                    _refCounts.Add(rangedVkBuffer.RefCount);
                }
                else if (type == VkDescriptorType.SampledImage)
                {
                    TextureView   texView   = Util.GetTextureView(_gd, boundResources[i]);
                    VkTextureView vkTexView = Util.AssertSubtype <TextureView, VkTextureView>(texView);
                    imageInfos[i].imageView        = vkTexView.ImageView;
                    imageInfos[i].imageLayout      = VkImageLayout.ShaderReadOnlyOptimal;
                    descriptorWrites[i].pImageInfo = &imageInfos[i];
                    _sampledTextures.Add(Util.AssertSubtype <Texture, VkTexture>(texView.Target));
                    _refCounts.Add(vkTexView.RefCount);
                }
                else if (type == VkDescriptorType.StorageImage)
                {
                    TextureView   texView   = Util.GetTextureView(_gd, boundResources[i]);
                    VkTextureView vkTexView = Util.AssertSubtype <TextureView, VkTextureView>(texView);
                    imageInfos[i].imageView        = vkTexView.ImageView;
                    imageInfos[i].imageLayout      = VkImageLayout.General;
                    descriptorWrites[i].pImageInfo = &imageInfos[i];
                    _storageImages.Add(Util.AssertSubtype <Texture, VkTexture>(texView.Target));
                    _refCounts.Add(vkTexView.RefCount);
                }
                else if (type == VkDescriptorType.Sampler)
                {
                    VkSampler sampler = Util.AssertSubtype <BindableResource, VkSampler>(boundResources[i]);
                    imageInfos[i].sampler          = sampler.DeviceSampler;
                    descriptorWrites[i].pImageInfo = &imageInfos[i];
                    _refCounts.Add(sampler.RefCount);
                }
            }

            vkUpdateDescriptorSets(_gd.Device, descriptorWriteCount, descriptorWrites, 0, null);
        }
Example #10
0
 public void Remove(DeviceBufferRange range) => Remove((int)(range.Offset / matrixStride));
Example #11
0
 public SyncedLocation(DeviceBufferRange range) => this.BufferRange = range;