/// <summary> /// Creates a new instance of the GPU state. /// </summary> /// <param name="channel">Channel that the sub-channel state belongs to</param> public GpuState(GpuChannel channel) { Channel = channel; _memory = new int[RegistersCount]; _shadow = new int[RegistersCount]; _registers = new Register[RegistersCount]; for (int index = 0; index < _registers.Length; index++) { _registers[index].BaseOffset = (MethodOffset)index; _registers[index].Stride = 1; _registers[index].Count = 1; _registers[index].Modified = true; } foreach (var item in GpuStateTable.Table) { int totalRegs = item.Size * item.Count; for (int regOffset = 0; regOffset < totalRegs; regOffset++) { int index = (int)item.Offset + regOffset; _registers[index].BaseOffset = item.Offset; _registers[index].Stride = item.Size; _registers[index].Count = item.Count; } } InitializeDefaultState(_memory); InitializeDefaultState(_shadow); }
private static void UpdateCachedBuffer( GpuChannel channel, bool isCompute, ref int cachedTextureBufferIndex, ref int cachedSamplerBufferIndex, ref ReadOnlySpan <int> cachedTextureBuffer, ref ReadOnlySpan <int> cachedSamplerBuffer, ref int cachedStageIndex, int textureBufferIndex, int samplerBufferIndex, int stageIndex) { bool stageChange = stageIndex != cachedStageIndex; if (stageChange || textureBufferIndex != cachedTextureBufferIndex) { ref BufferBounds bounds = ref channel.BufferManager.GetUniformBufferBounds(isCompute, stageIndex, textureBufferIndex); cachedTextureBuffer = MemoryMarshal.Cast <byte, int>(channel.MemoryManager.Physical.GetSpan(bounds.Address, (int)bounds.Size)); cachedTextureBufferIndex = textureBufferIndex; if (samplerBufferIndex == textureBufferIndex) { cachedSamplerBuffer = cachedTextureBuffer; cachedSamplerBufferIndex = samplerBufferIndex; } }
/// <summary> /// Creates a new instance of the GPU General Purpose FIFO command processor. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">Channel that the GPFIFO processor belongs to</param> public GPFifoProcessor(GpuContext context, GpuChannel channel) { _context = context; _channel = channel; _fifoClass = new GPFifoClass(context, this); _subChannels = new GpuState[8]; _subChannels2 = new IDeviceState[8] { null, new ComputeClass(context, channel), new InlineToMemoryClass(context, channel), new TwodClass(channel), new DmaClass(context, channel), null, null, null }; for (int index = 0; index < _subChannels.Length; index++) { _subChannels[index] = new GpuState(channel, _subChannels2[index]); _context.Methods.RegisterCallbacks(_subChannels[index]); } }
/// <summary> /// Constructs a new instance of the texture bindings manager. /// </summary> /// <param name="context">The GPU context that the texture bindings manager belongs to</param> /// <param name="channel">The GPU channel that the texture bindings manager belongs to</param> /// <param name="poolCache">Texture pools cache used to get texture pools from</param> /// <param name="scales">Array where the scales for the currently bound textures are stored</param> /// <param name="isCompute">True if the bindings manager is used for the compute engine</param> public TextureBindingsManager(GpuContext context, GpuChannel channel, TexturePoolCache poolCache, float[] scales, bool isCompute) { _context = context; _channel = channel; _texturePoolCache = poolCache; _scales = scales; _isCompute = isCompute; int stages = isCompute ? 1 : Constants.ShaderStages; _textureBindings = new TextureBindingInfo[stages][]; _imageBindings = new TextureBindingInfo[stages][]; _textureState = new TextureStatePerStage[stages][]; _imageState = new TextureStatePerStage[stages][]; _textureBindingsCount = new int[stages]; _imageBindingsCount = new int[stages]; for (int stage = 0; stage < stages; stage++) { _textureBindings[stage] = new TextureBindingInfo[InitialTextureStateSize]; _imageBindings[stage] = new TextureBindingInfo[InitialImageStateSize]; _textureState[stage] = new TextureStatePerStage[InitialTextureStateSize]; _imageState[stage] = new TextureStatePerStage[InitialImageStateSize]; } }
/// <summary> /// Creates a new instance of the GPU state accessor for graphics shader translation. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> /// <param name="state">Current GPU state</param> /// <param name="stageIndex">Graphics shader stage index (0 = Vertex, 4 = Fragment)</param> public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state, int stageIndex) { _context = context; _channel = channel; _state = state; _stageIndex = stageIndex; }
/// <summary> /// Creates a new instance of the buffer manager. /// </summary> /// <param name="context">GPU context that the buffer manager belongs to</param> /// <param name="channel">GPU channel that the buffer manager belongs to</param> public BufferManager(GpuContext context, GpuChannel channel) { _context = context; _channel = channel; _vertexBuffers = new VertexBuffer[Constants.TotalVertexBuffers]; _transformFeedbackBuffers = new BufferBounds[Constants.TotalTransformFeedbackBuffers]; _cpStorageBuffers = new BuffersPerStage(Constants.TotalCpStorageBuffers); _cpUniformBuffers = new BuffersPerStage(Constants.TotalCpUniformBuffers); _gpStorageBuffers = new BuffersPerStage[Constants.ShaderStages]; _gpUniformBuffers = new BuffersPerStage[Constants.ShaderStages]; for (int index = 0; index < Constants.ShaderStages; index++) { _gpStorageBuffers[index] = new BuffersPerStage(Constants.TotalGpStorageBuffers); _gpUniformBuffers[index] = new BuffersPerStage(Constants.TotalGpUniformBuffers); } _bufferTextures = new List <BufferTextureBinding>(); _ranges = new BufferRange[Constants.TotalGpUniformBuffers * Constants.ShaderStages]; }
/// <summary> /// Creates a new instance of the draw manager. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> /// <param name="state">Channel state</param> /// <param name="drawState">Draw state</param> public DrawManager(GpuContext context, GpuChannel channel, DeviceStateWithShadow <ThreedClassState> state, DrawState drawState) { _context = context; _channel = channel; _state = state; _drawState = drawState; }
/// <summary> /// Creates a new instance of the 2D engine class. /// </summary> /// <param name="channel">The channel that will make use of the engine</param> public TwodClass(GpuChannel channel) { _channel = channel; _state = new DeviceState <TwodClassState>(new Dictionary <string, RwCallback> { { nameof(TwodClassState.PixelsFromMemorySrcY0Int), new RwCallback(PixelsFromMemorySrcY0Int, null) } }); }
/// <summary> /// Creates a new instance of the GPU state accessor for graphics shader translation. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> /// <param name="state">Current GPU state</param> /// <param name="tfd">Transform feedback descriptors</param> /// <param name="stageIndex">Graphics shader stage index (0 = Vertex, 4 = Fragment)</param> public GpuAccessor(GpuContext context, GpuChannel channel, GpuAccessorState state, TransformFeedbackDescriptor[] tfd, int stageIndex) { _context = context; _channel = channel; _state = state; _tfd = tfd; _stageIndex = stageIndex; }
/// <summary> /// Creates a new instance of the DMA copy engine class. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> public DmaClass(GpuContext context, GpuChannel channel) { _context = context; _channel = channel; _state = new DeviceState <DmaClassState>(new Dictionary <string, RwCallback> { { nameof(DmaClassState.LaunchDma), new RwCallback(LaunchDma, null) } }); }
/// <summary> /// Creates a new instance of the compute engine class. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> public ComputeClass(GpuContext context, GpuChannel channel) : base(context, channel, false) { _context = context; _channel = channel; _state = new DeviceState <ComputeClassState>(new Dictionary <string, RwCallback> { { nameof(ComputeClassState.LaunchDma), new RwCallback(LaunchDma, null) }, { nameof(ComputeClassState.LoadInlineData), new RwCallback(LoadInlineData, null) }, { nameof(ComputeClassState.SendSignalingPcasB), new RwCallback(SendSignalingPcasB, null) } }); }
/// <summary> /// Creates a new instance of the GPU General Purpose FIFO command processor. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">Channel that the GPFIFO processor belongs to</param> public GPFifoProcessor(GpuContext context, GpuChannel channel) { _channel = channel; _fifoClass = new GPFifoClass(context, this); _3dClass = new ThreedClass(context, channel, _fifoClass); _computeClass = new ComputeClass(context, channel, _3dClass); _i2mClass = new InlineToMemoryClass(context, channel); _2dClass = new TwodClass(channel); _dmaClass = new DmaClass(context, channel, _3dClass); }
/// <summary> /// Creates a new instance of the GPU state accessor for graphics shader translation. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> /// <param name="state">Current GPU state</param> /// <param name="stageIndex">Graphics shader stage index (0 = Vertex, 4 = Fragment)</param> public GpuAccessor( GpuContext context, GpuChannel channel, GpuAccessorState state, int stageIndex) : base(context, state.ResourceCounts, stageIndex) { _isVulkan = context.Capabilities.Api == TargetApi.Vulkan; _channel = channel; _state = state; _stageIndex = stageIndex; }
/// <summary> /// Creates a new instance of the texture manager. /// </summary> /// <param name="context">GPU context that the texture manager belongs to</param> /// <param name="channel">GPU channel that the texture manager belongs to</param> public TextureManager(GpuContext context, GpuChannel channel) { _context = context; TexturePoolCache texturePoolCache = new TexturePoolCache(context); _cpBindingsManager = new TextureBindingsManager(context, channel, texturePoolCache, isCompute: true); _gpBindingsManager = new TextureBindingsManager(context, channel, texturePoolCache, isCompute: false); _rtColors = new Texture[Constants.TotalRenderTargets]; _rtHostColors = new ITexture[Constants.TotalRenderTargets]; }
/// <summary> /// Gets a compute shader from the cache. /// </summary> /// <remarks> /// This automatically translates, compiles and adds the code to the cache if not present. /// </remarks> /// <param name="channel">GPU channel</param> /// <param name="poolState">Texture pool state</param> /// <param name="computeState">Compute engine state</param> /// <param name="gpuVa">GPU virtual address of the binary shader code</param> /// <returns>Compiled compute shader code</returns> public CachedShaderProgram GetComputeShader( GpuChannel channel, GpuChannelPoolState poolState, GpuChannelComputeState computeState, ulong gpuVa) { if (_cpPrograms.TryGetValue(gpuVa, out var cpShader) && IsShaderEqual(channel, poolState, cpShader, gpuVa)) { return(cpShader); } if (_computeShaderCache.TryFind(channel, poolState, gpuVa, out cpShader, out byte[] cachedGuestCode))
/// <summary> /// Tries to find a cached program. /// </summary> /// <param name="channel">GPU channel</param> /// <param name="poolState">Texture pool state</param> /// <param name="gpuVa">GPU virtual address of the compute shader</param> /// <param name="program">Cached host program for the given state, if found</param> /// <param name="cachedGuestCode">Cached guest code, if any found</param> /// <returns>True if a cached host program was found, false otherwise</returns> public bool TryFind( GpuChannel channel, GpuChannelPoolState poolState, ulong gpuVa, out CachedShaderProgram program, out byte[] cachedGuestCode) { program = null; ShaderCodeAccessor codeAccessor = new ShaderCodeAccessor(channel.MemoryManager, gpuVa); bool hasSpecList = _cache.TryFindItem(codeAccessor, out var specList, out cachedGuestCode); return(hasSpecList && specList.TryFindForCompute(channel, poolState, out program)); }
/// <summary> /// Creates a new instance of the GPU state accessor for graphics shader translation. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> /// <param name="state">Current GPU state</param> /// <param name="attributeTypes">Type of the vertex attributes consumed by the shader</param> /// <param name="tfd">Transform feedback descriptors</param> /// <param name="stageIndex">Graphics shader stage index (0 = Vertex, 4 = Fragment)</param> public GpuAccessor( GpuContext context, GpuChannel channel, GpuAccessorState state, AttributeType[] attributeTypes, TransformFeedbackDescriptor[] tfd, int stageIndex) : base(context) { _channel = channel; _state = state; _attributeTypes = attributeTypes; _tfd = tfd; _stageIndex = stageIndex; }
/// <summary> /// Creates a new instance of the compute engine class. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> /// <param name="threedEngine">3D engine</param> public ComputeClass(GpuContext context, GpuChannel channel, ThreedClass threedEngine) { _context = context; _channel = channel; _3dEngine = threedEngine; _state = new DeviceState <ComputeClassState>(new Dictionary <string, RwCallback> { { nameof(ComputeClassState.LaunchDma), new RwCallback(LaunchDma, null) }, { nameof(ComputeClassState.LoadInlineData), new RwCallback(LoadInlineData, null) }, { nameof(ComputeClassState.SendSignalingPcasB), new RwCallback(SendSignalingPcasB, null) } }); _i2mClass = new InlineToMemoryClass(context, channel, initializeState: false); }
/// <summary> /// Tries to find an existing compute program on the cache. /// </summary> /// <param name="channel">GPU channel</param> /// <param name="poolState">Texture pool state</param> /// <param name="program">Cached program, if found</param> /// <returns>True if a compatible program is found, false otherwise</returns> public bool TryFindForCompute(GpuChannel channel, GpuChannelPoolState poolState, out CachedShaderProgram program) { foreach (var entry in _entries) { if (entry.SpecializationState.MatchesCompute(channel, poolState, true)) { program = entry; return(true); } } program = default; return(false); }
/// <summary> /// Creates a new instance of the Inline-to-Memory engine class. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> /// <param name="initializeState">Indicates if the internal state should be initialized. Set to false if part of another engine</param> public InlineToMemoryClass(GpuContext context, GpuChannel channel, bool initializeState) { _context = context; _channel = channel; if (initializeState) { _state = new DeviceState <InlineToMemoryClassState>(new Dictionary <string, RwCallback> { { nameof(InlineToMemoryClassState.LaunchDma), new RwCallback(LaunchDma, null) }, { nameof(InlineToMemoryClassState.LoadInlineData), new RwCallback(LoadInlineData, null) } }); } }
/// <summary> /// Creates a new instance of the 3D engine class. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> public ThreedClass(GpuContext context, GpuChannel channel, GPFifoClass fifoClass) { _context = context; _fifoClass = fifoClass; _state = new DeviceStateWithShadow <ThreedClassState>(new Dictionary <string, RwCallback> { { nameof(ThreedClassState.LaunchDma), new RwCallback(LaunchDma, null) }, { nameof(ThreedClassState.LoadInlineData), new RwCallback(LoadInlineData, null) }, { nameof(ThreedClassState.SyncpointAction), new RwCallback(IncrementSyncpoint, null) }, { nameof(ThreedClassState.InvalidateSamplerCacheNoWfi), new RwCallback(InvalidateSamplerCacheNoWfi, null) }, { nameof(ThreedClassState.InvalidateTextureHeaderCacheNoWfi), new RwCallback(InvalidateTextureHeaderCacheNoWfi, null) }, { nameof(ThreedClassState.TextureBarrier), new RwCallback(TextureBarrier, null) }, { nameof(ThreedClassState.TextureBarrierTiled), new RwCallback(TextureBarrierTiled, null) }, { nameof(ThreedClassState.DrawTextureSrcY), new RwCallback(DrawTexture, null) }, { nameof(ThreedClassState.VbElementU8), new RwCallback(VbElementU8, null) }, { nameof(ThreedClassState.VbElementU16), new RwCallback(VbElementU16, null) }, { nameof(ThreedClassState.VbElementU32), new RwCallback(VbElementU32, null) }, { nameof(ThreedClassState.ResetCounter), new RwCallback(ResetCounter, null) }, { nameof(ThreedClassState.RenderEnableCondition), new RwCallback(null, Zero) }, { nameof(ThreedClassState.DrawEnd), new RwCallback(DrawEnd, null) }, { nameof(ThreedClassState.DrawBegin), new RwCallback(DrawBegin, null) }, { nameof(ThreedClassState.DrawIndexedSmall), new RwCallback(DrawIndexedSmall, null) }, { nameof(ThreedClassState.DrawIndexedSmall2), new RwCallback(DrawIndexedSmall2, null) }, { nameof(ThreedClassState.DrawIndexedSmallIncInstance), new RwCallback(DrawIndexedSmallIncInstance, null) }, { nameof(ThreedClassState.DrawIndexedSmallIncInstance2), new RwCallback(DrawIndexedSmallIncInstance2, null) }, { nameof(ThreedClassState.IndexBufferCount), new RwCallback(SetIndexBufferCount, null) }, { nameof(ThreedClassState.Clear), new RwCallback(Clear, null) }, { nameof(ThreedClassState.SemaphoreControl), new RwCallback(Report, null) }, { nameof(ThreedClassState.SetFalcon04), new RwCallback(SetFalcon04, null) }, { nameof(ThreedClassState.UniformBufferUpdateData), new RwCallback(ConstantBufferUpdate, null) }, { nameof(ThreedClassState.UniformBufferBindVertex), new RwCallback(ConstantBufferBindVertex, null) }, { nameof(ThreedClassState.UniformBufferBindTessControl), new RwCallback(ConstantBufferBindTessControl, null) }, { nameof(ThreedClassState.UniformBufferBindTessEvaluation), new RwCallback(ConstantBufferBindTessEvaluation, null) }, { nameof(ThreedClassState.UniformBufferBindGeometry), new RwCallback(ConstantBufferBindGeometry, null) }, { nameof(ThreedClassState.UniformBufferBindFragment), new RwCallback(ConstantBufferBindFragment, null) } }); _i2mClass = new InlineToMemoryClass(context, channel, initializeState: false); var drawState = new DrawState(); _drawManager = new DrawManager(context, channel, _state, drawState); _semaphoreUpdater = new SemaphoreUpdater(context, channel, _state); _cbUpdater = new ConstantBufferUpdater(channel, _state); _stateUpdater = new StateUpdater(context, channel, _state, drawState); // This defaults to "always", even without any register write. // Reads just return 0, regardless of what was set there. _state.State.RenderEnableCondition = Condition.Always; }
/// <summary> /// Creates a new instance of the texture manager. /// </summary> /// <param name="context">GPU context that the texture manager belongs to</param> /// <param name="channel">GPU channel that the texture manager belongs to</param> public TextureManager(GpuContext context, GpuChannel channel) { _context = context; TexturePoolCache texturePoolCache = new TexturePoolCache(context); float[] scales = new float[64]; new Span <float>(scales).Fill(1f); _cpBindingsManager = new TextureBindingsManager(context, channel, texturePoolCache, scales, isCompute: true); _gpBindingsManager = new TextureBindingsManager(context, channel, texturePoolCache, scales, isCompute: false); _rtColors = new Texture[Constants.TotalRenderTargets]; _rtHostColors = new ITexture[Constants.TotalRenderTargets]; }
/// <summary> /// Creates a new instance of the GPU General Purpose FIFO command processor. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">Channel that the GPFIFO processor belongs to</param> public GPFifoProcessor(GpuContext context, GpuChannel channel) { _context = context; _channel = channel; _fifoClass = new GPFifoClass(context, this); _subChannels = new GpuState[8]; for (int index = 0; index < _subChannels.Length; index++) { _subChannels[index] = new GpuState(channel); _context.Methods.RegisterCallbacks(_subChannels[index]); } }
/// <summary> /// Checks if the recorded state matches the current GPU 3D engine state. /// </summary> /// <param name="channel">GPU channel</param> /// <param name="poolState">Texture pool state</param> /// <param name="graphicsState">Graphics state</param> /// <param name="checkTextures">Indicates whether texture descriptors should be checked</param> /// <returns>True if the state matches, false otherwise</returns> public bool MatchesGraphics(GpuChannel channel, GpuChannelPoolState poolState, GpuChannelGraphicsState graphicsState, bool checkTextures) { if (graphicsState.ViewportTransformDisable != GraphicsState.ViewportTransformDisable) { return(false); } bool thisA2cDitherEnable = GraphicsState.AlphaToCoverageEnable && GraphicsState.AlphaToCoverageDitherEnable; bool otherA2cDitherEnable = graphicsState.AlphaToCoverageEnable && graphicsState.AlphaToCoverageDitherEnable; if (otherA2cDitherEnable != thisA2cDitherEnable) { return(false); } return(Matches(channel, poolState, checkTextures, isCompute: false)); }
/// <summary> /// Decode the binary Maxwell shader code to a translator context. /// </summary> /// <remarks> /// This will combine the "Vertex A" and "Vertex B" shader stages, if specified, into one shader. /// </remarks> /// <param name="channel">GPU channel</param> /// <param name="gas">GPU accessor state</param> /// <param name="counts">Cumulative shader resource counts</param> /// <param name="flags">Flags that controls shader translation</param> /// <param name="stage">Shader stage</param> /// <param name="gpuVa">GPU virtual address of the shader code</param> /// <returns>The generated translator context</returns> private TranslatorContext DecodeGraphicsShader( GpuChannel channel, GpuAccessorState gas, TranslationCounts counts, TranslationFlags flags, ShaderStage stage, ulong gpuVa) { if (gpuVa == 0) { return(null); } GpuAccessor gpuAccessor = new GpuAccessor(_context, channel, gas, (int)stage - 1); var options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, flags); return(Translator.CreateContext(gpuVa, gpuAccessor, options, counts)); }
/// <summary> /// Decode the binary Maxwell shader code to a translator context. /// </summary> /// <remarks> /// This will combine the "Vertex A" and "Vertex B" shader stages, if specified, into one shader. /// </remarks> /// <param name="channel">GPU channel</param> /// <param name="gas">GPU accessor state</param> /// <param name="tfd">Transform feedback descriptors</param> /// <param name="flags">Flags that controls shader translation</param> /// <param name="stage">Shader stage</param> /// <param name="gpuVa">GPU virtual address of the shader code</param> /// <returns>The generated translator context</returns> private TranslatorContext DecodeGraphicsShader( GpuChannel channel, GpuAccessorState gas, TransformFeedbackDescriptor[] tfd, TranslationFlags flags, ShaderStage stage, ulong gpuVa) { if (gpuVa == 0) { return(null); } GpuAccessor gpuAccessor = new GpuAccessor(_context, channel, gas, tfd, (int)stage - 1); var options = CreateTranslationOptions(flags); return(Translator.CreateContext(gpuVa, gpuAccessor, options)); }
/// <summary> /// Creates a new instance of the GPU state accessor for compute shader translation. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> /// <param name="state">Current GPU state</param> /// <param name="localSizeX">Local group size X of the compute shader</param> /// <param name="localSizeY">Local group size Y of the compute shader</param> /// <param name="localSizeZ">Local group size Z of the compute shader</param> /// <param name="localMemorySize">Local memory size of the compute shader</param> /// <param name="sharedMemorySize">Shared memory size of the compute shader</param> public GpuAccessor( GpuContext context, GpuChannel channel, GpuAccessorState state, int localSizeX, int localSizeY, int localSizeZ, int localMemorySize, int sharedMemorySize) : base(context) { _channel = channel; _state = state; _compute = true; _localSizeX = localSizeX; _localSizeY = localSizeY; _localSizeZ = localSizeZ; _localMemorySize = localMemorySize; _sharedMemorySize = sharedMemorySize; }
/// <summary> /// Finds a cache texture pool, or creates a new one if not found. /// </summary> /// <param name="channel">GPU channel that the texture pool cache belongs to</param> /// <param name="address">Start address of the texture pool</param> /// <param name="maximumId">Maximum ID of the texture pool</param> /// <returns>The found or newly created texture pool</returns> public T FindOrCreate(GpuChannel channel, ulong address, int maximumId) { // Remove old entries from the cache, if possible. while (_pools.Count > MaxCapacity && (_currentTimestamp - _pools.First.Value.CacheTimestamp) >= MinDeltaForRemoval) { T oldestPool = _pools.First.Value; _pools.RemoveFirst(); oldestPool.Dispose(); oldestPool.CacheNode = null; } T pool; // Try to find the pool on the cache. for (LinkedListNode <T> node = _pools.First; node != null; node = node.Next) { pool = node.Value; if (pool.Address == address) { if (pool.CacheNode != _pools.Last) { _pools.Remove(pool.CacheNode); pool.CacheNode = _pools.AddLast(pool); } pool.CacheTimestamp = _currentTimestamp; return(pool); } } // If not found, create a new one. pool = CreatePool(_context, channel, address, maximumId); pool.CacheNode = _pools.AddLast(pool); pool.CacheTimestamp = _currentTimestamp; return(pool); }
/// <summary> /// Decode the binary Maxwell shader code to a translator context. /// </summary> /// <param name="channel">GPU channel</param> /// <param name="gas">GPU accessor 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>The generated translator context</returns> private TranslatorContext DecodeComputeShader( GpuChannel channel, GpuAccessorState gas, ulong gpuVa, int localSizeX, int localSizeY, int localSizeZ, int localMemorySize, int sharedMemorySize) { if (gpuVa == 0) { return(null); } GpuAccessor gpuAccessor = new GpuAccessor(_context, channel, gas, localSizeX, localSizeY, localSizeZ, localMemorySize, sharedMemorySize); var options = new TranslationOptions(TargetLanguage.Glsl, TargetApi.OpenGL, DefaultFlags | TranslationFlags.Compute); return(Translator.CreateContext(gpuVa, gpuAccessor, options)); }
/// <summary> /// Finds a cache texture pool, or creates a new one if not found. /// </summary> /// <param name="channel">GPU channel that the texture pool cache belongs to</param> /// <param name="address">Start address of the texture pool</param> /// <param name="maximumId">Maximum ID of the texture pool</param> /// <returns>The found or newly created texture pool</returns> public TexturePool FindOrCreate(GpuChannel channel, ulong address, int maximumId) { TexturePool pool; // First we try to find the pool. for (LinkedListNode <TexturePool> node = _pools.First; node != null; node = node.Next) { pool = node.Value; if (pool.Address == address) { if (pool.CacheNode != _pools.Last) { _pools.Remove(pool.CacheNode); pool.CacheNode = _pools.AddLast(pool); } return(pool); } } // If not found, create a new one. pool = new TexturePool(_context, channel, address, maximumId); pool.CacheNode = _pools.AddLast(pool); if (_pools.Count > MaxCapacity) { TexturePool oldestPool = _pools.First.Value; _pools.RemoveFirst(); oldestPool.Dispose(); oldestPool.CacheNode = null; } return(pool); }