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(); }
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); }
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}."); } } } }
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(); }
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(); }
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(); }
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; }
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); }
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); }
public void Remove(DeviceBufferRange range) => Remove((int)(range.Offset / matrixStride));
public SyncedLocation(DeviceBufferRange range) => this.BufferRange = range;