Beispiel #1
0
void DoSerialise(SerialiserType &ser, DynamicDescriptorCopy &el)
{
  D3D12ResourceManager *rm = (D3D12ResourceManager *)ser.GetUserData();

  SERIALISE_MEMBER(type);

  PortableHandle dst, src;

  if(ser.IsWriting())
  {
    dst = ToPortableHandle(el.dst);
    src = ToPortableHandle(el.src);
  }

  ser.Serialise("dst", dst);
  ser.Serialise("src", src);

  if(ser.IsReading())
  {
    if(rm)
    {
      el.dst = DescriptorFromPortableHandle(rm, dst);
      el.src = DescriptorFromPortableHandle(rm, src);
    }
    else
    {
      el.dst = NULL;
      el.src = NULL;
    }
  }
}
Beispiel #2
0
void DoSerialise(SerialiserType &ser, D3D12_SHADER_BYTECODE &el)
{
  // don't serialise size_t, otherwise capture/replay between different bit-ness won't work
  {
    uint64_t BytecodeLength = el.BytecodeLength;
    ser.Serialise("BytecodeLength", BytecodeLength);
    if(ser.IsReading())
      el.BytecodeLength = (size_t)BytecodeLength;
  }

  SERIALISE_MEMBER_ARRAY(pShaderBytecode, BytecodeLength);
}
Beispiel #3
0
void DoSerialise(SerialiserType &ser, D3D12_RANGE &el)
{
  // serialise as uint64, so we're 32-bit/64-bit compatible

  uint64_t Begin = el.Begin;
  uint64_t End = el.End;

  ser.Serialise("Begin", Begin);
  ser.Serialise("End", End);

  if(ser.IsReading())
  {
    el.Begin = (SIZE_T)Begin;
    el.End = (SIZE_T)End;
  }
}
Beispiel #4
0
void DoSerialise(SerialiserType &ser, D3D12_GRAPHICS_PIPELINE_STATE_DESC &el)
{
  SERIALISE_MEMBER(pRootSignature);
  SERIALISE_MEMBER(VS);
  SERIALISE_MEMBER(PS);
  SERIALISE_MEMBER(DS);
  SERIALISE_MEMBER(HS);
  SERIALISE_MEMBER(GS);
  SERIALISE_MEMBER(StreamOutput);
  SERIALISE_MEMBER(BlendState);
  SERIALISE_MEMBER(SampleMask);
  SERIALISE_MEMBER(RasterizerState);
  SERIALISE_MEMBER(DepthStencilState);
  SERIALISE_MEMBER(InputLayout);
  SERIALISE_MEMBER(IBStripCutValue);
  SERIALISE_MEMBER(PrimitiveTopologyType);
  SERIALISE_MEMBER(NumRenderTargets);
  SERIALISE_MEMBER(RTVFormats);
  SERIALISE_MEMBER(DSVFormat);
  SERIALISE_MEMBER(SampleDesc);
  SERIALISE_MEMBER(NodeMask);
  SERIALISE_MEMBER(Flags);

  if(ser.IsReading())
  {
    el.CachedPSO.CachedBlobSizeInBytes = 0;
    el.CachedPSO.pCachedBlob = NULL;
  }
}
Beispiel #5
0
void DoSerialise(SerialiserType &ser, D3D12_CACHED_PIPELINE_STATE &el)
{
  // don't serialise these, just set to NULL/0. See the definition of SERIALISE_MEMBER_DUMMY
  SERIALISE_MEMBER_ARRAY_EMPTY(pCachedBlob);
  uint64_t CachedBlobSizeInBytes = 0;
  ser.Serialise("CachedBlobSizeInBytes", CachedBlobSizeInBytes);
}
Beispiel #6
0
void DoSerialiseViaResourceId(SerialiserType &ser, Interface *&el)
{
  D3D12ResourceManager *rm = (D3D12ResourceManager *)ser.GetUserData();

  ResourceId id;

  if(ser.IsWriting())
    id = GetResID(el);

  DoSerialise(ser, id);

  if(ser.IsReading())
  {
    if(id != ResourceId() && rm && rm->HasLiveResource(id))
      el = rm->GetLiveAs<Interface>(id);
    else
      el = NULL;
  }
}
Beispiel #7
0
void DoSerialise(SerialiserType &ser, D3D12_GPU_DESCRIPTOR_HANDLE &el)
{
  D3D12ResourceManager *rm = (D3D12ResourceManager *)ser.GetUserData();

  PortableHandle ph;

  if(ser.IsWriting())
    ph = ToPortableHandle(el);

  DoSerialise(ser, ph);

  if(ser.IsReading())
  {
    if(rm)
      el.ptr = (SIZE_T)DescriptorFromPortableHandle(rm, ph);
    else
      el.ptr = 0;
  }
}
Beispiel #8
0
void DoSerialise(SerialiserType &ser, D3D12BufferLocation &el)
{
  D3D12ResourceManager *rm = (D3D12ResourceManager *)ser.GetUserData();

  ResourceId buffer;
  UINT64 offs = 0;

  if(ser.IsWriting())
    WrappedID3D12Resource::GetResIDFromAddr(el.Location, buffer, offs);

  ser.Serialise("Buffer", buffer);
  ser.Serialise("Offset", offs);

  if(ser.IsReading())
  {
    if(rm && buffer != ResourceId() && rm->HasLiveResource(buffer))
      el.Location = rm->GetLiveAs<ID3D12Resource>(buffer)->GetGPUVirtualAddress() + offs;
    else
      el.Location = 0;
  }
}
Beispiel #9
0
void DoSerialise(SerialiserType &ser, D3D12_COMPUTE_PIPELINE_STATE_DESC &el)
{
  SERIALISE_MEMBER(pRootSignature);
  SERIALISE_MEMBER(CS);
  SERIALISE_MEMBER(NodeMask);
  SERIALISE_MEMBER(Flags);

  if(ser.IsReading())
  {
    el.CachedPSO.CachedBlobSizeInBytes = 0;
    el.CachedPSO.pCachedBlob = NULL;
  }
}
Beispiel #10
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!");
            }
          }
        }
      }
    }
  }
}
Beispiel #11
0
void DoSerialise(SerialiserType &ser, ProgramUniformValue &el)
{
  SERIALISE_MEMBER(Type);
  SERIALISE_MEMBER(Location);

  // some special logic here, we decode Type to figure out what the actual data is, and serialise it
  // with the right type.

  VarType baseType = VarType::Float;
  uint32_t elemCount = 1;

  switch(el.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: baseType = VarType::Float; 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: baseType = VarType::Double; break;
    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: baseType = VarType::Int; break;
    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: baseType = VarType::UInt; break;
    default:
      RDCERR("Unhandled uniform type '%s'", ToStr(el.Type).c_str());
      baseType = VarType::Float;
      elemCount = 1;
      break;
  }

  switch(el.Type)
  {
    case eGL_FLOAT_MAT4:
    case eGL_DOUBLE_MAT4: elemCount = 16; break;
    case eGL_FLOAT_MAT4x3:
    case eGL_FLOAT_MAT3x4:
    case eGL_DOUBLE_MAT4x3:
    case eGL_DOUBLE_MAT3x4: elemCount = 12; break;
    case eGL_FLOAT_MAT4x2:
    case eGL_FLOAT_MAT2x4:
    case eGL_DOUBLE_MAT4x2:
    case eGL_DOUBLE_MAT2x4: elemCount = 8; break;
    case eGL_FLOAT_MAT3:
    case eGL_DOUBLE_MAT3: elemCount = 9; break;
    case eGL_FLOAT_MAT3x2:
    case eGL_DOUBLE_MAT3x2:
    case eGL_FLOAT_MAT2x3:
    case eGL_DOUBLE_MAT2x3: elemCount = 6; break;
    case eGL_FLOAT_MAT2:
    case eGL_DOUBLE_MAT2:
    case eGL_FLOAT_VEC4:
    case eGL_DOUBLE_VEC4: elemCount = 4; break;
    case eGL_FLOAT_VEC3:
    case eGL_DOUBLE_VEC3: elemCount = 3; break;
    case eGL_FLOAT_VEC2:
    case eGL_DOUBLE_VEC2: elemCount = 2; break;
    default:
      // all other types are elemCount = 1
      break;
  }

  double *dv = el.data.dval;
  float *fv = el.data.fval;
  int32_t *iv = el.data.ival;
  uint32_t *uv = el.data.uval;

  if(baseType == VarType::Double)
    ser.Serialise("data", fv, elemCount, SerialiserFlags::NoFlags);
  else if(baseType == VarType::Float)
    ser.Serialise("data", dv, elemCount, SerialiserFlags::NoFlags);
  else if(baseType == VarType::Int)
    ser.Serialise("data", iv, elemCount, SerialiserFlags::NoFlags);
  else if(baseType == VarType::UInt)
    ser.Serialise("data", uv, elemCount, SerialiserFlags::NoFlags);
}
Beispiel #12
0
void DoSerialise(SerialiserType &ser, D3D12Descriptor &el)
{
  D3D12DescriptorType type = el.GetType();
  ser.Serialise("type", type);

  ID3D12DescriptorHeap *heap = (ID3D12DescriptorHeap *)el.samp.heap;

  ser.Serialise("heap", heap);
  ser.Serialise("index", el.samp.idx);

  if(ser.IsReading())
  {
    el.samp.heap = (WrappedID3D12DescriptorHeap *)heap;

    // for sampler types, this will be overwritten when serialising the sampler descriptor
    el.nonsamp.type = type;
  }

  switch(type)
  {
    case D3D12DescriptorType::Sampler:
    {
      ser.Serialise("Descriptor", el.samp.desc);
      RDCASSERTEQUAL(el.GetType(), D3D12DescriptorType::Sampler);
      break;
    }
    case D3D12DescriptorType::CBV:
    {
      ser.Serialise("Descriptor", el.nonsamp.cbv);
      break;
    }
    case D3D12DescriptorType::SRV:
    {
      ser.Serialise("Resource", el.nonsamp.resource);
      ser.Serialise("Descriptor", el.nonsamp.srv);
      break;
    }
    case D3D12DescriptorType::RTV:
    {
      ser.Serialise("Resource", el.nonsamp.resource);
      ser.Serialise("Descriptor", el.nonsamp.rtv);
      break;
    }
    case D3D12DescriptorType::DSV:
    {
      ser.Serialise("Resource", el.nonsamp.resource);
      ser.Serialise("Descriptor", el.nonsamp.dsv);
      break;
    }
    case D3D12DescriptorType::UAV:
    {
      ser.Serialise("Resource", el.nonsamp.resource);
      ser.Serialise("CounterResource", el.nonsamp.uav.counterResource);

      // special case because of extra resource and squeezed descriptor
      D3D12_UNORDERED_ACCESS_VIEW_DESC desc = el.nonsamp.uav.desc.AsDesc();
      ser.Serialise("Descriptor", desc);
      el.nonsamp.uav.desc.Init(desc);
      break;
    }
    case D3D12DescriptorType::Undefined:
    {
      el.nonsamp.type = type;
      break;
    }
  }
}
Beispiel #13
0
bool WrappedOpenGL::Serialise_wglDXLockObjectsNV(SerialiserType &ser, GLResource Resource)
{
  SERIALISE_ELEMENT(Resource);
  SERIALISE_ELEMENT_LOCAL(textype, Resource.Namespace == eResBuffer
                                       ? eGL_NONE
                                       : m_Textures[GetResourceManager()->GetID(Resource)].curType)
      .Hidden();

  const GLHookSet &gl = m_Real;

  // buffer contents are easier to save
  if(textype == eGL_NONE)
  {
    byte *Contents = NULL;
    uint32_t length = 1;

    // while writing, fetch the buffer's size and contents
    if(ser.IsWriting())
    {
      gl.glGetNamedBufferParameterivEXT(Resource.name, eGL_BUFFER_SIZE, (GLint *)&length);

      Contents = new byte[length];

      GLuint oldbuf = 0;
      gl.glGetIntegerv(eGL_COPY_READ_BUFFER_BINDING, (GLint *)&oldbuf);
      gl.glBindBuffer(eGL_COPY_READ_BUFFER, Resource.name);

      gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, 0, (GLsizeiptr)length, Contents);

      gl.glBindBuffer(eGL_COPY_READ_BUFFER, oldbuf);
    }

    SERIALISE_ELEMENT_ARRAY(Contents, length);

    SERIALISE_CHECK_READ_ERRORS();

    // restore on replay
    if(IsReplayingAndReading())
    {
      uint32_t liveLength = 1;
      gl.glGetNamedBufferParameterivEXT(Resource.name, eGL_BUFFER_SIZE, (GLint *)&liveLength);

      gl.glNamedBufferSubData(Resource.name, 0, (GLsizeiptr)RDCMIN(length, liveLength), Contents);
    }
  }
  else
  {
    GLuint ppb = 0, pub = 0;
    PixelPackState pack;
    PixelUnpackState unpack;

    // save and restore pixel pack/unpack state. We only need one or the other but for clarity we
    // push and pop both always.
    if(ser.IsWriting() || !IsStructuredExporting(m_State))
    {
      gl.glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, (GLint *)&ppb);
      gl.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&pub);
      gl.glBindBuffer(eGL_PIXEL_PACK_BUFFER, 0);
      gl.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0);

      pack.Fetch(&gl, false);
      unpack.Fetch(&gl, false);

      ResetPixelPackState(gl, false, 1);
      ResetPixelUnpackState(gl, false, 1);
    }

    TextureData &details = m_Textures[GetResourceManager()->GetID(Resource)];
    GLuint tex = Resource.name;

    // serialise the metadata for convenience
    SERIALISE_ELEMENT_LOCAL(internalFormat, details.internalFormat).Hidden();
    SERIALISE_ELEMENT_LOCAL(width, details.width).Hidden();
    SERIALISE_ELEMENT_LOCAL(height, details.height).Hidden();
    SERIALISE_ELEMENT_LOCAL(depth, details.depth).Hidden();

    RDCASSERT(internalFormat == details.internalFormat, internalFormat, details.internalFormat);
    RDCASSERT(width == details.width, width, details.width);
    RDCASSERT(height == details.height, height, details.height);
    RDCASSERT(depth == details.depth, depth, details.depth);

    GLenum fmt = GetBaseFormat(internalFormat);
    GLenum type = GetDataType(internalFormat);

    GLint dim = details.dimension;

    uint32_t size = (uint32_t)GetByteSize(width, height, depth, fmt, type);

    int mips = 0;
    if(IsReplayingAndReading())
      mips = GetNumMips(gl, textype, tex, width, height, depth);

    byte *scratchBuf = NULL;

    // on read and write, we allocate a single buffer big enough for all mips and re-use it
    // to avoid repeated new/free.
    scratchBuf = AllocAlignedBuffer(size);

    GLuint prevtex = 0;
    if(!IsStructuredExporting(m_State))
    {
      gl.glGetIntegerv(TextureBinding(details.curType), (GLint *)&prevtex);
      gl.glBindTexture(textype, tex);
    }

    for(int i = 0; i < mips; i++)
    {
      int w = RDCMAX(details.width >> i, 1);
      int h = RDCMAX(details.height >> i, 1);
      int d = RDCMAX(details.depth >> i, 1);

      if(textype == eGL_TEXTURE_CUBE_MAP_ARRAY || textype == eGL_TEXTURE_1D_ARRAY ||
         textype == eGL_TEXTURE_2D_ARRAY)
        d = details.depth;

      size = (uint32_t)GetByteSize(w, h, d, fmt, type);

      GLenum targets[] = {
          eGL_TEXTURE_CUBE_MAP_POSITIVE_X, eGL_TEXTURE_CUBE_MAP_NEGATIVE_X,
          eGL_TEXTURE_CUBE_MAP_POSITIVE_Y, eGL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
          eGL_TEXTURE_CUBE_MAP_POSITIVE_Z, eGL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
      };

      int count = ARRAY_COUNT(targets);

      if(textype != eGL_TEXTURE_CUBE_MAP)
      {
        targets[0] = textype;
        count = 1;
      }

      for(int trg = 0; trg < count; trg++)
      {
        if(ser.IsWriting())
        {
          // we avoid glGetTextureImageEXT as it seems buggy for cubemap faces
          gl.glGetTexImage(targets[trg], i, fmt, type, scratchBuf);
        }

        // serialise without allocating memory as we already have our scratch buf sized.
        ser.Serialise("SubresourceContents", scratchBuf, size, SerialiserFlags::NoFlags);

        if(IsReplayingAndReading() && !ser.IsErrored())
        {
          if(dim == 1)
            gl.glTextureSubImage1DEXT(tex, targets[trg], i, 0, w, fmt, type, scratchBuf);
          else if(dim == 2)
            gl.glTextureSubImage2DEXT(tex, targets[trg], i, 0, 0, w, h, fmt, type, scratchBuf);
          else if(dim == 3)
            gl.glTextureSubImage3DEXT(tex, targets[trg], i, 0, 0, 0, w, h, d, fmt, type, scratchBuf);
        }
      }
    }

    FreeAlignedBuffer(scratchBuf);

    // restore pixel (un)packing state
    if(ser.IsWriting() || !IsStructuredExporting(m_State))
    {
      gl.glBindBuffer(eGL_PIXEL_PACK_BUFFER, ppb);
      gl.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, pub);
      pack.Apply(&gl, false);
      unpack.Apply(&gl, false);
    }

    if(!IsStructuredExporting(m_State))
      gl.glBindTexture(textype, prevtex);

    SERIALISE_CHECK_READ_ERRORS();
  }

  return true;
}
Beispiel #14
0
bool WrappedOpenGL::Serialise_wglDXRegisterObjectNV(SerialiserType &ser, GLResource Resource,
                                                    GLenum type, void *dxObject)
{
  SERIALISE_ELEMENT(Resource);

  GLenum internalFormat = eGL_NONE;
  uint32_t width = 0, height = 0, depth = 0, mips = 0, layers = 0, samples = 0;
  if(ser.IsWriting())
  {
    ResourceFormat format;
#if ENABLED(RDOC_WIN32) && ENABLED(RENDERDOC_DX_GL_INTEROP)
    GetDXTextureProperties(dxObject, format, width, height, depth, mips, layers, samples);
    if(type != eGL_NONE)
      internalFormat = MakeGLFormat(format);
#else
    RDCERR("Should never happen - cannot serialise wglDXRegisterObjectNV, interop is disabled");
#endif
  }

  SERIALISE_ELEMENT(type);
  SERIALISE_ELEMENT(internalFormat);
  SERIALISE_ELEMENT(width);
  SERIALISE_ELEMENT(height);
  SERIALISE_ELEMENT(depth);
  SERIALISE_ELEMENT(mips);
  SERIALISE_ELEMENT(layers);
  SERIALISE_ELEMENT(samples);

  SERIALISE_CHECK_READ_ERRORS();

  if(IsReplayingAndReading())
  {
    GLuint name = Resource.name;

    switch(type)
    {
      case eGL_NONE:
      case eGL_TEXTURE_BUFFER:
      {
        m_Real.glNamedBufferDataEXT(name, width, NULL, eGL_STATIC_DRAW);
        break;
      }
      case eGL_TEXTURE_1D:
        m_Real.glTextureStorage1DEXT(name, type, mips, internalFormat, width);
        break;
      case eGL_TEXTURE_1D_ARRAY:
        m_Real.glTextureStorage2DEXT(name, type, mips, internalFormat, width, layers);
        break;
      // treat renderbuffers and texture rects as tex2D just to make things easier
      case eGL_RENDERBUFFER:
      case eGL_TEXTURE_RECTANGLE:
      case eGL_TEXTURE_2D:
      case eGL_TEXTURE_CUBE_MAP:
        m_Real.glTextureStorage2DEXT(name, type, mips, internalFormat, width, height);
        break;
      case eGL_TEXTURE_2D_ARRAY:
      case eGL_TEXTURE_CUBE_MAP_ARRAY:
        m_Real.glTextureStorage3DEXT(name, type, mips, internalFormat, width, height, layers);
        break;
      case eGL_TEXTURE_2D_MULTISAMPLE:
        m_Real.glTextureStorage2DMultisampleEXT(name, type, samples, internalFormat, width, height,
                                                GL_TRUE);
        break;
      case eGL_TEXTURE_2D_MULTISAMPLE_ARRAY:
        m_Real.glTextureStorage3DMultisampleEXT(name, type, samples, internalFormat, width, height,
                                                layers, GL_TRUE);
        break;
      case eGL_TEXTURE_3D:
        m_Real.glTextureStorage3DEXT(name, type, mips, internalFormat, width, height, depth);
        break;
      default: RDCERR("Unexpected type of interop texture: %s", ToStr(type).c_str()); break;
    }

    if(type != eGL_NONE)
    {
      ResourceId liveId = GetResourceManager()->GetID(Resource);
      m_Textures[liveId].curType = type;
      m_Textures[liveId].width = width;
      m_Textures[liveId].height = height;
      m_Textures[liveId].depth = RDCMAX(depth, samples);
      m_Textures[liveId].samples = samples;
      m_Textures[liveId].dimension = 2;
      if(type == eGL_TEXTURE_1D || type == eGL_TEXTURE_1D_ARRAY)
        m_Textures[liveId].dimension = 1;
      else if(type == eGL_TEXTURE_3D)
        m_Textures[liveId].dimension = 3;

      m_Textures[liveId].internalFormat = internalFormat;
    }

    AddResourceInitChunk(Resource);
  }

  return true;
}
Beispiel #15
0
bool WrappedOpenGL::Serialise_glObjectLabel(SerialiserType &ser, GLenum identifier, GLuint name,
                                            GLsizei length, const GLchar *label)
{
  GLResource Resource;
  std::string Label;

  if(ser.IsWriting())
  {
    // we share implementations between KHR_debug and EXT_debug_label, however KHR_debug follows the
    // pattern elsewhere (e.g. in glShaderSource) of a length of -1 meaning indeterminate
    // NULL-terminated length, but EXT_debug_label takes length of 0 to mean that.
    GLsizei realLength = length;
    if(gl_CurChunk == GLChunk::glLabelObjectEXT && length == 0)
      realLength = -1;

    // if length is negative (after above twiddling), it's taken from strlen and the label must be
    // NULL-terminated
    if(realLength < 0)
      realLength = label ? (GLsizei)strlen(label) : 0;

    if(realLength == 0 || label == NULL)
      Label = "";
    else
      Label = std::string(label, label + realLength);

    switch(identifier)
    {
      case eGL_TEXTURE: Resource = TextureRes(GetCtx(), name); break;
      case eGL_BUFFER_OBJECT_EXT:
      case eGL_BUFFER: Resource = BufferRes(GetCtx(), name); break;
      case eGL_PROGRAM_OBJECT_EXT:
      case eGL_PROGRAM: Resource = ProgramRes(GetCtx(), name); break;
      case eGL_PROGRAM_PIPELINE_OBJECT_EXT:
      case eGL_PROGRAM_PIPELINE: Resource = ProgramPipeRes(GetCtx(), name); break;
      case eGL_VERTEX_ARRAY_OBJECT_EXT:
      case eGL_VERTEX_ARRAY: Resource = VertexArrayRes(GetCtx(), name); break;
      case eGL_SHADER_OBJECT_EXT:
      case eGL_SHADER: Resource = ShaderRes(GetCtx(), name); break;
      case eGL_QUERY_OBJECT_EXT:
      case eGL_QUERY: Resource = QueryRes(GetCtx(), name); break;
      case eGL_TRANSFORM_FEEDBACK: Resource = FeedbackRes(GetCtx(), name); break;
      case eGL_SAMPLER: Resource = SamplerRes(GetCtx(), name); break;
      case eGL_RENDERBUFFER: Resource = RenderbufferRes(GetCtx(), name); break;
      case eGL_FRAMEBUFFER: Resource = FramebufferRes(GetCtx(), name); break;
      default: RDCERR("Unhandled namespace in glObjectLabel");
    }
  }

  SERIALISE_ELEMENT(Resource);
  SERIALISE_ELEMENT(length);
  SERIALISE_ELEMENT(Label);

  SERIALISE_CHECK_READ_ERRORS();

  if(IsReplayingAndReading() && Resource.name)
  {
    ResourceId origId = GetResourceManager()->GetOriginalID(GetResourceManager()->GetID(Resource));

    GetResourceManager()->SetName(origId, Label);

    ResourceDescription &descr = GetReplay()->GetResourceDesc(origId);
    descr.SetCustomName(Label);
    AddResourceCurChunk(descr);
  }

  return true;
}