Commit ca03b35c by Jamie Madill

Re-land "Compute packed varyings in ProgramD3D only."

Instead of storing varying information in the shader, use a temporary set when linking a D3D program. This also means we won't have to modify information in the Shader object when linking a D3D program. This completes the refactoring for PackedVaryings. Re-land with fix for missing init of PackedVarying::vertexOnly. BUG=angleproject:1123 Change-Id: If110809c3817d88b0370ac575d739d7385b067d9 Reviewed-on: https://chromium-review.googlesource.com/296731Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 3a86ad38
...@@ -46,14 +46,36 @@ struct PixelShaderOutputVariable ...@@ -46,14 +46,36 @@ struct PixelShaderOutputVariable
size_t outputIndex; size_t outputIndex;
}; };
struct PackedVarying
{
PackedVarying(const sh::Varying &varyingIn)
: varying(&varyingIn), registerIndex(GL_INVALID_INDEX), columnIndex(0), vertexOnly(false)
{
}
bool registerAssigned() const { return registerIndex != GL_INVALID_INDEX; }
void resetRegisterAssignment() { registerIndex = GL_INVALID_INDEX; }
const sh::Varying *varying;
// Assigned during link
unsigned int registerIndex;
// Assigned during link, Defaults to 0
unsigned int columnIndex;
// Transform feedback varyings can be only referenced in the VS.
bool vertexOnly;
};
class DynamicHLSL : angle::NonCopyable class DynamicHLSL : angle::NonCopyable
{ {
public: public:
explicit DynamicHLSL(RendererD3D *const renderer); explicit DynamicHLSL(RendererD3D *const renderer);
int packVaryings(gl::InfoLog &infoLog, int packVaryings(gl::InfoLog &infoLog,
ShaderD3D *fragmentShader, std::vector<PackedVarying> *packedVaryings,
ShaderD3D *vertexShader,
const std::vector<std::string> &transformFeedbackVaryings); const std::vector<std::string> &transformFeedbackVaryings);
std::string generateVertexShaderForInputLayout(const std::string &sourceShader, std::string generateVertexShaderForInputLayout(const std::string &sourceShader,
const gl::InputLayout &inputLayout, const gl::InputLayout &inputLayout,
...@@ -66,13 +88,14 @@ class DynamicHLSL : angle::NonCopyable ...@@ -66,13 +88,14 @@ class DynamicHLSL : angle::NonCopyable
int registers, int registers,
std::string &pixelHLSL, std::string &pixelHLSL,
std::string &vertexHLSL, std::string &vertexHLSL,
const std::vector<PackedVarying> &packedVaryings,
std::vector<gl::LinkedVarying> *linkedVaryings, std::vector<gl::LinkedVarying> *linkedVaryings,
std::vector<PixelShaderOutputVariable> *outPixelShaderKey, std::vector<PixelShaderOutputVariable> *outPixelShaderKey,
bool *outUsesFragDepth) const; bool *outUsesFragDepth) const;
std::string generateGeometryShaderHLSL(int registers, std::string generateGeometryShaderHLSL(int registers,
const ShaderD3D *fragmentShader, const ShaderD3D *fragmentShader,
const ShaderD3D *vertexShader) const; const std::vector<PackedVarying> &packedVaryings) const;
private: private:
RendererD3D *const mRenderer; RendererD3D *const mRenderer;
...@@ -83,12 +106,15 @@ class DynamicHLSL : angle::NonCopyable ...@@ -83,12 +106,15 @@ class DynamicHLSL : angle::NonCopyable
SemanticInfo getSemanticInfo(int startRegisters, bool position, bool fragCoord, bool pointCoord, SemanticInfo getSemanticInfo(int startRegisters, bool position, bool fragCoord, bool pointCoord,
bool pointSize, bool pixelShader) const; bool pointSize, bool pixelShader) const;
std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const; std::string generateVaryingLinkHLSL(const SemanticInfo &info, const std::string &varyingHLSL) const;
std::string generateVaryingHLSL(const ShaderD3D *shader) const; std::string generateVaryingHLSL(const std::vector<PackedVarying> &varyings,
void storeUserLinkedVaryings(const ShaderD3D *vertexShader, std::vector<gl::LinkedVarying> *linkedVaryings) const; bool shaderUsesPointSize) const;
void storeUserLinkedVaryings(const std::vector<PackedVarying> &packedVaryings,
bool shaderUsesPointSize,
std::vector<gl::LinkedVarying> *linkedVaryings) const;
void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<gl::LinkedVarying> *linkedVaryings) const; void storeBuiltinLinkedVaryings(const SemanticInfo &info, std::vector<gl::LinkedVarying> *linkedVaryings) const;
std::string generatePointSpriteHLSL(int registers, std::string generatePointSpriteHLSL(int registers,
const ShaderD3D *fragmentShader, const ShaderD3D *fragmentShader,
const ShaderD3D *vertexShader) const; const std::vector<PackedVarying> &packedVaryings) const;
// Prepend an underscore // Prepend an underscore
static std::string decorateVariable(const std::string &name); static std::string decorateVariable(const std::string &name);
......
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DynamicHLSL unittests:
// Tests for DynamicHLSL and related classes.
//
#include <gtest/gtest.h>
#include "libANGLE/renderer/d3d/DynamicHLSL.h"
using namespace rx;
namespace
{
TEST(PackedVarying, DefaultInitialization)
{
sh::Varying defaultVarying;
PackedVarying pv(defaultVarying);
EXPECT_EQ(&defaultVarying, pv.varying);
EXPECT_EQ(GL_INVALID_INDEX, pv.registerIndex);
EXPECT_EQ(0, pv.columnIndex);
EXPECT_FALSE(pv.vertexOnly);
}
} // anonymous namespace
...@@ -127,37 +127,48 @@ struct AttributeSorter ...@@ -127,37 +127,48 @@ struct AttributeSorter
const ProgramD3D::SemanticIndexArray *originalIndices; const ProgramD3D::SemanticIndexArray *originalIndices;
}; };
bool LinkVaryingRegisters(gl::InfoLog &infoLog, std::vector<PackedVarying> MergeVaryings(const gl::Shader &vertexShader,
ShaderD3D *vertexShaderD3D, const gl::Shader &fragmentShader,
ShaderD3D *fragmentShaderD3D) const std::vector<std::string> &tfVaryings)
{ {
for (PackedVarying &input : fragmentShaderD3D->getPackedVaryings()) std::vector<PackedVarying> packedVaryings;
for (const sh::Varying &output : vertexShader.getVaryings())
{ {
bool matched = false; bool packed = false;
// Built-in varyings obey special rules // Built-in varyings obey special rules
if (input.varying->isBuiltIn()) if (output.isBuiltIn())
{ {
continue; continue;
} }
for (PackedVarying &output : vertexShaderD3D->getPackedVaryings()) for (const sh::Varying &input : fragmentShader.getVaryings())
{ {
if (output.varying->name == input.varying->name) if (output.name == input.name)
{ {
output.registerIndex = input.registerIndex; packedVaryings.push_back(PackedVarying(input));
output.columnIndex = input.columnIndex; packed = true;
matched = true;
break; break;
} }
} }
// We permit unmatched, unreferenced varyings // Keep Transform FB varyings in the merged list always.
ASSERT(matched || !input.varying->staticUse); if (!packed)
{
for (const std::string &tfVarying : tfVaryings)
{
if (tfVarying == output.name)
{
packedVaryings.push_back(PackedVarying(output));
packedVaryings.back().vertexOnly = true;
break;
}
}
}
} }
return true; return packedVaryings;
} }
} // anonymous namespace } // anonymous namespace
...@@ -1048,9 +1059,10 @@ gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::InputLayout &i ...@@ -1048,9 +1059,10 @@ gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::InputLayout &i
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, int registers) LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog,
int registers,
const std::vector<PackedVarying> &packedVaryings)
{ {
const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(mData.getAttachedVertexShader());
const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(mData.getAttachedFragmentShader()); const ShaderD3D *fragmentShaderD3D = GetImplAs<ShaderD3D>(mData.getAttachedFragmentShader());
const gl::InputLayout &defaultInputLayout = const gl::InputLayout &defaultInputLayout =
...@@ -1072,7 +1084,8 @@ LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, int regis ...@@ -1072,7 +1084,8 @@ LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, int regis
if (usesGeometryShader()) if (usesGeometryShader())
{ {
std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, vertexShaderD3D); std::string geometryHLSL =
mDynamicHLSL->generateGeometryShaderHLSL(registers, fragmentShaderD3D, packedVaryings);
error = mRenderer->compileToExecutable( error = mRenderer->compileToExecutable(
infoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings, infoLog, geometryHLSL, SHADER_GEOMETRY, mTransformFeedbackLinkedVaryings,
...@@ -1085,6 +1098,8 @@ LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, int regis ...@@ -1085,6 +1098,8 @@ LinkResult ProgramD3D::compileProgramExecutables(gl::InfoLog &infoLog, int regis
} }
#if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED #if ANGLE_SHADER_DEBUG_INFO == ANGLE_ENABLED
const ShaderD3D *vertexShaderD3D = GetImplAs<ShaderD3D>(mData.getAttachedVertexShader());
if (usesGeometryShader() && mGeometryExecutable) if (usesGeometryShader() && mGeometryExecutable)
{ {
// Geometry shaders are currently only used internally, so there is no corresponding shader object at the interface level // Geometry shaders are currently only used internally, so there is no corresponding shader object at the interface level
...@@ -1136,8 +1151,11 @@ LinkResult ProgramD3D::link(const gl::Data &data, ...@@ -1136,8 +1151,11 @@ LinkResult ProgramD3D::link(const gl::Data &data,
} }
} }
std::vector<PackedVarying> packedVaryings =
MergeVaryings(*vertexShader, *fragmentShader, mData.getTransformFeedbackVaryingNames());
// Map the varyings to the register file // Map the varyings to the register file
int registers = mDynamicHLSL->packVaryings(infoLog, fragmentShaderD3D, vertexShaderD3D, int registers = mDynamicHLSL->packVaryings(infoLog, &packedVaryings,
mData.getTransformFeedbackVaryingNames()); mData.getTransformFeedbackVaryingNames());
if (registers < 0) if (registers < 0)
...@@ -1145,12 +1163,10 @@ LinkResult ProgramD3D::link(const gl::Data &data, ...@@ -1145,12 +1163,10 @@ LinkResult ProgramD3D::link(const gl::Data &data,
return LinkResult(false, gl::Error(GL_NO_ERROR)); return LinkResult(false, gl::Error(GL_NO_ERROR));
} }
LinkVaryingRegisters(infoLog, vertexShaderD3D, fragmentShaderD3D);
std::vector<gl::LinkedVarying> linkedVaryings; std::vector<gl::LinkedVarying> linkedVaryings;
if (!mDynamicHLSL->generateShaderLinkHLSL(data, mData, infoLog, registers, mPixelHLSL, if (!mDynamicHLSL->generateShaderLinkHLSL(data, mData, infoLog, registers, mPixelHLSL,
mVertexHLSL, &linkedVaryings, &mPixelShaderKey, mVertexHLSL, packedVaryings, &linkedVaryings,
&mUsesFragDepth)) &mPixelShaderKey, &mUsesFragDepth))
{ {
return LinkResult(false, gl::Error(GL_NO_ERROR)); return LinkResult(false, gl::Error(GL_NO_ERROR));
} }
...@@ -1168,7 +1184,7 @@ LinkResult ProgramD3D::link(const gl::Data &data, ...@@ -1168,7 +1184,7 @@ LinkResult ProgramD3D::link(const gl::Data &data,
gatherTransformFeedbackVaryings(linkedVaryings); gatherTransformFeedbackVaryings(linkedVaryings);
LinkResult result = compileProgramExecutables(infoLog, registers); LinkResult result = compileProgramExecutables(infoLog, registers, packedVaryings);
if (result.error.isError() || !result.linkSuccess) if (result.error.isError() || !result.linkSuccess)
{ {
infoLog << "Failed to create D3D shaders."; infoLog << "Failed to create D3D shaders.";
......
...@@ -207,7 +207,9 @@ class ProgramD3D : public ProgramImpl ...@@ -207,7 +207,9 @@ class ProgramD3D : public ProgramImpl
sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes, sh::BlockLayoutEncoder *encoder, std::vector<unsigned int> *blockUniformIndexes,
bool inRowMajorLayout); bool inRowMajorLayout);
LinkResult compileProgramExecutables(gl::InfoLog &infoLog, int registers); LinkResult compileProgramExecutables(gl::InfoLog &infoLog,
int registers,
const std::vector<PackedVarying> &packedVaryings);
void gatherTransformFeedbackVaryings(const std::vector<gl::LinkedVarying> &varyings); void gatherTransformFeedbackVaryings(const std::vector<gl::LinkedVarying> &varyings);
......
...@@ -110,11 +110,6 @@ void ShaderD3D::parseVaryings(ShHandle compiler) ...@@ -110,11 +110,6 @@ void ShaderD3D::parseVaryings(ShHandle compiler)
mVaryings = *varyings; mVaryings = *varyings;
for (size_t varyingIndex = 0; varyingIndex < varyings->size(); varyingIndex++)
{
mPackedVaryings.push_back(PackedVarying(mVaryings[varyingIndex]));
}
mUsesMultipleRenderTargets = mTranslatedSource.find("GL_USES_MRT") != std::string::npos; mUsesMultipleRenderTargets = mTranslatedSource.find("GL_USES_MRT") != std::string::npos;
mUsesFragColor = mTranslatedSource.find("GL_USES_FRAG_COLOR") != std::string::npos; mUsesFragColor = mTranslatedSource.find("GL_USES_FRAG_COLOR") != std::string::npos;
mUsesFragData = mTranslatedSource.find("GL_USES_FRAG_DATA") != std::string::npos; mUsesFragData = mTranslatedSource.find("GL_USES_FRAG_DATA") != std::string::npos;
...@@ -131,14 +126,6 @@ void ShaderD3D::parseVaryings(ShHandle compiler) ...@@ -131,14 +126,6 @@ void ShaderD3D::parseVaryings(ShHandle compiler)
} }
} }
void ShaderD3D::resetVaryingsRegisterAssignment()
{
for (size_t varyingIndex = 0; varyingIndex < mVaryings.size(); varyingIndex++)
{
mPackedVaryings[varyingIndex].resetRegisterAssignment();
}
}
// initialize/clean up previous state // initialize/clean up previous state
void ShaderD3D::uncompile() void ShaderD3D::uncompile()
{ {
......
...@@ -20,24 +20,6 @@ namespace rx ...@@ -20,24 +20,6 @@ namespace rx
class DynamicHLSL; class DynamicHLSL;
class RendererD3D; class RendererD3D;
struct PackedVarying
{
PackedVarying(const sh::Varying &varyingIn)
: varying(&varyingIn), registerIndex(GL_INVALID_INDEX), columnIndex(0)
{
}
bool registerAssigned() const { return registerIndex != GL_INVALID_INDEX; }
void resetRegisterAssignment() { registerIndex = GL_INVALID_INDEX; }
const sh::Varying *varying;
// TODO(jmadill): Make these D3D-only or otherwise clearly separate from GL.
unsigned int registerIndex; // Assigned during link
unsigned int columnIndex; // Assigned during link, defaults to 0
};
class ShaderD3D : public ShaderImpl class ShaderD3D : public ShaderImpl
{ {
friend class DynamicHLSL; friend class DynamicHLSL;
...@@ -51,7 +33,6 @@ class ShaderD3D : public ShaderImpl ...@@ -51,7 +33,6 @@ class ShaderD3D : public ShaderImpl
// D3D-specific methods // D3D-specific methods
virtual void uncompile(); virtual void uncompile();
void resetVaryingsRegisterAssignment();
unsigned int getUniformRegister(const std::string &uniformName) const; unsigned int getUniformRegister(const std::string &uniformName) const;
unsigned int getInterfaceBlockRegister(const std::string &blockName) const; unsigned int getInterfaceBlockRegister(const std::string &blockName) const;
void appendDebugInfo(const std::string &info) { mDebugInfo += info; } void appendDebugInfo(const std::string &info) { mDebugInfo += info; }
...@@ -68,11 +49,6 @@ class ShaderD3D : public ShaderImpl ...@@ -68,11 +49,6 @@ class ShaderD3D : public ShaderImpl
virtual bool compile(gl::Compiler *compiler, const std::string &source); virtual bool compile(gl::Compiler *compiler, const std::string &source);
const std::vector<PackedVarying> &getPackedVaryings() const { return mPackedVaryings; }
// TODO(jmadill): remove this
std::vector<PackedVarying> &getPackedVaryings() { return mPackedVaryings; }
private: private:
void compileToHLSL(ShHandle compiler, const std::string &source); void compileToHLSL(ShHandle compiler, const std::string &source);
void parseVaryings(ShHandle compiler); void parseVaryings(ShHandle compiler);
...@@ -100,7 +76,6 @@ class ShaderD3D : public ShaderImpl ...@@ -100,7 +76,6 @@ class ShaderD3D : public ShaderImpl
std::map<std::string, unsigned int> mUniformRegisterMap; std::map<std::string, unsigned int> mUniformRegisterMap;
std::map<std::string, unsigned int> mInterfaceBlockRegisterMap; std::map<std::string, unsigned int> mInterfaceBlockRegisterMap;
RendererD3D *mRenderer; RendererD3D *mRenderer;
std::vector<PackedVarying> mPackedVaryings;
}; };
} }
......
...@@ -75,8 +75,10 @@ ...@@ -75,8 +75,10 @@
'<(angle_path)/src/tests/test_utils/compiler_test.cpp', '<(angle_path)/src/tests/test_utils/compiler_test.cpp',
'<(angle_path)/src/tests/test_utils/compiler_test.h', '<(angle_path)/src/tests/test_utils/compiler_test.h',
], ],
# TODO(jmadill): should probably call this windows sources
'angle_unittests_hlsl_sources': 'angle_unittests_hlsl_sources':
[ [
'<(angle_path)/src/libANGLE/renderer/d3d/DynamicHLSL_unittest.cpp',
'<(angle_path)/src/tests/compiler_tests/UnrollFlatten_test.cpp', '<(angle_path)/src/tests/compiler_tests/UnrollFlatten_test.cpp',
], ],
}, },
......
...@@ -264,6 +264,71 @@ TEST_P(TransformFeedbackTest, BufferBinding) ...@@ -264,6 +264,71 @@ TEST_P(TransformFeedbackTest, BufferBinding)
glDeleteBuffers(1, &scratchBuffer); glDeleteBuffers(1, &scratchBuffer);
} }
// Test that we can capture varyings only used in the vertex shader.
TEST_P(TransformFeedbackTest, VertexOnly)
{
const std::string &vertexShaderSource =
"#version 300 es\n"
"in vec2 position;\n"
"in float attrib;\n"
"out float varyingAttrib;\n"
"void main() {\n"
" gl_Position = vec4(position, 0, 1);\n"
" varyingAttrib = attrib;\n"
"}";
const std::string &fragmentShaderSource =
"#version 300 es\n"
"out mediump vec4 color;\n"
"void main() {\n"
" color = vec4(0.0, 1.0, 0.0, 1.0);\n"
"}";
std::vector<std::string> tfVaryings;
tfVaryings.push_back("varyingAttrib");
GLuint program = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource,
tfVaryings, GL_INTERLEAVED_ATTRIBS);
ASSERT_NE(0u, program);
GLuint transformFeedback;
glGenTransformFeedbacks(1, &transformFeedback);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer);
std::vector<float> attribData;
for (unsigned int cnt = 0; cnt < 100; ++cnt)
{
attribData.push_back(static_cast<float>(cnt));
}
GLint attribLocation = glGetAttribLocation(program, "attrib");
ASSERT_NE(-1, attribLocation);
glVertexAttribPointer(attribLocation, 1, GL_FLOAT, GL_FALSE, 4, &attribData[0]);
glEnableVertexAttribArray(attribLocation);
glBeginTransformFeedback(GL_TRIANGLES);
drawQuad(program, "position", 0.5f);
glEndTransformFeedback();
ASSERT_GL_NO_ERROR();
GLvoid *mappedBuffer =
glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(float) * 6, GL_MAP_READ_BIT);
ASSERT_NE(nullptr, mappedBuffer);
float *mappedFloats = static_cast<float *>(mappedBuffer);
for (unsigned int cnt = 0; cnt < 6; ++cnt)
{
EXPECT_EQ(attribData[cnt], mappedFloats[cnt]);
}
glDeleteTransformFeedbacks(1, &transformFeedback);
glDeleteProgram(program);
EXPECT_GL_NO_ERROR();
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(TransformFeedbackTest, ES3_D3D11()); ANGLE_INSTANTIATE_TEST(TransformFeedbackTest, ES3_D3D11());
......
...@@ -69,7 +69,11 @@ GLuint CompileShaderFromFile(GLenum type, const std::string &sourcePath) ...@@ -69,7 +69,11 @@ GLuint CompileShaderFromFile(GLenum type, const std::string &sourcePath)
return CompileShader(type, source); return CompileShader(type, source);
} }
GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource) GLuint CompileProgramWithTransformFeedback(
const std::string &vsSource,
const std::string &fsSource,
const std::vector<std::string> &transformFeedbackVaryings,
GLenum bufferMode)
{ {
GLuint program = glCreateProgram(); GLuint program = glCreateProgram();
...@@ -90,6 +94,19 @@ GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource) ...@@ -90,6 +94,19 @@ GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource)
glAttachShader(program, fs); glAttachShader(program, fs);
glDeleteShader(fs); glDeleteShader(fs);
if (transformFeedbackVaryings.size() > 0)
{
std::vector<const char *> constCharTFVaryings;
for (const std::string &transformFeedbackVarying : transformFeedbackVaryings)
{
constCharTFVaryings.push_back(transformFeedbackVarying.c_str());
}
glTransformFeedbackVaryings(program, static_cast<GLsizei>(transformFeedbackVaryings.size()),
&constCharTFVaryings[0], bufferMode);
}
glLinkProgram(program); glLinkProgram(program);
GLint linkStatus; GLint linkStatus;
...@@ -112,6 +129,12 @@ GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource) ...@@ -112,6 +129,12 @@ GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource)
return program; return program;
} }
GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource)
{
std::vector<std::string> emptyVector;
return CompileProgramWithTransformFeedback(vsSource, fsSource, emptyVector, GL_NONE);
}
GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath) GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath)
{ {
std::string vsSource = ReadFileToString(vsPath); std::string vsSource = ReadFileToString(vsPath);
......
...@@ -17,12 +17,18 @@ ...@@ -17,12 +17,18 @@
#include <EGL/eglext.h> #include <EGL/eglext.h>
#include <string> #include <string>
#include <vector>
#define SHADER_SOURCE(...) #__VA_ARGS__ #define SHADER_SOURCE(...) #__VA_ARGS__
GLuint CompileShader(GLenum type, const std::string &source); GLuint CompileShader(GLenum type, const std::string &source);
GLuint CompileShaderFromFile(GLenum type, const std::string &sourcePath); GLuint CompileShaderFromFile(GLenum type, const std::string &sourcePath);
GLuint CompileProgramWithTransformFeedback(
const std::string &vsSource,
const std::string &fsSource,
const std::vector<std::string> &transformFeedbackVaryings,
GLenum bufferMode);
GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource); GLuint CompileProgram(const std::string &vsSource, const std::string &fsSource);
GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath); GLuint CompileProgramFromFiles(const std::string &vsPath, const std::string &fsPath);
......
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