/// <summary> /// Recompiles a compute program from guest code. /// </summary> /// <param name="shaders">Shader stages</param> /// <param name="specState">Specialization state</param> /// <param name="programIndex">Program index</param> private void RecompileComputeFromGuestCode(CachedShaderStage[] shaders, ShaderSpecializationState specState, int programIndex) { CachedShaderStage shader = shaders[0]; ResourceCounts counts = new ResourceCounts(); ShaderSpecializationState newSpecState = new ShaderSpecializationState(specState.ComputeState); DiskCacheGpuAccessor gpuAccessor = new DiskCacheGpuAccessor(_context, shader.Code, shader.Cb1Data, specState, newSpecState, counts, 0); TranslatorContext translatorContext = DecodeComputeShader(gpuAccessor, 0); ShaderProgram program = translatorContext.Translate(); shaders[0] = new CachedShaderStage(program.Info, shader.Code, shader.Cb1Data); _compilationQueue.Enqueue(new ProgramCompilation(new[] { program }, shaders, newSpecState, programIndex, isCompute: true)); }
/// <summary> /// Recompiles a graphics program from guest code. /// </summary> /// <param name="shaders">Shader stages</param> /// <param name="specState">Specialization state</param> /// <param name="programIndex">Program index</param> private void RecompileGraphicsFromGuestCode(CachedShaderStage[] shaders, ShaderSpecializationState specState, int programIndex) { ShaderSpecializationState newSpecState = new ShaderSpecializationState(specState.GraphicsState, specState.TransformFeedbackDescriptors); ResourceCounts counts = new ResourceCounts(); TranslatorContext[] translatorContexts = new TranslatorContext[Constants.ShaderStages + 1]; TranslatorContext nextStage = null; for (int stageIndex = Constants.ShaderStages - 1; stageIndex >= 0; stageIndex--) { CachedShaderStage shader = shaders[stageIndex + 1]; if (shader != null) { byte[] guestCode = shader.Code; byte[] cb1Data = shader.Cb1Data; DiskCacheGpuAccessor gpuAccessor = new DiskCacheGpuAccessor(_context, guestCode, cb1Data, specState, newSpecState, counts, stageIndex); TranslatorContext currentStage = DecodeGraphicsShader(gpuAccessor, DefaultFlags, 0); if (nextStage != null) { currentStage.SetNextStage(nextStage); } if (stageIndex == 0 && shaders[0] != null) { byte[] guestCodeA = shaders[0].Code; byte[] cb1DataA = shaders[0].Cb1Data; DiskCacheGpuAccessor gpuAccessorA = new DiskCacheGpuAccessor(_context, guestCodeA, cb1DataA, specState, newSpecState, counts, 0); translatorContexts[0] = DecodeGraphicsShader(gpuAccessorA, DefaultFlags | TranslationFlags.VertexA, 0); } translatorContexts[stageIndex + 1] = currentStage; nextStage = currentStage; } } List <ShaderProgram> translatedStages = new List <ShaderProgram>(); for (int stageIndex = 0; stageIndex < Constants.ShaderStages; stageIndex++) { TranslatorContext currentStage = translatorContexts[stageIndex + 1]; if (currentStage != null) { ShaderProgram program; byte[] guestCode = shaders[stageIndex + 1].Code; byte[] cb1Data = shaders[stageIndex + 1].Cb1Data; if (stageIndex == 0 && shaders[0] != null) { program = currentStage.Translate(translatorContexts[0]); byte[] guestCodeA = shaders[0].Code; byte[] cb1DataA = shaders[0].Cb1Data; shaders[0] = new CachedShaderStage(null, guestCodeA, cb1DataA); shaders[1] = new CachedShaderStage(program.Info, guestCode, cb1Data); } else { program = currentStage.Translate(); shaders[stageIndex + 1] = new CachedShaderStage(program.Info, guestCode, cb1Data); } if (program != null) { translatedStages.Add(program); } } } _compilationQueue.Enqueue(new ProgramCompilation(translatedStages.ToArray(), shaders, newSpecState, programIndex, isCompute: false)); }