1 // 2 // Copyright 2015 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // FeaturesD3D.h: Features and workarounds for D3D driver bugs and other issues. 8 9 #ifndef ANGLE_PLATFORM_FEATURESD3D_H_ 10 #define ANGLE_PLATFORM_FEATURESD3D_H_ 11 12 #include "platform/Feature.h" 13 14 namespace angle 15 { 16 17 // Workarounds attached to each shader. Do not need to expose information about these workarounds so 18 // a simple bool struct suffices. 19 struct CompilerWorkaroundsD3D 20 { 21 bool skipOptimization = false; 22 23 bool useMaxOptimization = false; 24 25 // IEEE strictness needs to be enabled for NANs to work. 26 bool enableIEEEStrictness = false; 27 }; 28 29 struct FeaturesD3D : FeatureSetBase 30 { 31 FeaturesD3D(); 32 ~FeaturesD3D(); 33 34 // On some systems, having extra rendertargets than necessary slows down the shader. 35 // We can fix this by optimizing those out of the shader. At the same time, we can 36 // work around a bug on some nVidia drivers that they ignore "null" render targets 37 // in D3D11, by compacting the active color attachments list to omit null entries. 38 Feature mrtPerfWorkaround = {"mrt_perf_workaround", FeatureCategory::D3DWorkarounds, 39 "Some drivers have a bug where they ignore null render targets", 40 &members}; 41 42 Feature setDataFasterThanImageUpload = {"set_data_faster_than_image_upload", 43 FeatureCategory::D3DWorkarounds, 44 "Set data faster than image upload", &members}; 45 46 // Some renderers can't disable mipmaps on a mipmapped texture (i.e. solely sample from level 47 // zero, and ignore the other levels). D3D11 Feature Level 10+ does this by setting MaxLOD to 48 // 0.0f in the Sampler state. D3D9 sets D3DSAMP_MIPFILTER to D3DTEXF_NONE. There is no 49 // equivalent to this in D3D11 Feature Level 9_3. This causes problems when (for example) an 50 // application creates a mipmapped texture2D, but sets GL_TEXTURE_MIN_FILTER to GL_NEAREST 51 // (i.e disables mipmaps). To work around this, D3D11 FL9_3 has to create two copies of the 52 // texture. The textures' level zeros are identical, but only one texture has mips. 53 Feature zeroMaxLodWorkaround = {"zero_max_lod", FeatureCategory::D3DWorkarounds, 54 "Missing an option to disable mipmaps on a mipmapped texture", 55 &members}; 56 57 // Some renderers do not support Geometry Shaders so the Geometry Shader-based PointSprite 58 // emulation will not work. To work around this, D3D11 FL9_3 has to use a different pointsprite 59 // emulation that is implemented using instanced quads. 60 Feature useInstancedPointSpriteEmulation = { 61 "use_instanced_point_sprite_emulation", FeatureCategory::D3DWorkarounds, 62 "Some D3D11 renderers do not support geometry shaders for pointsprite emulation", &members}; 63 64 // A bug fixed in NVIDIA driver version 347.88 < x <= 368.81 triggers a TDR when using 65 // CopySubresourceRegion from a staging texture to a depth/stencil in D3D11. The workaround 66 // is to use UpdateSubresource to trigger an extra copy. We disable this workaround on newer 67 // NVIDIA driver versions because of a second driver bug present with the workaround enabled. 68 // (See: http://anglebug.com/1452) 69 Feature depthStencilBlitExtraCopy = { 70 "depth_stencil_blit_extra_copy", FeatureCategory::D3DWorkarounds, 71 "Bug in some drivers triggers a TDR when using CopySubresourceRegion from a staging " 72 "texture to a depth/stencil", 73 &members, "http://anglebug.com/1452"}; 74 75 // The HLSL optimizer has a bug with optimizing "pow" in certain integer-valued expressions. 76 // We can work around this by expanding the pow into a series of multiplies if we're running 77 // under the affected compiler. 78 Feature expandIntegerPowExpressions = { 79 "expand_integer_pow_expressions", FeatureCategory::D3DWorkarounds, 80 "The HLSL optimizer has a bug with optimizing 'pow' in certain integer-valued expressions", 81 &members}; 82 83 // NVIDIA drivers sometimes write out-of-order results to StreamOut buffers when transform 84 // feedback is used to repeatedly write to the same buffer positions. 85 Feature flushAfterEndingTransformFeedback = { 86 "flush_after_ending_transform_feedback", FeatureCategory::D3DWorkarounds, 87 "Some drivers sometimes write out-of-order results to StreamOut buffers when transform " 88 "feedback is used to repeatedly write to the same buffer positions", 89 &members}; 90 91 // Some drivers (NVIDIA) do not take into account the base level of the texture in the results 92 // of the HLSL GetDimensions builtin. 93 Feature getDimensionsIgnoresBaseLevel = { 94 "get_dimensions_ignores_base_level", FeatureCategory::D3DWorkarounds, 95 "Some drivers do not take into account the base level of the " 96 "texture in the results of the HLSL GetDimensions builtin", 97 &members}; 98 99 // On some Intel drivers, HLSL's function texture.Load returns 0 when the parameter Location 100 // is negative, even if the sum of Offset and Location is in range. This may cause errors when 101 // translating GLSL's function texelFetchOffset into texture.Load, as it is valid for 102 // texelFetchOffset to use negative texture coordinates as its parameter P when the sum of P 103 // and Offset is in range. To work around this, we translate texelFetchOffset into texelFetch 104 // by adding Offset directly to Location before reading the texture. 105 Feature preAddTexelFetchOffsets = { 106 "pre_add_texel_fetch_offsets", FeatureCategory::D3DWorkarounds, 107 "HLSL's function texture.Load returns 0 when the parameter Location is negative, even if " 108 "the sum of Offset and Location is in range", 109 &members}; 110 111 // On some AMD drivers, 1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly. 112 // We can work around this bug by doing an internal blit to a temporary single-channel texture 113 // before we sample. 114 Feature emulateTinyStencilTextures = { 115 "emulate_tiny_stencil_textures", FeatureCategory::D3DWorkarounds, 116 "1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly", &members}; 117 118 // In Intel driver, the data with format DXGI_FORMAT_B5G6R5_UNORM will be parsed incorrectly. 119 // This workaroud will disable B5G6R5 support when it's Intel driver. By default, it will use 120 // R8G8B8A8 format. This bug is fixed in version 4539 on Intel drivers. 121 // On older AMD drivers, the data in DXGI_FORMAT_B5G6R5_UNORM becomes corrupted for unknown 122 // reasons. 123 Feature disableB5G6R5Support = {"disable_b5g6r5_support", FeatureCategory::D3DWorkarounds, 124 "Textures with the format " 125 "DXGI_FORMAT_B5G6R5_UNORM have incorrect data", 126 &members}; 127 128 // On some Intel drivers, evaluating unary minus operator on integer may get wrong answer in 129 // vertex shaders. To work around this bug, we translate -(int) into ~(int)+1. 130 // This driver bug is fixed in 20.19.15.4624. 131 Feature rewriteUnaryMinusOperator = { 132 "rewrite_unary_minus_operator", FeatureCategory::D3DWorkarounds, 133 "Evaluating unary minus operator on integer may get wrong answer in vertex shaders", 134 &members}; 135 136 // On some Intel drivers, using isnan() on highp float will get wrong answer. To work around 137 // this bug, we use an expression to emulate function isnan(). 138 // Tracking bug: https://crbug.com/650547 139 // This driver bug is fixed in 21.20.16.4542. 140 Feature emulateIsnanFloat = {"emulate_isnan_float", FeatureCategory::D3DWorkarounds, 141 "Using isnan() on highp float will get wrong answer", &members, 142 "https://crbug.com/650547"}; 143 144 // On some Intel drivers, using clear() may not take effect. To work around this bug, we call 145 // clear() twice on these platforms. 146 // Tracking bug: https://crbug.com/655534 147 Feature callClearTwice = {"call_clear_twice", FeatureCategory::D3DWorkarounds, 148 "Using clear() may not take effect", &members, 149 "https://crbug.com/655534"}; 150 151 // On some Intel drivers, copying from staging storage to constant buffer storage does not 152 // seem to work. Work around this by keeping system memory storage as a canonical reference 153 // for buffer data. 154 // D3D11-only workaround. See http://crbug.com/593024. 155 Feature useSystemMemoryForConstantBuffers = {"use_system_memory_for_constant_buffers", 156 FeatureCategory::D3DWorkarounds, 157 "Copying from staging storage to constant buffer " 158 "storage does not work", 159 &members, "https://crbug.com/593024"}; 160 161 // This workaround is for the ANGLE_multiview extension. If enabled the viewport or render 162 // target slice will be selected in the geometry shader stage. The workaround flag is added to 163 // make it possible to select the code path in end2end and performance tests. 164 Feature selectViewInGeometryShader = { 165 "select_view_in_geometry_shader", FeatureCategory::D3DWorkarounds, 166 "The viewport or render target slice will be selected in the geometry shader stage for " 167 "the ANGLE_multiview extension", 168 &members}; 169 170 // When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel 171 // drivers < 4815. The rendering samples always pass neglecting discard statements in pixel 172 // shader. 173 // 1. If rendertarget is not set, the pixel shader will be recompiled to drop 'SV_TARGET'. 174 // When using a pixel shader with no 'SV_TARGET' in a draw, the pixels are always generated even 175 // if they should be discard by 'discard' statements. 176 // 2. If ID3D11BlendState.RenderTarget[].RenderTargetWriteMask is 0 and rendertarget is not set, 177 // then rendering samples also pass neglecting discard statements in pixel shader. 178 // So we add a mock texture as render target in such case. See http://anglebug.com/2152 179 Feature addMockTextureNoRenderTarget = { 180 "add_mock_texture_no_render_target", FeatureCategory::D3DWorkarounds, 181 "On some drivers when rendering with no render target, two bugs lead to incorrect behavior", 182 &members, "http://anglebug.com/2152"}; 183 184 // Don't use D3D constant register zero when allocating space for uniforms in the vertex shader. 185 // This is targeted to work around a bug in NVIDIA D3D driver version 388.59 where in very 186 // specific cases the driver would not handle constant register zero correctly. 187 Feature skipVSConstantRegisterZero = { 188 "skip_vs_constant_register_zero", FeatureCategory::D3DWorkarounds, 189 "In specific cases the driver doesn't handle constant register zero correctly", &members}; 190 191 // Forces the value returned from an atomic operations to be always be resolved. This is 192 // targeted to workaround a bug in NVIDIA D3D driver where the return value from 193 // RWByteAddressBuffer.InterlockedAdd does not get resolved when used in the .yzw components of 194 // a RWByteAddressBuffer.Store operation. Only has an effect on HLSL translation. 195 // http://anglebug.com/3246 196 Feature forceAtomicValueResolution = { 197 "force_atomic_value_resolution", FeatureCategory::D3DWorkarounds, 198 "On some drivers the return value from RWByteAddressBuffer.InterlockedAdd does not resolve " 199 "when used in the .yzw components of a RWByteAddressBuffer.Store operation", 200 &members, "http://anglebug.com/3246"}; 201 202 // Match chromium's robust resource init behaviour by always prefering to upload texture data 203 // instead of clearing. Clear calls have been observed to cause texture corruption for some 204 // formats. 205 Feature allowClearForRobustResourceInit = { 206 "allow_clear_for_robust_resource_init", FeatureCategory::D3DWorkarounds, 207 "Some drivers corrupt texture data when clearing for robust resource initialization.", 208 &members, "http://crbug.com/941620"}; 209 210 // Allow translating uniform block to StructuredBuffer. This is targeted to work around a slow 211 // fxc compile performance issue with dynamic uniform indexing. http://anglebug.com/3682 212 Feature allowTranslateUniformBlockToStructuredBuffer = { 213 "allow_translate_uniform_block_to_structured_buffer", FeatureCategory::D3DWorkarounds, 214 "There is a slow fxc compile performance issue with dynamic uniform indexing if " 215 "translating a uniform block with a large array member to cbuffer.", 216 &members, "http://anglebug.com/3682"}; 217 218 Feature allowES3OnFL10_0 = {"allowES3OnFL10_0", FeatureCategory::D3DWorkarounds, 219 "Allow ES3 on 10.0 devices", &members}; 220 }; 221 222 inline FeaturesD3D::FeaturesD3D() = default; 223 inline FeaturesD3D::~FeaturesD3D() = default; 224 225 } // namespace angle 226 227 #endif // ANGLE_PLATFORM_FEATURESD3D_H_ 228