зеркало из https://github.com/AvaloniaUI/angle.git
D3D11: Fix overlapping vertex shader signatures.
For the case of drawing with un-normalized integer vertex attributes, we need to do some dynamic conversion in the VS. However, each attribute can either be signed or unsigned, and our shader signature code would treat both as a match, giving rise to a warning in the D3D11 Debug runtime. It's unclear if this would give incorrect results, but it certainly should not produce a warning. BUG=angleproject:1329 Change-Id: I302d11b44e8a0ef981e89c181aefac5451a899b7 Reviewed-on: https://chromium-review.googlesource.com/329998 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Zhenyao Mo <zmo@chromium.org>
This commit is contained in:
Родитель
d8fa921572
Коммит
bdec2f4e7d
|
@ -508,25 +508,45 @@ ProgramD3D::VertexExecutable::~VertexExecutable()
|
|||
SafeDelete(mShaderExecutable);
|
||||
}
|
||||
|
||||
// static
|
||||
ProgramD3D::VertexExecutable::HLSLAttribType ProgramD3D::VertexExecutable::GetAttribType(
|
||||
GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GL_INT:
|
||||
return HLSLAttribType::SIGNED_INT;
|
||||
case GL_UNSIGNED_INT:
|
||||
return HLSLAttribType::UNSIGNED_INT;
|
||||
case GL_SIGNED_NORMALIZED:
|
||||
case GL_UNSIGNED_NORMALIZED:
|
||||
case GL_FLOAT:
|
||||
return HLSLAttribType::FLOAT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return HLSLAttribType::FLOAT;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void ProgramD3D::VertexExecutable::getSignature(RendererD3D *renderer,
|
||||
const gl::InputLayout &inputLayout,
|
||||
Signature *signatureOut)
|
||||
{
|
||||
signatureOut->resize(inputLayout.size());
|
||||
signatureOut->assign(inputLayout.size(), HLSLAttribType::FLOAT);
|
||||
|
||||
for (size_t index = 0; index < inputLayout.size(); ++index)
|
||||
{
|
||||
gl::VertexFormatType vertexFormatType = inputLayout[index];
|
||||
bool converted = false;
|
||||
if (vertexFormatType != gl::VERTEX_FORMAT_INVALID)
|
||||
{
|
||||
VertexConversionType conversionType =
|
||||
renderer->getVertexConversionType(vertexFormatType);
|
||||
converted = ((conversionType & VERTEX_CONVERT_GPU) != 0);
|
||||
}
|
||||
if (vertexFormatType == gl::VERTEX_FORMAT_INVALID)
|
||||
continue;
|
||||
|
||||
(*signatureOut)[index] = converted;
|
||||
VertexConversionType conversionType = renderer->getVertexConversionType(vertexFormatType);
|
||||
if ((conversionType & VERTEX_CONVERT_GPU) == 0)
|
||||
continue;
|
||||
|
||||
GLenum componentType = renderer->getVertexComponentType(vertexFormatType);
|
||||
(*signatureOut)[index] = GetAttribType(componentType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -535,9 +555,9 @@ bool ProgramD3D::VertexExecutable::matchesSignature(const Signature &signature)
|
|||
size_t limit = std::max(mSignature.size(), signature.size());
|
||||
for (size_t index = 0; index < limit; ++index)
|
||||
{
|
||||
// treat undefined indexes as 'not converted'
|
||||
bool a = index < signature.size() ? signature[index] : false;
|
||||
bool b = index < mSignature.size() ? mSignature[index] : false;
|
||||
// treat undefined indexes as FLOAT
|
||||
auto a = index < signature.size() ? signature[index] : HLSLAttribType::FLOAT;
|
||||
auto b = index < mSignature.size() ? mSignature[index] : HLSLAttribType::FLOAT;
|
||||
if (a != b)
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -254,7 +254,14 @@ class ProgramD3D : public ProgramImpl
|
|||
class VertexExecutable
|
||||
{
|
||||
public:
|
||||
typedef std::vector<bool> Signature;
|
||||
enum HLSLAttribType
|
||||
{
|
||||
FLOAT,
|
||||
UNSIGNED_INT,
|
||||
SIGNED_INT,
|
||||
};
|
||||
|
||||
typedef std::vector<HLSLAttribType> Signature;
|
||||
|
||||
VertexExecutable(const gl::InputLayout &inputLayout,
|
||||
const Signature &signature,
|
||||
|
@ -271,6 +278,8 @@ class ProgramD3D : public ProgramImpl
|
|||
ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
|
||||
|
||||
private:
|
||||
static HLSLAttribType GetAttribType(GLenum type);
|
||||
|
||||
gl::InputLayout mInputs;
|
||||
Signature mSignature;
|
||||
ShaderExecutableD3D *mShaderExecutable;
|
||||
|
|
|
@ -124,6 +124,24 @@ TEST_P(ProgramBinaryTest, FloatDynamicShaderSize)
|
|||
}
|
||||
}
|
||||
|
||||
// Tests that switching between signed and unsigned un-normalized data doesn't trigger a bug
|
||||
// in the D3D11 back-end.
|
||||
TEST_P(ProgramBinaryTest, DynamicShadersSignatureBug)
|
||||
{
|
||||
glUseProgram(mProgram);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
|
||||
|
||||
GLint attribLocation = glGetAttribLocation(mProgram, "inputAttribute");
|
||||
ASSERT_NE(-1, attribLocation);
|
||||
glEnableVertexAttribArray(attribLocation);
|
||||
|
||||
glVertexAttribPointer(attribLocation, 2, GL_BYTE, GL_FALSE, 0, nullptr);
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
|
||||
glVertexAttribPointer(attribLocation, 2, GL_UNSIGNED_BYTE, GL_FALSE, 0, nullptr);
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
}
|
||||
|
||||
// This tests the ability to successfully save and load a program binary.
|
||||
TEST_P(ProgramBinaryTest, SaveAndLoadBinary)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче