зеркало из https://github.com/AvaloniaUI/angle.git
Change all ANGLE workarounds to use struct definition with info.
Change each workaround from a simple bool to a struct with info including name, workaround set, description, and bug IDs. This will help with future workaround integration with Chrome. Bug: angleproject:1621 Change-Id: Ia27c180abaf845e280060c803e5994cc3152a057 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1593917 Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Родитель
cd078c3392
Коммит
776694cdad
|
@ -0,0 +1,155 @@
|
|||
//
|
||||
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// Feature.h: Definition of structs to hold feature/workaround information.
|
||||
//
|
||||
|
||||
#ifndef ANGLE_PLATFORM_FEATURE_H_
|
||||
#define ANGLE_PLATFORM_FEATURE_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
enum class FeatureCategory
|
||||
{
|
||||
FrontendWorkarounds,
|
||||
OpenGLWorkarounds,
|
||||
D3DWorkarounds,
|
||||
D3DCompilerWorkarounds,
|
||||
VulkanWorkarounds,
|
||||
VulkanFeatures,
|
||||
};
|
||||
|
||||
constexpr char kFeatureCategoryFrontendWorkarounds[] = "Frontend workarounds";
|
||||
constexpr char kFeatureCategoryOpenGLWorkarounds[] = "OpenGL workarounds";
|
||||
constexpr char kFeatureCategoryD3DWorkarounds[] = "D3D workarounds";
|
||||
constexpr char kFeatureCategoryD3DCompilerWorkarounds[] = "D3D compiler workarounds";
|
||||
constexpr char kFeatureCategoryVulkanWorkarounds[] = "Vulkan workarounds";
|
||||
constexpr char kFeatureCategoryVulkanFeatures[] = "Vulkan features";
|
||||
|
||||
inline const char *FeatureCategoryToString(const FeatureCategory &fc)
|
||||
{
|
||||
switch (fc)
|
||||
{
|
||||
case FeatureCategory::FrontendWorkarounds:
|
||||
return kFeatureCategoryFrontendWorkarounds;
|
||||
break;
|
||||
|
||||
case FeatureCategory::OpenGLWorkarounds:
|
||||
return kFeatureCategoryOpenGLWorkarounds;
|
||||
break;
|
||||
|
||||
case FeatureCategory::D3DWorkarounds:
|
||||
return kFeatureCategoryD3DWorkarounds;
|
||||
break;
|
||||
|
||||
case FeatureCategory::D3DCompilerWorkarounds:
|
||||
return kFeatureCategoryD3DCompilerWorkarounds;
|
||||
break;
|
||||
|
||||
case FeatureCategory::VulkanWorkarounds:
|
||||
return kFeatureCategoryVulkanWorkarounds;
|
||||
break;
|
||||
|
||||
case FeatureCategory::VulkanFeatures:
|
||||
return kFeatureCategoryVulkanFeatures;
|
||||
break;
|
||||
|
||||
default:
|
||||
return "Unknown";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct Feature;
|
||||
|
||||
using FeatureMap = std::map<std::string, Feature *>;
|
||||
using FeatureList = std::vector<const Feature *>;
|
||||
|
||||
struct Feature
|
||||
{
|
||||
Feature(const Feature &other);
|
||||
Feature(const char *name,
|
||||
const FeatureCategory &category,
|
||||
const char *description,
|
||||
FeatureMap *const mapPtr,
|
||||
const char *bug);
|
||||
~Feature();
|
||||
|
||||
// The name of the workaround, lowercase, camel_case
|
||||
const char *const name;
|
||||
|
||||
// The category that the workaround belongs to. Eg. "Vulkan workarounds"
|
||||
const FeatureCategory category;
|
||||
|
||||
// A short description to be read by the user.
|
||||
const char *const description;
|
||||
|
||||
// A link to the bug, if any
|
||||
const char *const bug;
|
||||
|
||||
// Whether the workaround is enabled or not. Determined by heuristics like vendor ID and
|
||||
// version, but may be overriden to any value.
|
||||
bool enabled = false;
|
||||
};
|
||||
|
||||
inline Feature::Feature(const Feature &other) = default;
|
||||
inline Feature::Feature(const char *name,
|
||||
const FeatureCategory &category,
|
||||
const char *description,
|
||||
FeatureMap *const mapPtr,
|
||||
const char *bug = "")
|
||||
: name(name), category(category), description(description), bug(bug), enabled(false)
|
||||
{
|
||||
if (mapPtr != nullptr)
|
||||
{
|
||||
(*mapPtr)[std::string(name)] = this;
|
||||
}
|
||||
}
|
||||
|
||||
inline Feature::~Feature() = default;
|
||||
|
||||
struct FeatureSetBase
|
||||
{
|
||||
public:
|
||||
FeatureSetBase();
|
||||
~FeatureSetBase();
|
||||
|
||||
private:
|
||||
// Non-copyable
|
||||
FeatureSetBase(const FeatureSetBase &other) = delete;
|
||||
FeatureSetBase &operator=(const FeatureSetBase &other) = delete;
|
||||
|
||||
protected:
|
||||
FeatureMap members = FeatureMap();
|
||||
|
||||
public:
|
||||
void forceFeatureEnabled(const std::string &name, const bool enabled)
|
||||
{
|
||||
if (members.find(name) != members.end())
|
||||
{
|
||||
members[name]->enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
void getFeatures(FeatureList &features) const
|
||||
{
|
||||
for (FeatureMap::const_iterator it = members.begin(); it != members.end(); it++)
|
||||
{
|
||||
features.push_back(it->second);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline FeatureSetBase::FeatureSetBase() = default;
|
||||
inline FeatureSetBase::~FeatureSetBase() = default;
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // ANGLE_PLATFORM_WORKAROUND_H_
|
|
@ -9,18 +9,25 @@
|
|||
#ifndef ANGLE_PLATFORM_FEATURESVK_H_
|
||||
#define ANGLE_PLATFORM_FEATURESVK_H_
|
||||
|
||||
#include "platform/Feature.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
struct FeaturesVk
|
||||
struct FeaturesVk : angle::FeatureSetBase
|
||||
{
|
||||
FeaturesVk();
|
||||
~FeaturesVk();
|
||||
|
||||
// Line segment rasterization must follow OpenGL rules. This means using an algorithm similar
|
||||
// to Bresenham's. Vulkan uses a different algorithm. This feature enables the use of pixel
|
||||
// shader patching to implement OpenGL basic line rasterization rules. This feature will
|
||||
// normally always be enabled. Exposing it as an option enables performance testing.
|
||||
bool basicGLLineRasterization = false;
|
||||
angle::Feature basicGLLineRasterization = {
|
||||
"basic_gl_line_rasterization", angle::FeatureCategory::VulkanFeatures,
|
||||
"Enable the use of pixel shader patching to implement OpenGL basic line "
|
||||
"rasterization rules",
|
||||
&members};
|
||||
|
||||
// Flips the viewport to render upside-down. This has the effect to render the same way as
|
||||
// OpenGL. If this feature gets enabled, we enable the KHR_MAINTENANCE_1 extension to allow
|
||||
|
@ -35,68 +42,112 @@ struct FeaturesVk
|
|||
// -generating mipmaps
|
||||
// -Point sprites tests
|
||||
// -texStorage
|
||||
bool flipViewportY = false;
|
||||
angle::Feature flipViewportY = {"flip_viewport_y", angle::FeatureCategory::VulkanFeatures,
|
||||
"Flips the viewport to render upside-down", &members};
|
||||
|
||||
// Add an extra copy region when using vkCmdCopyBuffer as the Windows Intel driver seems
|
||||
// to have a bug where the last region is ignored.
|
||||
bool extraCopyBufferRegion = false;
|
||||
angle::Feature extraCopyBufferRegion = {
|
||||
"extra_copy_buffer_region", angle::FeatureCategory::VulkanWorkarounds,
|
||||
"Windows Intel driver seems to have a bug where the last copy region in "
|
||||
"vkCmdCopyBuffer is ignored",
|
||||
&members};
|
||||
|
||||
// This flag is added for the sole purpose of end2end tests, to test the correctness
|
||||
// of various algorithms when a fallback format is used, such as using a packed format to
|
||||
// emulate a depth- or stencil-only format.
|
||||
bool forceFallbackFormat = false;
|
||||
angle::Feature forceFallbackFormat = {
|
||||
"force_fallback_format", angle::FeatureCategory::VulkanWorkarounds,
|
||||
"Force a fallback format for angle_end2end_tests", &members};
|
||||
|
||||
// On some NVIDIA drivers the point size range reported from the API is inconsistent with the
|
||||
// actual behavior. Clamp the point size to the value from the API to fix this.
|
||||
// Tracked in http://anglebug.com/2970.
|
||||
bool clampPointSize = false;
|
||||
angle::Feature clampPointSize = {
|
||||
"clamp_point_size", angle::FeatureCategory::VulkanWorkarounds,
|
||||
"On some NVIDIA drivers the point size range reported from the API is "
|
||||
"inconsistent with the actual behavior",
|
||||
&members, "http://anglebug.com/2970"};
|
||||
|
||||
// On some android devices, the memory barrier between the compute shader that converts vertex
|
||||
// attributes and the vertex shader that reads from it is ineffective. Only known workaround is
|
||||
// to perform a flush after the conversion. http://anglebug.com/3016
|
||||
bool flushAfterVertexConversion = false;
|
||||
angle::Feature flushAfterVertexConversion = {
|
||||
"flush_after_vertex_conversion", angle::FeatureCategory::VulkanWorkarounds,
|
||||
"On some android devices, the memory barrier between the compute shader that converts "
|
||||
"vertex attributes and the vertex shader that reads from it is ineffective",
|
||||
&members, "http://anglebug.com/3016"};
|
||||
|
||||
// Whether the VkDevice supports the VK_KHR_incremental_present extension, on which the
|
||||
// EGL_KHR_swap_buffers_with_damage extension can be layered.
|
||||
bool supportsIncrementalPresent = false;
|
||||
angle::Feature supportsIncrementalPresent = {
|
||||
"supports_incremental_present", angle::FeatureCategory::VulkanFeatures,
|
||||
"VkDevice supports the VK_KHR_incremental_present extension", &members};
|
||||
|
||||
// Whether texture copies on cube map targets should be done on GPU. This is a workaround for
|
||||
// Intel drivers on windows that have an issue with creating single-layer views on cube map
|
||||
// textures.
|
||||
bool forceCpuPathForCubeMapCopy = false;
|
||||
angle::Feature forceCpuPathForCubeMapCopy = {
|
||||
"force_cpu_path_for_cube_map_copy", angle::FeatureCategory::VulkanWorkarounds,
|
||||
"Some Intel Windows drivers have an issue with creating single-layer "
|
||||
"views on cube map textures",
|
||||
&members};
|
||||
|
||||
// Whether the VkDevice supports the VK_ANDROID_external_memory_android_hardware_buffer
|
||||
// extension, on which the EGL_ANDROID_image_native_buffer extension can be layered.
|
||||
bool supportsAndroidHardwareBuffer = false;
|
||||
angle::Feature supportsAndroidHardwareBuffer = {
|
||||
"supports_android_hardware_buffer", angle::FeatureCategory::VulkanFeatures,
|
||||
"VkDevice supports the VK_ANDROID_external_memory_android_hardware_buffer extension",
|
||||
&members};
|
||||
|
||||
// Whether the VkDevice supports the VK_KHR_external_memory_fd
|
||||
// extension, on which the GL_EXT_memory_object_fd extension can be layered.
|
||||
bool supportsExternalMemoryFd = false;
|
||||
// Whether the VkDevice supports the VK_KHR_external_memory_fd extension, on which the
|
||||
// GL_EXT_memory_object_fd extension can be layered.
|
||||
angle::Feature supportsExternalMemoryFd = {
|
||||
"supports_external_memory_fd", angle::FeatureCategory::VulkanFeatures,
|
||||
"VkDevice supports the VK_KHR_external_memory_fd extension", &members};
|
||||
|
||||
// Whether the VkDevice supports the VK_KHR_external_semaphore_fd
|
||||
// extension, on which the GL_EXT_semaphore_fd extension can be layered.
|
||||
bool supportsExternalSemaphoreFd = false;
|
||||
// Whether the VkDevice supports the VK_KHR_external_semaphore_fd extension, on which the
|
||||
// GL_EXT_semaphore_fd extension can be layered.
|
||||
angle::Feature supportsExternalSemaphoreFd = {
|
||||
"supports_external_semaphore_fd", angle::FeatureCategory::VulkanFeatures,
|
||||
"VkDevice supports the VK_KHR_external_semaphore_fd extension", &members};
|
||||
|
||||
// VK_PRESENT_MODE_FIFO_KHR causes random timeouts on Linux Intel. http://anglebug.com/3153
|
||||
bool disableFifoPresentMode = false;
|
||||
angle::Feature disableFifoPresentMode = {
|
||||
"disable_fifo_present_mode", angle::FeatureCategory::VulkanWorkarounds,
|
||||
"On Linux Intel, VK_PRESENT_MODE_FIFO_KHR causes random timeouts", &members,
|
||||
"http://anglebug.com/3153"};
|
||||
|
||||
// On Qualcomm, a bug is preventing us from using loadOp=Clear with inline commands in the
|
||||
// render pass. http://anglebug.com/2361
|
||||
bool restartRenderPassAfterLoadOpClear = false;
|
||||
angle::Feature restartRenderPassAfterLoadOpClear = {
|
||||
"restart_render_pass_after_load_op_clear", angle::FeatureCategory::VulkanWorkarounds,
|
||||
"On Qualcomm, a bug is preventing us from using loadOp=Clear with inline "
|
||||
"commands in the render pass",
|
||||
&members, "http://anglebug.com/2361"};
|
||||
|
||||
// On Qualcomm, gaps in bound descriptor set indices causes the post-gap sets to misbehave.
|
||||
// For example, binding only descriptor set 3 results in zero being read from a uniform buffer
|
||||
// object within that set. This flag results in empty descriptor sets being bound for any
|
||||
// unused descriptor set to work around this issue. http://anglebug.com/2727
|
||||
bool bindEmptyForUnusedDescriptorSets = false;
|
||||
angle::Feature bindEmptyForUnusedDescriptorSets = {
|
||||
"bind_empty_for_unused_descriptor_sets", angle::FeatureCategory::VulkanWorkarounds,
|
||||
"On Qualcomm,gaps in bound descriptor set indices causes the post-gap sets to misbehave",
|
||||
&members, "http://anglebug.com/2727"};
|
||||
|
||||
// When the scissor is (0,0,0,0) on Windows Intel, the driver acts as if the scissor was
|
||||
// disabled. Work-around this by setting the scissor to just outside of the render area
|
||||
// (e.g. (renderArea.x, renderArea.y, 1, 1)). http://anglebug.com/3153
|
||||
bool forceNonZeroScissor = false;
|
||||
angle::Feature forceNonZeroScissor = {
|
||||
"force_non_zero_scissor", angle::FeatureCategory::VulkanWorkarounds,
|
||||
"On Windows Intel, when the scissor is (0,0,0,0), the driver acts as if the "
|
||||
"scissor was disabled",
|
||||
&members, "http://anglebug.com/3153"};
|
||||
};
|
||||
|
||||
inline FeaturesVk::FeaturesVk() = default;
|
||||
inline FeaturesVk::~FeaturesVk() = default;
|
||||
|
||||
} // namespace angle
|
||||
|
||||
#endif // ANGLE_PLATFORM_FEATURESVK_H_
|
||||
|
|
|
@ -9,33 +9,39 @@
|
|||
#ifndef ANGLE_PLATFORM_WORKAROUNDSD3D_H_
|
||||
#define ANGLE_PLATFORM_WORKAROUNDSD3D_H_
|
||||
|
||||
// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate
|
||||
// independent of ANGLE's renderer. Workarounds should also be accessible
|
||||
// outside of the Renderer.
|
||||
#include "platform/Feature.h"
|
||||
|
||||
namespace angle
|
||||
{
|
||||
|
||||
// Workarounds attached to each shader. Do not need to expose information about these workarounds so
|
||||
// a simple bool struct suffices.
|
||||
struct CompilerWorkaroundsD3D
|
||||
{
|
||||
bool skipOptimization = false;
|
||||
bool skipOptimization = false;
|
||||
|
||||
bool useMaxOptimization = false;
|
||||
|
||||
// IEEE strictness needs to be enabled for NANs to work.
|
||||
bool enableIEEEStrictness = false;
|
||||
};
|
||||
|
||||
struct WorkaroundsD3D
|
||||
struct WorkaroundsD3D : angle::FeatureSetBase
|
||||
{
|
||||
WorkaroundsD3D();
|
||||
WorkaroundsD3D(const WorkaroundsD3D &other);
|
||||
~WorkaroundsD3D();
|
||||
|
||||
// On some systems, having extra rendertargets than necessary slows down the shader.
|
||||
// We can fix this by optimizing those out of the shader. At the same time, we can
|
||||
// work around a bug on some nVidia drivers that they ignore "null" render targets
|
||||
// in D3D11, by compacting the active color attachments list to omit null entries.
|
||||
bool mrtPerfWorkaround = false;
|
||||
angle::Feature mrtPerfWorkaround = {
|
||||
"mrt_perf_workaround", angle::FeatureCategory::D3DWorkarounds,
|
||||
"Some NVIDIA D3D11 drivers have a bug where they ignore null render targets", &members};
|
||||
|
||||
bool setDataFasterThanImageUpload = false;
|
||||
angle::Feature setDataFasterThanImageUpload = {"set_data_faster_than_image_upload",
|
||||
angle::FeatureCategory::D3DWorkarounds,
|
||||
"Set data faster than image upload", &members};
|
||||
|
||||
// Some renderers can't disable mipmaps on a mipmapped texture (i.e. solely sample from level
|
||||
// zero, and ignore the other levels). D3D11 Feature Level 10+ does this by setting MaxLOD to
|
||||
|
@ -44,32 +50,51 @@ struct WorkaroundsD3D
|
|||
// application creates a mipmapped texture2D, but sets GL_TEXTURE_MIN_FILTER to GL_NEAREST
|
||||
// (i.e disables mipmaps). To work around this, D3D11 FL9_3 has to create two copies of the
|
||||
// texture. The textures' level zeros are identical, but only one texture has mips.
|
||||
bool zeroMaxLodWorkaround = false;
|
||||
angle::Feature zeroMaxLodWorkaround = {
|
||||
"zero_max_lod", angle::FeatureCategory::D3DWorkarounds,
|
||||
"D3D11 is missing an option to disable mipmaps on a mipmapped texture", &members};
|
||||
|
||||
// Some renderers do not support Geometry Shaders so the Geometry Shader-based PointSprite
|
||||
// emulation will not work. To work around this, D3D11 FL9_3 has to use a different pointsprite
|
||||
// emulation that is implemented using instanced quads.
|
||||
bool useInstancedPointSpriteEmulation = false;
|
||||
angle::Feature useInstancedPointSpriteEmulation = {
|
||||
"use_instanced_point_sprite_emulation", angle::FeatureCategory::D3DWorkarounds,
|
||||
"Some D3D11 renderers do not support geometry shaders for pointsprite emulation", &members};
|
||||
|
||||
// A bug fixed in NVIDIA driver version 347.88 < x <= 368.81 triggers a TDR when using
|
||||
// CopySubresourceRegion from a staging texture to a depth/stencil in D3D11. The workaround
|
||||
// is to use UpdateSubresource to trigger an extra copy. We disable this workaround on newer
|
||||
// NVIDIA driver versions because of a second driver bug present with the workaround enabled.
|
||||
// (See: http://anglebug.com/1452)
|
||||
bool depthStencilBlitExtraCopy = false;
|
||||
angle::Feature depthStencilBlitExtraCopy = {
|
||||
"depth_stencil_blit_extra_copy", angle::FeatureCategory::D3DWorkarounds,
|
||||
"Bug in NVIDIA D3D11 Driver version <=347.88 and >368.81 triggers a TDR when using "
|
||||
"CopySubresourceRegion from a staging texture to a depth/stencil",
|
||||
&members, "http://anglebug.com/1452"};
|
||||
|
||||
// The HLSL optimizer has a bug with optimizing "pow" in certain integer-valued expressions.
|
||||
// We can work around this by expanding the pow into a series of multiplies if we're running
|
||||
// under the affected compiler.
|
||||
bool expandIntegerPowExpressions = false;
|
||||
angle::Feature expandIntegerPowExpressions = {
|
||||
"expand_integer_pow_expressions", angle::FeatureCategory::D3DWorkarounds,
|
||||
"The HLSL optimizer has a bug with optimizing 'pow' in certain integer-valued expressions",
|
||||
&members};
|
||||
|
||||
// NVIDIA drivers sometimes write out-of-order results to StreamOut buffers when transform
|
||||
// feedback is used to repeatedly write to the same buffer positions.
|
||||
bool flushAfterEndingTransformFeedback = false;
|
||||
angle::Feature flushAfterEndingTransformFeedback = {
|
||||
"flush_after_ending_transform_feedback", angle::FeatureCategory::D3DWorkarounds,
|
||||
"NVIDIA drivers sometimes write out-of-order results to StreamOut buffers when transform "
|
||||
"feedback is used to repeatedly write to the same buffer positions",
|
||||
&members};
|
||||
|
||||
// Some drivers (NVIDIA) do not take into account the base level of the texture in the results
|
||||
// of the HLSL GetDimensions builtin.
|
||||
bool getDimensionsIgnoresBaseLevel = false;
|
||||
angle::Feature getDimensionsIgnoresBaseLevel = {
|
||||
"get_dimensions_ignores_base_level", angle::FeatureCategory::D3DWorkarounds,
|
||||
"Some NVIDIA drivers o not take into account the base level of the "
|
||||
"texture in the results of the HLSL GetDimensions builtin",
|
||||
&members};
|
||||
|
||||
// On some Intel drivers, HLSL's function texture.Load returns 0 when the parameter Location
|
||||
// is negative, even if the sum of Offset and Location is in range. This may cause errors when
|
||||
|
@ -77,44 +102,70 @@ struct WorkaroundsD3D
|
|||
// texelFetchOffset to use negative texture coordinates as its parameter P when the sum of P
|
||||
// and Offset is in range. To work around this, we translate texelFetchOffset into texelFetch
|
||||
// by adding Offset directly to Location before reading the texture.
|
||||
bool preAddTexelFetchOffsets = false;
|
||||
angle::Feature preAddTexelFetchOffsets = {
|
||||
"pre_add_texel_fetch_offsets", angle::FeatureCategory::D3DWorkarounds,
|
||||
"On some Intel drivers, HLSL's function texture.Load returns 0 when the parameter Location "
|
||||
"is negative, even if the sum of Offset and Location is in range",
|
||||
&members};
|
||||
|
||||
// On some AMD drivers, 1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly.
|
||||
// We can work around this bug by doing an internal blit to a temporary single-channel texture
|
||||
// before we sample.
|
||||
bool emulateTinyStencilTextures = false;
|
||||
angle::Feature emulateTinyStencilTextures = {
|
||||
"emulate_tiny_stencil_textures", angle::FeatureCategory::D3DWorkarounds,
|
||||
"On some AMD drivers, 1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly",
|
||||
&members};
|
||||
|
||||
// In Intel driver, the data with format DXGI_FORMAT_B5G6R5_UNORM will be parsed incorrectly.
|
||||
// This workaroud will disable B5G6R5 support when it's Intel driver. By default, it will use
|
||||
// R8G8B8A8 format. This bug is fixed in version 4539 on Intel drivers.
|
||||
bool disableB5G6R5Support = false;
|
||||
angle::Feature disableB5G6R5Support = {
|
||||
"disable_b5g6r5_support", angle::FeatureCategory::D3DWorkarounds,
|
||||
"In Intel driver, the data with format DXGI_FORMAT_B5G6R5_UNORM will be parsed incorrectly",
|
||||
&members};
|
||||
|
||||
// On some Intel drivers, evaluating unary minus operator on integer may get wrong answer in
|
||||
// vertex shaders. To work around this bug, we translate -(int) into ~(int)+1.
|
||||
// This driver bug is fixed in 20.19.15.4624.
|
||||
bool rewriteUnaryMinusOperator = false;
|
||||
angle::Feature rewriteUnaryMinusOperator = {
|
||||
"rewrite_unary_minus_operator", angle::FeatureCategory::D3DWorkarounds,
|
||||
"On some Intel drivers, evaluating unary minus operator on integer may "
|
||||
"get wrong answer in vertex shaders",
|
||||
&members};
|
||||
|
||||
// On some Intel drivers, using isnan() on highp float will get wrong answer. To work around
|
||||
// this bug, we use an expression to emulate function isnan().
|
||||
// Tracking bug: https://crbug.com/650547
|
||||
// This driver bug is fixed in 21.20.16.4542.
|
||||
bool emulateIsnanFloat = false;
|
||||
angle::Feature emulateIsnanFloat = {
|
||||
"emulate_isnan_float", angle::FeatureCategory::D3DWorkarounds,
|
||||
"On some Intel drivers, using isnan() on highp float will get wrong answer", &members,
|
||||
"https://crbug.com/650547"};
|
||||
|
||||
// On some Intel drivers, using clear() may not take effect. To work around this bug, we call
|
||||
// clear() twice on these platforms.
|
||||
// Tracking bug: https://crbug.com/655534
|
||||
bool callClearTwice = false;
|
||||
angle::Feature callClearTwice = {"call_clear_twice", angle::FeatureCategory::D3DWorkarounds,
|
||||
"On some Intel drivers, using clear() may not take effect",
|
||||
&members, "https://crbug.com/655534"};
|
||||
|
||||
// On some Intel drivers, copying from staging storage to constant buffer storage does not
|
||||
// seem to work. Work around this by keeping system memory storage as a canonical reference
|
||||
// for buffer data.
|
||||
// D3D11-only workaround. See http://crbug.com/593024.
|
||||
bool useSystemMemoryForConstantBuffers = false;
|
||||
angle::Feature useSystemMemoryForConstantBuffers = {
|
||||
"use_system_memory_for_constant_buffers", angle::FeatureCategory::D3DWorkarounds,
|
||||
"On some Intel drivers, copying from staging storage to constant buffer "
|
||||
"storage does not work",
|
||||
&members, "https://crbug.com/593024"};
|
||||
|
||||
// This workaround is for the ANGLE_multiview extension. If enabled the viewport or render
|
||||
// target slice will be selected in the geometry shader stage. The workaround flag is added to
|
||||
// make it possible to select the code path in end2end and performance tests.
|
||||
bool selectViewInGeometryShader = false;
|
||||
angle::Feature selectViewInGeometryShader = {
|
||||
"select_view_in_geometry_shader", angle::FeatureCategory::D3DWorkarounds,
|
||||
"The viewport or render target slice will be selected in the geometry shader stage",
|
||||
&members};
|
||||
|
||||
// When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel
|
||||
// drivers < 4815. The rendering samples always pass neglecting discard statements in pixel
|
||||
|
@ -125,23 +176,35 @@ struct WorkaroundsD3D
|
|||
// 2. If ID3D11BlendState.RenderTarget[].RenderTargetWriteMask is 0 and rendertarget is not set,
|
||||
// then rendering samples also pass neglecting discard statements in pixel shader.
|
||||
// So we add a dummy texture as render target in such case. See http://anglebug.com/2152
|
||||
bool addDummyTextureNoRenderTarget = false;
|
||||
angle::Feature addDummyTextureNoRenderTarget = {
|
||||
"add_dummy_texture_no_render_target", angle::FeatureCategory::D3DWorkarounds,
|
||||
"On D3D ntel drivers <4815 when rendering with no render target, two "
|
||||
"bugs lead to incorrect behavior",
|
||||
&members, "http://anglebug.com/2152"};
|
||||
|
||||
// Don't use D3D constant register zero when allocating space for uniforms in the vertex shader.
|
||||
// This is targeted to work around a bug in NVIDIA D3D driver version 388.59 where in very
|
||||
// specific cases the driver would not handle constant register zero correctly.
|
||||
bool skipVSConstantRegisterZero = false;
|
||||
angle::Feature skipVSConstantRegisterZero = {
|
||||
"skip_vs_constant_register_zero", angle::FeatureCategory::D3DWorkarounds,
|
||||
"On NVIDIA D3D driver v388.59 in specific cases the driver doesn't "
|
||||
"handle constant register zero correctly",
|
||||
&members};
|
||||
|
||||
// Forces the value returned from an atomic operations to be always be resolved. This is
|
||||
// targeted to workaround a bug in NVIDIA D3D driver where the return value from
|
||||
// RWByteAddressBuffer.InterlockedAdd does not get resolved when used in the .yzw components of
|
||||
// a RWByteAddressBuffer.Store operation. Only has an effect on HLSL translation.
|
||||
// http://anglebug.com/3246
|
||||
bool forceAtomicValueResolution = false;
|
||||
angle::Feature forceAtomicValueResolution = {
|
||||
"force_atomic_value_resolution", angle::FeatureCategory::D3DWorkarounds,
|
||||
"On an NVIDIA D3D driver, the return value from RWByteAddressBuffer.InterlockedAdd does "
|
||||
"not resolve when used in the .yzw components of a RWByteAddressBuffer.Store operation",
|
||||
&members, "http://anglebug.com/3246"};
|
||||
};
|
||||
|
||||
inline WorkaroundsD3D::WorkaroundsD3D() = default;
|
||||
inline WorkaroundsD3D::WorkaroundsD3D(const WorkaroundsD3D &other) = default;
|
||||
inline WorkaroundsD3D::~WorkaroundsD3D() = default;
|
||||
|
||||
} // namespace angle
|
||||
|
||||
|
|
|
@ -3454,9 +3454,10 @@ void Context::initWorkarounds()
|
|||
|
||||
// Lose the context upon out of memory error if the application is
|
||||
// expecting to watch for those events.
|
||||
mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
|
||||
mWorkarounds.loseContextOnOutOfMemory.enabled =
|
||||
(mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
|
||||
|
||||
if (mWorkarounds.syncFramebufferBindingsOnTexImage)
|
||||
if (mWorkarounds.syncFramebufferBindingsOnTexImage.enabled)
|
||||
{
|
||||
// Update the Framebuffer bindings on TexImage to work around an Intel bug.
|
||||
mTexImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
|
||||
|
@ -8272,7 +8273,8 @@ void ErrorSet::handleError(GLenum errorCode,
|
|||
const char *function,
|
||||
unsigned int line)
|
||||
{
|
||||
if (errorCode == GL_OUT_OF_MEMORY && mContext->getWorkarounds().loseContextOnOutOfMemory)
|
||||
if (errorCode == GL_OUT_OF_MEMORY &&
|
||||
mContext->getWorkarounds().loseContextOnOutOfMemory.enabled)
|
||||
{
|
||||
mContext->markContextLost(GraphicsResetStatus::UnknownContextReset);
|
||||
}
|
||||
|
|
|
@ -1480,9 +1480,9 @@ void Program::resolveLinkImpl(const Context *context)
|
|||
|
||||
// Save to the program cache.
|
||||
auto *cache = linkingState->context->getMemoryProgramCache();
|
||||
if (cache &&
|
||||
(mState.mLinkedTransformFeedbackVaryings.empty() ||
|
||||
!linkingState->context->getWorkarounds().disableProgramCachingForTransformFeedback))
|
||||
if (cache && (mState.mLinkedTransformFeedbackVaryings.empty() ||
|
||||
!linkingState->context->getWorkarounds()
|
||||
.disableProgramCachingForTransformFeedback.enabled))
|
||||
{
|
||||
cache->putProgram(linkingState->programHash, linkingState->context, this);
|
||||
}
|
||||
|
@ -4463,7 +4463,7 @@ void Program::serialize(const Context *context, angle::MemoryBuffer *binaryOut)
|
|||
|
||||
// Warn the app layer if saving a binary with unsupported transform feedback.
|
||||
if (!mState.getLinkedTransformFeedbackVaryings().empty() &&
|
||||
context->getWorkarounds().disableProgramCachingForTransformFeedback)
|
||||
context->getWorkarounds().disableProgramCachingForTransformFeedback.enabled)
|
||||
{
|
||||
WARN() << "Saving program binary with transform feedback, which is not supported on this "
|
||||
"driver.";
|
||||
|
@ -4682,7 +4682,7 @@ angle::Result Program::deserialize(const Context *context,
|
|||
|
||||
// Reject programs that use transform feedback varyings if the hardware cannot support them.
|
||||
if (transformFeedbackVaryingCount > 0 &&
|
||||
context->getWorkarounds().disableProgramCachingForTransformFeedback)
|
||||
context->getWorkarounds().disableProgramCachingForTransformFeedback.enabled)
|
||||
{
|
||||
infoLog << "Current driver does not support transform feedback in binary programs.";
|
||||
return angle::Result::Incomplete;
|
||||
|
|
|
@ -10,25 +10,45 @@
|
|||
#ifndef LIBANGLE_WORKAROUNDS_H_
|
||||
#define LIBANGLE_WORKAROUNDS_H_
|
||||
|
||||
#include "platform/Feature.h"
|
||||
|
||||
namespace gl
|
||||
{
|
||||
|
||||
struct Workarounds
|
||||
struct Workarounds : angle::FeatureSetBase
|
||||
{
|
||||
Workarounds();
|
||||
~Workarounds();
|
||||
|
||||
// Force the context to be lost (via KHR_robustness) if a GL_OUT_OF_MEMORY error occurs. The
|
||||
// driver may be in an inconsistent state if this happens, and some users of ANGLE rely on this
|
||||
// notification to prevent further execution.
|
||||
bool loseContextOnOutOfMemory = false;
|
||||
angle::Feature loseContextOnOutOfMemory = {
|
||||
"lose_context_on_out_of_memory", angle::FeatureCategory::FrontendWorkarounds,
|
||||
"Some users rely on a lost context notification if a GL_OUT_OF_MEMORY "
|
||||
"error occurs",
|
||||
&members};
|
||||
|
||||
// Program binaries don't contain transform feedback varyings on Qualcomm GPUs.
|
||||
// Work around this by disabling the program cache for programs with transform feedback.
|
||||
bool disableProgramCachingForTransformFeedback = false;
|
||||
angle::Feature disableProgramCachingForTransformFeedback = {
|
||||
"disable_program_caching_for_transform_feedback",
|
||||
angle::FeatureCategory::FrontendWorkarounds,
|
||||
"On Qualcomm GPUs, program binaries don't contain transform feedback varyings", &members};
|
||||
|
||||
// On Windows Intel OpenGL drivers TexImage sometimes seems to interact with the Framebuffer.
|
||||
// Flaky crashes can occur unless we sync the Framebuffer bindings. The workaround is to add
|
||||
// Framebuffer binding dirty bits to TexImage updates. See http://anglebug.com/2906
|
||||
bool syncFramebufferBindingsOnTexImage = false;
|
||||
angle::Feature syncFramebufferBindingsOnTexImage = {
|
||||
"sync_framebuffer_bindings_on_tex_image", angle::FeatureCategory::FrontendWorkarounds,
|
||||
"On Windows Intel OpenGL drivers TexImage sometimes seems to interact "
|
||||
"with the Framebuffer",
|
||||
&members};
|
||||
};
|
||||
|
||||
inline Workarounds::Workarounds() = default;
|
||||
inline Workarounds::~Workarounds() = default;
|
||||
|
||||
} // namespace gl
|
||||
|
||||
#endif // LIBANGLE_WORKAROUNDS_H_
|
||||
|
|
|
@ -160,7 +160,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(
|
|||
// must be used.
|
||||
bool usesPointSize = sourceShader.find("GL_USES_POINT_SIZE") != std::string::npos;
|
||||
bool useInstancedPointSpriteEmulation =
|
||||
usesPointSize && mRenderer->getWorkarounds().useInstancedPointSpriteEmulation;
|
||||
usesPointSize && mRenderer->getWorkarounds().useInstancedPointSpriteEmulation.enabled;
|
||||
|
||||
// Instanced PointSprite emulation requires additional entries in the
|
||||
// VS_INPUT structure to support the vertices that make up the quad vertices.
|
||||
|
@ -485,7 +485,7 @@ void DynamicHLSL::generateShaderLinkHLSL(const gl::Caps &caps,
|
|||
|
||||
bool useInstancedPointSpriteEmulation =
|
||||
programMetadata.usesPointSize() &&
|
||||
mRenderer->getWorkarounds().useInstancedPointSpriteEmulation;
|
||||
mRenderer->getWorkarounds().useInstancedPointSpriteEmulation.enabled;
|
||||
|
||||
// Validation done in the compiler
|
||||
ASSERT(!fragmentShader->usesFragColor() || !fragmentShader->usesFragData());
|
||||
|
|
|
@ -370,7 +370,7 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl:
|
|||
drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex));
|
||||
colorAttachmentsForRender.push_back(&colorAttachment);
|
||||
}
|
||||
else if (!workarounds.mrtPerfWorkaround)
|
||||
else if (!workarounds.mrtPerfWorkaround.enabled)
|
||||
{
|
||||
colorAttachmentsForRender.push_back(nullptr);
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl:
|
|||
// When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel
|
||||
// drivers < 4815. The rendering samples always pass neglecting discard statements in pixel
|
||||
// shader. We add a dummy texture as render target in such case.
|
||||
if (mRenderer->getWorkarounds().addDummyTextureNoRenderTarget &&
|
||||
if (mRenderer->getWorkarounds().addDummyTextureNoRenderTarget.enabled &&
|
||||
colorAttachmentsForRender.empty() && activeProgramOutputs.any())
|
||||
{
|
||||
static_assert(static_cast<size_t>(activeProgramOutputs.size()) <= 32,
|
||||
|
|
|
@ -386,7 +386,7 @@ ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer,
|
|||
: mRendererMajorShaderModel(renderer->getMajorShaderModel()),
|
||||
mShaderModelSuffix(renderer->getShaderModelSuffix()),
|
||||
mUsesInstancedPointSpriteEmulation(
|
||||
renderer->getWorkarounds().useInstancedPointSpriteEmulation),
|
||||
renderer->getWorkarounds().useInstancedPointSpriteEmulation.enabled),
|
||||
mUsesViewScale(renderer->presentPathFastEnabled()),
|
||||
mCanSelectViewInVertexShader(renderer->canSelectViewInVertexShader()),
|
||||
mAttachedShaders(attachedShaders)
|
||||
|
@ -693,7 +693,7 @@ bool ProgramD3D::usesGeometryShader(const gl::State &state, const gl::PrimitiveM
|
|||
|
||||
bool ProgramD3D::usesInstancedPointSpriteEmulation() const
|
||||
{
|
||||
return mRenderer->getWorkarounds().useInstancedPointSpriteEmulation;
|
||||
return mRenderer->getWorkarounds().useInstancedPointSpriteEmulation.enabled;
|
||||
}
|
||||
|
||||
GLint ProgramD3D::getSamplerMapping(gl::ShaderType type,
|
||||
|
@ -2862,7 +2862,6 @@ void ProgramD3D::reset()
|
|||
for (gl::ShaderType shaderType : gl::AllShaderTypes())
|
||||
{
|
||||
mShaderHLSL[shaderType].clear();
|
||||
mShaderWorkarounds[shaderType] = CompilerWorkaroundsD3D();
|
||||
}
|
||||
|
||||
mUsesFragDepth = false;
|
||||
|
|
|
@ -408,7 +408,7 @@ class RendererD3D : public BufferFactoryD3D
|
|||
private:
|
||||
void ensureCapsInitialized() const;
|
||||
|
||||
virtual angle::WorkaroundsD3D generateWorkarounds() const = 0;
|
||||
virtual void generateWorkarounds(angle::WorkaroundsD3D *workarounds) const = 0;
|
||||
|
||||
mutable bool mCapsInitialized;
|
||||
mutable gl::Caps mNativeCaps;
|
||||
|
|
|
@ -92,33 +92,34 @@ ShaderD3D::ShaderD3D(const gl::ShaderState &data,
|
|||
{
|
||||
uncompile();
|
||||
|
||||
if (workarounds.expandIntegerPowExpressions)
|
||||
if (workarounds.expandIntegerPowExpressions.enabled)
|
||||
{
|
||||
mAdditionalOptions |= SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS;
|
||||
}
|
||||
|
||||
if (workarounds.getDimensionsIgnoresBaseLevel)
|
||||
if (workarounds.getDimensionsIgnoresBaseLevel.enabled)
|
||||
{
|
||||
mAdditionalOptions |= SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL;
|
||||
}
|
||||
|
||||
if (workarounds.preAddTexelFetchOffsets)
|
||||
if (workarounds.preAddTexelFetchOffsets.enabled)
|
||||
{
|
||||
mAdditionalOptions |= SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH;
|
||||
}
|
||||
if (workarounds.rewriteUnaryMinusOperator)
|
||||
if (workarounds.rewriteUnaryMinusOperator.enabled)
|
||||
{
|
||||
mAdditionalOptions |= SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR;
|
||||
}
|
||||
if (workarounds.emulateIsnanFloat)
|
||||
if (workarounds.emulateIsnanFloat.enabled)
|
||||
{
|
||||
mAdditionalOptions |= SH_EMULATE_ISNAN_FLOAT_FUNCTION;
|
||||
}
|
||||
if (workarounds.skipVSConstantRegisterZero && mData.getShaderType() == gl::ShaderType::Vertex)
|
||||
if (workarounds.skipVSConstantRegisterZero.enabled &&
|
||||
mData.getShaderType() == gl::ShaderType::Vertex)
|
||||
{
|
||||
mAdditionalOptions |= SH_SKIP_D3D_CONSTANT_REGISTER_ZERO;
|
||||
}
|
||||
if (workarounds.forceAtomicValueResolution)
|
||||
if (workarounds.forceAtomicValueResolution.enabled)
|
||||
{
|
||||
mAdditionalOptions |= SH_FORCE_ATOMIC_VALUE_RESOLUTION;
|
||||
}
|
||||
|
|
|
@ -198,7 +198,7 @@ angle::Result TextureD3D::setStorageExternalMemory(const gl::Context *context,
|
|||
|
||||
bool TextureD3D::shouldUseSetData(const ImageD3D *image) const
|
||||
{
|
||||
if (!mRenderer->getWorkarounds().setDataFasterThanImageUpload)
|
||||
if (!mRenderer->getWorkarounds().setDataFasterThanImageUpload.enabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ angle::Result TextureD3D::generateMipmap(const gl::Context *context)
|
|||
const GLuint maxLevel = mState.getMipmapMaxLevel();
|
||||
ASSERT(maxLevel > baseLevel); // Should be checked before calling this.
|
||||
|
||||
if (mTexStorage && mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (mTexStorage && mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
// Switch to using the mipmapped texture.
|
||||
TextureStorage *textureStorage = nullptr;
|
||||
|
@ -474,7 +474,7 @@ angle::Result TextureD3D::generateMipmapUsingImages(const gl::Context *context,
|
|||
// When making mipmaps with the setData workaround enabled, the texture storage has
|
||||
// the image data already. For non-render-target storage, we have to pull it out into
|
||||
// an image layer.
|
||||
if (mRenderer->getWorkarounds().setDataFasterThanImageUpload && mTexStorage)
|
||||
if (mRenderer->getWorkarounds().setDataFasterThanImageUpload.enabled && mTexStorage)
|
||||
{
|
||||
if (!mTexStorage->isRenderTarget())
|
||||
{
|
||||
|
@ -501,7 +501,7 @@ angle::Result TextureD3D::generateMipmapUsingImages(const gl::Context *context,
|
|||
// Blit9::boxFilter). Feature Level 9_3 could do something similar, or it could continue to use
|
||||
// CPU-side mipmap generation, or something else.
|
||||
bool renderableStorage = (mTexStorage && mTexStorage->isRenderTarget() &&
|
||||
!(mRenderer->getWorkarounds().zeroMaxLodWorkaround));
|
||||
!(mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled));
|
||||
|
||||
for (GLint layer = 0; layer < layerCount; ++layer)
|
||||
{
|
||||
|
@ -732,7 +732,8 @@ angle::Result TextureD3D::initializeContents(const gl::Context *context,
|
|||
// Fast path: can use a render target clear.
|
||||
// We don't use the fast path with the zero max lod workaround because it would introduce a race
|
||||
// between the rendertarget and the staging images.
|
||||
if (canCreateRenderTargetForImage(index) && !mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (canCreateRenderTargetForImage(index) &&
|
||||
!mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ANGLE_TRY(ensureRenderTarget(context));
|
||||
ASSERT(mTexStorage);
|
||||
|
@ -1006,7 +1007,8 @@ angle::Result TextureD3D_2D::copyImage(const gl::Context *context,
|
|||
|
||||
// If the zero max LOD workaround is active, then we can't sample from individual layers of the
|
||||
// framebuffer in shaders, so we should use the non-rendering copy path.
|
||||
if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (!canCreateRenderTargetForImage(index) ||
|
||||
mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ANGLE_TRY(mImageArray[index.getLevelIndex()]->copyFromFramebuffer(context, destOffset,
|
||||
clippedArea, source));
|
||||
|
@ -1051,7 +1053,8 @@ angle::Result TextureD3D_2D::copySubImage(const gl::Context *context,
|
|||
|
||||
// If the zero max LOD workaround is active, then we can't sample from individual layers of the
|
||||
// framebuffer in shaders, so we should use the non-rendering copy path.
|
||||
if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (!canCreateRenderTargetForImage(index) ||
|
||||
mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ANGLE_TRY(mImageArray[index.getLevelIndex()]->copyFromFramebuffer(context, clippedOffset,
|
||||
clippedArea, source));
|
||||
|
@ -1431,7 +1434,7 @@ angle::Result TextureD3D_2D::createCompleteStorage(bool renderTarget,
|
|||
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
|
||||
|
||||
bool hintLevelZeroOnly = false;
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
// If any of the CPU images (levels >= 1) are dirty, then the textureStorage2D should use
|
||||
// the mipped texture to begin with. Otherwise, it should use the level-zero-only texture.
|
||||
|
@ -1754,7 +1757,8 @@ angle::Result TextureD3D_Cube::copyImage(const gl::Context *context,
|
|||
|
||||
// If the zero max LOD workaround is active, then we can't sample from individual layers of the
|
||||
// framebuffer in shaders, so we should use the non-rendering copy path.
|
||||
if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (!canCreateRenderTargetForImage(index) ||
|
||||
mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ANGLE_TRY(mImageArray[faceIndex][index.getLevelIndex()]->copyFromFramebuffer(
|
||||
context, destOffset, clippedArea, source));
|
||||
|
@ -1797,7 +1801,8 @@ angle::Result TextureD3D_Cube::copySubImage(const gl::Context *context,
|
|||
|
||||
// If the zero max LOD workaround is active, then we can't sample from individual layers of the
|
||||
// framebuffer in shaders, so we should use the non-rendering copy path.
|
||||
if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (!canCreateRenderTargetForImage(index) ||
|
||||
mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ANGLE_TRY(mImageArray[faceIndex][index.getLevelIndex()]->copyFromFramebuffer(
|
||||
context, clippedOffset, clippedArea, source));
|
||||
|
@ -2085,7 +2090,7 @@ angle::Result TextureD3D_Cube::createCompleteStorage(bool renderTarget,
|
|||
GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1));
|
||||
|
||||
bool hintLevelZeroOnly = false;
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
// If any of the CPU images (levels >= 1) are dirty, then the textureStorage should use the
|
||||
// mipped texture to begin with. Otherwise, it should use the level-zero-only texture.
|
||||
|
|
|
@ -1310,7 +1310,7 @@ angle::Result Blit11::copyAndConvert(const gl::Context *context,
|
|||
copySize, srcPixelStride, destPixelStride, convertFunction));
|
||||
|
||||
// Work around timeouts/TDRs in older NVIDIA drivers.
|
||||
if (mRenderer->getWorkarounds().depthStencilBlitExtraCopy)
|
||||
if (mRenderer->getWorkarounds().depthStencilBlitExtraCopy.enabled)
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
ANGLE_TRY(
|
||||
|
|
|
@ -391,7 +391,7 @@ angle::Result Buffer11::setSubData(const gl::Context *context,
|
|||
// TODO(jmadill): Use Context caps.
|
||||
if (offset == 0 && size >= mSize &&
|
||||
size <= static_cast<UINT>(mRenderer->getNativeCaps().maxUniformBlockSize) &&
|
||||
!mRenderer->getWorkarounds().useSystemMemoryForConstantBuffers)
|
||||
!mRenderer->getWorkarounds().useSystemMemoryForConstantBuffers.enabled)
|
||||
{
|
||||
ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_UNIFORM, &writeBuffer));
|
||||
}
|
||||
|
@ -605,7 +605,7 @@ angle::Result Buffer11::checkForDeallocation(const gl::Context *context, BufferU
|
|||
bool Buffer11::canDeallocateSystemMemory() const
|
||||
{
|
||||
// Must keep system memory on Intel.
|
||||
if (mRenderer->getWorkarounds().useSystemMemoryForConstantBuffers)
|
||||
if (mRenderer->getWorkarounds().useSystemMemoryForConstantBuffers.enabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -551,7 +551,7 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context,
|
|||
// We shouldn't reach here if deviceContext1 is unavailable.
|
||||
ASSERT(deviceContext1);
|
||||
deviceContext1->ClearView(framebufferRTV.get(), clearValues, &scissorRect, 1);
|
||||
if (mRenderer->getWorkarounds().callClearTwice)
|
||||
if (mRenderer->getWorkarounds().callClearTwice.enabled)
|
||||
{
|
||||
deviceContext1->ClearView(framebufferRTV.get(), clearValues, &scissorRect, 1);
|
||||
}
|
||||
|
@ -559,7 +559,7 @@ angle::Result Clear11::clearFramebuffer(const gl::Context *context,
|
|||
else
|
||||
{
|
||||
deviceContext->ClearRenderTargetView(framebufferRTV.get(), clearValues);
|
||||
if (mRenderer->getWorkarounds().callClearTwice)
|
||||
if (mRenderer->getWorkarounds().callClearTwice.enabled)
|
||||
{
|
||||
deviceContext->ClearRenderTargetView(framebufferRTV.get(), clearValues);
|
||||
}
|
||||
|
|
|
@ -918,7 +918,7 @@ void Renderer11::populateRenderer11DeviceCaps()
|
|||
mRenderer11DeviceCaps.supportsMultisampledDepthStencilSRVs =
|
||||
mRenderer11DeviceCaps.featureLevel > D3D_FEATURE_LEVEL_10_0;
|
||||
|
||||
if (getWorkarounds().disableB5G6R5Support)
|
||||
if (getWorkarounds().disableB5G6R5Support.enabled)
|
||||
{
|
||||
mRenderer11DeviceCaps.B5G6R5support = 0;
|
||||
mRenderer11DeviceCaps.B5G6R5maxSamples = 0;
|
||||
|
@ -1496,7 +1496,7 @@ angle::Result Renderer11::drawArrays(const gl::Context *context,
|
|||
return drawTriangleFan(context, clampedVertexCount, gl::DrawElementsType::InvalidEnum,
|
||||
nullptr, 0, adjustedInstanceCount);
|
||||
case gl::PrimitiveMode::Points:
|
||||
if (getWorkarounds().useInstancedPointSpriteEmulation)
|
||||
if (getWorkarounds().useInstancedPointSpriteEmulation.enabled)
|
||||
{
|
||||
// This code should not be reachable by multi-view programs.
|
||||
ASSERT(programD3D->getState().usesMultiview() == false);
|
||||
|
@ -2176,7 +2176,7 @@ const angle::WorkaroundsD3D &RendererD3D::getWorkarounds() const
|
|||
{
|
||||
if (!mWorkaroundsInitialized)
|
||||
{
|
||||
mWorkarounds = generateWorkarounds();
|
||||
generateWorkarounds(&mWorkarounds);
|
||||
mWorkaroundsInitialized = true;
|
||||
}
|
||||
|
||||
|
@ -3692,9 +3692,9 @@ void Renderer11::generateCaps(gl::Caps *outCaps,
|
|||
outCaps, outTextureCaps, outExtensions, outLimitations);
|
||||
}
|
||||
|
||||
angle::WorkaroundsD3D Renderer11::generateWorkarounds() const
|
||||
void Renderer11::generateWorkarounds(angle::WorkaroundsD3D *workarounds) const
|
||||
{
|
||||
return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps, mAdapterDescription);
|
||||
d3d11::GenerateWorkarounds(mRenderer11DeviceCaps, mAdapterDescription, workarounds);
|
||||
}
|
||||
|
||||
DeviceImpl *Renderer11::createEGLDevice()
|
||||
|
@ -3925,7 +3925,7 @@ angle::Result Renderer11::clearRenderTarget(const gl::Context *context,
|
|||
|
||||
bool Renderer11::canSelectViewInVertexShader() const
|
||||
{
|
||||
return !getWorkarounds().selectViewInGeometryShader &&
|
||||
return !getWorkarounds().selectViewInGeometryShader.enabled &&
|
||||
getRenderer11DeviceCaps().supportsVpRtIndexWriteFromVertexShader;
|
||||
}
|
||||
|
||||
|
|
|
@ -505,7 +505,7 @@ class Renderer11 : public RendererD3D
|
|||
gl::Extensions *outExtensions,
|
||||
gl::Limitations *outLimitations) const override;
|
||||
|
||||
angle::WorkaroundsD3D generateWorkarounds() const override;
|
||||
void generateWorkarounds(angle::WorkaroundsD3D *workarounds) const override;
|
||||
|
||||
angle::Result drawLineLoop(const gl::Context *context,
|
||||
GLuint count,
|
||||
|
|
|
@ -1912,7 +1912,7 @@ angle::Result StateManager11::syncFramebuffer(const gl::Context *context)
|
|||
const auto &colorRTs = mFramebuffer11->getCachedColorRenderTargets();
|
||||
|
||||
size_t appliedRTIndex = 0;
|
||||
bool skipInactiveRTs = mRenderer->getWorkarounds().mrtPerfWorkaround;
|
||||
bool skipInactiveRTs = mRenderer->getWorkarounds().mrtPerfWorkaround.enabled;
|
||||
const auto &drawStates = mFramebuffer11->getState().getDrawBufferStates();
|
||||
gl::DrawBufferMask activeProgramOutputs = mProgramD3D->getState().getActiveOutputVariables();
|
||||
UINT maxExistingRT = 0;
|
||||
|
@ -3808,7 +3808,8 @@ void StateManager11::syncPrimitiveTopology(const gl::State &glState,
|
|||
|
||||
// If instanced pointsprites are enabled and the shader uses gl_PointSize, the topology
|
||||
// must be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST.
|
||||
if (usesPointSize && mRenderer->getWorkarounds().useInstancedPointSpriteEmulation)
|
||||
if (usesPointSize &&
|
||||
mRenderer->getWorkarounds().useInstancedPointSpriteEmulation.enabled)
|
||||
{
|
||||
primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
|
||||
}
|
||||
|
|
|
@ -228,7 +228,7 @@ angle::Result TextureStorage11::getSRVForSampler(const gl::Context *context,
|
|||
ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
|
||||
}
|
||||
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
// We must ensure that the level zero texture is in sync with mipped texture.
|
||||
ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1));
|
||||
|
@ -241,7 +241,7 @@ angle::Result TextureStorage11::getSRVForSampler(const gl::Context *context,
|
|||
|
||||
// We drop the stencil when sampling from the SRV if three conditions hold:
|
||||
// 1. the drop stencil workaround is enabled.
|
||||
const bool workaround = mRenderer->getWorkarounds().emulateTinyStencilTextures;
|
||||
const bool workaround = mRenderer->getWorkarounds().emulateTinyStencilTextures.enabled;
|
||||
// 2. this is a stencil texture.
|
||||
const bool hasStencil = (mFormatInfo.format().stencilBits > 0);
|
||||
// 3. the texture has a 1x1 or 2x2 mip.
|
||||
|
@ -364,7 +364,7 @@ angle::Result TextureStorage11::getSRVLevels(const gl::Context *context,
|
|||
ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
|
||||
}
|
||||
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
// We must ensure that the level zero texture is in sync with mipped texture.
|
||||
ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1));
|
||||
|
@ -525,7 +525,7 @@ angle::Result TextureStorage11::updateSubresourceLevel(const gl::Context *contex
|
|||
|
||||
// If the zero-LOD workaround is active and we want to update a level greater than zero, then we
|
||||
// should update the mipmapped texture, even if mapmaps are currently disabled.
|
||||
if (level > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (level > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ANGLE_TRY(getMippedResource(context, &dstTexture));
|
||||
}
|
||||
|
@ -579,7 +579,7 @@ angle::Result TextureStorage11::copySubresourceLevel(const gl::Context *context,
|
|||
|
||||
// If the zero-LOD workaround is active and we want to update a level greater than zero, then we
|
||||
// should update the mipmapped texture, even if mapmaps are currently disabled.
|
||||
if (index.getLevelIndex() > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (index.getLevelIndex() > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ANGLE_TRY(getMippedResource(context, &srcTexture));
|
||||
}
|
||||
|
@ -908,7 +908,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer,
|
|||
mTextureDepth = 1;
|
||||
|
||||
// The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
|
||||
ASSERT(!mUseLevelZeroTexture || mRenderer->getWorkarounds().zeroMaxLodWorkaround);
|
||||
ASSERT(!mUseLevelZeroTexture || mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled);
|
||||
}
|
||||
|
||||
angle::Result TextureStorage11_2D::onDestroy(const gl::Context *context)
|
||||
|
@ -945,7 +945,7 @@ angle::Result TextureStorage11_2D::copyToStorage(const gl::Context *context,
|
|||
TextureStorage11_2D *dest11 = GetAs<TextureStorage11_2D>(destStorage);
|
||||
ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
|
||||
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
// If either mTexture or mLevelZeroTexture exist, then we need to copy them into the
|
||||
// corresponding textures in destStorage.
|
||||
|
@ -1101,7 +1101,7 @@ angle::Result TextureStorage11_2D::getMippedResource(const gl::Context *context,
|
|||
const TextureHelper11 **outResource)
|
||||
{
|
||||
// This shouldn't be called unless the zero max LOD workaround is active.
|
||||
ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround);
|
||||
ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled);
|
||||
|
||||
ANGLE_TRY(ensureTextureExists(context, mMipLevels));
|
||||
|
||||
|
@ -1112,7 +1112,7 @@ angle::Result TextureStorage11_2D::getMippedResource(const gl::Context *context,
|
|||
angle::Result TextureStorage11_2D::ensureTextureExists(const gl::Context *context, int mipLevels)
|
||||
{
|
||||
// If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
|
||||
bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround
|
||||
bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled
|
||||
? (mipLevels == 1) && (mMipLevels > 1)
|
||||
: false;
|
||||
TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture;
|
||||
|
@ -1177,7 +1177,7 @@ angle::Result TextureStorage11_2D::getRenderTarget(const gl::Context *context,
|
|||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ASSERT(level == 0);
|
||||
ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true));
|
||||
|
@ -1274,7 +1274,7 @@ angle::Result TextureStorage11_2D::createSRVForSampler(const gl::Context *contex
|
|||
|
||||
const TextureHelper11 *srvTexture = &texture;
|
||||
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ASSERT(mTopLevel == 0);
|
||||
ASSERT(baseLevel == 0);
|
||||
|
@ -1899,7 +1899,7 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer,
|
|||
mTextureDepth = 1;
|
||||
|
||||
// The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
|
||||
ASSERT(!mUseLevelZeroTexture || mRenderer->getWorkarounds().zeroMaxLodWorkaround);
|
||||
ASSERT(!mUseLevelZeroTexture || mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled);
|
||||
}
|
||||
|
||||
angle::Result TextureStorage11_Cube::onDestroy(const gl::Context *context)
|
||||
|
@ -1929,7 +1929,7 @@ angle::Result TextureStorage11_Cube::getSubresourceIndex(const gl::Context *cont
|
|||
UINT *outSubresourceIndex) const
|
||||
{
|
||||
UINT arraySlice = index.cubeMapFaceIndex();
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround && mUseLevelZeroTexture &&
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled && mUseLevelZeroTexture &&
|
||||
index.getLevelIndex() == 0)
|
||||
{
|
||||
UINT subresource = D3D11CalcSubresource(0, arraySlice, 1);
|
||||
|
@ -1953,7 +1953,7 @@ angle::Result TextureStorage11_Cube::copyToStorage(const gl::Context *context,
|
|||
|
||||
TextureStorage11_Cube *dest11 = GetAs<TextureStorage11_Cube>(destStorage);
|
||||
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
|
||||
|
||||
|
@ -2139,7 +2139,7 @@ angle::Result TextureStorage11_Cube::getMippedResource(const gl::Context *contex
|
|||
const TextureHelper11 **outResource)
|
||||
{
|
||||
// This shouldn't be called unless the zero max LOD workaround is active.
|
||||
ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround);
|
||||
ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled);
|
||||
|
||||
ANGLE_TRY(ensureTextureExists(context, mMipLevels));
|
||||
*outResource = &mTexture;
|
||||
|
@ -2149,7 +2149,7 @@ angle::Result TextureStorage11_Cube::getMippedResource(const gl::Context *contex
|
|||
angle::Result TextureStorage11_Cube::ensureTextureExists(const gl::Context *context, int mipLevels)
|
||||
{
|
||||
// If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
|
||||
bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround
|
||||
bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled
|
||||
? (mipLevels == 1) && (mMipLevels > 1)
|
||||
: false;
|
||||
TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture;
|
||||
|
@ -2223,7 +2223,7 @@ angle::Result TextureStorage11_Cube::getRenderTarget(const gl::Context *context,
|
|||
|
||||
if (!mRenderTarget[faceIndex][level])
|
||||
{
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ASSERT(index.getLevelIndex() == 0);
|
||||
ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true));
|
||||
|
@ -2351,7 +2351,7 @@ angle::Result TextureStorage11_Cube::createSRVForSampler(const gl::Context *cont
|
|||
|
||||
const TextureHelper11 *srvTexture = &texture;
|
||||
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround)
|
||||
if (mRenderer->getWorkarounds().zeroMaxLodWorkaround.enabled)
|
||||
{
|
||||
ASSERT(mTopLevel == 0);
|
||||
ASSERT(baseLevel == 0);
|
||||
|
|
|
@ -51,7 +51,7 @@ angle::Result TransformFeedback11::begin(const gl::Context *context,
|
|||
angle::Result TransformFeedback11::end(const gl::Context *context)
|
||||
{
|
||||
mRenderer->getStateManager()->invalidateTransformFeedback();
|
||||
if (mRenderer->getWorkarounds().flushAfterEndingTransformFeedback)
|
||||
if (mRenderer->getWorkarounds().flushAfterEndingTransformFeedback.enabled)
|
||||
{
|
||||
mRenderer->getDeviceContext()->Flush();
|
||||
}
|
||||
|
|
|
@ -1467,7 +1467,7 @@ void GenerateCaps(ID3D11Device *device,
|
|||
caps->maxVertexAttributes = static_cast<GLuint>(GetMaximumVertexInputSlots(featureLevel));
|
||||
caps->maxVertexUniformVectors =
|
||||
static_cast<GLuint>(GetMaximumVertexUniformVectors(featureLevel));
|
||||
if (workarounds.skipVSConstantRegisterZero)
|
||||
if (workarounds.skipVSConstantRegisterZero.enabled)
|
||||
{
|
||||
caps->maxVertexUniformVectors -= 1;
|
||||
}
|
||||
|
@ -2364,16 +2364,16 @@ angle::Result LazyBlendState::resolve(d3d::Context *context, Renderer11 *rendere
|
|||
return resolveImpl(context, renderer, mDesc, nullptr, mDebugName);
|
||||
}
|
||||
|
||||
angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
|
||||
const DXGI_ADAPTER_DESC &adapterDesc)
|
||||
void GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
|
||||
const DXGI_ADAPTER_DESC &adapterDesc,
|
||||
angle::WorkaroundsD3D *workarounds)
|
||||
{
|
||||
bool is9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
|
||||
|
||||
angle::WorkaroundsD3D workarounds;
|
||||
workarounds.mrtPerfWorkaround = true;
|
||||
workarounds.setDataFasterThanImageUpload = true;
|
||||
workarounds.zeroMaxLodWorkaround = is9_3;
|
||||
workarounds.useInstancedPointSpriteEmulation = is9_3;
|
||||
workarounds->mrtPerfWorkaround.enabled = true;
|
||||
workarounds->setDataFasterThanImageUpload.enabled = true;
|
||||
workarounds->zeroMaxLodWorkaround.enabled = is9_3;
|
||||
workarounds->useInstancedPointSpriteEmulation.enabled = is9_3;
|
||||
|
||||
// TODO(jmadill): Narrow problematic driver range.
|
||||
if (IsNvidia(adapterDesc.VendorId))
|
||||
|
@ -2384,43 +2384,43 @@ angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps
|
|||
WORD part2 = LOWORD(deviceCaps.driverVersion.value().LowPart);
|
||||
|
||||
// Disable the workaround to fix a second driver bug on newer NVIDIA.
|
||||
workarounds.depthStencilBlitExtraCopy = (part1 <= 13u && part2 < 6881);
|
||||
workarounds->depthStencilBlitExtraCopy.enabled = (part1 <= 13u && part2 < 6881);
|
||||
}
|
||||
else
|
||||
{
|
||||
workarounds.depthStencilBlitExtraCopy = true;
|
||||
workarounds->depthStencilBlitExtraCopy.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jmadill): Disable workaround when we have a fixed compiler DLL.
|
||||
workarounds.expandIntegerPowExpressions = true;
|
||||
workarounds->expandIntegerPowExpressions.enabled = true;
|
||||
|
||||
workarounds.flushAfterEndingTransformFeedback = IsNvidia(adapterDesc.VendorId);
|
||||
workarounds.getDimensionsIgnoresBaseLevel = IsNvidia(adapterDesc.VendorId);
|
||||
workarounds.skipVSConstantRegisterZero = IsNvidia(adapterDesc.VendorId);
|
||||
workarounds.forceAtomicValueResolution = IsNvidia(adapterDesc.VendorId);
|
||||
workarounds->flushAfterEndingTransformFeedback.enabled = IsNvidia(adapterDesc.VendorId);
|
||||
workarounds->getDimensionsIgnoresBaseLevel.enabled = IsNvidia(adapterDesc.VendorId);
|
||||
workarounds->skipVSConstantRegisterZero.enabled = IsNvidia(adapterDesc.VendorId);
|
||||
workarounds->forceAtomicValueResolution.enabled = IsNvidia(adapterDesc.VendorId);
|
||||
|
||||
if (IsIntel(adapterDesc.VendorId))
|
||||
{
|
||||
IntelDriverVersion capsVersion = d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion);
|
||||
|
||||
workarounds.preAddTexelFetchOffsets = true;
|
||||
workarounds.useSystemMemoryForConstantBuffers = true;
|
||||
workarounds.disableB5G6R5Support = capsVersion < IntelDriverVersion(4539);
|
||||
workarounds.addDummyTextureNoRenderTarget = capsVersion < IntelDriverVersion(4815);
|
||||
workarounds->preAddTexelFetchOffsets.enabled = true;
|
||||
workarounds->useSystemMemoryForConstantBuffers.enabled = true;
|
||||
workarounds->disableB5G6R5Support.enabled = capsVersion < IntelDriverVersion(4539);
|
||||
workarounds->addDummyTextureNoRenderTarget.enabled = capsVersion < IntelDriverVersion(4815);
|
||||
if (IsSkylake(adapterDesc.DeviceId))
|
||||
{
|
||||
workarounds.callClearTwice = capsVersion < IntelDriverVersion(4771);
|
||||
workarounds.emulateIsnanFloat = capsVersion < IntelDriverVersion(4542);
|
||||
workarounds->callClearTwice.enabled = capsVersion < IntelDriverVersion(4771);
|
||||
workarounds->emulateIsnanFloat.enabled = capsVersion < IntelDriverVersion(4542);
|
||||
}
|
||||
else if (IsBroadwell(adapterDesc.DeviceId) || IsHaswell(adapterDesc.DeviceId))
|
||||
{
|
||||
workarounds.rewriteUnaryMinusOperator = capsVersion < IntelDriverVersion(4624);
|
||||
workarounds->rewriteUnaryMinusOperator.enabled = capsVersion < IntelDriverVersion(4624);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jmadill): Disable when we have a fixed driver version.
|
||||
workarounds.emulateTinyStencilTextures = IsAMD(adapterDesc.VendorId);
|
||||
workarounds->emulateTinyStencilTextures.enabled = IsAMD(adapterDesc.VendorId);
|
||||
|
||||
// The tiny stencil texture workaround involves using CopySubresource or UpdateSubresource on a
|
||||
// depth stencil texture. This is not allowed until feature level 10.1 but since it is not
|
||||
|
@ -2428,19 +2428,17 @@ angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps
|
|||
// (anglebug.com/1572).
|
||||
if (deviceCaps.featureLevel < D3D_FEATURE_LEVEL_10_1)
|
||||
{
|
||||
workarounds.emulateTinyStencilTextures = false;
|
||||
workarounds->emulateTinyStencilTextures.enabled = false;
|
||||
}
|
||||
|
||||
// If the VPAndRTArrayIndexFromAnyShaderFeedingRasterizer feature is not available, we have to
|
||||
// select the viewport / RT array index in the geometry shader.
|
||||
workarounds.selectViewInGeometryShader =
|
||||
workarounds->selectViewInGeometryShader.enabled =
|
||||
(deviceCaps.supportsVpRtIndexWriteFromVertexShader == false);
|
||||
|
||||
// Call platform hooks for testing overrides.
|
||||
auto *platform = ANGLEPlatformCurrent();
|
||||
platform->overrideWorkaroundsD3D(platform, &workarounds);
|
||||
|
||||
return workarounds;
|
||||
platform->overrideWorkaroundsD3D(platform, workarounds);
|
||||
}
|
||||
|
||||
void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t byteWidth)
|
||||
|
|
|
@ -305,8 +305,9 @@ void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, c
|
|||
}
|
||||
}
|
||||
|
||||
angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
|
||||
const DXGI_ADAPTER_DESC &adapterDesc);
|
||||
void GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
|
||||
const DXGI_ADAPTER_DESC &adapterDesc,
|
||||
angle::WorkaroundsD3D *workarounds);
|
||||
|
||||
enum ReservedConstantBufferSlot
|
||||
{
|
||||
|
|
|
@ -2976,9 +2976,9 @@ void Renderer9::generateCaps(gl::Caps *outCaps,
|
|||
outExtensions, outLimitations);
|
||||
}
|
||||
|
||||
angle::WorkaroundsD3D Renderer9::generateWorkarounds() const
|
||||
void Renderer9::generateWorkarounds(angle::WorkaroundsD3D *workarounds) const
|
||||
{
|
||||
return d3d9::GenerateWorkarounds();
|
||||
d3d9::GenerateWorkarounds(workarounds);
|
||||
}
|
||||
|
||||
DeviceImpl *Renderer9::createEGLDevice()
|
||||
|
|
|
@ -438,7 +438,7 @@ class Renderer9 : public RendererD3D
|
|||
gl::Extensions *outExtensions,
|
||||
gl::Limitations *outLimitations) const override;
|
||||
|
||||
angle::WorkaroundsD3D generateWorkarounds() const override;
|
||||
void generateWorkarounds(angle::WorkaroundsD3D *workarounds) const override;
|
||||
|
||||
angle::Result setBlendDepthRasterStates(const gl::Context *context, gl::PrimitiveMode drawMode);
|
||||
|
||||
|
|
|
@ -791,21 +791,18 @@ void MakeValidSize(bool isImage,
|
|||
*levelOffset = upsampleCount;
|
||||
}
|
||||
|
||||
angle::WorkaroundsD3D GenerateWorkarounds()
|
||||
void GenerateWorkarounds(angle::WorkaroundsD3D *workarounds)
|
||||
{
|
||||
angle::WorkaroundsD3D workarounds;
|
||||
workarounds.mrtPerfWorkaround = true;
|
||||
workarounds.setDataFasterThanImageUpload = false;
|
||||
workarounds.useInstancedPointSpriteEmulation = false;
|
||||
workarounds->mrtPerfWorkaround.enabled = true;
|
||||
workarounds->setDataFasterThanImageUpload.enabled = false;
|
||||
workarounds->useInstancedPointSpriteEmulation.enabled = false;
|
||||
|
||||
// TODO(jmadill): Disable workaround when we have a fixed compiler DLL.
|
||||
workarounds.expandIntegerPowExpressions = true;
|
||||
workarounds->expandIntegerPowExpressions.enabled = true;
|
||||
|
||||
// Call platform hooks for testing overrides.
|
||||
auto *platform = ANGLEPlatformCurrent();
|
||||
platform->overrideWorkaroundsD3D(platform, &workarounds);
|
||||
|
||||
return workarounds;
|
||||
platform->overrideWorkaroundsD3D(platform, workarounds);
|
||||
}
|
||||
|
||||
} // namespace d3d9
|
||||
|
|
|
@ -97,7 +97,7 @@ inline bool isDeviceLostError(HRESULT errorCode)
|
|||
}
|
||||
}
|
||||
|
||||
angle::WorkaroundsD3D GenerateWorkarounds();
|
||||
void GenerateWorkarounds(angle::WorkaroundsD3D *workarounds);
|
||||
} // namespace d3d9
|
||||
|
||||
} // namespace rx
|
||||
|
|
|
@ -451,9 +451,9 @@ angle::Result FramebufferGL::readPixels(const gl::Context *context,
|
|||
|
||||
stateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferID);
|
||||
|
||||
bool useOverlappingRowsWorkaround = workarounds.packOverlappingRowsSeparatelyPackBuffer &&
|
||||
packBuffer && packState.rowLength != 0 &&
|
||||
packState.rowLength < clippedArea.width;
|
||||
bool useOverlappingRowsWorkaround =
|
||||
workarounds.packOverlappingRowsSeparatelyPackBuffer.enabled && packBuffer &&
|
||||
packState.rowLength != 0 && packState.rowLength < clippedArea.width;
|
||||
|
||||
GLubyte *outPtr = static_cast<GLubyte *>(pixels);
|
||||
int leftClip = clippedArea.x - area.x;
|
||||
|
@ -487,7 +487,7 @@ angle::Result FramebufferGL::readPixels(const gl::Context *context,
|
|||
}
|
||||
|
||||
bool useLastRowPaddingWorkaround = false;
|
||||
if (workarounds.packLastRowSeparatelyForPaddingInclusion)
|
||||
if (workarounds.packLastRowSeparatelyForPaddingInclusion.enabled)
|
||||
{
|
||||
ANGLE_TRY(ShouldApplyLastRowPaddingWorkaround(
|
||||
contextGL, gl::Extents(clippedArea.width, clippedArea.height, 1), packState, packBuffer,
|
||||
|
@ -735,7 +735,7 @@ void FramebufferGL::syncClearState(const gl::Context *context, GLbitfield mask)
|
|||
StateManagerGL *stateManager = GetStateManagerGL(context);
|
||||
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
|
||||
|
||||
if (workarounds.doesSRGBClearsOnLinearFramebufferAttachments &&
|
||||
if (workarounds.doesSRGBClearsOnLinearFramebufferAttachments.enabled &&
|
||||
(mask & GL_COLOR_BUFFER_BIT) != 0 && !mIsDefault)
|
||||
{
|
||||
bool hasSRGBAttachment = false;
|
||||
|
@ -768,8 +768,8 @@ void FramebufferGL::syncClearBufferState(const gl::Context *context,
|
|||
StateManagerGL *stateManager = GetStateManagerGL(context);
|
||||
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
|
||||
|
||||
if (workarounds.doesSRGBClearsOnLinearFramebufferAttachments && buffer == GL_COLOR &&
|
||||
!mIsDefault)
|
||||
if (workarounds.doesSRGBClearsOnLinearFramebufferAttachments.enabled &&
|
||||
buffer == GL_COLOR && !mIsDefault)
|
||||
{
|
||||
// If doing a clear on a color buffer, set SRGB blend enabled only if the color buffer
|
||||
// is an SRGB format.
|
||||
|
|
|
@ -105,7 +105,7 @@ void ProgramGL::reapplyUBOBindingsIfNeeded(const gl::Context *context)
|
|||
{
|
||||
// Re-apply UBO bindings to work around driver bugs.
|
||||
const WorkaroundsGL &workaroundsGL = GetImplAs<ContextGL>(context)->getWorkaroundsGL();
|
||||
if (workaroundsGL.reapplyUBOBindingsAfterUsingBinaryProgram)
|
||||
if (workaroundsGL.reapplyUBOBindingsAfterUsingBinaryProgram.enabled)
|
||||
{
|
||||
const auto &blocks = mState.getUniformBlocks();
|
||||
for (size_t blockIndex : mState.getActiveUniformBlockBindingsMask())
|
||||
|
@ -453,7 +453,7 @@ std::unique_ptr<LinkEvent> ProgramGL::link(const gl::Context *context,
|
|||
return angle::Result::Incomplete;
|
||||
}
|
||||
|
||||
if (mWorkarounds.alwaysCallUseProgramAfterLink)
|
||||
if (mWorkarounds.alwaysCallUseProgramAfterLink.enabled)
|
||||
{
|
||||
mStateManager->forceUseProgram(mProgramID);
|
||||
}
|
||||
|
@ -470,7 +470,7 @@ std::unique_ptr<LinkEvent> ProgramGL::link(const gl::Context *context,
|
|||
return std::make_unique<LinkEventNativeParallel>(postLinkImplTask, mFunctions, mProgramID);
|
||||
}
|
||||
else if (workerPool->isAsync() &&
|
||||
(!mWorkarounds.dontRelinkProgramsInParallel || !mLinkedInParallel))
|
||||
(!mWorkarounds.dontRelinkProgramsInParallel.enabled || !mLinkedInParallel))
|
||||
{
|
||||
mLinkedInParallel = true;
|
||||
return std::make_unique<LinkEventGL>(workerPool, linkTask, postLinkImplTask);
|
||||
|
|
|
@ -219,7 +219,7 @@ RendererGL::RendererGL(std::unique_ptr<FunctionsGL> functions, const egl::Attrib
|
|||
mFunctions->debugMessageCallback(&LogGLDebugMessage, nullptr);
|
||||
}
|
||||
|
||||
if (mWorkarounds.initializeCurrentVertexAttributes)
|
||||
if (mWorkarounds.initializeCurrentVertexAttributes.enabled)
|
||||
{
|
||||
GLint maxVertexAttribs = 0;
|
||||
mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
|
||||
|
@ -257,14 +257,14 @@ angle::Result RendererGL::flush()
|
|||
|
||||
angle::Result RendererGL::finish()
|
||||
{
|
||||
if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable && mUseDebugOutput)
|
||||
if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable.enabled && mUseDebugOutput)
|
||||
{
|
||||
mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
}
|
||||
|
||||
mFunctions->finish();
|
||||
|
||||
if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable && mUseDebugOutput)
|
||||
if (mWorkarounds.finishDoesNotCauseQueriesToBeAvailable.enabled && mUseDebugOutput)
|
||||
{
|
||||
mFunctions->disable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
}
|
||||
|
@ -586,7 +586,7 @@ angle::Result RendererGL::memoryBarrierByRegion(GLbitfield barriers)
|
|||
|
||||
bool RendererGL::bindWorkerContext(std::string *infoLog)
|
||||
{
|
||||
if (mWorkarounds.disableWorkerContexts)
|
||||
if (mWorkarounds.disableWorkerContexts.enabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -252,72 +252,72 @@ std::shared_ptr<WaitableCompileEvent> ShaderGL::compile(const gl::Context *conte
|
|||
|
||||
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
|
||||
|
||||
if (workarounds.doWhileGLSLCausesGPUHang)
|
||||
if (workarounds.doWhileGLSLCausesGPUHang.enabled)
|
||||
{
|
||||
additionalOptions |= SH_REWRITE_DO_WHILE_LOOPS;
|
||||
}
|
||||
|
||||
if (workarounds.emulateAbsIntFunction)
|
||||
if (workarounds.emulateAbsIntFunction.enabled)
|
||||
{
|
||||
additionalOptions |= SH_EMULATE_ABS_INT_FUNCTION;
|
||||
}
|
||||
|
||||
if (workarounds.addAndTrueToLoopCondition)
|
||||
if (workarounds.addAndTrueToLoopCondition.enabled)
|
||||
{
|
||||
additionalOptions |= SH_ADD_AND_TRUE_TO_LOOP_CONDITION;
|
||||
}
|
||||
|
||||
if (workarounds.emulateIsnanFloat)
|
||||
if (workarounds.emulateIsnanFloat.enabled)
|
||||
{
|
||||
additionalOptions |= SH_EMULATE_ISNAN_FLOAT_FUNCTION;
|
||||
}
|
||||
|
||||
if (workarounds.emulateAtan2Float)
|
||||
if (workarounds.emulateAtan2Float.enabled)
|
||||
{
|
||||
additionalOptions |= SH_EMULATE_ATAN2_FLOAT_FUNCTION;
|
||||
}
|
||||
|
||||
if (workarounds.useUnusedBlocksWithStandardOrSharedLayout)
|
||||
if (workarounds.useUnusedBlocksWithStandardOrSharedLayout.enabled)
|
||||
{
|
||||
additionalOptions |= SH_USE_UNUSED_STANDARD_SHARED_BLOCKS;
|
||||
}
|
||||
|
||||
if (workarounds.removeInvariantAndCentroidForESSL3)
|
||||
if (workarounds.removeInvariantAndCentroidForESSL3.enabled)
|
||||
{
|
||||
additionalOptions |= SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3;
|
||||
}
|
||||
|
||||
if (workarounds.rewriteFloatUnaryMinusOperator)
|
||||
if (workarounds.rewriteFloatUnaryMinusOperator.enabled)
|
||||
{
|
||||
additionalOptions |= SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR;
|
||||
}
|
||||
|
||||
if (!workarounds.dontInitializeUninitializedLocals)
|
||||
if (!workarounds.dontInitializeUninitializedLocals.enabled)
|
||||
{
|
||||
additionalOptions |= SH_INITIALIZE_UNINITIALIZED_LOCALS;
|
||||
}
|
||||
|
||||
if (workarounds.clampPointSize)
|
||||
if (workarounds.clampPointSize.enabled)
|
||||
{
|
||||
additionalOptions |= SH_CLAMP_POINT_SIZE;
|
||||
}
|
||||
|
||||
if (workarounds.rewriteVectorScalarArithmetic)
|
||||
if (workarounds.rewriteVectorScalarArithmetic.enabled)
|
||||
{
|
||||
additionalOptions |= SH_REWRITE_VECTOR_SCALAR_ARITHMETIC;
|
||||
}
|
||||
|
||||
if (workarounds.dontUseLoopsToInitializeVariables)
|
||||
if (workarounds.dontUseLoopsToInitializeVariables.enabled)
|
||||
{
|
||||
additionalOptions |= SH_DONT_USE_LOOPS_TO_INITIALIZE_VARIABLES;
|
||||
}
|
||||
|
||||
if (workarounds.clampFragDepth)
|
||||
if (workarounds.clampFragDepth.enabled)
|
||||
{
|
||||
additionalOptions |= SH_CLAMP_FRAG_DEPTH;
|
||||
}
|
||||
|
||||
if (workarounds.rewriteRepeatedAssignToSwizzled)
|
||||
if (workarounds.rewriteRepeatedAssignToSwizzled.enabled)
|
||||
{
|
||||
additionalOptions |= SH_REWRITE_REPEATED_ASSIGN_TO_SWIZZLED;
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ angle::Result TextureGL::setImage(const gl::Context *context,
|
|||
gl::TextureTarget target = index.getTarget();
|
||||
size_t level = static_cast<size_t>(index.getLevelIndex());
|
||||
|
||||
if (workarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpackBuffer &&
|
||||
if (workarounds.unpackOverlappingRowsSeparatelyUnpackBuffer.enabled && unpackBuffer &&
|
||||
unpack.rowLength != 0 && unpack.rowLength < size.width)
|
||||
{
|
||||
// The rows overlap in unpack memory. Upload the texture row by row to work around
|
||||
|
@ -175,7 +175,7 @@ angle::Result TextureGL::setImage(const gl::Context *context,
|
|||
unpackBuffer, pixels);
|
||||
}
|
||||
|
||||
if (workarounds.unpackLastRowSeparatelyForPaddingInclusion)
|
||||
if (workarounds.unpackLastRowSeparatelyForPaddingInclusion.enabled)
|
||||
{
|
||||
bool apply = false;
|
||||
ANGLE_TRY(ShouldApplyLastRowPaddingWorkaround(
|
||||
|
@ -281,14 +281,14 @@ angle::Result TextureGL::setSubImage(const gl::Context *context,
|
|||
GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled);
|
||||
|
||||
stateManager->bindTexture(getType(), mTextureID);
|
||||
if (workarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpackBuffer &&
|
||||
if (workarounds.unpackOverlappingRowsSeparatelyUnpackBuffer.enabled && unpackBuffer &&
|
||||
unpack.rowLength != 0 && unpack.rowLength < area.width)
|
||||
{
|
||||
return setSubImageRowByRowWorkaround(context, target, level, area, format, type, unpack,
|
||||
unpackBuffer, pixels);
|
||||
}
|
||||
|
||||
if (workarounds.unpackLastRowSeparatelyForPaddingInclusion)
|
||||
if (workarounds.unpackLastRowSeparatelyForPaddingInclusion.enabled)
|
||||
{
|
||||
gl::Extents size(area.width, area.height, area.depth);
|
||||
|
||||
|
|
|
@ -9,12 +9,15 @@
|
|||
#ifndef LIBANGLE_RENDERER_GL_WORKAROUNDSGL_H_
|
||||
#define LIBANGLE_RENDERER_GL_WORKAROUNDSGL_H_
|
||||
|
||||
#include "platform/Feature.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
struct WorkaroundsGL
|
||||
struct WorkaroundsGL : angle::FeatureSetBase
|
||||
{
|
||||
WorkaroundsGL();
|
||||
~WorkaroundsGL();
|
||||
|
||||
// When writing a float to a normalized integer framebuffer, desktop OpenGL is allowed to write
|
||||
// one of the two closest normalized integer representations (although round to nearest is
|
||||
|
@ -23,18 +26,27 @@ struct WorkaroundsGL
|
|||
// section 2.1.2 of the OpenGL ES 2.0.25 spec). This issue only shows up on Intel and AMD
|
||||
// drivers on framebuffer formats that have 1-bit alpha, work around this by using higher
|
||||
// precision formats instead.
|
||||
bool avoid1BitAlphaTextureFormats = false;
|
||||
angle::Feature avoid1BitAlphaTextureFormats = {
|
||||
"avoid_1_bit_alpha_texture_formats", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"Issue on Intel and AMD drivers with 1-bit alpha framebuffer formats", &members};
|
||||
|
||||
// On some older Intel drivers, GL_RGBA4 is not color renderable, glCheckFramebufferStatus
|
||||
// returns GL_FRAMEBUFFER_UNSUPPORTED. Work around this by using a known color-renderable
|
||||
// format.
|
||||
bool rgba4IsNotSupportedForColorRendering = false;
|
||||
angle::Feature rgba4IsNotSupportedForColorRendering = {
|
||||
"rgba4_is_not_supported_for_color_rendering", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"Issue on older Intel drivers, GL_RGBA4 is not color renderable", &members};
|
||||
|
||||
// When clearing a framebuffer on Intel or AMD drivers, when GL_FRAMEBUFFER_SRGB is enabled, the
|
||||
// driver clears to the linearized clear color despite the framebuffer not supporting SRGB
|
||||
// blending. It only seems to do this when the framebuffer has only linear attachments, mixed
|
||||
// attachments appear to get the correct clear color.
|
||||
bool doesSRGBClearsOnLinearFramebufferAttachments = false;
|
||||
angle::Feature doesSRGBClearsOnLinearFramebufferAttachments = {
|
||||
"does_srgb_clears_on_linear_framebuffer_attachments",
|
||||
angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"Issue clearing framebuffers with linear attachments on Indel or AMD "
|
||||
"drivers when GL_FRAMEBUFFER_SRGB is enabled",
|
||||
&members};
|
||||
|
||||
// On Mac some GLSL constructs involving do-while loops cause GPU hangs, such as the following:
|
||||
// int i = 1;
|
||||
|
@ -43,34 +55,56 @@ struct WorkaroundsGL
|
|||
// continue;
|
||||
// } while (i > 0)
|
||||
// Work around this by rewriting the do-while to use another GLSL construct (block + while)
|
||||
bool doWhileGLSLCausesGPUHang = false;
|
||||
angle::Feature doWhileGLSLCausesGPUHang = {
|
||||
"do_while_glsl_causes_gpu_hang", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On Mac some GLSL constructs involving do-while loops cause GPU hangs", &members};
|
||||
|
||||
// Calling glFinish doesn't cause all queries to report that the result is available on some
|
||||
// (NVIDIA) drivers. It was found that enabling GL_DEBUG_OUTPUT_SYNCHRONOUS before the finish
|
||||
// causes it to fully finish.
|
||||
bool finishDoesNotCauseQueriesToBeAvailable = false;
|
||||
angle::Feature finishDoesNotCauseQueriesToBeAvailable = {
|
||||
"finish_does_not_cause_queries_to_be_available", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On some NVIDIA drivers, glFinish doesn't cause all queries to report available result",
|
||||
&members};
|
||||
|
||||
// Always call useProgram after a successful link to avoid a driver bug.
|
||||
// This workaround is meant to reproduce the use_current_program_after_successful_link
|
||||
// workaround in Chromium (http://crbug.com/110263). It has been shown that this workaround is
|
||||
// not necessary for MacOSX 10.9 and higher (http://crrev.com/39eb535b).
|
||||
bool alwaysCallUseProgramAfterLink = false;
|
||||
angle::Feature alwaysCallUseProgramAfterLink = {
|
||||
"always_call_use_program_after_link", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"Always call useProgram after a successful link to avoid a driver bug", &members};
|
||||
|
||||
// In the case of unpacking from a pixel unpack buffer, unpack overlapping rows row by row.
|
||||
bool unpackOverlappingRowsSeparatelyUnpackBuffer = false;
|
||||
angle::Feature unpackOverlappingRowsSeparatelyUnpackBuffer = {
|
||||
"unpack_overlapping_rows_separately_unpack_buffer",
|
||||
angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"In the case of unpacking from a pixel unpack buffer, unpack overlapping rows row by row",
|
||||
&members};
|
||||
|
||||
// In the case of packing to a pixel pack buffer, pack overlapping rows row by row.
|
||||
bool packOverlappingRowsSeparatelyPackBuffer = false;
|
||||
angle::Feature packOverlappingRowsSeparatelyPackBuffer = {
|
||||
"pack_overlapping_rows_separately_pack_buffer", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"In the case of packing to a pixel pack buffer, pack overlapping rows row by row",
|
||||
&members};
|
||||
|
||||
// During initialization, assign the current vertex attributes to the spec-mandated defaults.
|
||||
bool initializeCurrentVertexAttributes = false;
|
||||
angle::Feature initializeCurrentVertexAttributes = {
|
||||
"initialize_current_vertex_attributes", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"During initialization, assign the current vertex attributes to the spec-mandated defaults",
|
||||
&members};
|
||||
|
||||
// abs(i) where i is an integer returns unexpected result on Intel Mac.
|
||||
// Emulate abs(i) with i * sign(i).
|
||||
bool emulateAbsIntFunction = false;
|
||||
angle::Feature emulateAbsIntFunction = {
|
||||
"emulate_abs_int_function", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On Intel mac, abs(i) where i is an integer returns unexpected result", &members};
|
||||
|
||||
// On Intel Mac, calculation of loop conditions in for and while loop has bug.
|
||||
// Add "&& true" to the end of the condition expression to work around the bug.
|
||||
bool addAndTrueToLoopCondition = false;
|
||||
angle::Feature addAndTrueToLoopCondition = {
|
||||
"add_and_true_to_loop_condition", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On Intel Mac, calculation of loop conditions in for and while loop has bug", &members};
|
||||
|
||||
// When uploading textures from an unpack buffer, some drivers count an extra row padding when
|
||||
// checking if the pixel unpack buffer is big enough. Tracking bug: http://anglebug.com/1512
|
||||
|
@ -84,97 +118,167 @@ struct WorkaroundsGL
|
|||
// +-------A--B
|
||||
// The last pixel read will be A, but the driver will think it is B, causing it to generate an
|
||||
// error when the pixel buffer is just big enough.
|
||||
bool unpackLastRowSeparatelyForPaddingInclusion = false;
|
||||
angle::Feature unpackLastRowSeparatelyForPaddingInclusion = {
|
||||
"unpack_last_row_separately_for_padding_inclusion",
|
||||
angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"When uploading textures from an unpack buffer, some drivers count an extra row padding",
|
||||
&members};
|
||||
|
||||
// Equivalent workaround when uploading data from a pixel pack buffer.
|
||||
bool packLastRowSeparatelyForPaddingInclusion = false;
|
||||
angle::Feature packLastRowSeparatelyForPaddingInclusion = {
|
||||
"pack_last_row_separately_for_padding_inclusion", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"When uploading textures from an pack buffer, some drivers count an extra row padding",
|
||||
&members};
|
||||
|
||||
// On some Intel drivers, using isnan() on highp float will get wrong answer. To work around
|
||||
// this bug, we use an expression to emulate function isnan().
|
||||
// Tracking bug: http://crbug.com/650547
|
||||
bool emulateIsnanFloat = false;
|
||||
angle::Feature emulateIsnanFloat = {
|
||||
"emulate_isnan_float", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On some Intel drivers, using isnan() on highp float will get wrong answer", &members};
|
||||
|
||||
// On Mac with OpenGL version 4.1, unused std140 or shared uniform blocks will be
|
||||
// treated as inactive which is not consistent with WebGL2.0 spec. Reference all members in a
|
||||
// unused std140 or shared uniform block at the beginning of main to work around it.
|
||||
// Also used on Linux AMD.
|
||||
bool useUnusedBlocksWithStandardOrSharedLayout = false;
|
||||
angle::Feature useUnusedBlocksWithStandardOrSharedLayout = {
|
||||
"use_unused_blocks_with_standard_or_shared_layout",
|
||||
angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On Mac with OpenGL version 4.1, unused std140 or shared uniform blocks "
|
||||
"will be treated as inactive",
|
||||
&members};
|
||||
|
||||
// This flag is used to fix spec difference between GLSL 4.1 or lower and ESSL3.
|
||||
bool removeInvariantAndCentroidForESSL3 = false;
|
||||
angle::Feature removeInvariantAndCentroidForESSL3 = {
|
||||
"remove_invarient_and_centroid_for_essl3", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"Fix spec difference between GLSL 4.1 or lower and ESSL3", &members};
|
||||
|
||||
// On Intel Mac OSX 10.11 driver, using "-float" will get wrong answer. Use "0.0 - float" to
|
||||
// replace "-float".
|
||||
// Tracking bug: http://crbug.com/308366
|
||||
bool rewriteFloatUnaryMinusOperator = false;
|
||||
angle::Feature rewriteFloatUnaryMinusOperator = {
|
||||
"rewrite_float_unary_minus_operator", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On Intel Mac OSX 10.11 driver, using '-<float>' will get wrong answer", &members,
|
||||
"http://crbug.com/308366"};
|
||||
|
||||
// On NVIDIA drivers, atan(y, x) may return a wrong answer.
|
||||
// Tracking bug: http://crbug.com/672380
|
||||
bool emulateAtan2Float = false;
|
||||
angle::Feature emulateAtan2Float = {"emulate_atan_2_float",
|
||||
angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On NVIDIA drivers, atan(y, x) may return a wrong answer",
|
||||
&members, "http://crbug.com/672380"};
|
||||
|
||||
// Some drivers seem to forget about UBO bindings when using program binaries. Work around
|
||||
// this by re-applying the bindings after the program binary is loaded or saved.
|
||||
// This only seems to affect AMD OpenGL drivers, and some Android devices.
|
||||
// http://anglebug.com/1637
|
||||
bool reapplyUBOBindingsAfterUsingBinaryProgram = false;
|
||||
angle::Feature reapplyUBOBindingsAfterUsingBinaryProgram = {
|
||||
"reapply_ubo_bindings_after_using_binary_program",
|
||||
angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"Some AMD OpenGL drivers and Android devices forget about UBO bindings "
|
||||
"when using program binaries",
|
||||
&members, "http://anglebug.com/1637"};
|
||||
|
||||
// Some OpenGL drivers return 0 when we query MAX_VERTEX_ATTRIB_STRIDE in an OpenGL 4.4 or
|
||||
// higher context.
|
||||
// This only seems to affect AMD OpenGL drivers.
|
||||
// Tracking bug: http://anglebug.com/1936
|
||||
bool emulateMaxVertexAttribStride = false;
|
||||
angle::Feature emulateMaxVertexAttribStride = {
|
||||
"emulate_max_vertex_attrib_stride", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"Some AMD OpenGL >= 4.4 drivers return 0 when MAX_VERTEX_ATTRIB_STRIED queried", &members,
|
||||
"http://anglebug.com/1936"};
|
||||
|
||||
// Initializing uninitialized locals caused odd behavior on Mac in a few WebGL 2 tests.
|
||||
// Tracking bug: http://anglebug/2041
|
||||
bool dontInitializeUninitializedLocals = false;
|
||||
angle::Feature dontInitializeUninitializedLocals = {
|
||||
"dont_initialize_uninitialized_locals", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On Mac initializing uninitialized locals caused odd behavior in a few WebGL 2 tests",
|
||||
&members, "http://anglebug.com/2041"};
|
||||
|
||||
// On some NVIDIA drivers the point size range reported from the API is inconsistent with the
|
||||
// actual behavior. Clamp the point size to the value from the API to fix this.
|
||||
bool clampPointSize = false;
|
||||
angle::Feature clampPointSize = {
|
||||
"clamp_point_size", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On some NVIDIA drivers the point size range reported from the API is "
|
||||
"inconsistent with the actual behavior",
|
||||
&members};
|
||||
|
||||
// On some NVIDIA drivers certain types of GLSL arithmetic ops mixing vectors and scalars may be
|
||||
// executed incorrectly. Change them in the shader translator. Tracking bug:
|
||||
// http://crbug.com/772651
|
||||
bool rewriteVectorScalarArithmetic = false;
|
||||
angle::Feature rewriteVectorScalarArithmetic = {
|
||||
"rewrite_vector_scalar_arithmetic", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On some NVIDIA drivers certain types of GLSL arithmetic ops mixing "
|
||||
"vectors and scalars may be executed incorrectly",
|
||||
&members, "http://crbug.com/772651"};
|
||||
|
||||
// On some Android devices for loops used to initialize variables hit native GLSL compiler bugs.
|
||||
bool dontUseLoopsToInitializeVariables = false;
|
||||
angle::Feature dontUseLoopsToInitializeVariables = {
|
||||
"dont_use_loops_to_initialize_variables", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On some Android devices for loops used to initialize variables hit "
|
||||
"native GLSL compiler bugs",
|
||||
&members};
|
||||
|
||||
// On some NVIDIA drivers gl_FragDepth is not clamped correctly when rendering to a floating
|
||||
// point depth buffer. Clamp it in the translated shader to fix this.
|
||||
bool clampFragDepth = false;
|
||||
angle::Feature clampFragDepth = {
|
||||
"clamp_frag_depth", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On some NVIDIA drivers gl_FragDepth is not clamped correctly when "
|
||||
"rendering to a floating point depth buffer",
|
||||
&members};
|
||||
|
||||
// On some NVIDIA drivers before version 397.31 repeated assignment to swizzled values inside a
|
||||
// GLSL user-defined function have incorrect results. Rewrite this type of statements to fix
|
||||
// this.
|
||||
bool rewriteRepeatedAssignToSwizzled = false;
|
||||
|
||||
angle::Feature rewriteRepeatedAssignToSwizzled = {
|
||||
"rewrite_repeated_assign_to_swizzled", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On some NVIDIA drivers < v397.31, repeated assignment to swizzled "
|
||||
"values inside a GLSL user-defined function have incorrect results",
|
||||
&members};
|
||||
// On some AMD and Intel GL drivers ARB_blend_func_extended does not pass the tests.
|
||||
// It might be possible to work around the Intel bug by rewriting *FragData to *FragColor
|
||||
// instead of disabling the functionality entirely. The AMD bug looked like incorrect blending,
|
||||
// not sure if a workaround is feasible. http://anglebug.com/1085
|
||||
bool disableBlendFuncExtended = false;
|
||||
angle::Feature disableBlendFuncExtended = {
|
||||
"disable_blend_func_extended", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On some AMD and Intel GL drivers ARB_blend_func_extended does not pass the tests",
|
||||
&members, "http://anglebug.com/1085"};
|
||||
|
||||
// Qualcomm drivers returns raw sRGB values instead of linearized values when calling
|
||||
// glReadPixels on unsized sRGB texture formats. http://crbug.com/550292 and
|
||||
// http://crbug.com/565179
|
||||
bool unsizedsRGBReadPixelsDoesntTransform = false;
|
||||
angle::Feature unsizedsRGBReadPixelsDoesntTransform = {
|
||||
"unsized_srgb_read_pixels_doesnt_transform", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"Qualcomm drivers returns raw sRGB values instead of linearized values "
|
||||
"when calling glReadPixels on unsized sRGB texture formats",
|
||||
&members, "http://crbug.com/565179"};
|
||||
|
||||
// Older Qualcomm drivers generate errors when querying the number of bits in timer queries, ex:
|
||||
// GetQueryivEXT(GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS). http://anglebug.com/3027
|
||||
bool queryCounterBitsGeneratesErrors = false;
|
||||
angle::Feature queryCounterBitsGeneratesErrors = {
|
||||
"query_counter_bits_generates_errors", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"Older Qualcomm drivers generate errors when querying the number of bits in timer queries",
|
||||
&members, "http://anglebug.com/3027"};
|
||||
|
||||
// Re-linking a program in parallel is buggy on some Intel Windows OpenGL drivers and Android
|
||||
// platforms.
|
||||
// http://anglebug.com/3045
|
||||
bool dontRelinkProgramsInParallel = false;
|
||||
angle::Feature dontRelinkProgramsInParallel = {
|
||||
"query_counter_bits_generates_errors", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"On some Intel Windows OpenGL drivers and Android, relinking a program "
|
||||
"in parallel is buggy",
|
||||
&members, "http://anglebug.com/3045"};
|
||||
|
||||
// Some tests have been seen to fail using worker contexts, this switch allows worker contexts
|
||||
// to be disabled for some platforms. http://crbug.com/849576
|
||||
bool disableWorkerContexts = false;
|
||||
angle::Feature disableWorkerContexts = {
|
||||
"disable_worker_contexts", angle::FeatureCategory::OpenGLWorkarounds,
|
||||
"Some tests have been seen to fail using worker contexts", &members,
|
||||
"http://crbug.com/849576"};
|
||||
};
|
||||
|
||||
inline WorkaroundsGL::WorkaroundsGL() = default;
|
||||
inline WorkaroundsGL::WorkaroundsGL() = default;
|
||||
inline WorkaroundsGL::~WorkaroundsGL() = default;
|
||||
|
||||
} // namespace rx
|
||||
|
||||
|
|
|
@ -355,13 +355,13 @@ static GLenum GetNativeInternalFormat(const FunctionsGL *functions,
|
|||
// even if the provided type is GL_FLOAT.
|
||||
result = internalFormat.sizedInternalFormat;
|
||||
|
||||
if (workarounds.avoid1BitAlphaTextureFormats && internalFormat.alphaBits == 1)
|
||||
if (workarounds.avoid1BitAlphaTextureFormats.enabled && internalFormat.alphaBits == 1)
|
||||
{
|
||||
// Use an 8-bit format instead
|
||||
result = GL_RGBA8;
|
||||
}
|
||||
|
||||
if (workarounds.rgba4IsNotSupportedForColorRendering &&
|
||||
if (workarounds.rgba4IsNotSupportedForColorRendering.enabled &&
|
||||
internalFormat.sizedInternalFormat == GL_RGBA4)
|
||||
{
|
||||
// Use an 8-bit format instead
|
||||
|
@ -413,7 +413,7 @@ static GLenum GetNativeInternalFormat(const FunctionsGL *functions,
|
|||
// Workaround Adreno driver not supporting unsized EXT_texture_rg formats
|
||||
result = internalFormat.sizedInternalFormat;
|
||||
}
|
||||
else if (workarounds.unsizedsRGBReadPixelsDoesntTransform &&
|
||||
else if (workarounds.unsizedsRGBReadPixelsDoesntTransform.enabled &&
|
||||
internalFormat.colorEncoding == GL_SRGB)
|
||||
{
|
||||
// Work around some Adreno driver bugs that don't read back SRGB data correctly when
|
||||
|
@ -462,7 +462,7 @@ static GLenum GetNativeFormat(const FunctionsGL *functions,
|
|||
}
|
||||
else if (functions->isAtLeastGLES(gl::Version(3, 0)))
|
||||
{
|
||||
if (workarounds.unsizedsRGBReadPixelsDoesntTransform)
|
||||
if (workarounds.unsizedsRGBReadPixelsDoesntTransform.enabled)
|
||||
{
|
||||
if (format == GL_SRGB)
|
||||
{
|
||||
|
|
|
@ -893,7 +893,7 @@ void GenerateCaps(const FunctionsGL *functions,
|
|||
|
||||
// OpenGL 4.3 has no limit on maximum value of stride.
|
||||
// [OpenGL 4.3 (Core Profile) - February 14, 2013] Chapter 10.3.1 Page 298
|
||||
if (workarounds.emulateMaxVertexAttribStride ||
|
||||
if (workarounds.emulateMaxVertexAttribStride.enabled ||
|
||||
(functions->standard == STANDARD_GL_DESKTOP && functions->version == gl::Version(4, 3)))
|
||||
{
|
||||
caps->maxVertexAttribStride = 2048;
|
||||
|
@ -1165,7 +1165,7 @@ void GenerateCaps(const FunctionsGL *functions,
|
|||
extensions->disjointTimerQuery = true;
|
||||
|
||||
// If we can't query the counter bits, leave them at 0.
|
||||
if (!workarounds.queryCounterBitsGeneratesErrors)
|
||||
if (!workarounds.queryCounterBitsGeneratesErrors.enabled)
|
||||
{
|
||||
extensions->queryCounterBitsTimeElapsed =
|
||||
QueryQueryValue(functions, GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS);
|
||||
|
@ -1351,7 +1351,7 @@ void GenerateCaps(const FunctionsGL *functions,
|
|||
// EXT_blend_func_extended.
|
||||
// Note that this could be implemented also on top of native EXT_blend_func_extended, but it's
|
||||
// currently not fully implemented.
|
||||
extensions->blendFuncExtended = !workarounds.disableBlendFuncExtended &&
|
||||
extensions->blendFuncExtended = !workarounds.disableBlendFuncExtended.enabled &&
|
||||
functions->standard == STANDARD_GL_DESKTOP &&
|
||||
functions->hasGLExtension("GL_ARB_blend_func_extended");
|
||||
if (extensions->blendFuncExtended)
|
||||
|
@ -1375,7 +1375,7 @@ void GenerateCaps(const FunctionsGL *functions,
|
|||
|
||||
// To work around broken unsized sRGB textures, sized sRGB textures are used. Disable EXT_sRGB
|
||||
// if those formats are not available.
|
||||
if (workarounds.unsizedsRGBReadPixelsDoesntTransform &&
|
||||
if (workarounds.unsizedsRGBReadPixelsDoesntTransform.enabled &&
|
||||
!functions->isAtLeastGLES(gl::Version(3, 0)))
|
||||
{
|
||||
extensions->sRGB = false;
|
||||
|
@ -1392,86 +1392,87 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround
|
|||
uint32_t device = GetDeviceID(functions);
|
||||
|
||||
// Don't use 1-bit alpha formats on desktop GL with AMD or Intel drivers.
|
||||
workarounds->avoid1BitAlphaTextureFormats =
|
||||
workarounds->avoid1BitAlphaTextureFormats.enabled =
|
||||
functions->standard == STANDARD_GL_DESKTOP && (IsAMD(vendor));
|
||||
|
||||
workarounds->rgba4IsNotSupportedForColorRendering =
|
||||
workarounds->rgba4IsNotSupportedForColorRendering.enabled =
|
||||
functions->standard == STANDARD_GL_DESKTOP && IsIntel(vendor);
|
||||
|
||||
workarounds->emulateAbsIntFunction = IsIntel(vendor);
|
||||
workarounds->emulateAbsIntFunction.enabled = IsIntel(vendor);
|
||||
|
||||
workarounds->addAndTrueToLoopCondition = IsIntel(vendor);
|
||||
workarounds->addAndTrueToLoopCondition.enabled = IsIntel(vendor);
|
||||
|
||||
workarounds->emulateIsnanFloat = IsIntel(vendor);
|
||||
workarounds->emulateIsnanFloat.enabled = IsIntel(vendor);
|
||||
|
||||
workarounds->doesSRGBClearsOnLinearFramebufferAttachments =
|
||||
workarounds->doesSRGBClearsOnLinearFramebufferAttachments.enabled =
|
||||
functions->standard == STANDARD_GL_DESKTOP && (IsIntel(vendor) || IsAMD(vendor));
|
||||
|
||||
workarounds->emulateMaxVertexAttribStride =
|
||||
workarounds->emulateMaxVertexAttribStride.enabled =
|
||||
IsLinux() && functions->standard == STANDARD_GL_DESKTOP && IsAMD(vendor);
|
||||
workarounds->useUnusedBlocksWithStandardOrSharedLayout = IsLinux() && IsAMD(vendor);
|
||||
workarounds->useUnusedBlocksWithStandardOrSharedLayout.enabled = IsLinux() && IsAMD(vendor);
|
||||
|
||||
workarounds->doWhileGLSLCausesGPUHang = IsApple();
|
||||
workarounds->useUnusedBlocksWithStandardOrSharedLayout = IsApple();
|
||||
workarounds->rewriteFloatUnaryMinusOperator = IsApple() && IsIntel(vendor);
|
||||
workarounds->doWhileGLSLCausesGPUHang.enabled = IsApple();
|
||||
workarounds->useUnusedBlocksWithStandardOrSharedLayout.enabled = IsApple();
|
||||
workarounds->rewriteFloatUnaryMinusOperator.enabled = IsApple() && IsIntel(vendor);
|
||||
|
||||
// Triggers a bug on Marshmallow Adreno (4xx?) driver.
|
||||
// http://anglebug.com/2046
|
||||
workarounds->dontInitializeUninitializedLocals = IsAndroid() && IsQualcomm(vendor);
|
||||
workarounds->dontInitializeUninitializedLocals.enabled = IsAndroid() && IsQualcomm(vendor);
|
||||
|
||||
workarounds->finishDoesNotCauseQueriesToBeAvailable =
|
||||
workarounds->finishDoesNotCauseQueriesToBeAvailable.enabled =
|
||||
functions->standard == STANDARD_GL_DESKTOP && IsNvidia(vendor);
|
||||
|
||||
// TODO(cwallez): Disable this workaround for MacOSX versions 10.9 or later.
|
||||
workarounds->alwaysCallUseProgramAfterLink = true;
|
||||
workarounds->alwaysCallUseProgramAfterLink.enabled = true;
|
||||
|
||||
workarounds->unpackOverlappingRowsSeparatelyUnpackBuffer = IsNvidia(vendor);
|
||||
workarounds->packOverlappingRowsSeparatelyPackBuffer = IsNvidia(vendor);
|
||||
workarounds->unpackOverlappingRowsSeparatelyUnpackBuffer.enabled = IsNvidia(vendor);
|
||||
workarounds->packOverlappingRowsSeparatelyPackBuffer.enabled = IsNvidia(vendor);
|
||||
|
||||
workarounds->initializeCurrentVertexAttributes = IsNvidia(vendor);
|
||||
workarounds->initializeCurrentVertexAttributes.enabled = IsNvidia(vendor);
|
||||
|
||||
workarounds->unpackLastRowSeparatelyForPaddingInclusion = IsApple() || IsNvidia(vendor);
|
||||
workarounds->packLastRowSeparatelyForPaddingInclusion = IsApple() || IsNvidia(vendor);
|
||||
workarounds->unpackLastRowSeparatelyForPaddingInclusion.enabled = IsApple() || IsNvidia(vendor);
|
||||
workarounds->packLastRowSeparatelyForPaddingInclusion.enabled = IsApple() || IsNvidia(vendor);
|
||||
|
||||
workarounds->removeInvariantAndCentroidForESSL3 =
|
||||
workarounds->removeInvariantAndCentroidForESSL3.enabled =
|
||||
functions->isAtMostGL(gl::Version(4, 1)) ||
|
||||
(functions->standard == STANDARD_GL_DESKTOP && IsAMD(vendor));
|
||||
|
||||
// TODO(oetuaho): Make this specific to the affected driver versions. Versions that came after
|
||||
// 364 are known to be affected, at least up to 375.
|
||||
workarounds->emulateAtan2Float = IsNvidia(vendor);
|
||||
workarounds->emulateAtan2Float.enabled = IsNvidia(vendor);
|
||||
|
||||
workarounds->reapplyUBOBindingsAfterUsingBinaryProgram = IsAMD(vendor);
|
||||
workarounds->reapplyUBOBindingsAfterUsingBinaryProgram.enabled = IsAMD(vendor);
|
||||
|
||||
workarounds->rewriteVectorScalarArithmetic = IsNvidia(vendor);
|
||||
workarounds->rewriteVectorScalarArithmetic.enabled = IsNvidia(vendor);
|
||||
|
||||
// TODO(oetuaho): Make this specific to the affected driver versions. Versions at least up to
|
||||
// 390 are known to be affected. Versions after that are expected not to be affected.
|
||||
workarounds->clampFragDepth = IsNvidia(vendor);
|
||||
workarounds->clampFragDepth.enabled = IsNvidia(vendor);
|
||||
|
||||
// TODO(oetuaho): Make this specific to the affected driver versions. Versions since 397.31 are
|
||||
// not affected.
|
||||
workarounds->rewriteRepeatedAssignToSwizzled = IsNvidia(vendor);
|
||||
workarounds->rewriteRepeatedAssignToSwizzled.enabled = IsNvidia(vendor);
|
||||
|
||||
// TODO(jmadill): Narrow workaround range for specific devices.
|
||||
workarounds->reapplyUBOBindingsAfterUsingBinaryProgram = IsAndroid();
|
||||
workarounds->reapplyUBOBindingsAfterUsingBinaryProgram.enabled = IsAndroid();
|
||||
|
||||
workarounds->clampPointSize = IsAndroid() || IsNvidia(vendor);
|
||||
workarounds->clampPointSize.enabled = IsAndroid() || IsNvidia(vendor);
|
||||
|
||||
workarounds->dontUseLoopsToInitializeVariables = IsAndroid() && !IsNvidia(vendor);
|
||||
workarounds->dontUseLoopsToInitializeVariables.enabled = IsAndroid() && !IsNvidia(vendor);
|
||||
|
||||
workarounds->disableBlendFuncExtended = IsAMD(vendor) || IsIntel(vendor);
|
||||
workarounds->disableBlendFuncExtended.enabled = IsAMD(vendor) || IsIntel(vendor);
|
||||
|
||||
workarounds->unsizedsRGBReadPixelsDoesntTransform = IsAndroid() && IsQualcomm(vendor);
|
||||
workarounds->unsizedsRGBReadPixelsDoesntTransform.enabled = IsAndroid() && IsQualcomm(vendor);
|
||||
|
||||
workarounds->queryCounterBitsGeneratesErrors = IsNexus5X(vendor, device);
|
||||
workarounds->queryCounterBitsGeneratesErrors.enabled = IsNexus5X(vendor, device);
|
||||
|
||||
workarounds->dontRelinkProgramsInParallel = IsAndroid() || (IsWindows() && IsIntel(vendor));
|
||||
workarounds->dontRelinkProgramsInParallel.enabled =
|
||||
IsAndroid() || (IsWindows() && IsIntel(vendor));
|
||||
|
||||
// TODO(jie.a.chen@intel.com): Clean up the bugs.
|
||||
// anglebug.com/3031
|
||||
// crbug.com/922936
|
||||
workarounds->disableWorkerContexts =
|
||||
workarounds->disableWorkerContexts.enabled =
|
||||
(IsWindows() && (IsIntel(vendor) || IsAMD(vendor))) || (IsLinux() && IsNvidia(vendor));
|
||||
}
|
||||
|
||||
|
@ -1479,8 +1480,9 @@ void ApplyWorkarounds(const FunctionsGL *functions, gl::Workarounds *workarounds
|
|||
{
|
||||
VendorID vendor = GetVendorID(functions);
|
||||
|
||||
workarounds->disableProgramCachingForTransformFeedback = IsAndroid() && IsQualcomm(vendor);
|
||||
workarounds->syncFramebufferBindingsOnTexImage = IsWindows() && IsIntel(vendor);
|
||||
workarounds->disableProgramCachingForTransformFeedback.enabled =
|
||||
IsAndroid() && IsQualcomm(vendor);
|
||||
workarounds->syncFramebufferBindingsOnTexImage.enabled = IsWindows() && IsIntel(vendor);
|
||||
}
|
||||
|
||||
} // namespace nativegl_gl
|
||||
|
|
|
@ -719,7 +719,7 @@ void ContextVk::updateScissor(const gl::State &glState)
|
|||
scissoredArea.y = renderArea.height - scissoredArea.y - scissoredArea.height;
|
||||
}
|
||||
|
||||
if (getRenderer()->getFeatures().forceNonZeroScissor && scissoredArea.width == 0 &&
|
||||
if (getRenderer()->getFeatures().forceNonZeroScissor.enabled && scissoredArea.width == 0 &&
|
||||
scissoredArea.height == 0)
|
||||
{
|
||||
// There is no overlap between the app-set viewport and clippedRect. This code works
|
||||
|
@ -1033,7 +1033,7 @@ angle::Result ContextVk::onMakeCurrent(const gl::Context *context)
|
|||
// surface is flipped.
|
||||
egl::Surface *drawSurface = context->getCurrentDrawSurface();
|
||||
mFlipYForCurrentSurface =
|
||||
drawSurface != nullptr && mRenderer->getFeatures().flipViewportY &&
|
||||
drawSurface != nullptr && mRenderer->getFeatures().flipViewportY.enabled &&
|
||||
!IsMaskFlagSet(drawSurface->getOrientation(), EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE);
|
||||
|
||||
if (drawSurface && drawSurface->getType() == EGL_WINDOW_BIT)
|
||||
|
@ -1064,14 +1064,14 @@ void ContextVk::updateFlipViewportDrawFramebuffer(const gl::State &glState)
|
|||
{
|
||||
gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
|
||||
mFlipViewportForDrawFramebuffer =
|
||||
drawFramebuffer->isDefault() && mRenderer->getFeatures().flipViewportY;
|
||||
drawFramebuffer->isDefault() && mRenderer->getFeatures().flipViewportY.enabled;
|
||||
}
|
||||
|
||||
void ContextVk::updateFlipViewportReadFramebuffer(const gl::State &glState)
|
||||
{
|
||||
gl::Framebuffer *readFramebuffer = glState.getReadFramebuffer();
|
||||
mFlipViewportForReadFramebuffer =
|
||||
readFramebuffer->isDefault() && mRenderer->getFeatures().flipViewportY;
|
||||
readFramebuffer->isDefault() && mRenderer->getFeatures().flipViewportY.enabled;
|
||||
}
|
||||
|
||||
gl::Caps ContextVk::getNativeCaps() const
|
||||
|
|
|
@ -189,7 +189,8 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
|
|||
outExtensions->glTextureCubemapImage = true;
|
||||
outExtensions->glTexture3DImage = false;
|
||||
outExtensions->glRenderbufferImage = true;
|
||||
outExtensions->imageNativeBuffer = getRenderer()->getFeatures().supportsAndroidHardwareBuffer;
|
||||
outExtensions->imageNativeBuffer =
|
||||
getRenderer()->getFeatures().supportsAndroidHardwareBuffer.enabled;
|
||||
}
|
||||
|
||||
void DisplayVk::generateCaps(egl::Caps *outCaps) const
|
||||
|
|
|
@ -295,7 +295,7 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context,
|
|||
|
||||
// On some hardware, having inline commands at this point results in corrupted output. In
|
||||
// that case, end the render pass immediately. http://anglebug.com/2361
|
||||
if (contextVk->getRenderer()->getFeatures().restartRenderPassAfterLoadOpClear)
|
||||
if (contextVk->getRenderer()->getFeatures().restartRenderPassAfterLoadOpClear.enabled)
|
||||
{
|
||||
mFramebuffer.finishCurrentCommands(contextVk->getRenderer());
|
||||
}
|
||||
|
|
|
@ -1063,7 +1063,7 @@ angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk,
|
|||
VkDescriptorSet descSet = mDescriptorSets[descriptorSetIndex];
|
||||
if (descSet == VK_NULL_HANDLE)
|
||||
{
|
||||
if (!contextVk->getRenderer()->getFeatures().bindEmptyForUnusedDescriptorSets)
|
||||
if (!contextVk->getRenderer()->getFeatures().bindEmptyForUnusedDescriptorSets.enabled)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace rx
|
|||
{
|
||||
ANGLE_INLINE bool UseLineRaster(const ContextVk *contextVk, gl::PrimitiveMode mode)
|
||||
{
|
||||
return contextVk->getFeatures().basicGLLineRasterization && gl::IsLineMode(mode);
|
||||
return contextVk->getFeatures().basicGLLineRasterization.enabled && gl::IsLineMode(mode);
|
||||
}
|
||||
|
||||
class ProgramVk : public ProgramImpl
|
||||
|
|
|
@ -976,23 +976,24 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
|
|||
mFeaturesInitialized = true;
|
||||
|
||||
// Selectively enable KHR_MAINTENANCE1 to support viewport flipping.
|
||||
if ((getFeatures().flipViewportY) &&
|
||||
if ((getFeatures().flipViewportY.enabled) &&
|
||||
(mPhysicalDeviceProperties.apiVersion < VK_MAKE_VERSION(1, 1, 0)))
|
||||
{
|
||||
enabledDeviceExtensions.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
|
||||
}
|
||||
if (getFeatures().supportsIncrementalPresent)
|
||||
if (getFeatures().supportsIncrementalPresent.enabled)
|
||||
{
|
||||
enabledDeviceExtensions.push_back(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
if (getFeatures().supportsAndroidHardwareBuffer || getFeatures().supportsExternalMemoryFd)
|
||||
if (getFeatures().supportsAndroidHardwareBuffer.enabled ||
|
||||
getFeatures().supportsExternalMemoryFd.enabled)
|
||||
{
|
||||
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_ANDROID)
|
||||
if (getFeatures().supportsAndroidHardwareBuffer)
|
||||
if (getFeatures().supportsAndroidHardwareBuffer.enabled)
|
||||
{
|
||||
enabledDeviceExtensions.push_back(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME);
|
||||
enabledDeviceExtensions.push_back(
|
||||
|
@ -1000,20 +1001,20 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
|
|||
InitExternalMemoryHardwareBufferANDROIDFunctions(mInstance);
|
||||
}
|
||||
#else
|
||||
ASSERT(!getFeatures().supportsAndroidHardwareBuffer);
|
||||
ASSERT(!getFeatures().supportsAndroidHardwareBuffer.enabled);
|
||||
#endif
|
||||
|
||||
if (getFeatures().supportsExternalMemoryFd)
|
||||
if (getFeatures().supportsExternalMemoryFd.enabled)
|
||||
{
|
||||
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
if (getFeatures().supportsExternalSemaphoreFd)
|
||||
if (getFeatures().supportsExternalSemaphoreFd.enabled)
|
||||
{
|
||||
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
if (getFeatures().supportsExternalSemaphoreFd)
|
||||
if (getFeatures().supportsExternalSemaphoreFd.enabled)
|
||||
{
|
||||
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
|
||||
}
|
||||
|
@ -1239,9 +1240,9 @@ void RendererVk::initFeatures(const ExtensionNameList &deviceExtensionNames)
|
|||
// Use OpenGL line rasterization rules by default.
|
||||
// TODO(jmadill): Fix Android support. http://anglebug.com/2830
|
||||
#if defined(ANGLE_PLATFORM_ANDROID)
|
||||
mFeatures.basicGLLineRasterization = false;
|
||||
mFeatures.basicGLLineRasterization.enabled = false;
|
||||
#else
|
||||
mFeatures.basicGLLineRasterization = true;
|
||||
mFeatures.basicGLLineRasterization.enabled = true;
|
||||
#endif // defined(ANGLE_PLATFORM_ANDROID)
|
||||
|
||||
if ((mPhysicalDeviceProperties.apiVersion >= VK_MAKE_VERSION(1, 1, 0)) ||
|
||||
|
@ -1249,15 +1250,15 @@ void RendererVk::initFeatures(const ExtensionNameList &deviceExtensionNames)
|
|||
{
|
||||
// TODO(lucferron): Currently disabled on Intel only since many tests are failing and need
|
||||
// investigation. http://anglebug.com/2728
|
||||
mFeatures.flipViewportY = !IsIntel(mPhysicalDeviceProperties.vendorID);
|
||||
mFeatures.flipViewportY.enabled = !IsIntel(mPhysicalDeviceProperties.vendorID);
|
||||
}
|
||||
|
||||
#ifdef ANGLE_PLATFORM_WINDOWS
|
||||
// http://anglebug.com/2838
|
||||
mFeatures.extraCopyBufferRegion = IsIntel(mPhysicalDeviceProperties.vendorID);
|
||||
mFeatures.extraCopyBufferRegion.enabled = IsIntel(mPhysicalDeviceProperties.vendorID);
|
||||
|
||||
// http://anglebug.com/3055
|
||||
mFeatures.forceCpuPathForCubeMapCopy = IsIntel(mPhysicalDeviceProperties.vendorID);
|
||||
mFeatures.forceCpuPathForCubeMapCopy.enabled = IsIntel(mPhysicalDeviceProperties.vendorID);
|
||||
#endif
|
||||
|
||||
angle::PlatformMethods *platform = ANGLEPlatformCurrent();
|
||||
|
@ -1267,24 +1268,24 @@ void RendererVk::initFeatures(const ExtensionNameList &deviceExtensionNames)
|
|||
// TODO(jmadill): Narrow driver range once fixed. http://anglebug.com/2970
|
||||
if (IsNvidia(mPhysicalDeviceProperties.vendorID))
|
||||
{
|
||||
mFeatures.clampPointSize = true;
|
||||
mFeatures.clampPointSize.enabled = true;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_ANDROID)
|
||||
// Work around ineffective compute-graphics barriers on Nexus 5X.
|
||||
// TODO(syoussefi): Figure out which other vendors and driver versions are affected.
|
||||
// http://anglebug.com/3019
|
||||
mFeatures.flushAfterVertexConversion =
|
||||
mFeatures.flushAfterVertexConversion.enabled =
|
||||
IsNexus5X(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID);
|
||||
#endif
|
||||
|
||||
if (ExtensionFound(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME, deviceExtensionNames))
|
||||
{
|
||||
mFeatures.supportsIncrementalPresent = true;
|
||||
mFeatures.supportsIncrementalPresent.enabled = true;
|
||||
}
|
||||
|
||||
#if defined(ANGLE_PLATFORM_ANDROID)
|
||||
mFeatures.supportsAndroidHardwareBuffer =
|
||||
mFeatures.supportsAndroidHardwareBuffer.enabled =
|
||||
ExtensionFound(VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
|
||||
deviceExtensionNames) &&
|
||||
ExtensionFound(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME, deviceExtensionNames);
|
||||
|
@ -1292,32 +1293,32 @@ void RendererVk::initFeatures(const ExtensionNameList &deviceExtensionNames)
|
|||
|
||||
if (ExtensionFound(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, deviceExtensionNames))
|
||||
{
|
||||
mFeatures.supportsExternalMemoryFd = true;
|
||||
mFeatures.supportsExternalMemoryFd.enabled = true;
|
||||
}
|
||||
|
||||
if (ExtensionFound(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, deviceExtensionNames))
|
||||
{
|
||||
mFeatures.supportsExternalSemaphoreFd = true;
|
||||
mFeatures.supportsExternalSemaphoreFd.enabled = true;
|
||||
}
|
||||
|
||||
if (IsLinux() && IsIntel(mPhysicalDeviceProperties.vendorID))
|
||||
{
|
||||
mFeatures.disableFifoPresentMode = true;
|
||||
mFeatures.disableFifoPresentMode.enabled = true;
|
||||
}
|
||||
|
||||
if (IsAndroid() && IsQualcomm(mPhysicalDeviceProperties.vendorID))
|
||||
{
|
||||
if (vk::CommandBuffer::ExecutesInline())
|
||||
{
|
||||
mFeatures.restartRenderPassAfterLoadOpClear = true;
|
||||
mFeatures.restartRenderPassAfterLoadOpClear.enabled = true;
|
||||
}
|
||||
|
||||
mFeatures.bindEmptyForUnusedDescriptorSets = true;
|
||||
mFeatures.bindEmptyForUnusedDescriptorSets.enabled = true;
|
||||
}
|
||||
|
||||
if (IsWindows() && IsIntel(mPhysicalDeviceProperties.vendorID))
|
||||
{
|
||||
mFeatures.forceNonZeroScissor = true;
|
||||
mFeatures.forceNonZeroScissor.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ std::shared_ptr<WaitableCompileEvent> ShaderVk::compile(const gl::Context *conte
|
|||
|
||||
ContextVk *contextVk = vk::GetImpl(context);
|
||||
|
||||
if (contextVk->getFeatures().clampPointSize)
|
||||
if (contextVk->getFeatures().clampPointSize.enabled)
|
||||
{
|
||||
compileOptions |= SH_CLAMP_POINT_SIZE;
|
||||
}
|
||||
|
|
|
@ -453,7 +453,7 @@ angle::Result WindowSurfaceVk::initializeImpl(DisplayVk *displayVk)
|
|||
|
||||
// Select appropriate present mode based on vsync parameter. Default to 1 (FIFO), though it
|
||||
// will get clamped to the min/max values specified at display creation time.
|
||||
setSwapInterval(renderer->getFeatures().disableFifoPresentMode ? 0 : 1);
|
||||
setSwapInterval(renderer->getFeatures().disableFifoPresentMode.enabled ? 0 : 1);
|
||||
|
||||
// Default to identity transform.
|
||||
mPreTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
||||
|
@ -758,7 +758,7 @@ angle::Result WindowSurfaceVk::present(DisplayVk *displayVk,
|
|||
VkPresentRegionKHR presentRegion = {};
|
||||
VkPresentRegionsKHR presentRegions = {};
|
||||
std::vector<VkRectLayerKHR> vkRects;
|
||||
if (renderer->getFeatures().supportsIncrementalPresent && (n_rects > 0))
|
||||
if (renderer->getFeatures().supportsIncrementalPresent.enabled && (n_rects > 0))
|
||||
{
|
||||
EGLint width = getWidth();
|
||||
EGLint height = getHeight();
|
||||
|
|
|
@ -63,7 +63,7 @@ bool CanCopyWithDraw(RendererVk *renderer,
|
|||
|
||||
bool ForceCpuPathForCopy(RendererVk *renderer, vk::ImageHelper *image)
|
||||
{
|
||||
return image->getLayerCount() > 1 && renderer->getFeatures().forceCpuPathForCubeMapCopy;
|
||||
return image->getLayerCount() > 1 && renderer->getFeatures().forceCpuPathForCubeMapCopy.enabled;
|
||||
}
|
||||
|
||||
gl::TextureType Get2DTextureType(uint32_t layerCount, GLint samples)
|
||||
|
|
|
@ -502,7 +502,7 @@ angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
|
|||
ensureConversionReleased(renderer, attribIndex);
|
||||
}
|
||||
|
||||
if (anyVertexBufferConvertedOnGpu && renderer->getFeatures().flushAfterVertexConversion)
|
||||
if (anyVertexBufferConvertedOnGpu && renderer->getFeatures().flushAfterVertexConversion.enabled)
|
||||
{
|
||||
ANGLE_TRY(contextVk->flushImpl());
|
||||
}
|
||||
|
|
|
@ -57,10 +57,10 @@ void RendererVk::ensureCapsInitialized() const
|
|||
mNativeExtensions.eglImageExternalEssl3 = false;
|
||||
|
||||
mNativeExtensions.memoryObject = true;
|
||||
mNativeExtensions.memoryObjectFd = getFeatures().supportsExternalMemoryFd;
|
||||
mNativeExtensions.memoryObjectFd = getFeatures().supportsExternalMemoryFd.enabled;
|
||||
|
||||
mNativeExtensions.semaphore = true;
|
||||
mNativeExtensions.semaphoreFd = getFeatures().supportsExternalSemaphoreFd;
|
||||
mNativeExtensions.semaphoreFd = getFeatures().supportsExternalSemaphoreFd.enabled;
|
||||
|
||||
// TODO: Enable this always and emulate instanced draws if any divisor exceeds the maximum
|
||||
// supported. http://anglebug.com/2672
|
||||
|
|
|
@ -118,7 +118,7 @@ Format::Format()
|
|||
|
||||
void Format::initImageFallback(RendererVk *renderer, const ImageFormatInitInfo *info, int numInfo)
|
||||
{
|
||||
size_t skip = renderer->getFeatures().forceFallbackFormat ? 1 : 0;
|
||||
size_t skip = renderer->getFeatures().forceFallbackFormat.enabled ? 1 : 0;
|
||||
int i = FindSupportedFormat(renderer, info + skip, numInfo - skip, HasFullTextureFormatSupport);
|
||||
i += skip;
|
||||
|
||||
|
@ -129,7 +129,7 @@ void Format::initImageFallback(RendererVk *renderer, const ImageFormatInitInfo *
|
|||
|
||||
void Format::initBufferFallback(RendererVk *renderer, const BufferFormatInitInfo *info, int numInfo)
|
||||
{
|
||||
size_t skip = renderer->getFeatures().forceFallbackFormat ? 1 : 0;
|
||||
size_t skip = renderer->getFeatures().forceFallbackFormat.enabled ? 1 : 0;
|
||||
int i = FindSupportedFormat(renderer, info + skip, numInfo - skip, HasFullBufferFormatSupport);
|
||||
i += skip;
|
||||
|
||||
|
|
|
@ -1036,7 +1036,7 @@ angle::Result LineLoopHelper::getIndexBufferForElementArrayBuffer(ContextVk *con
|
|||
{sourceOffset, *bufferOffsetOut, unitCount * unitSize},
|
||||
{sourceOffset, *bufferOffsetOut + unitCount * unitSize, unitSize},
|
||||
};
|
||||
if (contextVk->getRenderer()->getFeatures().extraCopyBufferRegion)
|
||||
if (contextVk->getRenderer()->getFeatures().extraCopyBufferRegion.enabled)
|
||||
copies.push_back({sourceOffset, *bufferOffsetOut + (unitCount + 1) * unitSize, 1});
|
||||
|
||||
ANGLE_TRY(
|
||||
|
|
|
@ -152,6 +152,7 @@ libangle_includes = [
|
|||
"include/GLSLANG/ShaderVars.h",
|
||||
"include/KHR/khrplatform.h",
|
||||
"include/WGL/wgl.h",
|
||||
"include/platform/Feature.h",
|
||||
"include/platform/FeaturesVk.h",
|
||||
"include/platform/Platform.h",
|
||||
"include/platform/WorkaroundsD3D.h",
|
||||
|
|
|
@ -301,7 +301,7 @@ class VulkanClearTest : public MaskedScissoredClearTestBase
|
|||
// depth/stencil format
|
||||
void overrideFeaturesVk(FeaturesVk *featuresVk) override
|
||||
{
|
||||
featuresVk->forceFallbackFormat = true;
|
||||
featuresVk->forceFeatureEnabled("force_fallback_format", true);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -265,7 +265,7 @@ class TinyDepthStencilWorkaroundTest : public ANGLETest
|
|||
// Override the workarounds to enable "tiny" depth/stencil textures.
|
||||
void overrideWorkaroundsD3D(WorkaroundsD3D *workarounds) override
|
||||
{
|
||||
workarounds->emulateTinyStencilTextures = true;
|
||||
workarounds->forceFeatureEnabled("emulate_tiny_stencil_textures", true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ class DepthStencilTest : public ANGLETest
|
|||
// depth/stencil format
|
||||
void overrideFeaturesVk(FeaturesVk *featuresVk) override
|
||||
{
|
||||
featuresVk->forceFallbackFormat = true;
|
||||
featuresVk->forceFeatureEnabled("force_fallback_format", true);
|
||||
}
|
||||
|
||||
void prepareSingleEmulatedWithPacked();
|
||||
|
|
|
@ -926,7 +926,7 @@ class AddDummyTextureNoRenderTargetTest : public ANGLETest
|
|||
|
||||
void overrideWorkaroundsD3D(WorkaroundsD3D *workarounds) override
|
||||
{
|
||||
workarounds->addDummyTextureNoRenderTarget = true;
|
||||
workarounds->forceFeatureEnabled("add_dummy_texture_no_render_target", true);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -287,7 +287,8 @@ class MultiviewRenderTest : public MultiviewFramebufferTestBase
|
|||
|
||||
void overrideWorkaroundsD3D(WorkaroundsD3D *workarounds) override
|
||||
{
|
||||
workarounds->selectViewInGeometryShader = GetParam().mForceUseGeometryShaderOnD3D;
|
||||
workarounds->forceFeatureEnabled("select_view_in_geometry_shader",
|
||||
GetParam().mForceUseGeometryShaderOnD3D);
|
||||
}
|
||||
|
||||
virtual void testSetUp() {}
|
||||
|
@ -528,7 +529,8 @@ class MultiviewLayeredRenderTest : public MultiviewFramebufferTestBase
|
|||
void TearDown() final { MultiviewFramebufferTestBase::FramebufferTestTearDown(); }
|
||||
void overrideWorkaroundsD3D(WorkaroundsD3D *workarounds) final
|
||||
{
|
||||
workarounds->selectViewInGeometryShader = GetParam().mForceUseGeometryShaderOnD3D;
|
||||
workarounds->forceFeatureEnabled("select_view_in_geometry_shader",
|
||||
GetParam().mForceUseGeometryShaderOnD3D);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ class VertexAttributeTest : public ANGLETest
|
|||
// Override a feature to force emulation of attribute formats.
|
||||
void overrideFeaturesVk(FeaturesVk *featuresVk) override
|
||||
{
|
||||
featuresVk->forceFallbackFormat = true;
|
||||
featuresVk->forceFeatureEnabled("force_fallback_format", true);
|
||||
}
|
||||
|
||||
GLuint compileMultiAttribProgram(GLint attribCount)
|
||||
|
|
|
@ -171,8 +171,9 @@ class MultiviewBenchmark : public ANGLERenderTest,
|
|||
|
||||
void overrideWorkaroundsD3D(WorkaroundsD3D *workarounds) override
|
||||
{
|
||||
workarounds->selectViewInGeometryShader =
|
||||
(GetParam().multiviewOption == MultiviewOption::InstancedMultiviewGeometryShader);
|
||||
workarounds->forceFeatureEnabled(
|
||||
"select_view_in_geometry_shader",
|
||||
GetParam().multiviewOption == MultiviewOption::InstancedMultiviewGeometryShader);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -265,7 +265,8 @@ MultiviewImplementationParams GeomShaderD3D11(GLint majorVersion,
|
|||
|
||||
void MultiviewTest::overrideWorkaroundsD3D(WorkaroundsD3D *workarounds)
|
||||
{
|
||||
workarounds->selectViewInGeometryShader = GetParam().mForceUseGeometryShaderOnD3D;
|
||||
workarounds->forceFeatureEnabled("select_view_in_geometry_shader",
|
||||
GetParam().mForceUseGeometryShaderOnD3D);
|
||||
}
|
||||
|
||||
} // namespace angle
|
||||
|
|
Загрузка…
Ссылка в новой задаче