Exemplo n.º 1
0
        public Shader GetComputeShader(

            ulong gpuVa,
            int localSizeX,
            int localSizeY,
            int localSizeZ,
            int localMemorySize,
            int sharedMemorySize)
        {
            if (gpuVa == 0)
            {
                return null;
            }

            ShaderPack pack = new ShaderPack();

            ReadOnlySpan<byte> code = GetShaderCodeHeaderless(gpuVa);

            pack.Add(code);

            Shader cs = _cache.Get(pack, out int hash);

            if (cs != null)
            {
                return cs;
            }

            _dumper.Dump(code, compute: true, out string fullPath, out string codePath);

            int QueryInfo(QueryInfoName info, int index)
            {
                return info switch
                {
                    QueryInfoName.ComputeLocalSizeX => localSizeX,
                    QueryInfoName.ComputeLocalSizeY => localSizeY,
                    QueryInfoName.ComputeLocalSizeZ => localSizeZ,
                    QueryInfoName.ComputeLocalMemorySize => localMemorySize,
                    QueryInfoName.ComputeSharedMemorySize => sharedMemorySize,
                    _ => QueryInfoCommon(info)
                };
            }


            CachedShader shader = TranslateComputeShader(
                state,
                gpuVa,
                localSizeX,
                localSizeY,
                localSizeZ,
                localMemorySize,
                sharedMemorySize);

            TranslatorCallbacks callbacks = new TranslatorCallbacks(QueryInfo, PrintLog);


            ShaderProgram program = Translator.Translate(code, callbacks, DefaultFlags | TranslationFlags.Compute);

            if (fullPath != null && codePath != null)
            {
                program.Prepend("// " + codePath);
                program.Prepend("// " + fullPath);
            }

            IShader shader = _context.Renderer.CompileShader(program);

            IProgram hostProgram = _context.Renderer.CreateProgram(new IShader[] { shader });

            cs = new Shader(hostProgram, new ShaderMeta(hostProgram, program.Info));

            int insertIndex = _cache.Add(hash, cs, pack);

            if (Configuration.Enabled)
            {
                ShaderProgramInfo[] info = new ShaderProgramInfo[] { program.Info };

                ShaderCacheFile.Save(Configuration.ShaderPath, info, pack, hostProgram.GetGpuBinary(), hash, insertIndex);
            }

            return cs;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Translates the binary Maxwell shader code to something that the host API accepts.
        /// </summary>
        /// <param name="state">Current GPU state</param>
        /// <param name="gpuVa">GPU virtual address of the binary shader code</param>
        /// <param name="localSizeX">Local group size X of the computer shader</param>
        /// <param name="localSizeY">Local group size Y of the computer shader</param>
        /// <param name="localSizeZ">Local group size Z of the computer shader</param>
        /// <param name="localMemorySize">Local memory size of the compute shader</param>
        /// <param name="sharedMemorySize">Shared memory size of the compute shader</param>
        /// <returns>Compiled compute shader code</returns>
        private CachedShader TranslateComputeShader(
            GpuState state,
            ulong gpuVa,
            int localSizeX,
            int localSizeY,
            int localSizeZ,
            int localMemorySize,
            int sharedMemorySize)
        {
            if (gpuVa == 0)
            {
                return null;
            }

            int index = 0;

            for (int stage = 0; stage < programs.Length; stage++)
            {
                ShaderProgram program = programs[stage];

                if (program != null)
                {

                    QueryInfoName.ComputeLocalSizeX
                        => localSizeX,
                    QueryInfoName.ComputeLocalSizeY
                        => localSizeY,
                    QueryInfoName.ComputeLocalSizeZ
                        => localSizeZ,
                    QueryInfoName.ComputeLocalMemorySize
                        => localMemorySize,
                    QueryInfoName.ComputeSharedMemorySize
                        => sharedMemorySize,
                    QueryInfoName.IsTextureBuffer
                        => Convert.ToInt32(QueryIsTextureBuffer(state, 0, index, compute: true)),
                    QueryInfoName.IsTextureRectangle
                        => Convert.ToInt32(QueryIsTextureRectangle(state, 0, index, compute: true)),
                    QueryInfoName.TextureFormat
                        => (int)QueryTextureFormat(state, 0, index, compute: true),
                    _
                        => QueryInfoCommon(info)
                };

                    shaders[index++] = _context.Renderer.CompileShader(program);
                }
            }

            IProgram hostProgram = _context.Renderer.CreateProgram(shaders);

            ShaderProgramInfo[] info = programs.Select(x => x?.Info).ToArray();

            gs = new Shader(hostProgram, new ShaderMeta(hostProgram, info));

            int insertIndex = _cache.Add(hash, gs, pack);

            if (Configuration.Enabled)
            {
                ShaderCacheFile.Save(Configuration.ShaderPath, info, pack, hostProgram.GetGpuBinary(), hash, insertIndex);
            }

            return gs;
        }