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; } }
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; } } }
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); }
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; } }
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; } }
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; } }
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; } }
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; } }
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!"); } } } } } } }
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; } } }