private void LoadShaders() { var vShader = BuiltinShaderRepository.GetBuiltinShader(typeof(VertexPositionColorTexture), ShaderStages.Vertex); vertexShader = vShader.CreateDeviceShader(device); var fShader = BuiltinShaderRepository.GetBuiltinShader(typeof(VertexPositionColorTexture), ShaderStages.Fragment); fragmentShader = fShader.CreateDeviceShader(device); }
private Shader(Type t, GraphicsDevice graphicsDevice) { var shaderType = t; var shaderName = shaderType.Name; _vertexShader = LoadShader(graphicsDevice.ResourceFactory, shaderName, ShaderStages.Vertex, "VS"); _fragmentShader = LoadShader(graphicsDevice.ResourceFactory, shaderName, ShaderStages.Fragment, "PS"); _hash = _vertexHash + _fragmentHash; }
//TODO: REMOVE public ShaderTechnique(GraphicsDevice device, byte[] vert, byte[] frag, string name) { GraphicsDevice = device; _assetPath = name; //Loads a SPIR-V binary from the byte[], and attempts to use SPIR-V cross to cross compile it for other platforms if the current platform isn't Vulkan Programs = device.veldridGraphicsDevice.ResourceFactory.CreateFromSpirv( new ShaderDescription(ShaderStages.Vertex, vert, "main", VesselEngine.DebugMode), new ShaderDescription(ShaderStages.Fragment, frag, "main", VesselEngine.DebugMode)); InternalVertexShader = Programs[0]; InternalFragmentShader = Programs[1]; }
/// <summary> /// Loads the shader from the binary object /// </summary> /// <param name="bytes">The byte stream</param> private void LoadFromShaderBinary(GraphicsDevice device, byte[] bytes) { GraphicsDevice = device; //TODO: Read ShaderTechnique /* * ENCODED USING LITTLE ENDIAN * * ShaderTable * { * byte availablePrograms = A|B|C|D|E|F|G|H; //each bit in this byte represents a specific shader stage. the order of bits is the order of the following 4 longs * ulong vertexShader; //pointer to the start of the vertex shader program * ulong fragmentShader; //pointer to the start of the fragment shader program * //etc, repeat for each shader stage * } * Shader [] * { * int nameLength; // length in bytes of name character; size = 4b * byte[] name; // ASCII encoded byte[] representing the name * ulong offset; // pointer to the start of the byte[] in the file stream * ulong length; // how long the byte[] is in bytes, used to determine when to stop reading * } * * availablePrograms * * */ int pointer = 0; byte availableProgramFlags = bytes[pointer++]; int shaderCount = 0; //Determine which shaders are included in the binary bool hasVertexProgram = (availableProgramFlags & (1 << 1 - 1)) != 0; bool hasGeometryProgram = (availableProgramFlags & (1 << 2 - 1)) != 0; bool hasTesselationControlProgram = (availableProgramFlags & (1 << 3 - 1)) != 0; bool hasTesselationEvaluationProgram = (availableProgramFlags & (1 << 4 - 1)) != 0; bool hasFragmentProgram = (availableProgramFlags & (1 << 5 - 1)) != 0; bool hasComputeProgram = (availableProgramFlags & (1 << 6 - 1)) != 0; //Count the number of shaders if (hasVertexProgram) { shaderCount++; } if (hasGeometryProgram) { shaderCount++; } if (hasTesselationControlProgram) { shaderCount++; } if (hasTesselationEvaluationProgram) { shaderCount++; } if (hasFragmentProgram) { shaderCount++; } if (hasComputeProgram) { shaderCount++; } byte[] vertShader = new byte[] { }; byte[] fragShader = new byte[] { }; byte[] computeShader = new byte[] { }; ulong vertShaderPtr = ulong.MaxValue; ulong fragShaderPtr = ulong.MaxValue; ulong compShaderPtr = ulong.MaxValue; //Determine the addresses of the shader programs included in the shader binary if (hasVertexProgram) { vertShaderPtr = BinaryUtils.ReadIntFromByteArray(bytes, pointer, 8, true); pointer += 8; } if (hasFragmentProgram) { fragShaderPtr = BinaryUtils.ReadIntFromByteArray(bytes, pointer, 8, true); pointer += 8; } if (hasComputeProgram) { compShaderPtr = BinaryUtils.ReadIntFromByteArray(bytes, pointer, 8, true); pointer += 8; } //Loads a SPIR-V binary from the byte[], and attempts to use SPIR-V cross to cross compile it for other platforms if the current platform isn't Vulkan Programs = device.veldridGraphicsDevice.ResourceFactory.CreateFromSpirv( new ShaderDescription(ShaderStages.Vertex, vertShader, "main", VesselEngine.DebugMode), new ShaderDescription(ShaderStages.Fragment, fragShader, "main", VesselEngine.DebugMode)); InternalVertexShader = Programs[0]; InternalFragmentShader = Programs[1]; GraphicsPipelineDescription pipelineDescription = new GraphicsPipelineDescription(); pipelineDescription.BlendState = BlendStateDescription.SingleOverrideBlend; pipelineDescription.DepthStencilState = new DepthStencilStateDescription( depthTestEnabled: true, depthWriteEnabled: true, comparisonKind: ComparisonKind.LessEqual); pipelineDescription.RasterizerState = new RasterizerStateDescription( cullMode: FaceCullMode.Back, fillMode: PolygonFillMode.Solid, frontFace: FrontFace.Clockwise, depthClipEnabled: true, scissorTestEnabled: false); pipelineDescription.PrimitiveTopology = PrimitiveTopology.TriangleStrip; pipelineDescription.ResourceLayouts = System.Array.Empty <ResourceLayout>(); pipelineDescription.Outputs = device.veldridGraphicsDevice.SwapchainFramebuffer.OutputDescription; pipelineDescription.ShaderSet = new ShaderSetDescription( vertexLayouts: new VertexLayoutDescription[] { VertexPositionColor.VertexLayout, }, shaders: Programs); shaderPipeline = device.veldridGraphicsDevice.ResourceFactory.CreateGraphicsPipeline(pipelineDescription); }