protected override void Destroy() { RootSignature?.Dispose(); RootSignature = null; base.Destroy(); }
public void AddLocalRootSignature(RootSignature signature, ReadOnlyMemory <ReadOnlyMemory <char> > associations) { _localRootSigs.Add((signature, associations)); _totalNumAssociations += associations.Length; _totalNumAssocationObjects += associations.IsEmpty ? 0 : 1; _totalNumSubObjects += associations.IsEmpty ? 1 : 2; }
private void BuildRootSignature() { var texTable = new DescriptorRange(DescriptorRangeType.ShaderResourceView, 1, 0); var descriptor1 = new RootDescriptor(0, 0); var descriptor2 = new RootDescriptor(1, 0); var descriptor3 = new RootDescriptor(2, 0); // Root parameter can be a table, root descriptor or root constants. // Perfomance TIP: Order from most frequent to least frequent. var slotRootParameters = new[] { new RootParameter(ShaderVisibility.Pixel, texTable), new RootParameter(ShaderVisibility.Vertex, descriptor1, RootParameterType.ConstantBufferView), new RootParameter(ShaderVisibility.All, descriptor2, RootParameterType.ConstantBufferView), new RootParameter(ShaderVisibility.All, descriptor3, RootParameterType.ConstantBufferView) }; // A root signature is an array of root parameters. var rootSigDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, slotRootParameters, GetStaticSamplers()); _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize()); }
public D3DApp(IntPtr handleIntPtr) { this.handleIntPtr = handleIntPtr; this.m4XMsaaState = false; this.swapChainBuffers = new Resource[SwapChainBufferCount]; this.frameResources = new List <FrameResource>(NumFrameResources); this.fenceEvents = new List <AutoResetEvent>(NumFrameResources); this.mainPassCb = PassConstants.Default; this.meshes = new List <Mesh>(); this.InitDirect3D(); this.commandObjects = new CommandObjects(device); this.swapChain = SwapChainObject.New(this.handleIntPtr, this.factory, this.commandObjects.GetCommandQueue, BackBufferFormat, SwapChainBufferCount, MsaaCount, MsaaQuality); this.descriptorHeapObjects = new DescriptorHeapObjects(device, SwapChainBufferCount, 1); this.rootSignature = RootSignatureObject.New(device); this.BuildMesh(); this.BuildFrameResources(); this.BuildConstantBuffers(); this.pso = PipelinesStateObject.New(device, rootSignature, MsaaCount, MsaaQuality, DepthStencilFormat, BackBufferFormat); this.FlushCommandQueue(); this.camera = new OrbitCamera(); }
public static PipelineState New(Device device, RootSignature rootSignature, int msaaCount, int msaaQuality, Format depthStencilFormat, Format backBufferFormat) { var graphicsPipelineStateDescription = BuildGraphicsPipelineStateDescription(rootSignature, msaaCount, msaaQuality, depthStencilFormat); graphicsPipelineStateDescription.RenderTargetFormats[0] = backBufferFormat; return(device.CreateGraphicsPipelineState(graphicsPipelineStateDescription)); }
protected override void Destroy() { RootSignature?.Dispose(); RootSignature = null; bufferUploader.Clear(); base.Destroy(); }
public void Initialize() { // Pipeline state. var testShaderPath = "../../../../../Resources/Engine/MipMap.hlsl"; ComputeShader = ShaderBytecode.CompileFromFile(testShaderPath, "GenerateMipMaps", "cs_5_0"); // Root parameters. var rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.All, new RootConstants(0, 0, 2)), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, // D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND BaseShaderRegister = 0 }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.UnorderedAccessView, BaseShaderRegister = 0, OffsetInDescriptorsFromTableStart = int.MinValue, // D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND DescriptorCount = 1 }), }; var staticSamplers = new StaticSamplerDescription[] { new StaticSamplerDescription() { Filter = Filter.MinMagLinearMipPoint, AddressUVW = TextureAddressMode.Clamp, MipLODBias = 0f, ComparisonFunc = Comparison.Never, MinLOD = 0f, MaxLOD = float.MaxValue, MaxAnisotropy = 0, BorderColor = StaticBorderColor.OpaqueBlack, ShaderRegister = 0, RegisterSpace = 0, ShaderVisibility = ShaderVisibility.All } }; var rootSignatureDescription = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, staticSamplers); RootSignature = RootSignature.Create(Device, rootSignatureDescription); Layout = new DescriptorLayout( DescriptorLayout.EntryType.ConstantBufferShaderResourceOrUnorderedAccessView, DescriptorLayout.EntryType.ConstantBufferShaderResourceOrUnorderedAccessView); }
public virtual async Task <PipelineState> CreateComputePipelineStateAsync() { CompiledShader compiledShader = await CreateShaderAsync(); RootSignature rootSignature = CreateRootSignature(); PipelineState pipelineState = new PipelineState(GraphicsDevice, rootSignature, compiledShader.Shaders["compute"]); return(pipelineState); }
public static PipelineState CreateComputePipelineState(Device device, RootSignature rootSignature, byte[] computeShader) { var computePipelineStateDesc = new ComputePipelineStateDescription() { RootSignature = rootSignature, ComputeShader = new ShaderBytecode(computeShader), Flags = PipelineStateFlags.None }; return(device.CreateComputePipelineState(computePipelineStateDesc)); }
public void Update(GameTimer gt, GraphicsCommandList cmdList, RootSignature rootSig, PipelineState pso) { // Accumulate time. _t += gt.DeltaTime; cmdList.PipelineState = pso; cmdList.SetComputeRootSignature(rootSig); // Only update the simulation at the specified time step. if (_t >= _timeStep) { // Set the update constants. Utilities.Pin(_k, ptr => cmdList.SetComputeRoot32BitConstants(0, 3, ptr, 0)); cmdList.SetComputeRootDescriptorTable(1, _prevSolUav); cmdList.SetComputeRootDescriptorTable(2, _currSolUav); cmdList.SetComputeRootDescriptorTable(3, _nextSolUav); // How many groups do we need to dispatch to cover the wave grid. // Note that RowCount and ColumnCount should be divisible by 16 // so there is no remainder. int numGroupsX = ColumnCount / 16; int numGroupsY = RowCount / 16; cmdList.Dispatch(numGroupsX, numGroupsY, 1); // // Ping-pong buffers in preparation for the next update. // The previous solution is no longer needed and becomes the target of the next solution in the next update. // The current solution becomes the previous solution. // The next solution becomes the current solution. // Resource resTemp = _prevSol; _prevSol = _currSol; _currSol = _nextSol; _nextSol = resTemp; GpuDescriptorHandle srvTemp = _prevSolSrv; _prevSolSrv = _currSolSrv; _currSolSrv = _nextSolSrv; _nextSolSrv = srvTemp; GpuDescriptorHandle uavTemp = _prevSolUav; _prevSolUav = _currSolUav; _currSolUav = _nextSolUav; _nextSolUav = uavTemp; // Reset time. _t = 0.0f; // The current solution needs to be able to be read by the vertex shader, so change its state to GENERIC_READ. cmdList.ResourceBarrierTransition(_currSol, ResourceStates.UnorderedAccess, ResourceStates.GenericRead); } }
//[MemberNotNull(nameof(_tex), nameof(_texMsaa8x))] public void CreatePipelines() { var rootParams = new[] { RootParameter.CreateDescriptor(RootParameterType.ConstantBufferView, 0, 0), RootParameter.CreateDescriptor(RootParameterType.ConstantBufferView, 1, 0), RootParameter.CreateDescriptor(RootParameterType.ConstantBufferView, 2, 0), RootParameter.CreateDescriptorTable(DescriptorRangeType.ShaderResourceView, 0, 1, 0) }; var samplers = new[] { new StaticSampler( TextureAddressMode.Clamp, SamplerFilterType.Anistropic, shaderRegister: 0, registerSpace: 0, ShaderVisibility.All, StaticSampler.OpaqueWhite ) }; _rootSig = _device.CreateRootSignature(rootParams, samplers); var compilationFlags = new[] { ShaderCompileFlag.PackMatricesInRowMajorOrder, ShaderCompileFlag.AllResourcesBound, ShaderCompileFlag.EnableDebugInformation, ShaderCompileFlag.WriteDebugInformationToFile() //ShaderCompileFlag.DefineMacro("NORMALS") }; var vertexShader = ShaderManager.CompileShader("Shaders/SimpleTexture/TextureVertexShader.hlsl", ShaderModel.Vs_6_0, compilationFlags); var pixelShader = ShaderManager.CompileShader("Shaders/SimpleTexture/TexturePixelShader.hlsl", ShaderModel.Ps_6_0, compilationFlags); var psoDesc = new GraphicsPipelineDesc { RootSignature = _rootSig, RenderTargetFormats = RenderTargetFormat, DepthStencilFormat = DepthStencilFormat, VertexShader = vertexShader, PixelShader = pixelShader, Topology = TopologyClass.Triangle, Inputs = InputLayout.FromType <TexturedVertex>() }; _tex = _device.PipelineManager.CreatePipelineStateObject(psoDesc, "Texture"); //psoDesc.Msaa = MultisamplingDesc.X8; _texMsaa8x = _device.PipelineManager.CreatePipelineStateObject(psoDesc, "Texture_MSAA8X"); }
public static RootSignature FromString(CommonContext context, string s) { RootSignature rootSignature; if (context.rootSignatures.TryGetValue(s, out rootSignature)) { return(rootSignature); } rootSignature = new RootSignature(); context.rootSignatures[s] = rootSignature; RootSignatureParamP[] desc = new RootSignatureParamP[s.Length]; for (int i = 0; i < s.Length; i++) { char c = s[i]; switch (c) { case 'C': desc[i] = RootSignatureParamP.CBV; break; case 'c': desc[i] = RootSignatureParamP.CBVTable; break; case 'S': desc[i] = RootSignatureParamP.SRV; break; case 's': desc[i] = RootSignatureParamP.SRVTable; break; case 'U': desc[i] = RootSignatureParamP.UAV; break; case 'u': desc[i] = RootSignatureParamP.UAVTable; break; default: throw new NotImplementedException("error root signature desc."); break; } } context.device.CreateRootSignature(rootSignature, desc); return(rootSignature); }
public void LoadShaders(string path) { BuildDescriptorHeaps(); BuildConstantBuffers <Simple2DConst>(); if (RootMake == null) { BuildRootSignature(); Root = _rootSignature; } else { RootMake?.Invoke(); } VertexCode = LoadVertex(path); FragCode = LoadFrag(path); SetupShader(); var psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(Input), RootSignature = Root, VertexShader = VertexCode, PixelShader = FragCode, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = false, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; //psoDesc. pipelineState = DXGlobal.device.CreateGraphicsPipelineState(psoDesc); _pip = pipelineState; // commandList = DXGlobal.device.CreateCommandList(CommandListType.Direct, DXGlobal.Display.DirectCmdListAlloc, pipelineState); }
public async Task <PipelineState> CreateGraphicsPipelineStateAsync(InputElementDescription[] inputElements) { CompiledShader compiledShader = await CreateShaderAsync(); RootSignature rootSignature = CreateRootSignature(); PipelineState pipelineState = new PipelineState(GraphicsDevice, rootSignature, inputElements, compiledShader.Shaders["vertex"], compiledShader.Shaders["pixel"], compiledShader.Shaders.ContainsKey("geometry") ? compiledShader.Shaders["geometry"] : null, compiledShader.Shaders.ContainsKey("hull") ? compiledShader.Shaders["hull"] : null, compiledShader.Shaders.ContainsKey("domain") ? compiledShader.Shaders["domain"] : null); return(pipelineState); }
private void BuildRootSignature() { // Root parameter can be a table, root descriptor or root constants. // Perfomance TIP: Order from most frequent to least frequent. var slotRootParameters = new[] { new RootParameter(ShaderVisibility.All, new RootDescriptor(0, 0), RootParameterType.ShaderResourceView), new RootParameter(ShaderVisibility.All, new RootDescriptor(1, 0), RootParameterType.ShaderResourceView), new RootParameter(ShaderVisibility.All, new RootDescriptor(0, 0), RootParameterType.UnorderedAccessView) }; // A root signature is an array of root parameters. var rootSigDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, slotRootParameters); _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize()); }
private void BuildRootSignature() { // Root parameter can be a table, root descriptor or root constants. var slotRootParameters = new[] { // TODO: API suggestion: RootDescriptor register space default value = 0. new RootParameter(ShaderVisibility.Vertex, new RootDescriptor(0, 0), RootParameterType.ConstantBufferView), new RootParameter(ShaderVisibility.Vertex, new RootDescriptor(1, 0), RootParameterType.ConstantBufferView) }; // A root signature is an array of root parameters. var rootSigDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, slotRootParameters); // Create a root signature with a single slot which points to a descriptor range consisting of a single constant buffer. _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize()); }
public void Initialize() { // Pipeline state. var testShaderPath = "../../../../../Resources/Engine/Forward/Standard.hlsl"; VertexShader = ShaderBytecode.CompileFromFile(testShaderPath, "VSMain", "vs_5_0"); PixelShader = ShaderBytecode.CompileFromFile(testShaderPath, "PSMain", "ps_5_0"); // Root parameters. var rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.All, new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, OffsetInDescriptorsFromTableStart = int.MinValue, DescriptorCount = 1, }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.Sampler, BaseShaderRegister = 0, DescriptorCount = 1 }), }; var rootSignatureDescription = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters); RootSignature = RootSignature.Create(Device, rootSignatureDescription); Layout = new DescriptorLayout( DescriptorLayout.EntryType.ConstantBufferShaderResourceOrUnorderedAccessView, DescriptorLayout.EntryType.ConstantBufferShaderResourceOrUnorderedAccessView, DescriptorLayout.EntryType.SamplerState); }
public void Execute(GraphicsCommandList cmdList, RootSignature rootSig, PipelineState pso, GpuDescriptorHandle input) { cmdList.SetComputeRootSignature(rootSig); cmdList.PipelineState = pso; cmdList.SetComputeRootDescriptorTable(0, input); cmdList.SetComputeRootDescriptorTable(2, _gpuUav); cmdList.ResourceBarrierTransition(_output, ResourceStates.GenericRead, ResourceStates.UnorderedAccess); // How many groups do we need to dispatch to cover image, where each // group covers 16x16 pixels. int numGroupsX = (int)Math.Ceiling(_width / 16.0); int numGroupsY = (int)Math.Ceiling(_height / 16.0); cmdList.Dispatch(numGroupsX, numGroupsY, 1); cmdList.ResourceBarrierTransition(_output, ResourceStates.UnorderedAccess, ResourceStates.GenericRead); }
private static async Task ExecuteOnGpu(GraphicsDevice device, StructuredBuffer <float> sourceBufferView, WriteableStructuredBuffer <float> destinationBufferView) { bool generateWithDelegate = false; DescriptorSet descriptorSet = new DescriptorSet(device, 2); descriptorSet.AddResourceViews(destinationBufferView); descriptorSet.AddResourceViews(sourceBufferView); // Generate computer shader ShaderGenerator shaderGenerator = generateWithDelegate ? CreateShaderGeneratorWithDelegate(sourceBufferView, destinationBufferView) : CreateShaderGeneratorWithClass(); ShaderGeneratorResult result = shaderGenerator.GenerateShader(); // Compile shader byte[] shaderBytecode = ShaderCompiler.Compile(ShaderStage.ComputeShader, result.ShaderSource, result.EntryPoints["compute"]); DescriptorRange[] descriptorRanges = new DescriptorRange[] { new DescriptorRange(DescriptorRangeType.UnorderedAccessView, 1, 0), new DescriptorRange(DescriptorRangeType.ShaderResourceView, 1, 0) }; RootParameter rootParameter = new RootParameter(new RootDescriptorTable(descriptorRanges), ShaderVisibility.All); RootSignatureDescription rootSignatureDescription = new RootSignatureDescription(RootSignatureFlags.None, new[] { rootParameter }); RootSignature rootSignature = new RootSignature(device, rootSignatureDescription); PipelineState pipelineState = new PipelineState(device, rootSignature, shaderBytecode); // Execute computer shader using (CommandList commandList = new CommandList(device, CommandListType.Compute)) { commandList.SetPipelineState(pipelineState); commandList.SetComputeRootDescriptorTable(0, descriptorSet); commandList.Dispatch(1, 1, 1); await commandList.FlushAsync(); } }
private void BuildRootSignature() { var cbvTable0 = new DescriptorRange(DescriptorRangeType.ConstantBufferView, 1, 0); var cbvTable1 = new DescriptorRange(DescriptorRangeType.ConstantBufferView, 1, 1); // Root parameter can be a table, root descriptor or root constants. var slotRootParameters = new[] { new RootParameter(ShaderVisibility.Vertex, cbvTable0), new RootParameter(ShaderVisibility.Vertex, cbvTable1) }; // A root signature is an array of root parameters. var rootSigDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, slotRootParameters); // Create a root signature with a single slot which points to a descriptor range consisting of a single constant buffer. _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize()); }
/// <summary> /// Compiles or recompiles the effect if necesssary. /// </summary> /// <param name="graphicsDevice"></param> /// <returns>True if the effect was recompiled, false otherwise.</returns> public bool UpdateEffect(GraphicsDevice graphicsDevice) { if (effect == null || permutationCounter != Parameters.PermutationCounter || (effect != null && effect.SourceChanged)) { permutationCounter = Parameters.PermutationCounter; var oldEffect = effect; ChooseEffect(graphicsDevice); // Early exit: same effect, and already initialized if (oldEffect == effect && descriptorReflection != null) { return(false); } // Update reflection and rearrange buffers/resources var layoutNames = effect.Bytecode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList(); descriptorReflection = EffectDescriptorSetReflection.New(graphicsDevice, effect.Bytecode, layoutNames, "Globals"); RootSignature?.Dispose(); RootSignature = RootSignature.New(graphicsDevice, descriptorReflection); bufferUploader.Clear(); bufferUploader.Compile(graphicsDevice, descriptorReflection, effect.Bytecode); // Create parameter updater var layouts = new DescriptorSetLayoutBuilder[descriptorReflection.Layouts.Count]; for (int i = 0; i < descriptorReflection.Layouts.Count; ++i) { layouts[i] = descriptorReflection.Layouts[i].Layout; } var parameterUpdaterLayout = new EffectParameterUpdaterLayout(graphicsDevice, effect, layouts); parameterUpdater = new EffectParameterUpdater(parameterUpdaterLayout, Parameters); descriptorSets = new DescriptorSet[parameterUpdater.ResourceGroups.Length]; return(true); } return(false); }
public void Disturb(GraphicsCommandList cmdList, RootSignature rootSig, PipelineState pso, int i, int j, float magnitude) { cmdList.PipelineState = pso; cmdList.SetComputeRootSignature(rootSig); // Set the disturb constants. int[] disturbIndex = { j, i }; Utilities.Pin(ref magnitude, ptr => cmdList.SetComputeRoot32BitConstants(0, 1, ptr, 3)); Utilities.Pin(disturbIndex, ptr => cmdList.SetComputeRoot32BitConstants(0, 2, ptr, 4)); cmdList.SetComputeRootDescriptorTable(3, _currSolUav); // The current solution is in the GENERIC_READ state so it can be read by the vertex shader. // Change it to UNORDERED_ACCESS for the compute shader. Note that a UAV can still be // read in a compute shader. cmdList.ResourceBarrierTransition(_currSol, ResourceStates.GenericRead, ResourceStates.UnorderedAccess); // One thread group kicks off one thread, which displaces the height of one // vertex and its neighbors. cmdList.Dispatch(1, 1, 1); }
private void BuildRootSignature() { // Shader programs typically require resources as input (constant buffers, // textures, samplers). The root signature defines the resources the shader // programs expect. If we think of the shader programs as a function, and // the input resources as function parameters, then the root signature can be // thought of as defining the function signature. // Root parameter can be a table, root descriptor or root constants. // Create a single descriptor table of CBVs. var cbvTable = new DescriptorRange(DescriptorRangeType.ConstantBufferView, 1, 0); // A root signature is an array of root parameters. var rootSigDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new[] { new RootParameter(ShaderVisibility.Vertex, cbvTable) }); _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize()); }
private void BuildWavesRootSignature() { var uavTable0 = new DescriptorRange(DescriptorRangeType.UnorderedAccessView, 1, 0); var uavTable1 = new DescriptorRange(DescriptorRangeType.UnorderedAccessView, 1, 1); var uavTable2 = new DescriptorRange(DescriptorRangeType.UnorderedAccessView, 1, 2); // Root parameter can be a table, root descriptor or root constants. // Perfomance TIP: Order from most frequent to least frequent. var slotRootParameters = new[] { new RootParameter(ShaderVisibility.All, new RootConstants(0, 0, 6)), new RootParameter(ShaderVisibility.All, uavTable0), new RootParameter(ShaderVisibility.All, uavTable1), new RootParameter(ShaderVisibility.All, uavTable2), }; // A root signature is an array of root parameters. var rootSigDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, slotRootParameters); _wavesRootSignature = Device.CreateRootSignature(rootSigDesc.Serialize()); }
private void BuildRootSignature() { // Perfomance TIP: Order from most frequent to least frequent. var descriptor1 = new RootDescriptor(0, 0); var descriptor2 = new RootDescriptor(1, 0); var descriptor3 = new RootDescriptor(2, 0); // Root parameter can be a table, root descriptor or root constants. var slotRootParameters = new[] { new RootParameter(ShaderVisibility.Vertex, descriptor1, RootParameterType.ConstantBufferView), new RootParameter(ShaderVisibility.Pixel, descriptor2, RootParameterType.ConstantBufferView), new RootParameter(ShaderVisibility.All, descriptor3, RootParameterType.ConstantBufferView) }; // A root signature is an array of root parameters. var rootSigDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, slotRootParameters); // Create a root signature with a single slot which points to a descriptor range consisting of a single constant buffer. _rootSignature = Device.CreateRootSignature(rootSigDesc.Serialize()); }
private void LoadAssets() { RootParameter parameter1 = new RootParameter(ShaderVisibility.All, new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, DescriptorCount = 1 }); RootParameter parameter2 = new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, BaseShaderRegister = 0, DescriptorCount = 1 }); RootParameter parameter3 = new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.Sampler, BaseShaderRegister = 0, DescriptorCount = 1 }); // Create a root signature. RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter1, parameter2, parameter3 }); rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION",0,Format.R32G32B32_Float,0,0), new InputElement("NORMAL",0,Format.R32G32B32_Float,12,0), new InputElement("TEXCOORD",0,Format.R32G32B32_Float,24,0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Create the command list. commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. commandList.Close(); // Create the vertex buffer. float aspectRatio = viewport.Width / viewport.Height; //constant Buffer int constantBufferSize = (Utilities.SizeOf<Transform>() + 255) & ~255; constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(constantBufferSize), ResourceStates.GenericRead); constantBufferDescriptorSize = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView); //constant buffer ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription() { BufferLocation = constantBuffer.GPUVirtualAddress, SizeInBytes = constantBufferSize }; CpuDescriptorHandle cbHandleHeapStart = constantBufferViewHeap.CPUDescriptorHandleForHeapStart; device.CreateConstantBufferView(cbvDesc, cbHandleHeapStart); cbvDesc.BufferLocation += Utilities.SizeOf<Transform>(); cbHandleHeapStart += constantBufferDescriptorSize; LoadMesh(cbHandleHeapStart); // Create synchronization objects. { fence = device.CreateFence(0, FenceFlags.None); fenceValue = 1; // Create an event handle to use for frame synchronization. fenceEvent = new AutoResetEvent(false); } InitBundles(); }
/// <param name="context"></param> /// <inheritdoc/> public override void PrepareEffectPermutations(RenderDrawContext context) { base.PrepareEffectPermutations(context); // TODO: Temporary until we have a better system for handling permutations var renderEffects = RenderData.GetData(RenderEffectKey); int effectSlotCount = EffectPermutationSlotCount; Dispatcher.ForEach(RenderSystem.Views, view => { var viewFeature = view.Features[Index]; Dispatcher.ForEach(viewFeature.RenderNodes, renderNodeReference => { var renderNode = this.GetRenderNode(renderNodeReference); var renderObject = renderNode.RenderObject; // Get RenderEffect var staticObjectNode = renderObject.StaticObjectNode; var staticEffectObjectNode = staticObjectNode * effectSlotCount + effectSlots[renderNode.RenderStage.Index].Index; var renderEffect = renderEffects[staticEffectObjectNode]; var effectSelector = renderObject.ActiveRenderStages[renderNode.RenderStage.Index].EffectSelector; // Create it (first time) or regenerate it if effect changed if (renderEffect == null || effectSelector != renderEffect.EffectSelector) { renderEffect = new RenderEffect(renderObject.ActiveRenderStages[renderNode.RenderStage.Index].EffectSelector); renderEffects[staticEffectObjectNode] = renderEffect; } // Is it the first time this frame that we check this RenderEffect? if (renderEffect.MarkAsUsed(RenderSystem)) { renderEffect.EffectValidator.BeginEffectValidation(); } }); }); // Step1: Perform permutations PrepareEffectPermutationsImpl(context); PrepareRenderTargetExtensionsMixins(context); var currentTime = DateTime.UtcNow; // Step2: Compile effects Dispatcher.ForEach(RenderObjects, renderObject => { //var renderObject = RenderObjects[index]; var staticObjectNode = renderObject.StaticObjectNode; for (int i = 0; i < effectSlotCount; ++i) { var staticEffectObjectNode = staticObjectNode * effectSlotCount + i; var renderEffect = renderEffects[staticEffectObjectNode]; // Skip if not used if (renderEffect == null) { continue; } // Skip reflection update unless a state change requires it renderEffect.IsReflectionUpdateRequired = false; if (!renderEffect.IsUsedDuringThisFrame(RenderSystem)) { continue; } // Skip if nothing changed if (renderEffect.EffectValidator.ShouldSkip) { // Reset pending effect, as it is now obsolete anyway renderEffect.Effect = null; renderEffect.State = RenderEffectState.Skip; } else if (renderEffect.EffectValidator.EndEffectValidation() && (renderEffect.Effect == null || !renderEffect.Effect.SourceChanged) && !(renderEffect.State == RenderEffectState.Error && currentTime >= renderEffect.RetryTime)) { InvalidateEffectPermutation(renderObject, renderEffect); // Still, let's check if there is a pending effect compiling var pendingEffect = renderEffect.PendingEffect; if (pendingEffect == null || !pendingEffect.IsCompleted) { continue; } renderEffect.ClearFallbackParameters(); if (pendingEffect.IsFaulted) { // The effect can fail compilation asynchronously renderEffect.State = RenderEffectState.Error; renderEffect.Effect = ComputeFallbackEffect?.Invoke(renderObject, renderEffect, RenderEffectState.Error); } else { renderEffect.State = RenderEffectState.Normal; renderEffect.Effect = pendingEffect.Result; } renderEffect.PendingEffect = null; } else { // Reset pending effect, as it is now obsolete anyway renderEffect.PendingEffect = null; renderEffect.State = RenderEffectState.Normal; // CompilerParameters are ThreadStatic if (staticCompilerParameters == null) { staticCompilerParameters = new CompilerParameters(); } foreach (var effectValue in renderEffect.EffectValidator.EffectValues) { staticCompilerParameters.SetObject(effectValue.Key, effectValue.Value); } TaskOrResult <Effect> asyncEffect; try { // The effect can fail compilation synchronously asyncEffect = RenderSystem.EffectSystem.LoadEffect(renderEffect.EffectSelector.EffectName, staticCompilerParameters); staticCompilerParameters.Clear(); } catch { staticCompilerParameters.Clear(); renderEffect.ClearFallbackParameters(); renderEffect.State = RenderEffectState.Error; renderEffect.Effect = ComputeFallbackEffect?.Invoke(renderObject, renderEffect, RenderEffectState.Error); continue; } renderEffect.Effect = asyncEffect.Result; if (renderEffect.Effect == null) { // Effect still compiling, let's find if there is a fallback renderEffect.ClearFallbackParameters(); renderEffect.PendingEffect = asyncEffect.Task; renderEffect.State = RenderEffectState.Compiling; renderEffect.Effect = ComputeFallbackEffect?.Invoke(renderObject, renderEffect, RenderEffectState.Compiling); } } renderEffect.IsReflectionUpdateRequired = true; } }); // Step3: Uupdate reflection infos (offset, etc...) foreach (var renderObject in RenderObjects) { var staticObjectNode = renderObject.StaticObjectNode; for (int i = 0; i < effectSlotCount; ++i) { var staticEffectObjectNode = staticObjectNode * effectSlotCount + i; var renderEffect = renderEffects[staticEffectObjectNode]; // Skip if not used if (renderEffect == null || !renderEffect.IsReflectionUpdateRequired) { continue; } var effect = renderEffect.Effect; if (effect == null && renderEffect.State == RenderEffectState.Compiling) { // Need to wait for completion because we have nothing else renderEffect.PendingEffect.Wait(); if (!renderEffect.PendingEffect.IsFaulted) { renderEffect.Effect = effect = renderEffect.PendingEffect.Result; renderEffect.State = RenderEffectState.Normal; } else { renderEffect.ClearFallbackParameters(); renderEffect.State = RenderEffectState.Error; renderEffect.Effect = effect = ComputeFallbackEffect?.Invoke(renderObject, renderEffect, RenderEffectState.Error); } } var effectHashCode = effect != null ? (uint)effect.GetHashCode() : 0; // Effect is last 16 bits renderObject.StateSortKey = (renderObject.StateSortKey & 0xFFFF0000) | (effectHashCode & 0x0000FFFF); if (effect != null) { RenderEffectReflection renderEffectReflection; if (!InstantiatedEffects.TryGetValue(effect, out renderEffectReflection)) { renderEffectReflection = new RenderEffectReflection(); // Build root signature automatically from reflection renderEffectReflection.DescriptorReflection = EffectDescriptorSetReflection.New(RenderSystem.GraphicsDevice, effect.Bytecode, effectDescriptorSetSlots, "PerFrame"); renderEffectReflection.ResourceGroupDescriptions = new ResourceGroupDescription[renderEffectReflection.DescriptorReflection.Layouts.Count]; // Compute ResourceGroup hashes for (int index = 0; index < renderEffectReflection.DescriptorReflection.Layouts.Count; index++) { var descriptorSet = renderEffectReflection.DescriptorReflection.Layouts[index]; if (descriptorSet.Layout == null) { continue; } var constantBufferReflection = effect.Bytecode.Reflection.ConstantBuffers.FirstOrDefault(x => x.Name == descriptorSet.Name); renderEffectReflection.ResourceGroupDescriptions[index] = new ResourceGroupDescription(descriptorSet.Layout, constantBufferReflection); } renderEffectReflection.RootSignature = RootSignature.New(RenderSystem.GraphicsDevice, renderEffectReflection.DescriptorReflection); renderEffectReflection.BufferUploader.Compile(RenderSystem.GraphicsDevice, renderEffectReflection.DescriptorReflection, effect.Bytecode); // Prepare well-known descriptor set layouts renderEffectReflection.PerDrawLayout = CreateDrawResourceGroupLayout(renderEffectReflection.ResourceGroupDescriptions[perDrawDescriptorSetSlot.Index], renderEffect.State); renderEffectReflection.PerFrameLayout = CreateFrameResourceGroupLayout(renderEffectReflection.ResourceGroupDescriptions[perFrameDescriptorSetSlot.Index], renderEffect.State); renderEffectReflection.PerViewLayout = CreateViewResourceGroupLayout(renderEffectReflection.ResourceGroupDescriptions[perViewDescriptorSetSlot.Index], renderEffect.State); InstantiatedEffects.Add(effect, renderEffectReflection); // Notify a new effect has been compiled EffectCompiled?.Invoke(RenderSystem, effect, renderEffectReflection); } // Setup fallback parameters if (renderEffect.State != RenderEffectState.Normal && renderEffectReflection.FallbackUpdaterLayout == null) { // Process all "non standard" layouts var layoutMapping = new int[renderEffectReflection.DescriptorReflection.Layouts.Count - 3]; var layouts = new DescriptorSetLayoutBuilder[renderEffectReflection.DescriptorReflection.Layouts.Count - 3]; int layoutMappingIndex = 0; for (int index = 0; index < renderEffectReflection.DescriptorReflection.Layouts.Count; index++) { var layout = renderEffectReflection.DescriptorReflection.Layouts[index]; // Skip well-known layouts (already handled) if (layout.Name == "PerDraw" || layout.Name == "PerFrame" || layout.Name == "PerView") { continue; } layouts[layoutMappingIndex] = layout.Layout; layoutMapping[layoutMappingIndex++] = index; } renderEffectReflection.FallbackUpdaterLayout = new EffectParameterUpdaterLayout(RenderSystem.GraphicsDevice, effect, layouts); renderEffectReflection.FallbackResourceGroupMapping = layoutMapping; } // Update effect renderEffect.Effect = effect; renderEffect.Reflection = renderEffectReflection; // Invalidate pipeline state (new effect) renderEffect.PipelineState = null; renderEffects[staticEffectObjectNode] = renderEffect; } else { renderEffect.Reflection = RenderEffectReflection.Empty; renderEffect.PipelineState = null; } } } }
private void LoadAssets() { DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, DescriptorCount = 1 } }; RootParameter parameter = new RootParameter(ShaderVisibility.Vertex, ranges); // Create a root signature. RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter }); rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION",0,Format.R32G32B32_Float,0,0), new InputElement("COLOR",0,Format.R32G32B32A32_Float,12,0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Create the command list. commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. commandList.Close(); // Create the vertex buffer. float aspectRatio = viewport.Width / viewport.Height; // Define the geometry for a cube. Vertex[] vertices = new[] { ////TOP new Vertex(new Vector3(-5,5,5),new Vector4(0,1,0,0)), new Vertex(new Vector3(5,5,5),new Vector4(0,1,0,0)), new Vertex(new Vector3(5,5,-5),new Vector4(0,1,0,0)), new Vertex(new Vector3(-5,5,-5),new Vector4(0,1,0,0)), //BOTTOM new Vertex(new Vector3(-5,-5,5),new Vector4(1,0,1,1)), new Vertex(new Vector3(5,-5,5),new Vector4(1,0,1,1)), new Vertex(new Vector3(5,-5,-5),new Vector4(1,0,1,1)), new Vertex(new Vector3(-5,-5,-5),new Vector4(1,0,1,1)), //LEFT new Vertex(new Vector3(-5,-5,5),new Vector4(1,0,0,1)), new Vertex(new Vector3(-5,5,5),new Vector4(1,0,0,1)), new Vertex(new Vector3(-5,5,-5),new Vector4(1,0,0,1)), new Vertex(new Vector3(-5,-5,-5),new Vector4(1,0,0,1)), //RIGHT new Vertex(new Vector3(5,-5,5),new Vector4(1,1,0,1)), new Vertex(new Vector3(5,5,5),new Vector4(1,1,0,1)), new Vertex(new Vector3(5,5,-5),new Vector4(1,1,0,1)), new Vertex(new Vector3(5,-5,-5),new Vector4(1,1,0,1)), //FRONT new Vertex(new Vector3(-5,5,5),new Vector4(0,1,1,1)), new Vertex(new Vector3(5,5,5),new Vector4(0,1,1,1)), new Vertex(new Vector3(5,-5,5),new Vector4(0,1,1,1)), new Vertex(new Vector3(-5,-5,5),new Vector4(0,1,1,1)), //BACK new Vertex(new Vector3(-5,5,-5),new Vector4(0,0,1,1)), new Vertex(new Vector3(5,5,-5),new Vector4(0,0,1,1)), new Vertex(new Vector3(5,-5,-5),new Vector4(0,0,1,1)), new Vertex(new Vector3(-5,-5,-5),new Vector4(0,0,1,1)) }; int vertexBufferSize = Utilities.SizeOf(vertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, vertices, 0, vertices.Length); vertexBuffer.Unmap(0); // Initialize the vertex buffer view. vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf<Vertex>(); vertexBufferView.SizeInBytes = vertexBufferSize; //Create Index Buffer //Indices int[] indices = new int[] { 0,1,2,0,2,3, 4,6,5,4,7,6, 8,9,10,8,10,11, 12,14,13,12,15,14, 16,18,17,16,19,18, 20,21,22,20,22,23 }; int indexBufferSize = Utilities.SizeOf(indices); indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pIndexDataBegin = indexBuffer.Map(0); Utilities.Write(pIndexDataBegin, indices, 0, indices.Length); indexBuffer.Unmap(0); // Initialize the index buffer view. indexBufferView = new IndexBufferView(); indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress; indexBufferView.Format = Format.R32_UInt; indexBufferView.SizeInBytes = indexBufferSize; //constant Buffer for each cubes constantBufferViewHeap = device.CreateDescriptorHeap(new DescriptorHeapDescription() { DescriptorCount = NumCubes, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, Flags = DescriptorHeapFlags.ShaderVisible }); int constantBufferSize = (Utilities.SizeOf<Transform>() + 255) & ~255; constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(constantBufferSize * NumCubes), ResourceStates.GenericRead); constantBufferDescriptorSize = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView); //First cube ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription() { BufferLocation = constantBuffer.GPUVirtualAddress, SizeInBytes = constantBufferSize }; CpuDescriptorHandle cbHandleHeapStart = constantBufferViewHeap.CPUDescriptorHandleForHeapStart; for (int i = 0; i < NumCubes; i++) { device.CreateConstantBufferView(cbvDesc, cbHandleHeapStart); cbvDesc.BufferLocation += Utilities.SizeOf<Transform>(); cbHandleHeapStart += constantBufferDescriptorSize; } InitBundles(); }
public void BuildPSO(Device3 device, GraphicsCommandList commandList) { World = Matrix.Translation(-2.5f, -2.5f, -2.5f); buffer.World = World; light = new Lighting { GlobalAmbientX = 1, GlobalAmbientY = 1, GlobalAmbientZ = 1, KaX = .1f, KaY = .1f, KaZ = .1f, KdX = .5f, KdY = .5f, KdZ = .5f, KeX = .25f, KeY = .25f, KeZ = .25f, KsX = .1f, KsY = .1f, KsZ = .1f, LightColorX = 1, LightColorY = 1, LightColorZ = 1, LightPositionX = 10, LightPositionY = 10, LightPositionZ = 10, shininess = 5 }; DescriptorHeapDescription srvHeapDesc = new DescriptorHeapDescription() { DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView }; _srvDescriptorHeap = device.CreateDescriptorHeap(srvHeapDesc); //setup descriptor ranges DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 } }; //Get sampler state setup StaticSamplerDescription sampler = new StaticSamplerDescription() { Filter = Filter.MinimumMinMagMipPoint, AddressU = TextureAddressMode.Border, AddressV = TextureAddressMode.Border, AddressW = TextureAddressMode.Border, MipLODBias = 0, MaxAnisotropy = 0, ComparisonFunc = Comparison.Never, BorderColor = StaticBorderColor.TransparentBlack, MinLOD = 0.0f, MaxLOD = float.MaxValue, ShaderRegister = 0, RegisterSpace = 0, ShaderVisibility = ShaderVisibility.Pixel, }; Projection = Matrix.PerspectiveFovLH((float)Math.PI / 3f, 4f / 3f, 1, 1000); View = Matrix.LookAtLH(new Vector3(10 * (float)Math.Sin(rotation), 5, 10 * (float)Math.Cos(rotation)), Vector3.Zero, Vector3.UnitY); World = Matrix.Translation(-2.5f, -2.5f, -2.5f); DescriptorHeapDescription cbvHeapDesc = new DescriptorHeapDescription() { DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView }; _objectViewHeap = device.CreateDescriptorHeap(cbvHeapDesc); _lightingViewHeap = device.CreateDescriptorHeap(cbvHeapDesc); RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges), new RootParameter(ShaderVisibility.All, new RootDescriptor(1, 0), RootParameterType.ConstantBufferView), new RootParameter(ShaderVisibility.All, new RootDescriptor(2, 0), RootParameterType.ConstantBufferView) }; // Create an empty root signature. RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler }); _rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 24, 0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = _rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D24_UNorm_S8_UInt, DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; _pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Define the geometry for a triangle. Vertex[] triangleVertices = new Vertex[] { //Front new Vertex() { Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitZ }, new Vertex() { Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitZ }, //Back new Vertex() { Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitZ }, new Vertex() { Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitZ }, //Left new Vertex() { Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitX }, new Vertex() { Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitX }, new Vertex() { Position = new Vector3(0, 0, 5), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitX }, new Vertex() { Position = new Vector3(0, 5, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitX }, //Right new Vertex() { Position = new Vector3(5, 0, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitX }, new Vertex() { Position = new Vector3(5, 5, 0), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitX }, new Vertex() { Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitX }, new Vertex() { Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitX }, //Top new Vertex() { Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitY }, new Vertex() { Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitY }, //Bottom new Vertex() { Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitY }, new Vertex() { Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitY } }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. _vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = _vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); _vertexBuffer.Unmap(0); _indicies = new int[] { 0, 1, 2, 3, 2, 1, 6, 5, 4, 5, 6, 7, 10, 9, 8, 9, 10, 11, 12, 13, 14, 15, 14, 13, 18, 17, 16, 17, 18, 19, 20, 21, 22, 23, 22, 21 }; int indBufferSize = Utilities.SizeOf(_indicies); _indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indBufferSize), ResourceStates.GenericRead); IntPtr pIndBegin = _indexBuffer.Map(0); Utilities.Write(pIndBegin, _indicies, 0, _indicies.Length); _indexBuffer.Unmap(0); _indexBufferView = new IndexBufferView() { BufferLocation = _indexBuffer.GPUVirtualAddress, Format = Format.R32_UInt, SizeInBytes = indBufferSize }; // Initialize the vertex buffer view. _vertexBufferView = new VertexBufferView { BufferLocation = _vertexBuffer.GPUVirtualAddress, StrideInBytes = Utilities.SizeOf <Vertex>(), SizeInBytes = vertexBufferSize }; _objectBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <ObjectData>()), ResourceStates.GenericRead); //// Describe and create a constant buffer view. ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription() { BufferLocation = _objectBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf <ObjectData>() + 255) & ~255 }; device.CreateConstantBufferView(cbvDesc, _objectViewHeap.CPUDescriptorHandleForHeapStart); // Initialize and map the constant buffers. We don't unmap this until the // app closes. Keeping things mapped for the lifetime of the resource is okay. _objectPointer = _objectBuffer.Map(0); Utilities.Write(_objectPointer, ref buffer); _lightingBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <Lighting>()), ResourceStates.GenericRead); //// Describe and create a constant buffer view. ConstantBufferViewDescription cbvDesc2 = new ConstantBufferViewDescription() { BufferLocation = _objectBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf <Lighting>() + 255) & ~255 }; device.CreateConstantBufferView(cbvDesc2, _lightingViewHeap.CPUDescriptorHandleForHeapStart); // Initialize and map the constant buffers. We don't unmap this until the // app closes. Keeping things mapped for the lifetime of the resource is okay. _lightingPointer = _lightingBuffer.Map(0); Utilities.Write(_lightingPointer, ref light); Resource textureUploadHeap; // Create the texture. // Describe and create a Texture2D. ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight); _texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination); long uploadBufferSize = GetRequiredIntermediateSize(device, _texture, 0, 1); // Create the GPU upload buffer. textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight), ResourceStates.GenericRead); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. byte[] textureData = GenerateTextureData(); GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned); IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0); textureUploadHeap.WriteToSubresource(0, null, ptr, 4 * textureWidth, textureData.Length); handle.Free(); commandList.CopyTextureRegion(new TextureCopyLocation(_texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null); commandList.ResourceBarrierTransition(_texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource); // Describe and create a SRV for the texture. ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription() { Shader4ComponentMapping = ComponentMapping(0, 1, 2, 3), Format = textureDesc.Format, Dimension = ShaderResourceViewDimension.Texture2D, }; srvDesc.Texture2D.MipLevels = 1; device.CreateShaderResourceView(_texture, srvDesc, _srvDescriptorHeap.CPUDescriptorHandleForHeapStart); _resources = new[] { new GraphicsResource() { Heap = _srvDescriptorHeap, Register = 0, type = ResourceType.DescriptorTable }, new GraphicsResource() { Resource = _objectBuffer, Register = 2, type = ResourceType.ConstantBufferView }, new GraphicsResource() { Resource = _lightingBuffer, Register = 1, type = ResourceType.ConstantBufferView } }; }
private void CreateDeviceResources() { #if DEBUG Configuration.EnableObjectTracking = true; Configuration.ThrowOnShaderCompileError = false; // Enable the D3D12 debug layer. DebugInterface.Get().EnableDebugLayer(); #endif using (var factory = new Factory4()) { // Create the Direct3D 12 API device object device = new Device(null, SharpDX.Direct3D.FeatureLevel.Level_11_0); if (device == null) { // TODO: We want to be able to specify adaptor var adapter = factory.Adapters[0]; device = new Device(adapter, SharpDX.Direct3D.FeatureLevel.Level_11_0); } // Create the command queue. var queueDesc = new CommandQueueDescription(CommandListType.Direct); commandQueue = device.CreateCommandQueue(queueDesc); commandQueue.Name = $"CommandQueue"; // Create Command Allocator buffers. for (int i = 0; i < FrameCount; i++) { commandAllocators[i] = device.CreateCommandAllocator(CommandListType.Direct); commandAllocators[i].Name = $"CommandAllocator F{i}"; } } // Create RootSignature. var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new[] { new RootParameter(ShaderVisibility.Vertex, new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0, }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 }) }, new[] { new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0) { Filter = Filter.MinimumMinMagMipPoint, AddressUVW = TextureAddressMode.Border, } }); rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create Constant Buffer View Heap. var cbvHeapDesc = new DescriptorHeapDescription() { DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, }; cbvHeap = device.CreateDescriptorHeap(cbvHeapDesc); cbvHeap.Name = "CBV Heap"; // Create Shader Render View Heap. var srvHeapDesc = new DescriptorHeapDescription() { DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, }; srvHeap = device.CreateDescriptorHeap(srvHeapDesc); srvHeap.Name = "SRV Heap"; // Create synchronization objects. fence = device.CreateFence(fenceValues[currentFrame], FenceFlags.None); fence.Name = $"Fence"; fenceValues[currentFrame]++; // Create an event handle to use for frame synchronization. fenceEvent = new AutoResetEvent(false); }
//创建资源 private void LoadAssets() { //创建一个空的根签名 var rootSignatureDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, //根常量 new[] { new RootParameter(ShaderVisibility.All, //指定可以访问根签名绑定的内容的着色器,这里设置为顶点着色器 new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, //指定描述符范围,这里的参数是CBV BaseShaderRegister = 0, //指定描述符范围内的基本着色器 OffsetInDescriptorsFromTableStart = int.MinValue, //描述符从根签名开始的偏移量 DescriptorCount = 1 //描述符范围内的描述符数 }) }); //表示该根签名需要一组顶点缓冲区来绑定 rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); //创建流水线状态,负责编译和加载着色器 #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VS", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VS", "vs_5_0")); #endif //#if DEBUG // var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PS", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); //#else // var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PS", "ps_5_0")); //#endif //描述输入装配器阶段的输入元素,这里定义顶点输入布局 var inputElementDescs = new[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0) }; //创建流水线状态对象(PSO) var psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), //描述输入缓冲器 RootSignature = rootSignature, //根签名 VertexShader = vertexShader, //顶点着色器 //PixelShader = pixelShader,//像素着色器 RasterizerState = RasterizerStateDescription.Default(), //描述光栅器状态 BlendState = BlendStateDescription.Default(), //描述混合状态 DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, //描述深度/模板格式(纹理资源) DepthStencilState = DepthStencilStateDescription.Default(), //描述深度模板状态 SampleMask = int.MaxValue, //混合状态的样本掩码 PrimitiveTopologyType = PrimitiveTopologyType.Triangle, //定义该管道的几何或外壳着色器的输入类型,这里是三角 RenderTargetCount = 1, //RTVFormat成员中的渲染目标格式数 Flags = PipelineStateFlags.None, //用于控制管道状态的标志,这里表示没有标志 SampleDescription = new SampleDescription(1, 0), //描述资源的多采样参数 StreamOutput = new StreamOutputDescription() //描述输出缓冲器 }; psoDesc.RenderTargetFormats[0] = Format.R8G8B8A8_UNorm; //描述渲染目标格式的数组 //设置管道 pipelineState = device.CreateGraphicsPipelineState(psoDesc); //创建命令列表 commandList = device.CreateCommandList( CommandListType.Direct, //指定命令列表的创建类型,Direct命令列表不会继承任何GPU状态 commandAllocator, //指向设备创建的命令列表对象的指针 pipelineState); //指向(管道)内存块的指针 commandList.Close(); float aspectRatio = viewPort.Width / viewPort.Height; //定义待绘制图形的几何形状 string bitmapPath = @"C:\Users\yulanli\Desktop\TerrainForm\heightMap.BMP"; Bitmap bitmap = new Bitmap(bitmapPath); xCount = (bitmap.Width - 1) / 2; yCount = (bitmap.Height - 1) / 2; cellWidth = bitmap.Width / xCount; cellHeight = bitmap.Height / yCount; var vertices = new PositionTextured[(xCount + 1) * (yCount + 1)];//定义顶点 for (int i = 0; i < yCount + 1; i++) { for (int j = 0; j < xCount + 1; j++) { System.Drawing.Color color = bitmap.GetPixel((int)(j * cellWidth), (int)(i * cellHeight)); float height = float.Parse(color.R.ToString()) + float.Parse(color.G.ToString()) + float.Parse(color.B.ToString()); height /= 10; vertices[j + i * (xCount + 1)].Position = new Vector3(j * cellWidth, height, i * cellHeight); vertices[j + i * (xCount + 1)].Texcoord = new Vector2((float)j / (xCount + 1), (float)i / (yCount + 1)); } } texture = TextureLoader.TextureLoader.CreateTextureFromDDS(device, @"C:\Users\yulanli\Desktop\TerrainForm\colorMapDDS.DDS"); //创建待绘制图形的顶点索引 indices = new int[6 * xCount * yCount]; for (int i = 0; i < yCount; i++) { for (int j = 0; j < xCount; j++) { indices[6 * (j + i * xCount)] = j + i * (xCount + 1); indices[6 * (j + i * xCount) + 1] = j + (i + 1) * (xCount + 1); indices[6 * (j + i * xCount) + 2] = j + i * (xCount + 1) + 1; indices[6 * (j + i * xCount) + 3] = j + i * (xCount + 1) + 1; indices[6 * (j + i * xCount) + 4] = j + (i + 1) * (xCount + 1); indices[6 * (j + i * xCount) + 5] = j + (i + 1) * (xCount + 1) + 1; } } //创建视锥体 //创建摄像机 CamTarget = new Vector3(bitmap.Width / 2, 0f, bitmap.Height / 2); view = Matrix.LookAtLH( CamPostion, //摄像机原点 CamTarget, //摄像机观察目标点 Vector3.UnitY); //当前世界的向上方向的向量,通常为(0,1,0),即这里的UnitY参数 proj = Matrix.Identity; proj = Matrix.PerspectiveFovLH( (float)Math.PI / 4.0f, //用弧度制表示垂直视场角,这里是45°角 aspectRatio, //纵横比 0.3f, //到近平面的距离 500.0f //到远平面的距离 ); var worldViewProj = Matrix.Multiply(proj, view); //使用上传堆来传递顶点缓冲区的数据 /*--------------------------------------------------* * 不推荐使用上传堆来传递像顶点缓冲区这样的静态数据 * * 这里使用上载堆是为了代码的简洁性,并且还因为需要 * * 传递的资源很少 * *--------------------------------------------------*/ var vertexBufferSize = Utilities.SizeOf(vertices); vertexBuffer = device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); //将顶点的数据复制到顶点缓冲区 IntPtr pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write( pVertexDataBegin, vertices, 0, vertices.Length); vertexBuffer.Unmap(0); //初始化顶点缓冲区视图 vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf <PositionTextured>(); vertexBufferView.SizeInBytes = vertexBufferSize; //使用上传堆来传递索引缓冲区的数据 int indexBufferSize = Utilities.SizeOf(indices); indexBuffer = device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indexBufferSize), ResourceStates.GenericRead); //将索引的数据复制到索引缓冲区 IntPtr pIndexDataBegin = indexBuffer.Map(0); Utilities.Write( pIndexDataBegin, indices, 0, indices.Length); indexBuffer.Unmap(0); //初始化索引缓冲区视图 indexBufferView = new IndexBufferView(); indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress; indexBufferView.SizeInBytes = indexBufferSize; indexBufferView.Format = Format.R32_UInt; //创建bundle bundle = device.CreateCommandList( 0, CommandListType.Bundle, bundleAllocator, pipelineState); bundle.SetGraphicsRootSignature(rootSignature); bundle.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList; bundle.SetVertexBuffer(0, vertexBufferView); bundle.SetIndexBuffer(indexBufferView); //bundle.DrawInstanced( // vertices.Length,//VertexCountPerInstance,要绘制的顶点数 // 1,//InstanceCount,要绘制的实例数,这里是1个 // 0,//StartVertexLocation,第一个顶点的索引,这里是0 // 0);//StartInstanceLocation,在从顶点缓冲区读取每个实例数据之前添加到每个索引的值 bundle.DrawIndexedInstanced( indices.Length, //IndexCountPerInstance,要绘制的索引数 1, //InstanceCount,要绘制的实例数,这里是1个 0, //StartIndexLocation,第一个顶点的索引,这里是0 0, //BaseVertexLocation,,从顶点缓冲区读取顶点之前添加到每个索引的值 0); //StartInstanceLocation,在从顶点缓冲区读取每个实例数据之前添加到每个索引的值 bundle.Close(); //使用上传堆来传递常量缓冲区的数据 /*--------------------------------------------------* * 不推荐使用上传堆来传递像垂直缓冲区这样的静态数据 * * 这里使用上载堆是为了代码的简洁性,并且还因为需要 * * 传递的资源很少 * *--------------------------------------------------*/ constantBuffer = device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead); //创建SRV视图 var srvDesc = new ShaderResourceViewDescription(); srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.ResourceMinLODClamp = 0.0f; device.CreateShaderResourceView(texture, srvDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart); //创建常量缓冲区视图(CBV) var cbvDesc = new ConstantBufferViewDescription() { BufferLocation = constantBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf <ConstantBuffer>() + 255) & ~255 }; device.CreateConstantBufferView( cbvDesc, constantBufferViewHeap.CPUDescriptorHandleForHeapStart); //初始化并映射常量缓冲区 /*--------------------------------------------------* * 直到应用程序关闭,我们才会取消映射,因此在资源的 * * 生命周期中保持映射是可以的 * *------------------------------------------------- */ constantBufferPointer = constantBuffer.Map(0); Utilities.Write(constantBufferPointer, ref worldViewProj); //创建同步对象 //创建围栏 fence = device.CreateFence( 0, //围栏的初始值 FenceFlags.None); //指定围栏的类型,None表示没有指定的类型 fenceValue = 1; //创建用于帧同步的事件句柄 fenceEvent = new AutoResetEvent(false); }
private void LoadAssets() { DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, OffsetInDescriptorsFromTableStart = int.MinValue, DescriptorCount = 1 } }; RootParameter parameter = new RootParameter(ShaderVisibility.Vertex, ranges); // Create an empty root signature. RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter }); rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION",0,Format.R32G32B32_Float,0,0), new InputElement("COLOR",0,Format.R32G32B32A32_Float,12,0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = false, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Create the command list. commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); // Create the vertex buffer. float aspectRatio = viewport.Width / viewport.Height; // Define the geometry for a triangle. Vertex[] triangleVertices = new Vertex[] { new Vertex() {position=new Vector3(0.0f, 0.25f * aspectRatio, 0.0f ),color=new Vector4(1.0f, 0.0f, 0.0f, 1.0f ) }, new Vertex() {position=new Vector3(0.25f, -0.25f * aspectRatio, 0.0f),color=new Vector4(0.0f, 1.0f, 0.0f, 1.0f) }, new Vertex() {position=new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f),color=new Vector4(0.0f, 0.0f, 1.0f, 1.0f ) }, }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); vertexBuffer.Unmap(0); // Initialize the vertex buffer view. vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf<Vertex>(); vertexBufferView.SizeInBytes = vertexBufferSize; // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. commandList.Close(); constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead); //// Describe and create a constant buffer view. ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription() { BufferLocation = constantBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf<ConstantBuffer>() + 255) & ~255 }; device.CreateConstantBufferView(cbvDesc, constantBufferViewHeap.CPUDescriptorHandleForHeapStart); // Initialize and map the constant buffers. We don't unmap this until the // app closes. Keeping things mapped for the lifetime of the resource is okay. constantBufferPointer = constantBuffer.Map(0); Utilities.Write(constantBufferPointer, ref constantBufferData); // Create synchronization objects. fence = device.CreateFence(0, FenceFlags.None); fenceValue = 1; // Create an event handle to use for frame synchronization. fenceEvent = new AutoResetEvent(false); }
private void LoadAssets() { // Create the root signature description. var rootSignatureDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, // Root Parameters new[] { new RootParameter(ShaderVisibility.All, new [] { new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = 0, BaseShaderRegister = 0 } }), new RootParameter(ShaderVisibility.All, new RootConstants() { ShaderRegister = 1, Value32BitCount = 1 }), new RootParameter(ShaderVisibility.All, new [] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 2, OffsetInDescriptorsFromTableStart = 0, BaseShaderRegister = 0 } }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.Sampler, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = 0, BaseShaderRegister = 0 }), }); rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); // Define the vertex input layout. var inputElementDescs = new[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0), new InputElement("TANGENT", 0, Format.R32G32B32_Float, 24, 0), new InputElement("BITANGENT", 0, Format.R32G32B32_Float, 36, 0), new InputElement("DIFFUSE", 0, Format.R32G32B32_Float, 48, 0), new InputElement("EMISSIVE", 0, Format.R32G32B32_Float, 64, 0), new InputElement("SPECULAR", 0, Format.R32G32B32_Float, 80, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 96, 0) }; CreatePSO(inputElementDescs, vertexShader, pixelShader); // build model resources BuildModelResources(); // build depth buffer BuildDepthBuffer(); CreateTerrainBind(); BuildTerrainResouces(); fence = device.CreateFence(0, FenceFlags.None); fenceValue = 1; fenceEvent = new AutoResetEvent(false); }
private void CreateTerrainBind() { var rootSignatureDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, // Root Parameters new[] { new RootParameter(ShaderVisibility.All, new [] { new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = 0, BaseShaderRegister = 0 } }), new RootParameter(ShaderVisibility.All, new [] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 2, OffsetInDescriptorsFromTableStart = 0, BaseShaderRegister = 0 } }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.Sampler, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = 0, BaseShaderRegister = 0 }), }); terrainRootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize()); var inputElementDescs = new[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0), new InputElement("TANGENT", 0, Format.R32G32B32_Float, 24, 0), new InputElement("BITANGENT", 0, Format.R32G32B32_Float, 36, 0), new InputElement("DIFFUSE", 0, Format.R32G32B32_Float, 48, 0), new InputElement("EMISSIVE", 0, Format.R32G32B32_Float, 64, 0), new InputElement("SPECULAR", 0, Format.R32G32B32_Float, 80, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 96, 0) }; var psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = terrainRootSignature, VertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../Terrain.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)), PixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../Terrain.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)), RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthComparison = Comparison.LessEqual, DepthWriteMask = DepthWriteMask.All, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState2 = device.CreateGraphicsPipelineState(psoDesc); }
private void LoadAssets() { // Create an empty root signature. var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout); rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("shaders.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("shaders.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. var inputElementDescs = new [] { new InputElement("POSITION",0,Format.R32G32B32_Float,0,0), new InputElement("COLOR",0,Format.R32G32B32A32_Float,12,0) }; // Describe and create the graphics pipeline state object (PSO). var psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = false, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Create the command list. commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. commandList.Close(); // Create the vertex buffer. float aspectRatio = viewport.Width / viewport.Height; // Define the geometry for a triangle. var triangleVertices = new [] { new Vertex() {Position=new Vector3(0.0f, 0.25f * aspectRatio, 0.0f ),Color=new Vector4(1.0f, 0.0f, 0.0f, 1.0f ) }, new Vertex() {Position=new Vector3(0.25f, -0.25f * aspectRatio, 0.0f),Color=new Vector4(0.0f, 1.0f, 0.0f, 1.0f) }, new Vertex() {Position=new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f),Color=new Vector4(0.0f, 0.0f, 1.0f, 1.0f ) }, }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); vertexBuffer.Unmap(0); // Initialize the vertex buffer view. vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf<Vertex>(); vertexBufferView.SizeInBytes = vertexBufferSize; // Create and record the bundle. bundle = device.CreateCommandList(0, CommandListType.Bundle, bundleAllocator, pipelineState); bundle.SetGraphicsRootSignature(rootSignature); bundle.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList; bundle.SetVertexBuffer(0, vertexBufferView); bundle.DrawInstanced(3, 1, 0, 0); bundle.Close(); // Create synchronization objects. { fence = device.CreateFence(0, FenceFlags.None); fenceValue = 1; // Create an event handle to use for frame synchronization. fenceEvent = new AutoResetEvent(false); } }
/// <summary> /// Setup resources for rendering /// </summary> void LoadAssets() { // Create the main command list commandList = Collect(device.CreateCommandList(CommandListType.Direct, commandListAllocator, pipelineState)); // Create the descriptor heap for the render target view descriptorHeapRT = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription() { Type = DescriptorHeapType.RenderTargetView, DescriptorCount = 1 })); #if USE_DEPTH descriptorHeapDS = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription() { Type = DescriptorHeapType.DepthStencilView, DescriptorCount = 1 })); #endif #if USE_TEXTURE descriptorHeapCB = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription() { Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, DescriptorCount = 2, Flags = DescriptorHeapFlags.ShaderVisible, })); descriptorHeapS = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription() { Type = DescriptorHeapType.Sampler, DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, })); descriptorsHeaps[0] = descriptorHeapCB; descriptorsHeaps[1] = descriptorHeapS; #else descriptorHeapCB = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription() { Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, })); descriptorsHeaps[0] = descriptorHeapCB; #endif #if true // root signature in code var rsparams = new RootParameter[] { new RootParameter(ShaderVisibility.Vertex, new RootDescriptor(), RootParameterType.ConstantBufferView), new RootParameter(ShaderVisibility.Vertex, new DescriptorRange { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 1, DescriptorCount = 1, }), #if USE_TEXTURE new RootParameter(ShaderVisibility.Pixel, new DescriptorRange { RangeType = DescriptorRangeType.ShaderResourceView, BaseShaderRegister = 0, DescriptorCount = 1, }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange { RangeType = DescriptorRangeType.Sampler, BaseShaderRegister = 0, DescriptorCount = 1, }), #endif }; var rs = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rsparams); rootSignature = Collect(device.CreateRootSignature(rs.Serialize())); #else var rootSignatureByteCode = Utilities.ReadStream(assembly.GetManifestResourceStream("Shaders.Cube" + shaderNameSuffix + ".rs")); using (var bufferRootSignature = DataBuffer.Create(rootSignatureByteCode)) rootSignature = Collect(device.CreateRootSignature(bufferRootSignature)); #endif byte[] vertexShaderByteCode = GetResourceBytes("Cube" + shaderNameSuffix + ".vso"); byte[] pixelShaderByteCode = GetResourceBytes("Cube" + shaderNameSuffix + ".pso"); var layout = new InputLayoutDescription(new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0), new InputElement("NORMAL", 0, Format.R32G32B32_Float, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 0), #if USE_INSTANCES new InputElement("OFFSET", 0, Format.R32G32B32_Float, 0, 1, InputClassification.PerInstanceData, 1), #endif }); #region pipeline state var psd = new GraphicsPipelineStateDescription { InputLayout = layout, VertexShader = vertexShaderByteCode, PixelShader = pixelShaderByteCode, RootSignature = rootSignature, DepthStencilState = DepthStencilStateDescription.Default(), DepthStencilFormat = Format.Unknown, BlendState = BlendStateDescription.Default(), RasterizerState = RasterizerStateDescription.Default(), SampleDescription = new SampleDescription(1, 0), RenderTargetCount = 1, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, SampleMask = -1, StreamOutput = new StreamOutputDescription() }; psd.RenderTargetFormats[0] = Format.R8G8B8A8_UNorm; #if USE_DEPTH psd.DepthStencilFormat = Format.D32_Float; #else psd.DepthStencilState.IsDepthEnabled = false; #endif //psd.RasterizerState.CullMode = CullMode.None; pipelineState = Collect(device.CreateGraphicsPipelineState(psd)); #endregion pipeline state #region vertices var vertices = new[] { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Front -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // BACK -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // BACK 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Top -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Top -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Bottom -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Bottom 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Left -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Left -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Right 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Right 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, }; #endregion vertices #region vertex buffer // Instantiate Vertex buiffer from vertex data int sizeOfFloat = sizeof(float); int sizeInBytes = vertices.Length * sizeOfFloat; vertexBuffer = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription(ResourceDimension.Buffer, 0, sizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead)); vertexBufferView = new[] { new VertexBufferView { BufferLocation = vertexBuffer.GPUVirtualAddress, SizeInBytes = sizeInBytes, StrideInBytes = sizeOfFloat * 8, } }; var ptr = vertexBuffer.Map(0); Utilities.Write(ptr, vertices, 0, vertices.Length); vertexBuffer.Unmap(0); #endregion vertex buffer #region instances #if USE_INSTANCES int instanceSizeInBytes = sizeOfFloat * instances.Length; instancesBuffer = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription(ResourceDimension.Buffer, 0, instanceSizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead)); instancesBufferView = new[] { new VertexBufferView { BufferLocation = instancesBuffer.GPUVirtualAddress, SizeInBytes = instanceSizeInBytes, StrideInBytes = sizeOfFloat * 3, } }; ptr = instancesBuffer.Map(0); Utilities.Write(ptr, instances, 0, instances.Length); instancesBuffer.Unmap(0); #endif #endregion instances #region indices #if USE_INDICES var indexData = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 }; sizeInBytes = indexData.Length * sizeof(int); indexBuffer = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription(ResourceDimension.Buffer, 0, sizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead)); ptr = indexBuffer.Map(0); Utilities.Write(ptr, indexData, 0, indexData.Length); indexBuffer.Unmap(0); indexBufferView = new IndexBufferView { BufferLocation = indexBuffer.GPUVirtualAddress, SizeInBytes = sizeInBytes, Format = Format.R32_UInt }; #endif #endregion indices #region transform transWorld = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription(ResourceDimension.Buffer, 0, 16 * sizeOfMatrix, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead)); transWorldPtr = transWorld.Map(0); transViewProj = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription(ResourceDimension.Buffer, 0, sizeOfMatrix, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead)); device.CreateConstantBufferView(new ConstantBufferViewDescription { BufferLocation = transViewProj.GPUVirtualAddress, SizeInBytes = sizeOfMatrix, }, descriptorHeapCB.CPUDescriptorHandleForHeapStart); var view = Matrix.LookAtLH(new Vector3(5, 5, -5), Vector3.Zero, Vector3.UnitY); var proj = Matrix.PerspectiveFovLH(MathUtil.Pi / 4, (float)width / height, 0.1f, 100); var vpT = view * proj; vpT.Transpose(); ptr = transViewProj.Map(0); Utilities.Write(ptr, ref vpT); transViewProj.Unmap(0); #endregion transform #if USE_TEXTURE #region texture Resource buf; using (var tl = new TextureLoader("GeneticaMortarlessBlocks.jpg")) { int w = tl.Width, h = tl.Height; var descrs = new[] { new ResourceDescription(ResourceDimension.Texture2D, 0, w, h, 1, 1, Format.B8G8R8A8_UNorm, 1, 0, TextureLayout.Unknown, ResourceFlags.None), }; texture = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Default), HeapFlags.None, descrs[0], ResourceStates.CopyDestination) ); var resAllocInfo = device.GetResourceAllocationInfo(1, 1, descrs); buf = device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription( ResourceDimension.Buffer, 0, resAllocInfo.SizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead); var ptrBuf = buf.Map(0); int rowPitch = tl.CopyImageData(ptrBuf); buf.Unmap(0); var src = new TextureCopyLocation(buf, new PlacedSubResourceFootprint { Offset = 0, Footprint = new SubResourceFootprint { Format = Format.B8G8R8A8_UNorm_SRgb, Width = w, Height = h, Depth = 1, RowPitch = rowPitch } } ); var dst = new TextureCopyLocation(texture, 0); // record copy commandList.CopyTextureRegion(dst, 0, 0, 0, src, null); commandList.ResourceBarrierTransition(texture, ResourceStates.CopyDestination, ResourceStates.GenericRead); } descrOffsetCB = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView); device.CreateShaderResourceView(texture, null, descriptorHeapCB.CPUDescriptorHandleForHeapStart + descrOffsetCB); #endregion texture #region sampler device.CreateSampler(new SamplerStateDescription { AddressU = TextureAddressMode.Wrap, AddressV = TextureAddressMode.Wrap, AddressW = TextureAddressMode.Wrap, Filter = Filter.MaximumMinMagMipLinear, }, descriptorHeapS.CPUDescriptorHandleForHeapStart); #endregion sampler #endif // Get the backbuffer and creates the render target view renderTarget = Collect(swapChain.GetBackBuffer <Resource>(0)); device.CreateRenderTargetView(renderTarget, null, descriptorHeapRT.CPUDescriptorHandleForHeapStart); #if USE_DEPTH depthBuffer = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Default), HeapFlags.None, new ResourceDescription(ResourceDimension.Texture2D, 0, width, height, 1, 1, Format.D32_Float, 1, 0, TextureLayout.Unknown, ResourceFlags.AllowDepthStencil), ResourceStates.Present, new ClearValue { Format = Format.D32_Float, DepthStencil = new DepthStencilValue { Depth = 1, Stencil = 0, } })); device.CreateDepthStencilView(depthBuffer, null, descriptorHeapDS.CPUDescriptorHandleForHeapStart); #endif // Create the viewport viewPort = new ViewportF(0, 0, width, height); // Create the scissor scissorRectangle = new Rectangle(0, 0, width, height); // Create a fence to wait for next frame fence = Collect(device.CreateFence(0, FenceFlags.None)); currentFence = 1; // Close command list commandList.Close(); commandQueue.ExecuteCommandList(commandList); // Create an event handle use for VTBL CreateWaitEvent(); // Wait the command list to complete WaitForPrevFrame(); #if USE_TEXTURE buf.Dispose(); #endif }
private void LoadAssets() { DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 } }; StaticSamplerDescription sampler = new StaticSamplerDescription() { Filter = Filter.MinimumMinMagMipPoint, AddressU = TextureAddressMode.Border, AddressV = TextureAddressMode.Border, AddressW = TextureAddressMode.Border, MipLODBias = 0, MaxAnisotropy = 0, ComparisonFunc = Comparison.Never, BorderColor = StaticBorderColor.TransparentBlack, MinLOD = 0.0f, MaxLOD = float.MaxValue, ShaderRegister = 0, RegisterSpace = 0, ShaderVisibility = ShaderVisibility.Pixel, }; RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges) }; RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler }); rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION",0,Format.R32G32B32_Float,0,0), new InputElement("TEXCOORD",0,Format.R32G32_Float,12,0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = false, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Create the command list. commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); // Create the vertex buffer. float aspectRatio = viewport.Width / viewport.Height; // Define the geometry for a triangle. Vertex[] triangleVertices = new Vertex[] { new Vertex() {position=new Vector3(0.0f, 0.25f * aspectRatio, 0.0f ),uv=new Vector2(0.5f, 0.0f) }, new Vertex() {position=new Vector3(0.25f, -0.25f * aspectRatio, 0.0f),uv=new Vector2(1.0f, 1.0f) }, new Vertex() {position=new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f),uv=new Vector2(0.0f, 1.0f) }, }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); vertexBuffer.Unmap(0); // Initialize the vertex buffer view. vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf<Vertex>(); vertexBufferView.SizeInBytes = vertexBufferSize; Resource textureUploadHeap; // Create the texture. // Describe and create a Texture2D. ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight); texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination); long uploadBufferSize = GetRequiredIntermediateSize(this.texture, 0, 1); // Create the GPU upload buffer. textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight), ResourceStates.GenericRead); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. byte[] textureData = GenerateTextureData(); GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned); IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0); textureUploadHeap.WriteToSubresource(0, null, ptr, TexturePixelSize * TextureWidth, textureData.Length); handle.Free(); commandList.CopyTextureRegion(new TextureCopyLocation(texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null); commandList.ResourceBarrierTransition(this.texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource); // Describe and create a SRV for the texture. ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription() { Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(), Format = textureDesc.Format, Dimension = ShaderResourceViewDimension.Texture2D, }; srvDesc.Texture2D.MipLevels = 1; device.CreateShaderResourceView(this.texture, srvDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. commandList.Close(); commandQueue.ExecuteCommandList(commandList); // Create synchronization objects. fence = device.CreateFence(0, FenceFlags.None); fenceValue = 1; // Create an event handle to use for frame synchronization. fenceEvent = new AutoResetEvent(false); WaitForPreviousFrame(); //release temp texture textureUploadHeap.Dispose(); }
private void LoadAssets() { // Create the root signature description. var rootSignatureDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, // Root Parameters new[] { new RootParameter(ShaderVisibility.All, new [] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 }, new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue + 1, BaseShaderRegister = 0 } }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.Sampler, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 }), }); //// Samplers //new[] //{ // new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0) // { // Filter = Filter.MinimumMinMagMipPoint, // AddressUVW = TextureAddressMode.Border, // } //}); rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif #if DEBUG //var result = SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "GSMain", "gs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug); var geometryShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../shaders.hlsl"), "GSMain", "gs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. var inputElementDescs = new[] { new InputElement("POSITION",0,Format.R32G32B32_Float,0,0), new InputElement("TEXCOORD",0,Format.R32G32_Float,12,0) }; // Describe and create the graphics pipeline state object (PSO). var psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, GeometryShader = geometryShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthComparison = Comparison.LessEqual, DepthWriteMask = DepthWriteMask.All, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); commandList.Close(); // build vertex buffer var triangleVertices = new[] { //TOP new Vertex() {Position = new Vector3(-1f , 1f , 1f) , TexCoord = new Vector2(1f ,1f)} , new Vertex() {Position = new Vector3(1f , 1f , 1f) , TexCoord = new Vector2(0f ,1f)} , new Vertex() {Position = new Vector3(1f , 1f ,-1f) , TexCoord = new Vector2(0f ,0f)} , new Vertex() {Position = new Vector3(-1f , 1f ,-1f) , TexCoord = new Vector2(1f ,0f)} , //BOTTOM new Vertex() {Position = new Vector3(-1f ,-1f , 1f) , TexCoord = new Vector2(1f ,1f)} , new Vertex() {Position = new Vector3(1f ,-1f , 1f) , TexCoord = new Vector2(0f ,1f)} , new Vertex() {Position = new Vector3(1f ,-1f ,-1f) , TexCoord = new Vector2(0f ,0f)} , new Vertex() {Position = new Vector3(-1f ,-1f ,-1f) , TexCoord = new Vector2(1f ,0f)} , //LEFT new Vertex() {Position = new Vector3(-1f ,-1f , 1f) , TexCoord = new Vector2(0f ,1f)} , new Vertex() {Position = new Vector3(-1f , 1f , 1f) , TexCoord = new Vector2(0f ,0f)} , new Vertex() {Position = new Vector3(-1f , 1f ,-1f) , TexCoord = new Vector2(1f ,0f)} , new Vertex() {Position = new Vector3(-1f ,-1f ,-1f) , TexCoord = new Vector2(1f ,1f)} , //RIGHT new Vertex() {Position = new Vector3(1f ,-1f , 1f) , TexCoord = new Vector2(1f ,1f)} , new Vertex() {Position = new Vector3(1f , 1f , 1f) , TexCoord = new Vector2(1f ,0f)} , new Vertex() {Position = new Vector3(1f , 1f ,-1f) , TexCoord = new Vector2(0f ,0f)} , new Vertex() {Position = new Vector3(1f ,-1f ,-1f) , TexCoord = new Vector2(0f ,1f)} , //FRONT new Vertex() {Position = new Vector3(-1f , 1f , 1f) , TexCoord = new Vector2(1f ,0f)} , new Vertex() {Position = new Vector3(1f , 1f , 1f) , TexCoord = new Vector2(0f ,0f)} , new Vertex() {Position = new Vector3(1f ,-1f , 1f) , TexCoord = new Vector2(0f ,1f)} , new Vertex() {Position = new Vector3(-1f ,-1f , 1f) , TexCoord = new Vector2(1f ,1f)} , //BACK new Vertex() {Position = new Vector3(-1f , 1f ,-1f) , TexCoord = new Vector2(0f ,0f)} , new Vertex() {Position = new Vector3(1f , 1f ,-1f) , TexCoord = new Vector2(1f ,0f)} , new Vertex() {Position = new Vector3(1f ,-1f ,-1f) , TexCoord = new Vector2(1f ,1f)} , new Vertex() {Position = new Vector3(-1f ,-1f ,-1f) , TexCoord = new Vector2(0f ,1f)} }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); IntPtr pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); vertexBuffer.Unmap(0); vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf<Vertex>(); vertexBufferView.SizeInBytes = vertexBufferSize; // build index buffer var triangleIndexes = new uint[] { 0,1,2, 0,2,3, 4,6,5, 4,7,6, 8,9,10, 8,10,11, 12,14,13, 12,15,14, 16,18,17, 16,19,18, 20,21,22, 20,22,23 }; int indexBufferSize = Utilities.SizeOf(triangleIndexes); indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indexBufferSize), ResourceStates.GenericRead); IntPtr pIndexDataBegin = indexBuffer.Map(0); Utilities.Write(pIndexDataBegin, triangleIndexes, 0, triangleIndexes.Length); indexBuffer.Unmap(0); indexBufferView = new IndexBufferView(); indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress; indexBufferView.SizeInBytes = indexBufferSize; indexBufferView.Format = Format.R32_UInt; // Create the texture. // Describe and create a Texture2D. var textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight, 1, 1, 1, 0, ResourceFlags.None, TextureLayout.Unknown, 0); texture = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, textureDesc, ResourceStates.GenericRead, null); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. byte[] textureData = Utilities.ReadStream(new FileStream("../../texture1.dds", FileMode.Open)); texture.Name = "Texture"; var handle = GCHandle.Alloc(textureData, GCHandleType.Pinned); var ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0); texture.WriteToSubresource(0, null, ptr, TextureWidth * 4, textureData.Length); handle.Free(); // Describe and create a SRV for the texture. var srvDesc = new ShaderResourceViewDescription { Shader4ComponentMapping = ((((0) & 0x7) |(((1) & 0x7) << 3) |(((2) & 0x7) << (3 * 2)) |(((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))), Format = textureDesc.Format, Dimension = ShaderResourceViewDimension.Texture2D, Texture2D = { MipLevels = 1, MostDetailedMip = 0, PlaneSlice = 0, ResourceMinLODClamp = 0.0f }, }; device.CreateShaderResourceView(texture, srvDesc, srvCbvHeap.CPUDescriptorHandleForHeapStart); SamplerStateDescription samplerDesc = new SamplerStateDescription { Filter = Filter.MinMagMipLinear, AddressU = TextureAddressMode.Clamp, AddressV = TextureAddressMode.Clamp, AddressW = TextureAddressMode.Clamp, MaximumAnisotropy = 0, MaximumLod = float.MaxValue, MinimumLod = -float.MaxValue, MipLodBias = 0, ComparisonFunction = Comparison.Never }; device.CreateSampler(samplerDesc, samplerViewHeap.CPUDescriptorHandleForHeapStart); // build constant buffer constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead); var cbDesc = new ConstantBufferViewDescription() { BufferLocation = constantBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf<ConstantBufferData>() + 255) & ~255 }; var srvCbvStep = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView); device.CreateConstantBufferView(cbDesc, srvCbvHeap.CPUDescriptorHandleForHeapStart + srvCbvStep); constantBufferData = new ConstantBufferData { Project = Matrix.Identity }; constantBufferPointer = constantBuffer.Map(0); Utilities.Write(constantBufferPointer, ref constantBufferData); // build depth buffer DescriptorHeapDescription descDescriptorHeapDSB = new DescriptorHeapDescription() { DescriptorCount = 1, Type = DescriptorHeapType.DepthStencilView, Flags = DescriptorHeapFlags.None }; DescriptorHeap descriptorHeapDSB = device.CreateDescriptorHeap(descDescriptorHeapDSB); ResourceDescription descDepth = new ResourceDescription() { Dimension = ResourceDimension.Texture2D, DepthOrArraySize = 1, MipLevels = 0, Flags = ResourceFlags.AllowDepthStencil, Width = (int)viewport.Width, Height = (int)viewport.Height, Format = Format.R32_Typeless, Layout = TextureLayout.Unknown, SampleDescription = new SampleDescription() { Count = 1 } }; ClearValue dsvClearValue = new ClearValue() { Format = Format.D32_Float, DepthStencil = new DepthStencilValue() { Depth = 1.0f, Stencil = 0 } }; Resource renderTargetDepth = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, descDepth, ResourceStates.GenericRead, dsvClearValue); DepthStencilViewDescription depthDSV = new DepthStencilViewDescription() { Dimension = DepthStencilViewDimension.Texture2D, Format = Format.D32_Float, Texture2D = new DepthStencilViewDescription.Texture2DResource() { MipSlice = 0 } }; device.CreateDepthStencilView(renderTargetDepth, depthDSV, descriptorHeapDSB.CPUDescriptorHandleForHeapStart); handleDSV = descriptorHeapDSB.CPUDescriptorHandleForHeapStart; fence = device.CreateFence(0, FenceFlags.None); fenceValue = 1; fenceEvent = new AutoResetEvent(false); }