Commit 0e82ae9c by Jamie Madill

Vulkan: Implement depth range correction.

This is done via inserting a statement at the end of the "main" of the vertex shader which scales and offsets gl_Position.z. Relevant sections of the Vulkan spec are 23.4. Coordinate Transformations and OpenGL spec "2.12.1 Controlling the Viewport". Bug: angleproject:2406 Change-Id: Ibf5403b3ad06a5114a7de3be0a406d696cbb7dea Reviewed-on: https://chromium-review.googlesource.com/964733Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 6f5444da
...@@ -13,12 +13,18 @@ ...@@ -13,12 +13,18 @@
#include "angle_gl.h" #include "angle_gl.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "compiler/translator/BuiltIn_autogen.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/OutputVulkanGLSL.h" #include "compiler/translator/OutputVulkanGLSL.h"
#include "compiler/translator/RunAtTheEndOfShader.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/util.h" #include "compiler/translator/util.h"
namespace sh namespace sh
{ {
namespace
{
class DeclareDefaultUniformsTraverser : public TIntermTraverser class DeclareDefaultUniformsTraverser : public TIntermTraverser
{ {
public: public:
...@@ -90,6 +96,53 @@ class DeclareDefaultUniformsTraverser : public TIntermTraverser ...@@ -90,6 +96,53 @@ class DeclareDefaultUniformsTraverser : public TIntermTraverser
bool mInDefaultUniform; bool mInDefaultUniform;
}; };
// This operation performs the viewport depth translation needed by Vulkan. In GL the viewport
// transformation is slightly different - see the GL 2.0 spec section "2.12.1 Controlling the
// Viewport". In Vulkan the corresponding spec section is currently "23.4. Coordinate
// Transformations".
// The equations reduce to an expression:
//
// z_vk = w_gl * (0.5 * z_gl + 0.5)
//
// where z_vk is the depth output of a Vulkan vertex shader and z_gl is the same for GL.
void AppendVertexShaderDepthCorrectionToMain(TIntermBlock *root, TSymbolTable *symbolTable)
{
// Create a symbol reference to "gl_Position"
const TVariable *position = BuiltInVariable::gl_Position();
TIntermSymbol *positionRef = new TIntermSymbol(position);
// Create a swizzle to "gl_Position.z"
TVector<int> swizzleOffsetZ;
swizzleOffsetZ.push_back(2);
TIntermSwizzle *positionZ = new TIntermSwizzle(positionRef, swizzleOffsetZ);
// Create a constant "0.5"
const TType *constantType = StaticType::GetBasic<TBasicType::EbtFloat>();
TConstantUnion *constantValue = new TConstantUnion();
constantValue->setFConst(0.5f);
TIntermConstantUnion *oneHalf = new TIntermConstantUnion(constantValue, *constantType);
// Create the expression "gl_Position.z * 0.5 + 0.5"
TIntermBinary *halfZ = new TIntermBinary(TOperator::EOpMul, positionZ, oneHalf);
TIntermBinary *halfZPlusHalf = new TIntermBinary(TOperator::EOpAdd, halfZ, oneHalf->deepCopy());
// Create a swizzle to "gl_Position.w"
TVector<int> swizzleOffsetW;
swizzleOffsetW.push_back(3);
TIntermSwizzle *positionW = new TIntermSwizzle(positionRef->deepCopy(), swizzleOffsetW);
// Create the expression "gl_Position.w * (gl_Position.z * 0.5 + 0.5)"
TIntermBinary *vulkanZ = new TIntermBinary(TOperator::EOpMul, positionW, halfZPlusHalf);
// Create the assignment "gl_Position.z = gl_Position.w * (gl_Position.z * 0.5 + 0.5)"
TIntermTyped *positionZLHS = positionZ->deepCopy();
TIntermBinary *assignment = new TIntermBinary(TOperator::EOpAssign, positionZLHS, vulkanZ);
// Append the assignment as a statement at the end of the shader.
RunAtTheEndOfShader(root, assignment, symbolTable);
}
} // anonymous namespace
TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec) TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec)
: TCompiler(type, spec, SH_GLSL_450_CORE_OUTPUT) : TCompiler(type, spec, SH_GLSL_450_CORE_OUTPUT)
{ {
...@@ -156,6 +209,13 @@ void TranslatorVulkan::translate(TIntermBlock *root, ...@@ -156,6 +209,13 @@ void TranslatorVulkan::translate(TIntermBlock *root,
sink << "layout(location = 0) out vec4 webgl_FragData[gl_MaxDrawBuffers];\n"; sink << "layout(location = 0) out vec4 webgl_FragData[gl_MaxDrawBuffers];\n";
} }
} }
else
{
ASSERT(getShaderType() == GL_VERTEX_SHADER);
// Append depth range translation to main.
AppendVertexShaderDepthCorrectionToMain(root, &getSymbolTable());
}
// Write translated shader. // Write translated shader.
TOutputVulkanGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), TOutputVulkanGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(),
......
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