Commit b36a4816 by Jamie Madill Committed by Commit Bot

Vulkan: Add OpenGL line segment rasterization.

Line rasterization rules are implemented using a shader patch. The patch does a small test and discards pixels that are outside of the OpenGL line region. The feature is disabled on Android until we can determine the root cause of the test failures. Bug: angleproject:2598 Change-Id: Ic76c5e40fa3ceff7643e735e66f5a9050240c80b Reviewed-on: https://chromium-review.googlesource.com/1120153 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent beb669da
...@@ -591,6 +591,21 @@ bool IsTriangleMode(PrimitiveMode drawMode) ...@@ -591,6 +591,21 @@ bool IsTriangleMode(PrimitiveMode drawMode)
return false; return false;
} }
bool IsLineMode(PrimitiveMode primitiveMode)
{
switch (primitiveMode)
{
case PrimitiveMode::LineLoop:
case PrimitiveMode::LineStrip:
case PrimitiveMode::LineStripAdjacency:
case PrimitiveMode::Lines:
return true;
default:
return false;
}
}
bool IsIntegerFormat(GLenum unsizedFormat) bool IsIntegerFormat(GLenum unsizedFormat)
{ {
switch (unsizedFormat) switch (unsizedFormat)
......
...@@ -72,6 +72,7 @@ IndexRange ComputeIndexRange(GLenum indexType, ...@@ -72,6 +72,7 @@ IndexRange ComputeIndexRange(GLenum indexType,
GLuint GetPrimitiveRestartIndex(GLenum indexType); GLuint GetPrimitiveRestartIndex(GLenum indexType);
bool IsTriangleMode(PrimitiveMode drawMode); bool IsTriangleMode(PrimitiveMode drawMode);
bool IsLineMode(PrimitiveMode primitiveMode);
bool IsIntegerFormat(GLenum unsizedFormat); bool IsIntegerFormat(GLenum unsizedFormat);
// Returns the product of the sizes in the vector, or 1 if the vector is empty. Doesn't currently // Returns the product of the sizes in the vector, or 1 if the vector is empty. Doesn't currently
......
...@@ -863,6 +863,12 @@ void TIntermBlock::appendStatement(TIntermNode *statement) ...@@ -863,6 +863,12 @@ void TIntermBlock::appendStatement(TIntermNode *statement)
} }
} }
void TIntermBlock::insertStatement(size_t insertPosition, TIntermNode *statement)
{
ASSERT(statement != nullptr);
mStatements.insert(mStatements.begin() + insertPosition, statement);
}
void TIntermDeclaration::appendDeclarator(TIntermTyped *declarator) void TIntermDeclaration::appendDeclarator(TIntermTyped *declarator)
{ {
ASSERT(declarator != nullptr); ASSERT(declarator != nullptr);
......
...@@ -239,7 +239,7 @@ class TIntermBranch : public TIntermNode ...@@ -239,7 +239,7 @@ class TIntermBranch : public TIntermNode
protected: protected:
TOperator mFlowOp; TOperator mFlowOp;
TIntermTyped *mExpression; // non-zero except for "return exp;" statements TIntermTyped *mExpression; // zero except for "return exp;" statements
}; };
// Nodes that correspond to variable symbols in the source code. These may be regular variables or // Nodes that correspond to variable symbols in the source code. These may be regular variables or
...@@ -665,6 +665,7 @@ class TIntermBlock : public TIntermNode, public TIntermAggregateBase ...@@ -665,6 +665,7 @@ class TIntermBlock : public TIntermNode, public TIntermAggregateBase
// Only intended for initially building the block. // Only intended for initially building the block.
void appendStatement(TIntermNode *statement); void appendStatement(TIntermNode *statement);
void insertStatement(size_t insertPosition, TIntermNode *statement);
TIntermSequence *getSequence() override { return &mStatements; } TIntermSequence *getSequence() override { return &mStatements; }
const TIntermSequence *getSequence() const override { return &mStatements; } const TIntermSequence *getSequence() const override { return &mStatements; }
......
...@@ -81,7 +81,6 @@ class TOutputGLSLBase : public TIntermTraverser ...@@ -81,7 +81,6 @@ class TOutputGLSLBase : public TIntermTraverser
bool structDeclared(const TStructure *structure) const; bool structDeclared(const TStructure *structure) const;
private: private:
void declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock); void declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock);
void declareInterfaceBlock(const TInterfaceBlock *interfaceBlock); void declareInterfaceBlock(const TInterfaceBlock *interfaceBlock);
......
...@@ -44,6 +44,7 @@ class TSymbol : angle::NonCopyable ...@@ -44,6 +44,7 @@ class TSymbol : angle::NonCopyable
bool isFunction() const { return mSymbolClass == SymbolClass::Function; } bool isFunction() const { return mSymbolClass == SymbolClass::Function; }
bool isVariable() const { return mSymbolClass == SymbolClass::Variable; } bool isVariable() const { return mSymbolClass == SymbolClass::Variable; }
bool isStruct() const { return mSymbolClass == SymbolClass::Struct; } bool isStruct() const { return mSymbolClass == SymbolClass::Struct; }
bool isInterfaceBlock() const { return mSymbolClass == SymbolClass::InterfaceBlock; }
const TSymbolUniqueId &uniqueId() const { return mUniqueId; } const TSymbolUniqueId &uniqueId() const { return mUniqueId; }
SymbolType symbolType() const { return mSymbolType; } SymbolType symbolType() const { return mSymbolType; }
......
...@@ -146,6 +146,8 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer) ...@@ -146,6 +146,8 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
mDirtyBitHandlers[DIRTY_BIT_INDEX_BUFFER] = &ContextVk::handleDirtyIndexBuffer; mDirtyBitHandlers[DIRTY_BIT_INDEX_BUFFER] = &ContextVk::handleDirtyIndexBuffer;
mDirtyBitHandlers[DIRTY_BIT_DRIVER_UNIFORMS] = &ContextVk::handleDirtyDriverUniforms; mDirtyBitHandlers[DIRTY_BIT_DRIVER_UNIFORMS] = &ContextVk::handleDirtyDriverUniforms;
mDirtyBitHandlers[DIRTY_BIT_DESCRIPTOR_SETS] = &ContextVk::handleDirtyDescriptorSets; mDirtyBitHandlers[DIRTY_BIT_DESCRIPTOR_SETS] = &ContextVk::handleDirtyDescriptorSets;
mDirtyBits = mNewCommandBufferDirtyBits;
} }
ContextVk::~ContextVk() = default; ContextVk::~ContextVk() = default;
......
...@@ -288,7 +288,7 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -288,7 +288,7 @@ class ContextVk : public ContextImpl, public vk::Context
float halfRenderAreaHeight; float halfRenderAreaHeight;
float viewportYScale; float viewportYScale;
float invViewportYScale; float negViewportYScale;
float padding; float padding;
// We'll use x, y, z for near / far / diff respectively. // We'll use x, y, z for near / far / diff respectively.
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <array> #include <array>
#include "common/FixedVector.h"
#include "common/string_utils.h" #include "common/string_utils.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
...@@ -25,14 +26,17 @@ ...@@ -25,14 +26,17 @@
namespace rx namespace rx
{ {
namespace namespace
{ {
constexpr char kQualifierMarkerBegin[] = "@@ QUALIFIER-"; constexpr char kQualifierMarkerBegin[] = "@@ QUALIFIER-";
constexpr char kLayoutMarkerBegin[] = "@@ LAYOUT-"; constexpr char kLayoutMarkerBegin[] = "@@ LAYOUT-";
constexpr char kMarkerEnd[] = " @@"; constexpr char kMarkerEnd[] = " @@";
constexpr char kUniformQualifier[] = "uniform"; constexpr char kUniformQualifier[] = "uniform";
constexpr char kVersionDefine[] = "#version 450 core\n";
constexpr char kLineRasterDefine[] = R"(#version 450 core
#define ANGLE_ENABLE_LINE_SEGMENT_RASTERIZATION
)";
void GetBuiltInResourcesFromCaps(const gl::Caps &caps, TBuiltInResource *outBuiltInResources) void GetBuiltInResourcesFromCaps(const gl::Caps &caps, TBuiltInResource *outBuiltInResources)
{ {
...@@ -203,15 +207,13 @@ void GlslangWrapper::GetShaderSource(const gl::ProgramState &programState, ...@@ -203,15 +207,13 @@ void GlslangWrapper::GetShaderSource(const gl::ProgramState &programState,
// Bind the default uniforms for vertex and fragment shaders. // Bind the default uniforms for vertex and fragment shaders.
// See corresponding code in OutputVulkanGLSL.cpp. // See corresponding code in OutputVulkanGLSL.cpp.
std::stringstream searchStringBuilder; std::string uniformsSearchString("@@ DEFAULT-UNIFORMS-SET-BINDING @@");
searchStringBuilder << "@@ DEFAULT-UNIFORMS-SET-BINDING @@";
std::string searchString = searchStringBuilder.str();
std::string vertexDefaultUniformsBinding = "set = 0, binding = 0"; std::string vertexDefaultUniformsBinding = "set = 0, binding = 0";
std::string fragmentDefaultUniformsBinding = "set = 0, binding = 1"; std::string fragmentDefaultUniformsBinding = "set = 0, binding = 1";
angle::ReplaceSubstring(&vertexSource, searchString, vertexDefaultUniformsBinding); angle::ReplaceSubstring(&vertexSource, uniformsSearchString, vertexDefaultUniformsBinding);
angle::ReplaceSubstring(&fragmentSource, searchString, fragmentDefaultUniformsBinding); angle::ReplaceSubstring(&fragmentSource, uniformsSearchString, fragmentDefaultUniformsBinding);
// Assign textures to a descriptor set and binding. // Assign textures to a descriptor set and binding.
int textureCount = 0; int textureCount = 0;
...@@ -279,6 +281,18 @@ void GlslangWrapper::GetShaderSource(const gl::ProgramState &programState, ...@@ -279,6 +281,18 @@ void GlslangWrapper::GetShaderSource(const gl::ProgramState &programState,
InsertQualifierSpecifierString(&vertexSource, kDriverBlockName, kUniformQualifier); InsertQualifierSpecifierString(&vertexSource, kDriverBlockName, kUniformQualifier);
InsertQualifierSpecifierString(&fragmentSource, kDriverBlockName, kUniformQualifier); InsertQualifierSpecifierString(&fragmentSource, kDriverBlockName, kUniformQualifier);
// Substitute layout and qualifier strings for the position varying. Use the first free
// varying register after the packed varyings.
constexpr char kVaryingName[] = "ANGLEPosition";
std::stringstream layoutStream;
layoutStream << "location = " << (resources.varyingPacking.getMaxSemanticIndex() + 1);
const std::string layout = layoutStream.str();
InsertLayoutSpecifierString(&vertexSource, kVaryingName, layout);
InsertLayoutSpecifierString(&fragmentSource, kVaryingName, layout);
InsertQualifierSpecifierString(&vertexSource, kVaryingName, "out");
InsertQualifierSpecifierString(&fragmentSource, kVaryingName, "in");
*vertexSourceOut = vertexSource; *vertexSourceOut = vertexSource;
*fragmentSourceOut = fragmentSource; *fragmentSourceOut = fragmentSource;
} }
...@@ -286,11 +300,45 @@ void GlslangWrapper::GetShaderSource(const gl::ProgramState &programState, ...@@ -286,11 +300,45 @@ void GlslangWrapper::GetShaderSource(const gl::ProgramState &programState,
// static // static
angle::Result GlslangWrapper::GetShaderCode(vk::Context *context, angle::Result GlslangWrapper::GetShaderCode(vk::Context *context,
const gl::Caps &glCaps, const gl::Caps &glCaps,
bool enableLineRasterEmulation,
const std::string &vertexSource, const std::string &vertexSource,
const std::string &fragmentSource, const std::string &fragmentSource,
std::vector<uint32_t> *vertexCodeOut, std::vector<uint32_t> *vertexCodeOut,
std::vector<uint32_t> *fragmentCodeOut) std::vector<uint32_t> *fragmentCodeOut)
{ {
if (enableLineRasterEmulation)
{
std::string patchedVertexSource = vertexSource;
std::string patchedFragmentSource = fragmentSource;
// #defines must come after the #version directive.
ANGLE_VK_CHECK(
context,
angle::ReplaceSubstring(&patchedVertexSource, kVersionDefine, kLineRasterDefine),
VK_ERROR_INVALID_SHADER_NV);
ANGLE_VK_CHECK(
context,
angle::ReplaceSubstring(&patchedFragmentSource, kVersionDefine, kLineRasterDefine),
VK_ERROR_INVALID_SHADER_NV);
return GetShaderCodeImpl(context, glCaps, patchedVertexSource, patchedFragmentSource,
vertexCodeOut, fragmentCodeOut);
}
else
{
return GetShaderCodeImpl(context, glCaps, vertexSource, fragmentSource, vertexCodeOut,
fragmentCodeOut);
}
}
// static
angle::Result GlslangWrapper::GetShaderCodeImpl(vk::Context *context,
const gl::Caps &glCaps,
const std::string &vertexSource,
const std::string &fragmentSource,
std::vector<uint32_t> *vertexCodeOut,
std::vector<uint32_t> *fragmentCodeOut)
{
std::array<const char *, 2> strings = {{vertexSource.c_str(), fragmentSource.c_str()}}; std::array<const char *, 2> strings = {{vertexSource.c_str(), fragmentSource.c_str()}};
std::array<int, 2> lengths = { std::array<int, 2> lengths = {
{static_cast<int>(vertexSource.length()), static_cast<int>(fragmentSource.length())}}; {static_cast<int>(vertexSource.length()), static_cast<int>(fragmentSource.length())}};
......
...@@ -29,12 +29,20 @@ class GlslangWrapper ...@@ -29,12 +29,20 @@ class GlslangWrapper
static angle::Result GetShaderCode(vk::Context *context, static angle::Result GetShaderCode(vk::Context *context,
const gl::Caps &glCaps, const gl::Caps &glCaps,
bool enableLineRasterEmulation,
const std::string &vertexSource, const std::string &vertexSource,
const std::string &fragmentSource, const std::string &fragmentSource,
std::vector<uint32_t> *vertexCodeOut, std::vector<uint32_t> *vertexCodeOut,
std::vector<uint32_t> *fragmentCodeOut); std::vector<uint32_t> *fragmentCodeOut);
};
private:
static angle::Result GetShaderCodeImpl(vk::Context *context,
const gl::Caps &glCaps,
const std::string &vertexSource,
const std::string &fragmentSource,
std::vector<uint32_t> *vertexCodeOut,
std::vector<uint32_t> *fragmentCodeOut);
};
} // namespace rx } // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_GLSLANG_WRAPPER_H_ #endif // LIBANGLE_RENDERER_VULKAN_GLSLANG_WRAPPER_H_
...@@ -128,6 +128,12 @@ angle::Result SyncDefaultUniformBlock(ContextVk *contextVk, ...@@ -128,6 +128,12 @@ angle::Result SyncDefaultUniformBlock(ContextVk *contextVk,
ANGLE_TRY(dynamicBuffer->flush(contextVk)); ANGLE_TRY(dynamicBuffer->flush(contextVk));
return angle::Result::Continue(); return angle::Result::Continue();
} }
bool UseLineRaster(const ContextVk *contextVk, const gl::DrawCallParams &drawCallParams)
{
return contextVk->getFeatures().basicGLLineRasterization &&
gl::IsLineMode(drawCallParams.mode());
}
} // anonymous namespace } // anonymous namespace
// ProgramVk::ShaderInfo implementation. // ProgramVk::ShaderInfo implementation.
...@@ -141,6 +147,7 @@ angle::Result ProgramVk::ShaderInfo::getShaders( ...@@ -141,6 +147,7 @@ angle::Result ProgramVk::ShaderInfo::getShaders(
ContextVk *contextVk, ContextVk *contextVk,
const std::string &vertexSource, const std::string &vertexSource,
const std::string &fragmentSource, const std::string &fragmentSource,
bool enableLineRasterEmulation,
const vk::ShaderAndSerial **vertexShaderAndSerialOut, const vk::ShaderAndSerial **vertexShaderAndSerialOut,
const vk::ShaderAndSerial **fragmentShaderAndSerialOut) const vk::ShaderAndSerial **fragmentShaderAndSerialOut)
{ {
...@@ -148,7 +155,8 @@ angle::Result ProgramVk::ShaderInfo::getShaders( ...@@ -148,7 +155,8 @@ angle::Result ProgramVk::ShaderInfo::getShaders(
{ {
std::vector<uint32_t> vertexCode; std::vector<uint32_t> vertexCode;
std::vector<uint32_t> fragmentCode; std::vector<uint32_t> fragmentCode;
ANGLE_TRY(GlslangWrapper::GetShaderCode(contextVk, contextVk->getCaps(), vertexSource, ANGLE_TRY(GlslangWrapper::GetShaderCode(contextVk, contextVk->getCaps(),
enableLineRasterEmulation, vertexSource,
fragmentSource, &vertexCode, &fragmentCode)); fragmentSource, &vertexCode, &fragmentCode));
ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mVertexShaderAndSerial, vertexCode.data(), ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mVertexShaderAndSerial, vertexCode.data(),
...@@ -211,8 +219,8 @@ angle::Result ProgramVk::reset(ContextVk *contextVk) ...@@ -211,8 +219,8 @@ angle::Result ProgramVk::reset(ContextVk *contextVk)
uniformBlock.storage.release(renderer); uniformBlock.storage.release(renderer);
} }
// TODO(jmadill): Line rasterization emulation shaders. http://anglebug.com/2598
mDefaultShaderInfo.destroy(device); mDefaultShaderInfo.destroy(device);
mLineRasterShaderInfo.destroy(device);
Serial currentSerial = renderer->getCurrentQueueSerial(); Serial currentSerial = renderer->getCurrentQueueSerial();
renderer->releaseObject(currentSerial, &mEmptyUniformBlockStorage.memory); renderer->releaseObject(currentSerial, &mEmptyUniformBlockStorage.memory);
...@@ -732,10 +740,20 @@ angle::Result ProgramVk::initShaders(ContextVk *contextVk, ...@@ -732,10 +740,20 @@ angle::Result ProgramVk::initShaders(ContextVk *contextVk,
const vk::ShaderAndSerial **fragmentShaderAndSerialOut, const vk::ShaderAndSerial **fragmentShaderAndSerialOut,
const vk::PipelineLayout **pipelineLayoutOut) const vk::PipelineLayout **pipelineLayoutOut)
{ {
// TODO(jmadill): Line rasterization emulation shaders. http://anglebug.com/2598 if (UseLineRaster(contextVk, drawCallParams))
ANGLE_TRY(mDefaultShaderInfo.getShaders(contextVk, mVertexSource, mFragmentSource, {
vertexShaderAndSerialOut, fragmentShaderAndSerialOut)); ANGLE_TRY(mLineRasterShaderInfo.getShaders(contextVk, mVertexSource, mFragmentSource, true,
ASSERT(mDefaultShaderInfo.valid()); vertexShaderAndSerialOut,
fragmentShaderAndSerialOut));
ASSERT(mLineRasterShaderInfo.valid());
}
else
{
ANGLE_TRY(mDefaultShaderInfo.getShaders(contextVk, mVertexSource, mFragmentSource, false,
vertexShaderAndSerialOut,
fragmentShaderAndSerialOut));
ASSERT(mDefaultShaderInfo.valid());
}
*pipelineLayoutOut = &mPipelineLayout.get(); *pipelineLayoutOut = &mPipelineLayout.get();
...@@ -925,7 +943,6 @@ angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk, ...@@ -925,7 +943,6 @@ angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk,
const gl::DrawCallParams &drawCallParams, const gl::DrawCallParams &drawCallParams,
vk::CommandBuffer *commandBuffer) vk::CommandBuffer *commandBuffer)
{ {
// TODO(jmadill): Line rasterization emulation shaders. http://anglebug.com/2598
// Can probably use better dirty bits here. // Can probably use better dirty bits here.
if (mUsedDescriptorSetRange.empty()) if (mUsedDescriptorSetRange.empty())
......
...@@ -183,6 +183,7 @@ class ProgramVk : public ProgramImpl ...@@ -183,6 +183,7 @@ class ProgramVk : public ProgramImpl
angle::Result getShaders(ContextVk *contextVk, angle::Result getShaders(ContextVk *contextVk,
const std::string &vertexSource, const std::string &vertexSource,
const std::string &fragmentSource, const std::string &fragmentSource,
bool enableLineRasterEmulation,
const vk::ShaderAndSerial **vertexShaderAndSerialOut, const vk::ShaderAndSerial **vertexShaderAndSerialOut,
const vk::ShaderAndSerial **fragmentShaderAndSerialOut); const vk::ShaderAndSerial **fragmentShaderAndSerialOut);
void destroy(VkDevice device); void destroy(VkDevice device);
...@@ -193,8 +194,8 @@ class ProgramVk : public ProgramImpl ...@@ -193,8 +194,8 @@ class ProgramVk : public ProgramImpl
vk::ShaderAndSerial mFragmentShaderAndSerial; vk::ShaderAndSerial mFragmentShaderAndSerial;
}; };
// TODO(jmadill): Line rasterization emulation shaders. http://anglebug.com/2598
ShaderInfo mDefaultShaderInfo; ShaderInfo mDefaultShaderInfo;
ShaderInfo mLineRasterShaderInfo;
// We keep the translated linked shader sources to use with shader draw call patching. // We keep the translated linked shader sources to use with shader draw call patching.
std::string mVertexSource; std::string mVertexSource;
......
...@@ -683,8 +683,13 @@ std::string RendererVk::getRendererDescription() const ...@@ -683,8 +683,13 @@ std::string RendererVk::getRendererDescription() const
void RendererVk::initFeatures() void RendererVk::initFeatures()
{ {
// Use OpenGL line rasterization rules by default. // Use OpenGL line rasterization rules by default.
// TODO(jmadill): Fix Android support. http://anglebug.com/2830
#if defined(ANGLE_PLATFORM_ANDROID)
mFeatures.basicGLLineRasterization = false;
#else
mFeatures.basicGLLineRasterization = true; mFeatures.basicGLLineRasterization = true;
#endif // defined(ANGLE_PLATFORM_ANDROID)
// TODO(lucferron): Currently disabled on Intel only since many tests are failing and need // TODO(lucferron): Currently disabled on Intel only since many tests are failing and need
// investigation. http://anglebug.com/2728 // investigation. http://anglebug.com/2728
......
...@@ -183,6 +183,19 @@ ...@@ -183,6 +183,19 @@
2630 GLES ANDROID : dEQP-GLES2.functional.shaders.struct.uniform.sampler_in_array_function_arg_* = FAIL 2630 GLES ANDROID : dEQP-GLES2.functional.shaders.struct.uniform.sampler_in_array_function_arg_* = FAIL
2630 GLES ANDROID : dEQP-GLES2.functional.shaders.struct.uniform.sampler_in_function_arg_* = FAIL 2630 GLES ANDROID : dEQP-GLES2.functional.shaders.struct.uniform.sampler_in_function_arg_* = FAIL
2567 GLES ANDROID : dEQP-GLES2.functional.fbo.completeness.renderable.texture.depth.red_unsigned_byte = FAIL
2567 GLES ANDROID : dEQP-GLES2.functional.fbo.completeness.renderable.texture.depth.rg_unsigned_byte = FAIL
2567 GLES ANDROID : dEQP-GLES2.functional.fbo.completeness.renderable.texture.stencil.red_unsigned_byte = FAIL
2567 GLES ANDROID : dEQP-GLES2.functional.fbo.completeness.renderable.texture.stencil.rg_unsigned_byte = FAIL
// Windows Linux and Mac failures
1028 WIN LINUX MAC : dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.srgb8 = FAIL
1028 WIN LINUX MAC : dEQP-GLES2.functional.fbo.completeness.renderable.texture.stencil.srgb8 = FAIL
1028 WIN LINUX MAC : dEQP-GLES2.functional.fbo.completeness.renderable.texture.depth.srgb8 = FAIL
// General Vulkan failures
// Nothing here!
// Android Vulkan backend only failures // Android Vulkan backend only failures
2549 VULKAN ANDROID : dEQP-GLES2.functional.fragment_ops.depth_stencil.stencil* = SKIP 2549 VULKAN ANDROID : dEQP-GLES2.functional.fragment_ops.depth_stencil.stencil* = SKIP
2606 VULKAN ANDROID : dEQP-GLES2.functional.debug_marker.random = SKIP 2606 VULKAN ANDROID : dEQP-GLES2.functional.debug_marker.random = SKIP
...@@ -190,23 +203,15 @@ ...@@ -190,23 +203,15 @@
2609 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.generate.* = SKIP 2609 VULKAN ANDROID : dEQP-GLES2.functional.texture.mipmap.cube.generate.* = SKIP
2405 VULKAN ANDROID : dEQP-GLES2.functional.draw.random.42 = SKIP 2405 VULKAN ANDROID : dEQP-GLES2.functional.draw.random.42 = SKIP
2405 VULKAN ANDROID : dEQP-GLES2.functional.draw.random.59 = SKIP 2405 VULKAN ANDROID : dEQP-GLES2.functional.draw.random.59 = SKIP
2830 VULKAN ANDROID : dEQP-GLES2.functional.rasterization.primitives.line* = SKIP
// Fails on Nexus 5x only. TODO(jmadill): Remove suppression when possible. http://anglebug.com/2791 // Fails on Nexus 5x only. TODO(jmadill): Remove suppression when possible. http://anglebug.com/2791
2791 VULKAN ANDROID : dEQP-GLES2.functional.clipping.* = SKIP 2791 VULKAN ANDROID : dEQP-GLES2.functional.clipping.* = SKIP
2599 VULKAN ANDROID : dEQP-GLES2.functional.rasterization.limits.points = FAIL 2599 VULKAN ANDROID : dEQP-GLES2.functional.rasterization.limits.points = FAIL
2567 GLES ANDROID : dEQP-GLES2.functional.fbo.completeness.renderable.texture.depth.red_unsigned_byte = FAIL // Failing on the Pixel 2.
2567 GLES ANDROID : dEQP-GLES2.functional.fbo.completeness.renderable.texture.depth.rg_unsigned_byte = FAIL 2727 VULKAN ANDROID : dEQP-GLES2.functional.shaders.builtin_variable.pointcoord = FAIL
2567 GLES ANDROID : dEQP-GLES2.functional.fbo.completeness.renderable.texture.stencil.red_unsigned_byte = FAIL 2808 VULKAN ANDROID : dEQP-GLES2.functional.shaders.builtin_variable.fragcoord_w = FAIL
2567 GLES ANDROID : dEQP-GLES2.functional.fbo.completeness.renderable.texture.stencil.rg_unsigned_byte = FAIL
// Windows Linux and Mac failures
1028 WIN LINUX MAC : dEQP-GLES2.functional.fbo.completeness.renderable.texture.color0.srgb8 = FAIL
1028 WIN LINUX MAC : dEQP-GLES2.functional.fbo.completeness.renderable.texture.stencil.srgb8 = FAIL
1028 WIN LINUX MAC : dEQP-GLES2.functional.fbo.completeness.renderable.texture.depth.srgb8 = FAIL
// Vulkan failures
2598 VULKAN : dEQP-GLES2.functional.rasterization.primitives.line* = SKIP
// Vulkan AMD Windows specific failures // Vulkan AMD Windows specific failures
2602 VULKAN WIN AMD : dEQP-GLES2.functional.buffer.write.* = SKIP 2602 VULKAN WIN AMD : dEQP-GLES2.functional.buffer.write.* = SKIP
...@@ -243,6 +248,5 @@ ...@@ -243,6 +248,5 @@
2405 VULKAN WIN AMD : dEQP-GLES2.functional.vertex_arrays.single_attribute.usages.buffer_0_32_float* = SKIP 2405 VULKAN WIN AMD : dEQP-GLES2.functional.vertex_arrays.single_attribute.usages.buffer_0_32_float* = SKIP
2405 VULKAN WIN AMD : dEQP-GLES2.functional.vertex_arrays.single_attribute.usages.buffer_0_32_short* = SKIP 2405 VULKAN WIN AMD : dEQP-GLES2.functional.vertex_arrays.single_attribute.usages.buffer_0_32_short* = SKIP
// Failing on the Pixel 2. // Fails after OpenGL line rasterization rules implementation. Possibly a bug in FragCoord.
2727 VULKAN ANDROID : dEQP-GLES2.functional.shaders.builtin_variable.pointcoord = FAIL 2809 VULKAN WIN AMD : dEQP-GLES2.functional.clipping.line.long_line_clip = FAIL
2808 VULKAN ANDROID : dEQP-GLES2.functional.shaders.builtin_variable.fragcoord_w = FAIL
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
// //
#include "test_utils/ANGLETest.h" #include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
using namespace angle; using namespace angle;
...@@ -241,6 +242,86 @@ TEST_P(ViewportTest, TripleWindowOffCenter) ...@@ -241,6 +242,86 @@ TEST_P(ViewportTest, TripleWindowOffCenter)
runScissoredTest(); runScissoredTest();
} }
// Test line rendering with a non-standard viewport.
TEST_P(ViewportTest, DrawLineWithViewport)
{
// We assume in the test the width and height are equal and we are tracing
// the line from bottom left to top right. Verify that all pixels along that line
// have been traced with green.
ASSERT_EQ(getWindowWidth(), getWindowHeight());
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
glUseProgram(program);
std::vector<Vector3> vertices = {{-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}};
const GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
ASSERT_NE(-1, positionLocation);
GLBuffer vertexBuffer;
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
GL_STATIC_DRAW);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(positionLocation);
// Set the viewport.
GLint quarterWidth = getWindowWidth() / 4;
GLint quarterHeight = getWindowHeight() / 4;
glViewport(quarterWidth, quarterHeight, quarterWidth, quarterHeight);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(vertices.size()));
glDisableVertexAttribArray(positionLocation);
ASSERT_GL_NO_ERROR();
for (GLint x = quarterWidth; x < getWindowWidth() / 2; x++)
{
EXPECT_PIXEL_COLOR_EQ(x, x, GLColor::green);
}
}
// Test line rendering with an overly large viewport.
TEST_P(ViewportTest, DrawLineWithLargeViewport)
{
// We assume in the test the width and height are equal and we are tracing
// the line from bottom left to top right. Verify that all pixels along that line
// have been traced with green.
ASSERT_EQ(getWindowWidth(), getWindowHeight());
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
glUseProgram(program);
std::vector<Vector3> vertices = {{-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}};
const GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
ASSERT_NE(-1, positionLocation);
GLBuffer vertexBuffer;
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
GL_STATIC_DRAW);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(positionLocation);
// Set the viewport.
glViewport(0, 0, getWindowWidth() * 2, getWindowHeight() * 2);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(vertices.size()));
glDisableVertexAttribArray(positionLocation);
ASSERT_GL_NO_ERROR();
for (GLint x = 0; x < getWindowWidth(); x++)
{
EXPECT_PIXEL_COLOR_EQ(x, x, GLColor::green);
}
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
// D3D11 Feature Level 9 and D3D9 emulate large and negative viewports in the vertex shader. We should test both of these as well as D3D11 Feature Level 10_0+. // D3D11 Feature Level 9 and D3D9 emulate large and negative viewports in the vertex shader. We should test both of these as well as D3D11 Feature Level 10_0+.
ANGLE_INSTANTIATE_TEST(ViewportTest, ANGLE_INSTANTIATE_TEST(ViewportTest,
......
...@@ -364,6 +364,17 @@ void main() ...@@ -364,6 +364,17 @@ void main()
})"; })";
} }
// A shader that fills with 100% opaque green.
const char *Green()
{
return R"(precision mediump float;
void main()
{
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
})";
}
// A shader that fills with 100% opaque blue. // A shader that fills with 100% opaque blue.
const char *Blue() const char *Blue()
{ {
......
...@@ -83,6 +83,9 @@ ANGLE_EXPORT const char *UniformColor(); ...@@ -83,6 +83,9 @@ ANGLE_EXPORT const char *UniformColor();
// A shader that fills with 100% opaque red. // A shader that fills with 100% opaque red.
ANGLE_EXPORT const char *Red(); ANGLE_EXPORT const char *Red();
// A shader that fills with 100% opaque green.
ANGLE_EXPORT const char *Green();
// A shader that fills with 100% opaque blue. // A shader that fills with 100% opaque blue.
ANGLE_EXPORT const char *Blue(); ANGLE_EXPORT const char *Blue();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment