Commit 93a540fc by Geoff Lang Committed by Commit Bot

D3D11: Reset the TF binding offsets when glBeginTransformFeedback is called.

BUG=angleproject:2051 Change-Id: I09e8548ef76b7d824743d06b0bba21633bc40a24 Reviewed-on: https://chromium-review.googlesource.com/523671 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent bd044ed8
......@@ -8,8 +8,9 @@
#ifndef COMMON_VECTOR_UTILS_H_
#define COMMON_VECTOR_UTILS_H_
#include <cstddef>
#include <cmath>
#include <cstddef>
#include <ostream>
#include <type_traits>
namespace angle
......@@ -109,6 +110,9 @@ class VectorBase
Type mData[Dimension];
};
template <size_t Dimension, typename Type>
std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector);
template <typename Type>
class Vector<2, Type> : public VectorBase<2, Type>
{
......@@ -125,6 +129,9 @@ class Vector<2, Type> : public VectorBase<2, Type>
};
template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector);
template <typename Type>
class Vector<3, Type> : public VectorBase<3, Type>
{
public:
......@@ -145,6 +152,9 @@ class Vector<3, Type> : public VectorBase<3, Type>
};
template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector);
template <typename Type>
class Vector<4, Type> : public VectorBase<4, Type>
{
public:
......@@ -163,6 +173,9 @@ class Vector<4, Type> : public VectorBase<4, Type>
const Type &w() const { return this->mData[3]; }
};
template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector);
// Implementation of constructors and misc operations
template <size_t Dimension, typename Type>
......@@ -457,6 +470,22 @@ Type VectorBase<Dimension, Type>::dot(const VectorBase<Dimension, Type> &other)
}
template <size_t Dimension, typename Type>
std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector)
{
ostream << "[ ";
for (size_t elementIdx = 0; elementIdx < Dimension; elementIdx++)
{
if (elementIdx > 0)
{
ostream << ", ";
}
ostream << vector.data()[elementIdx];
}
ostream << " ]";
return ostream;
}
template <size_t Dimension, typename Type>
Vector<Dimension, Type> VectorBase<Dimension, Type>::normalized() const
{
static_assert(std::is_floating_point<Type>::value,
......@@ -465,12 +494,30 @@ Vector<Dimension, Type> VectorBase<Dimension, Type>::normalized() const
}
template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector)
{
return ostream << static_cast<const VectorBase<2, Type> &>(vector);
}
template <typename Type>
Vector<3, Type> Vector<3, Type>::cross(const Vector<3, Type> &other) const
{
return Vector<3, Type>(y() * other.z() - z() * other.y(), z() * other.x() - x() * other.z(),
x() * other.y() - y() * other.x());
}
template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector)
{
return ostream << static_cast<const VectorBase<3, Type> &>(vector);
}
template <typename Type>
std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector)
{
return ostream << static_cast<const VectorBase<4, Type> &>(vector);
}
} // namespace angle
#endif // COMMON_VECTOR_UTILS_H_
......@@ -31,6 +31,20 @@ TransformFeedback11::~TransformFeedback11()
void TransformFeedback11::begin(GLenum primitiveMode)
{
// Reset all the cached offsets to the binding offsets
mIsDirty = true;
for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++)
{
const auto &binding = mState.getIndexedBuffer(bindingIdx);
if (binding.get() != nullptr)
{
mBufferOffsets[bindingIdx] = static_cast<UINT>(binding.getOffset());
}
else
{
mBufferOffsets[bindingIdx] = 0;
}
}
}
void TransformFeedback11::end()
......
......@@ -877,6 +877,94 @@ TEST_P(TransformFeedbackTest, TwoUnreferencedInFragShader)
ASSERT_GL_NO_ERROR();
}
// Test that the transform feedback write offset is reset to the buffer's offset when
// glBeginTransformFeedback is called
TEST_P(TransformFeedbackTest, OffsetResetOnBeginTransformFeedback)
{
if (IsOSX() && IsAMD())
{
std::cout << "Test skipped on Mac AMD." << std::endl;
return;
}
if (IsAndroid())
{
std::cout << "Test skipped on Android." << std::endl;
return;
}
const std::string &vertexShaderSource =
"#version 300 es\n"
"in vec4 position;\n"
"out vec4 outAttrib;\n"
"void main() {"
" outAttrib = position;\n"
" gl_Position = vec4(0);\n"
"}";
const std::string &fragmentShaderSource =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 color;\n"
"void main() {\n"
" color = vec4(0);\n"
"}";
std::vector<std::string> tfVaryings;
tfVaryings.push_back("outAttrib");
mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource,
tfVaryings, GL_INTERLEAVED_ATTRIBS);
ASSERT_NE(0u, mProgram);
GLint positionLocation = glGetAttribLocation(mProgram, "position");
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBuffer);
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(Vector4) * 2, nullptr, GL_STREAM_DRAW);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer);
glUseProgram(mProgram);
Vector4 drawVertex0(4, 3, 2, 1);
Vector4 drawVertex1(8, 7, 6, 5);
Vector4 drawVertex2(12, 11, 10, 9);
glEnableVertexAttribArray(positionLocation);
glBeginTransformFeedback(GL_POINTS);
// Write vertex 0 at offset 0
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, false, 0, &drawVertex0);
glDrawArrays(GL_POINTS, 0, 1);
// Append vertex 1
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, false, 0, &drawVertex1);
glDrawArrays(GL_POINTS, 0, 1);
glEndTransformFeedback();
glBeginTransformFeedback(GL_POINTS);
// Write vertex 2 at offset 0
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, false, 0, &drawVertex2);
glDrawArrays(GL_POINTS, 0, 1);
glEndTransformFeedback();
const void *mapPointer =
glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(Vector4) * 2, GL_MAP_READ_BIT);
ASSERT_NE(nullptr, mapPointer);
const Vector4 *vecPointer = static_cast<const Vector4 *>(mapPointer);
ASSERT_EQ(drawVertex2, vecPointer[0]);
ASSERT_EQ(drawVertex1, vecPointer[1]);
glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
ASSERT_GL_NO_ERROR();
}
class TransformFeedbackLifetimeTest : public TransformFeedbackTest
{
protected:
......
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