Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }