aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-11-18 23:27:54 -0300
committerGitHub <noreply@github.com>2022-11-18 23:27:54 -0300
commit2e43d01d3658d82f98c9eeea8280d8ec122c0c6b (patch)
tree9d9e33db173a6dfc9e3fa0c05b3421a74f621d14
parent7373ec579226e198d3d7825811eb592489acee1c (diff)
Move gl_Layer from vertex to geometry if GPU does not support it on vertex (#3866)1.1.364
* Move gl_Layer from vertex to geometry if GPU does not support it on vertex * Shader cache version bump * PR feedback
-rw-r--r--Ryujinx.Graphics.GAL/Capabilities.cs3
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs12
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs12
-rw-r--r--Ryujinx.Graphics.OpenGL/HwCapabilities.cs2
-rw-r--r--Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs3
-rw-r--r--Ryujinx.Graphics.Shader/IGpuAccessor.cs9
-rw-r--r--Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs14
-rw-r--r--Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs38
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Translator.cs12
-rw-r--r--Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs97
-rw-r--r--Ryujinx.Graphics.Vulkan/VulkanRenderer.cs1
13 files changed, 190 insertions, 17 deletions
diff --git a/Ryujinx.Graphics.GAL/Capabilities.cs b/Ryujinx.Graphics.GAL/Capabilities.cs
index 3138a43b..60f93bc4 100644
--- a/Ryujinx.Graphics.GAL/Capabilities.cs
+++ b/Ryujinx.Graphics.GAL/Capabilities.cs
@@ -21,6 +21,7 @@ namespace Ryujinx.Graphics.GAL
public readonly bool SupportsFragmentShaderOrderingIntel;
public readonly bool SupportsGeometryShaderPassthrough;
public readonly bool SupportsImageLoadFormatted;
+ public readonly bool SupportsLayerVertexTessellation;
public readonly bool SupportsMismatchingViewFormat;
public readonly bool SupportsCubemapView;
public readonly bool SupportsNonConstantTextureOffset;
@@ -55,6 +56,7 @@ namespace Ryujinx.Graphics.GAL
bool supportsFragmentShaderOrderingIntel,
bool supportsGeometryShaderPassthrough,
bool supportsImageLoadFormatted,
+ bool supportsLayerVertexTessellation,
bool supportsMismatchingViewFormat,
bool supportsCubemapView,
bool supportsNonConstantTextureOffset,
@@ -86,6 +88,7 @@ namespace Ryujinx.Graphics.GAL
SupportsFragmentShaderOrderingIntel = supportsFragmentShaderOrderingIntel;
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
SupportsImageLoadFormatted = supportsImageLoadFormatted;
+ SupportsLayerVertexTessellation = supportsLayerVertexTessellation;
SupportsMismatchingViewFormat = supportsMismatchingViewFormat;
SupportsCubemapView = supportsCubemapView;
SupportsNonConstantTextureOffset = supportsNonConstantTextureOffset;
diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
index 7923a393..69067fe6 100644
--- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
- private const uint CodeGenVersion = 3863;
+ private const uint CodeGenVersion = 3866;
private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data";
diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs
index 04d93bba..9261cb0d 100644
--- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/ParallelDiskCacheLoader.cs
@@ -636,6 +636,8 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
CachedShaderStage[] shaders = new CachedShaderStage[guestShaders.Length];
List<ShaderProgram> translatedStages = new List<ShaderProgram>();
+ TranslatorContext previousStage = null;
+
for (int stageIndex = 0; stageIndex < Constants.ShaderStages; stageIndex++)
{
TranslatorContext currentStage = translatorContexts[stageIndex + 1];
@@ -668,6 +670,16 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
{
translatedStages.Add(program);
}
+
+ previousStage = currentStage;
+ }
+ else if (
+ previousStage != null &&
+ previousStage.LayerOutputWritten &&
+ stageIndex == 3 &&
+ !_context.Capabilities.SupportsLayerVertexTessellation)
+ {
+ translatedStages.Add(previousStage.GenerateGeometryPassthrough());
}
}
diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs b/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs
index 40c5ed64..9648298e 100644
--- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessorBase.cs
@@ -128,6 +128,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
public bool QueryHostSupportsImageLoadFormatted() => _context.Capabilities.SupportsImageLoadFormatted;
+ public bool QueryHostSupportsLayerVertexTessellation() => _context.Capabilities.SupportsLayerVertexTessellation;
+
public bool QueryHostSupportsNonConstantTextureOffset() => _context.Capabilities.SupportsNonConstantTextureOffset;
public bool QueryHostSupportsShaderBallot() => _context.Capabilities.SupportsShaderBallot;
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index 2a9dd6a5..3eaab79f 100644
--- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -356,6 +356,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
CachedShaderStage[] shaders = new CachedShaderStage[Constants.ShaderStages + 1];
List<ShaderSource> shaderSources = new List<ShaderSource>();
+ TranslatorContext previousStage = null;
+
for (int stageIndex = 0; stageIndex < Constants.ShaderStages; stageIndex++)
{
TranslatorContext currentStage = translatorContexts[stageIndex + 1];
@@ -392,6 +394,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
{
shaderSources.Add(CreateShaderSource(program));
}
+
+ previousStage = currentStage;
+ }
+ else if (
+ previousStage != null &&
+ previousStage.LayerOutputWritten &&
+ stageIndex == 3 &&
+ !_context.Capabilities.SupportsLayerVertexTessellation)
+ {
+ shaderSources.Add(CreateShaderSource(previousStage.GenerateGeometryPassthrough()));
}
}
diff --git a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
index ba2cc2df..8caf11dd 100644
--- a/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
+++ b/Ryujinx.Graphics.OpenGL/HwCapabilities.cs
@@ -18,6 +18,7 @@ namespace Ryujinx.Graphics.OpenGL
private static readonly Lazy<bool> _supportsQuads = new Lazy<bool>(SupportsQuadsCheck);
private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new Lazy<bool>(() => HasExtension("GL_ARB_seamless_cubemap_per_texture"));
private static readonly Lazy<bool> _supportsShaderBallot = new Lazy<bool>(() => HasExtension("GL_ARB_shader_ballot"));
+ private static readonly Lazy<bool> _supportsShaderViewportLayerArray = new Lazy<bool>(() => HasExtension("GL_ARB_shader_viewport_layer_array"));
private static readonly Lazy<bool> _supportsTextureCompressionBptc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_bptc"));
private static readonly Lazy<bool> _supportsTextureCompressionRgtc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_rgtc"));
private static readonly Lazy<bool> _supportsTextureCompressionS3tc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_s3tc"));
@@ -61,6 +62,7 @@ namespace Ryujinx.Graphics.OpenGL
public static bool SupportsQuads => _supportsQuads.Value;
public static bool SupportsSeamlessCubemapPerTexture => _supportsSeamlessCubemapPerTexture.Value;
public static bool SupportsShaderBallot => _supportsShaderBallot.Value;
+ public static bool SupportsShaderViewportLayerArray => _supportsShaderViewportLayerArray.Value;
public static bool SupportsTextureCompressionBptc => _supportsTextureCompressionBptc.Value;
public static bool SupportsTextureCompressionRgtc => _supportsTextureCompressionRgtc.Value;
public static bool SupportsTextureCompressionS3tc => _supportsTextureCompressionS3tc.Value;
diff --git a/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
index 418976e6..e26fe6b6 100644
--- a/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
+++ b/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs
@@ -117,12 +117,13 @@ namespace Ryujinx.Graphics.OpenGL
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
supportsImageLoadFormatted: HwCapabilities.SupportsImageLoadFormatted,
+ supportsLayerVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
supportsMismatchingViewFormat: HwCapabilities.SupportsMismatchingViewFormat,
supportsCubemapView: true,
supportsNonConstantTextureOffset: HwCapabilities.SupportsNonConstantTextureOffset,
supportsShaderBallot: HwCapabilities.SupportsShaderBallot,
supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod,
- supportsViewportIndex: true,
+ supportsViewportIndex: HwCapabilities.SupportsShaderViewportLayerArray,
supportsViewportSwizzle: HwCapabilities.SupportsViewportSwizzle,
supportsIndirectParameters: HwCapabilities.SupportsIndirectParameters,
maximumUniformBuffersPerStage: 13, // TODO: Avoid hardcoding those limits here and get from driver?
diff --git a/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/Ryujinx.Graphics.Shader/IGpuAccessor.cs
index f05a8527..cc690eed 100644
--- a/Ryujinx.Graphics.Shader/IGpuAccessor.cs
+++ b/Ryujinx.Graphics.Shader/IGpuAccessor.cs
@@ -259,6 +259,15 @@ namespace Ryujinx.Graphics.Shader
}
/// <summary>
+ /// Queries host support for writes to Layer from vertex or tessellation shader stages.
+ /// </summary>
+ /// <returns>True if writes to layer from vertex or tessellation are supported, false otherwise</returns>
+ bool QueryHostSupportsLayerVertexTessellation()
+ {
+ return true;
+ }
+
+ /// <summary>
/// Queries host GPU non-constant texture offset support.
/// </summary>
/// <returns>True if the GPU and driver supports non-constant texture offsets, false otherwise</returns>
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs
index 2f75d248..9f9ac141 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs
@@ -278,13 +278,21 @@ namespace Ryujinx.Graphics.Shader.Instructions
private static int FixedFuncToUserAttribute(ShaderConfig config, int attr, bool isOutput)
{
- if (attr >= AttributeConsts.FrontColorDiffuseR && attr < AttributeConsts.ClipDistance0)
+ bool supportsLayerFromVertexOrTess = config.GpuAccessor.QueryHostSupportsLayerVertexTessellation();
+ int fixedStartAttr = supportsLayerFromVertexOrTess ? 0 : 1;
+
+ if (attr == AttributeConsts.Layer && config.Stage != ShaderStage.Geometry && !supportsLayerFromVertexOrTess)
+ {
+ attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.Layer, 0, isOutput);
+ config.SetLayerOutputAttribute(attr);
+ }
+ else if (attr >= AttributeConsts.FrontColorDiffuseR && attr < AttributeConsts.ClipDistance0)
{
- attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.FrontColorDiffuseR, 0, isOutput);
+ attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.FrontColorDiffuseR, fixedStartAttr, isOutput);
}
else if (attr >= AttributeConsts.TexCoordBase && attr < AttributeConsts.TexCoordEnd)
{
- attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.TexCoordBase, 4, isOutput);
+ attr = FixedFuncToUserAttribute(config, attr, AttributeConsts.TexCoordBase, fixedStartAttr + 4, isOutput);
}
return attr;
diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
index fcf35ce2..ae4107e8 100644
--- a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
+++ b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
@@ -48,6 +48,9 @@ namespace Ryujinx.Graphics.Shader.Translation
public int Cb1DataSize { get; private set; }
+ public bool LayerOutputWritten { get; private set; }
+ public int LayerOutputAttribute { get; private set; }
+
public bool NextUsesFixedFuncAttributes { get; private set; }
public int UsedInputAttributes { get; private set; }
public int UsedOutputAttributes { get; private set; }
@@ -131,6 +134,20 @@ namespace Ryujinx.Graphics.Shader.Translation
_usedImages = new Dictionary<TextureInfo, TextureMeta>();
}
+ public ShaderConfig(
+ ShaderStage stage,
+ OutputTopology outputTopology,
+ int maxOutputVertices,
+ IGpuAccessor gpuAccessor,
+ TranslationOptions options) : this(gpuAccessor, options)
+ {
+ Stage = stage;
+ ThreadsPerInputPrimitive = 1;
+ OutputTopology = outputTopology;
+ MaxOutputVertices = maxOutputVertices;
+ TransformFeedbackEnabled = gpuAccessor.QueryTransformFeedbackEnabled();
+ }
+
public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationOptions options) : this(gpuAccessor, options)
{
Stage = header.Stage;
@@ -240,6 +257,12 @@ namespace Ryujinx.Graphics.Shader.Translation
}
}
+ public void SetLayerOutputAttribute(int attr)
+ {
+ LayerOutputWritten = true;
+ LayerOutputAttribute = attr;
+ }
+
public void SetInputUserAttributeFixedFunc(int index)
{
UsedInputAttributes |= 1 << index;
@@ -694,5 +717,20 @@ namespace Ryujinx.Graphics.Shader.Translation
{
return FindDescriptorIndex(GetImageDescriptors(), texOp);
}
+
+ public ShaderProgramInfo CreateProgramInfo()
+ {
+ return new ShaderProgramInfo(
+ GetConstantBufferDescriptors(),
+ GetStorageBufferDescriptors(),
+ GetTextureDescriptors(),
+ GetImageDescriptors(),
+ Stage,
+ UsedFeatures.HasFlag(FeatureFlags.InstanceId),
+ UsedFeatures.HasFlag(FeatureFlags.DrawParameters),
+ UsedFeatures.HasFlag(FeatureFlags.RtLayer),
+ ClipDistancesWritten,
+ OmapTargets);
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs
index 82539196..f8795c0f 100644
--- a/Ryujinx.Graphics.Shader/Translation/Translator.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs
@@ -79,17 +79,7 @@ namespace Ryujinx.Graphics.Shader.Translation
var sInfo = StructuredProgram.MakeStructuredProgram(funcs, config);
- var info = new ShaderProgramInfo(
- config.GetConstantBufferDescriptors(),
- config.GetStorageBufferDescriptors(),
- config.GetTextureDescriptors(),
- config.GetImageDescriptors(),
- config.Stage,
- config.UsedFeatures.HasFlag(FeatureFlags.InstanceId),
- config.UsedFeatures.HasFlag(FeatureFlags.DrawParameters),
- config.UsedFeatures.HasFlag(FeatureFlags.RtLayer),
- config.ClipDistancesWritten,
- config.OmapTargets);
+ var info = config.CreateProgramInfo();
return config.Options.TargetLanguage switch
{
diff --git a/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs b/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs
index 7d820f03..127f84a6 100644
--- a/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs
+++ b/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs
@@ -1,7 +1,12 @@
-using Ryujinx.Graphics.Shader.Decoders;
+using Ryujinx.Graphics.Shader.CodeGen.Glsl;
+using Ryujinx.Graphics.Shader.CodeGen.Spirv;
+using Ryujinx.Graphics.Shader.Decoders;
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
+using Ryujinx.Graphics.Shader.StructuredIr;
+using System;
using System.Collections.Generic;
using System.Linq;
+using System.Numerics;
using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
using static Ryujinx.Graphics.Shader.Translation.Translator;
@@ -18,6 +23,7 @@ namespace Ryujinx.Graphics.Shader.Translation
public ShaderStage Stage => _config.Stage;
public int Size => _config.Size;
public int Cb1DataSize => _config.Cb1DataSize;
+ public bool LayerOutputWritten => _config.LayerOutputWritten;
public IGpuAccessor GpuAccessor => _config.GpuAccessor;
@@ -149,5 +155,94 @@ namespace Ryujinx.Graphics.Shader.Translation
return Translator.Translate(code, _config);
}
+
+ public ShaderProgram GenerateGeometryPassthrough()
+ {
+ int outputAttributesMask = _config.UsedOutputAttributes;
+ int layerOutputAttr = _config.LayerOutputAttribute;
+
+ OutputTopology outputTopology;
+ int maxOutputVertices;
+
+ switch (GpuAccessor.QueryPrimitiveTopology())
+ {
+ case InputTopology.Points:
+ outputTopology = OutputTopology.PointList;
+ maxOutputVertices = 1;
+ break;
+ case InputTopology.Lines:
+ case InputTopology.LinesAdjacency:
+ outputTopology = OutputTopology.LineStrip;
+ maxOutputVertices = 2;
+ break;
+ default:
+ outputTopology = OutputTopology.TriangleStrip;
+ maxOutputVertices = 3;
+ break;
+ }
+
+ ShaderConfig config = new ShaderConfig(ShaderStage.Geometry, outputTopology, maxOutputVertices, GpuAccessor, _config.Options);
+
+ EmitterContext context = new EmitterContext(default, config, false);
+
+ for (int v = 0; v < maxOutputVertices; v++)
+ {
+ int outAttrsMask = outputAttributesMask;
+
+ while (outAttrsMask != 0)
+ {
+ int attrIndex = BitOperations.TrailingZeroCount(outAttrsMask);
+
+ outAttrsMask &= ~(1 << attrIndex);
+
+ for (int c = 0; c < 4; c++)
+ {
+ int attr = AttributeConsts.UserAttributeBase + attrIndex * 16 + c * 4;
+
+ Operand value = context.LoadAttribute(Const(attr), Const(0), Const(v));
+
+ if (attr == layerOutputAttr)
+ {
+ context.Copy(Attribute(AttributeConsts.Layer), value);
+ }
+ else
+ {
+ context.Copy(Attribute(attr), value);
+ config.SetOutputUserAttribute(attrIndex);
+ }
+
+ config.SetInputUserAttribute(attrIndex, c);
+ }
+ }
+
+ for (int c = 0; c < 4; c++)
+ {
+ int attr = AttributeConsts.PositionX + c * 4;
+
+ Operand value = context.LoadAttribute(Const(attr), Const(0), Const(v));
+
+ context.Copy(Attribute(attr), value);
+ }
+
+ context.EmitVertex();
+ }
+
+ context.EndPrimitive();
+
+ var operations = context.GetOperations();
+ var cfg = ControlFlowGraph.Create(operations);
+ var function = new Function(cfg.Blocks, "main", false, 0, 0);
+
+ var sInfo = StructuredProgram.MakeStructuredProgram(new[] { function }, config);
+
+ var info = config.CreateProgramInfo();
+
+ return config.Options.TargetLanguage switch
+ {
+ TargetLanguage.Glsl => new ShaderProgram(info, TargetLanguage.Glsl, GlslGenerator.Generate(sInfo, config)),
+ TargetLanguage.Spirv => new ShaderProgram(info, TargetLanguage.Spirv, SpirvGenerator.Generate(sInfo, config)),
+ _ => throw new NotImplementedException(config.Options.TargetLanguage.ToString())
+ };
+ }
}
}
diff --git a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index 4a905d33..3f8ebe67 100644
--- a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -396,6 +396,7 @@ namespace Ryujinx.Graphics.Vulkan
supportsFragmentShaderOrderingIntel: false,
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
supportsImageLoadFormatted: features2.Features.ShaderStorageImageReadWithoutFormat,
+ supportsLayerVertexTessellation: featuresVk12.ShaderOutputLayer,
supportsMismatchingViewFormat: true,
supportsCubemapView: !IsAmdGcn,
supportsNonConstantTextureOffset: false,