Exemplo n.º 1
0
gl::LinkResult ProgramGL::load(const gl::Context *context,
                               gl::InfoLog &infoLog,
                               gl::BinaryInputStream *stream)
{
    preLink();

    // Read the binary format, size and blob
    GLenum binaryFormat   = stream->readInt<GLenum>();
    GLint binaryLength    = stream->readInt<GLint>();
    const uint8_t *binary = stream->data() + stream->offset();
    stream->skip(binaryLength);

    // Load the binary
    mFunctions->programBinary(mProgramID, binaryFormat, binary, binaryLength);

    // Verify that the program linked
    if (!checkLinkStatus(infoLog))
    {
        return false;
    }

    postLink();
    reapplyUBOBindingsIfNeeded(context);

    return true;
}
Exemplo n.º 2
0
/* Shader Program Helper
 This function will attempt to create a shader program that has
 the Vertex and Fragement shader code that you pass in. If successfully
 compiled and linked to the program, the unique program ID given by
 OpenGL will be returned. This ID will be >1 if successful, or 0 (an
 invalid ID) if any of the above fails.

 Most of the Code below is for checking if the shaders compiled and
 linked correctly.
 */
GLuint CreateShaderProgram(const std::string &vsSource,
                           const std::string &fsSource) {
  GLuint programID = glCreateProgram();
  GLuint vsID = glCreateShader(GL_VERTEX_SHADER);
  GLuint fsID = glCreateShader(GL_FRAGMENT_SHADER);

  if (programID == 0 || vsID == 0 || fsID == 0) {
    // Clean up others that were created
    glDeleteProgram(programID);
    glDeleteShader(vsID);
    glDeleteShader(fsID);

    std::cerr << "Cannot create Shaders or Program" << std::endl;
    return 0; // invalid ID
  }

  // glShaderSource() expects char**, so these are helper variables
  const char *vsSourceArray = vsSource.c_str();
  const char *fsSourceArray = fsSource.c_str();

  // https://www.opengl.org/sdk/docs/man4/xhtml/glShaderSource.xml
  glShaderSource(vsID, 1, &vsSourceArray, NULL);

  glShaderSource(fsID, 1, &fsSourceArray, NULL);

  // Compile the Shader Sources, check for errors
  glCompileShader(vsID);
  glCompileShader(fsID);

  if (!checkCompileStatus(vsID) || !checkCompileStatus(fsID)) {
    // Clean up others that were created
    glDeleteProgram(programID);
    glDeleteShader(vsID);
    glDeleteShader(fsID);

    std::cerr << "Cannot create Shaders or Program" << std::endl;
    return 0; // invalid ID
  }

  glAttachShader(programID, vsID);
  glAttachShader(programID, fsID);

  glLinkProgram(programID);

  if (!checkLinkStatus(programID)) {
    // Clean up others that were created
    glDeleteProgram(programID);
    glDeleteShader(vsID);
    glDeleteShader(fsID);

    std::cerr << "Cannot create Shaders or Program" << std::endl;
    return 0; // invalid ID
  }

  return programID;
}
Exemplo n.º 3
0
void Shader::createProgram()
{
    m_Program = glCreateProgram();

    glAttachShader(m_Program, m_VertexShader);
    glAttachShader(m_Program, m_FragmentShader);

    glLinkProgram(m_Program);

    checkLinkStatus();
}
Exemplo n.º 4
0
GrGLProgram* GrGLProgramBuilder::finalize() {
    // verify we can get a program id
    GrGLuint programID;
    GL_CALL_RET(programID, CreateProgram());
    if (0 == programID) {
        this->cleanupFragmentProcessors();
        return nullptr;
    }

    // compile shaders and bind attributes / uniforms
    SkTDArray<GrGLuint> shadersToDelete;
    fVS.finalize(GrGLSLUniformHandler::kVertex_Visibility);
    if (!this->compileAndAttachShaders(fVS, programID, GR_GL_VERTEX_SHADER, &shadersToDelete)) {
        this->cleanupProgram(programID, shadersToDelete);
        return nullptr;
    }

    // NVPR actually requires a vertex shader to compile
    bool useNvpr = primitiveProcessor().isPathRendering();
    if (!useNvpr) {
        const GrPrimitiveProcessor& primProc = this->primitiveProcessor();

        int vaCount = primProc.numAttribs();
        for (int i = 0; i < vaCount; i++) {
            GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).fName));
        }
    }

    fFS.finalize(GrGLSLUniformHandler::kFragment_Visibility);
    if (!this->compileAndAttachShaders(fFS, programID, GR_GL_FRAGMENT_SHADER, &shadersToDelete)) {
        this->cleanupProgram(programID, shadersToDelete);
        return nullptr;
    }

    this->bindProgramResourceLocations(programID);

    GL_CALL(LinkProgram(programID));

    // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
    bool checkLinked = kChromium_GrGLDriver != fGpu->ctxInfo().driver();
