示例#1
0
void CopyProgramAttribBindings(const GLHookSet &gl, GLuint progsrc, GLuint progdst,
                               ShaderReflection *refl)
{
  // copy over attrib bindings
  for(const SigParameter &sig : refl->inputSignature)
  {
    // skip built-ins
    if(sig.systemValue != ShaderBuiltin::Undefined)
      continue;

    GLint idx = gl.glGetAttribLocation(progsrc, sig.varName.c_str());
    if(idx >= 0)
      gl.glBindAttribLocation(progdst, (GLuint)idx, sig.varName.c_str());
  }
}
示例#2
0
void CopyProgramFragDataBindings(const GLHookSet &gl, GLuint progsrc, GLuint progdst,
                                 ShaderReflection *refl)
{
  uint64_t used = 0;

  // copy over fragdata bindings
  for(size_t i = 0; i < refl->outputSignature.size(); i++)
  {
    // only look at colour outputs (should be the only outputs from fs)
    if(refl->outputSignature[i].systemValue != ShaderBuiltin::ColorOutput)
      continue;

    if(!strncmp("gl_", refl->outputSignature[i].varName.c_str(), 3))
      continue;    // GL_INVALID_OPERATION if name starts with reserved gl_ prefix

    GLint idx = gl.glGetFragDataLocation(progsrc, refl->outputSignature[i].varName.c_str());
    if(idx >= 0)
    {
      uint64_t mask = 1ULL << idx;

      if(used & mask)
      {
        RDCWARN("Multiple signatures bound to output %zu, ignoring %s", i,
                refl->outputSignature[i].varName.c_str());
        continue;
      }

      used |= mask;

      if(gl.glBindFragDataLocation)
      {
        gl.glBindFragDataLocation(progdst, (GLuint)idx, refl->outputSignature[i].varName.c_str());
      }
      else
      {
        // glBindFragDataLocation is not core GLES, but it is in GL_EXT_blend_func_extended
        // TODO what to do if that extension is not supported
        RDCERR("glBindFragDataLocation is not supported!");
      }
    }
  }
}
示例#3
0
void GetFramebufferMipAndLayer(const GLHookSet &gl, GLenum framebuffer, GLenum attachment,
                               GLint *mip, GLint *layer)
{
  gl.glGetFramebufferAttachmentParameteriv(framebuffer, attachment,
                                           eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, mip);

  GLenum face = eGL_NONE;
  gl.glGetFramebufferAttachmentParameteriv(
      framebuffer, attachment, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint *)&face);

  if(face == 0)
  {
    gl.glGetFramebufferAttachmentParameteriv(framebuffer, attachment,
                                             eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, layer);
  }
  else
  {
    *layer = CubeTargetIndex(face);
  }
}
示例#4
0
int GetNumMips(const GLHookSet &gl, GLenum target, GLuint tex, GLuint w, GLuint h, GLuint d)
{
	int mips = 1;

	GLint immut = 0;
	gl.glGetTextureParameterivEXT(tex, target, eGL_TEXTURE_IMMUTABLE_FORMAT, &immut);

	if(immut)
		gl.glGetTextureParameterivEXT(tex, target, eGL_TEXTURE_IMMUTABLE_LEVELS, (GLint *)&mips);
	else
		mips = CalcNumMips(w, h, d);

	GLint maxLevel = 1000;
	gl.glGetTextureParameterivEXT(tex, target, eGL_TEXTURE_MAX_LEVEL, &maxLevel);
	mips = RDCMIN(mips, maxLevel+1);

	if(immut == 0)
	{
		// check to see if all mips are set, or clip the number of mips to those that are
		// set.
		if(target == eGL_TEXTURE_CUBE_MAP)
			target = eGL_TEXTURE_CUBE_MAP_POSITIVE_X;

		for(int i=0; i < mips; i++)
		{
			GLint width = 0;
			gl.glGetTextureLevelParameterivEXT(tex, target, i, eGL_TEXTURE_WIDTH, &width);
			if(width == 0)
			{
				mips = i;
				break;
			}
		}
	}

	return RDCMAX(1, mips);
}
示例#5
0
void SerialiseProgramBindings(SerialiserType &ser, CaptureState state, const GLHookSet &gl,
                              GLuint prog)
{
  std::vector<ProgramBinding> InputBindings;
  std::vector<ProgramBinding> OutputBindings;

  if(ser.IsWriting())
  {
    char buf[128] = {};

    for(int sigType = 0; sigType < 2; sigType++)
    {
      GLenum sigEnum = (sigType == 0 ? eGL_PROGRAM_INPUT : eGL_PROGRAM_OUTPUT);
      std::vector<ProgramBinding> &bindings = (sigType == 0 ? InputBindings : OutputBindings);

      int32_t NumAttributes = 0;
      gl.glGetProgramInterfaceiv(prog, sigEnum, eGL_ACTIVE_RESOURCES, (GLint *)&NumAttributes);
      bindings.reserve(NumAttributes);

      for(GLint i = 0; i < NumAttributes; i++)
      {
        gl.glGetProgramResourceName(prog, sigEnum, i, 128, NULL, buf);

        ProgramBinding bind;
        bind.Name = buf;

        if(sigType == 0)
          bind.Binding = gl.glGetAttribLocation(prog, buf);
        else
          bind.Binding = gl.glGetFragDataLocation(prog, buf);

        bindings.push_back(bind);
      }
    }
  }

  SERIALISE_ELEMENT(InputBindings);
  SERIALISE_ELEMENT(OutputBindings);

  if(ser.IsReading() && IsReplayMode(state))
  {
    for(int sigType = 0; sigType < 2; sigType++)
    {
      const std::vector<ProgramBinding> &bindings = (sigType == 0 ? InputBindings : OutputBindings);

      uint64_t used = 0;

      for(const ProgramBinding &bind : bindings)
      {
        if(bind.Binding >= 0)
        {
          uint64_t mask = 1ULL << bind.Binding;

          if(used & mask)
          {
            RDCWARN("Multiple %s items bound to location %d, ignoring %s",
                    sigType == 0 ? "attrib" : "fragdata", bind.Binding, bind.Name.c_str());
            continue;
          }

          used |= mask;

          if(!strncmp("gl_", bind.Name.c_str(), 3))
            continue;    // GL_INVALID_OPERATION if name starts with reserved gl_ prefix (for both
                         // glBindAttribLocation and glBindFragDataLocation)

          if(sigType == 0)
          {
            gl.glBindAttribLocation(prog, (GLuint)bind.Binding, bind.Name.c_str());
          }
          else
          {
            if(gl.glBindFragDataLocation)
            {
              gl.glBindFragDataLocation(prog, (GLuint)bind.Binding, bind.Name.c_str());
            }
            else
            {
              // glBindFragDataLocation is not core GLES, but it is in GL_EXT_blend_func_extended
              // TODO what to do if that extension is not supported
              RDCERR("glBindFragDataLocation is not supported!");
            }
          }
        }
      }
    }
  }
}
示例#6
0
static void ForAllProgramUniforms(SerialiserType *ser, CaptureState state, const GLHookSet &gl,
                                  GLuint progSrc, GLuint progDst, map<GLint, GLint> *locTranslate)
{
  const bool ReadSourceProgram = CopyUniforms || (SerialiseUniforms && ser && ser->IsWriting());
  const bool WriteDestProgram = CopyUniforms || (SerialiseUniforms && ser && ser->IsReading());

  RDCCOMPILE_ASSERT((CopyUniforms && !SerialiseUniforms) || (!CopyUniforms && SerialiseUniforms),
                    "Invalid call to ForAllProgramUniforms");

  // this struct will be serialised with the uniform binding data, or if we're just copying it will
  // be used to store the data fetched from the source program, before being applied to the
  // destination program. It's slightly redundant since we could unify the loops (as the code used
  // to do) but it's much better for code organisation and clarity to have a single path whether
  // serialising or not.
  ProgramUniforms serialisedUniforms;

  // if we're reading the source program, iterate over the interfaces and fetch the data.
  if(CheckConstParam(ReadSourceProgram))
  {
    const size_t numProps = 5;
    GLenum resProps[numProps] = {
        eGL_BLOCK_INDEX, eGL_TYPE, eGL_NAME_LENGTH, eGL_ARRAY_SIZE, eGL_LOCATION,
    };
    GLint values[numProps];

    GLint NumUniforms = 0;
    gl.glGetProgramInterfaceiv(progSrc, eGL_UNIFORM, eGL_ACTIVE_RESOURCES, &NumUniforms);

    // this is a very conservative figure - many uniforms will be in UBOs and so will be ignored
    serialisedUniforms.ValueUniforms.reserve(NumUniforms);

    for(GLint i = 0; i < NumUniforms; i++)
    {
      GLenum type = eGL_NONE;
      int32_t arraySize = 0;
      int32_t srcLocation = 0;
      string basename;
      bool isArray = false;

      gl.glGetProgramResourceiv(progSrc, eGL_UNIFORM, i, numProps, resProps, numProps, NULL, values);

      // we don't need to consider uniforms within UBOs
      if(values[0] >= 0)
        continue;

      // get the metadata we need for fetching the data
      type = (GLenum)values[1];
      arraySize = values[3];
      srcLocation = values[4];

      char n[1024] = {0};
      gl.glGetProgramResourceName(progSrc, eGL_UNIFORM, i, values[2], NULL, n);

      if(arraySize > 1)
      {
        isArray = true;

        size_t len = strlen(n);

        if(n[len - 3] == '[' && n[len - 2] == '0' && n[len - 1] == ']')
          n[len - 3] = 0;
      }
      else
      {
        arraySize = 1;
      }

      basename = n;

      // push it onto the list
      serialisedUniforms.ValueUniforms.push_back(ProgramUniform());
      ProgramUniform &uniform = serialisedUniforms.ValueUniforms.back();

      uniform.Basename = basename;
      uniform.IsArray = isArray;
      uniform.Values.resize(arraySize);

      // loop over every element in the array (arraySize = 1 for non arrays)
      for(GLint arr = 0; arr < arraySize; arr++)
      {
        ProgramUniformValue &uniformVal = uniform.Values[arr];
        uniformVal.Type = type;
        uniformVal.Location = srcLocation;

        std::string name = basename;

        // append the subscript if this item is an array.
        if(isArray)
        {
          name += StringFormat::Fmt("[%d]", arr);

          uniformVal.Location = srcLocation = gl.glGetUniformLocation(progSrc, name.c_str());
        }

        // fetch the data into the ProgramUniformValue, with the appropriate method for its type
        double *dv = uniformVal.data.dval;
        float *fv = uniformVal.data.fval;
        int32_t *iv = uniformVal.data.ival;
        uint32_t *uiv = uniformVal.data.uval;

        switch(type)
        {
          case eGL_FLOAT_MAT4:
          case eGL_FLOAT_MAT4x3:
          case eGL_FLOAT_MAT4x2:
          case eGL_FLOAT_MAT3:
          case eGL_FLOAT_MAT3x4:
          case eGL_FLOAT_MAT3x2:
          case eGL_FLOAT_MAT2:
          case eGL_FLOAT_MAT2x4:
          case eGL_FLOAT_MAT2x3:
          case eGL_FLOAT:
          case eGL_FLOAT_VEC2:
          case eGL_FLOAT_VEC3:
          case eGL_FLOAT_VEC4: gl.glGetUniformfv(progSrc, srcLocation, fv); break;
          case eGL_DOUBLE_MAT4:
          case eGL_DOUBLE_MAT4x3:
          case eGL_DOUBLE_MAT4x2:
          case eGL_DOUBLE_MAT3:
          case eGL_DOUBLE_MAT3x4:
          case eGL_DOUBLE_MAT3x2:
          case eGL_DOUBLE_MAT2:
          case eGL_DOUBLE_MAT2x4:
          case eGL_DOUBLE_MAT2x3:
          case eGL_DOUBLE:
          case eGL_DOUBLE_VEC2:
          case eGL_DOUBLE_VEC3:
          case eGL_DOUBLE_VEC4:
            gl.glGetUniformdv(progSrc, srcLocation, dv);
            break;

          // treat all samplers as just an int (since they just store their binding value)
          case eGL_SAMPLER_1D:
          case eGL_SAMPLER_2D:
          case eGL_SAMPLER_3D:
          case eGL_SAMPLER_CUBE:
          case eGL_SAMPLER_CUBE_MAP_ARRAY:
          case eGL_SAMPLER_1D_SHADOW:
          case eGL_SAMPLER_2D_SHADOW:
          case eGL_SAMPLER_1D_ARRAY:
          case eGL_SAMPLER_2D_ARRAY:
          case eGL_SAMPLER_1D_ARRAY_SHADOW:
          case eGL_SAMPLER_2D_ARRAY_SHADOW:
          case eGL_SAMPLER_2D_MULTISAMPLE:
          case eGL_SAMPLER_2D_MULTISAMPLE_ARRAY:
          case eGL_SAMPLER_CUBE_SHADOW:
          case eGL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
          case eGL_SAMPLER_BUFFER:
          case eGL_SAMPLER_2D_RECT:
          case eGL_SAMPLER_2D_RECT_SHADOW:
          case eGL_INT_SAMPLER_1D:
          case eGL_INT_SAMPLER_2D:
          case eGL_INT_SAMPLER_3D:
          case eGL_INT_SAMPLER_CUBE:
          case eGL_INT_SAMPLER_CUBE_MAP_ARRAY:
          case eGL_INT_SAMPLER_1D_ARRAY:
          case eGL_INT_SAMPLER_2D_ARRAY:
          case eGL_INT_SAMPLER_2D_MULTISAMPLE:
          case eGL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
          case eGL_INT_SAMPLER_BUFFER:
          case eGL_INT_SAMPLER_2D_RECT:
          case eGL_UNSIGNED_INT_SAMPLER_1D:
          case eGL_UNSIGNED_INT_SAMPLER_2D:
          case eGL_UNSIGNED_INT_SAMPLER_3D:
          case eGL_UNSIGNED_INT_SAMPLER_CUBE:
          case eGL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
          case eGL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
          case eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
          case eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
          case eGL_UNSIGNED_INT_SAMPLER_BUFFER:
          case eGL_UNSIGNED_INT_SAMPLER_2D_RECT:
          case eGL_IMAGE_1D:
          case eGL_IMAGE_2D:
          case eGL_IMAGE_3D:
          case eGL_IMAGE_2D_RECT:
          case eGL_IMAGE_CUBE:
          case eGL_IMAGE_BUFFER:
          case eGL_IMAGE_1D_ARRAY:
          case eGL_IMAGE_2D_ARRAY:
          case eGL_IMAGE_CUBE_MAP_ARRAY:
          case eGL_IMAGE_2D_MULTISAMPLE:
          case eGL_IMAGE_2D_MULTISAMPLE_ARRAY:
          case eGL_INT_IMAGE_1D:
          case eGL_INT_IMAGE_2D:
          case eGL_INT_IMAGE_3D:
          case eGL_INT_IMAGE_2D_RECT:
          case eGL_INT_IMAGE_CUBE:
          case eGL_INT_IMAGE_BUFFER:
          case eGL_INT_IMAGE_1D_ARRAY:
          case eGL_INT_IMAGE_2D_ARRAY:
          case eGL_INT_IMAGE_2D_MULTISAMPLE:
          case eGL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
          case eGL_UNSIGNED_INT_IMAGE_1D:
          case eGL_UNSIGNED_INT_IMAGE_2D:
          case eGL_UNSIGNED_INT_IMAGE_3D:
          case eGL_UNSIGNED_INT_IMAGE_2D_RECT:
          case eGL_UNSIGNED_INT_IMAGE_CUBE:
          case eGL_UNSIGNED_INT_IMAGE_BUFFER:
          case eGL_UNSIGNED_INT_IMAGE_1D_ARRAY:
          case eGL_UNSIGNED_INT_IMAGE_2D_ARRAY:
          case eGL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
          case eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
          case eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
          case eGL_UNSIGNED_INT_ATOMIC_COUNTER:
          case eGL_INT:
          case eGL_INT_VEC2:
          case eGL_INT_VEC3:
          case eGL_INT_VEC4:
            gl.glGetUniformiv(progSrc, srcLocation, iv);
            break;
          // bools are unsigned integers
          case eGL_UNSIGNED_INT:
          case eGL_BOOL:
          case eGL_UNSIGNED_INT_VEC2:
          case eGL_BOOL_VEC2:
          case eGL_UNSIGNED_INT_VEC3:
          case eGL_BOOL_VEC3:
          case eGL_UNSIGNED_INT_VEC4:
          case eGL_BOOL_VEC4: gl.glGetUniformuiv(progSrc, srcLocation, uiv); break;
          default: RDCERR("Unhandled uniform type '%s'", ToStr(type).c_str());
        }
      }
    }

    // now find how many UBOs we have, and store their binding indices
    GLint numUBOs = 0;
    gl.glGetProgramInterfaceiv(progSrc, eGL_UNIFORM_BLOCK, eGL_ACTIVE_RESOURCES, &numUBOs);

    serialisedUniforms.UBOBindings.reserve(numUBOs);

    for(GLint i = 0; i < numUBOs; i++)
    {
      GLenum prop = eGL_BUFFER_BINDING;
      uint32_t bind = 0;

      gl.glGetProgramResourceiv(progSrc, eGL_UNIFORM_BLOCK, i, 1, &prop, 1, NULL, (GLint *)&bind);

      char n[1024] = {0};
      gl.glGetProgramResourceName(progSrc, eGL_UNIFORM_BLOCK, i, 1023, NULL, n);

      serialisedUniforms.UBOBindings.push_back(ProgramBinding(n, bind));
    }

    // finally, if SSBOs are supported on this implementation, fetch their bindings
    GLint numSSBOs = 0;
    if(HasExt[ARB_shader_storage_buffer_object])
      gl.glGetProgramInterfaceiv(progSrc, eGL_SHADER_STORAGE_BLOCK, eGL_ACTIVE_RESOURCES, &numSSBOs);

    serialisedUniforms.SSBOBindings.reserve(numSSBOs);

    for(GLint i = 0; i < numSSBOs; i++)
    {
      GLenum prop = eGL_BUFFER_BINDING;
      uint32_t bind = 0;

      gl.glGetProgramResourceiv(progSrc, eGL_SHADER_STORAGE_BLOCK, i, 1, &prop, 1, NULL,
                                (GLint *)&bind);

      char n[1024] = {0};
      gl.glGetProgramResourceName(progSrc, eGL_SHADER_STORAGE_BLOCK, i, 1023, NULL, n);

      serialisedUniforms.SSBOBindings.push_back(ProgramBinding(n, bind));
    }
  }

  // now serialise all the bindings if we are serialising
  if(CheckConstParam(SerialiseUniforms) && ser)
  {
    ser->Serialise("ProgramUniforms", serialisedUniforms);
  }

  // if we are writing to a destination program and replaying, then apply the stored data from
  // serialisedUniforms
  if(CheckConstParam(WriteDestProgram) && IsReplayMode(state))
  {
    // loop over the loose global uniforms, see if there is an equivalent, and apply it.
    for(const ProgramUniform &uniform : serialisedUniforms.ValueUniforms)
    {
      for(size_t arr = 0; arr < uniform.Values.size(); arr++)
      {
        const ProgramUniformValue &val = uniform.Values[arr];

        std::string name = uniform.Basename;

        if(uniform.IsArray)
          name += StringFormat::Fmt("[%u]", (uint32_t)arr);

        GLint dstLocation = gl.glGetUniformLocation(progDst, name.c_str());
        if(locTranslate)
          (*locTranslate)[val.Location] = dstLocation;

        // don't try and apply the uniform if the new location is -1
        if(dstLocation == -1)
          continue;

        const double *dv = val.data.dval;
        const float *fv = val.data.fval;
        const int32_t *iv = val.data.ival;
        const uint32_t *uiv = val.data.uval;

        // call the appropriate function to apply the data to the destination program
        switch(val.Type)
        {
          case eGL_FLOAT_MAT4:
            gl.glProgramUniformMatrix4fv(progDst, dstLocation, 1, false, fv);
            break;
          case eGL_FLOAT_MAT4x3:
            gl.glProgramUniformMatrix4x3fv(progDst, dstLocation, 1, false, fv);
            break;
          case eGL_FLOAT_MAT4x2:
            gl.glProgramUniformMatrix4x2fv(progDst, dstLocation, 1, false, fv);
            break;
          case eGL_FLOAT_MAT3:
            gl.glProgramUniformMatrix3fv(progDst, dstLocation, 1, false, fv);
            break;
          case eGL_FLOAT_MAT3x4:
            gl.glProgramUniformMatrix3x4fv(progDst, dstLocation, 1, false, fv);
            break;
          case eGL_FLOAT_MAT3x2:
            gl.glProgramUniformMatrix3x2fv(progDst, dstLocation, 1, false, fv);
            break;
          case eGL_FLOAT_MAT2:
            gl.glProgramUniformMatrix2fv(progDst, dstLocation, 1, false, fv);
            break;
          case eGL_FLOAT_MAT2x4:
            gl.glProgramUniformMatrix2x4fv(progDst, dstLocation, 1, false, fv);
            break;
          case eGL_FLOAT_MAT2x3:
            gl.glProgramUniformMatrix2x3fv(progDst, dstLocation, 1, false, fv);
            break;
          case eGL_DOUBLE_MAT4:
            gl.glProgramUniformMatrix4dv(progDst, dstLocation, 1, false, dv);
            break;
          case eGL_DOUBLE_MAT4x3:
            gl.glProgramUniformMatrix4x3dv(progDst, dstLocation, 1, false, dv);
            break;
          case eGL_DOUBLE_MAT4x2:
            gl.glProgramUniformMatrix4x2dv(progDst, dstLocation, 1, false, dv);
            break;
          case eGL_DOUBLE_MAT3:
            gl.glProgramUniformMatrix3dv(progDst, dstLocation, 1, false, dv);
            break;
          case eGL_DOUBLE_MAT3x4:
            gl.glProgramUniformMatrix3x4dv(progDst, dstLocation, 1, false, dv);
            break;
          case eGL_DOUBLE_MAT3x2:
            gl.glProgramUniformMatrix3x2dv(progDst, dstLocation, 1, false, dv);
            break;
          case eGL_DOUBLE_MAT2:
            gl.glProgramUniformMatrix2dv(progDst, dstLocation, 1, false, dv);
            break;
          case eGL_DOUBLE_MAT2x4:
            gl.glProgramUniformMatrix2x4dv(progDst, dstLocation, 1, false, dv);
            break;
          case eGL_DOUBLE_MAT2x3:
            gl.glProgramUniformMatrix2x3dv(progDst, dstLocation, 1, false, dv);
            break;
          case eGL_FLOAT: gl.glProgramUniform1fv(progDst, dstLocation, 1, fv); break;
          case eGL_FLOAT_VEC2: gl.glProgramUniform2fv(progDst, dstLocation, 1, fv); break;
          case eGL_FLOAT_VEC3: gl.glProgramUniform3fv(progDst, dstLocation, 1, fv); break;
          case eGL_FLOAT_VEC4: gl.glProgramUniform4fv(progDst, dstLocation, 1, fv); break;
          case eGL_DOUBLE: gl.glProgramUniform1dv(progDst, dstLocation, 1, dv); break;
          case eGL_DOUBLE_VEC2: gl.glProgramUniform2dv(progDst, dstLocation, 1, dv); break;
          case eGL_DOUBLE_VEC3: gl.glProgramUniform3dv(progDst, dstLocation, 1, dv); break;
          case eGL_DOUBLE_VEC4: gl.glProgramUniform4dv(progDst, dstLocation, 1, dv); break;

          case eGL_IMAGE_1D:
          case eGL_IMAGE_2D:
          case eGL_IMAGE_3D:
          case eGL_IMAGE_2D_RECT:
          case eGL_IMAGE_CUBE:
          case eGL_IMAGE_BUFFER:
          case eGL_IMAGE_1D_ARRAY:
          case eGL_IMAGE_2D_ARRAY:
          case eGL_IMAGE_CUBE_MAP_ARRAY:
          case eGL_IMAGE_2D_MULTISAMPLE:
          case eGL_IMAGE_2D_MULTISAMPLE_ARRAY:
          case eGL_INT_IMAGE_1D:
          case eGL_INT_IMAGE_2D:
          case eGL_INT_IMAGE_3D:
          case eGL_INT_IMAGE_2D_RECT:
          case eGL_INT_IMAGE_CUBE:
          case eGL_INT_IMAGE_BUFFER:
          case eGL_INT_IMAGE_1D_ARRAY:
          case eGL_INT_IMAGE_2D_ARRAY:
          case eGL_INT_IMAGE_2D_MULTISAMPLE:
          case eGL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
          case eGL_UNSIGNED_INT_IMAGE_1D:
          case eGL_UNSIGNED_INT_IMAGE_2D:
          case eGL_UNSIGNED_INT_IMAGE_3D:
          case eGL_UNSIGNED_INT_IMAGE_2D_RECT:
          case eGL_UNSIGNED_INT_IMAGE_CUBE:
          case eGL_UNSIGNED_INT_IMAGE_BUFFER:
          case eGL_UNSIGNED_INT_IMAGE_1D_ARRAY:
          case eGL_UNSIGNED_INT_IMAGE_2D_ARRAY:
          case eGL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
          case eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
          case eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
          case eGL_UNSIGNED_INT_ATOMIC_COUNTER:
            if(IsGLES)
              // Image uniforms cannot be re-assigned in GLES.
              break;
          // deliberate fall-through
          // treat all samplers as just an int (since they just store their binding value)
          case eGL_SAMPLER_1D:
          case eGL_SAMPLER_2D:
          case eGL_SAMPLER_3D:
          case eGL_SAMPLER_CUBE:
          case eGL_SAMPLER_CUBE_MAP_ARRAY:
          case eGL_SAMPLER_1D_SHADOW:
          case eGL_SAMPLER_2D_SHADOW:
          case eGL_SAMPLER_1D_ARRAY:
          case eGL_SAMPLER_2D_ARRAY:
          case eGL_SAMPLER_1D_ARRAY_SHADOW:
          case eGL_SAMPLER_2D_ARRAY_SHADOW:
          case eGL_SAMPLER_2D_MULTISAMPLE:
          case eGL_SAMPLER_2D_MULTISAMPLE_ARRAY:
          case eGL_SAMPLER_CUBE_SHADOW:
          case eGL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
          case eGL_SAMPLER_BUFFER:
          case eGL_SAMPLER_2D_RECT:
          case eGL_SAMPLER_2D_RECT_SHADOW:
          case eGL_INT_SAMPLER_1D:
          case eGL_INT_SAMPLER_2D:
          case eGL_INT_SAMPLER_3D:
          case eGL_INT_SAMPLER_CUBE:
          case eGL_INT_SAMPLER_CUBE_MAP_ARRAY:
          case eGL_INT_SAMPLER_1D_ARRAY:
          case eGL_INT_SAMPLER_2D_ARRAY:
          case eGL_INT_SAMPLER_2D_MULTISAMPLE:
          case eGL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
          case eGL_INT_SAMPLER_BUFFER:
          case eGL_INT_SAMPLER_2D_RECT:
          case eGL_UNSIGNED_INT_SAMPLER_1D:
          case eGL_UNSIGNED_INT_SAMPLER_2D:
          case eGL_UNSIGNED_INT_SAMPLER_3D:
          case eGL_UNSIGNED_INT_SAMPLER_CUBE:
          case eGL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
          case eGL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
          case eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
          case eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
          case eGL_UNSIGNED_INT_SAMPLER_BUFFER:
          case eGL_UNSIGNED_INT_SAMPLER_2D_RECT:
          case eGL_INT: gl.glProgramUniform1iv(progDst, dstLocation, 1, iv); break;
          case eGL_INT_VEC2: gl.glProgramUniform2iv(progDst, dstLocation, 1, iv); break;
          case eGL_INT_VEC3: gl.glProgramUniform3iv(progDst, dstLocation, 1, iv); break;
          case eGL_INT_VEC4: gl.glProgramUniform4iv(progDst, dstLocation, 1, iv); break;
          case eGL_UNSIGNED_INT:
          case eGL_BOOL: gl.glProgramUniform1uiv(progDst, dstLocation, 1, uiv); break;
          case eGL_UNSIGNED_INT_VEC2:
          case eGL_BOOL_VEC2: gl.glProgramUniform2uiv(progDst, dstLocation, 1, uiv); break;
          case eGL_UNSIGNED_INT_VEC3:
          case eGL_BOOL_VEC3: gl.glProgramUniform3uiv(progDst, dstLocation, 1, uiv); break;
          case eGL_UNSIGNED_INT_VEC4:
          case eGL_BOOL_VEC4: gl.glProgramUniform4uiv(progDst, dstLocation, 1, uiv); break;
          default: RDCERR("Unhandled uniform type '%s'", ToStr(val.Type).c_str());
        }
      }
    }

    // apply UBO bindings
    for(const ProgramBinding &bind : serialisedUniforms.UBOBindings)
    {
      GLuint idx = gl.glGetUniformBlockIndex(progDst, bind.Name.c_str());
      if(idx != GL_INVALID_INDEX)
        gl.glUniformBlockBinding(progDst, idx, bind.Binding);
    }

    // apply SSBO bindings
    for(const ProgramBinding &bind : serialisedUniforms.SSBOBindings)
    {
      GLuint idx = gl.glGetProgramResourceIndex(progDst, eGL_SHADER_STORAGE_BLOCK, bind.Name.c_str());
      if(idx != GL_INVALID_INDEX)
      {
        if(gl.glShaderStorageBlockBinding)
        {
          gl.glShaderStorageBlockBinding(progDst, idx, bind.Binding);
        }
        else
        {
          // TODO glShaderStorageBlockBinding is not core GLES
          RDCERR("glShaderStorageBlockBinding is not supported!");
        }
      }
    }
  }
}
示例#7
0
void EmulateLuminanceFormat(const GLHookSet &gl, GLuint tex, GLenum target, GLenum &internalFormat, GLenum &dataFormat)
{
	GLenum swizzle[] = { eGL_RED, eGL_GREEN, eGL_BLUE, eGL_ALPHA };

	bool dataFormatLum = (dataFormat == eGL_LUMINANCE || dataFormat == eGL_LUMINANCE_ALPHA || dataFormat == eGL_ALPHA || dataFormat == eGL_INTENSITY);

	switch((int)internalFormat)
	{
		case eGL_INTENSITY:
		case eGL_INTENSITY8_EXT:
			internalFormat = eGL_R8;
			if(dataFormatLum) dataFormat = eGL_RED;
			swizzle[0] = swizzle[1] = swizzle[2] = swizzle[3] = eGL_RED; // intensity replicates across all 4 of RGBA
			break;
		case eGL_INTENSITY16_EXT:
			internalFormat = eGL_R16;
			if(dataFormatLum) dataFormat = eGL_RED;
			swizzle[0] = swizzle[1] = swizzle[2] = swizzle[3] = eGL_RED; // intensity replicates across all 4 of RGBA
			break;
		case eGL_ALPHA:
		case eGL_ALPHA8_EXT:
			internalFormat = eGL_R8;
			if(dataFormatLum) dataFormat = eGL_RED;
			swizzle[0] = swizzle[1] = swizzle[2] = eGL_NONE;
			swizzle[3] = eGL_RED; // single component alpha channel
			break;
		case eGL_LUMINANCE:
		case eGL_LUMINANCE8_EXT:
			internalFormat = eGL_R8;
			if(dataFormatLum) dataFormat = eGL_RED;
			swizzle[0] = swizzle[1] = swizzle[2] = eGL_RED;
			swizzle[3] = (GLenum)1; // alpha explicitly set to 1 in luminance formats
			break;
		case eGL_SLUMINANCE8_EXT:
			internalFormat = eGL_SRGB8;
			if(dataFormatLum) dataFormat = eGL_RED;
			swizzle[0] = swizzle[1] = swizzle[2] = eGL_RED;
			swizzle[3] = (GLenum)1; // alpha explicitly set to 1 in luminance formats
			break;
		case eGL_LUMINANCE16_EXT:
			internalFormat = eGL_R16;
			if(dataFormatLum) dataFormat = eGL_RED;
			swizzle[0] = swizzle[1] = swizzle[2] = eGL_RED;
			swizzle[3] = (GLenum)1; // alpha explicitly set to 1 in luminance formats
			break;
		case eGL_LUMINANCE32F_ARB:
			internalFormat = eGL_R32F;
			if(dataFormatLum) dataFormat = eGL_RED;
			swizzle[0] = swizzle[1] = swizzle[2] = eGL_RED;
			swizzle[3] = (GLenum)1; // alpha explicitly set to 1 in luminance formats
			break;
		case eGL_LUMINANCE32I_EXT:
			internalFormat = eGL_R32I;
			if(dataFormatLum) dataFormat = eGL_RED;
			swizzle[0] = swizzle[1] = swizzle[2] = eGL_RED;
			swizzle[3] = (GLenum)1; // alpha explicitly set to 1 in luminance formats
			break;
		case eGL_LUMINANCE32UI_EXT:
			internalFormat = eGL_R32UI;
			if(dataFormatLum) dataFormat = eGL_RED;
			swizzle[0] = swizzle[1] = swizzle[2] = eGL_RED;
			swizzle[3] = (GLenum)1; // alpha explicitly set to 1 in luminance formats
			break;
		case eGL_LUMINANCE_ALPHA:
		case eGL_LUMINANCE8_ALPHA8_EXT:
			internalFormat = eGL_RG8;
			if(dataFormatLum) dataFormat = eGL_RG;
			swizzle[0] = swizzle[1] = swizzle[2] = eGL_RED;
			swizzle[3] = eGL_GREEN;
			break;
		case eGL_SLUMINANCE8_ALPHA8_EXT:
			internalFormat = eGL_SRGB8_ALPHA8;
			if(dataFormatLum) dataFormat = eGL_RG;
			swizzle[0] = swizzle[1] = swizzle[2] = eGL_RED;
			swizzle[3] = eGL_GREEN;
			break;
		case eGL_LUMINANCE16_ALPHA16_EXT:
			internalFormat = eGL_RG16;
			if(dataFormatLum) dataFormat = eGL_RG;
			swizzle[0] = swizzle[1] = swizzle[2] = eGL_RED;
			swizzle[3] = eGL_GREEN;
			break;
		default:
			return;
	}

	if(tex)
		gl.glTextureParameterivEXT(tex, target, eGL_TEXTURE_SWIZZLE_RGBA, (GLint *)swizzle);
}
示例#8
0
GLenum GetSizedFormat(const GLHookSet &gl, GLenum target, GLenum internalFormat)
{
	switch(internalFormat)
	{
		case eGL_RED:
		case eGL_RG:
		case eGL_RGB:
		case eGL_RGBA:
		case eGL_DEPTH_COMPONENT:
		case eGL_DEPTH_STENCIL:
			break;
		default:
			return internalFormat; // already explicitly sized
	}

	switch(target)
	{
		case eGL_TEXTURE_CUBE_MAP_POSITIVE_X:
		case eGL_TEXTURE_CUBE_MAP_NEGATIVE_X:
		case eGL_TEXTURE_CUBE_MAP_POSITIVE_Y:
		case eGL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
		case eGL_TEXTURE_CUBE_MAP_POSITIVE_Z:
		case eGL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
			target = eGL_TEXTURE_CUBE_MAP;
		default:
			break;
	}
	
	GLint red, depth;
	if(gl.glGetInternalformativ)
	{
		gl.glGetInternalformativ(target, internalFormat, eGL_INTERNALFORMAT_RED_SIZE, sizeof(GLint), &red);
		gl.glGetInternalformativ(target, internalFormat, eGL_INTERNALFORMAT_DEPTH_SIZE, sizeof(GLint), &depth);
	}
	else
	{
		// without the query function, just default to sensible defaults
		red = 8;
		depth = 32;
	}

	switch(internalFormat)
	{
		case eGL_RED:
			if(red == 32)
				return eGL_R32F;
			else if(red == 16)
				return eGL_R16;
			else
				return eGL_R8;
		case eGL_RG:
			if(red == 32)
				return eGL_RG32F;
			else if(red == 16)
				return eGL_RG16;
			else
				return eGL_RG8;
		case eGL_RGB:
			if(red == 32)
				return eGL_RGB32F;
			else if(red == 16)
				return eGL_RGB16;
			else
				return eGL_RGB8;
		case eGL_RGBA:
			if(red == 32)
				return eGL_RGBA32F;
			else if(red == 16)
				return eGL_RGBA16;
			else
				return eGL_RGBA8;
		case eGL_DEPTH_COMPONENT:
			if(depth == 32)
				return eGL_DEPTH_COMPONENT32F;
			else if(depth == 16)
				return eGL_DEPTH_COMPONENT16;
			else
				return eGL_DEPTH_COMPONENT24;
		case eGL_DEPTH_STENCIL:
			if(depth == 32)
				return eGL_DEPTH32F_STENCIL8;
			else
				return eGL_DEPTH24_STENCIL8;
		default:
			break;
	}

	return internalFormat;
}
示例#9
0
GLenum GetSizedFormat(const GLHookSet &gl, GLenum target, GLenum internalFormat)
{
  switch(internalFormat)
  {
    // pick sized format ourselves for generic formats
    case eGL_COMPRESSED_RED: return eGL_COMPRESSED_RED_RGTC1;
    case eGL_COMPRESSED_RG: return eGL_COMPRESSED_RG_RGTC2;
    case eGL_COMPRESSED_RGB: return eGL_COMPRESSED_RGB_S3TC_DXT1_EXT;
    case eGL_COMPRESSED_RGBA: return eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
    case eGL_COMPRESSED_SRGB: return eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
    case eGL_COMPRESSED_SRGB_ALPHA:
      return eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;

    // only one sized format for SRGB
    case eGL_SRGB: return eGL_SRGB8;
    case eGL_SRGB_ALPHA: return eGL_SRGB8_ALPHA8;

    case eGL_RED:
    case eGL_RG:
    case eGL_RGB:
    case eGL_RGBA:
    case eGL_DEPTH_COMPONENT:
    case eGL_STENCIL:
    case eGL_STENCIL_INDEX:
    case eGL_DEPTH_STENCIL: break;
    default:
      return internalFormat;    // already explicitly sized
  }

  switch(target)
  {
    case eGL_TEXTURE_CUBE_MAP_POSITIVE_X:
    case eGL_TEXTURE_CUBE_MAP_NEGATIVE_X:
    case eGL_TEXTURE_CUBE_MAP_POSITIVE_Y:
    case eGL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
    case eGL_TEXTURE_CUBE_MAP_POSITIVE_Z:
    case eGL_TEXTURE_CUBE_MAP_NEGATIVE_Z: target = eGL_TEXTURE_CUBE_MAP;
    default: break;
  }

  GLint red, depth, stencil;
  if(gl.glGetInternalformativ)
  {
    gl.glGetInternalformativ(target, internalFormat, eGL_INTERNALFORMAT_RED_SIZE, sizeof(GLint),
                             &red);
    gl.glGetInternalformativ(target, internalFormat, eGL_INTERNALFORMAT_DEPTH_SIZE, sizeof(GLint),
                             &depth);
    gl.glGetInternalformativ(target, internalFormat, eGL_INTERNALFORMAT_STENCIL_SIZE, sizeof(GLint),
                             &stencil);
  }
  else
  {
    // without the query function, just default to sensible defaults
    red = 8;
    depth = 32;
    stencil = 8;
  }

  switch(internalFormat)
  {
    case eGL_RED:
      if(red == 32)
        return eGL_R32F;
      else if(red == 16)
        return eGL_R16;
      else
        return eGL_R8;
    case eGL_RG:
      if(red == 32)
        return eGL_RG32F;
      else if(red == 16)
        return eGL_RG16;
      else
        return eGL_RG8;
    case eGL_RGB:
      if(red == 32)
        return eGL_RGB32F;
      else if(red == 16)
        return eGL_RGB16;
      else
        return eGL_RGB8;
    case eGL_RGBA:
      if(red == 32)
        return eGL_RGBA32F;
      else if(red == 16)
        return eGL_RGBA16;
      else
        return eGL_RGBA8;
    case eGL_STENCIL:
    case eGL_STENCIL_INDEX:
      if(stencil == 16)
        return eGL_STENCIL_INDEX16;
      else
        return eGL_STENCIL_INDEX8;
    case eGL_DEPTH_COMPONENT:
      if(depth == 32)
        return eGL_DEPTH_COMPONENT32F;
      else if(depth == 16)
        return eGL_DEPTH_COMPONENT16;
      else
        return eGL_DEPTH_COMPONENT24;
    case eGL_DEPTH_STENCIL:
      if(depth == 32)
        return eGL_DEPTH32F_STENCIL8;
      else
        return eGL_DEPTH24_STENCIL8;
    default: break;
  }

  return internalFormat;
}