Commit 0b4bc585 by Ben Clayton

Style: clang-format the tests source too

Move the `.clang-format` rule up one level from `./src` to `.`. Add a `.clang-format` file to `./third_party` that disables formatting. Update `./src/clang-format-all.sh` to include `./tests`. Format all source files in `./tests`. Bug: b/144825072 Change-Id: I01c7ae37a7b1fe8d63ee143107da8acefba20e76 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/39873 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAntonio Maiorano <amaiorano@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com>
parent 4be96b5f
SRC_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" SRC_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
ROOT_DIR="$( cd "${SRC_DIR}/.." >/dev/null 2>&1 && pwd )"
TESTS_DIR="$( cd "${ROOT_DIR}/tests" >/dev/null 2>&1 && pwd )"
CLANG_FORMAT=${CLANG_FORMAT:-clang-format} CLANG_FORMAT=${CLANG_FORMAT:-clang-format}
for DIR in "Device" "Pipeline" "Reactor" "System" "Vulkan" "WSI" for DIR in "${SRC_DIR}/Device" "${SRC_DIR}/Pipeline" "${SRC_DIR}/Reactor" "${SRC_DIR}/System" "${SRC_DIR}/Vulkan" "${SRC_DIR}/WSI" "${TESTS_DIR}"
do do
# Double clang-format, as it seems that one pass isn't always enough # Double clang-format, as it seems that one pass isn't always enough
find ${SRC_DIR}/${DIR} -iname "*.hpp" -o -iname "*.cpp" -o -iname "*.inl" | xargs ${CLANG_FORMAT} -i -style=file find ${DIR} -iname "*.hpp" -o -iname "*.cpp" -o -iname "*.inl" | xargs ${CLANG_FORMAT} -i -style=file
find ${SRC_DIR}/${DIR} -iname "*.hpp" -o -iname "*.cpp" -o -iname "*.inl" | xargs ${CLANG_FORMAT} -i -style=file find ${DIR} -iname "*.hpp" -o -iname "*.cpp" -o -iname "*.inl" | xargs ${CLANG_FORMAT} -i -style=file
done done
...@@ -15,18 +15,18 @@ ...@@ -15,18 +15,18 @@
// OpenGL ES unit tests that provide coverage for functionality not tested by // OpenGL ES unit tests that provide coverage for functionality not tested by
// the dEQP test suite. Also used as a smoke test. // the dEQP test suite. Also used as a smoke test.
#include "gtest/gtest.h"
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <EGL/egl.h> #include <EGL/egl.h>
#include <GL/glcorearb.h>
#include <GL/glext.h>
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
#include <GLES3/gl3.h> #include <GLES3/gl3.h>
#include <GL/glcorearb.h>
#include <GL/glext.h>
#if defined(_WIN32) #if defined(_WIN32)
#include <Windows.h> # include <Windows.h>
#endif #endif
#include <string.h> #include <string.h>
...@@ -42,15 +42,15 @@ class SwiftShaderTest : public testing::Test ...@@ -42,15 +42,15 @@ class SwiftShaderTest : public testing::Test
protected: protected:
void SetUp() override void SetUp() override
{ {
#if defined(_WIN32) && !defined(STANDALONE) #if defined(_WIN32) && !defined(STANDALONE)
// The DLLs are delay loaded (see BUILD.gn), so we can load // The DLLs are delay loaded (see BUILD.gn), so we can load
// the correct ones from Chrome's swiftshader subdirectory. // the correct ones from Chrome's swiftshader subdirectory.
HMODULE libEGL = LoadLibraryA("swiftshader\\libEGL.dll"); HMODULE libEGL = LoadLibraryA("swiftshader\\libEGL.dll");
EXPECT_NE((HMODULE)NULL, libEGL); EXPECT_NE((HMODULE)NULL, libEGL);
HMODULE libGLESv2 = LoadLibraryA("swiftshader\\libGLESv2.dll"); HMODULE libGLESv2 = LoadLibraryA("swiftshader\\libGLESv2.dll");
EXPECT_NE((HMODULE)NULL, libGLESv2); EXPECT_NE((HMODULE)NULL, libGLESv2);
#endif #endif
} }
void expectFramebufferColor(const unsigned char referenceColor[4], GLint x = 0, GLint y = 0) void expectFramebufferColor(const unsigned char referenceColor[4], GLint x = 0, GLint y = 0)
...@@ -113,11 +113,10 @@ protected: ...@@ -113,11 +113,10 @@ protected:
eglBindAPI(EGL_OPENGL_ES_API); eglBindAPI(EGL_OPENGL_ES_API);
EXPECT_NO_EGL_ERROR(); EXPECT_NO_EGL_ERROR();
const EGLint configAttributes[] = const EGLint configAttributes[] = {
{ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_ALPHA_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_NONE EGL_NONE
}; };
...@@ -145,8 +144,7 @@ protected: ...@@ -145,8 +144,7 @@ protected:
EXPECT_TRUE(surfaceType & EGL_WINDOW_BIT); EXPECT_TRUE(surfaceType & EGL_WINDOW_BIT);
} }
EGLint surfaceAttributes[] = EGLint surfaceAttributes[] = {
{
EGL_WIDTH, 1920, EGL_WIDTH, 1920,
EGL_HEIGHT, 1080, EGL_HEIGHT, 1080,
EGL_NONE EGL_NONE
...@@ -156,8 +154,7 @@ protected: ...@@ -156,8 +154,7 @@ protected:
EXPECT_NO_EGL_ERROR(); EXPECT_NO_EGL_ERROR();
EXPECT_NE(EGL_NO_SURFACE, surface); EXPECT_NE(EGL_NO_SURFACE, surface);
EGLint contextAttributes[] = EGLint contextAttributes[] = {
{
EGL_CONTEXT_CLIENT_VERSION, version, EGL_CONTEXT_CLIENT_VERSION, version,
EGL_NONE EGL_NONE
}; };
...@@ -248,7 +245,8 @@ protected: ...@@ -248,7 +245,8 @@ protected:
GLint compileStatus = 0; GLint compileStatus = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
glGetShaderInfoLog(shader, sizeof(buf), nullptr, buf); glGetShaderInfoLog(shader, sizeof(buf), nullptr, buf);
EXPECT_EQ(compileStatus, GL_TRUE) << "Compile status: " << std::endl << buf; EXPECT_EQ(compileStatus, GL_TRUE) << "Compile status: " << std::endl
<< buf;
return shader; return shader;
} }
...@@ -275,13 +273,13 @@ protected: ...@@ -275,13 +273,13 @@ protected:
GLint linkStatus = 0; GLint linkStatus = 0;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
glGetProgramInfoLog(program, sizeof(buf), nullptr, buf); glGetProgramInfoLog(program, sizeof(buf), nullptr, buf);
EXPECT_NE(linkStatus, 0) << "Link status: " << std::endl << buf; EXPECT_NE(linkStatus, 0) << "Link status: " << std::endl
<< buf;
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
} }
ProgramHandles createProgram(const std::string &vs, const std::string &fs)
ProgramHandles createProgram(const std::string& vs, const std::string& fs)
{ {
ProgramHandles ph; ProgramHandles ph;
ph.vertexShader = MakeShader(vs, GL_VERTEX_SHADER); ph.vertexShader = MakeShader(vs, GL_VERTEX_SHADER);
...@@ -292,7 +290,7 @@ protected: ...@@ -292,7 +290,7 @@ protected:
return ph; return ph;
} }
void deleteProgram(const ProgramHandles& ph) void deleteProgram(const ProgramHandles &ph)
{ {
glDeleteShader(ph.fragmentShader); glDeleteShader(ph.fragmentShader);
glDeleteShader(ph.vertexShader); glDeleteShader(ph.vertexShader);
...@@ -301,7 +299,7 @@ protected: ...@@ -301,7 +299,7 @@ protected:
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
} }
void drawQuad(GLuint program, const char* textureName = nullptr) void drawQuad(GLuint program, const char *textureName = nullptr)
{ {
GLint prevProgram = 0; GLint prevProgram = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, &prevProgram); glGetIntegerv(GL_CURRENT_PROGRAM, &prevProgram);
...@@ -319,12 +317,12 @@ protected: ...@@ -319,12 +317,12 @@ protected:
glUniform1i(location, 0); glUniform1i(location, 0);
} }
float vertices[18] = { -1.0f, 1.0f, 0.5f, float vertices[18] = { -1.0f, 1.0f, 0.5f,
-1.0f, -1.0f, 0.5f, -1.0f, -1.0f, 0.5f,
1.0f, -1.0f, 0.5f, 1.0f, -1.0f, 0.5f,
-1.0f, 1.0f, 0.5f, -1.0f, 1.0f, 0.5f,
1.0f, -1.0f, 0.5f, 1.0f, -1.0f, 0.5f,
1.0f, 1.0f, 0.5f }; 1.0f, 1.0f, 0.5f };
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, vertices); glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(posLoc); glEnableVertexAttribArray(posLoc);
...@@ -337,10 +335,11 @@ protected: ...@@ -337,10 +335,11 @@ protected:
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
} }
std::string replace(std::string str, const std::string& substr, const std::string& replacement) std::string replace(std::string str, const std::string &substr, const std::string &replacement)
{ {
size_t pos = 0; size_t pos = 0;
while((pos = str.find(substr, pos)) != std::string::npos) { while((pos = str.find(substr, pos)) != std::string::npos)
{
str.replace(pos, substr.length(), replacement); str.replace(pos, substr.length(), replacement);
pos += replacement.length(); pos += replacement.length();
} }
...@@ -352,7 +351,7 @@ protected: ...@@ -352,7 +351,7 @@ protected:
Initialize(3, false); Initialize(3, false);
std::string vs = std::string vs =
R"(#version 300 es R"(#version 300 es
in vec4 position; in vec4 position;
out float unfoldable; out float unfoldable;
$INSERT $INSERT
...@@ -364,7 +363,7 @@ protected: ...@@ -364,7 +363,7 @@ protected:
})"; })";
std::string fs = std::string fs =
R"(#version 300 es R"(#version 300 es
precision mediump float; precision mediump float;
in float unfoldable; in float unfoldable;
out vec4 fragColor; out vec4 fragColor;
...@@ -438,7 +437,7 @@ protected: ...@@ -438,7 +437,7 @@ protected:
void checkCompileFails(std::string s) void checkCompileFails(std::string s)
{ {
std::string vs = std::string vs =
R"(#version 300 es R"(#version 300 es
in vec4 position; in vec4 position;
out float unfoldable; out float unfoldable;
$INSERT $INSERT
...@@ -450,7 +449,7 @@ protected: ...@@ -450,7 +449,7 @@ protected:
})"; })";
std::string fs = std::string fs =
R"(#version 300 es R"(#version 300 es
precision mediump float; precision mediump float;
in float unfoldable; in float unfoldable;
out vec4 fragColor; out vec4 fragColor;
...@@ -486,16 +485,16 @@ TEST_F(SwiftShaderTest, Initalization) ...@@ -486,16 +485,16 @@ TEST_F(SwiftShaderTest, Initalization)
const GLubyte *glVendor = glGetString(GL_VENDOR); const GLubyte *glVendor = glGetString(GL_VENDOR);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
EXPECT_STREQ("Google Inc.", (const char*)glVendor); EXPECT_STREQ("Google Inc.", (const char *)glVendor);
const GLubyte *glRenderer = glGetString(GL_RENDERER); const GLubyte *glRenderer = glGetString(GL_RENDERER);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
EXPECT_STREQ("Google SwiftShader", (const char*)glRenderer); EXPECT_STREQ("Google SwiftShader", (const char *)glRenderer);
// SwiftShader return an OpenGL ES 3.0 context when a 2.0 context is requested, as allowed by the spec. // SwiftShader return an OpenGL ES 3.0 context when a 2.0 context is requested, as allowed by the spec.
const GLubyte *glVersion = glGetString(GL_VERSION); const GLubyte *glVersion = glGetString(GL_VERSION);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
EXPECT_THAT((const char*)glVersion, testing::HasSubstr("OpenGL ES 3.0 SwiftShader ")); EXPECT_THAT((const char *)glVersion, testing::HasSubstr("OpenGL ES 3.0 SwiftShader "));
Uninitialize(); Uninitialize();
} }
...@@ -535,7 +534,7 @@ TEST_F(SwiftShaderTest, UnrollLoop) ...@@ -535,7 +534,7 @@ TEST_F(SwiftShaderTest, UnrollLoop)
unsigned char green[4] = { 0, 255, 0, 255 }; unsigned char green[4] = { 0, 255, 0, 255 };
const std::string vs = const std::string vs =
R"(#version 300 es R"(#version 300 es
in vec4 position; in vec4 position;
out vec4 color; out vec4 color;
void main() void main()
...@@ -548,7 +547,7 @@ TEST_F(SwiftShaderTest, UnrollLoop) ...@@ -548,7 +547,7 @@ TEST_F(SwiftShaderTest, UnrollLoop)
})"; })";
const std::string fs = const std::string fs =
R"(#version 300 es R"(#version 300 es
precision mediump float; precision mediump float;
in vec4 color; in vec4 color;
out vec4 fragColor; out vec4 fragColor;
...@@ -595,7 +594,7 @@ TEST_F(SwiftShaderTest, DynamicLoop) ...@@ -595,7 +594,7 @@ TEST_F(SwiftShaderTest, DynamicLoop)
Initialize(3, false); Initialize(3, false);
const std::string vs = const std::string vs =
R"(#version 300 es R"(#version 300 es
in vec4 position; in vec4 position;
out vec4 color; out vec4 color;
void main() void main()
...@@ -609,7 +608,7 @@ TEST_F(SwiftShaderTest, DynamicLoop) ...@@ -609,7 +608,7 @@ TEST_F(SwiftShaderTest, DynamicLoop)
})"; })";
const std::string fs = const std::string fs =
R"(#version 300 es R"(#version 300 es
precision mediump float; precision mediump float;
in vec4 color; in vec4 color;
out vec4 fragColor; out vec4 fragColor;
...@@ -659,7 +658,7 @@ TEST_F(SwiftShaderTest, DynamicIndexing) ...@@ -659,7 +658,7 @@ TEST_F(SwiftShaderTest, DynamicIndexing)
Initialize(3, false); Initialize(3, false);
const std::string vs = const std::string vs =
R"(#version 300 es R"(#version 300 es
in vec4 position; in vec4 position;
out float color[4]; out float color[4];
void main() void main()
...@@ -674,7 +673,7 @@ TEST_F(SwiftShaderTest, DynamicIndexing) ...@@ -674,7 +673,7 @@ TEST_F(SwiftShaderTest, DynamicIndexing)
})"; })";
const std::string fs = const std::string fs =
R"(#version 300 es R"(#version 300 es
precision mediump float; precision mediump float;
in float color[4]; in float color[4];
out vec4 fragColor; out vec4 fragColor;
...@@ -715,7 +714,7 @@ TEST_F(SwiftShaderTest, AttributeLocation) ...@@ -715,7 +714,7 @@ TEST_F(SwiftShaderTest, AttributeLocation)
Initialize(3, false); Initialize(3, false);
const std::string vs = const std::string vs =
R"(#version 300 es R"(#version 300 es
layout(location = 0) in vec4 a0; // Explicitly bound in GLSL layout(location = 0) in vec4 a0; // Explicitly bound in GLSL
layout(location = 2) in vec4 a2; // Explicitly bound in GLSL layout(location = 2) in vec4 a2; // Explicitly bound in GLSL
in vec4 a5; // Bound to location 5 by API in vec4 a5; // Bound to location 5 by API
...@@ -737,7 +736,7 @@ TEST_F(SwiftShaderTest, AttributeLocation) ...@@ -737,7 +736,7 @@ TEST_F(SwiftShaderTest, AttributeLocation)
})"; })";
const std::string fs = const std::string fs =
R"(#version 300 es R"(#version 300 es
precision mediump float; precision mediump float;
in vec4 color; in vec4 color;
out vec4 fragColor; out vec4 fragColor;
...@@ -775,18 +774,18 @@ TEST_F(SwiftShaderTest, AttributeLocation) ...@@ -775,18 +774,18 @@ TEST_F(SwiftShaderTest, AttributeLocation)
EXPECT_NE(linkStatus, 0); EXPECT_NE(linkStatus, 0);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
float vertices[6][3] = { { -1.0f, 1.0f, 0.5f }, float vertices[6][3] = { { -1.0f, 1.0f, 0.5f },
{ -1.0f, -1.0f, 0.5f }, { -1.0f, -1.0f, 0.5f },
{ 1.0f, -1.0f, 0.5f }, { 1.0f, -1.0f, 0.5f },
{ -1.0f, 1.0f, 0.5f }, { -1.0f, 1.0f, 0.5f },
{ 1.0f, -1.0f, 0.5f }, { 1.0f, -1.0f, 0.5f },
{ 1.0f, 1.0f, 0.5f } }; { 1.0f, 1.0f, 0.5f } };
float attributes[5][4] = { { 1.0f, 2.0f, 3.0f, 4.0f }, float attributes[5][4] = { { 1.0f, 2.0f, 3.0f, 4.0f },
{ 5.0f, 6.0f, 7.0f, 8.0f }, { 5.0f, 6.0f, 7.0f, 8.0f },
{ 9.0f, 10.0f, 11.0f, 12.0f }, { 9.0f, 10.0f, 11.0f, 12.0f },
{ 13.0f, 14.0f, 15.0f, 16.0f }, { 13.0f, 14.0f, 15.0f, 16.0f },
{ 17.0f, 18.0f, 19.0f, 20.0f } }; { 17.0f, 18.0f, 19.0f, 20.0f } };
GLint a0 = glGetAttribLocation(ph.program, "a0"); GLint a0 = glGetAttribLocation(ph.program, "a0");
EXPECT_EQ(a0, 0); EXPECT_EQ(a0, 0);
...@@ -802,7 +801,7 @@ TEST_F(SwiftShaderTest, AttributeLocation) ...@@ -802,7 +801,7 @@ TEST_F(SwiftShaderTest, AttributeLocation)
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
GLint a3 = glGetAttribLocation(ph.program, "a3"); GLint a3 = glGetAttribLocation(ph.program, "a3");
EXPECT_EQ(a3, 3); // Note: implementation specific EXPECT_EQ(a3, 3); // Note: implementation specific
glVertexAttribPointer(a3 + 0, 2, GL_FLOAT, GL_FALSE, 0, &attributes[1][0]); glVertexAttribPointer(a3 + 0, 2, GL_FLOAT, GL_FALSE, 0, &attributes[1][0]);
glVertexAttribPointer(a3 + 1, 2, GL_FLOAT, GL_FALSE, 0, &attributes[1][2]); glVertexAttribPointer(a3 + 1, 2, GL_FLOAT, GL_FALSE, 0, &attributes[1][2]);
glVertexAttribDivisor(a3 + 0, 1); glVertexAttribDivisor(a3 + 0, 1);
...@@ -819,14 +818,14 @@ TEST_F(SwiftShaderTest, AttributeLocation) ...@@ -819,14 +818,14 @@ TEST_F(SwiftShaderTest, AttributeLocation)
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
GLint a1 = glGetAttribLocation(ph.program, "a1"); GLint a1 = glGetAttribLocation(ph.program, "a1");
EXPECT_EQ(a1, 1); // Note: implementation specific EXPECT_EQ(a1, 1); // Note: implementation specific
glVertexAttribPointer(a1, 4, GL_FLOAT, GL_FALSE, 0, attributes[3]); glVertexAttribPointer(a1, 4, GL_FLOAT, GL_FALSE, 0, attributes[3]);
glVertexAttribDivisor(a1, 1); glVertexAttribDivisor(a1, 1);
glEnableVertexAttribArray(a1); glEnableVertexAttribArray(a1);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
GLint a6 = glGetAttribLocation(ph.program, "a6"); GLint a6 = glGetAttribLocation(ph.program, "a6");
EXPECT_EQ(a6, 6); // Note: implementation specific EXPECT_EQ(a6, 6); // Note: implementation specific
glVertexAttribPointer(a6, 4, GL_FLOAT, GL_FALSE, 0, attributes[4]); glVertexAttribPointer(a6, 4, GL_FLOAT, GL_FALSE, 0, attributes[4]);
glVertexAttribDivisor(a6, 1); glVertexAttribDivisor(a6, 1);
glEnableVertexAttribArray(a6); glEnableVertexAttribArray(a6);
...@@ -850,7 +849,7 @@ TEST_F(SwiftShaderTest, AttributeLocation) ...@@ -850,7 +849,7 @@ TEST_F(SwiftShaderTest, AttributeLocation)
TEST_F(SwiftShaderTest, NegativeLocation) TEST_F(SwiftShaderTest, NegativeLocation)
{ {
const std::string vs = const std::string vs =
R"(#version 300 es R"(#version 300 es
layout(location = 0x86868686u) in vec4 a0; // Explicitly bound in GLSL layout(location = 0x86868686u) in vec4 a0; // Explicitly bound in GLSL
layout(location = 0x96969696u) in vec4 a2; // Explicitly bound in GLSL layout(location = 0x96969696u) in vec4 a2; // Explicitly bound in GLSL
in vec4 a5; // Bound to location 5 by API in vec4 a5; // Bound to location 5 by API
...@@ -872,7 +871,7 @@ TEST_F(SwiftShaderTest, NegativeLocation) ...@@ -872,7 +871,7 @@ TEST_F(SwiftShaderTest, NegativeLocation)
})"; })";
const std::string fs = const std::string fs =
R"(#version 300 es R"(#version 300 es
precision mediump float; precision mediump float;
in vec4 color; in vec4 color;
layout(location = 0xA6A6A6A6u) out vec4 fragColor; layout(location = 0xA6A6A6A6u) out vec4 fragColor;
...@@ -956,22 +955,22 @@ TEST_F(SwiftShaderTest, CopyTexImage) ...@@ -956,22 +955,22 @@ TEST_F(SwiftShaderTest, CopyTexImage)
TEST_F(SwiftShaderTest, CopyTexImageFromPixelBuffer) TEST_F(SwiftShaderTest, CopyTexImageFromPixelBuffer)
{ {
Initialize(3, false); Initialize(3, false);
const GLuint red = 0xff0000ff; const GLuint red = 0xff0000ff;
const GLuint green = 0x00ff00ff; const GLuint green = 0x00ff00ff;
const GLuint blue = 0x0000ffff; const GLuint blue = 0x0000ffff;
// Set up texture // Set up texture
GLuint texture = 0; GLuint texture = 0;
glGenTextures(1, &texture); glGenTextures(1, &texture);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
GLuint tex_data[4][4] = { GLuint tex_data[4][4] = {
{red, red, red, red}, { red, red, red, red },
{red, red, red, red}, { red, red, red, red },
{red, red, red, red}, { red, red, red, red },
{red, red, red, red} { red, red, red, red }
}; };
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void *) tex_data[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void *)tex_data[0]);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
// Set up Pixel Buffer Object // Set up Pixel Buffer Object
GLuint pixelBuffer = 0; GLuint pixelBuffer = 0;
...@@ -982,12 +981,12 @@ TEST_F(SwiftShaderTest, CopyTexImageFromPixelBuffer) ...@@ -982,12 +981,12 @@ TEST_F(SwiftShaderTest, CopyTexImageFromPixelBuffer)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
GLuint pixel_data[4][4] = { GLuint pixel_data[4][4] = {
{blue, blue, green, green}, { blue, blue, green, green },
{blue, blue, green, green}, { blue, blue, green, green },
{blue, blue, green, green}, { blue, blue, green, green },
{blue, blue, green, green}, { blue, blue, green, green },
}; };
glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(pixel_data), (void *) pixel_data, GL_STREAM_DRAW); glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(pixel_data), (void *)pixel_data, GL_STREAM_DRAW);
// Should set the 2-rightmost columns of the currently bound texture to the // Should set the 2-rightmost columns of the currently bound texture to the
// 2-rightmost columns of the PBO; // 2-rightmost columns of the PBO;
GLintptr offset = 2 * sizeof(GLuint); GLintptr offset = 2 * sizeof(GLuint);
...@@ -1000,24 +999,24 @@ TEST_F(SwiftShaderTest, CopyTexImageFromPixelBuffer) ...@@ -1000,24 +999,24 @@ TEST_F(SwiftShaderTest, CopyTexImageFromPixelBuffer)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
unsigned int color[4][4] = { unsigned int color[4][4] = {
{0, 0, 0, 0}, { 0, 0, 0, 0 },
{0, 0, 0, 0}, { 0, 0, 0, 0 },
{0, 0, 0, 0}, { 0, 0, 0, 0 },
{0, 0, 0, 0} { 0, 0, 0, 0 }
}; };
glReadPixels(0, 0, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, &color); glReadPixels(0, 0, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, &color);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
bool allEqual = true; bool allEqual = true;
for (int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
for (int j = 0; j < 2; j++) for(int j = 0; j < 2; j++)
{ {
allEqual = allEqual && (color[i][j] == tex_data[i][j]); allEqual = allEqual && (color[i][j] == tex_data[i][j]);
allEqual = allEqual && (color[i][j+2] == pixel_data[i][j+2]); allEqual = allEqual && (color[i][j + 2] == pixel_data[i][j + 2]);
if (!allEqual) if(!allEqual)
break; break;
} }
if (!allEqual) if(!allEqual)
break; break;
} }
EXPECT_EQ(allEqual, true); EXPECT_EQ(allEqual, true);
...@@ -1074,7 +1073,7 @@ TEST_F(SwiftShaderTest, MatrixInStruct) ...@@ -1074,7 +1073,7 @@ TEST_F(SwiftShaderTest, MatrixInStruct)
Initialize(2, false); Initialize(2, false);
const std::string fs = const std::string fs =
R"(#version 100 R"(#version 100
precision mediump float; precision mediump float;
struct S struct S
{ {
...@@ -1106,7 +1105,7 @@ TEST_F(SwiftShaderTest, SamplerArrayInStructArrayAsFunctionArg) ...@@ -1106,7 +1105,7 @@ TEST_F(SwiftShaderTest, SamplerArrayInStructArrayAsFunctionArg)
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
const std::string vs = const std::string vs =
R"(#version 300 es R"(#version 300 es
in vec4 position; in vec4 position;
void main() void main()
{ {
...@@ -1114,7 +1113,7 @@ TEST_F(SwiftShaderTest, SamplerArrayInStructArrayAsFunctionArg) ...@@ -1114,7 +1113,7 @@ TEST_F(SwiftShaderTest, SamplerArrayInStructArrayAsFunctionArg)
})"; })";
const std::string fs = const std::string fs =
R"(#version 300 es R"(#version 300 es
precision mediump float; precision mediump float;
struct SamplerStruct{ sampler2D tex[2]; }; struct SamplerStruct{ sampler2D tex[2]; };
vec4 doSample(in SamplerStruct s[2]) vec4 doSample(in SamplerStruct s[2])
...@@ -1156,7 +1155,7 @@ TEST_F(SwiftShaderTest, AtanCornerCases) ...@@ -1156,7 +1155,7 @@ TEST_F(SwiftShaderTest, AtanCornerCases)
Initialize(3, false); Initialize(3, false);
const std::string vs = const std::string vs =
R"(#version 300 es R"(#version 300 es
in vec4 position; in vec4 position;
void main() void main()
{ {
...@@ -1164,7 +1163,7 @@ TEST_F(SwiftShaderTest, AtanCornerCases) ...@@ -1164,7 +1163,7 @@ TEST_F(SwiftShaderTest, AtanCornerCases)
})"; })";
const std::string fs = const std::string fs =
R"(#version 300 es R"(#version 300 es
precision mediump float; precision mediump float;
const float kPI = 3.14159265358979323846; const float kPI = 3.14159265358979323846;
uniform float positive_value; uniform float positive_value;
...@@ -1212,7 +1211,7 @@ TEST_F(SwiftShaderTest, TransformFeedback_DrawArraysInstanced) ...@@ -1212,7 +1211,7 @@ TEST_F(SwiftShaderTest, TransformFeedback_DrawArraysInstanced)
Initialize(3, false); Initialize(3, false);
std::string fs = std::string fs =
R"(#version 300 es R"(#version 300 es
in mediump vec2 vary; in mediump vec2 vary;
out mediump vec4 color; out mediump vec4 color;
void main() void main()
...@@ -1220,7 +1219,7 @@ TEST_F(SwiftShaderTest, TransformFeedback_DrawArraysInstanced) ...@@ -1220,7 +1219,7 @@ TEST_F(SwiftShaderTest, TransformFeedback_DrawArraysInstanced)
color = vec4(vary, 0.0, 1.0); color = vec4(vary, 0.0, 1.0);
})"; })";
std::string vs = std::string vs =
R"(#version 300 es R"(#version 300 es
layout(location=0) in mediump vec2 pos; layout(location=0) in mediump vec2 pos;
out mediump vec2 vary; out mediump vec2 vary;
void main() void main()
...@@ -1249,14 +1248,14 @@ TEST_F(SwiftShaderTest, TransformFeedback_BadViewport) ...@@ -1249,14 +1248,14 @@ TEST_F(SwiftShaderTest, TransformFeedback_BadViewport)
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1 << 12, nullptr, GL_STATIC_DRAW); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1 << 12, nullptr, GL_STATIC_DRAW);
std::string vsSource = std::string vsSource =
R"(#version 300 es R"(#version 300 es
in vec4 a_position; in vec4 a_position;
void main() void main()
{ {
gl_Position = a_position; gl_Position = a_position;
})"; })";
std::string fsSource = std::string fsSource =
R"(#version 300 es R"(#version 300 es
precision highp float; precision highp float;
out vec4 my_FragColor; out vec4 my_FragColor;
void main() void main()
...@@ -1271,7 +1270,7 @@ TEST_F(SwiftShaderTest, TransformFeedback_BadViewport) ...@@ -1271,7 +1270,7 @@ TEST_F(SwiftShaderTest, TransformFeedback_BadViewport)
GLuint program = MakeProgram(vs, fs); GLuint program = MakeProgram(vs, fs);
glTransformFeedbackVaryings(program, 1, glTransformFeedbackVaryings(program, 1,
&varyings[0], GL_INTERLEAVED_ATTRIBS); &varyings[0], GL_INTERLEAVED_ATTRIBS);
LinkProgram(program); LinkProgram(program);
glUseProgram(program); glUseProgram(program);
...@@ -1286,12 +1285,24 @@ TEST_F(SwiftShaderTest, TransformFeedback_BadViewport) ...@@ -1286,12 +1285,24 @@ TEST_F(SwiftShaderTest, TransformFeedback_BadViewport)
GLint positionLocation = glGetAttribLocation(program, "a_position"); GLint positionLocation = glGetAttribLocation(program, "a_position");
GLfloat quadVertices[] = { GLfloat quadVertices[] = {
-1.0f, 1.0f, 0.5f, -1.0f,
-1.0f, -1.0f, 0.5f, 1.0f,
1.0f, -1.0f, 0.5f, 0.5f,
-1.0f, 1.0f, 0.5f, -1.0f,
1.0f, -1.0f, 0.5f, -1.0f,
1.0f, 1.0f, 0.5f, 0.5f,
1.0f,
-1.0f,
0.5f,
-1.0f,
1.0f,
0.5f,
1.0f,
-1.0f,
0.5f,
1.0f,
1.0f,
0.5f,
}; };
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
...@@ -1345,12 +1356,11 @@ TEST_F(SwiftShaderTest, OutOfMemory) ...@@ -1345,12 +1356,11 @@ TEST_F(SwiftShaderTest, OutOfMemory)
TEST_F(SwiftShaderTest, ViewportBounds) TEST_F(SwiftShaderTest, ViewportBounds)
{ {
auto doRenderWithViewportSettings = [&](GLint x, GLint y, GLsizei w, GLsizei h) auto doRenderWithViewportSettings = [&](GLint x, GLint y, GLsizei w, GLsizei h) {
{
Initialize(3, false); Initialize(3, false);
std::string vs = std::string vs =
R"(#version 300 es R"(#version 300 es
in vec4 position; in vec4 position;
out float unfoldable; out float unfoldable;
void main() void main()
...@@ -1360,7 +1370,7 @@ TEST_F(SwiftShaderTest, ViewportBounds) ...@@ -1360,7 +1370,7 @@ TEST_F(SwiftShaderTest, ViewportBounds)
})"; })";
std::string fs = std::string fs =
R"(#version 300 es R"(#version 300 es
precision mediump float; precision mediump float;
in float unfoldable; in float unfoldable;
out vec4 fragColor; out vec4 fragColor;
...@@ -1598,14 +1608,14 @@ TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangle) ...@@ -1598,14 +1608,14 @@ TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangle)
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
const std::string vs = const std::string vs =
R"(attribute vec4 position; R"(attribute vec4 position;
void main() void main()
{ {
gl_Position = vec4(position.xy, 0.0, 1.0); gl_Position = vec4(position.xy, 0.0, 1.0);
})"; })";
const std::string fs = const std::string fs =
R"(#extension GL_ARB_texture_rectangle : require R"(#extension GL_ARB_texture_rectangle : require
precision mediump float; precision mediump float;
uniform sampler2DRect tex; uniform sampler2DRect tex;
void main() void main()
...@@ -1649,7 +1659,7 @@ TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangleESSL3) ...@@ -1649,7 +1659,7 @@ TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangleESSL3)
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
const std::string vs = const std::string vs =
R"(#version 300 es R"(#version 300 es
in vec4 position; in vec4 position;
void main() void main()
{ {
...@@ -1657,7 +1667,7 @@ TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangleESSL3) ...@@ -1657,7 +1667,7 @@ TEST_F(SwiftShaderTest, TextureRectangle_SamplingFromRectangleESSL3)
})"; })";
const std::string fs = const std::string fs =
R"(#version 300 es R"(#version 300 es
#extension GL_ARB_texture_rectangle : require #extension GL_ARB_texture_rectangle : require
precision mediump float; precision mediump float;
uniform sampler2DRect tex; uniform sampler2DRect tex;
...@@ -1808,21 +1818,21 @@ TEST_F(SwiftShaderTest, BlitTest) ...@@ -1808,21 +1818,21 @@ TEST_F(SwiftShaderTest, BlitTest)
{ {
Initialize(3, false); Initialize(3, false);
GLuint fbos[] = {0, 0}; GLuint fbos[] = { 0, 0 };
glGenFramebuffers(2, fbos); glGenFramebuffers(2, fbos);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]); glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[0]);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbos[1]);
GLuint textures[] = {0, 0}; GLuint textures[] = { 0, 0 };
glGenTextures(2, textures); glGenTextures(2, textures);
glBindTexture(GL_TEXTURE_2D, textures[0]); glBindTexture(GL_TEXTURE_2D, textures[0]);
unsigned char red[4][4] = { unsigned char red[4][4] = {
{255, 0, 0, 255}, { 255, 0, 0, 255 },
{255, 0, 0, 255}, { 255, 0, 0, 255 },
{255, 0, 0, 255}, { 255, 0, 0, 255 },
{255, 0, 0, 255} { 255, 0, 0, 255 }
}; };
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, red); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, red);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
...@@ -1832,10 +1842,10 @@ TEST_F(SwiftShaderTest, BlitTest) ...@@ -1832,10 +1842,10 @@ TEST_F(SwiftShaderTest, BlitTest)
glBindTexture(GL_TEXTURE_2D, textures[1]); glBindTexture(GL_TEXTURE_2D, textures[1]);
unsigned char black[4][4] = { unsigned char black[4][4] = {
{0, 0, 0, 255}, { 0, 0, 0, 255 },
{0, 0, 0, 255}, { 0, 0, 0, 255 },
{0, 0, 0, 255}, { 0, 0, 0, 255 },
{0, 0, 0, 255} { 0, 0, 0, 255 }
}; };
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, black); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
...@@ -1847,39 +1857,39 @@ TEST_F(SwiftShaderTest, BlitTest) ...@@ -1847,39 +1857,39 @@ TEST_F(SwiftShaderTest, BlitTest)
EXPECT_EQ(red[0][1], black[0][1]); EXPECT_EQ(red[0][1], black[0][1]);
// Check that glBlitFramebuffer doesn't crash with ugly input. // Check that glBlitFramebuffer doesn't crash with ugly input.
const int big = (int) 2e9; const int big = (int)2e9;
const int small = 200; const int small = 200;
const int neg_small = -small; const int neg_small = -small;
const int neg_big = -big; const int neg_big = -big;
int max = 0x7fffffff; int max = 0x7fffffff;
int data[][8] = { int data[][8] = {
// sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1 // sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1
{0, 0, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, 0, 0 },
{-1, -1, -1, -1, -1, -1, -1, -1}, { -1, -1, -1, -1, -1, -1, -1, -1 },
{1, 1, 1, 1, 1, 1, 1, 1}, { 1, 1, 1, 1, 1, 1, 1, 1 },
{-1, -1, 1, 1, -1, -1, 1, 1}, { -1, -1, 1, 1, -1, -1, 1, 1 },
{0, 0, 127, (int) 2e9, 10, 10, 200, 200}, { 0, 0, 127, (int)2e9, 10, 10, 200, 200 },
{-2, -2, 127, 2147483470, 10, 10, 200, 200}, { -2, -2, 127, 2147483470, 10, 10, 200, 200 },
{big, small, small, big, big, big, small, small}, { big, small, small, big, big, big, small, small },
{neg_small, small, neg_small, neg_small, neg_small, big, small}, { neg_small, small, neg_small, neg_small, neg_small, big, small },
{big, big-1, big-2, big-3, big-4, big-5, big-6, big-7}, { big, big - 1, big - 2, big - 3, big - 4, big - 5, big - 6, big - 7 },
{big, neg_big, neg_big, big, small, big, 0, neg_small}, { big, neg_big, neg_big, big, small, big, 0, neg_small },
{323479648, 21931, 1769809195, 32733, 0, 0, -161640504, 32766}, { 323479648, 21931, 1769809195, 32733, 0, 0, -161640504, 32766 },
{0, 0, max, max, 0, 0, 8, 8}, { 0, 0, max, max, 0, 0, 8, 8 },
{0, 0, 8, 8, 0, 0, max, max}, { 0, 0, 8, 8, 0, 0, max, max },
{0, 0, max, max, 0, 0, max, max}, { 0, 0, max, max, 0, 0, max, max },
{-1, -1, max, max, 0, 0, 8, 8}, { -1, -1, max, max, 0, 0, 8, 8 },
{0, 0, 8, 8, -1, -1, max, max}, { 0, 0, 8, 8, -1, -1, max, max },
{-1, -1, max, max, -1, -1, max, max}, { -1, -1, max, max, -1, -1, max, max },
{-max-1, -max-1, max, max, -max-1, -max-1, max, max} { -max - 1, -max - 1, max, max, -max - 1, -max - 1, max, max }
}; };
for (int i = 0; i < (int) (sizeof(data)/sizeof(data[0])); i++) for(int i = 0; i < (int)(sizeof(data) / sizeof(data[0])); i++)
{ {
glBlitFramebuffer( glBlitFramebuffer(
data[i][0], data[i][1], data[i][2], data[i][3], data[i][0], data[i][1], data[i][2], data[i][3],
data[i][4], data[i][5], data[i][6], data[i][7], data[i][4], data[i][5], data[i][6], data[i][7],
GL_COLOR_BUFFER_BIT, GL_NEAREST); GL_COLOR_BUFFER_BIT, GL_NEAREST);
// Ignore error state, just make sure that we don't crash on these inputs. // Ignore error state, just make sure that we don't crash on these inputs.
} }
...@@ -1923,20 +1933,19 @@ TEST_F(SwiftShaderTest, InvalidEnum_TexImage2D) ...@@ -1923,20 +1933,19 @@ TEST_F(SwiftShaderTest, InvalidEnum_TexImage2D)
TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedIfs) TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedIfs)
{ {
std::string body = "return 1.0;"; std::string body = "return 1.0;";
for (int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
body = " if (f > " + std::to_string(i * 0.1f) + ") {\n" + body + "}\n"; body = " if (f > " + std::to_string(i * 0.1f) + ") {\n" + body + "}\n";
} }
checkCompiles( checkCompiles(
"float F(float f) {\n" + body + " return 0.0f;\n}\n" "float F(float f) {\n" + body + " return 0.0f;\n}\n");
);
} }
TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedSwitches) TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedSwitches)
{ {
std::string body = "return 1.0;"; std::string body = "return 1.0;";
for (int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
body = " switch (int(f)) {\n case 1:\n f *= 2.0;\n" + body + "}\n"; body = " switch (int(f)) {\n case 1:\n f *= 2.0;\n" + body + "}\n";
} }
...@@ -1947,25 +1956,25 @@ TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedSwitches) ...@@ -1947,25 +1956,25 @@ TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedSwitches)
TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedLoops) TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedLoops)
{ {
std::string loops = "f = f + f * 2.0;"; std::string loops = "f = f + f * 2.0;";
for (int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
auto it = "l" + std::to_string(i); auto it = "l" + std::to_string(i);
loops = " for (int " + it + " = 0; " + it + " < i; " + it + "++) {\n" + loops + "}\n"; loops = " for (int " + it + " = 0; " + it + " < i; " + it + "++) {\n" + loops + "}\n";
} }
checkCompiles( checkCompiles(
"float F(float f) {\n" "float F(float f) {\n"
" int i = (f > 0.0) ? 1 : 0;\n" + loops + " int i = (f > 0.0) ? 1 : 0;\n" +
" return f;\n" loops +
"}\n" " return f;\n"
); "}\n");
} }
TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedCalls) TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedCalls)
{ {
std::string funcs = "float E(float f) { return f * 2.0f; }\n"; std::string funcs = "float E(float f) { return f * 2.0f; }\n";
std::string last = "E"; std::string last = "E";
for (int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
std::string f = "C" + std::to_string(i); std::string f = "C" + std::to_string(i);
funcs += "float " + f + "(float f) { return " + last + "(f) + 1.0f; }\n"; funcs += "float " + f + "(float f) { return " + last + "(f) + 1.0f; }\n";
...@@ -1973,29 +1982,28 @@ TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedCalls) ...@@ -1973,29 +1982,28 @@ TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedCalls)
} }
checkCompiles(funcs + checkCompiles(funcs +
"float F(float f) { return " + last + "(f); }\n" "float F(float f) { return " + last + "(f); }\n");
);
} }
TEST_F(SwiftShaderTest, CompilerLimits_ManyCallSites) TEST_F(SwiftShaderTest, CompilerLimits_ManyCallSites)
{ {
std::string calls; std::string calls;
for (int i = 0; i < 256; i++) for(int i = 0; i < 256; i++)
{ {
calls += " f += C(f);\n"; calls += " f += C(f);\n";
} }
checkCompiles( checkCompiles(
"float C(float f) { return f * 2.0f; }\n" "float C(float f) { return f * 2.0f; }\n"
"float F(float f) {\n" + calls + " return f;\n}\n" "float F(float f) {\n" +
); calls + " return f;\n}\n");
} }
TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedCallsInUnusedFunction) TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedCallsInUnusedFunction)
{ {
std::string funcs = "float E(float f) { return f * 2.0f; }\n"; std::string funcs = "float E(float f) { return f * 2.0f; }\n";
std::string last = "E"; std::string last = "E";
for (int i = 0; i < 16; i++) for(int i = 0; i < 16; i++)
{ {
std::string f = "C" + std::to_string(i); std::string f = "C" + std::to_string(i);
funcs += "float " + f + "(float f) { return " + last + "(f) + 1.0f; }\n"; funcs += "float " + f + "(float f) { return " + last + "(f) + 1.0f; }\n";
...@@ -2003,8 +2011,7 @@ TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedCallsInUnusedFunction) ...@@ -2003,8 +2011,7 @@ TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedCallsInUnusedFunction)
} }
checkCompiles(funcs + checkCompiles(funcs +
"float F(float f) { return f; }\n" "float F(float f) { return f; }\n");
);
} }
// Test that the compiler correctly handles functions being stripped. // Test that the compiler correctly handles functions being stripped.
...@@ -2014,13 +2021,12 @@ TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedCallsInUnusedFunction) ...@@ -2014,13 +2021,12 @@ TEST_F(SwiftShaderTest, CompilerLimits_DeepNestedCallsInUnusedFunction)
TEST_F(SwiftShaderTest, CompilerLimits_SparseLabels) TEST_F(SwiftShaderTest, CompilerLimits_SparseLabels)
{ {
checkCompiles( checkCompiles(
R"(void Dead1() {} R"(void Dead1() {}
void Dead2() {} void Dead2() {}
void Dead3() {} void Dead3() {}
void Dead4() {} void Dead4() {}
void Dead5() { Dead1(); Dead2(); Dead3(); Dead4(); } void Dead5() { Dead1(); Dead2(); Dead3(); Dead4(); }
float F(float f) { for(int i = 0; i < -1; ++i) { Dead5(); } return f; })" float F(float f) { for(int i = 0; i < -1; ++i) { Dead5(); } return f; })");
);
} }
// Test that the compiler doesn't compile arrays larger than // Test that the compiler doesn't compile arrays larger than
...@@ -2028,10 +2034,10 @@ TEST_F(SwiftShaderTest, CompilerLimits_SparseLabels) ...@@ -2028,10 +2034,10 @@ TEST_F(SwiftShaderTest, CompilerLimits_SparseLabels)
TEST_F(SwiftShaderTest, CompilerLimits_ArraySize) TEST_F(SwiftShaderTest, CompilerLimits_ArraySize)
{ {
checkCompileFails( checkCompileFails(
R"(uniform float u_var[100000000]; R"(uniform float u_var[100000000];
float F(float f) { return u_var[2]; })"); float F(float f) { return u_var[2]; })");
checkCompileFails( checkCompileFails(
R"(struct structType { mediump sampler2D m0; mediump samplerCube m1; }; R"(struct structType { mediump sampler2D m0; mediump samplerCube m1; };
uniform structType u_var[100000000]; uniform structType u_var[100000000];
float F(float f) { return texture(u_var[2].m1, vec3(0.0)), vec4(0.26, 1.72, 0.60, 0.12).x; })"); float F(float f) { return texture(u_var[2].m1, vec3(0.0)), vec4(0.26, 1.72, 0.60, 0.12).x; })");
} }
...@@ -2040,52 +2046,46 @@ TEST_F(SwiftShaderTest, CompilerLimits_ArraySize) ...@@ -2040,52 +2046,46 @@ TEST_F(SwiftShaderTest, CompilerLimits_ArraySize)
TEST_F(SwiftShaderTest, BadNegation) TEST_F(SwiftShaderTest, BadNegation)
{ {
checkCompileFails( checkCompileFails(
R"(uniform samplerCube m; R"(uniform samplerCube m;
float F (float f) { vec4 ret = texture(-m, vec3(f)); return ret.x; })" float F (float f) { vec4 ret = texture(-m, vec3(f)); return ret.x; })");
);
checkCompileFails( checkCompileFails(
R"(uniform sampler2D m[9]; R"(uniform sampler2D m[9];
vec4 G (sampler2D X[9]) { return texture(X[0], vec2(0.0f)); } vec4 G (sampler2D X[9]) { return texture(X[0], vec2(0.0f)); }
float F (float f) { vec4 ret = G(-m); return ret.x; })" float F (float f) { vec4 ret = G(-m); return ret.x; })");
);
checkCompileFails( checkCompileFails(
R"(struct structType { int a; float b; }; R"(struct structType { int a; float b; };
uniform structType m; uniform structType m;
float F (float f) { structType n = -m; return f; })" float F (float f) { structType n = -m; return f; })");
);
checkCompileFails( checkCompileFails(
R"(struct structType { int a; float b; }; R"(struct structType { int a; float b; };
uniform structType m[4]; uniform structType m[4];
float F (float f) { structType n[4] = -m; return f; })" float F (float f) { structType n[4] = -m; return f; })");
);
checkCompileFails( checkCompileFails(
R"(uniform float m[4]; R"(uniform float m[4];
float G (float f[4]) { return f[0]; } float G (float f[4]) { return f[0]; }
float F (float f) { return G(-m); })" float F (float f) { return G(-m); })");
);
} }
#ifndef EGL_ANGLE_iosurface_client_buffer #ifndef EGL_ANGLE_iosurface_client_buffer
#define EGL_ANGLE_iosurface_client_buffer 1 # define EGL_ANGLE_iosurface_client_buffer 1
#define EGL_IOSURFACE_ANGLE 0x3454 # define EGL_IOSURFACE_ANGLE 0x3454
#define EGL_IOSURFACE_PLANE_ANGLE 0x345A # define EGL_IOSURFACE_PLANE_ANGLE 0x345A
#define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B # define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
#define EGL_TEXTURE_TYPE_ANGLE 0x345C # define EGL_TEXTURE_TYPE_ANGLE 0x345C
#define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D # define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
#endif /* EGL_ANGLE_iosurface_client_buffer */ #endif /* EGL_ANGLE_iosurface_client_buffer */
#if defined(__APPLE__) #if defined(__APPLE__)
#include <CoreFoundation/CoreFoundation.h> # include <CoreFoundation/CoreFoundation.h>
#include <IOSurface/IOSurface.h> # include <IOSurface/IOSurface.h>
namespace namespace {
void AddIntegerValue(CFMutableDictionaryRef dictionary, const CFStringRef key, int32_t value)
{ {
void AddIntegerValue(CFMutableDictionaryRef dictionary, const CFStringRef key, int32_t value) CFNumberRef number = CFNumberCreate(nullptr, kCFNumberSInt32Type, &value);
{ CFDictionaryAddValue(dictionary, key, number);
CFNumberRef number = CFNumberCreate(nullptr, kCFNumberSInt32Type, &value); CFRelease(number);
CFDictionaryAddValue(dictionary, key, number); }
CFRelease(number);
}
} // anonymous namespace } // anonymous namespace
class EGLClientBufferWrapper class EGLClientBufferWrapper
...@@ -2097,7 +2097,7 @@ public: ...@@ -2097,7 +2097,7 @@ public:
ioSurface = nullptr; ioSurface = nullptr;
CFMutableDictionaryRef dict = CFDictionaryCreateMutable( CFMutableDictionaryRef dict = CFDictionaryCreateMutable(
kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
AddIntegerValue(dict, kIOSurfaceWidth, width); AddIntegerValue(dict, kIOSurfaceWidth, width);
AddIntegerValue(dict, kIOSurfaceHeight, height); AddIntegerValue(dict, kIOSurfaceHeight, height);
AddIntegerValue(dict, kIOSurfacePixelFormat, 'BGRA'); AddIntegerValue(dict, kIOSurfacePixelFormat, 'BGRA');
...@@ -2121,10 +2121,10 @@ public: ...@@ -2121,10 +2121,10 @@ public:
return ioSurface; return ioSurface;
} }
const unsigned char* lockColor() const unsigned char *lockColor()
{ {
IOSurfaceLock(ioSurface, kIOSurfaceLockReadOnly, nullptr); IOSurfaceLock(ioSurface, kIOSurfaceLockReadOnly, nullptr);
return reinterpret_cast<const unsigned char*>(IOSurfaceGetBaseAddress(ioSurface)); return reinterpret_cast<const unsigned char *>(IOSurfaceGetBaseAddress(ioSurface));
} }
void unlockColor() void unlockColor()
...@@ -2132,18 +2132,19 @@ public: ...@@ -2132,18 +2132,19 @@ public:
IOSurfaceUnlock(ioSurface, kIOSurfaceLockReadOnly, nullptr); IOSurfaceUnlock(ioSurface, kIOSurfaceLockReadOnly, nullptr);
} }
void writeColor(void* data, size_t dataSize) void writeColor(void *data, size_t dataSize)
{ {
// Write the data to the IOSurface // Write the data to the IOSurface
IOSurfaceLock(ioSurface, 0, nullptr); IOSurfaceLock(ioSurface, 0, nullptr);
memcpy(IOSurfaceGetBaseAddress(ioSurface), data, dataSize); memcpy(IOSurfaceGetBaseAddress(ioSurface), data, dataSize);
IOSurfaceUnlock(ioSurface, 0, nullptr); IOSurfaceUnlock(ioSurface, 0, nullptr);
} }
private: private:
IOSurfaceRef ioSurface; IOSurfaceRef ioSurface;
}; };
#else // __APPLE__ #else // __APPLE__
class EGLClientBufferWrapper class EGLClientBufferWrapper
{ {
...@@ -2163,7 +2164,7 @@ public: ...@@ -2163,7 +2164,7 @@ public:
return clientBuffer; return clientBuffer;
} }
const unsigned char* lockColor() const unsigned char *lockColor()
{ {
return clientBuffer; return clientBuffer;
} }
...@@ -2172,12 +2173,13 @@ public: ...@@ -2172,12 +2173,13 @@ public:
{ {
} }
void writeColor(void* data, size_t dataSize) void writeColor(void *data, size_t dataSize)
{ {
memcpy(clientBuffer, data, dataSize); memcpy(clientBuffer, data, dataSize);
} }
private: private:
unsigned char* clientBuffer; unsigned char *clientBuffer;
}; };
#endif #endif
...@@ -2189,14 +2191,22 @@ protected: ...@@ -2189,14 +2191,22 @@ protected:
{ {
// Make a PBuffer from it using the EGL_ANGLE_iosurface_client_buffer extension // Make a PBuffer from it using the EGL_ANGLE_iosurface_client_buffer extension
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, width, EGL_WIDTH,
EGL_HEIGHT, height, width,
EGL_IOSURFACE_PLANE_ANGLE, plane, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, height,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, (EGLint)internalFormat, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, plane,
EGL_TEXTURE_TYPE_ANGLE, (EGLint)type, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
(EGLint)internalFormat,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
(EGLint)type,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, buffer, getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, buffer, getConfig(), attribs);
...@@ -2226,16 +2236,16 @@ protected: ...@@ -2226,16 +2236,16 @@ protected:
else else
{ {
glClearColor(clearToZero ? 0.0f : 1.0f / 255.0f, glClearColor(clearToZero ? 0.0f : 1.0f / 255.0f,
clearToZero ? 0.0f : 2.0f / 255.0f, clearToZero ? 0.0f : 2.0f / 255.0f,
clearToZero ? 0.0f : 3.0f / 255.0f, clearToZero ? 0.0f : 3.0f / 255.0f,
clearToZero ? 0.0f : 4.0f / 255.0f); clearToZero ? 0.0f : 4.0f / 255.0f);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
EXPECT_NO_GL_ERROR(); EXPECT_NO_GL_ERROR();
} }
} }
void doClearTest(EGLClientBufferWrapper& clientBufferWrapper, GLenum internalFormat, GLenum type, void *data, size_t dataSize) void doClearTest(EGLClientBufferWrapper &clientBufferWrapper, GLenum internalFormat, GLenum type, void *data, size_t dataSize)
{ {
ASSERT_TRUE(dataSize <= 4); ASSERT_TRUE(dataSize <= 4);
...@@ -2260,10 +2270,10 @@ protected: ...@@ -2260,10 +2270,10 @@ protected:
EXPECT_EQ((EGLBoolean)EGL_TRUE, result); EXPECT_EQ((EGLBoolean)EGL_TRUE, result);
EXPECT_NO_EGL_ERROR(); EXPECT_NO_EGL_ERROR();
const unsigned char* color = clientBufferWrapper.lockColor(); const unsigned char *color = clientBufferWrapper.lockColor();
for(size_t i = 0; i < dataSize; ++i) for(size_t i = 0; i < dataSize; ++i)
{ {
EXPECT_EQ(color[i], reinterpret_cast<unsigned char*>(data)[i]); EXPECT_EQ(color[i], reinterpret_cast<unsigned char *>(data)[i]);
} }
result = eglDestroySurface(getDisplay(), pbuffer); result = eglDestroySurface(getDisplay(), pbuffer);
...@@ -2271,7 +2281,7 @@ protected: ...@@ -2271,7 +2281,7 @@ protected:
EXPECT_NO_EGL_ERROR(); EXPECT_NO_EGL_ERROR();
} }
void doSampleTest(EGLClientBufferWrapper& clientBufferWrapper, GLenum internalFormat, GLenum type, void *data, size_t dataSize) void doSampleTest(EGLClientBufferWrapper &clientBufferWrapper, GLenum internalFormat, GLenum type, void *data, size_t dataSize)
{ {
ASSERT_TRUE(dataSize <= 4); ASSERT_TRUE(dataSize <= 4);
...@@ -2286,14 +2296,14 @@ protected: ...@@ -2286,14 +2296,14 @@ protected:
// Create program and draw quad using it // Create program and draw quad using it
const std::string vs = const std::string vs =
R"(attribute vec4 position; R"(attribute vec4 position;
void main() void main()
{ {
gl_Position = vec4(position.xy, 0.0, 1.0); gl_Position = vec4(position.xy, 0.0, 1.0);
})"; })";
const std::string fs = const std::string fs =
R"(#extension GL_ARB_texture_rectangle : require R"(#extension GL_ARB_texture_rectangle : require
precision mediump float; precision mediump float;
uniform sampler2DRect tex; uniform sampler2DRect tex;
void main() void main()
...@@ -2313,10 +2323,10 @@ protected: ...@@ -2313,10 +2323,10 @@ protected:
EXPECT_EQ((EGLBoolean)EGL_TRUE, result); EXPECT_EQ((EGLBoolean)EGL_TRUE, result);
EXPECT_NO_EGL_ERROR(); EXPECT_NO_EGL_ERROR();
const unsigned char* color = clientBufferWrapper.lockColor(); const unsigned char *color = clientBufferWrapper.lockColor();
for(size_t i = 0; i < dataSize; ++i) for(size_t i = 0; i < dataSize; ++i)
{ {
EXPECT_EQ(color[i], reinterpret_cast<unsigned char*>(data)[i]); EXPECT_EQ(color[i], reinterpret_cast<unsigned char *>(data)[i]);
} }
clientBufferWrapper.unlockColor(); clientBufferWrapper.unlockColor();
} }
...@@ -2327,11 +2337,11 @@ TEST_F(IOSurfaceClientBufferTest, RenderToBGRA8888IOSurface) ...@@ -2327,11 +2337,11 @@ TEST_F(IOSurfaceClientBufferTest, RenderToBGRA8888IOSurface)
{ {
Initialize(3, false); Initialize(3, false);
{ // EGLClientBufferWrapper scope { // EGLClientBufferWrapper scope
EGLClientBufferWrapper clientBufferWrapper; EGLClientBufferWrapper clientBufferWrapper;
unsigned char data[4] = { 3, 2, 1, 4 }; unsigned char data[4] = { 3, 2, 1, 4 };
doClearTest(clientBufferWrapper, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data, 4); doClearTest(clientBufferWrapper, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data, 4);
} // end of EGLClientBufferWrapper scope } // end of EGLClientBufferWrapper scope
Uninitialize(); Uninitialize();
} }
...@@ -2341,11 +2351,11 @@ TEST_F(IOSurfaceClientBufferTest, ReadFromBGRA8888IOSurface) ...@@ -2341,11 +2351,11 @@ TEST_F(IOSurfaceClientBufferTest, ReadFromBGRA8888IOSurface)
{ {
Initialize(3, false); Initialize(3, false);
{ // EGLClientBufferWrapper scope { // EGLClientBufferWrapper scope
EGLClientBufferWrapper clientBufferWrapper; EGLClientBufferWrapper clientBufferWrapper;
unsigned char data[4] = { 3, 2, 1, 4 }; unsigned char data[4] = { 3, 2, 1, 4 };
doSampleTest(clientBufferWrapper, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data, 4); doSampleTest(clientBufferWrapper, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data, 4);
} // end of EGLClientBufferWrapper scope } // end of EGLClientBufferWrapper scope
Uninitialize(); Uninitialize();
} }
...@@ -2355,11 +2365,11 @@ TEST_F(IOSurfaceClientBufferTest, RenderToRGBX8888IOSurface) ...@@ -2355,11 +2365,11 @@ TEST_F(IOSurfaceClientBufferTest, RenderToRGBX8888IOSurface)
{ {
Initialize(3, false); Initialize(3, false);
{ // EGLClientBufferWrapper scope { // EGLClientBufferWrapper scope
EGLClientBufferWrapper clientBufferWrapper; EGLClientBufferWrapper clientBufferWrapper;
unsigned char data[3] = { 1, 2, 3 }; unsigned char data[3] = { 1, 2, 3 };
doClearTest(clientBufferWrapper, GL_RGB, GL_UNSIGNED_BYTE, data, 3); doClearTest(clientBufferWrapper, GL_RGB, GL_UNSIGNED_BYTE, data, 3);
} // end of EGLClientBufferWrapper scope } // end of EGLClientBufferWrapper scope
Uninitialize(); Uninitialize();
} }
...@@ -2369,11 +2379,11 @@ TEST_F(IOSurfaceClientBufferTest, ReadFromRGBX8888IOSurface) ...@@ -2369,11 +2379,11 @@ TEST_F(IOSurfaceClientBufferTest, ReadFromRGBX8888IOSurface)
{ {
Initialize(3, false); Initialize(3, false);
{ // EGLClientBufferWrapper scope { // EGLClientBufferWrapper scope
EGLClientBufferWrapper clientBufferWrapper; EGLClientBufferWrapper clientBufferWrapper;
unsigned char data[3] = { 1, 2, 3 }; unsigned char data[3] = { 1, 2, 3 };
doSampleTest(clientBufferWrapper, GL_RGB, GL_UNSIGNED_BYTE, data, 3); doSampleTest(clientBufferWrapper, GL_RGB, GL_UNSIGNED_BYTE, data, 3);
} // end of EGLClientBufferWrapper scope } // end of EGLClientBufferWrapper scope
Uninitialize(); Uninitialize();
} }
...@@ -2383,11 +2393,11 @@ TEST_F(IOSurfaceClientBufferTest, RenderToRG88IOSurface) ...@@ -2383,11 +2393,11 @@ TEST_F(IOSurfaceClientBufferTest, RenderToRG88IOSurface)
{ {
Initialize(3, false); Initialize(3, false);
{ // EGLClientBufferWrapper scope { // EGLClientBufferWrapper scope
EGLClientBufferWrapper clientBufferWrapper; EGLClientBufferWrapper clientBufferWrapper;
unsigned char data[2] = { 1, 2 }; unsigned char data[2] = { 1, 2 };
doClearTest(clientBufferWrapper, GL_RG, GL_UNSIGNED_BYTE, data, 2); doClearTest(clientBufferWrapper, GL_RG, GL_UNSIGNED_BYTE, data, 2);
} // end of EGLClientBufferWrapper scope } // end of EGLClientBufferWrapper scope
Uninitialize(); Uninitialize();
} }
...@@ -2397,11 +2407,11 @@ TEST_F(IOSurfaceClientBufferTest, ReadFromRG88IOSurface) ...@@ -2397,11 +2407,11 @@ TEST_F(IOSurfaceClientBufferTest, ReadFromRG88IOSurface)
{ {
Initialize(3, false); Initialize(3, false);
{ // EGLClientBufferWrapper scope { // EGLClientBufferWrapper scope
EGLClientBufferWrapper clientBufferWrapper; EGLClientBufferWrapper clientBufferWrapper;
unsigned char data[2] = { 1, 2 }; unsigned char data[2] = { 1, 2 };
doSampleTest(clientBufferWrapper, GL_RG, GL_UNSIGNED_BYTE, data, 2); doSampleTest(clientBufferWrapper, GL_RG, GL_UNSIGNED_BYTE, data, 2);
} // end of EGLClientBufferWrapper scope } // end of EGLClientBufferWrapper scope
Uninitialize(); Uninitialize();
} }
...@@ -2411,11 +2421,11 @@ TEST_F(IOSurfaceClientBufferTest, RenderToR8IOSurface) ...@@ -2411,11 +2421,11 @@ TEST_F(IOSurfaceClientBufferTest, RenderToR8IOSurface)
{ {
Initialize(3, false); Initialize(3, false);
{ // EGLClientBufferWrapper scope { // EGLClientBufferWrapper scope
EGLClientBufferWrapper clientBufferWrapper; EGLClientBufferWrapper clientBufferWrapper;
unsigned char data[1] = { 1 }; unsigned char data[1] = { 1 };
doClearTest(clientBufferWrapper, GL_RED, GL_UNSIGNED_BYTE, data, 1); doClearTest(clientBufferWrapper, GL_RED, GL_UNSIGNED_BYTE, data, 1);
} // end of EGLClientBufferWrapper scope } // end of EGLClientBufferWrapper scope
Uninitialize(); Uninitialize();
} }
...@@ -2425,11 +2435,11 @@ TEST_F(IOSurfaceClientBufferTest, ReadFromR8IOSurface) ...@@ -2425,11 +2435,11 @@ TEST_F(IOSurfaceClientBufferTest, ReadFromR8IOSurface)
{ {
Initialize(3, false); Initialize(3, false);
{ // EGLClientBufferWrapper scope { // EGLClientBufferWrapper scope
EGLClientBufferWrapper clientBufferWrapper; EGLClientBufferWrapper clientBufferWrapper;
unsigned char data[1] = { 1 }; unsigned char data[1] = { 1 };
doSampleTest(clientBufferWrapper, GL_RED, GL_UNSIGNED_BYTE, data, 1); doSampleTest(clientBufferWrapper, GL_RED, GL_UNSIGNED_BYTE, data, 1);
} // end of EGLClientBufferWrapper scope } // end of EGLClientBufferWrapper scope
Uninitialize(); Uninitialize();
} }
...@@ -2439,11 +2449,11 @@ TEST_F(IOSurfaceClientBufferTest, RenderToR16IOSurface) ...@@ -2439,11 +2449,11 @@ TEST_F(IOSurfaceClientBufferTest, RenderToR16IOSurface)
{ {
Initialize(3, false); Initialize(3, false);
{ // EGLClientBufferWrapper scope { // EGLClientBufferWrapper scope
EGLClientBufferWrapper clientBufferWrapper; EGLClientBufferWrapper clientBufferWrapper;
uint16_t data[1] = { 257 }; uint16_t data[1] = { 257 };
doClearTest(clientBufferWrapper, GL_R16UI, GL_UNSIGNED_SHORT, data, 2); doClearTest(clientBufferWrapper, GL_R16UI, GL_UNSIGNED_SHORT, data, 2);
} // end of EGLClientBufferWrapper scope } // end of EGLClientBufferWrapper scope
Uninitialize(); Uninitialize();
} }
...@@ -2453,11 +2463,11 @@ TEST_F(IOSurfaceClientBufferTest, ReadFromR16IOSurface) ...@@ -2453,11 +2463,11 @@ TEST_F(IOSurfaceClientBufferTest, ReadFromR16IOSurface)
{ {
Initialize(3, false); Initialize(3, false);
{ // EGLClientBufferWrapper scope { // EGLClientBufferWrapper scope
EGLClientBufferWrapper clientBufferWrapper; EGLClientBufferWrapper clientBufferWrapper;
uint16_t data[1] = { 257 }; uint16_t data[1] = { 257 };
doSampleTest(clientBufferWrapper, GL_R16UI, GL_UNSIGNED_SHORT, data, 1); doSampleTest(clientBufferWrapper, GL_R16UI, GL_UNSIGNED_SHORT, data, 1);
} // end of EGLClientBufferWrapper scope } // end of EGLClientBufferWrapper scope
Uninitialize(); Uninitialize();
} }
...@@ -2474,14 +2484,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes) ...@@ -2474,14 +2484,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes)
// Success case // Success case
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 10,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, 0,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2495,13 +2513,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes) ...@@ -2495,13 +2513,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes)
// Missing EGL_WIDTH // Missing EGL_WIDTH
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_HEIGHT, 10, EGL_HEIGHT,
EGL_IOSURFACE_PLANE_ANGLE, 0, 10,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, 0,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_NONE, EGL_NONE, EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2512,13 +2537,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes) ...@@ -2512,13 +2537,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes)
// Missing EGL_HEIGHT // Missing EGL_HEIGHT
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_IOSURFACE_PLANE_ANGLE, 0, 10,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, 0,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_NONE, EGL_NONE, EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2529,13 +2561,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes) ...@@ -2529,13 +2561,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes)
// Missing EGL_IOSURFACE_PLANE_ANGLE // Missing EGL_IOSURFACE_PLANE_ANGLE
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, EGL_HEIGHT,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, 10,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_TEXTURE_TARGET,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_NONE, EGL_NONE, EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2547,13 +2586,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes) ...@@ -2547,13 +2586,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes)
// eglCreatePbufferFromClientBuffer // eglCreatePbufferFromClientBuffer
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, 10,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, 0,
EGL_NONE, EGL_NONE, EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2564,13 +2610,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes) ...@@ -2564,13 +2610,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes)
// Missing EGL_TEXTURE_INTERNAL_FORMAT_ANGLE // Missing EGL_TEXTURE_INTERNAL_FORMAT_ANGLE
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 10,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, 0,
EGL_NONE, EGL_NONE, EGL_TEXTURE_TARGET,
EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2582,13 +2635,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes) ...@@ -2582,13 +2635,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes)
// eglCreatePbufferFromClientBuffer // eglCreatePbufferFromClientBuffer
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 10,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, 0,
EGL_NONE, EGL_NONE, EGL_TEXTURE_TARGET,
EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2599,13 +2659,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes) ...@@ -2599,13 +2659,20 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationMissingAttributes)
// Missing EGL_TEXTURE_TYPE_ANGLE // Missing EGL_TEXTURE_TYPE_ANGLE
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 10,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, 0,
EGL_NONE, EGL_NONE, EGL_TEXTURE_TARGET,
EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2628,14 +2695,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes) ...@@ -2628,14 +2695,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
// Success case // Success case
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 10,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, 0,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2649,14 +2724,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes) ...@@ -2649,14 +2724,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
// EGL_TEXTURE_FORMAT must be EGL_TEXTURE_RGBA // EGL_TEXTURE_FORMAT must be EGL_TEXTURE_RGBA
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 10,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB, 0,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGB,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2667,14 +2750,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes) ...@@ -2667,14 +2750,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
// EGL_WIDTH must be at least 1 // EGL_WIDTH must be at least 1
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 0, EGL_WIDTH,
EGL_HEIGHT, 10, 0,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 10,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, 0,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2685,14 +2776,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes) ...@@ -2685,14 +2776,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
// EGL_HEIGHT must be at least 1 // EGL_HEIGHT must be at least 1
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 0, 10,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 0,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, 0,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2704,14 +2803,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes) ...@@ -2704,14 +2803,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
// EGL_WIDTH must be at most the width of the IOSurface // EGL_WIDTH must be at most the width of the IOSurface
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 11, EGL_WIDTH,
EGL_HEIGHT, 10, 11,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 10,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, 0,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2722,14 +2829,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes) ...@@ -2722,14 +2829,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
// EGL_HEIGHT must be at most the height of the IOSurface // EGL_HEIGHT must be at most the height of the IOSurface
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 11, 10,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 11,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, 0,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2740,14 +2855,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes) ...@@ -2740,14 +2855,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
// EGL_IOSURFACE_PLANE_ANGLE must less than the number of planes of the IOSurface // EGL_IOSURFACE_PLANE_ANGLE must less than the number of planes of the IOSurface
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_IOSURFACE_PLANE_ANGLE, 1, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 10,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, 1,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2759,14 +2882,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes) ...@@ -2759,14 +2882,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
// EGL_TEXTURE_FORMAT must be at EGL_TEXTURE_RECTANGLE_ANGLE // EGL_TEXTURE_FORMAT must be at EGL_TEXTURE_RECTANGLE_ANGLE
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, 10,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, 0,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_2D,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2777,14 +2908,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes) ...@@ -2777,14 +2908,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
// EGL_IOSURFACE_PLANE_ANGLE must be at least 0 // EGL_IOSURFACE_PLANE_ANGLE must be at least 0
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_IOSURFACE_PLANE_ANGLE, -1, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 10,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_BGRA_EXT, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, -1,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_BGRA_EXT,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2795,14 +2934,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes) ...@@ -2795,14 +2934,22 @@ TEST_F(IOSurfaceClientBufferTest, NegativeValidationBadAttributes)
// The internal format / type most be listed in the table // The internal format / type most be listed in the table
{ {
const EGLint attribs[] = { const EGLint attribs[] = {
EGL_WIDTH, 10, EGL_WIDTH,
EGL_HEIGHT, 10, 10,
EGL_IOSURFACE_PLANE_ANGLE, 0, EGL_HEIGHT,
EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE, 10,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_RGBA, EGL_IOSURFACE_PLANE_ANGLE,
EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, 0,
EGL_TEXTURE_TYPE_ANGLE, GL_UNSIGNED_BYTE, EGL_TEXTURE_TARGET,
EGL_NONE, EGL_NONE, EGL_TEXTURE_RECTANGLE_ANGLE,
EGL_TEXTURE_INTERNAL_FORMAT_ANGLE,
GL_RGBA,
EGL_TEXTURE_FORMAT,
EGL_TEXTURE_RGBA,
EGL_TEXTURE_TYPE_ANGLE,
GL_UNSIGNED_BYTE,
EGL_NONE,
EGL_NONE,
}; };
EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs); EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(getDisplay(), EGL_IOSURFACE_ANGLE, clientBufferWrapper.getClientBuffer(), getConfig(), attribs);
...@@ -2831,4 +2978,3 @@ TEST_F(IOSurfaceClientBufferTest, MakeCurrentAllowed) ...@@ -2831,4 +2978,3 @@ TEST_F(IOSurfaceClientBufferTest, MakeCurrentAllowed)
Uninitialize(); Uninitialize();
} }
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
#include "System/Half.hpp" #include "System/Half.hpp"
#include <gtest/gtest.h>
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <cstdlib> #include <cstdlib>
...@@ -48,9 +48,9 @@ unsigned int RGB9E5_reference(float r, float g, float b) ...@@ -48,9 +48,9 @@ unsigned int RGB9E5_reference(float r, float g, float b)
constexpr int g_sharedexp_maxexponent = 31; constexpr int g_sharedexp_maxexponent = 31;
constexpr float g_sharedexp_max = constexpr float g_sharedexp_max =
((static_cast<float>(1 << g_sharedexp_mantissabits) - 1) / ((static_cast<float>(1 << g_sharedexp_mantissabits) - 1) /
static_cast<float>(1 << g_sharedexp_mantissabits)) * static_cast<float>(1 << g_sharedexp_mantissabits)) *
static_cast<float>(1 << (g_sharedexp_maxexponent - g_sharedexp_bias)); static_cast<float>(1 << (g_sharedexp_maxexponent - g_sharedexp_bias));
const float red_c = clamp0hi(r, g_sharedexp_max); const float red_c = clamp0hi(r, g_sharedexp_max);
const float green_c = clamp0hi(g, g_sharedexp_max); const float green_c = clamp0hi(g, g_sharedexp_max);
......
...@@ -14,34 +14,37 @@ ...@@ -14,34 +14,37 @@
#include "System/Memory.hpp" #include "System/Memory.hpp"
#ifdef __linux__ #ifdef __linux__
#include "System/Linux/MemFd.hpp" # include "System/Linux/MemFd.hpp"
#endif #endif
#include <gtest/gtest.h>
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <cstdlib> #include <cstdlib>
using namespace sw; using namespace sw;
#ifdef __linux__ #ifdef __linux__
TEST(MemFd, DefaultConstructor) { TEST(MemFd, DefaultConstructor)
{
LinuxMemFd memfd; LinuxMemFd memfd;
ASSERT_FALSE(memfd.isValid()); ASSERT_FALSE(memfd.isValid());
ASSERT_EQ(-1, memfd.exportFd()); ASSERT_EQ(-1, memfd.exportFd());
} }
TEST(MemFd, AllocatingConstructor) { TEST(MemFd, AllocatingConstructor)
{
const size_t kRegionSize = sw::memoryPageSize() * 8; const size_t kRegionSize = sw::memoryPageSize() * 8;
LinuxMemFd memfd("test-region", kRegionSize); LinuxMemFd memfd("test-region", kRegionSize);
ASSERT_TRUE(memfd.isValid()); ASSERT_TRUE(memfd.isValid());
ASSERT_GE(memfd.fd(), 0); ASSERT_GE(memfd.fd(), 0);
void* addr = memfd.mapReadWrite(0, kRegionSize); void *addr = memfd.mapReadWrite(0, kRegionSize);
ASSERT_TRUE(addr); ASSERT_TRUE(addr);
memfd.unmap(addr, kRegionSize); memfd.unmap(addr, kRegionSize);
} }
TEST(MemFd, ExplicitAllocation) { TEST(MemFd, ExplicitAllocation)
{
const size_t kRegionSize = sw::memoryPageSize() * 8; const size_t kRegionSize = sw::memoryPageSize() * 8;
LinuxMemFd memfd; LinuxMemFd memfd;
ASSERT_FALSE(memfd.isValid()); ASSERT_FALSE(memfd.isValid());
...@@ -50,7 +53,8 @@ TEST(MemFd, ExplicitAllocation) { ...@@ -50,7 +53,8 @@ TEST(MemFd, ExplicitAllocation) {
ASSERT_TRUE(memfd.isValid()); ASSERT_TRUE(memfd.isValid());
} }
TEST(MemFd, Close) { TEST(MemFd, Close)
{
const size_t kRegionSize = sw::memoryPageSize() * 8; const size_t kRegionSize = sw::memoryPageSize() * 8;
LinuxMemFd memfd("test-region", kRegionSize); LinuxMemFd memfd("test-region", kRegionSize);
ASSERT_TRUE(memfd.isValid()); ASSERT_TRUE(memfd.isValid());
...@@ -61,12 +65,13 @@ TEST(MemFd, Close) { ...@@ -61,12 +65,13 @@ TEST(MemFd, Close) {
::close(fd); ::close(fd);
} }
TEST(MemFd, ExportImportFd) { TEST(MemFd, ExportImportFd)
{
const size_t kRegionSize = sw::memoryPageSize() * 8; const size_t kRegionSize = sw::memoryPageSize() * 8;
LinuxMemFd memfd("test-region1", kRegionSize); LinuxMemFd memfd("test-region1", kRegionSize);
auto* addr = reinterpret_cast<uint8_t*>(memfd.mapReadWrite(0, kRegionSize)); auto *addr = reinterpret_cast<uint8_t *>(memfd.mapReadWrite(0, kRegionSize));
ASSERT_TRUE(addr); ASSERT_TRUE(addr);
for (size_t n = 0; n < kRegionSize; ++n) for(size_t n = 0; n < kRegionSize; ++n)
{ {
addr[n] = static_cast<uint8_t>(n); addr[n] = static_cast<uint8_t>(n);
} }
...@@ -77,9 +82,9 @@ TEST(MemFd, ExportImportFd) { ...@@ -77,9 +82,9 @@ TEST(MemFd, ExportImportFd) {
LinuxMemFd memfd2; LinuxMemFd memfd2;
memfd2.importFd(fd); memfd2.importFd(fd);
ASSERT_TRUE(memfd2.isValid()); ASSERT_TRUE(memfd2.isValid());
addr = reinterpret_cast<uint8_t*>(memfd2.mapReadWrite(0, kRegionSize)); addr = reinterpret_cast<uint8_t *>(memfd2.mapReadWrite(0, kRegionSize));
ASSERT_TRUE(addr); ASSERT_TRUE(addr);
for (size_t n = 0; n < kRegionSize; ++n) for(size_t n = 0; n < kRegionSize; ++n)
{ {
ASSERT_EQ(addr[n], static_cast<uint8_t>(n)) << "# " << n; ASSERT_EQ(addr[n], static_cast<uint8_t>(n)) << "# " << n;
} }
......
...@@ -16,153 +16,158 @@ ...@@ -16,153 +16,158 @@
#include "Driver.hpp" #include "Driver.hpp"
Device::Device() Device::Device()
: driver(nullptr), : driver(nullptr)
device(nullptr), , device(nullptr)
physicalDevice(nullptr), , physicalDevice(nullptr)
queueFamilyIndex(0) {} , queueFamilyIndex(0)
{}
Device::Device( Device::Device(
Driver const *driver, VkDevice device, VkPhysicalDevice physicalDevice, Driver const *driver, VkDevice device, VkPhysicalDevice physicalDevice,
uint32_t queueFamilyIndex) uint32_t queueFamilyIndex)
: driver(driver), : driver(driver)
device(device), , device(device)
physicalDevice(physicalDevice), , physicalDevice(physicalDevice)
queueFamilyIndex(queueFamilyIndex) {} , queueFamilyIndex(queueFamilyIndex)
{}
Device::~Device() Device::~Device()
{ {
if (device != nullptr) if(device != nullptr)
{ {
driver->vkDeviceWaitIdle(device); driver->vkDeviceWaitIdle(device);
driver->vkDestroyDevice(device, nullptr); driver->vkDestroyDevice(device, nullptr);
} }
} }
bool Device::IsValid() const { return device != nullptr; } bool Device::IsValid() const
{
return device != nullptr;
}
VkResult Device::CreateComputeDevice( VkResult Device::CreateComputeDevice(
Driver const *driver, VkInstance instance, std::unique_ptr<Device> &out) Driver const *driver, VkInstance instance, std::unique_ptr<Device> &out)
{ {
VkResult result; VkResult result;
// Gather all physical devices // Gather all physical devices
std::vector<VkPhysicalDevice> physicalDevices; std::vector<VkPhysicalDevice> physicalDevices;
result = GetPhysicalDevices(driver, instance, physicalDevices); result = GetPhysicalDevices(driver, instance, physicalDevices);
if (result != VK_SUCCESS) if(result != VK_SUCCESS)
{ {
return result; return result;
} }
// Inspect each physical device's queue families for compute support. // Inspect each physical device's queue families for compute support.
for (auto physicalDevice : physicalDevices) for(auto physicalDevice : physicalDevices)
{ {
int queueFamilyIndex = GetComputeQueueFamilyIndex(driver, physicalDevice); int queueFamilyIndex = GetComputeQueueFamilyIndex(driver, physicalDevice);
if (queueFamilyIndex < 0) if(queueFamilyIndex < 0)
{ {
continue; continue;
} }
const float queuePrioritory = 1.0f; const float queuePrioritory = 1.0f;
const VkDeviceQueueCreateInfo deviceQueueCreateInfo = { const VkDeviceQueueCreateInfo deviceQueueCreateInfo = {
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
(uint32_t)queueFamilyIndex, // queueFamilyIndex (uint32_t)queueFamilyIndex, // queueFamilyIndex
1, // queueCount 1, // queueCount
&queuePrioritory, // pQueuePriorities &queuePrioritory, // pQueuePriorities
}; };
const VkDeviceCreateInfo deviceCreateInfo = { const VkDeviceCreateInfo deviceCreateInfo = {
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
1, // queueCreateInfoCount 1, // queueCreateInfoCount
&deviceQueueCreateInfo, // pQueueCreateInfos &deviceQueueCreateInfo, // pQueueCreateInfos
0, // enabledLayerCount 0, // enabledLayerCount
nullptr, // ppEnabledLayerNames nullptr, // ppEnabledLayerNames
0, // enabledExtensionCount 0, // enabledExtensionCount
nullptr, // ppEnabledExtensionNames nullptr, // ppEnabledExtensionNames
nullptr, // pEnabledFeatures nullptr, // pEnabledFeatures
}; };
VkDevice device; VkDevice device;
result = driver->vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device); result = driver->vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device);
if (result != VK_SUCCESS) if(result != VK_SUCCESS)
{ {
return result; return result;
} }
out.reset(new Device(driver, device, physicalDevice, static_cast<uint32_t>(queueFamilyIndex))); out.reset(new Device(driver, device, physicalDevice, static_cast<uint32_t>(queueFamilyIndex)));
return VK_SUCCESS; return VK_SUCCESS;
} }
return VK_SUCCESS; return VK_SUCCESS;
} }
int Device::GetComputeQueueFamilyIndex( int Device::GetComputeQueueFamilyIndex(
Driver const *driver, VkPhysicalDevice device) Driver const *driver, VkPhysicalDevice device)
{ {
auto properties = GetPhysicalDeviceQueueFamilyProperties(driver, device); auto properties = GetPhysicalDeviceQueueFamilyProperties(driver, device);
for (uint32_t i = 0; i < properties.size(); i++) for(uint32_t i = 0; i < properties.size(); i++)
{ {
if ((properties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) != 0) if((properties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) != 0)
{ {
return static_cast<int>(i); return static_cast<int>(i);
} }
} }
return -1; return -1;
} }
std::vector<VkQueueFamilyProperties> std::vector<VkQueueFamilyProperties>
Device::GetPhysicalDeviceQueueFamilyProperties( Device::GetPhysicalDeviceQueueFamilyProperties(
Driver const *driver, VkPhysicalDevice device) Driver const *driver, VkPhysicalDevice device)
{ {
std::vector<VkQueueFamilyProperties> out; std::vector<VkQueueFamilyProperties> out;
uint32_t count = 0; uint32_t count = 0;
driver->vkGetPhysicalDeviceQueueFamilyProperties(device, &count, nullptr); driver->vkGetPhysicalDeviceQueueFamilyProperties(device, &count, nullptr);
out.resize(count); out.resize(count);
driver->vkGetPhysicalDeviceQueueFamilyProperties(device, &count, out.data()); driver->vkGetPhysicalDeviceQueueFamilyProperties(device, &count, out.data());
return out; return out;
} }
VkResult Device::GetPhysicalDevices( VkResult Device::GetPhysicalDevices(
const Driver* driver, VkInstance instance, const Driver *driver, VkInstance instance,
std::vector<VkPhysicalDevice>& out) std::vector<VkPhysicalDevice> &out)
{ {
uint32_t count = 0; uint32_t count = 0;
VkResult result = driver->vkEnumeratePhysicalDevices(instance, &count, 0); VkResult result = driver->vkEnumeratePhysicalDevices(instance, &count, 0);
if (result != VK_SUCCESS) if(result != VK_SUCCESS)
{ {
return result; return result;
} }
out.resize(count); out.resize(count);
return driver->vkEnumeratePhysicalDevices(instance, &count, out.data()); return driver->vkEnumeratePhysicalDevices(instance, &count, out.data());
} }
VkResult Device::CreateStorageBuffer( VkResult Device::CreateStorageBuffer(
VkDeviceMemory memory, VkDeviceSize size, VkDeviceMemory memory, VkDeviceSize size,
VkDeviceSize offset, VkBuffer* out) const VkDeviceSize offset, VkBuffer *out) const
{ {
const VkBufferCreateInfo info = { const VkBufferCreateInfo info = {
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
size, // size size, // size
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
VK_SHARING_MODE_EXCLUSIVE, // sharingMode VK_SHARING_MODE_EXCLUSIVE, // sharingMode
0, // queueFamilyIndexCount 0, // queueFamilyIndexCount
nullptr, // pQueueFamilyIndices nullptr, // pQueueFamilyIndices
}; };
VkBuffer buffer; VkBuffer buffer;
VkResult result = driver->vkCreateBuffer(device, &info, 0, &buffer); VkResult result = driver->vkCreateBuffer(device, &info, 0, &buffer);
if (result != VK_SUCCESS) if(result != VK_SUCCESS)
{ {
return result; return result;
} }
result = driver->vkBindBufferMemory(device, buffer, memory, offset); result = driver->vkBindBufferMemory(device, buffer, memory, offset);
if (result != VK_SUCCESS) if(result != VK_SUCCESS)
{ {
return result; return result;
} }
...@@ -177,14 +182,14 @@ void Device::DestroyBuffer(VkBuffer buffer) const ...@@ -177,14 +182,14 @@ void Device::DestroyBuffer(VkBuffer buffer) const
} }
VkResult Device::CreateShaderModule( VkResult Device::CreateShaderModule(
const std::vector<uint32_t>& spirv, VkShaderModule* out) const const std::vector<uint32_t> &spirv, VkShaderModule *out) const
{ {
VkShaderModuleCreateInfo info = { VkShaderModuleCreateInfo info = {
VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // sType VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
spirv.size() * 4, // codeSize spirv.size() * 4, // codeSize
spirv.data(), // pCode spirv.data(), // pCode
}; };
return driver->vkCreateShaderModule(device, &info, 0, out); return driver->vkCreateShaderModule(device, &info, 0, out);
} }
...@@ -195,15 +200,15 @@ void Device::DestroyShaderModule(VkShaderModule shaderModule) const ...@@ -195,15 +200,15 @@ void Device::DestroyShaderModule(VkShaderModule shaderModule) const
} }
VkResult Device::CreateDescriptorSetLayout( VkResult Device::CreateDescriptorSetLayout(
const std::vector<VkDescriptorSetLayoutBinding>& bindings, const std::vector<VkDescriptorSetLayoutBinding> &bindings,
VkDescriptorSetLayout* out) const VkDescriptorSetLayout *out) const
{ {
VkDescriptorSetLayoutCreateInfo info = { VkDescriptorSetLayoutCreateInfo info = {
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
(uint32_t)bindings.size(), // bindingCount (uint32_t)bindings.size(), // bindingCount
bindings.data(), // pBindings bindings.data(), // pBindings
}; };
return driver->vkCreateDescriptorSetLayout(device, &info, 0, out); return driver->vkCreateDescriptorSetLayout(device, &info, 0, out);
...@@ -215,16 +220,16 @@ void Device::DestroyDescriptorSetLayout(VkDescriptorSetLayout descriptorSetLayou ...@@ -215,16 +220,16 @@ void Device::DestroyDescriptorSetLayout(VkDescriptorSetLayout descriptorSetLayou
} }
VkResult Device::CreatePipelineLayout( VkResult Device::CreatePipelineLayout(
VkDescriptorSetLayout layout, VkPipelineLayout* out) const VkDescriptorSetLayout layout, VkPipelineLayout *out) const
{ {
VkPipelineLayoutCreateInfo info = { VkPipelineLayoutCreateInfo info = {
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
1, // setLayoutCount 1, // setLayoutCount
&layout, // pSetLayouts &layout, // pSetLayouts
0, // pushConstantRangeCount 0, // pushConstantRangeCount
nullptr, // pPushConstantRanges nullptr, // pPushConstantRanges
}; };
return driver->vkCreatePipelineLayout(device, &info, 0, out); return driver->vkCreatePipelineLayout(device, &info, 0, out);
...@@ -236,26 +241,26 @@ void Device::DestroyPipelineLayout(VkPipelineLayout pipelineLayout) const ...@@ -236,26 +241,26 @@ void Device::DestroyPipelineLayout(VkPipelineLayout pipelineLayout) const
} }
VkResult Device::CreateComputePipeline( VkResult Device::CreateComputePipeline(
VkShaderModule module, VkPipelineLayout pipelineLayout, VkShaderModule module, VkPipelineLayout pipelineLayout,
VkPipeline* out) const VkPipeline *out) const
{ {
VkComputePipelineCreateInfo info = { VkComputePipelineCreateInfo info = {
VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // sType VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
{ {
// stage // stage
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
VK_SHADER_STAGE_COMPUTE_BIT, // stage VK_SHADER_STAGE_COMPUTE_BIT, // stage
module, // module module, // module
"main", // pName "main", // pName
nullptr, // pSpecializationInfo nullptr, // pSpecializationInfo
}, },
pipelineLayout, // layout pipelineLayout, // layout
0, // basePipelineHandle 0, // basePipelineHandle
0, // basePipelineIndex 0, // basePipelineIndex
}; };
return driver->vkCreateComputePipelines(device, 0, 1, &info, 0, out); return driver->vkCreateComputePipelines(device, 0, 1, &info, 0, out);
...@@ -267,20 +272,20 @@ void Device::DestroyPipeline(VkPipeline pipeline) const ...@@ -267,20 +272,20 @@ void Device::DestroyPipeline(VkPipeline pipeline) const
} }
VkResult Device::CreateStorageBufferDescriptorPool(uint32_t descriptorCount, VkResult Device::CreateStorageBufferDescriptorPool(uint32_t descriptorCount,
VkDescriptorPool* out) const VkDescriptorPool *out) const
{ {
VkDescriptorPoolSize size = { VkDescriptorPoolSize size = {
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // type
descriptorCount, // descriptorCount descriptorCount, // descriptorCount
}; };
VkDescriptorPoolCreateInfo info = { VkDescriptorPoolCreateInfo info = {
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // sType VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
1, // maxSets 1, // maxSets
1, // poolSizeCount 1, // poolSizeCount
&size, // pPoolSizes &size, // pPoolSizes
}; };
return driver->vkCreateDescriptorPool(device, &info, 0, out); return driver->vkCreateDescriptorPool(device, &info, 0, out);
...@@ -292,58 +297,58 @@ void Device::DestroyDescriptorPool(VkDescriptorPool descriptorPool) const ...@@ -292,58 +297,58 @@ void Device::DestroyDescriptorPool(VkDescriptorPool descriptorPool) const
} }
VkResult Device::AllocateDescriptorSet( VkResult Device::AllocateDescriptorSet(
VkDescriptorPool pool, VkDescriptorSetLayout layout, VkDescriptorPool pool, VkDescriptorSetLayout layout,
VkDescriptorSet* out) const VkDescriptorSet *out) const
{ {
VkDescriptorSetAllocateInfo info = { VkDescriptorSetAllocateInfo info = {
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
pool, // descriptorPool pool, // descriptorPool
1, // descriptorSetCount 1, // descriptorSetCount
&layout, // pSetLayouts &layout, // pSetLayouts
}; };
return driver->vkAllocateDescriptorSets(device, &info, out); return driver->vkAllocateDescriptorSets(device, &info, out);
} }
void Device::UpdateStorageBufferDescriptorSets( void Device::UpdateStorageBufferDescriptorSets(
VkDescriptorSet descriptorSet, VkDescriptorSet descriptorSet,
const std::vector<VkDescriptorBufferInfo>& bufferInfos) const const std::vector<VkDescriptorBufferInfo> &bufferInfos) const
{ {
std::vector<VkWriteDescriptorSet> writes; std::vector<VkWriteDescriptorSet> writes;
writes.reserve(bufferInfos.size()); writes.reserve(bufferInfos.size());
for (uint32_t i = 0; i < bufferInfos.size(); i++) for(uint32_t i = 0; i < bufferInfos.size(); i++)
{ {
writes.push_back(VkWriteDescriptorSet{ writes.push_back(VkWriteDescriptorSet{
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
nullptr, // pNext nullptr, // pNext
descriptorSet, // dstSet descriptorSet, // dstSet
i, // dstBinding i, // dstBinding
0, // dstArrayElement 0, // dstArrayElement
1, // descriptorCount 1, // descriptorCount
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
nullptr, // pImageInfo nullptr, // pImageInfo
&bufferInfos[i], // pBufferInfo &bufferInfos[i], // pBufferInfo
nullptr, // pTexelBufferView nullptr, // pTexelBufferView
}); });
} }
driver->vkUpdateDescriptorSets(device, writes.size(), writes.data(), 0, nullptr); driver->vkUpdateDescriptorSets(device, writes.size(), writes.data(), 0, nullptr);
} }
VkResult Device::AllocateMemory(size_t size, VkMemoryPropertyFlags flags, VkDeviceMemory* out) const VkResult Device::AllocateMemory(size_t size, VkMemoryPropertyFlags flags, VkDeviceMemory *out) const
{ {
VkPhysicalDeviceMemoryProperties properties; VkPhysicalDeviceMemoryProperties properties;
driver->vkGetPhysicalDeviceMemoryProperties(physicalDevice, &properties); driver->vkGetPhysicalDeviceMemoryProperties(physicalDevice, &properties);
for(uint32_t type = 0; type < properties.memoryTypeCount; type++) for(uint32_t type = 0; type < properties.memoryTypeCount; type++)
{ {
if ((flags & properties.memoryTypes[type].propertyFlags) == 0) if((flags & properties.memoryTypes[type].propertyFlags) == 0)
{ {
continue; // Type mismatch continue; // Type mismatch
} }
if (size > properties.memoryHeaps[properties.memoryTypes[type].heapIndex].size) if(size > properties.memoryHeaps[properties.memoryTypes[type].heapIndex].size)
{ {
continue; // Too small. continue; // Too small.
} }
...@@ -358,7 +363,7 @@ VkResult Device::AllocateMemory(size_t size, VkMemoryPropertyFlags flags, VkDevi ...@@ -358,7 +363,7 @@ VkResult Device::AllocateMemory(size_t size, VkMemoryPropertyFlags flags, VkDevi
return driver->vkAllocateMemory(device, &info, 0, out); return driver->vkAllocateMemory(device, &info, 0, out);
} }
return VK_ERROR_OUT_OF_DEVICE_MEMORY; // TODO: Change to something not made up? return VK_ERROR_OUT_OF_DEVICE_MEMORY; // TODO: Change to something not made up?
} }
void Device::FreeMemory(VkDeviceMemory memory) const void Device::FreeMemory(VkDeviceMemory memory) const
...@@ -367,7 +372,7 @@ void Device::FreeMemory(VkDeviceMemory memory) const ...@@ -367,7 +372,7 @@ void Device::FreeMemory(VkDeviceMemory memory) const
} }
VkResult Device::MapMemory(VkDeviceMemory memory, VkDeviceSize offset, VkResult Device::MapMemory(VkDeviceMemory memory, VkDeviceSize offset,
VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) const VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) const
{ {
return driver->vkMapMemory(device, memory, offset, size, flags, ppData); return driver->vkMapMemory(device, memory, offset, size, flags, ppData);
} }
...@@ -377,33 +382,33 @@ void Device::UnmapMemory(VkDeviceMemory memory) const ...@@ -377,33 +382,33 @@ void Device::UnmapMemory(VkDeviceMemory memory) const
driver->vkUnmapMemory(device, memory); driver->vkUnmapMemory(device, memory);
} }
VkResult Device::CreateCommandPool(VkCommandPool* out) const VkResult Device::CreateCommandPool(VkCommandPool *out) const
{ {
VkCommandPoolCreateInfo info = { VkCommandPoolCreateInfo info = {
VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
queueFamilyIndex, // queueFamilyIndex queueFamilyIndex, // queueFamilyIndex
}; };
return driver->vkCreateCommandPool(device, &info, 0, out); return driver->vkCreateCommandPool(device, &info, 0, out);
} }
void Device::DestroyCommandPool(VkCommandPool commandPool) const void Device::DestroyCommandPool(VkCommandPool commandPool) const
{ {
return driver->vkDestroyCommandPool(device, commandPool, nullptr); return driver->vkDestroyCommandPool(device, commandPool, nullptr);
} }
VkResult Device::AllocateCommandBuffer( VkResult Device::AllocateCommandBuffer(
VkCommandPool pool, VkCommandBuffer* out) const VkCommandPool pool, VkCommandBuffer *out) const
{ {
VkCommandBufferAllocateInfo info = { VkCommandBufferAllocateInfo info = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
pool, // commandPool pool, // commandPool
VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
1, // commandBufferCount 1, // commandBufferCount
}; };
return driver->vkAllocateCommandBuffers(device, &info, out); return driver->vkAllocateCommandBuffers(device, &info, out);
} }
void Device::FreeCommandBuffer(VkCommandPool pool, VkCommandBuffer buffer) void Device::FreeCommandBuffer(VkCommandPool pool, VkCommandBuffer buffer)
...@@ -412,40 +417,40 @@ void Device::FreeCommandBuffer(VkCommandPool pool, VkCommandBuffer buffer) ...@@ -412,40 +417,40 @@ void Device::FreeCommandBuffer(VkCommandPool pool, VkCommandBuffer buffer)
} }
VkResult Device::BeginCommandBuffer( VkResult Device::BeginCommandBuffer(
VkCommandBufferUsageFlags usage, VkCommandBuffer commandBuffer) const VkCommandBufferUsageFlags usage, VkCommandBuffer commandBuffer) const
{ {
VkCommandBufferBeginInfo info = { VkCommandBufferBeginInfo info = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // sType
nullptr, // pNext nullptr, // pNext
usage, // flags usage, // flags
nullptr, // pInheritanceInfo nullptr, // pInheritanceInfo
}; };
return driver->vkBeginCommandBuffer(commandBuffer, &info); return driver->vkBeginCommandBuffer(commandBuffer, &info);
} }
VkResult Device::QueueSubmitAndWait(VkCommandBuffer commandBuffer) const VkResult Device::QueueSubmitAndWait(VkCommandBuffer commandBuffer) const
{ {
VkQueue queue; VkQueue queue;
driver->vkGetDeviceQueue(device, queueFamilyIndex, 0, &queue); driver->vkGetDeviceQueue(device, queueFamilyIndex, 0, &queue);
VkSubmitInfo info = { VkSubmitInfo info = {
VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType VK_STRUCTURE_TYPE_SUBMIT_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // waitSemaphoreCount 0, // waitSemaphoreCount
nullptr, // pWaitSemaphores nullptr, // pWaitSemaphores
nullptr, // pWaitDstStageMask nullptr, // pWaitDstStageMask
1, // commandBufferCount 1, // commandBufferCount
&commandBuffer, // pCommandBuffers &commandBuffer, // pCommandBuffers
0, // signalSemaphoreCount 0, // signalSemaphoreCount
nullptr, // pSignalSemaphores nullptr, // pSignalSemaphores
}; };
VkResult result = driver->vkQueueSubmit(queue, 1, &info, 0); VkResult result = driver->vkQueueSubmit(queue, 1, &info, 0);
if (result != VK_SUCCESS) if(result != VK_SUCCESS)
{ {
return result; return result;
} }
return driver->vkQueueWaitIdle(queue); return driver->vkQueueWaitIdle(queue);
} }
...@@ -35,7 +35,7 @@ public: ...@@ -35,7 +35,7 @@ public:
// returned (as there was no Vulkan error), but calling Device::IsValid() // returned (as there was no Vulkan error), but calling Device::IsValid()
// on this device will return false. // on this device will return false.
static VkResult CreateComputeDevice( static VkResult CreateComputeDevice(
Driver const *driver, VkInstance instance, std::unique_ptr<Device>& out); Driver const *driver, VkInstance instance, std::unique_ptr<Device> &out);
// IsValid returns true if the Device is initialized and can be used. // IsValid returns true if the Device is initialized and can be used.
bool IsValid() const; bool IsValid() const;
...@@ -44,7 +44,7 @@ public: ...@@ -44,7 +44,7 @@ public:
// VK_BUFFER_USAGE_STORAGE_BUFFER_BIT usage, and // VK_BUFFER_USAGE_STORAGE_BUFFER_BIT usage, and
// VK_SHARING_MODE_EXCLUSIVE sharing mode. // VK_SHARING_MODE_EXCLUSIVE sharing mode.
VkResult CreateStorageBuffer(VkDeviceMemory memory, VkDeviceSize size, VkResult CreateStorageBuffer(VkDeviceMemory memory, VkDeviceSize size,
VkDeviceSize offset, VkBuffer *out) const; VkDeviceSize offset, VkBuffer *out) const;
// DestroyBuffer destroys a VkBuffer. // DestroyBuffer destroys a VkBuffer.
void DestroyBuffer(VkBuffer buffer) const; void DestroyBuffer(VkBuffer buffer) const;
...@@ -52,7 +52,7 @@ public: ...@@ -52,7 +52,7 @@ public:
// CreateShaderModule creates a new shader module with the given SPIR-V // CreateShaderModule creates a new shader module with the given SPIR-V
// code. // code.
VkResult CreateShaderModule(const std::vector<uint32_t> &spirv, VkResult CreateShaderModule(const std::vector<uint32_t> &spirv,
VkShaderModule *out) const; VkShaderModule *out) const;
// DestroyShaderModule destroys a VkShaderModule. // DestroyShaderModule destroys a VkShaderModule.
void DestroyShaderModule(VkShaderModule shaderModule) const; void DestroyShaderModule(VkShaderModule shaderModule) const;
...@@ -60,15 +60,15 @@ public: ...@@ -60,15 +60,15 @@ public:
// CreateDescriptorSetLayout creates a new descriptor set layout with the // CreateDescriptorSetLayout creates a new descriptor set layout with the
// given bindings. // given bindings.
VkResult CreateDescriptorSetLayout( VkResult CreateDescriptorSetLayout(
const std::vector<VkDescriptorSetLayoutBinding> &bindings, const std::vector<VkDescriptorSetLayoutBinding> &bindings,
VkDescriptorSetLayout *out) const; VkDescriptorSetLayout *out) const;
// DestroyDescriptorSetLayout destroys a VkDescriptorSetLayout. // DestroyDescriptorSetLayout destroys a VkDescriptorSetLayout.
void DestroyDescriptorSetLayout(VkDescriptorSetLayout descriptorSetLayout) const; void DestroyDescriptorSetLayout(VkDescriptorSetLayout descriptorSetLayout) const;
// CreatePipelineLayout creates a new single set descriptor set layout. // CreatePipelineLayout creates a new single set descriptor set layout.
VkResult CreatePipelineLayout(VkDescriptorSetLayout layout, VkResult CreatePipelineLayout(VkDescriptorSetLayout layout,
VkPipelineLayout *out) const; VkPipelineLayout *out) const;
// DestroyPipelineLayout destroys a VkPipelineLayout. // DestroyPipelineLayout destroys a VkPipelineLayout.
void DestroyPipelineLayout(VkPipelineLayout pipelineLayout) const; void DestroyPipelineLayout(VkPipelineLayout pipelineLayout) const;
...@@ -76,8 +76,8 @@ public: ...@@ -76,8 +76,8 @@ public:
// CreateComputePipeline creates a new compute pipeline with the entry point // CreateComputePipeline creates a new compute pipeline with the entry point
// "main". // "main".
VkResult CreateComputePipeline(VkShaderModule module, VkResult CreateComputePipeline(VkShaderModule module,
VkPipelineLayout pipelineLayout, VkPipelineLayout pipelineLayout,
VkPipeline *out) const; VkPipeline *out) const;
// DestroyPipeline destroys a graphics or compute pipeline. // DestroyPipeline destroys a graphics or compute pipeline.
void DestroyPipeline(VkPipeline pipeline) const; void DestroyPipeline(VkPipeline pipeline) const;
...@@ -85,7 +85,7 @@ public: ...@@ -85,7 +85,7 @@ public:
// CreateStorageBufferDescriptorPool creates a new descriptor pool that can // CreateStorageBufferDescriptorPool creates a new descriptor pool that can
// hold descriptorCount storage buffers. // hold descriptorCount storage buffers.
VkResult CreateStorageBufferDescriptorPool(uint32_t descriptorCount, VkResult CreateStorageBufferDescriptorPool(uint32_t descriptorCount,
VkDescriptorPool *out) const; VkDescriptorPool *out) const;
// DestroyDescriptorPool destroys the VkDescriptorPool. // DestroyDescriptorPool destroys the VkDescriptorPool.
void DestroyDescriptorPool(VkDescriptorPool descriptorPool) const; void DestroyDescriptorPool(VkDescriptorPool descriptorPool) const;
...@@ -93,38 +93,38 @@ public: ...@@ -93,38 +93,38 @@ public:
// AllocateDescriptorSet allocates a single descriptor set with the given // AllocateDescriptorSet allocates a single descriptor set with the given
// layout from pool. // layout from pool.
VkResult AllocateDescriptorSet(VkDescriptorPool pool, VkResult AllocateDescriptorSet(VkDescriptorPool pool,
VkDescriptorSetLayout layout, VkDescriptorSetLayout layout,
VkDescriptorSet *out) const; VkDescriptorSet *out) const;
// UpdateStorageBufferDescriptorSets updates the storage buffers in // UpdateStorageBufferDescriptorSets updates the storage buffers in
// descriptorSet with the given list of VkDescriptorBufferInfos. // descriptorSet with the given list of VkDescriptorBufferInfos.
void UpdateStorageBufferDescriptorSets(VkDescriptorSet descriptorSet, void UpdateStorageBufferDescriptorSets(VkDescriptorSet descriptorSet,
const std::vector<VkDescriptorBufferInfo> &bufferInfos) const; const std::vector<VkDescriptorBufferInfo> &bufferInfos) const;
// AllocateMemory allocates size bytes from a memory heap that has all the // AllocateMemory allocates size bytes from a memory heap that has all the
// given flag bits set. // given flag bits set.
// If memory could not be allocated from any heap then // If memory could not be allocated from any heap then
// VK_ERROR_OUT_OF_DEVICE_MEMORY is returned. // VK_ERROR_OUT_OF_DEVICE_MEMORY is returned.
VkResult AllocateMemory(size_t size, VkMemoryPropertyFlags flags, VkDeviceMemory* out) const; VkResult AllocateMemory(size_t size, VkMemoryPropertyFlags flags, VkDeviceMemory *out) const;
// FreeMemory frees the VkDeviceMemory. // FreeMemory frees the VkDeviceMemory.
void FreeMemory(VkDeviceMemory memory) const; void FreeMemory(VkDeviceMemory memory) const;
// MapMemory wraps vkMapMemory, supplying the first VkDevice parameter. // MapMemory wraps vkMapMemory, supplying the first VkDevice parameter.
VkResult MapMemory(VkDeviceMemory memory, VkDeviceSize offset, VkResult MapMemory(VkDeviceMemory memory, VkDeviceSize offset,
VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) const; VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) const;
// UnmapMemory wraps vkUnmapMemory, supplying the first VkDevice parameter. // UnmapMemory wraps vkUnmapMemory, supplying the first VkDevice parameter.
void UnmapMemory(VkDeviceMemory memory) const; void UnmapMemory(VkDeviceMemory memory) const;
// CreateCommandPool creates a new command pool. // CreateCommandPool creates a new command pool.
VkResult CreateCommandPool(VkCommandPool* out) const; VkResult CreateCommandPool(VkCommandPool *out) const;
// DestroyCommandPool destroys a VkCommandPool. // DestroyCommandPool destroys a VkCommandPool.
void DestroyCommandPool(VkCommandPool commandPool) const; void DestroyCommandPool(VkCommandPool commandPool) const;
// AllocateCommandBuffer creates a new command buffer with a primary level. // AllocateCommandBuffer creates a new command buffer with a primary level.
VkResult AllocateCommandBuffer(VkCommandPool pool, VkCommandBuffer* out) const; VkResult AllocateCommandBuffer(VkCommandPool pool, VkCommandBuffer *out) const;
// FreeCommandBuffer frees the VkCommandBuffer. // FreeCommandBuffer frees the VkCommandBuffer.
void FreeCommandBuffer(VkCommandPool pool, VkCommandBuffer buffer); void FreeCommandBuffer(VkCommandPool pool, VkCommandBuffer buffer);
...@@ -137,19 +137,18 @@ public: ...@@ -137,19 +137,18 @@ public:
VkResult QueueSubmitAndWait(VkCommandBuffer commandBuffer) const; VkResult QueueSubmitAndWait(VkCommandBuffer commandBuffer) const;
static VkResult GetPhysicalDevices( static VkResult GetPhysicalDevices(
Driver const *driver, VkInstance instance, Driver const *driver, VkInstance instance,
std::vector<VkPhysicalDevice> &out); std::vector<VkPhysicalDevice> &out);
static int GetComputeQueueFamilyIndex( static int GetComputeQueueFamilyIndex(
Driver const *driver, VkPhysicalDevice device); Driver const *driver, VkPhysicalDevice device);
private: private:
Device(Driver const *driver, VkDevice device, VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); Device(Driver const *driver, VkDevice device, VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex);
static std::vector<VkQueueFamilyProperties> static std::vector<VkQueueFamilyProperties>
GetPhysicalDeviceQueueFamilyProperties( GetPhysicalDeviceQueueFamilyProperties(
Driver const *driver, VkPhysicalDevice device); Driver const *driver, VkPhysicalDevice device);
Driver const *driver; Driver const *driver;
VkDevice device; VkDevice device;
......
...@@ -15,26 +15,27 @@ ...@@ -15,26 +15,27 @@
#include "Driver.hpp" #include "Driver.hpp"
#if defined(_WIN32) #if defined(_WIN32)
# include "Windows.h" # include "Windows.h"
# define OS_WINDOWS 1 # define OS_WINDOWS 1
#elif defined(__APPLE__) #elif defined(__APPLE__)
# include "dlfcn.h" # include "dlfcn.h"
# define OS_MAC 1 # define OS_MAC 1
#elif defined(__ANDROID__) #elif defined(__ANDROID__)
# include "dlfcn.h" # include "dlfcn.h"
# define OS_ANDROID 1 # define OS_ANDROID 1
#elif defined(__linux__) #elif defined(__linux__)
# include "dlfcn.h" # include "dlfcn.h"
# define OS_LINUX 1 # define OS_LINUX 1
#elif defined(__Fuchsia__) #elif defined(__Fuchsia__)
# include <zircon/dlfcn.h> # include <zircon/dlfcn.h>
# define OS_FUCHSIA 1 # define OS_FUCHSIA 1
#else #else
# error Unimplemented platform # error Unimplemented platform
#endif #endif
Driver::Driver() : vk_icdGetInstanceProcAddr(nullptr), dll(nullptr) Driver::Driver()
{ : vk_icdGetInstanceProcAddr(nullptr)
, dll(nullptr){
#define VK_GLOBAL(N, R, ...) N = nullptr #define VK_GLOBAL(N, R, ...) N = nullptr
#include "VkGlobalFuncs.hpp" #include "VkGlobalFuncs.hpp"
#undef VK_GLOBAL #undef VK_GLOBAL
...@@ -42,43 +43,43 @@ Driver::Driver() : vk_icdGetInstanceProcAddr(nullptr), dll(nullptr) ...@@ -42,43 +43,43 @@ Driver::Driver() : vk_icdGetInstanceProcAddr(nullptr), dll(nullptr)
#define VK_INSTANCE(N, R, ...) N = nullptr #define VK_INSTANCE(N, R, ...) N = nullptr
#include "VkInstanceFuncs.hpp" #include "VkInstanceFuncs.hpp"
#undef VK_INSTANCE #undef VK_INSTANCE
} }
Driver::~Driver() Driver::~Driver()
{ {
unload(); unload();
} }
bool Driver::loadSwiftShader() bool Driver::loadSwiftShader()
{ {
#if OS_WINDOWS #if OS_WINDOWS
#if !defined(STANDALONE) # if !defined(STANDALONE)
// The DLL is delay loaded (see BUILD.gn), so we can load // The DLL is delay loaded (see BUILD.gn), so we can load
// the correct ones from Chrome's swiftshader subdirectory. // the correct ones from Chrome's swiftshader subdirectory.
HMODULE libvulkan = LoadLibraryA("swiftshader\\libvulkan.dll"); HMODULE libvulkan = LoadLibraryA("swiftshader\\libvulkan.dll");
EXPECT_NE((HMODULE)NULL, libvulkan); EXPECT_NE((HMODULE)NULL, libvulkan);
return true; return true;
#elif defined(NDEBUG) # elif defined(NDEBUG)
#if defined(_WIN64) # if defined(_WIN64)
return load("./build/Release_x64/vk_swiftshader.dll") || return load("./build/Release_x64/vk_swiftshader.dll") ||
load("./build/Release/vk_swiftshader.dll") || load("./build/Release/vk_swiftshader.dll") ||
load("./vk_swiftshader.dll"); load("./vk_swiftshader.dll");
#else # else
return load("./build/Release_Win32/vk_swiftshader.dll") || return load("./build/Release_Win32/vk_swiftshader.dll") ||
load("./build/Release/vk_swiftshader.dll") || load("./build/Release/vk_swiftshader.dll") ||
load("./vk_swiftshader.dll"); load("./vk_swiftshader.dll");
#endif # endif
#else # else
#if defined(_WIN64) # if defined(_WIN64)
return load("./build/Debug_x64/vk_swiftshader.dll") || return load("./build/Debug_x64/vk_swiftshader.dll") ||
load("./build/Debug/vk_swiftshader.dll") || load("./build/Debug/vk_swiftshader.dll") ||
load("./vk_swiftshader.dll"); load("./vk_swiftshader.dll");
#else # else
return load("./build/Debug_Win32/vk_swiftshader.dll") || return load("./build/Debug_Win32/vk_swiftshader.dll") ||
load("./build/Debug/vk_swiftshader.dll") || load("./build/Debug/vk_swiftshader.dll") ||
load("./vk_swiftshader.dll"); load("./vk_swiftshader.dll");
#endif # endif
#endif # endif
#elif OS_MAC #elif OS_MAC
return load("./build/Darwin/libvk_swiftshader.dylib") || return load("./build/Darwin/libvk_swiftshader.dylib") ||
load("swiftshader/libvk_swiftshader.dylib") || load("swiftshader/libvk_swiftshader.dylib") ||
...@@ -91,65 +92,65 @@ bool Driver::loadSwiftShader() ...@@ -91,65 +92,65 @@ bool Driver::loadSwiftShader()
#elif OS_ANDROID || OS_FUCHSIA #elif OS_ANDROID || OS_FUCHSIA
return load("libvk_swiftshader.so"); return load("libvk_swiftshader.so");
#else #else
#error Unimplemented platform # error Unimplemented platform
#endif #endif
} }
bool Driver::loadSystem() bool Driver::loadSystem()
{ {
#if OS_LINUX #if OS_LINUX
return load("libvulkan.so.1"); return load("libvulkan.so.1");
#else #else
return false; return false;
#endif #endif
} }
bool Driver::load(const char* path) bool Driver::load(const char *path)
{ {
#if OS_WINDOWS #if OS_WINDOWS
dll = LoadLibraryA(path); dll = LoadLibraryA(path);
#elif(OS_MAC || OS_LINUX || OS_ANDROID || OS_FUCHSIA) #elif(OS_MAC || OS_LINUX || OS_ANDROID || OS_FUCHSIA)
dll = dlopen(path, RTLD_LAZY | RTLD_LOCAL); dll = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
#else #else
return false; return false;
#endif #endif
if(dll == nullptr) if(dll == nullptr)
{ {
return false; return false;
} }
// Is the driver an ICD? // Is the driver an ICD?
if(!lookup(&vk_icdGetInstanceProcAddr, "vk_icdGetInstanceProcAddr")) if(!lookup(&vk_icdGetInstanceProcAddr, "vk_icdGetInstanceProcAddr"))
{ {
// Nope, attempt to use the loader version. // Nope, attempt to use the loader version.
if(!lookup(&vk_icdGetInstanceProcAddr, "vkGetInstanceProcAddr")) if(!lookup(&vk_icdGetInstanceProcAddr, "vkGetInstanceProcAddr"))
{ {
return false; return false;
} }
} }
#define VK_GLOBAL(N, R, ...) \ #define VK_GLOBAL(N, R, ...) \
if(auto pfn = vk_icdGetInstanceProcAddr(nullptr, #N)) \ if(auto pfn = vk_icdGetInstanceProcAddr(nullptr, #N)) \
{ \ { \
N = reinterpret_cast<decltype(N)>(pfn); \ N = reinterpret_cast<decltype(N)>(pfn); \
} }
#include "VkGlobalFuncs.hpp" #include "VkGlobalFuncs.hpp"
#undef VK_GLOBAL #undef VK_GLOBAL
return true; return true;
} }
void Driver::unload() void Driver::unload()
{ {
if(!isLoaded()) if(!isLoaded())
{ {
return; return;
} }
#if OS_WINDOWS #if OS_WINDOWS
FreeLibrary((HMODULE)dll); FreeLibrary((HMODULE)dll);
#elif (OS_LINUX || OS_FUCHSIA) #elif(OS_LINUX || OS_FUCHSIA)
dlclose(dll); dlclose(dll);
#endif #endif
#define VK_GLOBAL(N, R, ...) N = nullptr #define VK_GLOBAL(N, R, ...) N = nullptr
...@@ -163,38 +164,38 @@ void Driver::unload() ...@@ -163,38 +164,38 @@ void Driver::unload()
bool Driver::isLoaded() const bool Driver::isLoaded() const
{ {
return dll != nullptr; return dll != nullptr;
} }
bool Driver::resolve(VkInstance instance) bool Driver::resolve(VkInstance instance)
{ {
if(!isLoaded()) if(!isLoaded())
{ {
return false; return false;
} }
#define VK_INSTANCE(N, R, ...) \ #define VK_INSTANCE(N, R, ...) \
if(auto pfn = vk_icdGetInstanceProcAddr(instance, #N)) \ if(auto pfn = vk_icdGetInstanceProcAddr(instance, #N)) \
{ \ { \
N = reinterpret_cast<decltype(N)>(pfn); \ N = reinterpret_cast<decltype(N)>(pfn); \
} \ } \
else \ else \
{ \ { \
return false; \ return false; \
} }
#include "VkInstanceFuncs.hpp" #include "VkInstanceFuncs.hpp"
#undef VK_INSTANCE #undef VK_INSTANCE
return true; return true;
} }
void* Driver::lookup(const char* name) void *Driver::lookup(const char *name)
{ {
#if OS_WINDOWS #if OS_WINDOWS
return GetProcAddress((HMODULE)dll, name); return GetProcAddress((HMODULE)dll, name);
#elif(OS_MAC || OS_LINUX || OS_ANDROID || OS_FUCHSIA) #elif(OS_MAC || OS_LINUX || OS_ANDROID || OS_FUCHSIA)
return dlsym(dll, name); return dlsym(dll, name);
#else #else
return nullptr; return nullptr;
#endif #endif
} }
...@@ -20,69 +20,69 @@ ...@@ -20,69 +20,69 @@
class Driver class Driver
{ {
public: public:
Driver(); Driver();
~Driver(); ~Driver();
// loadSwiftShader attempts to load the SwiftShader vulkan driver. // loadSwiftShader attempts to load the SwiftShader vulkan driver.
// returns true on success, false on failure. // returns true on success, false on failure.
bool loadSwiftShader(); bool loadSwiftShader();
// loadSystem attempts to load the system's vulkan driver. // loadSystem attempts to load the system's vulkan driver.
// returns true on success, false on failure. // returns true on success, false on failure.
bool loadSystem(); bool loadSystem();
// load attempts to load the vulkan driver from the given path. // load attempts to load the vulkan driver from the given path.
// returns true on success, false on failure. // returns true on success, false on failure.
bool load(const char* path); bool load(const char *path);
// unloads the currently loaded driver. // unloads the currently loaded driver.
// No-op if no driver is currently loaded. // No-op if no driver is currently loaded.
void unload(); void unload();
// isLoaded returns true if the driver is currently loaded. // isLoaded returns true if the driver is currently loaded.
bool isLoaded() const; bool isLoaded() const;
// resolve all the functions for the given VkInstance. // resolve all the functions for the given VkInstance.
bool resolve(VkInstance); bool resolve(VkInstance);
VKAPI_ATTR PFN_vkVoidFunction(VKAPI_CALL* vk_icdGetInstanceProcAddr)(VkInstance instance, const char* pName); VKAPI_ATTR PFN_vkVoidFunction(VKAPI_CALL *vk_icdGetInstanceProcAddr)(VkInstance instance, const char *pName);
// Global vulkan function pointers. // Global vulkan function pointers.
#define VK_GLOBAL(N, R, ...) VKAPI_ATTR R (VKAPI_CALL *N)(__VA_ARGS__) #define VK_GLOBAL(N, R, ...) VKAPI_ATTR R(VKAPI_CALL *N)(__VA_ARGS__)
#include "VkGlobalFuncs.hpp" #include "VkGlobalFuncs.hpp"
#undef VK_GLOBAL #undef VK_GLOBAL
// Per-instance vulkan function pointers. // Per-instance vulkan function pointers.
#define VK_INSTANCE(N, R, ...) VKAPI_ATTR R (VKAPI_CALL *N)(__VA_ARGS__) #define VK_INSTANCE(N, R, ...) VKAPI_ATTR R(VKAPI_CALL *N)(__VA_ARGS__)
#include "VkInstanceFuncs.hpp" #include "VkInstanceFuncs.hpp"
#undef VK_INSTANCE #undef VK_INSTANCE
private: private:
Driver(const Driver&) = delete; Driver(const Driver &) = delete;
Driver(Driver&&) = delete; Driver(Driver &&) = delete;
Driver& operator=(const Driver&) = delete; Driver &operator=(const Driver &) = delete;
// lookup searches the loaded driver for a symbol with the given name, // lookup searches the loaded driver for a symbol with the given name,
// returning the address of this symbol if found, otherwise nullptr. // returning the address of this symbol if found, otherwise nullptr.
void* lookup(const char* name); void *lookup(const char *name);
// Helper function to lookup a symbol and cast it to the appropriate type. // Helper function to lookup a symbol and cast it to the appropriate type.
// Returns true if the symbol was found and assigned to ptr, otherwise // Returns true if the symbol was found and assigned to ptr, otherwise
// returns false. // returns false.
template<typename T> template<typename T>
inline bool lookup(T* ptr, const char* name); inline bool lookup(T *ptr, const char *name);
void* dll; void *dll;
}; };
template<typename T> template<typename T>
bool Driver::lookup(T* ptr, const char* name) bool Driver::lookup(T *ptr, const char *name)
{ {
void* sym = lookup(name); void *sym = lookup(name);
if(sym == nullptr) if(sym == nullptr)
{ {
return false; return false;
} }
*ptr = reinterpret_cast<T>(sym); *ptr = reinterpret_cast<T>(sym);
return true; return true;
} }
\ No newline at end of file
...@@ -17,5 +17,5 @@ ...@@ -17,5 +17,5 @@
// TODO: Generate this list. // TODO: Generate this list.
// VK_GLOBAL(<function name>, <return type>, <arguments>...) // VK_GLOBAL(<function name>, <return type>, <arguments>...)
VK_GLOBAL(vkCreateInstance, VkResult, const VkInstanceCreateInfo*, const VkAllocationCallbacks*, VkInstance*); VK_GLOBAL(vkCreateInstance, VkResult, const VkInstanceCreateInfo *, const VkAllocationCallbacks *, VkInstance *);
VK_GLOBAL(vkEnumerateInstanceVersion, VkResult, uint32_t*); VK_GLOBAL(vkEnumerateInstanceVersion, VkResult, uint32_t *);
...@@ -17,53 +17,53 @@ ...@@ -17,53 +17,53 @@
// TODO: Generate this list. // TODO: Generate this list.
// VK_INSTANCE(<function name>, <return type>, <arguments>...) // VK_INSTANCE(<function name>, <return type>, <arguments>...)
VK_INSTANCE(vkAllocateCommandBuffers, VkResult, VkDevice, const VkCommandBufferAllocateInfo*, VkCommandBuffer*); VK_INSTANCE(vkAllocateCommandBuffers, VkResult, VkDevice, const VkCommandBufferAllocateInfo *, VkCommandBuffer *);
VK_INSTANCE(vkAllocateDescriptorSets, VkResult, VkDevice, const VkDescriptorSetAllocateInfo*, VkDescriptorSet*); VK_INSTANCE(vkAllocateDescriptorSets, VkResult, VkDevice, const VkDescriptorSetAllocateInfo *, VkDescriptorSet *);
VK_INSTANCE(vkAllocateMemory, VkResult, VkDevice, const VkMemoryAllocateInfo*, const VkAllocationCallbacks*, VK_INSTANCE(vkAllocateMemory, VkResult, VkDevice, const VkMemoryAllocateInfo *, const VkAllocationCallbacks *,
VkDeviceMemory*); VkDeviceMemory *);
VK_INSTANCE(vkBeginCommandBuffer, VkResult, VkCommandBuffer, const VkCommandBufferBeginInfo*); VK_INSTANCE(vkBeginCommandBuffer, VkResult, VkCommandBuffer, const VkCommandBufferBeginInfo *);
VK_INSTANCE(vkBindBufferMemory, VkResult, VkDevice, VkBuffer, VkDeviceMemory, VkDeviceSize); VK_INSTANCE(vkBindBufferMemory, VkResult, VkDevice, VkBuffer, VkDeviceMemory, VkDeviceSize);
VK_INSTANCE(vkCmdBindDescriptorSets, void, VkCommandBuffer, VkPipelineBindPoint, VkPipelineLayout, uint32_t, uint32_t, VK_INSTANCE(vkCmdBindDescriptorSets, void, VkCommandBuffer, VkPipelineBindPoint, VkPipelineLayout, uint32_t, uint32_t,
const VkDescriptorSet*, uint32_t, const uint32_t*); const VkDescriptorSet *, uint32_t, const uint32_t *);
VK_INSTANCE(vkCmdBindPipeline, void, VkCommandBuffer, VkPipelineBindPoint, VkPipeline); VK_INSTANCE(vkCmdBindPipeline, void, VkCommandBuffer, VkPipelineBindPoint, VkPipeline);
VK_INSTANCE(vkCmdDispatch, void, VkCommandBuffer, uint32_t, uint32_t, uint32_t); VK_INSTANCE(vkCmdDispatch, void, VkCommandBuffer, uint32_t, uint32_t, uint32_t);
VK_INSTANCE(vkCreateBuffer, VkResult, VkDevice, const VkBufferCreateInfo*, const VkAllocationCallbacks*, VkBuffer*); VK_INSTANCE(vkCreateBuffer, VkResult, VkDevice, const VkBufferCreateInfo *, const VkAllocationCallbacks *, VkBuffer *);
VK_INSTANCE(vkCreateCommandPool, VkResult, VkDevice, const VkCommandPoolCreateInfo*, const VkAllocationCallbacks*, VK_INSTANCE(vkCreateCommandPool, VkResult, VkDevice, const VkCommandPoolCreateInfo *, const VkAllocationCallbacks *,
VkCommandPool*); VkCommandPool *);
VK_INSTANCE(vkCreateComputePipelines, VkResult, VkDevice, VkPipelineCache, uint32_t, const VkComputePipelineCreateInfo*, VK_INSTANCE(vkCreateComputePipelines, VkResult, VkDevice, VkPipelineCache, uint32_t, const VkComputePipelineCreateInfo *,
const VkAllocationCallbacks*, VkPipeline*); const VkAllocationCallbacks *, VkPipeline *);
VK_INSTANCE(vkCreateDescriptorPool, VkResult, VkDevice, const VkDescriptorPoolCreateInfo*, const VkAllocationCallbacks*, VK_INSTANCE(vkCreateDescriptorPool, VkResult, VkDevice, const VkDescriptorPoolCreateInfo *, const VkAllocationCallbacks *,
VkDescriptorPool*); VkDescriptorPool *);
VK_INSTANCE(vkCreateDescriptorSetLayout, VkResult, VkDevice, const VkDescriptorSetLayoutCreateInfo*, VK_INSTANCE(vkCreateDescriptorSetLayout, VkResult, VkDevice, const VkDescriptorSetLayoutCreateInfo *,
const VkAllocationCallbacks*, VkDescriptorSetLayout*); const VkAllocationCallbacks *, VkDescriptorSetLayout *);
VK_INSTANCE(vkCreateDevice, VkResult, VkPhysicalDevice, const VkDeviceCreateInfo*, const VkAllocationCallbacks*, VK_INSTANCE(vkCreateDevice, VkResult, VkPhysicalDevice, const VkDeviceCreateInfo *, const VkAllocationCallbacks *,
VkDevice*); VkDevice *);
VK_INSTANCE(vkCreatePipelineLayout, VkResult, VkDevice, const VkPipelineLayoutCreateInfo*, const VkAllocationCallbacks*, VK_INSTANCE(vkCreatePipelineLayout, VkResult, VkDevice, const VkPipelineLayoutCreateInfo *, const VkAllocationCallbacks *,
VkPipelineLayout*); VkPipelineLayout *);
VK_INSTANCE(vkCreateShaderModule, VkResult, VkDevice, const VkShaderModuleCreateInfo*, const VkAllocationCallbacks*, VK_INSTANCE(vkCreateShaderModule, VkResult, VkDevice, const VkShaderModuleCreateInfo *, const VkAllocationCallbacks *,
VkShaderModule*); VkShaderModule *);
VK_INSTANCE(vkDestroyBuffer, void, VkDevice, VkBuffer, const VkAllocationCallbacks*); VK_INSTANCE(vkDestroyBuffer, void, VkDevice, VkBuffer, const VkAllocationCallbacks *);
VK_INSTANCE(vkDestroyCommandPool, void, VkDevice, VkCommandPool, const VkAllocationCallbacks*); VK_INSTANCE(vkDestroyCommandPool, void, VkDevice, VkCommandPool, const VkAllocationCallbacks *);
VK_INSTANCE(vkDestroyDescriptorPool, void, VkDevice, VkDescriptorPool, const VkAllocationCallbacks*); VK_INSTANCE(vkDestroyDescriptorPool, void, VkDevice, VkDescriptorPool, const VkAllocationCallbacks *);
VK_INSTANCE(vkDestroyDescriptorSetLayout, void, VkDevice, VkDescriptorSetLayout, const VkAllocationCallbacks*); VK_INSTANCE(vkDestroyDescriptorSetLayout, void, VkDevice, VkDescriptorSetLayout, const VkAllocationCallbacks *);
VK_INSTANCE(vkDestroyDevice, VkResult, VkDevice, const VkAllocationCallbacks*); VK_INSTANCE(vkDestroyDevice, VkResult, VkDevice, const VkAllocationCallbacks *);
VK_INSTANCE(vkDestroyInstance, void, VkInstance, const VkAllocationCallbacks*); VK_INSTANCE(vkDestroyInstance, void, VkInstance, const VkAllocationCallbacks *);
VK_INSTANCE(vkDestroyPipeline, void, VkDevice, VkPipeline, const VkAllocationCallbacks*); VK_INSTANCE(vkDestroyPipeline, void, VkDevice, VkPipeline, const VkAllocationCallbacks *);
VK_INSTANCE(vkDestroyPipelineLayout, void, VkDevice, VkPipelineLayout, const VkAllocationCallbacks*); VK_INSTANCE(vkDestroyPipelineLayout, void, VkDevice, VkPipelineLayout, const VkAllocationCallbacks *);
VK_INSTANCE(vkDestroyShaderModule, void, VkDevice, VkShaderModule, const VkAllocationCallbacks*); VK_INSTANCE(vkDestroyShaderModule, void, VkDevice, VkShaderModule, const VkAllocationCallbacks *);
VK_INSTANCE(vkEndCommandBuffer, VkResult, VkCommandBuffer); VK_INSTANCE(vkEndCommandBuffer, VkResult, VkCommandBuffer);
VK_INSTANCE(vkEnumeratePhysicalDevices, VkResult, VkInstance, uint32_t*, VkPhysicalDevice*); VK_INSTANCE(vkEnumeratePhysicalDevices, VkResult, VkInstance, uint32_t *, VkPhysicalDevice *);
VK_INSTANCE(vkFreeCommandBuffers, void, VkDevice, VkCommandPool, uint32_t, const VkCommandBuffer*); VK_INSTANCE(vkFreeCommandBuffers, void, VkDevice, VkCommandPool, uint32_t, const VkCommandBuffer *);
VK_INSTANCE(vkFreeMemory, void, VkDevice, VkDeviceMemory, const VkAllocationCallbacks*); VK_INSTANCE(vkFreeMemory, void, VkDevice, VkDeviceMemory, const VkAllocationCallbacks *);
VK_INSTANCE(vkGetDeviceQueue, void, VkDevice, uint32_t, uint32_t, VkQueue*); VK_INSTANCE(vkGetDeviceQueue, void, VkDevice, uint32_t, uint32_t, VkQueue *);
VK_INSTANCE(vkGetPhysicalDeviceMemoryProperties, void, VkPhysicalDevice, VkPhysicalDeviceMemoryProperties*); VK_INSTANCE(vkGetPhysicalDeviceMemoryProperties, void, VkPhysicalDevice, VkPhysicalDeviceMemoryProperties *);
VK_INSTANCE(vkGetPhysicalDeviceProperties, void, VkPhysicalDevice, VkPhysicalDeviceProperties*); VK_INSTANCE(vkGetPhysicalDeviceProperties, void, VkPhysicalDevice, VkPhysicalDeviceProperties *);
VK_INSTANCE(vkGetPhysicalDeviceProperties2, void, VkPhysicalDevice, VkPhysicalDeviceProperties2*); VK_INSTANCE(vkGetPhysicalDeviceProperties2, void, VkPhysicalDevice, VkPhysicalDeviceProperties2 *);
VK_INSTANCE(vkGetPhysicalDeviceQueueFamilyProperties, void, VkPhysicalDevice, uint32_t*, VkQueueFamilyProperties*); VK_INSTANCE(vkGetPhysicalDeviceQueueFamilyProperties, void, VkPhysicalDevice, uint32_t *, VkQueueFamilyProperties *);
VK_INSTANCE(vkMapMemory, VkResult, VkDevice, VkDeviceMemory, VkDeviceSize, VkDeviceSize, VkMemoryMapFlags, void**); VK_INSTANCE(vkMapMemory, VkResult, VkDevice, VkDeviceMemory, VkDeviceSize, VkDeviceSize, VkMemoryMapFlags, void **);
VK_INSTANCE(vkQueueSubmit, VkResult, VkQueue, uint32_t, const VkSubmitInfo*, VkFence); VK_INSTANCE(vkQueueSubmit, VkResult, VkQueue, uint32_t, const VkSubmitInfo *, VkFence);
VK_INSTANCE(vkQueueWaitIdle, VkResult, VkQueue); VK_INSTANCE(vkQueueWaitIdle, VkResult, VkQueue);
VK_INSTANCE(vkUnmapMemory, void, VkDevice, VkDeviceMemory); VK_INSTANCE(vkUnmapMemory, void, VkDevice, VkDeviceMemory);
VK_INSTANCE(vkUpdateDescriptorSets, void, VkDevice, uint32_t, const VkWriteDescriptorSet*, uint32_t, VK_INSTANCE(vkUpdateDescriptorSets, void, VkDevice, uint32_t, const VkWriteDescriptorSet *, uint32_t,
const VkCopyDescriptorSet*); const VkCopyDescriptorSet *);
VK_INSTANCE(vkDeviceWaitIdle, VkResult, VkDevice); VK_INSTANCE(vkDeviceWaitIdle, VkResult, VkDevice);
\ No newline at end of file
...@@ -15,24 +15,23 @@ ...@@ -15,24 +15,23 @@
// Vulkan unit tests that provide coverage for functionality not tested by // Vulkan unit tests that provide coverage for functionality not tested by
// the dEQP test suite. Also used as a smoke test. // the dEQP test suite. Also used as a smoke test.
#include "Driver.hpp"
#include "Device.hpp" #include "Device.hpp"
#include "Driver.hpp"
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "spirv-tools/libspirv.hpp" #include "spirv-tools/libspirv.hpp"
#include <sstream>
#include <cstring> #include <cstring>
#include <sstream>
namespace namespace {
size_t alignUp(size_t val, size_t alignment)
{ {
size_t alignUp(size_t val, size_t alignment) return alignment * ((val + alignment - 1) / alignment);
{ }
return alignment * ((val + alignment - 1) / alignment); } // anonymous namespace
}
} // anonymous namespace
class SwiftShaderVulkanTest : public testing::Test class SwiftShaderVulkanTest : public testing::Test
{ {
...@@ -40,69 +39,69 @@ class SwiftShaderVulkanTest : public testing::Test ...@@ -40,69 +39,69 @@ class SwiftShaderVulkanTest : public testing::Test
TEST_F(SwiftShaderVulkanTest, ICD_Check) TEST_F(SwiftShaderVulkanTest, ICD_Check)
{ {
Driver driver; Driver driver;
ASSERT_TRUE(driver.loadSwiftShader()); ASSERT_TRUE(driver.loadSwiftShader());
auto createInstance = driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateInstance"); auto createInstance = driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateInstance");
EXPECT_NE(createInstance, nullptr); EXPECT_NE(createInstance, nullptr);
auto enumerateInstanceExtensionProperties = auto enumerateInstanceExtensionProperties =
driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
EXPECT_NE(enumerateInstanceExtensionProperties, nullptr); EXPECT_NE(enumerateInstanceExtensionProperties, nullptr);
auto enumerateInstanceLayerProperties = auto enumerateInstanceLayerProperties =
driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceLayerProperties"); driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceLayerProperties");
EXPECT_NE(enumerateInstanceLayerProperties, nullptr); EXPECT_NE(enumerateInstanceLayerProperties, nullptr);
auto enumerateInstanceVersion = driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion"); auto enumerateInstanceVersion = driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion");
EXPECT_NE(enumerateInstanceVersion, nullptr); EXPECT_NE(enumerateInstanceVersion, nullptr);
auto bad_function = driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "bad_function"); auto bad_function = driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "bad_function");
EXPECT_EQ(bad_function, nullptr); EXPECT_EQ(bad_function, nullptr);
} }
TEST_F(SwiftShaderVulkanTest, Version) TEST_F(SwiftShaderVulkanTest, Version)
{ {
Driver driver; Driver driver;
ASSERT_TRUE(driver.loadSwiftShader()); ASSERT_TRUE(driver.loadSwiftShader());
uint32_t apiVersion = 0; uint32_t apiVersion = 0;
VkResult result = driver.vkEnumerateInstanceVersion(&apiVersion); VkResult result = driver.vkEnumerateInstanceVersion(&apiVersion);
EXPECT_EQ(apiVersion, (uint32_t)VK_API_VERSION_1_1); EXPECT_EQ(apiVersion, (uint32_t)VK_API_VERSION_1_1);
const VkInstanceCreateInfo createInfo = { const VkInstanceCreateInfo createInfo = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
nullptr, // pApplicationInfo nullptr, // pApplicationInfo
0, // enabledLayerCount 0, // enabledLayerCount
nullptr, // ppEnabledLayerNames nullptr, // ppEnabledLayerNames
0, // enabledExtensionCount 0, // enabledExtensionCount
nullptr, // ppEnabledExtensionNames nullptr, // ppEnabledExtensionNames
}; };
VkInstance instance = VK_NULL_HANDLE; VkInstance instance = VK_NULL_HANDLE;
result = driver.vkCreateInstance(&createInfo, nullptr, &instance); result = driver.vkCreateInstance(&createInfo, nullptr, &instance);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
ASSERT_TRUE(driver.resolve(instance)); ASSERT_TRUE(driver.resolve(instance));
uint32_t pPhysicalDeviceCount = 0; uint32_t pPhysicalDeviceCount = 0;
result = driver.vkEnumeratePhysicalDevices(instance, &pPhysicalDeviceCount, nullptr); result = driver.vkEnumeratePhysicalDevices(instance, &pPhysicalDeviceCount, nullptr);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
EXPECT_EQ(pPhysicalDeviceCount, 1U); EXPECT_EQ(pPhysicalDeviceCount, 1U);
VkPhysicalDevice pPhysicalDevice = VK_NULL_HANDLE; VkPhysicalDevice pPhysicalDevice = VK_NULL_HANDLE;
result = driver.vkEnumeratePhysicalDevices(instance, &pPhysicalDeviceCount, &pPhysicalDevice); result = driver.vkEnumeratePhysicalDevices(instance, &pPhysicalDeviceCount, &pPhysicalDevice);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
EXPECT_NE(pPhysicalDevice, (VkPhysicalDevice)VK_NULL_HANDLE); EXPECT_NE(pPhysicalDevice, (VkPhysicalDevice)VK_NULL_HANDLE);
VkPhysicalDeviceProperties physicalDeviceProperties; VkPhysicalDeviceProperties physicalDeviceProperties;
driver.vkGetPhysicalDeviceProperties(pPhysicalDevice, &physicalDeviceProperties); driver.vkGetPhysicalDeviceProperties(pPhysicalDevice, &physicalDeviceProperties);
EXPECT_EQ(physicalDeviceProperties.apiVersion, (uint32_t)VK_API_VERSION_1_1); EXPECT_EQ(physicalDeviceProperties.apiVersion, (uint32_t)VK_API_VERSION_1_1);
EXPECT_EQ(physicalDeviceProperties.deviceID, 0xC0DEU); EXPECT_EQ(physicalDeviceProperties.deviceID, 0xC0DEU);
EXPECT_EQ(physicalDeviceProperties.deviceType, VK_PHYSICAL_DEVICE_TYPE_CPU); EXPECT_EQ(physicalDeviceProperties.deviceType, VK_PHYSICAL_DEVICE_TYPE_CPU);
EXPECT_NE(strstr(physicalDeviceProperties.deviceName, "SwiftShader Device"), nullptr); EXPECT_NE(strstr(physicalDeviceProperties.deviceName, "SwiftShader Device"), nullptr);
VkPhysicalDeviceProperties2 physicalDeviceProperties2; VkPhysicalDeviceProperties2 physicalDeviceProperties2;
VkPhysicalDeviceDriverPropertiesKHR physicalDeviceDriverProperties; VkPhysicalDeviceDriverPropertiesKHR physicalDeviceDriverProperties;
...@@ -119,142 +118,141 @@ TEST_F(SwiftShaderVulkanTest, Version) ...@@ -119,142 +118,141 @@ TEST_F(SwiftShaderVulkanTest, Version)
TEST_F(SwiftShaderVulkanTest, UnsupportedDeviceExtension) TEST_F(SwiftShaderVulkanTest, UnsupportedDeviceExtension)
{ {
Driver driver; Driver driver;
ASSERT_TRUE(driver.loadSwiftShader()); ASSERT_TRUE(driver.loadSwiftShader());
uint32_t apiVersion = 0; uint32_t apiVersion = 0;
VkResult result = driver.vkEnumerateInstanceVersion(&apiVersion); VkResult result = driver.vkEnumerateInstanceVersion(&apiVersion);
EXPECT_EQ(apiVersion, (uint32_t)VK_API_VERSION_1_1); EXPECT_EQ(apiVersion, (uint32_t)VK_API_VERSION_1_1);
const VkInstanceCreateInfo createInfo = { const VkInstanceCreateInfo createInfo = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
nullptr, // pApplicationInfo nullptr, // pApplicationInfo
0, // enabledLayerCount 0, // enabledLayerCount
nullptr, // ppEnabledLayerNames nullptr, // ppEnabledLayerNames
0, // enabledExtensionCount 0, // enabledExtensionCount
nullptr, // ppEnabledExtensionNames nullptr, // ppEnabledExtensionNames
}; };
VkInstance instance = VK_NULL_HANDLE; VkInstance instance = VK_NULL_HANDLE;
result = driver.vkCreateInstance(&createInfo, nullptr, &instance); result = driver.vkCreateInstance(&createInfo, nullptr, &instance);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
ASSERT_TRUE(driver.resolve(instance)); ASSERT_TRUE(driver.resolve(instance));
VkBaseInStructure unsupportedExt = { VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT, nullptr }; VkBaseInStructure unsupportedExt = { VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT, nullptr };
// Gather all physical devices // Gather all physical devices
std::vector<VkPhysicalDevice> physicalDevices; std::vector<VkPhysicalDevice> physicalDevices;
result = Device::GetPhysicalDevices(&driver, instance, physicalDevices); result = Device::GetPhysicalDevices(&driver, instance, physicalDevices);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
// Inspect each physical device's queue families for compute support. // Inspect each physical device's queue families for compute support.
for (auto physicalDevice : physicalDevices) for(auto physicalDevice : physicalDevices)
{ {
int queueFamilyIndex = Device::GetComputeQueueFamilyIndex(&driver, physicalDevice); int queueFamilyIndex = Device::GetComputeQueueFamilyIndex(&driver, physicalDevice);
if (queueFamilyIndex < 0) if(queueFamilyIndex < 0)
{ {
continue; continue;
} }
const float queuePrioritory = 1.0f; const float queuePrioritory = 1.0f;
const VkDeviceQueueCreateInfo deviceQueueCreateInfo = { const VkDeviceQueueCreateInfo deviceQueueCreateInfo = {
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
(uint32_t)queueFamilyIndex, // queueFamilyIndex (uint32_t)queueFamilyIndex, // queueFamilyIndex
1, // queueCount 1, // queueCount
&queuePrioritory, // pQueuePriorities &queuePrioritory, // pQueuePriorities
}; };
const VkDeviceCreateInfo deviceCreateInfo = { const VkDeviceCreateInfo deviceCreateInfo = {
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
&unsupportedExt, // pNext &unsupportedExt, // pNext
0, // flags 0, // flags
1, // queueCreateInfoCount 1, // queueCreateInfoCount
&deviceQueueCreateInfo, // pQueueCreateInfos &deviceQueueCreateInfo, // pQueueCreateInfos
0, // enabledLayerCount 0, // enabledLayerCount
nullptr, // ppEnabledLayerNames nullptr, // ppEnabledLayerNames
0, // enabledExtensionCount 0, // enabledExtensionCount
nullptr, // ppEnabledExtensionNames nullptr, // ppEnabledExtensionNames
nullptr, // pEnabledFeatures nullptr, // pEnabledFeatures
}; };
VkDevice device; VkDevice device;
result = driver.vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device); result = driver.vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device);
EXPECT_EQ(result, VK_SUCCESS); EXPECT_EQ(result, VK_SUCCESS);
driver.vkDestroyDevice(device, nullptr); driver.vkDestroyDevice(device, nullptr);
} }
driver.vkDestroyInstance(instance, nullptr); driver.vkDestroyInstance(instance, nullptr);
} }
std::vector<uint32_t> compileSpirv(const char* assembly) std::vector<uint32_t> compileSpirv(const char *assembly)
{ {
spvtools::SpirvTools core(SPV_ENV_VULKAN_1_0); spvtools::SpirvTools core(SPV_ENV_VULKAN_1_0);
core.SetMessageConsumer([](spv_message_level_t, const char*, const spv_position_t& p, const char* m) { core.SetMessageConsumer([](spv_message_level_t, const char *, const spv_position_t &p, const char *m) {
FAIL() << p.line << ":" << p.column << ": " << m; FAIL() << p.line << ":" << p.column << ": " << m;
}); });
std::vector<uint32_t> spirv; std::vector<uint32_t> spirv;
EXPECT_TRUE(core.Assemble(assembly, &spirv)); EXPECT_TRUE(core.Assemble(assembly, &spirv));
EXPECT_TRUE(core.Validate(spirv)); EXPECT_TRUE(core.Validate(spirv));
// Warn if the disassembly does not match the source assembly. // Warn if the disassembly does not match the source assembly.
// We do this as debugging tests in the debugger is often made much harder // We do this as debugging tests in the debugger is often made much harder
// if the SSA names (%X) in the debugger do not match the source. // if the SSA names (%X) in the debugger do not match the source.
std::string disassembled; std::string disassembled;
core.Disassemble(spirv, &disassembled, SPV_BINARY_TO_TEXT_OPTION_NO_HEADER); core.Disassemble(spirv, &disassembled, SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
if (disassembled != assembly) if(disassembled != assembly)
{ {
printf("-- WARNING: Disassembly does not match assembly: ---\n\n"); printf("-- WARNING: Disassembly does not match assembly: ---\n\n");
auto splitLines = [](const std::string& str) -> std::vector<std::string> auto splitLines = [](const std::string &str) -> std::vector<std::string> {
{ std::stringstream ss(str);
std::stringstream ss(str); std::vector<std::string> out;
std::vector<std::string> out; std::string line;
std::string line; while(std::getline(ss, line, '\n')) { out.push_back(line); }
while (std::getline(ss, line, '\n')) { out.push_back(line); } return out;
return out; };
};
auto srcLines = splitLines(std::string(assembly));
auto srcLines = splitLines(std::string(assembly)); auto disLines = splitLines(disassembled);
auto disLines = splitLines(disassembled);
for(size_t line = 0; line < srcLines.size() && line < disLines.size(); line++)
for (size_t line = 0; line < srcLines.size() && line < disLines.size(); line++) {
{ auto srcLine = (line < srcLines.size()) ? srcLines[line] : "<missing>";
auto srcLine = (line < srcLines.size()) ? srcLines[line] : "<missing>"; auto disLine = (line < disLines.size()) ? disLines[line] : "<missing>";
auto disLine = (line < disLines.size()) ? disLines[line] : "<missing>"; if(srcLine != disLine)
if (srcLine != disLine) {
{ printf("%zu: '%s' != '%s'\n", line, srcLine.c_str(), disLine.c_str());
printf("%zu: '%s' != '%s'\n", line, srcLine.c_str(), disLine.c_str()); }
} }
} printf("\n\n---\nExpected:\n\n%s", disassembled.c_str());
printf("\n\n---\nExpected:\n\n%s", disassembled.c_str()); }
}
return spirv;
return spirv;
} }
#define VK_ASSERT(x) ASSERT_EQ(x, VK_SUCCESS) #define VK_ASSERT(x) ASSERT_EQ(x, VK_SUCCESS)
struct ComputeParams struct ComputeParams
{ {
size_t numElements; size_t numElements;
int localSizeX; int localSizeX;
int localSizeY; int localSizeY;
int localSizeZ; int localSizeZ;
friend std::ostream& operator<<(std::ostream& os, const ComputeParams& params) { friend std::ostream &operator<<(std::ostream &os, const ComputeParams &params)
return os << "ComputeParams{" << {
"numElements: " << params.numElements << ", " << return os << "ComputeParams{"
"localSizeX: " << params.localSizeX << ", " << << "numElements: " << params.numElements << ", "
"localSizeY: " << params.localSizeY << ", " << << "localSizeX: " << params.localSizeX << ", "
"localSizeZ: " << params.localSizeZ << << "localSizeY: " << params.localSizeY << ", "
"}"; << "localSizeZ: " << params.localSizeZ << "}";
} }
}; };
// Base class for compute tests that read from an input buffer and write to an // Base class for compute tests that read from an input buffer and write to an
...@@ -262,231 +260,222 @@ struct ComputeParams ...@@ -262,231 +260,222 @@ struct ComputeParams
class SwiftShaderVulkanBufferToBufferComputeTest : public testing::TestWithParam<ComputeParams> class SwiftShaderVulkanBufferToBufferComputeTest : public testing::TestWithParam<ComputeParams>
{ {
public: public:
void test(const std::string& shader, void test(const std::string &shader,
std::function<uint32_t(uint32_t idx)> input, std::function<uint32_t(uint32_t idx)> input,
std::function<uint32_t(uint32_t idx)> expected); std::function<uint32_t(uint32_t idx)> expected);
}; };
void SwiftShaderVulkanBufferToBufferComputeTest::test( void SwiftShaderVulkanBufferToBufferComputeTest::test(
const std::string& shader, const std::string &shader,
std::function<uint32_t(uint32_t idx)> input, std::function<uint32_t(uint32_t idx)> input,
std::function<uint32_t(uint32_t idx)> expected) std::function<uint32_t(uint32_t idx)> expected)
{ {
auto code = compileSpirv(shader.c_str()); auto code = compileSpirv(shader.c_str());
Driver driver; Driver driver;
ASSERT_TRUE(driver.loadSwiftShader()); ASSERT_TRUE(driver.loadSwiftShader());
const VkInstanceCreateInfo createInfo = { const VkInstanceCreateInfo createInfo = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
nullptr, // pNext nullptr, // pNext
0, // flags 0, // flags
nullptr, // pApplicationInfo nullptr, // pApplicationInfo
0, // enabledLayerCount 0, // enabledLayerCount
nullptr, // ppEnabledLayerNames nullptr, // ppEnabledLayerNames
0, // enabledExtensionCount 0, // enabledExtensionCount
nullptr, // ppEnabledExtensionNames nullptr, // ppEnabledExtensionNames
}; };
VkInstance instance = VK_NULL_HANDLE; VkInstance instance = VK_NULL_HANDLE;
VK_ASSERT(driver.vkCreateInstance(&createInfo, nullptr, &instance)); VK_ASSERT(driver.vkCreateInstance(&createInfo, nullptr, &instance));
ASSERT_TRUE(driver.resolve(instance)); ASSERT_TRUE(driver.resolve(instance));
std::unique_ptr<Device> device; std::unique_ptr<Device> device;
VK_ASSERT(Device::CreateComputeDevice(&driver, instance, device)); VK_ASSERT(Device::CreateComputeDevice(&driver, instance, device));
ASSERT_TRUE(device->IsValid()); ASSERT_TRUE(device->IsValid());
// struct Buffers // struct Buffers
// { // {
// uint32_t pad0[63]; // uint32_t pad0[63];
// uint32_t magic0; // uint32_t magic0;
// uint32_t in[NUM_ELEMENTS]; // Aligned to 0x100 // uint32_t in[NUM_ELEMENTS]; // Aligned to 0x100
// uint32_t magic1; // uint32_t magic1;
// uint32_t pad1[N]; // uint32_t pad1[N];
// uint32_t magic2; // uint32_t magic2;
// uint32_t out[NUM_ELEMENTS]; // Aligned to 0x100 // uint32_t out[NUM_ELEMENTS]; // Aligned to 0x100
// uint32_t magic3; // uint32_t magic3;
// }; // };
static constexpr uint32_t magic0 = 0x01234567; static constexpr uint32_t magic0 = 0x01234567;
static constexpr uint32_t magic1 = 0x89abcdef; static constexpr uint32_t magic1 = 0x89abcdef;
static constexpr uint32_t magic2 = 0xfedcba99; static constexpr uint32_t magic2 = 0xfedcba99;
static constexpr uint32_t magic3 = 0x87654321; static constexpr uint32_t magic3 = 0x87654321;
size_t numElements = GetParam().numElements; size_t numElements = GetParam().numElements;
size_t alignElements = 0x100 / sizeof(uint32_t); size_t alignElements = 0x100 / sizeof(uint32_t);
size_t magic0Offset = alignElements - 1; size_t magic0Offset = alignElements - 1;
size_t inOffset = 1 + magic0Offset; size_t inOffset = 1 + magic0Offset;
size_t magic1Offset = numElements + inOffset; size_t magic1Offset = numElements + inOffset;
size_t magic2Offset = alignUp(magic1Offset+1, alignElements) - 1; size_t magic2Offset = alignUp(magic1Offset + 1, alignElements) - 1;
size_t outOffset = 1 + magic2Offset; size_t outOffset = 1 + magic2Offset;
size_t magic3Offset = numElements + outOffset; size_t magic3Offset = numElements + outOffset;
size_t buffersTotalElements = alignUp(1 + magic3Offset, alignElements); size_t buffersTotalElements = alignUp(1 + magic3Offset, alignElements);
size_t buffersSize = sizeof(uint32_t) * buffersTotalElements; size_t buffersSize = sizeof(uint32_t) * buffersTotalElements;
VkDeviceMemory memory; VkDeviceMemory memory;
VK_ASSERT(device->AllocateMemory(buffersSize, VK_ASSERT(device->AllocateMemory(buffersSize,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
&memory)); &memory));
uint32_t* buffers; uint32_t *buffers;
VK_ASSERT(device->MapMemory(memory, 0, buffersSize, 0, (void**)&buffers)); VK_ASSERT(device->MapMemory(memory, 0, buffersSize, 0, (void **)&buffers));
buffers[magic0Offset] = magic0; buffers[magic0Offset] = magic0;
buffers[magic1Offset] = magic1; buffers[magic1Offset] = magic1;
buffers[magic2Offset] = magic2; buffers[magic2Offset] = magic2;
buffers[magic3Offset] = magic3; buffers[magic3Offset] = magic3;
for(size_t i = 0; i < numElements; i++) for(size_t i = 0; i < numElements; i++)
{ {
buffers[inOffset + i] = input(i); buffers[inOffset + i] = input(i);
} }
device->UnmapMemory(memory); device->UnmapMemory(memory);
buffers = nullptr; buffers = nullptr;
VkBuffer bufferIn; VkBuffer bufferIn;
VK_ASSERT(device->CreateStorageBuffer(memory, VK_ASSERT(device->CreateStorageBuffer(memory,
sizeof(uint32_t) * numElements, sizeof(uint32_t) * numElements,
sizeof(uint32_t) * inOffset, sizeof(uint32_t) * inOffset,
&bufferIn)); &bufferIn));
VkBuffer bufferOut; VkBuffer bufferOut;
VK_ASSERT(device->CreateStorageBuffer(memory, VK_ASSERT(device->CreateStorageBuffer(memory,
sizeof(uint32_t) * numElements, sizeof(uint32_t) * numElements,
sizeof(uint32_t) * outOffset, sizeof(uint32_t) * outOffset,
&bufferOut)); &bufferOut));
VkShaderModule shaderModule; VkShaderModule shaderModule;
VK_ASSERT(device->CreateShaderModule(code, &shaderModule)); VK_ASSERT(device->CreateShaderModule(code, &shaderModule));
std::vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings = std::vector<VkDescriptorSetLayoutBinding> descriptorSetLayoutBindings = {
{ {
{ 0, // binding
0, // binding VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType 1, // descriptorCount
1, // descriptorCount VK_SHADER_STAGE_COMPUTE_BIT, // stageFlags
VK_SHADER_STAGE_COMPUTE_BIT, // stageFlags 0, // pImmutableSamplers
0, // pImmutableSamplers },
}, {
{ 1, // binding
1, // binding VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType 1, // descriptorCount
1, // descriptorCount VK_SHADER_STAGE_COMPUTE_BIT, // stageFlags
VK_SHADER_STAGE_COMPUTE_BIT, // stageFlags 0, // pImmutableSamplers
0, // pImmutableSamplers }
} };
};
VkDescriptorSetLayout descriptorSetLayout;
VkDescriptorSetLayout descriptorSetLayout; VK_ASSERT(device->CreateDescriptorSetLayout(descriptorSetLayoutBindings, &descriptorSetLayout));
VK_ASSERT(device->CreateDescriptorSetLayout(descriptorSetLayoutBindings, &descriptorSetLayout));
VkPipelineLayout pipelineLayout;
VkPipelineLayout pipelineLayout; VK_ASSERT(device->CreatePipelineLayout(descriptorSetLayout, &pipelineLayout));
VK_ASSERT(device->CreatePipelineLayout(descriptorSetLayout, &pipelineLayout));
VkPipeline pipeline;
VkPipeline pipeline; VK_ASSERT(device->CreateComputePipeline(shaderModule, pipelineLayout, &pipeline));
VK_ASSERT(device->CreateComputePipeline(shaderModule, pipelineLayout, &pipeline));
VkDescriptorPool descriptorPool;
VkDescriptorPool descriptorPool; VK_ASSERT(device->CreateStorageBufferDescriptorPool(2, &descriptorPool));
VK_ASSERT(device->CreateStorageBufferDescriptorPool(2, &descriptorPool));
VkDescriptorSet descriptorSet;
VkDescriptorSet descriptorSet; VK_ASSERT(device->AllocateDescriptorSet(descriptorPool, descriptorSetLayout, &descriptorSet));
VK_ASSERT(device->AllocateDescriptorSet(descriptorPool, descriptorSetLayout, &descriptorSet));
std::vector<VkDescriptorBufferInfo> descriptorBufferInfos = {
std::vector<VkDescriptorBufferInfo> descriptorBufferInfos = {
{ bufferIn, // buffer
{ 0, // offset
bufferIn, // buffer VK_WHOLE_SIZE, // range
0, // offset },
VK_WHOLE_SIZE, // range {
}, bufferOut, // buffer
{ 0, // offset
bufferOut, // buffer VK_WHOLE_SIZE, // range
0, // offset }
VK_WHOLE_SIZE, // range };
} device->UpdateStorageBufferDescriptorSets(descriptorSet, descriptorBufferInfos);
};
device->UpdateStorageBufferDescriptorSets(descriptorSet, descriptorBufferInfos); VkCommandPool commandPool;
VK_ASSERT(device->CreateCommandPool(&commandPool));
VkCommandPool commandPool;
VK_ASSERT(device->CreateCommandPool(&commandPool)); VkCommandBuffer commandBuffer;
VK_ASSERT(device->AllocateCommandBuffer(commandPool, &commandBuffer));
VkCommandBuffer commandBuffer;
VK_ASSERT(device->AllocateCommandBuffer(commandPool, &commandBuffer)); VK_ASSERT(device->BeginCommandBuffer(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, commandBuffer));
VK_ASSERT(device->BeginCommandBuffer(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, commandBuffer)); driver.vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
driver.vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); driver.vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet,
0, nullptr);
driver.vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet,
0, nullptr); driver.vkCmdDispatch(commandBuffer, numElements / GetParam().localSizeX, 1, 1);
driver.vkCmdDispatch(commandBuffer, numElements / GetParam().localSizeX, 1, 1); VK_ASSERT(driver.vkEndCommandBuffer(commandBuffer));
VK_ASSERT(driver.vkEndCommandBuffer(commandBuffer)); VK_ASSERT(device->QueueSubmitAndWait(commandBuffer));
VK_ASSERT(device->QueueSubmitAndWait(commandBuffer)); VK_ASSERT(device->MapMemory(memory, 0, buffersSize, 0, (void **)&buffers));
VK_ASSERT(device->MapMemory(memory, 0, buffersSize, 0, (void**)&buffers)); for(size_t i = 0; i < numElements; ++i)
{
for (size_t i = 0; i < numElements; ++i) auto got = buffers[i + outOffset];
{ EXPECT_EQ(expected(i), got) << "Unexpected output at " << i;
auto got = buffers[i + outOffset]; }
EXPECT_EQ(expected(i), got) << "Unexpected output at " << i;
} // Check for writes outside of bounds.
EXPECT_EQ(buffers[magic0Offset], magic0);
// Check for writes outside of bounds. EXPECT_EQ(buffers[magic1Offset], magic1);
EXPECT_EQ(buffers[magic0Offset], magic0); EXPECT_EQ(buffers[magic2Offset], magic2);
EXPECT_EQ(buffers[magic1Offset], magic1); EXPECT_EQ(buffers[magic3Offset], magic3);
EXPECT_EQ(buffers[magic2Offset], magic2);
EXPECT_EQ(buffers[magic3Offset], magic3); device->UnmapMemory(memory);
buffers = nullptr;
device->UnmapMemory(memory);
buffers = nullptr; device->FreeCommandBuffer(commandPool, commandBuffer);
device->FreeMemory(memory);
device->FreeCommandBuffer(commandPool, commandBuffer); device->DestroyPipeline(pipeline);
device->FreeMemory(memory); device->DestroyCommandPool(commandPool);
device->DestroyPipeline(pipeline); device->DestroyPipelineLayout(pipelineLayout);
device->DestroyCommandPool(commandPool); device->DestroyDescriptorSetLayout(descriptorSetLayout);
device->DestroyPipelineLayout(pipelineLayout); device->DestroyDescriptorPool(descriptorPool);
device->DestroyDescriptorSetLayout(descriptorSetLayout); device->DestroyBuffer(bufferIn);
device->DestroyDescriptorPool(descriptorPool); device->DestroyBuffer(bufferOut);
device->DestroyBuffer(bufferIn); device->DestroyShaderModule(shaderModule);
device->DestroyBuffer(bufferOut); device.reset(nullptr);
device->DestroyShaderModule(shaderModule); driver.vkDestroyInstance(instance, nullptr);
device.reset(nullptr);
driver.vkDestroyInstance(instance, nullptr);
} }
INSTANTIATE_TEST_SUITE_P(ComputeParams, SwiftShaderVulkanBufferToBufferComputeTest, testing::Values( INSTANTIATE_TEST_SUITE_P(ComputeParams, SwiftShaderVulkanBufferToBufferComputeTest, testing::Values(ComputeParams{ 512, 1, 1, 1 }, ComputeParams{ 512, 2, 1, 1 }, ComputeParams{ 512, 4, 1, 1 }, ComputeParams{ 512, 8, 1, 1 }, ComputeParams{ 512, 16, 1, 1 }, ComputeParams{ 512, 32, 1, 1 },
ComputeParams{512, 1, 1, 1},
ComputeParams{512, 2, 1, 1},
ComputeParams{512, 4, 1, 1},
ComputeParams{512, 8, 1, 1},
ComputeParams{512, 16, 1, 1},
ComputeParams{512, 32, 1, 1},
// Non-multiple of SIMD-lane. // Non-multiple of SIMD-lane.
ComputeParams{3, 1, 1, 1}, ComputeParams{ 3, 1, 1, 1 }, ComputeParams{ 2, 1, 1, 1 }));
ComputeParams{2, 1, 1, 1}
));
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, Memcpy) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, Memcpy)
{ {
std::stringstream src; std::stringstream src;
// #version 450 // #version 450
// layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; // layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
// layout(binding = 0, std430) buffer InBuffer // layout(binding = 0, std430) buffer InBuffer
// { // {
// int Data[]; // int Data[];
// } In; // } In;
// layout(binding = 1, std430) buffer OutBuffer // layout(binding = 1, std430) buffer OutBuffer
// { // {
// int Data[]; // int Data[];
// } Out; // } Out;
// void main() // void main()
// { // {
// Out.Data[gl_GlobalInvocationID.x] = In.Data[gl_GlobalInvocationID.x]; // Out.Data[gl_GlobalInvocationID.x] = In.Data[gl_GlobalInvocationID.x];
// } // }
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -529,13 +518,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, Memcpy) ...@@ -529,13 +518,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, Memcpy)
"OpStore %23 %22\n" // out.arr[gl_GlobalInvocationId.x] = in[gl_GlobalInvocationId.x] "OpStore %23 %22\n" // out.arr[gl_GlobalInvocationId.x] = in[gl_GlobalInvocationId.x]
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, GlobalInvocationId) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, GlobalInvocationId)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -587,14 +579,17 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, GlobalInvocationId) ...@@ -587,14 +579,17 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, GlobalInvocationId)
"OpStore %32 %31\n" // out.arr[gl_GlobalInvocationId.x] = in[gl_GlobalInvocationId.x] + gl_GlobalInvocationId.y + gl_GlobalInvocationId.z "OpStore %32 %31\n" // out.arr[gl_GlobalInvocationId.x] = in[gl_GlobalInvocationId.x] + gl_GlobalInvocationId.y + gl_GlobalInvocationId.z
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
// gl_GlobalInvocationId.y and gl_GlobalInvocationId.z should both be zero. // gl_GlobalInvocationId.y and gl_GlobalInvocationId.z should both be zero.
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchSimple) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchSimple)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -647,13 +642,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchSimple) ...@@ -647,13 +642,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchSimple)
"OpStore %23 %22\n" "OpStore %23 %22\n"
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchDeclareSSA) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchDeclareSSA)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -707,13 +705,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchDeclareSSA) ...@@ -707,13 +705,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchDeclareSSA)
"OpStore %23 %25\n" // use SSA value from previous block "OpStore %23 %25\n" // use SSA value from previous block
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i * 2; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i * 2; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalSimple) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalSimple)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -767,13 +768,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalSimple) ...@@ -767,13 +768,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalSimple)
"OpStore %25 %26\n" // use SSA value from previous block "OpStore %25 %26\n" // use SSA value from previous block
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i%2; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i % 2; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalTwoEmptyBlocks) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalTwoEmptyBlocks)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -831,14 +835,17 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalTwoEmptyBloc ...@@ -831,14 +835,17 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalTwoEmptyBloc
"OpStore %25 %26\n" // use SSA value from previous block "OpStore %25 %26\n" // use SSA value from previous block
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i%2; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i % 2; });
} }
// TODO: Test for parallel assignment // TODO: Test for parallel assignment
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalStore) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalStore)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -897,13 +904,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalStore) ...@@ -897,13 +904,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalStore)
// End of branch logic // End of branch logic
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 0 ? 1 : 2; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 0 ? 1 : 2; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalReturnTrue) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalReturnTrue)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -959,14 +969,17 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalReturnTrue) ...@@ -959,14 +969,17 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalReturnTrue)
// End of branch logic // End of branch logic
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 0 ? 0 : 2; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 0 ? 0 : 2; });
} }
// TODO: Test for parallel assignment // TODO: Test for parallel assignment
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalPhi) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalPhi)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -1025,13 +1038,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalPhi) ...@@ -1025,13 +1038,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, BranchConditionalPhi)
"OpStore %26 %32\n" "OpStore %26 %32\n"
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 0 ? 1 : 2; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 0 ? 1 : 2; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchEmptyCases) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchEmptyCases)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -1088,13 +1104,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchEmptyCases) ...@@ -1088,13 +1104,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchEmptyCases)
"OpStore %25 %26\n" // use SSA value from previous block "OpStore %25 %26\n" // use SSA value from previous block
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i%2; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i % 2; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchStore) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchStore)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -1152,13 +1171,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchStore) ...@@ -1152,13 +1171,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchStore)
// End of branch logic // End of branch logic
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 0 ? 2 : 1; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 0 ? 2 : 1; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchCaseReturn) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchCaseReturn)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -1215,13 +1237,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchCaseReturn) ...@@ -1215,13 +1237,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchCaseReturn)
// End of branch logic // End of branch logic
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 1 ? 0 : 1; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 1 ? 0 : 1; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchDefaultReturn) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchDefaultReturn)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -1278,13 +1303,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchDefaultReturn) ...@@ -1278,13 +1303,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchDefaultReturn)
// End of branch logic // End of branch logic
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 1 ? 1 : 0; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 1 ? 1 : 0; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchCaseFallthrough) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchCaseFallthrough)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -1345,13 +1373,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchCaseFallthrough) ...@@ -1345,13 +1373,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchCaseFallthrough)
// End of branch logic // End of branch logic
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return 2; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return 2; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchDefaultFallthrough) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchDefaultFallthrough)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -1414,13 +1445,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchDefaultFallthrough) ...@@ -1414,13 +1445,16 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchDefaultFallthrough)
// End of branch logic // End of branch logic
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return 2; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return 2; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchPhi) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchPhi)
{ {
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"OpMemoryModel Logical GLSL450\n" "OpMemoryModel Logical GLSL450\n"
...@@ -1478,37 +1512,40 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchPhi) ...@@ -1478,37 +1512,40 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, SwitchPhi)
// End of branch logic // End of branch logic
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
// clang-format on
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 1 ? 1 : 2; }); test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return (i % 2) == 1 ? 1 : 2; });
} }
TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, LoopDivergentMergePhi) TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, LoopDivergentMergePhi)
{ {
// #version 450 // #version 450
// layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; // layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
// layout(binding = 0, std430) buffer InBuffer // layout(binding = 0, std430) buffer InBuffer
// { // {
// int Data[]; // int Data[];
// } In; // } In;
// layout(binding = 1, std430) buffer OutBuffer // layout(binding = 1, std430) buffer OutBuffer
// { // {
// int Data[]; // int Data[];
// } Out; // } Out;
// void main() // void main()
// { // {
// int phi = 0; // int phi = 0;
// uint lane = gl_GlobalInvocationID.x % 4; // uint lane = gl_GlobalInvocationID.x % 4;
// for (uint i = 0; i < 4; i++) // for (uint i = 0; i < 4; i++)
// { // {
// if (lane == i) // if (lane == i)
// { // {
// phi = In.Data[gl_GlobalInvocationID.x]; // phi = In.Data[gl_GlobalInvocationID.x];
// break; // break;
// } // }
// } // }
// Out.Data[gl_GlobalInvocationID.x] = phi; // Out.Data[gl_GlobalInvocationID.x] = phi;
// } // }
std::stringstream src; std::stringstream src;
// clang-format off
src << src <<
"OpCapability Shader\n" "OpCapability Shader\n"
"%1 = OpExtInstImport \"GLSL.std.450\"\n" "%1 = OpExtInstImport \"GLSL.std.450\"\n"
...@@ -1581,5 +1618,8 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, LoopDivergentMergePhi) ...@@ -1581,5 +1618,8 @@ TEST_P(SwiftShaderVulkanBufferToBufferComputeTest, LoopDivergentMergePhi)
"OpStore %42 %41\n" "OpStore %42 %41\n"
"OpReturn\n" "OpReturn\n"
"OpFunctionEnd\n"; "OpFunctionEnd\n";
test(src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i; }); // clang-format on
test(
src.str(), [](uint32_t i) { return i; }, [](uint32_t i) { return i; });
} }
...@@ -24,52 +24,60 @@ ...@@ -24,52 +24,60 @@
#include "Renderer/VertexProcessor.hpp" #include "Renderer/VertexProcessor.hpp"
#include "Shader/VertexProgram.hpp" #include "Shader/VertexProgram.hpp"
#include <cassert>
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <cassert>
namespace { namespace {
// TODO(cwallez@google.com): Like in ANGLE, disable most of the pool allocator for fuzzing // TODO(cwallez@google.com): Like in ANGLE, disable most of the pool allocator for fuzzing
// This is a helper class to make sure all the resources used by the compiler are initialized // This is a helper class to make sure all the resources used by the compiler are initialized
class ScopedPoolAllocatorAndTLS { class ScopedPoolAllocatorAndTLS
public: {
ScopedPoolAllocatorAndTLS() { public:
InitializeParseContextIndex(); ScopedPoolAllocatorAndTLS()
InitializePoolIndex(); {
SetGlobalPoolAllocator(&allocator); InitializeParseContextIndex();
} InitializePoolIndex();
~ScopedPoolAllocatorAndTLS() { SetGlobalPoolAllocator(&allocator);
SetGlobalPoolAllocator(nullptr); }
FreePoolIndex(); ~ScopedPoolAllocatorAndTLS()
FreeParseContextIndex(); {
} SetGlobalPoolAllocator(nullptr);
FreePoolIndex();
FreeParseContextIndex();
}
private: private:
TPoolAllocator allocator; TPoolAllocator allocator;
}; };
// Trivial implementation of the glsl::Shader interface that fakes being an API-level // Trivial implementation of the glsl::Shader interface that fakes being an API-level
// shader object. // shader object.
class FakeVS : public glsl::Shader { class FakeVS : public glsl::Shader
public: {
FakeVS(sw::VertexShader* bytecode) : bytecode(bytecode) { public:
} FakeVS(sw::VertexShader *bytecode)
: bytecode(bytecode)
{
}
sw::Shader *getShader() const override { sw::Shader *getShader() const override
return bytecode; {
} return bytecode;
sw::VertexShader *getVertexShader() const override { }
return bytecode; sw::VertexShader *getVertexShader() const override
} {
return bytecode;
}
private: private:
sw::VertexShader* bytecode; sw::VertexShader *bytecode;
}; };
} // anonymous namespace } // anonymous namespace
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{ {
// Data layout: // Data layout:
// //
...@@ -111,8 +119,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) ...@@ -111,8 +119,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
resources.MaxTextureImageUnits = sw::TEXTURE_IMAGE_UNITS; resources.MaxTextureImageUnits = sw::TEXTURE_IMAGE_UNITS;
resources.MaxFragmentUniformVectors = sw::FRAGMENT_UNIFORM_VECTORS - 3; resources.MaxFragmentUniformVectors = sw::FRAGMENT_UNIFORM_VECTORS - 3;
resources.MaxDrawBuffers = sw::RENDERTARGETS; resources.MaxDrawBuffers = sw::RENDERTARGETS;
resources.MaxVertexOutputVectors = 16; // ??? resources.MaxVertexOutputVectors = 16; // ???
resources.MaxFragmentInputVectors = 15; // ??? resources.MaxFragmentInputVectors = 15; // ???
resources.MinProgramTexelOffset = sw::MIN_PROGRAM_TEXEL_OFFSET; resources.MinProgramTexelOffset = sw::MIN_PROGRAM_TEXEL_OFFSET;
resources.MaxProgramTexelOffset = sw::MAX_PROGRAM_TEXEL_OFFSET; resources.MaxProgramTexelOffset = sw::MAX_PROGRAM_TEXEL_OFFSET;
resources.OES_standard_derivatives = 1; resources.OES_standard_derivatives = 1;
...@@ -125,8 +133,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) ...@@ -125,8 +133,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
glslCompiler->Init(resources); glslCompiler->Init(resources);
const char* glslSource = reinterpret_cast<const char*>(data + kHeaderSize); const char *glslSource = reinterpret_cast<const char *>(data + kHeaderSize);
if (!glslCompiler->compile(&glslSource, 1, SH_OBJECT_CODE)) if(!glslCompiler->compile(&glslSource, 1, SH_OBJECT_CODE))
{ {
return 0; return 0;
} }
...@@ -146,7 +154,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) ...@@ -146,7 +154,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
state.transformFeedbackEnabled = (data[0] & 0x10) != 0; state.transformFeedbackEnabled = (data[0] & 0x10) != 0;
state.verticesPerPrimitive = 1 + ((data[0] & 0x20) != 0) + ((data[0] & 0x40) != 0); state.verticesPerPrimitive = 1 + ((data[0] & 0x20) != 0) + ((data[0] & 0x40) != 0);
if((data[0] & 0x80) != 0) // Unused/reserved. if((data[0] & 0x80) != 0) // Unused/reserved.
{ {
return 0; return 0;
} }
...@@ -163,7 +171,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) ...@@ -163,7 +171,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
for(int i = 0; i < sw::MAX_VERTEX_INPUTS; i++) for(int i = 0; i < sw::MAX_VERTEX_INPUTS; i++)
{ {
sw::StreamType type = (sw::StreamType)data[1 + 2 * i + 0]; sw::StreamType type = (sw::StreamType)data[1 + 2 * i + 0];
Stream stream = (Stream&)data[1 + 2 * i + 1]; Stream stream = (Stream &)data[1 + 2 * i + 1];
if(type > sw::STREAMTYPE_LAST) return 0; if(type > sw::STREAMTYPE_LAST) return 0;
if(stream.count > MAX_ATTRIBUTE_COMPONENTS) return 0; if(stream.count > MAX_ATTRIBUTE_COMPONENTS) return 0;
...@@ -178,10 +186,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) ...@@ -178,10 +186,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
for(unsigned int i = 0; i < sw::VERTEX_TEXTURE_IMAGE_UNITS; i++) for(unsigned int i = 0; i < sw::VERTEX_TEXTURE_IMAGE_UNITS; i++)
{ {
// TODO // TODO
// if(bytecodeShader->usesSampler(i)) // if(bytecodeShader->usesSampler(i))
// { // {
// state.samplerState[i] = context->sampler[sw::TEXTURE_IMAGE_UNITS + i].samplerState(); // state.samplerState[i] = context->sampler[sw::TEXTURE_IMAGE_UNITS + i].samplerState();
// } // }
for(int j = 0; j < 32; j++) for(int j = 0; j < 32; j++)
{ {
...@@ -206,7 +214,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) ...@@ -206,7 +214,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
auto routine = program("VertexRoutine"); auto routine = program("VertexRoutine");
assert(routine); assert(routine);
const void *entry = routine->getEntry(); const void *entry = routine->getEntry();
assert(entry); (void)entry; assert(entry);
(void)entry;
return 0; return 0;
} }
...@@ -219,7 +228,7 @@ int main(int argc, char *argv[]) ...@@ -219,7 +228,7 @@ int main(int argc, char *argv[])
fseek(file, 0L, SEEK_END); fseek(file, 0L, SEEK_END);
long numbytes = ftell(file); long numbytes = ftell(file);
fseek(file, 0L, SEEK_SET); fseek(file, 0L, SEEK_SET);
uint8_t *buffer = (uint8_t*)calloc(numbytes, sizeof(uint8_t)); uint8_t *buffer = (uint8_t *)calloc(numbytes, sizeof(uint8_t));
fread(buffer, sizeof(char), numbytes, file); fread(buffer, sizeof(char), numbytes, file);
fclose(file); fclose(file);
......
---
Language: Cpp
DisableFormat: true
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