#ifdef SK_DEBUG
    checkLinked = true;
#endif
    if (checkLinked) {
        checkLinkStatus(programID);
    }
    this->resolveProgramResourceLocations(programID);

    this->cleanupShaders(shadersToDelete);

    return this->createProgram(programID);
}
GrGLProgram* GrGLProgramBuilder::finalize() {
    // verify we can get a program id
    GrGLuint programID;
    GL_CALL_RET(programID, CreateProgram());
    if (0 == programID) {
        return NULL;
    }

    // compile shaders and bind attributes / uniforms
    SkTDArray<GrGLuint> shadersToDelete;

    if (!fVS.compileAndAttachShaders(programID, &shadersToDelete)) {
        this->cleanupProgram(programID, shadersToDelete);
        return NULL;
    }

    // NVPR actually requires a vertex shader to compile
    bool useNvpr = primitiveProcessor().isPathRendering();
    if (!useNvpr) {
        fVS.bindVertexAttributes(programID);
    }

    if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) {
        this->cleanupProgram(programID, shadersToDelete);
        return NULL;
    }

    bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
    if (usingBindUniform) {
        this->bindUniformLocations(programID);
    }
    fFS.bindFragmentShaderLocations(programID);
    GL_CALL(LinkProgram(programID));

    // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
    bool checkLinked = !fGpu->ctxInfo().isChromium();
#ifdef SK_DEBUG
    checkLinked = true;
#endif
    if (checkLinked) {
        checkLinkStatus(programID);
    }
    if (!usingBindUniform) {
        this->resolveUniformLocations(programID);
    }

    this->cleanupShaders(shadersToDelete);

    return this->createProgram(programID);
}
Exemplo n.º 6
0
GLuint Shader::ComputeByGPU(const char* computeShaderName)
{
	const char *computeShaderSource = loadComputeFile(computeShaderName);
	GLuint computeShaderID = glCreateShader(GL_COMPUTE_SHADER);
	glShaderSource(computeShaderID, 1, &computeShaderSource, NULL);
	glCompileShader(computeShaderID);
	checkCompileStatus(computeShaderID, computeShaderName);

	GLuint program = glCreateProgram();
	glAttachShader(program, computeShaderID);
	glLinkProgram(program);
	checkLinkStatus(program, computeShaderName);
	return program;
}
Exemplo n.º 7
0
void StereoBlitProgram::initializeShaders() {
    glow::Shader* vertShader = glowutils::createShaderFromFile(GL_VERTEX_SHADER, "data/shader/blit/stereoblit.vert");
    glow::Shader* fragShader = glowutils::createShaderFromFile(GL_FRAGMENT_SHADER, "data/shader/blit/stereoblit.frag");

    bindAttributeLocation(ScreenQuad::VERTEX_ATTRIBUTE_LOCATION, "v_vertex");

    attach(vertShader, fragShader);
    link();
    assert(checkLinkStatus());

    bindFragDataLocation(0, "fragColor");

    getUniform<GLint>("texture")->set(BlitProgram::TEXTURE_LOCATION);
}
Exemplo n.º 8
0
void Program::link() const
{
    m_linked = false;

    if (!binaryImplementation().updateProgramLinkSource(this))
        return;

    glLinkProgram(id());

    m_linked = checkLinkStatus();
	m_dirty = false;

    updateUniforms();
    updateUniformBlockBindings();
}
Exemplo n.º 9
0
LinkResult ProgramGL::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
{
    preLink();

    // Read the binary format, size and blob
    GLenum binaryFormat   = stream->readInt<GLenum>();
    GLint binaryLength    = stream->readInt<GLint>();
    const uint8_t *binary = stream->data() + stream->offset();
    stream->skip(binaryLength);

    // Load the binary
    mFunctions->programBinary(mProgramID, binaryFormat, binary, binaryLength);

    // Verify that the program linked
    if (!checkLinkStatus(infoLog))
    {
        return LinkResult(false, gl::Error(GL_NO_ERROR));
    }

    postLink();

    return LinkResult(true, gl::Error(GL_NO_ERROR));
}
Exemplo n.º 10
0
LinkResult ProgramGL::link(const gl::ContextState &data, gl::InfoLog &infoLog)
{
    preLink();

    // Set the transform feedback state
    std::vector<const GLchar *> transformFeedbackVaryings;
    for (const auto &tfVarying : mState.getTransformFeedbackVaryingNames())
    {
        transformFeedbackVaryings.push_back(tfVarying.c_str());
    }

    if (transformFeedbackVaryings.empty())
    {
        if (mFunctions->transformFeedbackVaryings)
        {
            mFunctions->transformFeedbackVaryings(mProgramID, 0, nullptr,
                                                  mState.getTransformFeedbackBufferMode());
        }
    }
    else
    {
        ASSERT(mFunctions->transformFeedbackVaryings);
        mFunctions->transformFeedbackVaryings(
            mProgramID, static_cast<GLsizei>(transformFeedbackVaryings.size()),
            &transformFeedbackVaryings[0], mState.getTransformFeedbackBufferMode());
    }

    const ShaderGL *vertexShaderGL   = GetImplAs<ShaderGL>(mState.getAttachedVertexShader());
    const ShaderGL *fragmentShaderGL = GetImplAs<ShaderGL>(mState.getAttachedFragmentShader());

    // Attach the shaders
    mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID());
    mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID());

    // Bind attribute locations to match the GL layer.
    for (const sh::Attribute &attribute : mState.getAttributes())
    {
        if (!attribute.staticUse)
        {
            continue;
        }

        mFunctions->bindAttribLocation(mProgramID, attribute.location, attribute.name.c_str());
    }

    // Link and verify
    mFunctions->linkProgram(mProgramID);

    // Detach the shaders
    mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID());
    mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID());

    // Verify the link
    if (!checkLinkStatus(infoLog))
    {
        return LinkResult(false, gl::Error(GL_NO_ERROR));
    }

    if (mWorkarounds.alwaysCallUseProgramAfterLink)
    {
        mStateManager->forceUseProgram(mProgramID);
    }

    postLink();

    return LinkResult(true, gl::Error(GL_NO_ERROR));
}
Exemplo n.º 11
0
gl::LinkResult ProgramGL::link(const gl::Context *context,
                               const gl::ProgramLinkedResources &resources,
                               gl::InfoLog &infoLog)
{
    preLink();

    if (mState.getAttachedComputeShader())
    {
        const ShaderGL *computeShaderGL = GetImplAs<ShaderGL>(mState.getAttachedComputeShader());

        mFunctions->attachShader(mProgramID, computeShaderGL->getShaderID());

        // Link and verify
        mFunctions->linkProgram(mProgramID);

        // Detach the shaders
        mFunctions->detachShader(mProgramID, computeShaderGL->getShaderID());
    }
    else
    {
        // Set the transform feedback state
        std::vector<std::string> transformFeedbackVaryingMappedNames;
        for (const auto &tfVarying : mState.getTransformFeedbackVaryingNames())
        {
            std::string tfVaryingMappedName =
                mState.getAttachedVertexShader()->getTransformFeedbackVaryingMappedName(tfVarying,
                                                                                        context);
            transformFeedbackVaryingMappedNames.push_back(tfVaryingMappedName);
        }

        if (transformFeedbackVaryingMappedNames.empty())
        {
            if (mFunctions->transformFeedbackVaryings)
            {
                mFunctions->transformFeedbackVaryings(mProgramID, 0, nullptr,
                                                      mState.getTransformFeedbackBufferMode());
            }
        }
        else
        {
            ASSERT(mFunctions->transformFeedbackVaryings);
            std::vector<const GLchar *> transformFeedbackVaryings;
            for (const auto &varying : transformFeedbackVaryingMappedNames)
            {
                transformFeedbackVaryings.push_back(varying.c_str());
            }
            mFunctions->transformFeedbackVaryings(
                mProgramID, static_cast<GLsizei>(transformFeedbackVaryingMappedNames.size()),
                &transformFeedbackVaryings[0], mState.getTransformFeedbackBufferMode());
        }

        const ShaderGL *vertexShaderGL   = GetImplAs<ShaderGL>(mState.getAttachedVertexShader());
        const ShaderGL *fragmentShaderGL = GetImplAs<ShaderGL>(mState.getAttachedFragmentShader());
        const ShaderGL *geometryShaderGL =
            rx::SafeGetImplAs<ShaderGL, gl::Shader>(mState.getAttachedGeometryShader());

        // Attach the shaders
        mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID());
        mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID());
        if (geometryShaderGL)
        {
            mFunctions->attachShader(mProgramID, geometryShaderGL->getShaderID());
        }

        // Bind attribute locations to match the GL layer.
        for (const sh::Attribute &attribute : mState.getAttributes())
        {
            if (!attribute.staticUse || attribute.isBuiltIn())
            {
                continue;
            }

            mFunctions->bindAttribLocation(mProgramID, attribute.location,
                                           attribute.mappedName.c_str());
        }

        // Link and verify
        mFunctions->linkProgram(mProgramID);

        // Detach the shaders
        mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID());
        mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID());
        if (geometryShaderGL)
        {
            mFunctions->detachShader(mProgramID, geometryShaderGL->getShaderID());
        }
    }

    // Verify the link
    if (!checkLinkStatus(infoLog))
    {
        return false;
    }

    if (mWorkarounds.alwaysCallUseProgramAfterLink)
    {
        mStateManager->forceUseProgram(mProgramID);
    }

    linkResources(resources);
    postLink();

    return true;
}