Remove cache entries on pool removal, disable for OpenGL
This commit is contained in:
parent
42b67818fc
commit
859d4675e4
10 changed files with 80 additions and 19 deletions
|
@ -36,6 +36,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
public readonly bool SupportsMismatchingViewFormat;
|
public readonly bool SupportsMismatchingViewFormat;
|
||||||
public readonly bool SupportsCubemapView;
|
public readonly bool SupportsCubemapView;
|
||||||
public readonly bool SupportsNonConstantTextureOffset;
|
public readonly bool SupportsNonConstantTextureOffset;
|
||||||
|
public readonly bool SupportsSeparateSampler;
|
||||||
public readonly bool SupportsShaderBallot;
|
public readonly bool SupportsShaderBallot;
|
||||||
public readonly bool SupportsShaderBarrierDivergence;
|
public readonly bool SupportsShaderBarrierDivergence;
|
||||||
public readonly bool SupportsShaderFloat64;
|
public readonly bool SupportsShaderFloat64;
|
||||||
|
@ -92,6 +93,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
bool supportsMismatchingViewFormat,
|
bool supportsMismatchingViewFormat,
|
||||||
bool supportsCubemapView,
|
bool supportsCubemapView,
|
||||||
bool supportsNonConstantTextureOffset,
|
bool supportsNonConstantTextureOffset,
|
||||||
|
bool supportsSeparateSampler,
|
||||||
bool supportsShaderBallot,
|
bool supportsShaderBallot,
|
||||||
bool supportsShaderBarrierDivergence,
|
bool supportsShaderBarrierDivergence,
|
||||||
bool supportsShaderFloat64,
|
bool supportsShaderFloat64,
|
||||||
|
@ -144,6 +146,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
|
SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
|
||||||
SupportsCubemapView = supportsCubemapView;
|
SupportsCubemapView = supportsCubemapView;
|
||||||
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
|
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
|
||||||
|
SupportsSeparateSampler = supportsSeparateSampler;
|
||||||
SupportsShaderBallot = supportsShaderBallot;
|
SupportsShaderBallot = supportsShaderBallot;
|
||||||
SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence;
|
SupportsShaderBarrierDivergence = supportsShaderBarrierDivergence;
|
||||||
SupportsShaderFloat64 = supportsShaderFloat64;
|
SupportsShaderFloat64 = supportsShaderFloat64;
|
||||||
|
|
|
@ -62,8 +62,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// <param name="channel">GPU channel that the texture pool cache belongs to</param>
|
/// <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="address">Start address of the texture pool</param>
|
||||||
/// <param name="maximumId">Maximum ID of the texture pool</param>
|
/// <param name="maximumId">Maximum ID of the texture pool</param>
|
||||||
|
/// <param name="bindingsArrayCache">Cache of texture array bindings</param>
|
||||||
/// <returns>The found or newly created texture pool</returns>
|
/// <returns>The found or newly created texture pool</returns>
|
||||||
public T FindOrCreate(GpuChannel channel, ulong address, int maximumId)
|
public T FindOrCreate(GpuChannel channel, ulong address, int maximumId, TextureBindingsArrayCache bindingsArrayCache)
|
||||||
{
|
{
|
||||||
// Remove old entries from the cache, if possible.
|
// Remove old entries from the cache, if possible.
|
||||||
while (_pools.Count > MaxCapacity && (_currentTimestamp - _pools.First.Value.CacheTimestamp) >= MinDeltaForRemoval)
|
while (_pools.Count > MaxCapacity && (_currentTimestamp - _pools.First.Value.CacheTimestamp) >= MinDeltaForRemoval)
|
||||||
|
@ -73,6 +74,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
_pools.RemoveFirst();
|
_pools.RemoveFirst();
|
||||||
oldestPool.Dispose();
|
oldestPool.Dispose();
|
||||||
oldestPool.CacheNode = null;
|
oldestPool.CacheNode = null;
|
||||||
|
bindingsArrayCache.RemoveAllWithPool(oldestPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
T pool;
|
T pool;
|
||||||
|
@ -87,8 +89,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
if (pool.CacheNode != _pools.Last)
|
if (pool.CacheNode != _pools.Last)
|
||||||
{
|
{
|
||||||
_pools.Remove(pool.CacheNode);
|
_pools.Remove(pool.CacheNode);
|
||||||
|
_pools.AddLast(pool.CacheNode);
|
||||||
pool.CacheNode = _pools.AddLast(pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pool.CacheTimestamp = _currentTimestamp;
|
pool.CacheTimestamp = _currentTimestamp;
|
||||||
|
|
|
@ -21,7 +21,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
private readonly GpuContext _context;
|
private readonly GpuContext _context;
|
||||||
private readonly GpuChannel _channel;
|
private readonly GpuChannel _channel;
|
||||||
private readonly bool _isCompute;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Array cache entry key.
|
/// Array cache entry key.
|
||||||
|
@ -69,6 +68,16 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
_samplerPool = samplerPool;
|
_samplerPool = samplerPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the pool matches the cached pool.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="texturePool">Texture or sampler pool instance</param>
|
||||||
|
/// <returns>True if the pool matches, false otherwise</returns>
|
||||||
|
public bool MatchesPool<T>(IPool<T> pool)
|
||||||
|
{
|
||||||
|
return _texturePool == pool || _samplerPool == pool;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if the texture and sampler pools matches the cached pools.
|
/// Checks if the texture and sampler pools matches the cached pools.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -531,12 +540,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">GPU context</param>
|
/// <param name="context">GPU context</param>
|
||||||
/// <param name="channel">GPU channel</param>
|
/// <param name="channel">GPU channel</param>
|
||||||
/// <param name="isCompute">Whether the bindings will be used for compute or graphics pipelines</param>
|
public TextureBindingsArrayCache(GpuContext context, GpuChannel channel)
|
||||||
public TextureBindingsArrayCache(GpuContext context, GpuChannel channel, bool isCompute)
|
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_channel = channel;
|
_channel = channel;
|
||||||
_isCompute = isCompute;
|
|
||||||
_cacheFromBuffer = new Dictionary<CacheEntryFromBufferKey, CacheEntryFromBuffer>();
|
_cacheFromBuffer = new Dictionary<CacheEntryFromBufferKey, CacheEntryFromBuffer>();
|
||||||
_cacheFromPool = new Dictionary<CacheEntryFromPoolKey, CacheEntry>();
|
_cacheFromPool = new Dictionary<CacheEntryFromPoolKey, CacheEntry>();
|
||||||
_lruCache = new LinkedList<CacheEntryFromBuffer>();
|
_lruCache = new LinkedList<CacheEntryFromBuffer>();
|
||||||
|
@ -757,9 +764,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
(textureBufferIndex, int samplerBufferIndex) = TextureHandle.UnpackSlots(bindingInfo.CbufSlot, textureBufferIndex);
|
(textureBufferIndex, int samplerBufferIndex) = TextureHandle.UnpackSlots(bindingInfo.CbufSlot, textureBufferIndex);
|
||||||
|
|
||||||
bool separateSamplerBuffer = textureBufferIndex != samplerBufferIndex;
|
bool separateSamplerBuffer = textureBufferIndex != samplerBufferIndex;
|
||||||
|
bool isCompute = stage == ShaderStage.Compute;
|
||||||
|
|
||||||
ref BufferBounds textureBufferBounds = ref _channel.BufferManager.GetUniformBufferBounds(_isCompute, stageIndex, textureBufferIndex);
|
ref BufferBounds textureBufferBounds = ref _channel.BufferManager.GetUniformBufferBounds(isCompute, stageIndex, textureBufferIndex);
|
||||||
ref BufferBounds samplerBufferBounds = ref _channel.BufferManager.GetUniformBufferBounds(_isCompute, stageIndex, samplerBufferIndex);
|
ref BufferBounds samplerBufferBounds = ref _channel.BufferManager.GetUniformBufferBounds(isCompute, stageIndex, samplerBufferIndex);
|
||||||
|
|
||||||
CacheEntryFromBuffer entry = GetOrAddEntry(
|
CacheEntryFromBuffer entry = GetOrAddEntry(
|
||||||
texturePool,
|
texturePool,
|
||||||
|
@ -1064,6 +1072,31 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes all cached texture arrays matching the specified texture pool.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pool">Texture pool</param>
|
||||||
|
public void RemoveAllWithPool<T>(IPool<T> pool)
|
||||||
|
{
|
||||||
|
List<CacheEntryFromPoolKey> keysToRemove = null;
|
||||||
|
|
||||||
|
foreach (CacheEntryFromPoolKey key in _cacheFromPool.Keys)
|
||||||
|
{
|
||||||
|
if (key.MatchesPool(pool))
|
||||||
|
{
|
||||||
|
(keysToRemove ??= new()).Add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keysToRemove != null)
|
||||||
|
{
|
||||||
|
foreach (CacheEntryFromPoolKey key in keysToRemove)
|
||||||
|
{
|
||||||
|
_cacheFromPool.Remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a handle indicates the binding should have all its textures sourced directly from a pool.
|
/// Checks if a handle indicates the binding should have all its textures sourced directly from a pool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
private readonly TexturePoolCache _texturePoolCache;
|
private readonly TexturePoolCache _texturePoolCache;
|
||||||
private readonly SamplerPoolCache _samplerPoolCache;
|
private readonly SamplerPoolCache _samplerPoolCache;
|
||||||
|
|
||||||
private readonly TextureBindingsArrayCache _arrayBindingsCache;
|
private readonly TextureBindingsArrayCache _bindingsArrayCache;
|
||||||
|
|
||||||
private TexturePool _cachedTexturePool;
|
private TexturePool _cachedTexturePool;
|
||||||
private SamplerPool _cachedSamplerPool;
|
private SamplerPool _cachedSamplerPool;
|
||||||
|
@ -72,12 +72,14 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">The GPU context that the texture bindings manager belongs to</param>
|
/// <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="channel">The GPU channel that the texture bindings manager belongs to</param>
|
||||||
|
/// <param name="bindingsArrayCache">Cache of texture array bindings</param>
|
||||||
/// <param name="texturePoolCache">Texture pools cache used to get texture pools from</param>
|
/// <param name="texturePoolCache">Texture pools cache used to get texture pools from</param>
|
||||||
/// <param name="samplerPoolCache">Sampler pools cache used to get sampler pools from</param>
|
/// <param name="samplerPoolCache">Sampler pools cache used to get sampler pools from</param>
|
||||||
/// <param name="isCompute">True if the bindings manager is used for the compute engine</param>
|
/// <param name="isCompute">True if the bindings manager is used for the compute engine</param>
|
||||||
public TextureBindingsManager(
|
public TextureBindingsManager(
|
||||||
GpuContext context,
|
GpuContext context,
|
||||||
GpuChannel channel,
|
GpuChannel channel,
|
||||||
|
TextureBindingsArrayCache bindingsArrayCache,
|
||||||
TexturePoolCache texturePoolCache,
|
TexturePoolCache texturePoolCache,
|
||||||
SamplerPoolCache samplerPoolCache,
|
SamplerPoolCache samplerPoolCache,
|
||||||
bool isCompute)
|
bool isCompute)
|
||||||
|
@ -89,7 +91,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
_isCompute = isCompute;
|
_isCompute = isCompute;
|
||||||
|
|
||||||
_arrayBindingsCache = new TextureBindingsArrayCache(context, channel, isCompute);
|
_bindingsArrayCache = bindingsArrayCache;
|
||||||
|
|
||||||
int stages = isCompute ? 1 : Constants.ShaderStages;
|
int stages = isCompute ? 1 : Constants.ShaderStages;
|
||||||
|
|
||||||
|
@ -456,7 +458,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
if (bindingInfo.ArrayLength > 1)
|
if (bindingInfo.ArrayLength > 1)
|
||||||
{
|
{
|
||||||
_arrayBindingsCache.UpdateTextureArray(texturePool, samplerPool, stage, stageIndex, _textureBufferIndex, _samplerIndex, bindingInfo);
|
_bindingsArrayCache.UpdateTextureArray(texturePool, samplerPool, stage, stageIndex, _textureBufferIndex, _samplerIndex, bindingInfo);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -594,7 +596,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
if (bindingInfo.ArrayLength > 1)
|
if (bindingInfo.ArrayLength > 1)
|
||||||
{
|
{
|
||||||
_arrayBindingsCache.UpdateImageArray(pool, stage, stageIndex, _textureBufferIndex, bindingInfo);
|
_bindingsArrayCache.UpdateImageArray(pool, stage, stageIndex, _textureBufferIndex, bindingInfo);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -732,7 +734,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
ulong poolAddress = _channel.MemoryManager.Translate(poolGpuVa);
|
ulong poolAddress = _channel.MemoryManager.Translate(poolGpuVa);
|
||||||
|
|
||||||
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, maximumId);
|
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, maximumId, _bindingsArrayCache);
|
||||||
|
|
||||||
TextureDescriptor descriptor;
|
TextureDescriptor descriptor;
|
||||||
|
|
||||||
|
@ -828,7 +830,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
if (poolAddress != MemoryManager.PteUnmapped)
|
if (poolAddress != MemoryManager.PteUnmapped)
|
||||||
{
|
{
|
||||||
texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, _texturePoolMaximumId);
|
texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, _texturePoolMaximumId, _bindingsArrayCache);
|
||||||
_texturePool = texturePool;
|
_texturePool = texturePool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -839,7 +841,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
if (poolAddress != MemoryManager.PteUnmapped)
|
if (poolAddress != MemoryManager.PteUnmapped)
|
||||||
{
|
{
|
||||||
samplerPool = _samplerPoolCache.FindOrCreate(_channel, poolAddress, _samplerPoolMaximumId);
|
samplerPool = _samplerPoolCache.FindOrCreate(_channel, poolAddress, _samplerPoolMaximumId, _bindingsArrayCache);
|
||||||
_samplerPool = samplerPool;
|
_samplerPool = samplerPool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
|
|
||||||
private readonly TextureBindingsManager _cpBindingsManager;
|
private readonly TextureBindingsManager _cpBindingsManager;
|
||||||
private readonly TextureBindingsManager _gpBindingsManager;
|
private readonly TextureBindingsManager _gpBindingsManager;
|
||||||
|
private readonly TextureBindingsArrayCache _bindingsArrayCache;
|
||||||
private readonly TexturePoolCache _texturePoolCache;
|
private readonly TexturePoolCache _texturePoolCache;
|
||||||
private readonly SamplerPoolCache _samplerPoolCache;
|
private readonly SamplerPoolCache _samplerPoolCache;
|
||||||
|
|
||||||
|
@ -46,8 +47,9 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
TexturePoolCache texturePoolCache = new(context);
|
TexturePoolCache texturePoolCache = new(context);
|
||||||
SamplerPoolCache samplerPoolCache = new(context);
|
SamplerPoolCache samplerPoolCache = new(context);
|
||||||
|
|
||||||
_cpBindingsManager = new TextureBindingsManager(context, channel, texturePoolCache, samplerPoolCache, isCompute: true);
|
_bindingsArrayCache = new TextureBindingsArrayCache(context, channel);
|
||||||
_gpBindingsManager = new TextureBindingsManager(context, channel, texturePoolCache, samplerPoolCache, isCompute: false);
|
_cpBindingsManager = new TextureBindingsManager(context, channel, _bindingsArrayCache, texturePoolCache, samplerPoolCache, isCompute: true);
|
||||||
|
_gpBindingsManager = new TextureBindingsManager(context, channel, _bindingsArrayCache, texturePoolCache, samplerPoolCache, isCompute: false);
|
||||||
_texturePoolCache = texturePoolCache;
|
_texturePoolCache = texturePoolCache;
|
||||||
_samplerPoolCache = samplerPoolCache;
|
_samplerPoolCache = samplerPoolCache;
|
||||||
|
|
||||||
|
@ -384,7 +386,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||||
{
|
{
|
||||||
ulong poolAddress = _channel.MemoryManager.Translate(poolGpuVa);
|
ulong poolAddress = _channel.MemoryManager.Translate(poolGpuVa);
|
||||||
|
|
||||||
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, maximumId);
|
TexturePool texturePool = _texturePoolCache.FindOrCreate(_channel, poolAddress, maximumId, _bindingsArrayCache);
|
||||||
|
|
||||||
return texturePool;
|
return texturePool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,6 +213,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
|
||||||
public bool QueryHostSupportsScaledVertexFormats() => _context.Capabilities.SupportsScaledVertexFormats;
|
public bool QueryHostSupportsScaledVertexFormats() => _context.Capabilities.SupportsScaledVertexFormats;
|
||||||
|
|
||||||
|
public bool QueryHostSupportsSeparateSampler() => _context.Capabilities.SupportsSeparateSampler;
|
||||||
|
|
||||||
public bool QueryHostSupportsShaderBallot() => _context.Capabilities.SupportsShaderBallot;
|
public bool QueryHostSupportsShaderBallot() => _context.Capabilities.SupportsShaderBallot;
|
||||||
|
|
||||||
public bool QueryHostSupportsShaderBarrierDivergence() => _context.Capabilities.SupportsShaderBarrierDivergence;
|
public bool QueryHostSupportsShaderBarrierDivergence() => _context.Capabilities.SupportsShaderBarrierDivergence;
|
||||||
|
|
|
@ -176,6 +176,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
supportsCubemapView: true,
|
supportsCubemapView: true,
|
||||||
supportsNonConstantTextureOffset: HwCapabilities.SupportsNonConstantTextureOffset,
|
supportsNonConstantTextureOffset: HwCapabilities.SupportsNonConstantTextureOffset,
|
||||||
supportsScaledVertexFormats: true,
|
supportsScaledVertexFormats: true,
|
||||||
|
supportsSeparateSampler: false,
|
||||||
supportsShaderBallot: HwCapabilities.SupportsShaderBallot,
|
supportsShaderBallot: HwCapabilities.SupportsShaderBallot,
|
||||||
supportsShaderBarrierDivergence: !(intelWindows || intelUnix),
|
supportsShaderBarrierDivergence: !(intelWindows || intelUnix),
|
||||||
supportsShaderFloat64: true,
|
supportsShaderFloat64: true,
|
||||||
|
|
|
@ -291,6 +291,15 @@ namespace Ryujinx.Graphics.Shader
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries host API support for separate textures and samplers.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if the API supports samplers and textures to be combined on the shader, false otherwise</returns>
|
||||||
|
bool QueryHostSupportsSeparateSampler()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queries host GPU shader ballot support.
|
/// Queries host GPU shader ballot support.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -55,6 +55,13 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
||||||
TextureOperation texOp,
|
TextureOperation texOp,
|
||||||
LinkedListNode<INode> node)
|
LinkedListNode<INode> node)
|
||||||
{
|
{
|
||||||
|
if (!gpuAccessor.QueryHostSupportsSeparateSampler())
|
||||||
|
{
|
||||||
|
// We depend on combining samplers and textures in the shader being supported for this.
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Operand nvHandle = texOp.GetSource(0);
|
Operand nvHandle = texOp.GetSource(0);
|
||||||
|
|
||||||
if (nvHandle.AsgOp is not Operation handleOp ||
|
if (nvHandle.AsgOp is not Operation handleOp ||
|
||||||
|
|
|
@ -706,6 +706,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
supportsCubemapView: !IsAmdGcn,
|
supportsCubemapView: !IsAmdGcn,
|
||||||
supportsNonConstantTextureOffset: false,
|
supportsNonConstantTextureOffset: false,
|
||||||
supportsScaledVertexFormats: FormatCapabilities.SupportsScaledVertexFormats(),
|
supportsScaledVertexFormats: FormatCapabilities.SupportsScaledVertexFormats(),
|
||||||
|
supportsSeparateSampler: true,
|
||||||
supportsShaderBallot: false,
|
supportsShaderBallot: false,
|
||||||
supportsShaderBarrierDivergence: Vendor != Vendor.Intel,
|
supportsShaderBarrierDivergence: Vendor != Vendor.Intel,
|
||||||
supportsShaderFloat64: Capabilities.SupportsShaderFloat64,
|
supportsShaderFloat64: Capabilities.SupportsShaderFloat64,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue